├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── feature_request.yml ├── README.md └── workflows │ ├── core-build.yml │ └── core_codestyle.yml ├── .gitignore ├── LICENSE ├── apps ├── .gitkeep └── ci │ ├── .gitkeep │ └── ci-codestyle.sh ├── conf ├── .gitkeep └── trialofstrength.conf.dist ├── data ├── .gitkeep └── sql │ ├── db-auth │ ├── base │ │ └── .gitkeep │ └── updates │ │ └── .gitkeep │ ├── db-characters │ ├── base │ │ └── .gitkeep │ └── updates │ │ └── .gitkeep │ └── db-world │ ├── base │ ├── .gitkeep │ └── tos_world_base.sql │ └── updates │ └── .gitkeep ├── include.sh ├── pull_request_template.md └── src ├── MP_loader.cpp ├── ToSMapMgr.cpp ├── ToSMapMgr.h ├── TrialOfStrength.cpp ├── TrialOfStrength.h └── scripts ├── AI └── ToSAIArenaSpectator.h ├── ToSArenaMasterScript.h ├── ToSCurseCrystalScript.cpp ├── ToSCurseCrystalScript.h ├── ToSInstanceMapScript.cpp ├── ToSInstanceMapScript.h ├── ToSInstanceScript.cpp ├── ToSInstanceScript.h ├── ToSPlayerScript.cpp ├── ToSPlayerScript.h ├── ToSUnitScript.cpp └── ToSUnitScript.h /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | indent_style = space 4 | indent_size = 4 5 | tab_width = 4 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | max_line_length = 80 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ## AUTO-DETECT 2 | ## Handle line endings automatically for files detected as 3 | ## text and leave all files detected as binary untouched. 4 | ## This will handle all files NOT defined below. 5 | * text=auto eol=lf 6 | 7 | # Text 8 | *.conf text 9 | *.conf.dist text 10 | *.cmake text 11 | 12 | ## Scripts 13 | *.sh text 14 | *.fish text 15 | *.lua text 16 | 17 | ## SQL 18 | *.sql text 19 | 20 | ## C++ 21 | *.c text 22 | *.cc text 23 | *.cxx text 24 | *.cpp text 25 | *.c++ text 26 | *.hpp text 27 | *.h text 28 | *.h++ text 29 | *.hh text 30 | 31 | 32 | ## For documentation 33 | 34 | # Documents 35 | *.doc diff=astextplain 36 | *.DOC diff=astextplain 37 | *.docx diff=astextplain 38 | *.DOCX diff=astextplain 39 | *.dot diff=astextplain 40 | *.DOT diff=astextplain 41 | *.pdf diff=astextplain 42 | *.PDF diff=astextplain 43 | *.rtf diff=astextplain 44 | *.RTF diff=astextplain 45 | 46 | ## DOCUMENTATION 47 | *.markdown text 48 | *.md text 49 | *.mdwn text 50 | *.mdown text 51 | *.mkd text 52 | *.mkdn text 53 | *.mdtxt text 54 | *.mdtext text 55 | *.txt text 56 | AUTHORS text 57 | CHANGELOG text 58 | CHANGES text 59 | CONTRIBUTING text 60 | COPYING text 61 | copyright text 62 | *COPYRIGHT* text 63 | INSTALL text 64 | license text 65 | LICENSE text 66 | NEWS text 67 | readme text 68 | *README* text 69 | TODO text 70 | 71 | ## GRAPHICS 72 | *.ai binary 73 | *.bmp binary 74 | *.eps binary 75 | *.gif binary 76 | *.ico binary 77 | *.jng binary 78 | *.jp2 binary 79 | *.jpg binary 80 | *.jpeg binary 81 | *.jpx binary 82 | *.jxr binary 83 | *.pdf binary 84 | *.png binary 85 | *.psb binary 86 | *.psd binary 87 | *.svg text 88 | *.svgz binary 89 | *.tif binary 90 | *.tiff binary 91 | *.wbmp binary 92 | *.webp binary 93 | 94 | 95 | ## ARCHIVES 96 | *.7z binary 97 | *.gz binary 98 | *.jar binary 99 | *.rar binary 100 | *.tar binary 101 | *.zip binary 102 | 103 | ## EXECUTABLES 104 | *.exe binary 105 | *.pyc binary 106 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Create a bug report to help us improve. 3 | title: "Bug: " 4 | body: 5 | - type: textarea 6 | id: current 7 | attributes: 8 | label: Current Behaviour 9 | description: | 10 | Description of the problem or issue here. 11 | Include entries of affected creatures / items / quests / spells etc. 12 | If this is a crash, post the crashlog (upload to https://gist.github.com/) and include the link here. 13 | Never upload files! Use GIST for text and YouTube for videos! 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: expected 18 | attributes: 19 | label: Expected Behaviour 20 | description: | 21 | Tell us what should happen instead. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: reproduce 26 | attributes: 27 | label: Steps to reproduce the problem 28 | description: | 29 | What does someone else need to do to encounter the same bug? 30 | placeholder: | 31 | 1. Step 1 32 | 2. Step 2 33 | 3. Step 3 34 | validations: 35 | required: true 36 | - type: textarea 37 | id: extra 38 | attributes: 39 | label: Extra Notes 40 | description: | 41 | Do you have any extra notes that can help solve the issue that does not fit any other field? 42 | placeholder: | 43 | None 44 | validations: 45 | required: false 46 | - type: textarea 47 | id: commit 48 | attributes: 49 | label: AC rev. hash/commit 50 | description: | 51 | Copy the result of the `.server debug` command (if you need to run it from the client get a prat addon) 52 | validations: 53 | required: true 54 | - type: input 55 | id: os 56 | attributes: 57 | label: Operating system 58 | description: | 59 | The Operating System the Server is running on. 60 | i.e. Windows 11 x64, Debian 10 x64, macOS 12, Ubuntu 20.04 61 | validations: 62 | required: true 63 | - type: textarea 64 | id: custom 65 | attributes: 66 | label: Custom changes or Modules 67 | description: | 68 | List which custom changes or modules you have applied, i.e. Eluna module, etc. 69 | placeholder: | 70 | None 71 | validations: 72 | required: false 73 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for this project 3 | title: "Feature: " 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thank you for taking your time to fill out a feature request. Remember to fill out all fields including the title above. 9 | An issue that is not properly filled out will be closed. 10 | - type: textarea 11 | id: description 12 | attributes: 13 | label: Describe your feature request or suggestion in detail 14 | description: | 15 | A clear and concise description of what you want to happen. 16 | validations: 17 | required: true 18 | - type: textarea 19 | id: solution 20 | attributes: 21 | label: Describe a possible solution to your feature or suggestion in detail 22 | description: | 23 | A clear and concise description of any alternative solutions or features you've considered. 24 | validations: 25 | required: false 26 | - type: textarea 27 | id: additional 28 | attributes: 29 | label: Additional context 30 | description: | 31 | Add any other context or screenshots about the feature request here. 32 | validations: 33 | required: false 34 | -------------------------------------------------------------------------------- /.github/README.md: -------------------------------------------------------------------------------- 1 | ![banner](https://cdn.discordapp.com/attachments/740999436876120127/1168057693907460136/banner2.png?ex=6550617f&is=653dec7f&hm=94411fcc08408464d7c1276c97f7246c965550efa86291ccef073e796d8691f6&) 2 | Trial of Strength (ToS) is an AzerothCore module that adds a test of strength arena to test players skills in combat. 3 | 4 | ## Features 5 | - Waves of monsters to fight. 6 | - Rewards at the end of every wave. 7 | - Curses to add difficulty and increase rewards. 8 | - Supports group play. 9 | 10 | ## Setup 11 | 1. Clone the module into your AzerothCore modules directory. 12 | 2. Setup the `creature_template` table with creatures you would like to use in the arena. 13 | 3. Pick one of the [CombatAI types](https://gist.github.com/AnchyDev/7d8847fd696e42c94efcfdc5baf88e7f) for each of the creatures you create. 14 | 4. Setup the `tos_wave_groups` table with your created creatures. 15 | 5. Setup the `tos_reward_template` with your rewards for each wave. 16 | 6. Create wave entries in `tos_wave_template` which links to your `tos_wave_groups` and `tos_reward_template` entries. 17 | 7. Enable the module. 18 | 8. Spawn the arena entry (entry: 441250) NPC anywhere you want. 19 | 20 | ## Note 21 | This module is a work in progress, so expect bugs and crashes as the module is not heavily tested. 22 | 23 | ## Contact 24 | If you have any issues setting up the module, you can [contact me on my community Discord](https://discord.gg/xdVPGcpJ8C). 25 | -------------------------------------------------------------------------------- /.github/workflows/core-build.yml: -------------------------------------------------------------------------------- 1 | name: core-build 2 | on: 3 | push: 4 | pull_request: 5 | workflow_dispatch: 6 | 7 | jobs: 8 | build: 9 | uses: azerothcore/reusable-workflows/.github/workflows/core_build_modules.yml@main 10 | with: 11 | module_repo: ${{ github.event.repository.name }} 12 | -------------------------------------------------------------------------------- /.github/workflows/core_codestyle.yml: -------------------------------------------------------------------------------- 1 | name: Codestyle Checks 2 | on: 3 | push: 4 | branches: [ master ] 5 | pull_request: 6 | branches: [ master ] 7 | 8 | jobs: 9 | check-codestyle: 10 | strategy: 11 | fail-fast: false 12 | 13 | runs-on: ubuntu-latest 14 | name: Check Codestyling 15 | steps: 16 | - uses: actions/checkout@v2 17 | 18 | - name: Check Codestyling 19 | run: source ./apps/ci/ci-codestyle.sh 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | 3 | # 4 | #Generic 5 | # 6 | 7 | .directory 8 | .mailmap 9 | *.orig 10 | *.rej 11 | *.*~ 12 | .hg/ 13 | *.kdev* 14 | .DS_Store 15 | CMakeLists.txt.user 16 | *.bak 17 | *.patch 18 | *.diff 19 | *.REMOTE.* 20 | *.BACKUP.* 21 | *.BASE.* 22 | *.LOCAL.* 23 | 24 | # 25 | # IDE & other softwares 26 | # 27 | /.settings/ 28 | /.externalToolBuilders/* 29 | # exclude in all levels 30 | nbproject/ 31 | .sync.ffs_db 32 | *.kate-swp 33 | 34 | # 35 | # Eclipse 36 | # 37 | *.pydevproject 38 | .metadata 39 | .gradle 40 | tmp/ 41 | *.tmp 42 | *.swp 43 | *~.nib 44 | local.properties 45 | .settings/ 46 | .loadpath 47 | .project 48 | .cproject 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 AzerothCore 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /apps/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/apps/.gitkeep -------------------------------------------------------------------------------- /apps/ci/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/apps/ci/.gitkeep -------------------------------------------------------------------------------- /apps/ci/ci-codestyle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | echo "Codestyle check script:" 5 | echo 6 | 7 | declare -A singleLineRegexChecks=( 8 | ["LOG_.+GetCounter"]="Use ObjectGuid::ToString().c_str() method instead of ObjectGuid::GetCounter() when logging. Check the lines above" 9 | ["[[:blank:]]$"]="Remove whitespace at the end of the lines above" 10 | ["\t"]="Replace tabs with 4 spaces in the lines above" 11 | ) 12 | 13 | for check in ${!singleLineRegexChecks[@]}; do 14 | echo " Checking RegEx: '${check}'" 15 | 16 | if grep -P -r -I -n ${check} src; then 17 | echo 18 | echo "${singleLineRegexChecks[$check]}" 19 | exit 1 20 | fi 21 | done 22 | 23 | declare -A multiLineRegexChecks=( 24 | ["LOG_[^;]+GetCounter"]="Use ObjectGuid::ToString().c_str() method instead of ObjectGuid::GetCounter() when logging. Check the lines above" 25 | ["\n\n\n"]="Multiple blank lines detected, keep only one. Check the files above" 26 | ) 27 | 28 | for check in ${!multiLineRegexChecks[@]}; do 29 | echo " Checking RegEx: '${check}'" 30 | 31 | if grep -Pzo -r -I ${check} src; then 32 | echo 33 | echo 34 | echo "${multiLineRegexChecks[$check]}" 35 | exit 1 36 | fi 37 | done 38 | 39 | echo 40 | echo "Everything looks good" 41 | -------------------------------------------------------------------------------- /conf/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/conf/.gitkeep -------------------------------------------------------------------------------- /conf/trialofstrength.conf.dist: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 3 | # 4 | 5 | [worldserver] 6 | 7 | ######################################## 8 | # Trial of Strength configuration 9 | ######################################## 10 | # 11 | # TrialOfStrength.Enable 12 | # Description: Enable/disable the module. 13 | # Default: 0 - Disabled 14 | # 1 - Enabled 15 | # 16 | 17 | TrialOfStrength.Enable = 0 18 | 19 | # 20 | # TrialOfStrength.ResetCooldowns 21 | # Description: Enable/disable resetting of player cooldowns after completion of a wave. 22 | # 0 - Disabled 23 | # Default: 1 - Enabled 24 | # 25 | 26 | TrialOfStrength.ResetCooldowns = 1 27 | 28 | # 29 | # TrialOfStrength.MinRewardMoney 30 | # Description: The minimum amount in copper that will be in the reward chest after completion of a wave. 31 | # Note: This value should be lower than MaxRewardMoney. 32 | # Default: 5000 33 | # 34 | 35 | TrialOfStrength.MinRewardMoney = 5000 36 | 37 | # 38 | # TrialOfStrength.MaxRewardMoney 39 | # Description: The maximum amount in copper that will be in the reward chest after completion of a wave. 40 | # Note: This value should be higher than MinRewardMoney. 41 | # Default: 10000 42 | # 43 | 44 | TrialOfStrength.MaxRewardMoney = 10000 45 | 46 | # 47 | # TrialOfStrength.CapRewardMoney 48 | # Description: The maximum amount in copper that will be in the reward chest after curse difficulty scaling. 49 | # Default: 1000000 50 | # 51 | 52 | TrialOfStrength.CapRewardMoney = 1000000 53 | 54 | # 55 | # TrialOfStrength.Scaling.RewardMoneyScalar 56 | # Description: Enable/disable scaling reward money with curse difficulty. 57 | # Note: The formula for scaling is (1 + (sum of every enabled curse difficulty / scalar)) 58 | # Default: 50 59 | # 60 | 61 | TrialOfStrength.Scaling.RewardMoneyScalar = 50 62 | 63 | # 64 | # TrialOfStrength.Scaling.RewardMoney 65 | # Description: Enable/disable scaling reward money with curse difficulty. 66 | # Note: The formula for scaling is (1 + (sum of every enabled curse difficulty / scalar)) 67 | # 0 - Disabled 68 | # Default: 1 - Enabled 69 | # 70 | 71 | TrialOfStrength.Scaling.RewardMoney = 1 72 | 73 | # 74 | # TrialOfStrength.AutoScaling (EXPERIMENTAL) 75 | # Description: Enable/disable auto scaling for the wave creatures level, health and damage. 76 | # Note: Disable this if you want to use your own custom npcs so they don't get auto-scaled. 77 | # Default: 0 - Disabled 78 | # 1 - Enabled 79 | # 80 | 81 | TrialOfStrength.AutoScaling = 0 82 | 83 | # 84 | # TrialOfStrength.AutoScaling.BaseHealth 85 | # Description: Controls the base health of creatures in the Trial of Strength waves. 86 | # Note: The formula for the health is: baseHealth * (1.0f + (float(currentWave) / float(healthDivider))); 87 | # Default: 8000 88 | # 89 | 90 | TrialOfStrength.AutoScaling.BaseHealth = 8000 91 | 92 | # 93 | # TrialOfStrength.AutoScaling.HealthDivider 94 | # Description: Controls the base health divider of creatures in the Trial of Strength waves. 95 | # Note: The formula for the health is: baseHealth * (1.0f + (float(currentWave) / float(healthDivider))); 96 | # Increasing/decreasing the value of this setting will change the difficulty between waves. 97 | # Default: 15 98 | # 99 | 100 | TrialOfStrength.AutoScaling.HealthDivider = 15 101 | 102 | # 103 | # TrialOfStrength.AutoScaling.BaseDamage.Physical 104 | # Description: Controls the base damage of creatures physical damage in the Trial of Strength waves. 105 | # Note: The formula for the damage is: baseDamage * (1.0f + (float(currentWave) / float(damageDivider))); 106 | # The damage range is calculated as: damage = urand(newDamage / 2, newDamage); 107 | # Default: 500 108 | # 109 | 110 | TrialOfStrength.AutoScaling.BaseDamage.Physical = 500 111 | 112 | # 113 | # TrialOfStrength.AutoScaling.BaseDamage.PhysicalDivider 114 | # Description: Controls the base damage divider of creatures physical damage in the Trial of Strength waves. 115 | # Note: The formula for the damage is: baseDamage * (1.0f + (float(currentWave) / float(damageDivider))); 116 | # Increasing/decreasing the value of this setting will change the difficulty between waves. 117 | # Default: 15 118 | # 119 | 120 | TrialOfStrength.AutoScaling.BaseDamage.PhysicalDivider = 15 121 | 122 | # 123 | # TrialOfStrength.AutoScaling.BaseDamage.SpellDivider 124 | # Description: Controls the base damage divider of creatures spell damage in the Trial of Strength waves. 125 | # Note: The formula for the damage is: baseDamage * (1.0f + (float(currentWave) / float(damageDivider))); 126 | # Increasing/decreasing the value of this setting will change the difficulty between waves. 127 | # Default: 15 128 | # 129 | 130 | TrialOfStrength.AutoScaling.BaseDamage.SpellDivider = 15 -------------------------------------------------------------------------------- /data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/data/.gitkeep -------------------------------------------------------------------------------- /data/sql/db-auth/base/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/data/sql/db-auth/base/.gitkeep -------------------------------------------------------------------------------- /data/sql/db-auth/updates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/data/sql/db-auth/updates/.gitkeep -------------------------------------------------------------------------------- /data/sql/db-characters/base/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/data/sql/db-characters/base/.gitkeep -------------------------------------------------------------------------------- /data/sql/db-characters/updates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/data/sql/db-characters/updates/.gitkeep -------------------------------------------------------------------------------- /data/sql/db-world/base/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/data/sql/db-world/base/.gitkeep -------------------------------------------------------------------------------- /data/sql/db-world/base/tos_world_base.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM `instance_template` WHERE `map`=44; 2 | INSERT INTO `instance_template` (`map`, `parent`, `script`, `allowMount`) VALUES (44, 0, 'instance_trial_of_strength', 0); 3 | 4 | -- Trial of Strength / Arena Master 5 | DELETE FROM `creature_template` WHERE `entry`=441250; 6 | INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `speed_swim`, `speed_flight`, `detection_range`, `scale`, `rank`, `dmgschool`, `DamageModifier`, `BaseAttackTime`, `RangeAttackTime`, `BaseVariance`, `RangeVariance`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `ExperienceModifier`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `spell_school_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) VALUES (441250, 0, 0, 0, 0, 0, 'Fortichad Ironfist', 'Arena Master', NULL, 0, 80, 80, 0, 35, 3, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 'ToSArenaMasterScript', 1); 7 | 8 | DELETE FROM `creature_template_model` WHERE `CreatureID`=441250 AND `Idx`=0; 9 | INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES (441250, 0, 18039, 1, 1, 1); 10 | 11 | -- Trial of Strength / Arena Spectator 12 | DELETE FROM `creature_template` WHERE `entry`=441253; 13 | INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `speed_swim`, `speed_flight`, `detection_range`, `scale`, `rank`, `dmgschool`, `DamageModifier`, `BaseAttackTime`, `RangeAttackTime`, `BaseVariance`, `RangeVariance`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `ExperienceModifier`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `spell_school_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) VALUES (441253, 0, 0, 0, 0, 0, 'Arena Spectator', NULL, NULL, 0, 78, 80, 0, 35, 0, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'NullCreatureAI', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 'ToSAIArenaSpectator', 1); 14 | 15 | DELETE FROM `creature_template_model` WHERE `CreatureID`=441253 AND `Idx`=0; 16 | INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES (441253, 0, 1485, 1, 1, 1); 17 | DELETE FROM `creature_template_model` WHERE `CreatureID`=441253 AND `Idx`=1; 18 | INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES (441253, 1, 3606, 1, 1, 1); 19 | DELETE FROM `creature_template_model` WHERE `CreatureID`=441253 AND `Idx`=2; 20 | INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES (441253, 2, 4123, 1, 1, 1); 21 | DELETE FROM `creature_template_model` WHERE `CreatureID`=441253 AND `Idx`=3; 22 | INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES (441253, 3, 2224, 1, 1, 1); 23 | 24 | DELETE FROM `npc_text` WHERE `ID`=441250; 25 | INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES (441250, 'Greetings, $n.|n|nI am the Arena Master for the Trial of Strength.|n|nIf you seek to test your abilities, then I can transport you to the arena.|n|nAre you ready to face the challenges that lie ahead?', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); 26 | DELETE FROM `npc_text` WHERE `ID`=441251; 27 | INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES (441251, 'Welcome $n, are you ready to start the Trial of Strength?|n|nYou only need one entry ticket to start the encounter.', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); 28 | DELETE FROM `npc_text` WHERE `ID`=441252; 29 | INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES (441252, 'You must finish the current trial before speaking to me again.', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); 30 | DELETE FROM `npc_text` WHERE `ID`=441253; 31 | INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES (441253, 'Are you ready for the next trial?', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); 32 | DELETE FROM `npc_text` WHERE `ID`=441254; 33 | INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES (441254, 'Congratulations, $n!|n|nYou have triumphed in the Trial of Strength, proving your mettle and determination. Your strength and skill have shone brightly, and your name will be celebrated in the annals of our arena\'s history.|n|nWhat would you like to do now?', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); 34 | DELETE FROM `npc_text` WHERE `ID`=441255; 35 | INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES (441255, 'You are not skilled enough to enter the Trial of Strength, come back later!', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); 36 | DELETE FROM `npc_text` WHERE `ID`=441256; 37 | INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES (441256, 'I\'m sorry, you do not have a valid ticket to start the encounter.|n|nCome back later when you have acquired an entry ticket.', NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); 38 | 39 | DELETE FROM `gameobject_template` WHERE `entry`=441250; 40 | INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `IconName`, `castBarCaption`, `unk1`, `size`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `Data8`, `Data9`, `Data10`, `Data11`, `Data12`, `Data13`, `Data14`, `Data15`, `Data16`, `Data17`, `Data18`, `Data19`, `Data20`, `Data21`, `Data22`, `Data23`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES (441250, 3, 259, 'Arena Master\'s Lootbox', '', '', '', 1.25, 57, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 1); 41 | 42 | DELETE FROM `gameobject_template` WHERE `entry`=441251; 43 | INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `IconName`, `castBarCaption`, `unk1`, `size`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `Data8`, `Data9`, `Data10`, `Data11`, `Data12`, `Data13`, `Data14`, `Data15`, `Data16`, `Data17`, `Data18`, `Data19`, `Data20`, `Data21`, `Data22`, `Data23`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES (441251, 5, 3272, 'Arena Master\'s Lootbox Beam', '', '', '', 0.5, 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); 44 | 45 | DELETE FROM `gameobject_template` WHERE `entry`=441252; 46 | INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `IconName`, `castBarCaption`, `unk1`, `size`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `Data8`, `Data9`, `Data10`, `Data11`, `Data12`, `Data13`, `Data14`, `Data15`, `Data16`, `Data17`, `Data18`, `Data19`, `Data20`, `Data21`, `Data22`, `Data23`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES (441252, 2, 327, 'Curse Crystal', '', '', '', 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, '', 'ToSCurseCrystalScript', 1); 47 | 48 | DELETE FROM `gameobject_template` WHERE `entry`=441350; 49 | INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `IconName`, `castBarCaption`, `unk1`, `size`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `Data8`, `Data9`, `Data10`, `Data11`, `Data12`, `Data13`, `Data14`, `Data15`, `Data16`, `Data17`, `Data18`, `Data19`, `Data20`, `Data21`, `Data22`, `Data23`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES (441350, 5, 5975, 'WestfallTree1', '', '', '', 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, '', '', 1); 50 | 51 | DELETE FROM `gameobject_template` WHERE `entry`=441352; 52 | INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `IconName`, `castBarCaption`, `unk1`, `size`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `Data8`, `Data9`, `Data10`, `Data11`, `Data12`, `Data13`, `Data14`, `Data15`, `Data16`, `Data17`, `Data18`, `Data19`, `Data20`, `Data21`, `Data22`, `Data23`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES (441352, 5, 7148, 'ToSArenaPortal', '', '', '', 0.85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', NULL); 53 | 54 | DELETE FROM `gameobject_template` WHERE `entry`=441353; 55 | INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `IconName`, `castBarCaption`, `unk1`, `size`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `Data8`, `Data9`, `Data10`, `Data11`, `Data12`, `Data13`, `Data14`, `Data15`, `Data16`, `Data17`, `Data18`, `Data19`, `Data20`, `Data21`, `Data22`, `Data23`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES (441353, 5, 6815, 'ToSStatue1', '', '', '', 1.25, 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); 56 | 57 | DELETE FROM `item_template` WHERE `entry`=25747; 58 | INSERT INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `stat_type1`, `stat_value1`, `stat_type2`, `stat_value2`, `stat_type3`, `stat_value3`, `stat_type4`, `stat_value4`, `stat_type5`, `stat_value5`, `stat_type6`, `stat_value6`, `stat_type7`, `stat_value7`, `stat_type8`, `stat_value8`, `stat_type9`, `stat_value9`, `stat_type10`, `stat_value10`, `ScalingStatDistribution`, `ScalingStatValue`, `dmg_min1`, `dmg_max1`, `dmg_type1`, `dmg_min2`, `dmg_max2`, `dmg_type2`, `armor`, `holy_res`, `fire_res`, `nature_res`, `frost_res`, `shadow_res`, `arcane_res`, `delay`, `ammo_type`, `RangedModRange`, `spellid_1`, `spelltrigger_1`, `spellcharges_1`, `spellppmRate_1`, `spellcooldown_1`, `spellcategory_1`, `spellcategorycooldown_1`, `spellid_2`, `spelltrigger_2`, `spellcharges_2`, `spellppmRate_2`, `spellcooldown_2`, `spellcategory_2`, `spellcategorycooldown_2`, `spellid_3`, `spelltrigger_3`, `spellcharges_3`, `spellppmRate_3`, `spellcooldown_3`, `spellcategory_3`, `spellcategorycooldown_3`, `spellid_4`, `spelltrigger_4`, `spellcharges_4`, `spellppmRate_4`, `spellcooldown_4`, `spellcategory_4`, `spellcategorycooldown_4`, `spellid_5`, `spelltrigger_5`, `spellcharges_5`, `spellppmRate_5`, `spellcooldown_5`, `spellcategory_5`, `spellcategorycooldown_5`, `bonding`, `description`, `PageText`, `LanguageID`, `PageMaterial`, `startquest`, `lockid`, `Material`, `sheath`, `RandomProperty`, `RandomSuffix`, `block`, `itemset`, `MaxDurability`, `area`, `Map`, `BagFamily`, `TotemCategory`, `socketColor_1`, `socketContent_1`, `socketColor_2`, `socketContent_2`, `socketColor_3`, `socketContent_3`, `socketBonus`, `GemProperties`, `RequiredDisenchantSkill`, `ArmorDamageModifier`, `duration`, `ItemLimitCategory`, `HolidayId`, `ScriptName`, `DisenchantID`, `FoodType`, `minMoneyLoot`, `maxMoneyLoot`, `flagsCustom`, `VerifiedBuild`) VALUES (25747, 12, 0, -1, 'Entry Ticket', 8927, 3, 0, 0, 1, 0, 0, 0, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 'Fortichad Ironfist would take interest in this item in the Trial of Strength.', 0, 0, 0, 0, 0, -1, 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, 1); 59 | 60 | 61 | CREATE TABLE IF NOT EXISTS `tos_reward_template` ( 62 | `id` int DEFAULT NULL, 63 | `item_entry` int DEFAULT '0', 64 | `count_min` int DEFAULT '1', 65 | `count_max` int DEFAULT '1', 66 | `count_cap` int DEFAULT NULL, 67 | `chance` float DEFAULT '100', 68 | `curse_scalar` float DEFAULT '0', 69 | `note` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' 70 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 71 | 72 | 73 | DELETE FROM `tos_reward_template`; 74 | INSERT INTO `tos_reward_template` (`id`, `item_entry`, `count_min`, `count_max`, `count_cap`, `chance`, `curse_scalar`, `note`) VALUES (1, 21215, 5, 10, 20, 50, 0, 'Graccu\'s Fruitcake'); 75 | INSERT INTO `tos_reward_template` (`id`, `item_entry`, `count_min`, `count_max`, `count_cap`, `chance`, `curse_scalar`, `note`) VALUES (1, 37711, 250, 300, 500, 100, 0, 'Test Currency 1'); 76 | 77 | 78 | CREATE TABLE IF NOT EXISTS `tos_wave_groups` ( 79 | `id` int NOT NULL, 80 | `group` int DEFAULT NULL, 81 | `sub_group` int DEFAULT NULL, 82 | `creature` int DEFAULT NULL, 83 | `note` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 84 | PRIMARY KEY (`id`) 85 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 86 | 87 | 88 | CREATE TABLE IF NOT EXISTS `tos_wave_template` ( 89 | `wave` int DEFAULT NULL, 90 | `enemy_group` int DEFAULT NULL, 91 | `has_reward` tinyint DEFAULT NULL, 92 | `reward_template` int DEFAULT NULL 93 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 94 | 95 | 96 | CREATE TABLE IF NOT EXISTS `tos_curse_template` ( 97 | `id` int DEFAULT NULL, 98 | `type` int DEFAULT NULL, 99 | `difficulty` int DEFAULT NULL, 100 | `aura` int DEFAULT NULL, 101 | `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 102 | `description` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL 103 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 104 | 105 | DELETE FROM `tos_curse_template`; 106 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (1, 0, 50, 68335, 'Enrage', 'Combatants are enraged, increasing their damage by 50%.'); 107 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (2, 0, 100, 29476, 'Astral Armor', 'Combatants are protected, decreasing the damage they receive by 90%.'); 108 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (3, 1, 60, 34102, 'Curse of the Violet Tower', 'Players are weakened, dealing 50% less damage.'); 109 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (4, 0, 75, 34337, 'Armored Skin', 'Combatants skin have been strengthened, taking 75% less physical damage.'); 110 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (5, 0, 0, 45673, 'Bigger!', 'Combatants are 15-25 percent larger!'); 111 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (6, 0, 20, 45444, 'Hot Hands', 'Combatants have bonfire\'s blessing, infusing their attacks with flame.'); 112 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (7, 1, 50, 69127, 'Chill of the Throne', 'Players have a 20% reduced chance to dodge.'); 113 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (8, 1, 10, 41631, 'Cold Feet', 'Players have a 20% reduced movement speed.'); 114 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (9, 0, 10, 41630, 'Hot Feet', 'Combatants have a 30% increased movement speed.'); 115 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (10, 0, 50, 64193, 'Heart Broken', 'Combatants have 15% increased damage and 60% increased health.'); 116 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (11, 1, 0, 45672, 'Shorter!', 'Players are 45-75 percent smaller!'); 117 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (12, 0, 20, 33795, 'Strength of Halaa', 'Combatants have 5% increased damage.'); 118 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (13, 0, 100, 58361, 'Might of Mograine', 'Combatants have 500% increased damage, 15000% increased health and 25% of health is regenerated every 2 seconds.'); 119 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (14, 0, 20, 33779, 'Twin Spire Blessing', 'Combatants have 5% increased damage.'); 120 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (15, 0, 100, 69491, 'Aura of Darkness', 'Combatants are consumed by darkness, radiating very high shadow damage every 2 seconds.'); 121 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (16, 0, 50, 25820, 'Fearful', 'Combatants have a 10% chance when taking damage to fear players.'); 122 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (17, 0, 30, 39444, 'Vengeance', 'Combatants have a 10% chance when taking damage to deal holy damage to the player.'); 123 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (18, 1, 60, 35500, 'Dampened', 'Players have 50% reduced maximum health and 50% increased mana cost of spells.'); 124 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (19, 0, 60, 31317, 'Vampiric', 'Combatants melee attacks heal for 300% of the damage.'); 125 | INSERT INTO `tos_curse_template` (`id`, `type`, `difficulty`, `aura`, `name`, `description`) VALUES (20, 0, 20, 39007, 'Lesser Immolation', 'Combatants are engulfed in flame, emitting low amounts of fire damage every 2 seconds.'); 126 | 127 | 128 | 129 | DELETE FROM `gameobject` WHERE map = 44; 130 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (180322, 44, 0, 0, 1, 1, 184.504, -109.872, 18.6773, 1.57865, -0, -0, -0.709877, -0.704325, 300, 0, 1, '', NULL, NULL); 131 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (187333, 44, 0, 0, 1, 1, 174.213, -137.483, 18.0228, 4.58435, -0, -0, -0.750895, 0.660421, 300, 0, 1, '', NULL, NULL); 132 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (187333, 44, 0, 0, 1, 1, 179.901, -125.052, 18.0228, 1.57627, -0, -0, -0.709041, -0.705168, 300, 0, 1, '', NULL, NULL); 133 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (441350, 44, 0, 0, 1, 1, 184.978, -127.535, 18.3479, 3.81323, -0, -0, -0.94414, 0.329544, 300, 0, 1, '', NULL, NULL); 134 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (180322, 44, 0, 0, 1, 1, 233.074, -100.053, 18.6777, 3.15535, -0, -0, -0.999976, 0.00687944, 300, 0, 1, '', NULL, NULL); 135 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195597, 44, 0, 0, 1, 1, 290.199, -100.049, 31.4936, 3.12237, -0, -0, -0.999954, -0.00961285, 300, 0, 1, '', NULL, NULL); 136 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195597, 44, 0, 0, 1, 1, 184.555, -109.506, 18.6773, 1.57721, -0, -0, -0.709369, -0.704837, 300, 0, 1, '', NULL, NULL); 137 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (164882, 44, 0, 0, 1, 1, 182.049, -125.522, 18.1433, 0.711694, -0, -0, -0.348384, -0.937352, 300, 0, 1, '', NULL, NULL); 138 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (1798, 44, 0, 0, 1, 1, 180.045, -131.558, 18.0228, 0.556973, -0, -0, -0.274901, -0.961473, 300, 0, 1, '', NULL, NULL); 139 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (189773, 44, 0, 0, 1, 1, 182.696, -125.131, 18.1489, 4.67089, -0, -0, -0.721626, 0.692283, 300, 0, 1, '', NULL, NULL); 140 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (211064, 44, 0, 0, 1, 1, 173.782, -131.44, 18.0234, 3.68207, -0, -0, -0.963707, 0.266962, 300, 0, 1, '', NULL, NULL); 141 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (211064, 44, 0, 0, 1, 1, 185.838, -138.786, 18.0228, 1.73193, -0, -0, -0.76172, -0.647907, 300, 0, 1, '', NULL, NULL); 142 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (61095, 44, 0, 0, 1, 1, 182.546, -130.531, 18.1014, 3.52656, -0, -0, -0.981532, 0.191298, 300, 0, 1, '', NULL, NULL); 143 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (61095, 44, 0, 0, 1, 1, 181.021, -129.44, 18.057, 4.48239, -0, -0, -0.783574, 0.621299, 300, 0, 1, '', NULL, NULL); 144 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (441352, 44, 0, 0, 1, 1, 187.423, -135.424, 18.538, 6.27128, -0, -0, -0.0059525, 0.999982, 300, 0, 1, '', NULL, NULL); 145 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (191615, 44, 0, 0, 1, 1, 255.373, -113.244, 18.6794, 1.56307, -0, -0, -0.704372, -0.709832, 300, 0, 1, '', NULL, NULL); 146 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (191615, 44, 0, 0, 1, 1, 252.502, -109.632, 18.6794, 2.83542, -0, -0, -0.988305, -0.152488, 300, 0, 1, '', NULL, NULL); 147 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (191615, 44, 0, 0, 1, 1, 255.468, -86.7371, 18.6794, 1.57093, -0, -0, -0.707153, -0.707061, 300, 0, 1, '', NULL, NULL); 148 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (191615, 44, 0, 0, 1, 1, 252.791, -90.2202, 18.6794, 0.18077, -0, -0, -0.0902622, -0.995918, 300, 0, 1, '', NULL, NULL); 149 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (441353, 44, 0, 0, 1, 1, 241.797, -99.9193, 23.7741, 6.27939, -0, -0, -0.0018995, 0.999998, 300, 0, 1, '', NULL, NULL); 150 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 239.128, -108.483, 23.7741, 0.54509, -0, -0, -0.269183, -0.963089, 300, 0, 1, '', NULL, NULL); 151 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 241.136, -111.455, 23.7742, 0.796417, -0, -0, -0.387768, -0.921757, 300, 0, 1, '', NULL, NULL); 152 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 242.857, -113.302, 23.7742, 0.796417, -0, -0, -0.387768, -0.921757, 300, 0, 1, '', NULL, NULL); 153 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 246.068, -114.791, 23.7742, 1.17027, -0, -0, -0.552311, -0.833638, 300, 0, 1, '', NULL, NULL); 154 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 248.064, -116.37, 23.7742, 0.953497, -0, -0, -0.458893, -0.888492, 300, 0, 1, '', NULL, NULL); 155 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 251.437, -117.301, 23.7742, 1.45929, -0, -0, -0.666606, -0.74541, 300, 0, 1, '', NULL, NULL); 156 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 255.862, -117.6, 24.1721, 1.61243, -0, -0, -0.721671, -0.692236, 300, 0, 1, '', NULL, NULL); 157 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 259.085, -117.311, 24.763, 1.81977, -0, -0, -0.789434, -0.613836, 300, 0, 1, '', NULL, NULL); 158 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 261.923, -116.563, 25.3607, 1.75694, -0, -0, -0.769763, -0.63833, 300, 0, 1, '', NULL, NULL); 159 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 264.731, -115.293, 25.9859, 2.12215, -0, -0, -0.872881, -0.487934, 300, 0, 1, '', NULL, NULL); 160 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 267.259, -112.944, 26.6915, 2.30907, -0, -0, -0.914608, -0.404342, 300, 0, 1, '', NULL, NULL); 161 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 269.084, -110.878, 27.253, 2.37583, -0, -0, -0.927593, -0.373593, 300, 0, 1, '', NULL, NULL); 162 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 269.047, -89.4085, 27.2794, 3.79348, -0, -0, -0.947349, 0.320204, 300, 0, 1, '', NULL, NULL); 163 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 267.364, -86.8026, 26.6438, 3.97412, -0, -0, -0.914605, 0.404347, 300, 0, 1, '', NULL, NULL); 164 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 264.634, -85.2402, 26.0047, 4.06444, -0, -0, -0.89542, 0.445223, 300, 0, 1, '', NULL, NULL); 165 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 261.905, -83.6527, 25.3464, 4.28827, -0, -0, -0.840094, 0.542441, 300, 0, 1, '', NULL, NULL); 166 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 258.929, -82.7403, 24.7012, 4.66449, -0, -0, -0.723838, 0.68997, 300, 0, 1, '', NULL, NULL); 167 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 255.896, -82.6158, 24.1629, 4.56632, -0, -0, -0.75682, 0.653623, 300, 0, 1, '', NULL, NULL); 168 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 251.421, -83.0151, 23.7743, 4.84121, -0, -0, -0.660127, 0.751154, 300, 0, 1, '', NULL, NULL); 169 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 248.293, -83.7262, 23.7742, 5.12788, -0, -0, -0.54606, 0.837746, 300, 0, 1, '', NULL, NULL); 170 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 245.891, -85.4046, 23.7742, 5.36742, -0, -0, -0.442049, 0.896991, 300, 0, 1, '', NULL, NULL); 171 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 243.248, -86.9934, 23.7742, 5.51272, -0, -0, -0.375773, 0.926712, 300, 0, 1, '', NULL, NULL); 172 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 241.044, -89.4855, 23.7742, 5.73656, -0, -0, -0.269924, 0.962882, 300, 0, 1, '', NULL, NULL); 173 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195418, 44, 0, 0, 1, 1, 239.486, -91.689, 23.7742, 5.691, -0, -0, -0.291786, 0.956484, 300, 0, 1, '', NULL, NULL); 174 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (180769, 44, 0, 0, 1, 1, 184.518, -121.014, 24.0744, 1.57325, -0, -0, -0.707975, -0.706237, 300, 0, 1, '', NULL, NULL); 175 | INSERT INTO `gameobject` (`id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES (195682, 44, 0, 0, 1, 1, 184.581, -116.498, 18.6774, 6.26992, -0, -0, -0.00663277, 0.999978, 300, 0, 1, '', NULL, NULL); 176 | 177 | DELETE FROM `creature` WHERE map = 44; 178 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 268.385, -89.8077, 27.2666, 3.78491, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 179 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 266.762, -87.5566, 26.6673, 3.98911, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 180 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 264.212, -85.9387, 26.0172, 4.17761, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 181 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 261.568, -84.4885, 25.3572, 4.33469, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 182 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 258.828, -83.6611, 24.7333, 4.54281, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 183 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 255.946, -83.3944, 24.1761, 4.68418, 300, 0, 0, 5194, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 184 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 268.54, -110.237, 27.285, 2.48114, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 185 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 266.636, -112.41, 26.6614, 2.27301, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 186 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 264.375, -114.227, 26.0362, 2.10808, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 187 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 261.703, -115.56, 25.3915, 1.96671, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 188 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 258.843, -116.468, 24.7421, 1.8489, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 189 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 255.893, -116.827, 24.1763, 1.62113, 300, 0, 0, 5194, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 190 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 251.451, -116.154, 23.7742, 1.40751, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 191 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 248.733, -115.43, 23.7742, 1.12477, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 192 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 246.308, -114.005, 23.7742, 1.01481, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 193 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 243.981, -112.169, 23.7742, 0.849881, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 194 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 242.107, -110.232, 23.7742, 0.673166, 300, 0, 0, 5194, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 195 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 251.447, -83.6958, 23.7742, 4.96144, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 196 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 248.695, -84.6653, 23.7742, 5.10674, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 197 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 246.16, -85.7946, 23.7742, 5.27559, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 198 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 243.84, -87.5796, 23.7742, 5.47194, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 199 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 241.798, -89.849, 23.7742, 5.68399, 300, 0, 0, 5194, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 200 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 240.368, -107.711, 23.7742, 0.492525, 300, 0, 0, 5052, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 201 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441253, 0, 0, 44, 0, 0, 1, 1, 0, 240.308, -92.1951, 23.7742, 5.77433, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 202 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (441250, 0, 0, 44, 0, 0, 1, 1, 0, 249.918, -100.064, 18.6794, 0.0307553, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 203 | INSERT INTO `creature` (`id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES (24780, 0, 0, 44, 0, 0, 1, 1, 0, 185.805, -131.234, 18.043, 3.68755, 300, 0, 0, 12150, 0, 0, 0, 0, 0, '', NULL, 0, NULL); 204 | 205 | 206 | DELETE FROM `tos_wave_template` WHERE `wave`=1 AND `enemy_group`=1 AND `has_reward`=1 AND `reward_template`=1; 207 | INSERT INTO `tos_wave_template` (`wave`, `enemy_group`, `has_reward`, `reward_template`) VALUES (1, 1, 1, 1); 208 | DELETE FROM `tos_wave_template` WHERE `wave`=2 AND `enemy_group`=2 AND `has_reward`=1 AND `reward_template`=1; 209 | INSERT INTO `tos_wave_template` (`wave`, `enemy_group`, `has_reward`, `reward_template`) VALUES (2, 2, 1, 1); 210 | DELETE FROM `tos_wave_template` WHERE `wave`=3 AND `enemy_group`=3 AND `has_reward`=1 AND `reward_template`=1; 211 | INSERT INTO `tos_wave_template` (`wave`, `enemy_group`, `has_reward`, `reward_template`) VALUES (3, 3, 1, 1); 212 | DELETE FROM `tos_wave_template` WHERE `wave`=4 AND `enemy_group`=4 AND `has_reward`=1 AND `reward_template`=1; 213 | INSERT INTO `tos_wave_template` (`wave`, `enemy_group`, `has_reward`, `reward_template`) VALUES (4, 4, 1, 1); 214 | 215 | 216 | DELETE FROM `tos_wave_groups` WHERE `id`=101; 217 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (101, 1, 1, 33537, 'G1 - Cult of the Damned - Cult Conspirator'); 218 | DELETE FROM `tos_wave_groups` WHERE `id`=102; 219 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (102, 1, 1, 31145, 'G1 - Cult of the Damned - Shadow Adept'); 220 | DELETE FROM `tos_wave_groups` WHERE `id`=103; 221 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (103, 1, 1, 33537, 'G1 - Cult of the Damned - Cult Conspirator'); 222 | DELETE FROM `tos_wave_groups` WHERE `id`=104; 223 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (104, 1, 2, 33537, 'G1 - Cult of the Damned - Cult Conspirator'); 224 | DELETE FROM `tos_wave_groups` WHERE `id`=105; 225 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (105, 1, 2, 34728, 'G1 - Cult of the Damned - Dark Zealot'); 226 | DELETE FROM `tos_wave_groups` WHERE `id`=106; 227 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (106, 1, 2, 32349, 'G1 - Cult of the Damned - Cultist Shard Watcher'); 228 | DELETE FROM `tos_wave_groups` WHERE `id`=107; 229 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (107, 1, 3, 33695, 'G1 - Cult of the Damned - Cultist Bombardier'); 230 | DELETE FROM `tos_wave_groups` WHERE `id`=201; 231 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (201, 2, 1, 31812, 'G2 - Plague Army - Decomposed Ghoul'); 232 | DELETE FROM `tos_wave_groups` WHERE `id`=202; 233 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (202, 2, 1, 31813, 'G2 - Plague Army - Frostskull Magus'); 234 | DELETE FROM `tos_wave_groups` WHERE `id`=203; 235 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (203, 2, 1, 31812, 'G2 - Plague Army - Decomposed Ghoul'); 236 | DELETE FROM `tos_wave_groups` WHERE `id`=204; 237 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (204, 2, 2, 32770, 'G2 - Plague Army - Enraged Fleshrender'); 238 | DELETE FROM `tos_wave_groups` WHERE `id`=205; 239 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (205, 2, 3, 16037, 'G2 - Plague Army - Plague Bat'); 240 | DELETE FROM `tos_wave_groups` WHERE `id`=206; 241 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (206, 2, 4, 27734, 'G2 - Plague Army - Crypt Fiend'); 242 | DELETE FROM `tos_wave_groups` WHERE `id`=301; 243 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (301, 3, 1, 31254, 'G3 - Old Lordaeron - Lordaeron Footsoldier'); 244 | DELETE FROM `tos_wave_groups` WHERE `id`=302; 245 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (302, 3, 1, 32414, 'G3 - Old Lordaeron - Lordaeron Captain'); 246 | DELETE FROM `tos_wave_groups` WHERE `id`=303; 247 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (303, 3, 1, 31254, 'G3 - Old Lordaeron - Lordaeron Footsoldier'); 248 | DELETE FROM `tos_wave_groups` WHERE `id`=304; 249 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (304, 3, 2, 27745, 'G3 - Old Lordaeron - Lordaeron Footman'); 250 | DELETE FROM `tos_wave_groups` WHERE `id`=305; 251 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (305, 3, 2, 27746, 'G3 - Old Lordaeron - Lordaeron Knight'); 252 | DELETE FROM `tos_wave_groups` WHERE `id`=306; 253 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (306, 3, 3, 26499, 'G3 - Old Lordaeron - Arthas'); 254 | DELETE FROM `tos_wave_groups` WHERE `id`=307; 255 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (307, 3, 3, 27747, 'G3 - Old Lordaeron - High Elf Mage-Priest'); 256 | DELETE FROM `tos_wave_groups` WHERE `id`=401; 257 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (401, 4, 1, 27744, 'G4 - Infinite Dragonflight - Infinite Agent'); 258 | DELETE FROM `tos_wave_groups` WHERE `id`=402; 259 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (402, 4, 2, 27743, 'G4 - Infinite Dragonflight - Infinite Hunter'); 260 | DELETE FROM `tos_wave_groups` WHERE `id`=403; 261 | INSERT INTO `tos_wave_groups` (`id`, `group`, `sub_group`, `creature`, `note`) VALUES (403, 4, 3, 27742, 'G4 - Infinite Dragonflight - Infinite Adversary'); 262 | 263 | -------------------------------------------------------------------------------- /data/sql/db-world/updates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/data/sql/db-world/updates/.gitkeep -------------------------------------------------------------------------------- /include.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AnchyDev/TrialOfStrength/7ff2b12f17bec5977ffd21185b6ccbadaf9b9313/include.sh -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Changes Proposed: 4 | - 5 | - 6 | 7 | ## Issues Addressed: 8 | 9 | - Closes 10 | 11 | ## SOURCE: 12 | 13 | 14 | ## Tests Performed: 15 | 16 | - 17 | - 18 | 19 | 20 | ## How to Test the Changes: 21 | 22 | 23 | 1. 24 | 2. 25 | 3. 26 | -------------------------------------------------------------------------------- /src/MP_loader.cpp: -------------------------------------------------------------------------------- 1 | void SC_AddTrialOfStrengthScripts(); 2 | 3 | void AddTrialOfStrengthScripts() 4 | { 5 | SC_AddTrialOfStrengthScripts(); 6 | } 7 | -------------------------------------------------------------------------------- /src/ToSMapMgr.cpp: -------------------------------------------------------------------------------- 1 | #include "ToSMapMgr.h" 2 | 3 | std::string ToSMapManager::GetHexColorFromClass(uint8 classId) 4 | { 5 | switch (classId) 6 | { 7 | case CLASS_DEATH_KNIGHT: 8 | return "|cffFC2A43"; 9 | case CLASS_HUNTER: 10 | return "|cffAAD174"; 11 | case CLASS_PALADIN: 12 | return "|cffF28CBC"; 13 | case CLASS_ROGUE: 14 | return "|cffFEF262"; 15 | case CLASS_WARLOCK: 16 | return "|cff9A81C2"; 17 | case CLASS_DRUID: 18 | return "|cffF67404"; 19 | case CLASS_MAGE: 20 | return "|cff70C9F1"; 21 | case CLASS_PRIEST: 22 | return "|cffF5F3F6"; 23 | case CLASS_SHAMAN: 24 | return "|cff05D7BA"; 25 | case CLASS_WARRIOR: 26 | return "|cffC9A074"; 27 | } 28 | 29 | return "|cffFFFFFF"; 30 | } 31 | 32 | std::string ToSMapManager::GetDifficultyString(uint32 difficulty) 33 | { 34 | std::stringstream ss; 35 | 36 | ss << ((difficulty >= 0) ? TOS_ICON_CROWN : TOS_ICON_CROWN_BW); 37 | ss << ((difficulty >= 20) ? TOS_ICON_CROWN : TOS_ICON_CROWN_BW); 38 | ss << ((difficulty >= 40) ? TOS_ICON_CROWN : TOS_ICON_CROWN_BW); 39 | ss << ((difficulty >= 60) ? TOS_ICON_CROWN : TOS_ICON_CROWN_BW); 40 | ss << ((difficulty >= 80) ? TOS_ICON_CROWN : TOS_ICON_CROWN_BW); 41 | 42 | return ss.str(); 43 | } 44 | 45 | std::vector ToSMapManager::GetCurses() 46 | { 47 | std::vector curses; 48 | 49 | for (auto curse : CurseTemplates) 50 | { 51 | curses.push_back(curse.second); 52 | } 53 | 54 | return curses; 55 | } 56 | 57 | void ToSMapManager::ClearCurses(Unit* unit) 58 | { 59 | if (!unit) 60 | { 61 | return; 62 | } 63 | 64 | for (auto const& curse : sToSMapMgr->GetCurses()) 65 | { 66 | if (unit->HasAura(curse.aura)) 67 | { 68 | unit->RemoveAura(curse.aura); 69 | } 70 | } 71 | } 72 | 73 | ToSCurseTemplate* ToSMapManager::GetCurseById(uint32 curseId) 74 | { 75 | auto it = CurseTemplates.find(curseId); 76 | if (it == CurseTemplates.end()) 77 | { 78 | return nullptr; 79 | } 80 | 81 | return &it->second; 82 | } 83 | 84 | ToSWaveTemplate* ToSMapManager::GetWaveTemplateForWave(uint32 wave) 85 | { 86 | auto it = WaveTemplates.find(wave); 87 | if (it == WaveTemplates.end()) 88 | { 89 | return nullptr; 90 | } 91 | 92 | return &it->second; 93 | } 94 | 95 | uint32 ToSMapManager::GetTotalWaves() 96 | { 97 | return WaveTemplates.size(); 98 | } 99 | 100 | std::vector ToSMapManager::GetEnemiesFromGroup(uint32 groupId, uint32 subGroup) 101 | { 102 | std::vector groups; 103 | 104 | for (auto it = EnemyGroups.begin(); it != EnemyGroups.end(); ++it) 105 | { 106 | if (it->second.group == groupId && 107 | it->second.subGroup == subGroup) 108 | { 109 | groups.push_back(&it->second); 110 | } 111 | } 112 | 113 | return groups; 114 | } 115 | 116 | uint32 ToSMapManager::GetEnemyCountForGroup(uint32 groupId) 117 | { 118 | uint32 count = 0; 119 | 120 | for (auto it = EnemyGroups.begin(); it != EnemyGroups.end(); ++it) 121 | { 122 | if (it->second.group == groupId) 123 | { 124 | count++; 125 | } 126 | } 127 | 128 | return count; 129 | } 130 | 131 | std::vector ToSMapManager::GetSubGroups(uint32 groupId) 132 | { 133 | std::vector subgroups; 134 | 135 | for (auto it = EnemyGroups.begin(); it != EnemyGroups.end(); ++it) 136 | { 137 | if (it->second.group == groupId) 138 | { 139 | uint32 subgroup = it->second.subGroup; 140 | 141 | auto it = std::find(subgroups.begin(), subgroups.end(), subgroup); 142 | if (it != subgroups.end()) 143 | { 144 | continue; 145 | } 146 | 147 | subgroups.push_back(subgroup); 148 | } 149 | } 150 | 151 | return subgroups; 152 | } 153 | 154 | std::vector* ToSMapManager::GetRewardTemplates(uint32 rewardId) 155 | { 156 | auto it = RewardTemplates.find(rewardId); 157 | if (it == RewardTemplates.end()) 158 | { 159 | return nullptr; 160 | } 161 | 162 | return &it->second; 163 | } 164 | 165 | Creature* ToSMapManager::SpawnNPC(uint32 entry, Map* map, Position* position) 166 | { 167 | if (!map || !position) 168 | { 169 | return nullptr; 170 | } 171 | 172 | if (!sObjectMgr->GetCreatureTemplate(entry)) 173 | { 174 | return nullptr; 175 | } 176 | 177 | return map->SummonCreature(entry, *position); 178 | } 179 | 180 | double ToSMapManager::LinearDistribution(double min, double max, double count, double index) 181 | { 182 | double total = abs(min) + abs(max); 183 | 184 | double amount = total / count; 185 | 186 | return (min + (amount * index) + (amount / 2.0)); 187 | } 188 | 189 | void ToSMapManager::ResetCooldowns(Player* player) 190 | { 191 | if (!player) 192 | { 193 | return; 194 | } 195 | 196 | player->RemoveAllSpellCooldown(); 197 | } 198 | 199 | bool ToSMapManager::CanPlayerEnter(Player* player) 200 | { 201 | if (!player) 202 | { 203 | return false; 204 | } 205 | 206 | if (player->GetLevel() < 80) 207 | { 208 | return false; 209 | } 210 | 211 | return true; 212 | } 213 | -------------------------------------------------------------------------------- /src/ToSMapMgr.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULE_TRIAL_OF_STRENGTH_MAP_MGR_H 2 | #define MODULE_TRIAL_OF_STRENGTH_MAP_MGR_H 3 | 4 | #include "TrialOfStrength.h" 5 | 6 | #include 7 | 8 | class ToSMapManager 9 | { 10 | private: 11 | ToSMapManager() { } 12 | public: 13 | static ToSMapManager* GetInstance() 14 | { 15 | if (!instance) 16 | { 17 | instance = new ToSMapManager(); 18 | } 19 | 20 | return instance; 21 | } 22 | 23 | std::string GetHexColorFromClass(uint8 classId); 24 | std::string GetDifficultyString(uint32 difficulty); 25 | std::vector GetCurses(); 26 | void ClearCurses(Unit* unit); 27 | ToSCurseTemplate* GetCurseById(uint32 curseId); 28 | ToSWaveTemplate* GetWaveTemplateForWave(uint32 wave); 29 | uint32 GetTotalWaves(); 30 | std::vector GetEnemiesFromGroup(uint32 groupId, uint32 subGroup); 31 | uint32 GetEnemyCountForGroup(uint32 groupId); 32 | std::vector* GetRewardTemplates(uint32 rewardId); 33 | std::vector GetSubGroups(uint32 groupId); 34 | Creature* SpawnNPC(uint32 entry, Map* map, Position* position); 35 | double LinearDistribution(double min, double max, double count, double index); 36 | void ResetCooldowns(Player* player); 37 | bool CanPlayerEnter(Player* player); 38 | public: 39 | std::unordered_map WaveTemplates; 40 | std::unordered_map EnemyGroups; 41 | std::unordered_map> RewardTemplates; 42 | std::unordered_map CurseTemplates; 43 | 44 | const std::string TOS_ICON_CROWN = "|TInterface\\LFGFrame\\LFGROLE:16:16:::64:16:0:16:0:16|t"; 45 | const std::string TOS_ICON_CROWN_BW = "|TInterface\\LFGFrame\\LFGROLE_BW:16:16:::64:16:0:16:0:16|t"; 46 | private: 47 | inline static ToSMapManager* instance; 48 | }; 49 | 50 | #define sToSMapMgr ToSMapManager::GetInstance() 51 | 52 | #endif // MODULE_TRIAL_OF_STRENGTH_MAP_MGR_H 53 | -------------------------------------------------------------------------------- /src/TrialOfStrength.cpp: -------------------------------------------------------------------------------- 1 | #include "TrialOfStrength.h" 2 | #include "ToSMapMgr.h" 3 | 4 | #include "scripts/AI/ToSAIArenaSpectator.h" 5 | 6 | #include "scripts/ToSArenaMasterScript.h" 7 | 8 | #include "scripts/ToSInstanceScript.h" 9 | #include "scripts/ToSInstanceMapScript.h" 10 | 11 | #include "scripts/ToSPlayerScript.h" 12 | #include "scripts/ToSCurseCrystalScript.h" 13 | 14 | #include "scripts/ToSUnitScript.h" 15 | 16 | void LoadWaveTemplates() 17 | { 18 | auto qResult = WorldDatabase.Query("SELECT * FROM tos_wave_template"); 19 | 20 | if (!qResult) 21 | { 22 | return; 23 | } 24 | 25 | LOG_INFO("module", "Loading trial of strength wave templates from 'tos_wave_template'.."); 26 | 27 | int count = 0; 28 | 29 | do 30 | { 31 | auto fields = qResult->Fetch(); 32 | 33 | ToSWaveTemplate waveTemplate; 34 | waveTemplate.wave = fields[0].Get(); 35 | waveTemplate.enemyGroup = fields[1].Get(); 36 | waveTemplate.hasReward = fields[2].Get(); 37 | waveTemplate.rewardTemplate = fields[3].Get(); 38 | 39 | sToSMapMgr->WaveTemplates.emplace(waveTemplate.wave, waveTemplate); 40 | 41 | count++; 42 | } while (qResult->NextRow()); 43 | 44 | LOG_INFO("module", "Loaded '{}' trial of strength wave templates.", count); 45 | } 46 | 47 | void LoadEnemyGroups() 48 | { 49 | auto qResult = WorldDatabase.Query("SELECT * FROM tos_wave_groups"); 50 | 51 | if (!qResult) 52 | { 53 | return; 54 | } 55 | 56 | LOG_INFO("module", "Loading trial of strength wave groups from 'tos_wave_groups'.."); 57 | 58 | int count = 0; 59 | 60 | do 61 | { 62 | auto fields = qResult->Fetch(); 63 | 64 | ToSEnemyGroup enemyGroup; 65 | 66 | enemyGroup.id = fields[0].Get(); 67 | enemyGroup.group = fields[1].Get(); 68 | enemyGroup.subGroup = fields[2].Get(); 69 | enemyGroup.creatureEntry = fields[3].Get(); 70 | 71 | sToSMapMgr->EnemyGroups.emplace(enemyGroup.id, enemyGroup); 72 | 73 | count++; 74 | } while (qResult->NextRow()); 75 | 76 | LOG_INFO("module", "Loaded '{}' trial of strength wave groups.", count); 77 | } 78 | 79 | void LoadRewardTemplates() 80 | { 81 | auto qResult = WorldDatabase.Query("SELECT * FROM tos_reward_template"); 82 | 83 | if (!qResult) 84 | { 85 | return; 86 | } 87 | 88 | LOG_INFO("module", "Loading trial of strength reward templates from 'tos_reward_template'.."); 89 | 90 | int count = 0; 91 | 92 | do 93 | { 94 | auto fields = qResult->Fetch(); 95 | 96 | ToSRewardTemplate rewardTemplate; 97 | 98 | auto rewardId = fields[0].Get(); 99 | rewardTemplate.itemEntry = fields[1].Get(); 100 | rewardTemplate.countMin = fields[2].Get(); 101 | rewardTemplate.countMax = fields[3].Get(); 102 | rewardTemplate.countCap = fields[4].Get(); 103 | rewardTemplate.chance = fields[5].Get(); 104 | rewardTemplate.curseScalar = fields[6].Get(); 105 | 106 | auto templates = sToSMapMgr->GetRewardTemplates(rewardId); 107 | if (!templates) 108 | { 109 | std::vector newTemplates; 110 | newTemplates.push_back(rewardTemplate); 111 | sToSMapMgr->RewardTemplates.emplace(rewardId, newTemplates); 112 | } 113 | else 114 | { 115 | templates->push_back(rewardTemplate); 116 | } 117 | 118 | count++; 119 | } while (qResult->NextRow()); 120 | 121 | LOG_INFO("module", "Loaded '{}' trial of strength reward templates.", count); 122 | } 123 | 124 | void LoadCurseTemplates() 125 | { 126 | auto qResult = WorldDatabase.Query("SELECT * FROM tos_curse_template"); 127 | 128 | if (!qResult) 129 | { 130 | return; 131 | } 132 | 133 | LOG_INFO("module", "Loading trial of strength curse templates from 'tos_curse_template'.."); 134 | 135 | int count = 0; 136 | 137 | do 138 | { 139 | auto fields = qResult->Fetch(); 140 | 141 | ToSCurseTemplate curseTemplate; 142 | 143 | auto curseId = fields[0].Get(); 144 | curseTemplate.id = curseId; 145 | curseTemplate.type = fields[1].Get(); 146 | curseTemplate.difficulty = fields[2].Get(); 147 | curseTemplate.aura = fields[3].Get(); 148 | curseTemplate.name = fields[4].Get(); 149 | curseTemplate.description = fields[5].Get(); 150 | 151 | sToSMapMgr->CurseTemplates.emplace(curseId, curseTemplate); 152 | 153 | count++; 154 | } while (qResult->NextRow()); 155 | 156 | LOG_INFO("module", "Loaded '{}' trial of strength curse templates.", count); 157 | } 158 | 159 | void ToSWorldScript::OnAfterConfigLoad(bool reload) 160 | { 161 | if (reload) 162 | { 163 | sToSMapMgr->WaveTemplates.clear(); 164 | sToSMapMgr->EnemyGroups.clear(); 165 | sToSMapMgr->RewardTemplates.clear(); 166 | sToSMapMgr->CurseTemplates.clear(); 167 | } 168 | 169 | if (!sConfigMgr->GetOption("TrialOfStrength.Enable", false)) 170 | { 171 | return; 172 | } 173 | 174 | LoadWaveTemplates(); 175 | LoadEnemyGroups(); 176 | LoadRewardTemplates(); 177 | LoadCurseTemplates(); 178 | } 179 | 180 | void SC_AddTrialOfStrengthScripts() 181 | { 182 | new ToSWorldScript(); 183 | 184 | new ToSArenaMasterScript(); 185 | new ToSAIArenaSpectator(); 186 | 187 | new ToSInstanceMapScript(); 188 | 189 | new ToSPlayerScript(); 190 | new ToSCurseCrystalScript(); 191 | 192 | new ToSUnitScript(); 193 | } 194 | -------------------------------------------------------------------------------- /src/TrialOfStrength.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULE_TRIAL_OF_STRENGTH_H 2 | #define MODULE_TRIAL_OF_STRENGTH_H 3 | 4 | #include "Player.h" 5 | #include "ScriptMgr.h" 6 | #include "CombatAI.h" 7 | #include "Config.h" 8 | #include "ScriptedGossip.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | enum ToSConstants { 15 | TOS_MAP_ID = 44, 16 | TOS_NPC_ARENA_MASTER = 441250, 17 | TOS_SPELL_TELEPORT_VISUAL = 64446, 18 | TOS_ENTRY_TICKET_ID = 25747, 19 | 20 | TOS_DATA_ENCOUNTER_START = 1, 21 | TOS_DATA_ENCOUNTER_CURRENT_WAVE = 2, 22 | TOS_DATA_ENCOUNTER_CURRENT_WAVE_CLEARED = 3, 23 | TOS_DATA_ENCOUNTER_HAS_MORE_WAVES = 4, 24 | TOS_DATA_ENCOUNTER_RESET = 5, 25 | TOS_DATA_ENCOUNTER_CURRENT_WAVE_REMAINING = 6, 26 | TOS_DATA_ENCOUNTER_COMBATANTS_HOSTILE = 7, 27 | TOS_DATA_ENCOUNTER_CHECK_WAVE_COMPLETE = 8, 28 | TOS_DATA_ENCOUNTER_START_NEXT_WAVE = 9, 29 | TOS_DATA_ENCOUNTER_CHECK_FAILURE = 10, 30 | TOS_DATA_ENCOUNTER_CURRENT_SUBWAVE = 11, 31 | TOS_DATA_ENCOUNTER_TOTAL_SUBWAVE = 12, 32 | TOS_DATA_ENCOUNTER_TRIAL_COMPLETED = 13, 33 | TOS_DATA_ENCOUNTER_CHECK_ARENA_MASTER_RELOCATE = 14, 34 | TOS_DATA_ENCOUNTER_WAVE_IN_PROGRESS = 15, 35 | TOS_DATA_ENCOUNTER_CROWD = 16, 36 | TOS_DATA_PORTAL_TRY_TELEPORT = 17, 37 | TOS_DATA_ENCOUNTER_UPDATE_INVADERS = 18, 38 | 39 | TOS_CURSE_TYPE_ENEMY = 0, 40 | TOS_CURSE_TYPE_PLAYER = 1, 41 | 42 | TOS_DATA_UINT32_BASE = 4411, 43 | TOS_DATA_UINT32_CURSE_ID = 0, 44 | }; 45 | 46 | struct ToSWaveTemplate { 47 | uint32 wave; 48 | uint32 enemyGroup; 49 | bool hasReward; 50 | uint32 rewardTemplate; 51 | }; 52 | 53 | struct ToSEnemyGroup { 54 | uint32 id; 55 | uint32 group; 56 | uint32 subGroup; 57 | uint32 creatureEntry; 58 | }; 59 | 60 | struct ToSRewardTemplate { 61 | uint32 itemEntry; 62 | uint32 countMin; 63 | uint32 countMax; 64 | uint32 countCap; 65 | uint32 chance; 66 | float curseScalar; 67 | }; 68 | 69 | struct ToSCurseTemplate { 70 | uint32 id; 71 | uint32 type; 72 | uint32 difficulty; 73 | uint32 aura; 74 | 75 | std::string name; 76 | std::string description; 77 | }; 78 | 79 | class ToSWorldScript : public WorldScript 80 | { 81 | public: 82 | ToSWorldScript() : WorldScript("ToSWorldScript") { } 83 | 84 | void OnAfterConfigLoad(bool /*reload*/) override; 85 | }; 86 | 87 | #endif // MODULE_TRIAL_OF_STRENGTH_H 88 | -------------------------------------------------------------------------------- /src/scripts/AI/ToSAIArenaSpectator.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULE_TRIAL_OF_STRENGTH_AI_ARENA_SPECTATOR_H 2 | #define MODULE_TRIAL_OF_STRENGTH_AI_ARENA_SPECTATOR_H 3 | 4 | #include "ScriptMgr.h" 5 | #include "ScriptedCreature.h" 6 | #include "ToSInstanceScript.h" 7 | 8 | class ToSAIArenaSpectator : public CreatureScript 9 | { 10 | public: 11 | ToSAIArenaSpectator() : CreatureScript("ToSAIArenaSpectator") { } 12 | 13 | CreatureAI* GetAI(Creature* creature) const override 14 | { 15 | return new ToSAIArenaSpectatorAI(creature); 16 | } 17 | 18 | struct ToSAIArenaSpectatorAI : public ScriptedAI 19 | { 20 | enum ToSSpectatorConstants 21 | { 22 | TOS_ARENA_SPEC_DO_EMOTE = 1 23 | }; 24 | 25 | EventMap events; 26 | 27 | ToSAIArenaSpectatorAI(Creature* creature) : ScriptedAI(creature) 28 | { 29 | events.Reset(); 30 | events.ScheduleEvent(TOS_ARENA_SPEC_DO_EMOTE, randtime(3s, 10s)); 31 | } 32 | 33 | void UpdateAI(uint32 diff) override 34 | { 35 | events.Update(diff); 36 | 37 | switch (events.ExecuteEvent()) 38 | { 39 | case TOS_ARENA_SPEC_DO_EMOTE: 40 | DoEmote(); 41 | events.RescheduleEvent(TOS_ARENA_SPEC_DO_EMOTE, randtime(3s, 10s)); 42 | break; 43 | } 44 | } 45 | 46 | void DoEmote() 47 | { 48 | auto iScript = (ToSInstanceScript*)me->GetInstanceScript(); 49 | if (!iScript) 50 | { 51 | events.Reset(); 52 | LOG_WARN("module", "Failed to find instance script for Arena Spectator."); 53 | return; 54 | } 55 | 56 | if (!iScript->IsEncounterInProgress() || 57 | !iScript->IsWaveInProgress()) 58 | { 59 | return; 60 | } 61 | 62 | switch (urand(0, 2)) 63 | { 64 | case 0: 65 | me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER); 66 | break; 67 | 68 | case 1: 69 | me->HandleEmoteCommand(EMOTE_ONESHOT_DANCE); 70 | break; 71 | 72 | case 2: 73 | me->HandleEmoteCommand(EMOTE_ONESHOT_APPLAUD); 74 | break; 75 | } 76 | } 77 | }; 78 | }; 79 | 80 | #endif // MODULE_TRIAL_OF_STRENGTH_AI_ARENA_SPECTATOR_H 81 | -------------------------------------------------------------------------------- /src/scripts/ToSArenaMasterScript.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULE_TRIAL_OF_STRENGTH_ARENA_MASTER_H 2 | #define MODULE_TRIAL_OF_STRENGTH_ARENA_MASTER_H 3 | 4 | class ToSArenaMasterScript : public CreatureScript 5 | { 6 | public: 7 | ToSArenaMasterScript() : CreatureScript("ToSArenaMasterScript") { } 8 | 9 | enum ArenaMasterConstants { 10 | TOS_ARENA_MASTER_TEXT_GREETING = 441250, 11 | TOS_ARENA_MASTER_TEXT_PRE_TRIAL = 441251, 12 | TOS_ARENA_MASTER_TEXT_WAVE_NOT_FINISHED = 441252, 13 | TOS_ARENA_MASTER_TEXT_WAVE_NEXT = 441253, 14 | TOS_ARENA_MASTER_TEXT_CONGRATULATE = 441254, 15 | TOS_ARENA_MASTER_TEXT_DENY_ENTRY = 441255, 16 | TOS_ARENA_MASTER_TEXT_DENY_ENTRY_NO_TICKET = 441256, 17 | 18 | TOS_GOSSIP_TELEPORT_TO = 1, 19 | TOS_GOSSIP_TELEPORT_FROM = 2, 20 | TOS_GOSSIP_ENCOUNTER_START = 3, 21 | TOS_GOSSIP_ENCOUNTER_NEXT_WAVE = 4, 22 | TOS_GOSSIP_ENCOUNTER_RESET = 5 23 | }; 24 | 25 | virtual bool OnGossipHello(Player* player, Creature* creature) override 26 | { 27 | if (!sConfigMgr->GetOption("TrialOfStrength.Enable", false)) 28 | { 29 | return false; 30 | } 31 | 32 | ClearGossipMenuFor(player); 33 | 34 | if (!sToSMapMgr->CanPlayerEnter(player)) 35 | { 36 | SendGossipMenuFor(player, TOS_ARENA_MASTER_TEXT_DENY_ENTRY, creature); 37 | 38 | return true; 39 | } 40 | 41 | auto map = creature->GetMap(); 42 | if (map && map->GetId() != TOS_MAP_ID) 43 | { 44 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Yes, I would like to attempt the trials.", GOSSIP_SENDER_MAIN, TOS_GOSSIP_TELEPORT_TO); 45 | SendGossipMenuFor(player, TOS_ARENA_MASTER_TEXT_GREETING, creature); 46 | 47 | return true; 48 | } 49 | 50 | auto iScript = (ToSInstanceScript*)creature->GetInstanceScript(); 51 | if (!iScript) 52 | { 53 | CloseGossipMenuFor(player); 54 | 55 | return false; 56 | } 57 | 58 | auto currentWave = iScript->GetData(TOS_DATA_ENCOUNTER_CURRENT_WAVE); 59 | auto currentSubWave = iScript->GetData(TOS_DATA_ENCOUNTER_CURRENT_SUBWAVE); 60 | auto totalSubWave = iScript->GetData(TOS_DATA_ENCOUNTER_TOTAL_SUBWAVE); 61 | auto waveCleared = iScript->GetData(TOS_DATA_ENCOUNTER_CURRENT_WAVE_CLEARED) > 0; 62 | auto hasMoreWaves = iScript->GetData(TOS_DATA_ENCOUNTER_HAS_MORE_WAVES) > 0; 63 | auto remainingAlive = iScript->GetData(TOS_DATA_ENCOUNTER_CURRENT_WAVE_REMAINING); 64 | auto trialCompleted = iScript->GetData(TOS_DATA_ENCOUNTER_TRIAL_COMPLETED) > 0; 65 | 66 | if (!iScript->IsEncounterInProgress() && !waveCleared) 67 | { 68 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Yes, I am ready to start the Trial of Strength.", GOSSIP_SENDER_MAIN, TOS_GOSSIP_ENCOUNTER_START); 69 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, "I changed my mind, I would like to leave.", GOSSIP_SENDER_MAIN, TOS_GOSSIP_TELEPORT_FROM); 70 | 71 | SendGossipMenuFor(player, TOS_ARENA_MASTER_TEXT_PRE_TRIAL, creature); 72 | 73 | return true; 74 | } 75 | 76 | if (iScript->IsEncounterInProgress() && !waveCleared) 77 | { 78 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, Acore::StringFormatFmt("Encounter In Progress: {}|nCurrent Wave: |cff0000FF{}|r|nCurrent Sub-Wave: {}/{}|nWave Cleared: {}|nAlive: |cffFF0000{}|r|nMore Waves?: {}", iScript->IsEncounterInProgress() ? "true" : "false", currentWave, currentSubWave, totalSubWave, waveCleared ? "true" : "false", remainingAlive, hasMoreWaves ? "true" : "false"), GOSSIP_SENDER_MAIN, 0); 79 | 80 | SendGossipMenuFor(player, TOS_ARENA_MASTER_TEXT_WAVE_NOT_FINISHED, creature); 81 | 82 | return true; 83 | } 84 | 85 | if (iScript->IsEncounterInProgress() && waveCleared && hasMoreWaves) 86 | { 87 | if (iScript->IsRewardChestEmpty()) 88 | { 89 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, Acore::StringFormatFmt("Yes, I would like to proceed to the next wave. ({})", currentWave + 1), GOSSIP_SENDER_MAIN, TOS_GOSSIP_ENCOUNTER_NEXT_WAVE); 90 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, "I would like to stop here.", GOSSIP_SENDER_MAIN, TOS_GOSSIP_ENCOUNTER_RESET); 91 | } 92 | else 93 | { 94 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, Acore::StringFormatFmt("Yes, I would like to proceed to the next wave. ({})", currentWave + 1), GOSSIP_SENDER_MAIN, TOS_GOSSIP_ENCOUNTER_NEXT_WAVE, "You have unlooted items in the reward chest, are you sure you want to continue?", 0, false); 95 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, "I would like to stop here.", GOSSIP_SENDER_MAIN, TOS_GOSSIP_ENCOUNTER_RESET, "You have unlooted items in the reward chest, are you sure you want to continue?", 0, false); 96 | } 97 | 98 | SendGossipMenuFor(player, TOS_ARENA_MASTER_TEXT_WAVE_NEXT, creature); 99 | 100 | return true; 101 | } 102 | 103 | if (trialCompleted) 104 | { 105 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, "I would like to attempt the trial again.", GOSSIP_SENDER_MAIN, TOS_GOSSIP_ENCOUNTER_RESET); 106 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, "I want to leave this place.", GOSSIP_SENDER_MAIN, TOS_GOSSIP_TELEPORT_FROM); 107 | 108 | SendGossipMenuFor(player, TOS_ARENA_MASTER_TEXT_CONGRATULATE, creature); 109 | 110 | return true; 111 | } 112 | 113 | CloseGossipMenuFor(player); 114 | 115 | return false; 116 | } 117 | 118 | virtual bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override 119 | { 120 | if (!sConfigMgr->GetOption("TrialOfStrength.Enable", false)) 121 | { 122 | return false; 123 | } 124 | 125 | if (action == 0) 126 | { 127 | OnGossipHello(player, creature); 128 | } 129 | 130 | if (action == TOS_GOSSIP_TELEPORT_TO) 131 | { 132 | CloseGossipMenuFor(player); 133 | player->TeleportTo(TOS_MAP_ID, 176.726, -126.015, 18.022, 4.739); 134 | } 135 | 136 | if (action == TOS_GOSSIP_TELEPORT_FROM) 137 | { 138 | CloseGossipMenuFor(player); 139 | player->TeleportTo(TOS_MAP_ID, 176.726, -126.015, 18.022, 4.739); 140 | } 141 | 142 | if (action == TOS_GOSSIP_ENCOUNTER_START) 143 | { 144 | ClearGossipMenuFor(player); 145 | 146 | auto ticketCount = player->GetItemCount(TOS_ENTRY_TICKET_ID); 147 | 148 | if (!ticketCount) 149 | { 150 | SendGossipMenuFor(player, TOS_ARENA_MASTER_TEXT_DENY_ENTRY_NO_TICKET, creature); 151 | return true; 152 | } 153 | 154 | player->DestroyItemCount(TOS_ENTRY_TICKET_ID, 1, true); 155 | 156 | CloseGossipMenuFor(player); 157 | 158 | if (InstanceScript* pInstance = creature->GetInstanceScript()) 159 | { 160 | pInstance->SetData(TOS_DATA_ENCOUNTER_START, 1); 161 | } 162 | } 163 | 164 | if (action == TOS_GOSSIP_ENCOUNTER_RESET) 165 | { 166 | CloseGossipMenuFor(player); 167 | 168 | if (InstanceScript* pInstance = creature->GetInstanceScript()) 169 | { 170 | pInstance->SetData(TOS_DATA_ENCOUNTER_RESET, 1); 171 | } 172 | } 173 | 174 | if (action == TOS_GOSSIP_ENCOUNTER_NEXT_WAVE) 175 | { 176 | CloseGossipMenuFor(player); 177 | 178 | if (InstanceScript* pInstance = creature->GetInstanceScript()) 179 | { 180 | if (!pInstance->GetData(TOS_DATA_ENCOUNTER_WAVE_IN_PROGRESS)) 181 | { 182 | pInstance->SetData(TOS_DATA_ENCOUNTER_CURRENT_WAVE, pInstance->GetData(TOS_DATA_ENCOUNTER_CURRENT_WAVE) + 1); 183 | pInstance->SetData(TOS_DATA_ENCOUNTER_START, 1); 184 | } 185 | } 186 | } 187 | 188 | return true; 189 | } 190 | }; 191 | 192 | #endif // MODULE_TRIAL_OF_STRENGTH_ARENA_MASTER_H 193 | -------------------------------------------------------------------------------- /src/scripts/ToSCurseCrystalScript.cpp: -------------------------------------------------------------------------------- 1 | #include "ToSCurseCrystalScript.h" 2 | 3 | #include "TrialOfStrength.h" 4 | #include "ToSInstanceScript.h" 5 | 6 | #include 7 | 8 | bool ToSCurseCrystalScript::OnGossipHello(Player* player, GameObject* go) 9 | { 10 | ClearGossipMenuFor(player); 11 | 12 | if (!go) 13 | { 14 | return false; 15 | } 16 | 17 | auto map = go->GetMap(); 18 | if (!map) 19 | { 20 | return false; 21 | } 22 | 23 | auto instance = map->ToInstanceMap(); 24 | if (!instance) 25 | { 26 | return false; 27 | } 28 | 29 | auto iScript = (ToSInstanceScript*)instance->GetInstanceScript(); 30 | if (!iScript) 31 | { 32 | return false; 33 | } 34 | 35 | auto curseId = iScript->GetCurseForGUID(go->GetGUID()); 36 | if (!curseId) 37 | { 38 | LOG_INFO("module", "Failed to get curse id for crystal."); 39 | return false; 40 | } 41 | 42 | auto curseInfo = sToSMapMgr->GetCurseById(curseId); 43 | if (!curseInfo) 44 | { 45 | LOG_INFO("module", "Failed to get curse information for crystal."); 46 | return false; 47 | } 48 | 49 | AddGossipItemFor(player, GOSSIP_ICON_CHAT, Acore::StringFormatFmt("|cff000000{}|n|cff212121{}|r|n{}", curseInfo->name, curseInfo->description, sToSMapMgr->GetDifficultyString(curseInfo->difficulty)), GOSSIP_SENDER_MAIN, curseInfo->id); 50 | SendGossipMenuFor(player, 1, go->GetGUID()); 51 | 52 | return true; 53 | } 54 | 55 | bool ToSCurseCrystalScript::OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 action) 56 | { 57 | if (!action) 58 | { 59 | return false; 60 | } 61 | 62 | if (!go || !player) 63 | { 64 | return false; 65 | } 66 | 67 | auto map = go->GetMap(); 68 | if (!map) 69 | { 70 | return false; 71 | } 72 | 73 | auto instance = map->ToInstanceMap(); 74 | if (!instance) 75 | { 76 | return false; 77 | } 78 | 79 | auto iScript = (ToSInstanceScript*)instance->GetInstanceScript(); 80 | if (!iScript) 81 | { 82 | return false; 83 | } 84 | 85 | iScript->AddCurse(action); 86 | iScript->RemoveAvailableCurse(action); 87 | iScript->DespawnCurseCrystals(); 88 | 89 | CloseGossipMenuFor(player); 90 | 91 | return true; 92 | } 93 | 94 | -------------------------------------------------------------------------------- /src/scripts/ToSCurseCrystalScript.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULE_TRIAL_OF_STRENGTH_CURSE_CRYSTAL_SCRIPT_H 2 | #define MODULE_TRIAL_OF_STRENGTH_CURSE_CRYSTAL_SCRIPT_H 3 | 4 | #include "ScriptMgr.h" 5 | #include "Player.h" 6 | 7 | class ToSCurseCrystalScript : public GameObjectScript 8 | { 9 | public: 10 | ToSCurseCrystalScript() : GameObjectScript("ToSCurseCrystalScript") { } 11 | 12 | bool OnGossipHello(Player* /*player*/, GameObject* /*go*/) override; 13 | bool OnGossipSelect(Player* /*player*/, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/) override; 14 | }; 15 | 16 | #endif // MODULE_TRIAL_OF_STRENGTH_CURSE_CRYSTAL_SCRIPT_H 17 | -------------------------------------------------------------------------------- /src/scripts/ToSInstanceMapScript.cpp: -------------------------------------------------------------------------------- 1 | #include "ToSInstanceMapScript.h" 2 | #include "ToSInstanceScript.h" 3 | 4 | InstanceScript* ToSInstanceMapScript::GetInstanceScript(InstanceMap* map) const 5 | { 6 | return new ToSInstanceScript(map); 7 | } 8 | -------------------------------------------------------------------------------- /src/scripts/ToSInstanceMapScript.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULE_TRIAL_OF_STRENGTH_INSTANCE_MAP_SCRIPT_H 2 | #define MODULE_TRIAL_OF_STRENGTH_INSTANCE_MAP_SCRIPT_H 3 | 4 | #include "ScriptMgr.h" 5 | 6 | class ToSInstanceMapScript : public InstanceMapScript 7 | { 8 | public: 9 | ToSInstanceMapScript() : InstanceMapScript("instance_trial_of_strength", 44) { } 10 | 11 | InstanceScript* GetInstanceScript(InstanceMap* map) const override; 12 | }; 13 | 14 | #endif // MODULE_TRIAL_OF_STRENGTH_INSTANCE_MAP_SCRIPT_H 15 | -------------------------------------------------------------------------------- /src/scripts/ToSInstanceScript.cpp: -------------------------------------------------------------------------------- 1 | #include "ToSInstanceScript.h" 2 | 3 | #include 4 | 5 | void ToSInstanceScript::AddCurse(uint32 curseId) 6 | { 7 | auto it = sToSMapMgr->CurseTemplates.find(curseId); 8 | if (it == sToSMapMgr->CurseTemplates.end()) 9 | { 10 | LOG_WARN("module", "Tried to add curse {} to creature curses but it does not exist.", curseId); 11 | return; 12 | } 13 | 14 | auto curse = sToSMapMgr->GetCurseById(curseId); 15 | if (!curse) 16 | { 17 | return; 18 | } 19 | 20 | curses.push_back(curse); 21 | } 22 | 23 | void ToSInstanceScript::OnCreatureCreate(Creature* creature) 24 | { 25 | if (creature && 26 | creature->GetEntry() == TOS_NPC_ARENA_MASTER) 27 | { 28 | arenaMaster = creature; 29 | } 30 | } 31 | 32 | bool ToSInstanceScript::IsSubWaveCleared() const 33 | { 34 | return waveInProgress && GetRemainingAlive() == 0; 35 | } 36 | 37 | bool ToSInstanceScript::IsWaveCleared() const 38 | { 39 | return waveCleared; 40 | } 41 | 42 | bool ToSInstanceScript::HasMoreWaves() const 43 | { 44 | return currentWave < totalWaves ? true : false; 45 | } 46 | 47 | bool ToSInstanceScript::IsWaveInProgress() const 48 | { 49 | return waveInProgress; 50 | } 51 | 52 | void ToSInstanceScript::SpawnNextWave(ToSWaveTemplate* waveTemplate = nullptr) 53 | { 54 | if (!waveTemplate) 55 | { 56 | waveTemplate = sToSMapMgr->GetWaveTemplateForWave(currentWave); 57 | } 58 | 59 | if (!waveTemplate) 60 | { 61 | LOG_WARN("module", "Wave template is nullptr."); 62 | return; 63 | } 64 | 65 | auto enemies = sToSMapMgr->GetEnemiesFromGroup(waveTemplate->enemyGroup, currentSubGroup); 66 | if (enemies.empty()) 67 | { 68 | LOG_WARN("module", "No enemies found in wave template."); 69 | return; 70 | } 71 | 72 | waveCleared = false; 73 | CleanupCreatures(); 74 | ApplyCursesToPlayers(); 75 | 76 | uint32 i = 0; 77 | 78 | for (auto it = enemies.begin(); it != enemies.end(); ++it) 79 | { 80 | auto enemy = (*it); 81 | 82 | auto diff = sToSMapMgr->LinearDistribution(-4, 4, enemies.size(), i); 83 | 84 | Position tempPos(combatantPosStart->GetPositionX(), combatantPosStart->GetPositionY() + diff, combatantPosStart->GetPositionZ(), combatantPosStart->GetOrientation()); 85 | 86 | auto summon = sToSMapMgr->SpawnNPC(enemy->creatureEntry, instance, &tempPos); 87 | 88 | if(sConfigMgr->GetOption("TrialOfStrength.AutoScaling", true)) 89 | { 90 | ApplyAutoScaling(summon); 91 | } 92 | 93 | ApplyCurses(summon); 94 | 95 | waveCreatures.push_back(summon); 96 | 97 | if (currentSubGroup == 1) 98 | { 99 | summon->SetFaction(FACTION_FRIENDLY); 100 | } 101 | 102 | summon->CastSpell(summon, TOS_SPELL_TELEPORT_VISUAL); 103 | MakeEntrance(summon, diff); 104 | 105 | i++; 106 | } 107 | 108 | events.ScheduleEvent(TOS_DATA_ENCOUNTER_COMBATANTS_HOSTILE, 5s); 109 | events.ScheduleEvent(TOS_DATA_ENCOUNTER_CHECK_WAVE_COMPLETE, 10s); 110 | events.ScheduleEvent(TOS_DATA_ENCOUNTER_CHECK_FAILURE, 5s); 111 | } 112 | 113 | void ToSInstanceScript::MakeEntrance(Creature* creature, float diff) 114 | { 115 | Position tempPos(combatantPosEnd->GetPositionX(), combatantPosEnd->GetPositionY() + diff, combatantPosEnd->GetPositionZ(), combatantPosEnd->GetOrientation()); 116 | creature->GetMotionMaster()->MovePoint(0, tempPos); 117 | creature->SetHomePosition(*combatantPosEnd); 118 | } 119 | 120 | void ToSInstanceScript::ApplyCurses(Unit* unit) 121 | { 122 | if (!unit || 123 | curses.empty()) 124 | { 125 | return; 126 | } 127 | 128 | for (auto const& curse : curses) 129 | { 130 | if (unit->ToPlayer() && 131 | curse->type == TOS_CURSE_TYPE_PLAYER && 132 | !unit->HasAura(curse->aura)) 133 | { 134 | unit->AddAura(curse->aura, unit); 135 | continue; 136 | } 137 | 138 | if (!unit->ToPlayer() && 139 | curse->type == TOS_CURSE_TYPE_ENEMY && 140 | !unit->HasAura(curse->aura)) 141 | { 142 | unit->AddAura(curse->aura, unit); 143 | continue; 144 | } 145 | } 146 | } 147 | 148 | void ToSInstanceScript::ApplyCursesToPlayers() 149 | { 150 | Map::PlayerList const& players = instance->GetPlayers(); 151 | 152 | for (const auto& it : players) 153 | { 154 | Player* player = it.GetSource(); 155 | 156 | if (!player) 157 | continue; 158 | 159 | ApplyCurses(player); 160 | } 161 | } 162 | 163 | void ToSInstanceScript::ApplyAutoScaling(Creature* creature) 164 | { 165 | if (!creature) 166 | { 167 | return; 168 | } 169 | 170 | creature->SetLevel(80, true); 171 | 172 | uint32 baseHP = sConfigMgr->GetOption("TrialOfStrength.AutoScaling.BaseHealth", 8000); 173 | uint32 hpDivider = sConfigMgr->GetOption("TrialOfStrength.AutoScaling.HealthDivider", 15); 174 | 175 | float hpMultiplier = (1.0f + (float(currentWave) / float(hpDivider))); 176 | uint32 health = (baseHP * hpMultiplier) * 177 | frand(1.01, 1.02); // Add a tiny bit of variation to the health 178 | 179 | creature->SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, health); 180 | creature->UpdateMaxHealth(); 181 | creature->SetHealth(creature->GetMaxHealth()); 182 | 183 | uint32 basePhys = sConfigMgr->GetOption("TrialOfStrength.AutoScaling.BaseDamage.Physical", 500); 184 | 185 | // Reduce physical damage for mages. 186 | if (creature->getClass() == CLASS_MAGE) 187 | { 188 | basePhys = basePhys / 5; 189 | } 190 | 191 | uint32 physDivider = sConfigMgr->GetOption("TrialOfStrength.AutoScaling.BaseDamage.PhysicalDivider", 15); 192 | 193 | uint32 newPhysDmg = basePhys * (1.0f + (float(currentWave) / float(physDivider))); 194 | 195 | LOG_INFO("module", "Base mainhand: {}, Pct mainhand: {}, AttackPower: {}", creature->GetModifierValue(UNIT_MOD_DAMAGE_MAINHAND, BASE_VALUE), creature->GetModifierValue(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT), creature->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE)); 196 | 197 | // Remove all attack power 198 | creature->HandleStatModifier(UNIT_MOD_ATTACK_POWER, BASE_VALUE, creature->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE), false); 199 | 200 | creature->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, BASE_VALUE, creature->GetModifierValue(UNIT_MOD_DAMAGE_MAINHAND, BASE_VALUE), false); 201 | creature->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, BASE_VALUE, newPhysDmg, true); 202 | 203 | creature->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, BASE_VALUE, creature->GetModifierValue(UNIT_MOD_DAMAGE_OFFHAND, BASE_VALUE), false); 204 | creature->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, BASE_VALUE, newPhysDmg, true); 205 | 206 | LOG_INFO("module", "Base mainhand: {}, Pct mainhand: {}, AttackPower: {}", creature->GetModifierValue(UNIT_MOD_DAMAGE_MAINHAND, BASE_VALUE), creature->GetModifierValue(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT), creature->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE)); 207 | } 208 | 209 | void ToSInstanceScript::ClearCursesFromPlayers() 210 | { 211 | Map::PlayerList const& players = instance->GetPlayers(); 212 | 213 | for (const auto& it : players) 214 | { 215 | Player* player = it.GetSource(); 216 | 217 | if (!player) 218 | { 219 | continue; 220 | } 221 | 222 | sToSMapMgr->ClearCurses(player); 223 | } 224 | } 225 | 226 | void ToSInstanceScript::SpawnCurseCrystals() 227 | { 228 | auto randomCurses = GetRandomAvailableCurses(3); 229 | 230 | // Crystal 1 231 | if(auto curse1 = randomCurses.at(0)) 232 | { 233 | Position* tempPos = new Position(255.072, -95.140, 18.679, 0); 234 | if ((curseCrystal1 = instance->SummonGameObject(TOS_GOB_CURSE, *tempPos, 0.0, 0.0, 0.0, 0.0, 0, true))) 235 | { 236 | curseId1 = curse1; 237 | } 238 | } 239 | 240 | // Crystal 2 241 | if (auto curse2 = randomCurses.at(1)) 242 | { 243 | Position* tempPos = new Position(259.940, -100.025, 18.679, 0); 244 | if ((curseCrystal2 = instance->SummonGameObject(TOS_GOB_CURSE, *tempPos, 0.0, 0.0, 0.0, 0.0, 0, true))) 245 | { 246 | curseId2 = curse2; 247 | } 248 | } 249 | 250 | // Crystal 3 251 | if (auto curse3 = randomCurses.at(2)) 252 | { 253 | Position* tempPos = new Position(255.067, -104.689, 18.679, 0); 254 | if ((curseCrystal3 = instance->SummonGameObject(TOS_GOB_CURSE, *tempPos, 0.0, 0.0, 0.0, 0.0, 0, true))) 255 | { 256 | curseId3 = curse3; 257 | } 258 | } 259 | } 260 | 261 | void ToSInstanceScript::DespawnCurseCrystals() 262 | { 263 | if (curseCrystal1) 264 | { 265 | curseCrystal1->Delete(); 266 | curseCrystal1 = nullptr; 267 | } 268 | 269 | if (curseCrystal2) 270 | { 271 | curseCrystal2->Delete(); 272 | curseCrystal2 = nullptr; 273 | } 274 | 275 | if (curseCrystal3) 276 | { 277 | curseCrystal3->Delete(); 278 | curseCrystal3 = nullptr; 279 | } 280 | } 281 | 282 | uint32 ToSInstanceScript::GetCurseForGUID(ObjectGuid guid) 283 | { 284 | if (curseCrystal1 && 285 | guid == curseCrystal1->GetGUID()) 286 | { 287 | return curseId1; 288 | } 289 | 290 | if (curseCrystal2 && 291 | guid == curseCrystal2->GetGUID()) 292 | { 293 | return curseId2; 294 | } 295 | 296 | if (curseCrystal3 && 297 | guid == curseCrystal3->GetGUID()) 298 | { 299 | return curseId3; 300 | } 301 | 302 | return 0; 303 | } 304 | 305 | uint32 ToSInstanceScript::GetCurseScaling() 306 | { 307 | uint32 total = 0; 308 | 309 | for (const auto& curse : curses) 310 | { 311 | total += curse->difficulty; 312 | } 313 | 314 | return total; 315 | } 316 | 317 | void ToSInstanceScript::ReloadCurses() 318 | { 319 | availableCurseIds.clear(); 320 | 321 | for (auto const& curseTemplate : sToSMapMgr->CurseTemplates) 322 | { 323 | const ToSCurseTemplate* curse = &curseTemplate.second; 324 | availableCurseIds.push_back(curse->id); 325 | } 326 | } 327 | 328 | uint32 ToSInstanceScript::GetRandomAvailableCurse() 329 | { 330 | if (availableCurseIds.size() < 1) 331 | { 332 | return 0; 333 | } 334 | 335 | auto index = urand(0, availableCurseIds.size() - 1); 336 | auto curseId = availableCurseIds.at(index); 337 | 338 | if (!curseId) 339 | { 340 | return 0; 341 | } 342 | 343 | return curseId; 344 | } 345 | 346 | std::vector ToSInstanceScript::GetRandomAvailableCurses(uint32 count) 347 | { 348 | std::vector randomCurses; 349 | 350 | if (availableCurseIds.size() < 1) 351 | { 352 | return randomCurses; 353 | } 354 | 355 | std::random_device rd; 356 | std::mt19937 g(rd()); 357 | std::shuffle(availableCurseIds.begin(), availableCurseIds.end(), g); 358 | 359 | for (uint32 i = 0; i < count; i++) 360 | { 361 | if (availableCurseIds.size() < count) 362 | { 363 | break; 364 | } 365 | 366 | randomCurses.push_back(availableCurseIds.at(i)); 367 | } 368 | 369 | return randomCurses; 370 | } 371 | 372 | void ToSInstanceScript::RemoveAvailableCurse(uint32 curseId) 373 | { 374 | uint32 i = 0; 375 | for (const auto& curse : availableCurseIds) 376 | { 377 | if (curse == curseId) 378 | { 379 | availableCurseIds.erase(availableCurseIds.begin() + i); 380 | } 381 | 382 | i++; 383 | } 384 | } 385 | 386 | void ToSInstanceScript::SetCombatantsHostile() 387 | { 388 | for (auto it = waveCreatures.begin(); it != waveCreatures.end(); ++it) 389 | { 390 | auto creature = *it; 391 | 392 | creature->SetFaction(FACTION_MONSTER); 393 | creature->SetInCombatWithZone(); 394 | 395 | if (auto minion = creature->GetFirstMinion()) 396 | { 397 | minion->SetFaction(FACTION_MONSTER); 398 | creature->SetInCombatWithZone(); 399 | } 400 | 401 | if (auto player = creature->SelectNearestPlayer(100.0f)) 402 | { 403 | if (creature->Attack(player, true)) 404 | { 405 | creature->GetMotionMaster()->MoveChase(player); 406 | } 407 | } 408 | } 409 | } 410 | 411 | void ToSInstanceScript::Update(uint32 diff) 412 | { 413 | events.Update(diff); 414 | 415 | switch (events.ExecuteEvent()) 416 | { 417 | case TOS_DATA_ENCOUNTER_START: 418 | SetupEncounter(); 419 | break; 420 | 421 | case TOS_DATA_ENCOUNTER_COMBATANTS_HOSTILE: 422 | SetCombatantsHostile(); 423 | break; 424 | 425 | case TOS_DATA_ENCOUNTER_CHECK_WAVE_COMPLETE: 426 | CheckWaveCompletion(); 427 | break; 428 | 429 | case TOS_DATA_ENCOUNTER_START_NEXT_WAVE: 430 | SpawnNextWave(); 431 | break; 432 | 433 | case TOS_DATA_ENCOUNTER_CHECK_FAILURE: 434 | if (!CheckFailure()) 435 | { 436 | events.RescheduleEvent(TOS_DATA_ENCOUNTER_CHECK_FAILURE, 2s); 437 | } 438 | break; 439 | case TOS_DATA_ENCOUNTER_CHECK_ARENA_MASTER_RELOCATE: 440 | CheckArenaMasterRelocate(); 441 | events.RescheduleEvent(TOS_DATA_ENCOUNTER_CHECK_ARENA_MASTER_RELOCATE, 2s); 442 | break; 443 | 444 | case TOS_DATA_ENCOUNTER_CROWD: 445 | PlayCrowd(); 446 | events.RescheduleEvent(TOS_DATA_ENCOUNTER_CROWD, 1s); 447 | break; 448 | 449 | case TOS_DATA_PORTAL_TRY_TELEPORT: 450 | TryTeleportPlayers(); 451 | events.RescheduleEvent(TOS_DATA_PORTAL_TRY_TELEPORT, 1s); 452 | break; 453 | } 454 | } 455 | 456 | void ToSInstanceScript::PlayCrowd() 457 | { 458 | if (IsEncounterInProgress() && IsWaveCleared() && !cheerPlayed) 459 | { 460 | instance->PlayDirectSoundToMap(TOS_SOUND_CHEER); 461 | cheerPlayed = true; 462 | } 463 | } 464 | 465 | void ToSInstanceScript::CheckArenaMasterRelocate() 466 | { 467 | if (!arenaMaster) 468 | { 469 | return; 470 | } 471 | 472 | if (!IsEncounterInProgress()) 473 | { 474 | return; 475 | } 476 | 477 | if (IsWaveInProgress() && !arenaMasterLeft) 478 | { 479 | RelocateArenaMaster(false); 480 | arenaMasterLeft = true; 481 | return; 482 | } 483 | 484 | if (!IsWaveInProgress() && arenaMasterLeft) 485 | { 486 | RelocateArenaMaster(true); 487 | arenaMasterLeft = false; 488 | return; 489 | } 490 | } 491 | 492 | void ToSInstanceScript::RelocateArenaMaster(bool returning) 493 | { 494 | if (!arenaMaster || !arenaMaster->IsInWorld()) 495 | { 496 | return; 497 | } 498 | 499 | arenaMaster->CastSpell(arenaMaster, TOS_SPELL_TELEPORT_VISUAL); 500 | 501 | if (returning) 502 | { 503 | arenaMaster->NearTeleportTo(249.918, -100.063, 18.679, 0.030); 504 | } 505 | else 506 | { 507 | arenaMaster->NearTeleportTo(272.296, -100.024, 28.869, 3.169); 508 | } 509 | } 510 | 511 | void ToSInstanceScript::TryTeleportPlayers() 512 | { 513 | Position portalCenter(187.469, -135.381, 18.529, 0.0); 514 | 515 | Map::PlayerList const& players = instance->GetPlayers(); 516 | 517 | for (const auto& it : players) 518 | { 519 | Player* player = it.GetSource(); 520 | 521 | if (!player) 522 | continue; 523 | 524 | auto distance = player->GetPosition().GetExactDist(portalCenter); 525 | if (distance > 1.0 || 526 | !player->IsAlive()) 527 | { 528 | continue; 529 | } 530 | 531 | if (IsEncounterInProgress() && IsWaveInProgress()) 532 | { 533 | player->SendSystemMessage("You cannot enter while an encounter is in progress."); 534 | continue; 535 | } 536 | 537 | player->TeleportTo(TOS_MAP_ID, 262.502, -100.013, 18.679, 3.137); 538 | } 539 | } 540 | 541 | bool ToSInstanceScript::AnyPlayerAlive() 542 | { 543 | Map::PlayerList const& players = instance->GetPlayers(); 544 | 545 | for (const auto& it : players) 546 | { 547 | Player* player = it.GetSource(); 548 | 549 | if (!player) 550 | continue; 551 | 552 | if (!player->isDead()) 553 | { 554 | return true; 555 | } 556 | } 557 | 558 | return false; 559 | } 560 | 561 | bool ToSInstanceScript::AnyPlayerInArena(bool checkAlive) 562 | { 563 | Position arenaCenter(255.124, -99.910, 18.679, 0.0); 564 | 565 | Map::PlayerList const& players = instance->GetPlayers(); 566 | 567 | for (const auto& it : players) 568 | { 569 | Player* player = it.GetSource(); 570 | 571 | if (!player) 572 | continue; 573 | 574 | auto distance = player->GetPosition().GetExactDist(arenaCenter); 575 | if (distance < 35.0) 576 | { 577 | if (checkAlive) 578 | { 579 | if (player->IsAlive()) 580 | { 581 | return true; 582 | } 583 | } 584 | else 585 | { 586 | return true; 587 | } 588 | } 589 | } 590 | 591 | return false; 592 | } 593 | 594 | bool ToSInstanceScript::CheckFailure() 595 | { 596 | // Check if any alive in the arena. 597 | if (AnyPlayerInArena(true)) 598 | { 599 | return false; 600 | } 601 | 602 | NotifyFailure(); 603 | ResetEncounter(); 604 | 605 | return true; 606 | } 607 | 608 | void ToSInstanceScript::NotifyFailure() 609 | { 610 | std::string message = Acore::StringFormatFmt("|cffFF9900Trial of Strength Failed!|r", currentWave); 611 | Map::PlayerList const& players = instance->GetPlayers(); 612 | 613 | for (const auto& it : players) 614 | { 615 | Player* player = it.GetSource(); 616 | 617 | if (!player) 618 | continue; 619 | 620 | player->SendSystemMessage(message); 621 | player->PlayDirectSound(TOS_SOUND_FAIL); 622 | 623 | { 624 | WorldPacket data(SMSG_NOTIFICATION, (message.size() + 1)); 625 | data << message; 626 | 627 | player->SendDirectMessage(&data); 628 | } 629 | } 630 | } 631 | 632 | void ToSInstanceScript::SetupEncounter() 633 | { 634 | encounterInProgress = true; 635 | waveInProgress = true; 636 | waveCleared = false; 637 | 638 | auto waveTemplate = sToSMapMgr->GetWaveTemplateForWave(currentWave); 639 | if (!waveTemplate) 640 | { 641 | LOG_WARN("module", "Wave template is nullptr."); 642 | return; 643 | } 644 | 645 | totalWaves = sToSMapMgr->GetTotalWaves(); 646 | 647 | currentSubGroup = 1; 648 | auto subGroups = sToSMapMgr->GetSubGroups(waveTemplate->enemyGroup); 649 | totalSubGroups = subGroups.size(); 650 | 651 | if (totalSubGroups < 1) 652 | { 653 | LOG_WARN("module", "There were no subgroups found for wave {}.", currentWave); 654 | return; 655 | } 656 | 657 | instance->PlayDirectSoundToMap(TOS_SOUND_HORN); 658 | 659 | CleanupCreatures(); 660 | CleanupGameObjects(); 661 | DespawnCurseCrystals(); 662 | 663 | totalInvaders = GetCurrentWaveTotal(); 664 | SendInvadersWorldState(true, totalInvaders); 665 | 666 | events.ScheduleEvent(TOS_DATA_ENCOUNTER_START_NEXT_WAVE, 3s); 667 | events.ScheduleEvent(TOS_DATA_ENCOUNTER_CROWD, 1s); 668 | } 669 | 670 | void ToSInstanceScript::CheckWaveCompletion() 671 | { 672 | if (!IsSubWaveCleared()) 673 | { 674 | events.RescheduleEvent(TOS_DATA_ENCOUNTER_CHECK_WAVE_COMPLETE, 2s); 675 | return; 676 | } 677 | 678 | if (currentSubGroup < totalSubGroups) 679 | { 680 | currentSubGroup++; 681 | 682 | instance->PlayDirectSoundToMap(TOS_SOUND_HORN); 683 | events.ScheduleEvent(TOS_DATA_ENCOUNTER_START_NEXT_WAVE, 3s); 684 | } 685 | else 686 | { 687 | NotifyPlayers(); 688 | PopulateRewardChest(); 689 | CleanupCreatures(); 690 | SendInvadersWorldState(false); 691 | 692 | if (sConfigMgr->GetOption("TrialOfStrength.ResetCooldowns", true)) 693 | { 694 | ResetPlayerCooldowns(); 695 | } 696 | 697 | waveInProgress = false; 698 | waveCleared = true; 699 | cheerPlayed = false; 700 | 701 | if (currentWave == totalWaves) 702 | { 703 | trialCompleted = true; 704 | AnnounceCompletion(); 705 | } 706 | else 707 | { 708 | SpawnCurseCrystals(); 709 | } 710 | } 711 | } 712 | 713 | void ToSInstanceScript::ResetPlayerCooldowns() 714 | { 715 | Map::PlayerList const& players = instance->GetPlayers(); 716 | 717 | for (const auto& it : players) 718 | { 719 | Player* player = it.GetSource(); 720 | 721 | if (!player) 722 | continue; 723 | 724 | if (player->HasAura(TOS_SPELL_EXHAUSTION)) 725 | { 726 | player->RemoveAura(TOS_SPELL_EXHAUSTION); 727 | } 728 | 729 | sToSMapMgr->ResetCooldowns(player); 730 | } 731 | } 732 | 733 | void ToSInstanceScript::NotifyPlayers() 734 | { 735 | Map::PlayerList const& players = instance->GetPlayers(); 736 | 737 | for (const auto& it : players) 738 | { 739 | Player* player = it.GetSource(); 740 | 741 | if (!player) 742 | continue; 743 | 744 | std::string message = Acore::StringFormatFmt("|cffFFFFFFWave |cff00FF00{}|r |cffFFFFFFcleared!|r", currentWave); 745 | 746 | player->SendSystemMessage(message); 747 | player->PlayDirectSound(17316 /* RDF Reward Sound */); 748 | 749 | { 750 | WorldPacket data(SMSG_NOTIFICATION, (message.size() + 1)); 751 | data << message; 752 | 753 | player->SendDirectMessage(&data); 754 | } 755 | } 756 | } 757 | 758 | void ToSInstanceScript::PopulateRewardChest() 759 | { 760 | auto waveTemplate = sToSMapMgr->GetWaveTemplateForWave(currentWave); 761 | if (!waveTemplate) 762 | { 763 | return; 764 | } 765 | 766 | if (!waveTemplate->hasReward) 767 | { 768 | return; 769 | } 770 | 771 | auto rewardId = waveTemplate->rewardTemplate; 772 | 773 | if (!rewardId) 774 | { 775 | return; 776 | } 777 | 778 | Position* tempPos = new Position(255.194, -99.974, 18.677, 6.270); 779 | if ((rewardChest = instance->SummonGameObject(TOS_GOB_REWARD_CHEST, *tempPos, 0.0, 0.0, 0.0, 0.0, 0, true))) 780 | { 781 | rewardChest->loot.clear(); 782 | rewardChest->SetLootRecipient(instance); 783 | 784 | rewardChest->loot.items.reserve(MAX_NR_LOOT_ITEMS); 785 | 786 | auto rewardTemplates = sToSMapMgr->GetRewardTemplates(rewardId); 787 | if (!rewardTemplates || rewardTemplates->empty()) 788 | { 789 | LOG_ERROR("module", "Failed to find trial of strength reward templates!"); 790 | return; 791 | } 792 | 793 | for (auto rewardTemplate = rewardTemplates->begin(); rewardTemplate != rewardTemplates->end(); ++rewardTemplate) 794 | { 795 | uint32 chance = urand(0, 100); 796 | if (chance > rewardTemplate->chance) 797 | { 798 | continue; 799 | } 800 | 801 | LootStoreItem* lootStoreItem = new LootStoreItem(rewardTemplate->itemEntry, 0, 0, false, 1, 0, 1, 1); 802 | 803 | LootItem lootItem(*lootStoreItem); 804 | lootItem.itemIndex = rewardChest->loot.items.size(); 805 | lootItem.itemid = rewardTemplate->itemEntry; 806 | lootItem.follow_loot_rules = true; 807 | lootItem.freeforall = false; 808 | 809 | uint32 itemCount = urand(rewardTemplate->countMin, rewardTemplate->countMax); 810 | if (rewardTemplate->curseScalar) 811 | { 812 | itemCount = itemCount + ((GetCurseScaling() / 100) * rewardTemplate->curseScalar); 813 | } 814 | 815 | // hard cap the item count. 816 | lootItem.count = itemCount > rewardTemplate->countCap ? rewardTemplate->countCap : itemCount; 817 | 818 | rewardChest->loot.unlootedCount += 1; 819 | 820 | rewardChest->loot.items.push_back(lootItem); 821 | } 822 | 823 | uint32 minMoney = sConfigMgr->GetOption("TrialOfStrength.MinRewardMoney", 5000); 824 | uint32 maxMoney = sConfigMgr->GetOption("TrialOfStrength.MaxRewardMoney", 10000); 825 | 826 | if (sConfigMgr->GetOption("TrialOfStrength.Scaling.RewardMoney", true)) 827 | { 828 | uint32 scalar = sConfigMgr->GetOption("TrialOfStrength.Scaling.RewardMoneyScalar", 50); 829 | uint32 curseScaling = 1 + (GetCurseScaling() / scalar); 830 | 831 | minMoney = minMoney * curseScaling; 832 | maxMoney = maxMoney * curseScaling; 833 | } 834 | 835 | uint32 capMoney = sConfigMgr->GetOption("TrialOfStrength.CapRewardMoney", 1000000); 836 | 837 | minMoney = minMoney > capMoney ? capMoney : minMoney; 838 | maxMoney = maxMoney > capMoney ? capMoney : maxMoney; 839 | 840 | rewardChest->loot.generateMoneyLoot(minMoney, maxMoney); 841 | 842 | rewardChest->SetLootGenerationTime(); 843 | rewardChest->SetLootState(GO_READY); 844 | } 845 | 846 | rewardBeam = instance->SummonGameObject(TOS_GOB_REWARD_BEAM, *tempPos, 0.0, 0.0, 0.0, 0.0, 0, true); 847 | } 848 | 849 | bool ToSInstanceScript::IsRewardChestEmpty() 850 | { 851 | if (!rewardChest || !rewardChest->IsInWorld()) 852 | { 853 | return true; 854 | } 855 | 856 | return rewardChest->loot.unlootedCount < 1; 857 | } 858 | 859 | void ToSInstanceScript::SetData(uint32 dataId, uint32 value) 860 | { 861 | switch (dataId) 862 | { 863 | case TOS_DATA_ENCOUNTER_START: 864 | events.ScheduleEvent(TOS_DATA_ENCOUNTER_START, 0s); 865 | break; 866 | 867 | case TOS_DATA_ENCOUNTER_CURRENT_WAVE: 868 | currentWave = value; 869 | break; 870 | 871 | case TOS_DATA_ENCOUNTER_RESET: 872 | ResetEncounter(); 873 | break; 874 | 875 | case TOS_DATA_ENCOUNTER_UPDATE_INVADERS: 876 | totalInvaders -= 1; 877 | UpdateInvadersWorldState(totalInvaders); 878 | break; 879 | } 880 | } 881 | 882 | uint32 ToSInstanceScript::GetData(uint32 dataId) const 883 | { 884 | switch (dataId) 885 | { 886 | case TOS_DATA_ENCOUNTER_START: 887 | return encounterInProgress; 888 | 889 | case TOS_DATA_ENCOUNTER_CURRENT_WAVE: 890 | return currentWave; 891 | 892 | case TOS_DATA_ENCOUNTER_CURRENT_WAVE_CLEARED: 893 | return IsWaveCleared(); 894 | 895 | case TOS_DATA_ENCOUNTER_HAS_MORE_WAVES: 896 | return HasMoreWaves(); 897 | 898 | case TOS_DATA_ENCOUNTER_CURRENT_WAVE_REMAINING: 899 | return GetRemainingAlive(); 900 | 901 | case TOS_DATA_ENCOUNTER_CURRENT_SUBWAVE: 902 | return currentSubGroup; 903 | 904 | case TOS_DATA_ENCOUNTER_TOTAL_SUBWAVE: 905 | return totalSubGroups; 906 | 907 | case TOS_DATA_ENCOUNTER_TRIAL_COMPLETED: 908 | return trialCompleted; 909 | 910 | case TOS_DATA_ENCOUNTER_WAVE_IN_PROGRESS: 911 | return waveInProgress; 912 | } 913 | 914 | return 0; 915 | } 916 | 917 | bool ToSInstanceScript::IsEncounterInProgress() const 918 | { 919 | return encounterInProgress; 920 | } 921 | 922 | uint32 ToSInstanceScript::GetRemainingAlive() const 923 | { 924 | if (waveCreatures.empty()) 925 | { 926 | return 0; 927 | } 928 | 929 | uint32 count = 0; 930 | for (auto it = waveCreatures.begin(); it != waveCreatures.end(); ++it) 931 | { 932 | auto creature = *it; 933 | 934 | if (!creature) 935 | { 936 | continue; 937 | } 938 | 939 | if (creature->IsInWorld() && 940 | creature->IsAlive() && 941 | creature->GetMapId() == TOS_MAP_ID /*When creatures are cleaned up they end up on another map, wtf?*/) 942 | { 943 | count++; 944 | } 945 | } 946 | 947 | return count; 948 | } 949 | 950 | void ToSInstanceScript::CleanupCreatures() 951 | { 952 | if (waveCreatures.empty()) 953 | { 954 | return; 955 | } 956 | 957 | for (auto it = waveCreatures.begin(); it != waveCreatures.end(); ++it) 958 | { 959 | auto creature = *it; 960 | 961 | if (!creature || 962 | !creature->IsInWorld() || 963 | creature->GetMapId() != TOS_MAP_ID) 964 | { 965 | continue; 966 | } 967 | 968 | creature->DespawnOrUnsummon(); 969 | } 970 | 971 | waveCreatures.clear(); 972 | } 973 | 974 | void ToSInstanceScript::CleanupGameObjects() 975 | { 976 | if (rewardBeam && 977 | rewardBeam->IsInWorld()) 978 | { 979 | rewardBeam->Delete(); 980 | rewardBeam = nullptr; 981 | } 982 | 983 | if (rewardChest && 984 | rewardChest->IsInWorld()) 985 | { 986 | rewardChest->Delete(); 987 | rewardChest = nullptr; 988 | } 989 | } 990 | 991 | void ToSInstanceScript::ResetEncounter() 992 | { 993 | encounterInProgress = false; 994 | waveInProgress = false; 995 | cheerPlayed = false; 996 | 997 | currentWave = 1; 998 | totalWaves = 0; 999 | currentSubGroup = 1; 1000 | totalSubGroups = 0; 1001 | 1002 | waveCleared = false; 1003 | trialCompleted = false; 1004 | 1005 | events.Reset(); 1006 | events.ScheduleEvent(TOS_DATA_ENCOUNTER_CHECK_ARENA_MASTER_RELOCATE, 2s); 1007 | events.ScheduleEvent(TOS_DATA_PORTAL_TRY_TELEPORT, 1s); 1008 | 1009 | CleanupCreatures(); 1010 | CleanupGameObjects(); 1011 | DespawnCurseCrystals(); 1012 | 1013 | ClearCursesFromPlayers(); 1014 | 1015 | curses.clear(); 1016 | ReloadCurses(); 1017 | 1018 | if (arenaMasterLeft) 1019 | { 1020 | RelocateArenaMaster(true); 1021 | arenaMasterLeft = false; 1022 | } 1023 | } 1024 | 1025 | void ToSInstanceScript::AnnounceCompletion() 1026 | { 1027 | bool hasCurses = curses.size() > 0; 1028 | 1029 | std::stringstream ss; 1030 | ss << "|TInterface\\WorldMap\\Skull_64Red:16|t |cffFFFFFFCongratulations to player(s) "; 1031 | 1032 | Map::PlayerList const& players = instance->GetPlayers(); 1033 | auto playerCount = players.getSize(); 1034 | 1035 | uint32 i = 0; 1036 | for (const auto& it : players) 1037 | { 1038 | i++; 1039 | 1040 | Player* player = it.GetSource(); 1041 | 1042 | if (!player) 1043 | { 1044 | continue; 1045 | } 1046 | 1047 | ss << Acore::StringFormatFmt("{}{}", sToSMapMgr->GetHexColorFromClass(player->getClass()), player->GetName()); 1048 | 1049 | if (i != playerCount) 1050 | { 1051 | ss << "|cffFFFFFF, "; 1052 | } 1053 | } 1054 | 1055 | ss << Acore::StringFormatFmt(" |cffFFFFFFfor defeating all waves ({}) in the |cffFF2651Trial of Strength", sToSMapMgr->GetTotalWaves()); 1056 | 1057 | if (hasCurses) 1058 | { 1059 | ss << Acore::StringFormatFmt(" |cffFFFFFFwith |cffC436C1{}|cffFFFFFF curses!|r", curses.size()); 1060 | } 1061 | else 1062 | { 1063 | ss << "!|r"; 1064 | } 1065 | 1066 | sWorld->SendServerMessage(SERVER_MSG_STRING, ss.str()); 1067 | } 1068 | 1069 | void ToSInstanceScript::SendInvadersWorldState(bool state, uint32 invaders) 1070 | { 1071 | Map::PlayerList const& players = instance->GetPlayers(); 1072 | 1073 | if (players.IsEmpty()) 1074 | { 1075 | return; 1076 | } 1077 | 1078 | for (const auto& it : players) 1079 | { 1080 | Player* player = it.GetSource(); 1081 | 1082 | if (!player) 1083 | { 1084 | continue; 1085 | } 1086 | 1087 | WorldPacket packet(SMSG_INIT_WORLD_STATES); 1088 | 1089 | packet << uint32(534); // map 1090 | packet << uint32(3606); // zone 1091 | packet << uint32(0); // ukn1 1092 | packet << uint16(1); // ukn2 1093 | packet << uint32(2453); // stateId 1094 | packet << uint32(state ? 1 : 0); // stateValue 1095 | 1096 | player->SendDirectMessage(&packet); 1097 | player->SendUpdateWorldState(2454, invaders); 1098 | } 1099 | } 1100 | 1101 | void ToSInstanceScript::UpdateInvadersWorldState(uint32 invaders) 1102 | { 1103 | Map::PlayerList const& players = instance->GetPlayers(); 1104 | 1105 | if (players.IsEmpty()) 1106 | { 1107 | return; 1108 | } 1109 | 1110 | for (const auto& it : players) 1111 | { 1112 | Player* player = it.GetSource(); 1113 | 1114 | if (!player) 1115 | { 1116 | continue; 1117 | } 1118 | 1119 | player->SendUpdateWorldState(2454, invaders); 1120 | } 1121 | } 1122 | 1123 | uint32 ToSInstanceScript::GetCurrentWaveTotal() 1124 | { 1125 | auto waveTemplate = sToSMapMgr->GetWaveTemplateForWave(currentWave); 1126 | if (!waveTemplate) 1127 | { 1128 | return 0; 1129 | } 1130 | 1131 | return sToSMapMgr->GetEnemyCountForGroup(waveTemplate->enemyGroup); 1132 | } 1133 | -------------------------------------------------------------------------------- /src/scripts/ToSInstanceScript.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULE_TRIAL_OF_STRENGTH_INSTANCE_SCRIPT_H 2 | #define MODULE_TRIAL_OF_STRENGTH_INSTANCE_SCRIPT_H 3 | 4 | #include "ScriptMgr.h" 5 | 6 | #include "TrialOfStrength.h" 7 | #include "ToSMapMgr.h" 8 | 9 | class ToSInstanceScript : public InstanceScript 10 | { 11 | private: 12 | enum ToSInstanceConstants 13 | { 14 | TOS_SOUND_HORN = 6140, 15 | TOS_SOUND_CHEER = 13904, 16 | TOS_SOUND_FAIL = 847, 17 | 18 | TOS_GOB_REWARD_CHEST = 441250, 19 | TOS_GOB_REWARD_BEAM = 441251, 20 | TOS_GOB_CURSE = 441252, 21 | 22 | TOS_SPELL_EXHAUSTION = 57723 23 | }; 24 | public: 25 | ToSInstanceScript(Map* map) : InstanceScript(map) 26 | { 27 | arenaMaster = nullptr; 28 | arenaMasterLeft = false; 29 | 30 | rewardChest = nullptr; 31 | rewardBeam = nullptr; 32 | 33 | curseCrystal1 = nullptr; 34 | curseCrystal2 = nullptr; 35 | curseCrystal3 = nullptr; 36 | 37 | combatantPosStart = new Position(228.324, -99.921, 18.007, 6.282); 38 | combatantPosEnd = new Position(249.918, -100.063, 18.679, 0.030); 39 | 40 | ResetEncounter(); 41 | } 42 | void OnCreatureCreate(Creature* creature) override; 43 | 44 | bool IsSubWaveCleared() const; 45 | bool IsWaveCleared() const; 46 | bool HasMoreWaves() const; 47 | bool IsWaveInProgress() const; 48 | 49 | void SpawnNextWave(ToSWaveTemplate* /*waveTemplate = nullptr*/); 50 | 51 | void MakeEntrance(Creature* creature, float diff); 52 | void SetCombatantsHostile(); 53 | uint32 GetRemainingAlive() const; 54 | 55 | void AddCurse(uint32 curseId); 56 | void ApplyCurses(Unit* unit); 57 | void ApplyCursesToPlayers(); 58 | void ApplyAutoScaling(Creature* creature); 59 | void ClearCursesFromPlayers(); 60 | void SpawnCurseCrystals(); 61 | void DespawnCurseCrystals(); 62 | uint32 GetCurseForGUID(ObjectGuid guid); 63 | uint32 GetCurseScaling(); 64 | void ReloadCurses(); 65 | uint32 GetRandomAvailableCurse(); 66 | std::vector GetRandomAvailableCurses(uint32 count); 67 | void RemoveAvailableCurse(uint32 curseId); 68 | 69 | void Update(uint32 diff) override; 70 | 71 | void CheckArenaMasterRelocate(); 72 | void RelocateArenaMaster(bool returning); 73 | void TryTeleportPlayers(); 74 | 75 | bool AnyPlayerAlive(); 76 | bool AnyPlayerInArena(bool checkAlive = false); 77 | 78 | bool CheckFailure(); 79 | 80 | void NotifyFailure(); 81 | void ResetPlayerCooldowns(); 82 | void NotifyPlayers(); 83 | 84 | void SetupEncounter(); 85 | 86 | void CheckWaveCompletion(); 87 | void PopulateRewardChest(); 88 | bool IsRewardChestEmpty(); 89 | void AnnounceCompletion(); 90 | void SendInvadersWorldState(bool state, uint32 invaders = 0); 91 | void UpdateInvadersWorldState(uint32 invaders); 92 | uint32 GetCurrentWaveTotal(); 93 | 94 | void PlayCrowd(); 95 | 96 | void SetData(uint32 dataId, uint32 value) override; 97 | uint32 GetData(uint32 dataId) const override; 98 | 99 | bool IsEncounterInProgress() const override; 100 | 101 | void CleanupCreatures(); 102 | void CleanupGameObjects(); 103 | void ResetEncounter(); 104 | 105 | private: 106 | EventMap events; 107 | 108 | bool encounterInProgress; 109 | bool waveInProgress; 110 | 111 | uint32 currentWave; 112 | uint32 totalWaves; 113 | uint32 currentSubGroup; 114 | uint32 totalSubGroups; 115 | uint32 totalInvaders; 116 | 117 | bool waveCleared; 118 | bool trialCompleted; 119 | bool cheerPlayed; 120 | 121 | std::vector waveCreatures; 122 | std::vector curses; 123 | std::vector availableCurseIds; 124 | 125 | Creature* arenaMaster; 126 | bool arenaMasterLeft; 127 | 128 | Position* combatantPosStart; 129 | Position* combatantPosEnd; 130 | 131 | GameObject* rewardChest; 132 | GameObject* rewardBeam; 133 | 134 | GameObject* curseCrystal1; 135 | uint32 curseId1; 136 | GameObject* curseCrystal2; 137 | uint32 curseId2; 138 | GameObject* curseCrystal3; 139 | uint32 curseId3; 140 | }; 141 | 142 | #endif // MODULE_TRIAL_OF_STRENGTH_INSTANCE_SCRIPT_H 143 | -------------------------------------------------------------------------------- /src/scripts/ToSPlayerScript.cpp: -------------------------------------------------------------------------------- 1 | #include "ToSPlayerScript.h" 2 | 3 | #include "TrialOfStrength.h" 4 | #include "ToSMapMgr.h" 5 | 6 | #include "Chat.h" 7 | 8 | bool ToSPlayerScript::CanRepopAtGraveyard(Player* player) 9 | { 10 | if (!player) 11 | { 12 | return true; 13 | } 14 | 15 | if (player->GetMapId() != TOS_MAP_ID) 16 | { 17 | return true; 18 | } 19 | 20 | player->TeleportTo(TOS_MAP_ID, 176.724, -116.484, 18.677, 4.732); 21 | 22 | if (player->isDead()) 23 | { 24 | player->ResurrectPlayer(100, false); 25 | 26 | if (player->HasCorpse()) 27 | { 28 | player->RemoveCorpse(); 29 | } 30 | } 31 | 32 | return false; 33 | } 34 | 35 | bool ToSPlayerScript::OnBeforeTeleport(Player* player, uint32 mapId, float /*x*/, float /*y*/, float /*z*/, float /*orientation*/, uint32 /*options*/, Unit* /*target*/) 36 | { 37 | if (!player) 38 | { 39 | return true; 40 | } 41 | 42 | if (!sToSMapMgr->CanPlayerEnter(player) && mapId == TOS_MAP_ID) 43 | { 44 | ChatHandler(player->GetSession()).SendSysMessage("|cffFF0000You do not meet the requirements to enter the Trial of Strength.|r"); 45 | return false; 46 | } 47 | 48 | auto oldMapId = player->GetMapId(); 49 | if (oldMapId != TOS_MAP_ID) 50 | { 51 | return true; 52 | } 53 | 54 | if (mapId == TOS_MAP_ID) 55 | { 56 | return true; 57 | } 58 | 59 | sToSMapMgr->ClearCurses(player); 60 | 61 | // Disable the invaders worldstate. 62 | { 63 | WorldPacket packet(SMSG_INIT_WORLD_STATES); 64 | 65 | packet << uint32(534); // map 66 | packet << uint32(3606); // zone 67 | packet << uint32(0); // ukn1 68 | packet << uint16(1); // ukn2 69 | packet << uint32(2453); // stateId 70 | packet << uint32(0); // stateValue 71 | 72 | player->SendDirectMessage(&packet); 73 | } 74 | 75 | return true; 76 | } 77 | 78 | void ToSPlayerScript::OnLogin(Player* player) 79 | { 80 | if (!player) 81 | { 82 | return; 83 | } 84 | 85 | sToSMapMgr->ClearCurses(player); 86 | } 87 | -------------------------------------------------------------------------------- /src/scripts/ToSPlayerScript.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULE_TRIAL_OF_STRENGTH_PLAYER_SCRIPT_H 2 | #define MODULE_TRIAL_OF_STRENGTH_PLAYER_SCRIPT_H 3 | 4 | #include "ScriptMgr.h" 5 | 6 | #include "Player.h" 7 | 8 | class ToSPlayerScript : public PlayerScript 9 | { 10 | public: 11 | ToSPlayerScript() : PlayerScript("ToSPlayerScript") { } 12 | 13 | bool CanRepopAtGraveyard(Player* /*player*/) override; 14 | bool OnBeforeTeleport(Player* /*player*/, uint32 /*mapId*/, float /*x*/, float /*y*/, float /*z*/, float /*orientation*/, uint32 /*options*/, Unit* /*target*/) override; 15 | void OnLogin(Player* /*player*/) override; 16 | }; 17 | 18 | #endif // MODULE_TRIAL_OF_STRENGTH_PLAYER_SCRIPT_H 19 | -------------------------------------------------------------------------------- /src/scripts/ToSUnitScript.cpp: -------------------------------------------------------------------------------- 1 | #include "ToSUnitScript.h" 2 | #include "TrialOfStrength.h" 3 | 4 | void ToSUnitScript::OnUnitDeath(Unit* unit, Unit* /*killer*/) 5 | { 6 | if (!sConfigMgr->GetOption("TrialOfStrength.Enable", false)) 7 | { 8 | return; 9 | } 10 | 11 | if (!unit) 12 | { 13 | return; 14 | } 15 | 16 | if (unit->IsPlayer()) 17 | { 18 | return; 19 | } 20 | 21 | if (unit->GetMapId() != TOS_MAP_ID) 22 | { 23 | return; 24 | } 25 | 26 | unit->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE); 27 | 28 | auto iScript = unit->GetInstanceScript(); 29 | if (!iScript) 30 | { 31 | return; 32 | } 33 | 34 | iScript->SetData(TOS_DATA_ENCOUNTER_UPDATE_INVADERS, 1); 35 | } 36 | 37 | void ToSUnitScript::ModifySpellDamageTaken(Unit* /*target*/, Unit* attacker, int32& damage, SpellInfo const* /*spellInfo*/) 38 | { 39 | if (!sConfigMgr->GetOption("TrialOfStrength.Enable", false)) 40 | { 41 | return; 42 | } 43 | 44 | if (!attacker) 45 | { 46 | return; 47 | } 48 | 49 | if (attacker->IsPlayer()) 50 | { 51 | return; 52 | } 53 | 54 | if (attacker->GetMapId() != TOS_MAP_ID) 55 | { 56 | return; 57 | } 58 | 59 | if (!sConfigMgr->GetOption("TrialOfStrength.AutoScaling", true)) 60 | { 61 | return; 62 | } 63 | 64 | auto map = attacker->GetMap(); 65 | if (!map) 66 | { 67 | return; 68 | } 69 | 70 | auto instance = map->ToInstanceMap(); 71 | if (!instance) 72 | { 73 | return; 74 | } 75 | 76 | auto iScript = instance->GetInstanceScript(); 77 | if (!iScript) 78 | { 79 | return; 80 | } 81 | 82 | uint32 originalLevel = attacker->ToCreature()->GetCreatureTemplate()->maxlevel; 83 | 84 | uint32 currentWave = iScript->GetData(TOS_DATA_ENCOUNTER_CURRENT_WAVE); 85 | uint32 damageDivider = sConfigMgr->GetOption("TrialOfStrength.AutoScaling.BaseDamage.SpellDivider", 15); 86 | 87 | uint32 newDamage = ((damage) * ((83 - originalLevel) / 2) / damageDivider) * currentWave; 88 | } 89 | -------------------------------------------------------------------------------- /src/scripts/ToSUnitScript.h: -------------------------------------------------------------------------------- 1 | #ifndef MODULE_TRIAL_OF_STRENGTH_UNIT_SCRIPT_H 2 | #define MODULE_TRIAL_OF_STRENGTH_UNIT_SCRIPT_H 3 | 4 | #include "ScriptMgr.h" 5 | 6 | #include "Player.h" 7 | 8 | class ToSUnitScript : public UnitScript 9 | { 10 | public: 11 | ToSUnitScript() : UnitScript("ToSUnitScript") { } 12 | 13 | void OnUnitDeath(Unit* /*unit*/, Unit* /*killer*/) override; 14 | 15 | void ModifySpellDamageTaken(Unit* /*target*/, Unit* /*attacker*/, int32& /*damage*/, SpellInfo const* /*spellInfo*/) override; 16 | }; 17 | 18 | #endif // MODULE_TRIAL_OF_STRENGTH_UNIT_SCRIPT_H 19 | --------------------------------------------------------------------------------