146 Commits

Author SHA1 Message Date
Ben Carter
565922c456 Revise README with project updates and goals
My update
2026-03-07 11:16:00 -05:00
Ben Carter
85b82d923e Update README.md
Fixed more wrong AI generated shit
2025-08-31 10:34:20 -04:00
Ben Carter
e53469c1ba Update README.md 2025-08-24 09:09:07 -04:00
Ben Carter
33f4d3d7ff Update README.md 2025-08-23 22:31:59 -04:00
Ben Carter
8ef539f817 Update README.md
Complete Readme v1
2025-08-23 22:30:33 -04:00
Ben Carter
d469f1c632 Merge pull request #34 from araxiaonline/araxia-main
Araxia main
2025-08-23 22:29:49 -04:00
Ben Carter
336a0a3257 Merge pull request #33 from araxiaonline/feature/full-expansion-upgrade
Feature/full expansion upgrade
2025-08-23 20:58:39 -04:00
Ben Carter
b8d4c5e698 Update data/sql/db-world/base/09_custom_items.sql
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-08-23 20:57:24 -04:00
Ben Carter
9120666bd5 Update data/sql/db-world/base/09_custom_items.sql
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-08-23 20:57:15 -04:00
8fbb47b5b6 Fixes from Gemini review 2025-08-23 16:41:56 -04:00
716ca94e73 resolve sql nullable key 2025-08-23 14:36:41 -04:00
fa81bd6f79 Added money fixes on mythic 2025-08-23 14:33:33 -04:00
e8ddac961d fixes xp and gold for scaled creatures 2025-08-22 01:14:06 -04:00
74c529a2b0 Added sql for molten core raid and rebalance of low ilevel gear 2025-08-21 01:30:34 -04:00
4801ab5484 Added death handlers for creatures 2025-08-21 01:30:30 -04:00
5fca712e62 Added creature scaling fixes for respawn and scripted events. 2025-08-21 01:29:47 -04:00
1b1c54782b Scaling updates for non creatures and fixes for elemental damage melee 2025-08-01 18:50:14 -04:00
3f3f63f90e Updates to enemy scaling mechanics for heroic, raids 2025-08-01 10:06:55 -04:00
64dd608dc4 Merge branch 'feature/full-expansion-upgrade' of https://github.com/araxiaonline/mod-mythic-plus into feature/full-expansion-upgrade 2025-07-19 09:47:50 -04:00
2dbbccc6eb updating spell damage mechanics 2025-07-19 09:47:30 -04:00
Ben Carter
f225a8211b Update src/MythicPlus.cpp
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-07-19 09:45:59 -04:00
1481fe1cce Major overhauls of key systems and scripts 2025-07-18 19:49:02 -04:00
53218b487a Major updates to the entire system lots of content changes. 2025-07-18 19:48:36 -04:00
7618b2af58 Added new commands and fixed PlayerScript dupe issue. 2025-02-09 23:25:48 -05:00
586858c485 updates to upgrade advancement event and new handlers 2025-02-09 23:25:41 -05:00
a5b22f84ed major fixes to advancement handler which is not upgrading stats correctly 2025-02-09 23:25:22 -05:00
f0f3b26229 updated index and added resistances 2025-02-09 23:24:46 -05:00
18bb3e6599 Updated logger, and fixed up event handlers 2025-02-04 00:24:08 -05:00
15c4e22967 updated for resist information 2025-02-04 00:23:36 -05:00
27db74e2ae Merge branch 'araxia-main' into refactor-scripts 2025-01-24 17:27:05 -05:00
ad39d53c58 fixed issues for newest version 2025-01-24 17:13:52 -05:00
Ben Carter
1cac20f7a5 Merge pull request #30 from araxiaonline/araxia-main
Updates to work with latest acore source
2025-01-18 11:38:42 -05:00
b4013b7024 commented ideas on how the perma stat bonuses will work with custom auras 2025-01-18 11:34:08 -05:00
7d1a9018df Many changes to bring in the Advancement system for upgrading player stats via dice 2025-01-18 11:29:21 -05:00
d4fa53d435 Updates to bring in event handlers for communication and register on server load 2025-01-18 11:28:07 -05:00
2aeafa689a New client event dispatchers to commumicate to WoW Client using formatted event structure 2025-01-18 11:27:30 -05:00
5986d314c7 Updates to work with latest acore source 2025-01-12 18:22:35 -05:00
f42cba3099 removed the CreatureHooks calls until later implemented 2024-12-17 17:48:16 -05:00
aa58b493ba move data channel to event processor since it makes more sense with that class 2024-12-17 17:47:28 -05:00
5387960965 Added EventProcessor for client and server communication 2024-12-17 17:43:13 -05:00
4be3fae368 Fixed warnings and updated comments 2024-12-13 19:19:29 -05:00
d410220bd0 Added methods for upgrading an advancement 2024-12-13 19:19:10 -05:00
4df7800afa Fixed all Warnings and added in advancement methods + material types loader 2024-12-13 19:18:44 -05:00
173d19bcd3 Fixed all Warnings and added in advancement methods + material types loader 2024-12-13 19:18:33 -05:00
738194fbfa added many methods related to increasing a players rank 2024-12-12 23:42:16 -05:00
81b7a87ced Added a new constant for MAX Advancement Ranks 2024-12-12 23:41:41 -05:00
8e0809cb1c Added constants for items 2024-12-12 18:53:08 -05:00
cb48af9e9d Added historical record for player advancmenets 2024-12-12 18:52:52 -05:00
acf11d25f2 Added information about the data channel used for client to server communication. 2024-12-11 15:41:36 -05:00
41fd4876cf renamed function 2024-12-11 15:40:44 -05:00
ef62c10df3 Updated schema definition 2024-12-11 15:40:24 -05:00
5fbb0eac74 Added in methods for loading in data for players 2024-12-11 15:40:00 -05:00
0982e24f06 Added Loading of advancments from database on server start and player login. 2024-12-11 15:39:45 -05:00
fa7389f24a Reorganized and fixed issues with material / types and ranks 2024-12-11 15:39:12 -05:00
8436460350 Added scheduling and fixed for death counting 2024-12-02 23:57:21 -05:00
3bd1f3cdc6 Added more handlers for players 2024-12-02 23:57:03 -05:00
6115459150 Added new sql changes for advancement 2024-12-02 23:56:22 -05:00
3093ab3280 Added new Advancement Manager classes for allowing upgrades 2024-12-02 23:56:01 -05:00
fa6f3f3eab Refactored scripts and Creature data 2024-11-29 15:25:38 -05:00
ccf222ec4f fixed issue with misaligned group deaths 2024-11-26 00:15:04 -05:00
91d3f91dfc Group data and player data objects were not referencing the same object corrected using right pointers 2024-11-25 23:55:50 -05:00
9612974b01 Added functions to store player data on bind 2024-11-24 23:53:14 -05:00
fd5e186032 Added boot on deaths limits hit 2024-11-24 21:51:13 -05:00
baf0d8e6e7 Added difficulty to death stats 2024-11-22 19:12:08 -05:00
f3230a6559 Merge branch 'main' of https://github.com/araxiaonline/mod-mythic-plus 2024-11-22 14:14:08 -05:00
86d5ba83f1 merged in branch and handled conflicts 2024-11-22 14:08:50 -05:00
Ben Carter
318244f0fd Merge pull request #9 from araxiaonline/feat/add-data-saves
Feature: Adds in data saves and upgrade system
2024-11-22 13:46:40 -05:00
73018100ac Turned on player scripts have segfault in bind to instance that needs fixed. 2024-11-21 23:52:02 -05:00
fbcb218dd6 player instance saves are working now on group entry 2024-11-21 23:25:46 -05:00
322243abf4 TEsting database stats saves. 2024-11-21 22:52:04 -05:00
9d009d0feb fixed segmentation fault related to null pointer 2024-11-21 22:52:01 -05:00
a0fdfc9836 Added golang script to generate ranks for stat level ups 2024-11-21 22:51:02 -05:00
a6de416efb Added more material types used for currency into game 2024-11-20 23:55:56 -05:00
1695f33f68 Added in new material types for resistances. 2024-11-19 23:28:55 -05:00
88d894eaaf Added schemas and material type data 2024-11-18 23:16:30 -05:00
f66b861079 updated scripts and reoganized them. Addded upgrade ranks script 2024-11-18 23:15:30 -05:00
79cb4d9835 Added more schemas used for tracking player instance data. 2024-11-17 11:22:09 -05:00
c32b64bb1f Added a bunch of methods for saving database information on key events 2024-11-14 23:12:25 -05:00
f083748c4a Added Mythic Plus method isFinalBoss for determining completion of run. 2024-11-14 19:52:53 -05:00
3cf1e17c99 Added more database storage of stats, timers, death and workign on final boss detection. 2024-11-14 00:07:36 -05:00
0a0236b273 updated the schema for stats and run s 2024-11-13 22:22:25 -05:00
8942d53b13 Fixed compile errors 2024-11-11 23:07:55 -05:00
41819432e9 updated command script to use new method signature for group data 2024-11-11 23:02:12 -05:00
d35a934b8a more work on player and group data storage for death counts and other stats 2024-11-11 22:56:18 -05:00
46d5a99f04 fixed issue with wrong type for player instance data 2024-11-08 18:15:56 -05:00
f8ecc0d1b9 Adding in player instance data 2024-11-08 00:53:43 -05:00
fcce3a0453 updated sql and added more methods to store state between server / character login/out 2024-11-07 23:41:40 -05:00
68efd1a732 Added instance resets when difficulty is changed and added personal difficulty tracking 2024-11-05 01:06:30 -05:00
9f4ea9d539 adding rescale all command and updated factors sql 2024-11-04 23:36:27 -05:00
803cb246bf updated to fix horsemen health scaling 2024-11-01 20:14:01 -04:00
1bd94e56fa Added easier way to tune up and down zones 2024-11-01 19:48:30 -04:00
0ee3ead805 Added new AP fixes and working on healing fixes for enemy creature 2024-10-29 19:45:30 -04:00
ec1663aa34 Removed ai change 2024-10-18 21:38:50 -04:00
3d0f314c39 updated to add headless horseman 2024-10-18 20:37:48 -04:00
5877e9122c Added event system and updated Bazzalan as a test. 2024-10-18 19:24:33 -04:00
5847754197 Added scale to respawn trigger, added creaturehook add to instance when creature is scaled. 2024-10-14 23:25:00 -04:00
6936f8b73e Added event handler for extending boss functions without disrupting existing AI or Eluna scripts. 2024-10-14 22:20:23 -04:00
a35e4b646d added changes to include difficulty into ai object 2024-10-13 23:30:27 -04:00
a4d7b00036 Got AI Event system working 2024-10-12 19:53:28 -04:00
73c2b8923b Added new base class for updating creatures for events from AI 2024-10-12 19:53:10 -04:00
d3af7990cb Added updates to all the melee and spell damage 2024-10-11 20:20:28 -04:00
25f74e1b5a Added new event handler system for creature events to allow for balancing 2024-10-10 00:55:00 -04:00
cbec66031d Adding event system for override necessary to balance higher levels 2024-10-08 23:58:59 -04:00
4a8731c876 Added first boss override script for balancing. 2024-10-07 23:43:21 -04:00
a62df56099 New spell scaling spell and command for reloading scaling factors 2024-10-05 22:44:06 -04:00
7f78971e49 added sql for leveling up pets to 90 2024-10-05 22:12:37 -04:00
c73dba69d7 Added new melee scaling 2024-10-04 20:41:52 -04:00
b9825b47e0 Working on spell scaling individually per dungeon to make sur eI account for everything and many different spells 2024-10-03 01:13:29 -04:00
cbde9bbfe2 Updated EligibleDamageTarget additional safeguard on owner check. 2024-10-02 23:27:33 -04:00
af9e7b3f3f Added pets generator script and fixed segfaults in eligible methods 2024-10-02 00:05:32 -04:00
5b6805dcc7 Added studio code props / settins 2024-10-01 22:56:41 -04:00
78648bd511 Added necessary sql files 2024-10-01 22:56:29 -04:00
Ben Carter
fd4c9d2b51 Merge pull request #2 from araxiaonline/feat/add-mythic-v1
Build: Feat/add mythic v1
2024-10-01 22:45:13 -04:00
2fda1c1a93 Scaling updates for Attack Power 2024-10-01 19:50:07 -04:00
ca1dda4979 Added debug command to CommandScript 2024-10-01 00:10:34 -04:00
04dc95f2e3 Addressed compile error not being defined in MythicPlus.h 2024-09-30 21:12:15 -04:00
d7e1f7a026 Adding base increases to normalize damange similar to heroic dungeons from normal 2024-09-30 21:03:28 -04:00
b6e21b5cf7 Adding scaling factors to how damage is scaled 2024-09-30 00:23:56 -04:00
e4a234b567 more work on unit script to increase damage 2024-09-29 02:27:54 -04:00
c4be5d44be Adding Spell scaling into base class 2024-09-29 02:04:02 -04:00
ff5eb09faa Refactored unit damage to be cleaner 2024-09-28 18:35:42 -04:00
6356d975d8 alpha seems to be working 2024-09-27 00:48:08 -04:00
5815d20c1c Added logging to test enemy weapon damage out and adding different setting for weapon base damage for enemies. 2024-09-26 23:34:25 -04:00
abee7bcc41 Added . eligible target checks and attempting to debug damage scalin for non-player supporters 2024-09-26 01:13:53 -04:00
014773379e Added changes to scaling and some debugging logic around the unit scripts 2024-09-25 22:32:38 -04:00
d74e9f96e1 Added more umph to multiplier on base damage 2024-09-25 01:28:45 -04:00
519d17a272 Added Unit damage code and removed chatty logging 2024-09-25 01:19:16 -04:00
7b79bf0316 Added Creature Map tracking and improved performance on storage 2024-09-20 23:28:58 -04:00
3b7c03ce0f Scaling tests are working for base stats 2024-09-20 01:28:33 -04:00
e7d1b85074 Added Scaling to boss and figured out event race conditions 2024-09-20 01:17:39 -04:00
7a73671b0f Added level ups for creatures and better logging around creature events 2024-09-19 00:59:40 -04:00
02f27a32f1 Added in leveling for enemies 2024-09-05 23:52:05 -04:00
a626114043 fixed typo in configuration settings and switched to afterconfig load 2024-09-03 23:42:14 -04:00
f98ec7ad57 Added in logic for when player enters an instance to store details and updated config settings 2024-09-03 23:01:31 -04:00
d98a0345d7 fixed compile issues for first compile and updated conf to remove duplicates 2024-09-02 00:37:11 -04:00
ef206b6a0d Merge branch 'main' into feat/add-mythic-v1 2024-09-01 23:54:11 -04:00
Ben Carter
3428bcc605 Merge pull request #1 from araxiaonline/feat/update-loot
Added scaled stats and mythicplus table up to 100
2024-09-01 23:53:35 -04:00
84543dc17a Added Legendary and Ascendant static shortcut commands 2024-09-01 23:50:31 -04:00
9a2b880350 Finished up commands 2024-09-01 23:49:35 -04:00
f7e2bf2450 Adding scripts that add creature higher level stats 2024-09-01 01:35:31 -04:00
3383cb1323 Added methods for saving group data to memory and the database
Also added some new commands
2024-09-01 01:34:35 -04:00
2c8b67ef07 Changed MythicPlus and MpDataStore to pure singletons and updated current
calling scripts to not get the instance just call via defined macro
2024-08-31 23:17:52 -04:00
87d748cef6 Added initial pass at configuration variables for mythic plus 2024-08-31 22:21:59 -04:00
a5dd94fe54 Adding data storage and commands 2024-08-17 20:51:27 -04:00
7446c676f2 Building out data stores. Moved logging to standalone class. 2024-08-05 22:19:46 -04:00
0415c5ef41 Starting to build out the base setup for the module 2024-08-03 23:06:45 -04:00
75 changed files with 61409 additions and 352 deletions

22
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,22 @@
{
"configurations": [
{
"name": "AzerothCore",
"includePath": [
"${workspaceFolder}/src/common/Logging/**",
"${workspaceFolder}/src",
"${workspaceFolder}/deps",
"${workspaceFolder}/**",
"/opt/homebrew/include"
],
"defines": [
"AZEROTHCORE"
],
"compilerPath": "/usr/bin/clang++", // macOS typically uses clang as the default compiler
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "macos-clang-x64"
}
],
"version": 4
}

339
README.md
View File

@@ -0,0 +1,339 @@
# Mythic Plus Module for AzerothCore
📣 **long overdue update**: This has been a passion project and relaxing output of my time. I was laid off, had to get surgery, then get a real job again at a high demand start-up that has uses up all my programming energy.
I also took a pause on this to build out some new action based mechanics for encounters, really early days on that and experimental.
I expect to come back to working on this project in a few months when as I am really getting the itch to revisit and **finish this**.
So what does that mean?
**Do the boring stuff**:
1. upgrade everything to latest version of npc bots and patch any problems.
2. start a fresh version not modified version and install as well as script a custom installer for the sql needs.
3. Write thorough docs on how to install this.
**Finish the content:**
1. Finish the remaining NPC trainers for new leveling tradeskills and make them more accessible.
2. Retool the items one final time simplifying the sprawl that happened while I iterated on item creator.
3. Add in the legendary and ascendant paths I always intended to complete
That list seems short but it is not, low effort or small amount of time I assure you.
Once I have checked those off... I am going to call this done.
I will fix bugs and put into maintainer mode, so only upgrading from new patches down from acore trickerrer, as I can.
👊 If you want to help me accomplish this to make it happen faster and have some programming skills or cash for AI credits to generate code, please DM me on discord, I am in all the WoW channels.
Look forward to completing this project and giving it to the rest of my nostalgic gamers out there.
-- Volek
🚨 **This is not mythic like in retail.** 🚨
This module started with the intention of creating a retail-like mythic plus system but has evolved into something unique. Instead, think of it as an **expansion of existing Wrath to new end game conte r** that reuses much of the existing dungeons and creatures, overhauling them to much higher difficulties with new loot mechanics.
## Overview
The Mythic Plus module transforms existing World of Warcraft dungeons (Wrath of the Lich King to add additional endgame content) into challenging, scaled encounters with progressive difficulty levels, enhanced rewards, and unique gameplay mechanics to extend gameplay experience.
## Features
### Core Systems
- **Progressive Difficulty Scaling**: Multiple tiers of difficulty that scale creature stats, abilities, and rewards
- **Player Advancement System**: Custom advancements for mythic plus progression, completion times, and special challenges
- **Voiced NPCs**: Enhanced immersion with voice acting for key NPCs and encounters
- **Dynamic Loot System**: New loot mechanics with scaled rewards based on difficulty completed
- **Death Penalty System**: Configurable death penalties that affect progression
- **Time-Based Challenges**:
- (In progress)
### Massive Content Expansion
- **50,000+ New Items**: Completely new item database with scaled equipment for all difficulty tiers
- **New Rare Materials**: Custom crafting materials and rare drops exclusive to mythic plus content
- **Reworked Tier Gear**: All expansion tier sets completely reworked and rebalanced for mythic plus scaling
- **Cross-Expansion Integration**: Unified progression system spanning Vanilla through Wrath
### Difficulty Tiers
The module supports multiple difficulty levels with configurable scaling:
- **Mythic Dungeons**: Base enhanced difficulty with improved creature stats and new rare material drops
- **Legendary Dungeons**: In progress
- **Ascendant Dungeons**: In progress
### Per-Dungeon Customization
- **Database-Driven Scaling**: Each dungeon can have unique scaling values configured through database tables
- **Individual Encounter Tuning**: Specific creatures and bosses can have custom multipliers independent of global settings
- **Dungeon-Specific Materials**: Unique rare materials and rewards exclusive to certain dungeons or difficulty combinations
### Creature Enhancements
- **Health & Damage Scaling**: Configurable multipliers for different difficulty tiers
- **Voiced Encounters**: Important NPCs and bosses feature voice acting for enhanced immersion
- **Cross-Expansion Itemization**: Unified item progression that spans all supported expansions
## Installation
### Prerequisites
-- Trickerer Acore or Azerothcore
- MySQL database 8.4
- C++ compiler with C++20 support
- docker for most tested experience
- companion lua scripts **more details coming here**
### Build Process
1. **Clone the repository** into your AzerothCore modules directory:
```bash
cd /path/to/azerothcore/modules
git clone https://github.com/araxiaonline/mod-mythic-plus.git
```
2. **Rebuild AzerothCore** with the module:
```bash
cd /path/to/azerothcore/build
make -j$(nproc)
```
3. **Install database changes**:
Database changes will be installed using azerothcores built in script, if it does not you can use the following commands below:
```bash
# Apply the SQL files from data/sql/ in the correct order
# Note: This includes extensive item database additions (50,000+ items)
# and achievement system integration
mysql -u username -p acore_world < modules/mod-mythic-plus/data/sql/db-characters/*.sql
mysql -u username -p acore_world < modules/mod-mythic-plus/data/sql/db-world/*.sql
# Verify the massive item additions were applied successfully
# The module includes a complete item database overhaul
```
### Configuration
1. **Copy the configuration file**:
```bash
cp modules/mod-mythic-plus/conf/mod-mythic-plus.conf.dist /path/to/azerothcore/etc/modules/mod-mythic-plus.conf
```
2. **Edit the configuration file** to customize your settings:
```bash
nano /path/to/azerothcore/etc/modules/mod-mythic-plus.conf
```
## Configuration Options
### Global Settings
```ini
# Enable/disable the entire Mythic Plus system
MythicPlus.Enabled = 1
# Enable enhanced rewards system
MythicPlus.EnableEnhancedRewards = 1
# Enable achievement system integration
MythicPlus.EnableAchievementSystem = 1
# Enable death limit system for dungeons
MythicPlus.EnableDeathLimits = 1
```
### Difficulty Scaling
```ini
# Mythic tier creature scaling
MythicPlus.Mythic.DungeonHealth = 1.5
MythicPlus.Mythic.DungeonDmg = 1.25
MythicPlus.Mythic.DungeonDmgSpell = 1.3
MythicPlus.Mythic.DungeonArmor = 1.25
MythicPlus.Mythic.DungeonXPGain = 1.5
# Legendary tier creature scaling
MythicPlus.Legendary.DungeonHealth = 2.25
MythicPlus.Legendary.DungeonDmg = 2.25
MythicPlus.Legendary.DungeonDmgSpell = 2.75
MythicPlus.Legendary.DungeonArmor = 3.25
MythicPlus.Legendary.DungeonXPGain = 85
# Ascendant tier creature scaling
MythicPlus.Ascendant.DungeonHealth = 3.25
MythicPlus.Ascendant.DungeonDmg = 3.25
MythicPlus.Ascendant.DungeonDmgSpell = 3.75
MythicPlus.Ascendant.DungeonArmor = 3.25
MythicPlus.Ascendant.DungeonXPGain = 87
```
### Death Penalty Settings
```ini
# Death limits before failure
MythicPlus.Death.DeathLimit = 5
# Enable/disable death penalties
MythicPlus.EnableDeathDifficulties = 1
# Death penalty scaling
MythicPlus.DisableDamageSpell = 1
```
## Supported Dungeons
The module enhances dungeons from multiple expansions:
### Wrath of the Lich King
- All major dungeons receive scaling enhancements
- Heroic and normal modes both supported
- Enhanced creature abilities and mechanics
###
### Cross-Expansion Features
- Unified scaling system across all supported content
- Consistent reward progression regardless of original expansion
- Balanced challenge curve from entry-level to extreme difficulti
## Commands
### Player Commands
- **`.mythicplus info`** - Display current dungeon difficulty and stats
- **`.mythicplus status`** - Show personal mythic plus progression and achievements
- **`.mythicplus materials`** - View collected rare materials and crafting components
- **`.mythicplus tokens`** - Check endgame token balance and available exchanges
- **`.mythicplus achievements`** - Display mythic plus specific achievement progress
- **`.mythicplus reset`** - Reset personal statistics (if enabled)
### GM Commands
- **`.mythicplus enable <level>`** - Set dungeon difficulty level
- **`.mythicplus disable`** - Disable mythic plus for current dungeon
- **`.mythicplus reload`** - Reload configuration without restart
- **`.mythicplus debug <player>`** - Show debug information for specified player
- **`.mythicplus scaling <dungeon_id> <multiplier>`** - Set custom scaling for specific dungeon
- **`.mythicplus materials add <player> <material_id> <count>`** - Add rare materials to player
- **`.mythicplus tokens grant <player> <token_type> <amount>`** - Grant endgame tokens
## Gameplay Mechanics
### Difficulty Progression
1. **Entry Level**: Start with Mythic difficulty for enhanced challenge
2. **Intermediate**: Progress to Legendary for significant stat increases
3. **Advanced**: Attempt Ascendant level for extreme challenges
4. **Mastery**: Custom difficulty configurations for server-specific content
### Death System
- Players have limited deaths before dungeon failure
- Death count affects final rewards and achievements
- Configurable penalties including reduced experience or currency
### Reward Scaling
- **50,000+ New Items**: Massive equipment database with items scaling from entry-level mythic to extreme ascendant tiers
- **Rare Material System**: Exclusive crafting materials that drop only in mythic plus content, used for high-end crafting and upgrades
- **Endgame Token Economy**: Multiple token types for different content tiers, exchangeable for premium rewards
- **Reworked Tier Sets**: Complete overhaul of all expansion tier gear, rescaled and rebalanced for mythic plus progression
- **Achievement Rewards**: Exclusive items, titles, and cosmetic rewards locked behind achievement completion
- **Cross-Expansion Progression**: Items and materials from different expansions integrated into a unified progression system
## Customization
### Adding Custom Difficulties
The module supports adding custom difficulty tiers by:
1. Editing the configuration file to add new scaling values
2. Updating database entries for custom creature stats
3. Implementing custom reward tables for new difficulties
### Creature Modifications
- Individual creature scaling can be customized per dungeon
- Special abilities can be added or modified through database entries
- Custom spell rotations and AI behaviors configurable
### Loot Customization
- **50,000+ Item Integration**: Massive custom item database with proper scaling and progression
- **Rare Material Drops**: Custom drop tables for exclusive mythic plus materials
- **Endgame Token Distribution**: Configurable token rewards based on difficulty and performance
- **Tier Set Reworks**: All expansion tier sets completely rebalanced with new set bonuses and scaling
- **Per-Dungeon Loot Tables**: Each dungeon can have unique reward pools and exclusive items
- **Achievement-Gated Rewards**: Special items and materials locked behind specific achievement completions
## Troubleshooting
### Common Issues
**Module not loading**:
- Verify the module was compiled correctly
- Check server logs for compilation errors
- Ensure all dependencies are met
**Database errors**:
- Confirm all SQL files were applied in correct order
- Verify database user has appropriate permissions
- Check for conflicting modules or custom modifications
**Configuration not working**:
- Verify configuration file is in correct location
- Check file permissions and syntax
- Use `.mythicplus reload` command after making changes
**Performance issues**:
- Monitor server resources during high-difficulty encounters
- Adjust scaling values if creatures are too powerful
- Consider reducing concurrent mythic plus dungeons
### Debug Mode
Enable debug logging by setting:
```ini
MythicPlus.DebugMode = 1
```
This provides detailed information about:
- Creature scaling calculations
- Reward calculations
- Player progression tracking
- System performance metrics
## Contributing
### Development Setup
1. Fork the repository
2. Create a feature branch
3. Make your changes following the existing code style
4. Test thoroughly on a development server
5. Submit a pull request with detailed description
### Code Standards
- Follow AzerothCore coding conventions
- Include appropriate comments and documentation
- Test all changes across multiple difficulty levels
- Ensure compatibility with other popular modules
### Bug Reports
When reporting bugs, include:
- AzerothCore version and commit hash
- Module version/commit
- Configuration file settings
- Detailed reproduction steps
- Server logs showing the issue
## Credits
**Development Team**: Araxia Online Development Team
- **Lead Developer**: ben-of-codecraft
- **Contributors**: james-huston
**Special Thanks**:
- AzerothCore development team for the excellent foundation
- Community members who provided testing and feedback
- Original World of Warcraft developers for creating the content we enhance
## License
This project is licensed under the GPL-3.0 License - see the [LICENSE](LICENSE) file for details.
## Support
- **GitHub Issues**: Report bugs and request features
- **Community Discord**: Join discussions and get help from other users
- **Documentation**: Check the wiki for additional guides and tutorials
---
*Remember: This module significantly increases dungeon difficulty. Start with lower difficulties and work your way up to avoid frustration. The enhanced challenge is designed to provide engaging content for experienced players seeking greater difficulty than the original game provided.*

View File

@@ -0,0 +1,134 @@
[worldserver]
##########################################################
#
# Logging Configuration
#
##########################################################
Appender.MythicPlusLog=2,4,0,mod-mythic-plus.log,w
# Appender.MythicPlusConsole=1,5,0,"1 9 3 6 5 8"
Logger.module.MythicPlus=5,MythicPlusLog MythicPlusConsole
##########################################################
#
# Mythic+ Global Settings
# - These settings are used to enable or disable the Mythic+ system and set the global settings for the system.
#
# Enabled: 1 = Enabled, 0 = Disabled - Enables the Mythic+ system.
# EnableItemRewards: 1 = Enabled, 0 = Disabled - Enables the reward system for Mythic+ dungeons.
# EnableDeathLimits: 1 = Enabled, 0 = Disabled - Enables the death limit system for Mythic+ dungeons.
# EnabledDifficulties: A comma separated list of difficulties that are enabled for Mythic+ dungeons.
# DisabledDungeons: A comma separated list of dungeons that are disabled for Mythic+ dungeons.
#
##########################################################
MythicPlus.Enabled = 1
MythicPlus.EnableItemRewards = 1
MythicPlus.EnableDeathLimits = 1
##########################################################
#
# Enabled difficulty settings
#
##########################################################
MythicPlus.EnabledDifficulties = mythic,legendary,ascendant
MythicPlus.DisabledDungeons =
##########################################################
#
# Mythic+ Global Stat Modifiers By Difficulty
# - These values are used to adjust the difficulty of enemies and bosses base
# stats based on the difficulty of the dungeon.
# - Bosses will only receive their multiplier not the Dungeon multiplier to prevent multiplicative scaling.
# - These values are used to scale the difficulty of all dungeons across new difficulty modes.
#
# To scale individual instances you should use the mp_scale_factors table per instance to increase/reduce Modifiers
##########################################################
MythicPlus.Mythic.DungeonHealth = 1.25
MythicPlus.Mythic.DungeonMelee = 1.25
MythicPlus.Mythic.DungeonBaseDamage = 1.50
MythicPlus.Mythic.DungeonSpell = 1.15
MythicPlus.Mythic.DungeonArmor = 1.95
MythicPlus.Mythic.DungeonAvgLevel = 83
MythicPlus.Mythic.DungeonBossHealth = 1.50
MythicPlus.Mythic.DungeonBossMelee = 1.35
MythicPlus.Mythic.DungeonBossBaseDamage = 2.00
MythicPlus.Mythic.DungeonBossSpell = 1.25
MythicPlus.Mythic.DungeonBossArmor = 1.35
MythicPlus.Mythic.DungeonBossLevel = 85
MythicPlus.Legendary.DungeonHealth = 2.25
MythicPlus.Legendary.DungeonMelee = 2.25
MythicPlus.Legendary.DungeonBaseDamage = 2.75
MythicPlus.Legendary.DungeonSpell = 2.25
MythicPlus.Legendary.DungeonArmor = 2.25
MythicPlus.Legendary.DungeonAvgLevel = 85
MythicPlus.Legendary.DungeonBossHealth = 2.25
MythicPlus.Legendary.DungeonBossMelee = 2.25
MythicPlus.Legendary.DungeonBossSpell = 2.25
MythicPlus.Legendary.DungeonBossBaseDamage = 4.00
MythicPlus.Legendary.DungeonBossArmor = 3.25
MythicPlus.Legendary.DungeonBossLevel = 87
MythicPlus.Ascendant.DungeonHealth = 3.25
MythicPlus.Ascendant.DungeonMelee = 3.25
MythicPlus.Ascendant.DungeonBaseDamage = 4.75
MythicPlus.Ascendant.DungeonSpell = 3.25
MythicPlus.Ascendant.DungeonArmor = 3.25
MythicPlus.Ascendant.DungeonAvgLevel = 87
MythicPlus.Ascendant.DungeonBossHealth = 3.25
MythicPlus.Ascendant.DungeonBossMelee = 3.25
MythicPlus.Ascendant.DungeonBossSpell = 3.25
MythicPlus.Ascendant.DungeonBossBaseDamage = 6.00
MythicPlus.Ascendant.DungeonBossArmor = 3.25
MythicPlus.Ascendant.DungeonBossLevel = 90
##########################################################
#
# Mythic+ Gameplay Settings
# - If Death limit mode is enabled the below numbers set the max number of total deaths before players are kicked out and the
# that instance of the dungeon is failed.
#
##########################################################
MythicPlus.Mythic.DeathAllowance = 100
MythicPlus.Legendary.DeathAllowance = 30
MythicPlus.Ascendant.DeathAllowance = 15
##########################################################
#
# Itemization Settings
# - These values are used to set the offset to where items per difficulty will map to.
# - Item drops in this mode use the original item entry + on offset to determine the new item entry reward.
# - This enables a fast lookup at loot drop time as it is just an addition operation.
# - If using the base generated sql the settings below will map to it. If the offset is incorrect,
# the item will not be found and the original low level item will be rewarded.
#
##########################################################
MythicPlus.Mythic.ItemOffset = 20000000
MythicPlus.Legendary.ItemOffset = 21000000
MythicPlus.Ascendant.ItemOffset = 22000000
##########################################################
# Diminishing Returns
# - These values are used to set the diminishing returns for the different difficulties.
# - The diminishing returns are used to limit the amount of damage that can be done to a target.
# - The diminishing returns are based on the difficulty of the dungeon and the amount of damage that has been done to the target.
##########################################################
MythicPlus.DiminishingExponent = 0.96
MythicPlus.DiminishingThreshold.Mythic = 10000
MythicPlus.DiminishingThreshold.Legendary = 20000
MythicPlus.DiminishingThreshold.Ascendant = 40000
##############
# Scaling Adjusters
#############
MythicPlus.ElementalMeleeReducer = 0.50
MythicPlus.NormalEnemyReducer = 0.50
MythicPlus.NonCreatureSpellReducer = 0.50

View File

@@ -1,7 +0,0 @@
DROP TABLE IF EXISTS group_difficulty;
CREATE TABLE group_difficulty (
guid INT UNSIGNED NOT NULL DEFAULT '0',
difficulty TINYINT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (guid)
);

View File

@@ -0,0 +1,100 @@
-- Used for tracking group instance data for mythic runs
DROP TABLE IF EXISTS mp_group_data;
CREATE TABLE mp_group_data (
groupId INT UNSIGNED NOT NULL DEFAULT '0',
difficulty INT UNSIGNED,
mapId INT UNSIGNED,
instanceId INT UNSIGNED,
instanceTimer INT UNSIGNED,
deaths INT UNSIGNED,
PRIMARY KEY (groupId)
);
-- Used for tracking current instance data for players
DROP TABLE IF EXISTS mp_player_instance_data;
CREATE TABLE mp_player_instance_data (
guid INT UNSIGNED NOT NULL DEFAULT '0',
difficulty INT UNSIGNED NOT NULL DEFAULT '3',
mapId INT UNSIGNED NOT NULL,
instanceId INT UNSIGNED NOT NULL DEFAULT '0',
deaths INT UNSIGNED NOT NULL,
PRIMARY KEY (guid, mapId, instanceId)
);
-- Used for tracking player deaths to specific creatures in mythic runs
DROP TABLE IF EXISTS mp_player_death_stats;
CREATE TABLE mp_player_death_stats (
guid INT UNSIGNED NOT NULL DEFAULT '0',
creatureEntry INT UNSIGNED NOT NULL,
difficulty TINYINT UNSIGNED NOT NULL DEFAULT '0',
numDeaths INT UNSIGNED NOT NULL DEFAULT '0',
lastUpdated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (guid, creatureEntry, difficulty)
);
-- Used for tracking player runs in mythic dungeons
DROP TABLE IF EXISTS mp_player_runs;
CREATE TABLE mp_player_runs (
runId INT UNSIGNED AUTO_INCREMENT,
guid INT UNSIGNED NOT NULL DEFAULT '0',
difficulty INT UNSIGNED NOT NULL DEFAULT '3',
mapId INT UNSIGNED NOT NULL DEFAULT '0',
groupDeaths INT UNSIGNED NOT NULL DEFAULT '0',
personalDeaths INT UNSIGNED NOT NULL DEFAULT '0',
startTime INT UNSIGNED,
completeTime TIMESTAMP,
botCount TINYINT UNSIGNED DEFAULT '0',
PRIMARY KEY (runId),
INDEX idx_guid (guid),
INDEX idx_mapId (mapId)
);
-- Used for tracking player stats in mythic dungeons
DROP TABLE IF EXISTS mp_player_stats;
CREATE TABLE mp_player_stats (
guid INT UNSIGNED NOT NULL DEFAULT '0',
mapId INT UNSIGNED NOT NULL DEFAULT '0',
difficulty TINYINT UNSIGNED NOT NULL DEFAULT '0',
deaths INT UNSIGNED DEFAULT '0',
runs INT UNSIGNED DEFAULT '0',
completions INT UNSIGNED DEFAULT '0',
totalTime INT UNSIGNED DEFAULT '0',
bestTime INT UNSIGNED DEFAULT '0',
PRIMARY KEY (guid, mapId, difficulty)
);
-- Used to enable custom stat upgrades from materials and drops in mythic dungeons
DROP TABLE IF EXISTS mp_player_advancements;
CREATE TABLE mp_player_advancements (
guid INT UNSIGNED NOT NULL,
advancementId INT UNSIGNED NOT NULL,
bonus FLOAT NOT NULL,
upgradeRank INT UNSIGNED NOT NULL,
diceSpent INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (guid, advancementId)
);
-- Used to show historic player roll data by advancement.
DROP TABLE IF EXISTS mp_player_advancement_history;
CREATE TABLE mp_player_advancement_history (
guid INT UNSIGNED NOT NULL,
advancementId INT UNSIGNED NOT NULL,
bonus FLOAT NOT NULL,
upgradeRank INT UNSIGNED NOT NULL,
diceSpent INT UNSIGNED NOT NULL DEFAULT '0',
entryId1 INT UNSIGNED NOT NULL,
entryId2 INT UNSIGNED,
entryId3 INT UNSIGNED,
itemCost1 INT UNSIGNED NOT NULL,
itemCost2 INT UNSIGNED,
itemCost3 INT UNSIGNED,
added TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (guid, advancementId, upgradeRank)
);

View File

@@ -0,0 +1,47 @@
-- Used to track upgrade ranks for stat improvements and min/max values
DROP TABLE IF EXISTS mp_stat_upgrade_ranks;
DROP TABLE IF EXISTS mp_upgrade_ranks;
CREATE TABLE mp_upgrade_ranks (
upgradeRank INT UNSIGNED NOT NULL,
advancementId INT UNSIGNED NOT NULL,
itemEntry1 INT UNSIGNED NOT NULL,
itemEntry2 INT UNSIGNED NOT NULL,
itemEntry3 INT UNSIGNED NOT NULL,
itemCost1 INT UNSIGNED NOT NULL,
itemCost2 INT UNSIGNED NOT NULL,
itemCost3 INT UNSIGNED NOT NULL,
minIncrease1 INT UNSIGNED NOT NULL,
maxIncrease1 INT UNSIGNED NOT NULL,
minIncrease2 INT UNSIGNED NOT NULL,
maxIncrease2 INT UNSIGNED NOT NULL,
minIncrease3 INT UNSIGNED NOT NULL,
maxIncrease3 INT UNSIGNED NOT NULL,
chanceCost1 INT UNSIGNED NOT NULL,
chanceCost2 INT UNSIGNED NOT NULL,
chanceCost3 INT UNSIGNED NOT NULL,
PRIMARY KEY (upgradeRank, advancementId)
);
-- Used to allocate trade materials to a category for fusion into new tradeskills
DROP TABLE IF EXISTS mp_material_types;
CREATE TABLE mp_material_types (
materialId INT UNSIGNED NOT NULL,
entry INT UNSIGNED NOT NULL,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (materialId, entry)
);
-- Description: Scale factors for Mythic+ dungeons used to normalize dungeon difficulty across expansions.
DROP TABLE IF EXISTS mp_scale_factors;
CREATE TABLE mp_scale_factors (
mapId SMALLINT NOT NULL,
melee_bonus FLOAT DEFAULT '1',
spell_bonus FLOAT DEFAULT '1',
heal_bonus FLOAT DEFAULT '1',
hp_bonus FLOAT DEFAULT '1',
difficulty FLOAT DEFAULT '1',
PRIMARY KEY (mapId)
);

View File

@@ -0,0 +1,539 @@
TRUNCATE TABLE mp_material_types;
-- MaterialID for all droppable cloth items
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT DISTINCT
1 AS materialId, -- Assign the same materialId to all rows
it.entry,
it.name
FROM item_template it
LEFT JOIN creature_loot_template clt ON (it.entry = clt.Item)
WHERE it.name LIKE '%Cloth'
AND it.class = 7
AND it.subclass = 5
AND it.name NOT LIKE 'Bolt%'
AND it.VerifiedBuild = 12340
AND clt.Entry IS NOT NULL;
-- Crafted cloth items that are not dropped by enemies
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
2 AS materialId, -- Assign the same materialId to all rows
it.entry,
it.name
FROM item_template it
LEFT JOIN creature_loot_template clt ON (it.entry = clt.Item)
WHERE it.name LIKE '%Cloth'
AND it.class = 7
AND it.subclass = 5
AND it.name NOT LIKE 'Bolt%'
AND it.VerifiedBuild = 12340
AND clt.Entry IS NULL;
-- Common Herbs available to herbalists
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
3 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE it.class = 7
AND it.subclass = 9
AND it.VerifiedBuild = 12340
AND it.RequiredSkillRank != 0
AND it.name NOT IN (
'Black Lotus',
'Ghost Mushroom',
'Dreamfoil',
'Bloodvine',
'Fel Lotus',
'Netherbloom',
'Nightmare Vine',
'Frost Lotus',
"Adder's Tongue",
'Fire Leaf',
'Lichbloom',
'Icethorn',
"Talandra's Rose"
);
-- Rare Herbs that are harder to find or drop in raids
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
4 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE it.name IN (
'Black Lotus', -- Classic: Rare spawn in Dire Maul and outdoor zones, extremely rare in raids.
'Ghost Mushroom', -- Classic: Found in Maraudon (Dungeon-only herb).
'Bloodvine', -- Classic: Drops from enemies in Zul'Gurub.
'Fel Lotus', -- TBC: Extremely rare herb drop while gathering Felweed, Dreaming Glory, etc., in Outland.
'Netherbloom', -- TBC: Rare spawn in Netherstorm, also dropped by some elites.
'Nightmare Vine', -- TBC: Found in Shadowmoon Valley and drops in Black Temple from specific mobs.
'Frost Lotus', -- Wrath: Extremely rare spawn from herb nodes or dungeons like Utgarde Pinnacle.
"Adder's Tongue", -- Wrath: Rare spawn from dungeon nodes in Drak'Tharon Keep and Gundrak.
'Fire Leaf', -- Wrath: Rare herb found in Wintergrasp, sometimes in dungeon PvP areas.
'Icethorn', -- Wrath: Harvested from specific dungeon nodes in higher-level Northrend zones.
"Talandra's Rose" -- Wrath: Found sparsely in Zul'Drak dungeons like Gundrak.
);
-- Common ores that are easy to find in the world
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT DISTINCT
5 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE it.class = 7
AND it.subclass = 7
AND it.VerifiedBuild = 12340
AND it.name NOT LIKE '%Bar'
AND it.name NOT LIKE '%Ingot'
AND it.name NOT LIKE '%Stone'
AND it.name NOT LIKE '%Shard'
AND it.name NOT IN ('Coal', 'Elemental Flux', 'Hardened Khorium')
AND it.name NOT IN ('Elementium Ore', 'Dark Iron Ore', 'Primal Nether', 'Runed Orb', 'Crusader Orb', 'Blood of the Mountain')
ORDER BY it.name;
-- Rare ores that are harder to find or drop in raids
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT DISTINCT
6 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE
it.name Like '%Obsidian Shard%'
OR it.name IN ('Elementium Ore', 'Dark Iron Ore', 'Primal Nether', 'Runed Orb', 'Crusader Orb', 'Blood of the Mountain')
and entry <= 2000000
ORDER BY it.name;
-- Common skins that are easy to find in the world
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
7 AS materialId, -- Unique ID for commonly skinnable materials
it.entry,
it.name
FROM item_template it
WHERE it.name IN (
'Borean Leather',
'Heavy Leather',
'Heavy Hide',
'Light Leather',
'Light Hide',
'Medium Leather',
'Medium Hide',
'Rugged Leather',
'Rugged Hide',
'Thick Leather',
'Thick Hide',
'Knothide Leather',
'Icy Dragonscale',
'Jormungar Scale',
'Nerubian Chitin',
'Turtle Scale'
);
-- Rare skinning material found in the world or dropped by enemies
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
8 AS materialId, -- Unique ID for rare skinnable and non-skinnable materials
it.entry,
it.name
FROM item_template it
WHERE it.name IN (
'Black Dragonscale',
'Blue Dragonscale',
'Green Dragonscale',
'Red Dragonscale',
'Scale of Onyxia',
'Nether Dragonscales',
'Wind Scales',
'Thick Clefthoof Leather',
'Cobra Scales',
'Devilsaur Leather',
'Green Whelp Scale',
'Black Whelp Scale',
'Perfect Deviate Scale',
'Core Leather',
'Dreamscale',
'Primal Bat Leather',
'Primal Tiger Leather'
);
-- Common uncut gems that are easy to find in the world
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
9 AS materialId, -- Unique ID for common uncut gems
it.entry,
it.name
FROM item_template it
WHERE
it.VerifiedBuild = 12340 -- Wrath of the Lich King build
AND it.name NOT LIKE '%Cut%' -- Exclude pre-cut gems
AND it.name IN (
'Malachite',
'Tigerseye',
'Moss Agate',
'Shadowgem',
'Jade',
'Lesser Moonstone',
'Citrine',
'Aquamarine',
'Star Ruby',
'Azerothian Diamond',
'Huge Emerald',
'Large Opal',
'Blue Sapphire',
'Arcane Crystal',
'Bloodstone',
'Sun Crystal',
'Chalcedony',
'Dark Jade',
'Shadow Crystal',
'Huge Citrine',
'Monarch Topaz',
'Forest Emerald',
'Sky Sapphire',
"Autumn's Glow",
'Twilight Opal',
'Scarlet Ruby'
);
-- Rare gems that are harder to find or drop in raids
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
10 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- TBC Epic Gems
'Crimson Spinel',
'Empyrean Sapphire',
'Lionseye',
'Shadowsong Amethyst',
'Pyrestone',
'Seaspray Emerald',
-- WotLK Epic Gems
'Cardinal Ruby',
'Ametrine',
"King's Amber",
'Eye of Zul',
'Majestic Zircon',
'Dreadstone'
);
-- common enchantment materials that are easy to find in the world
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
11 AS materialId, -- Example materialId for enchantment items
it.entry,
it.name
FROM item_template it
WHERE
it.class = 7
AND it.subclass = 12
AND it.VerifiedBuild = 12340
AND it.name NOT LIKE '%Rod%'
AND it.name NOT IN (
-- Classic Rare Enchantment Items
'Righteous Orb', -- Drops in Stratholme.
'Lava Core', -- Rare drop in Molten Core.
'Black Diamond', -- Rare drop in Blackrock Depths and related areas.
'Essence of the Red', -- Reward from Vaelastrasz in Blackwing Lair.
'Onyxia Scale', -- Dropped by Onyxia, used in fire resistance recipes.
-- TBC Rare Enchantment Items
'Primal Might', -- Crafted using all Primals, very rare due to material costs.
'Heart of Darkness', -- Rare drop in Black Temple.
'Sunmote', -- Drops in Sunwell Plateau.
'Nether Vortex', -- Raid-exclusive crafting material in TBC.
-- WotLK Rare Enchantment Items
'Eternal Might', -- Custom material replacing Eternal combinations, rare in high-level content.
'Frozen Orb', -- Drops in WotLK heroic dungeons.
'Runed Orb', -- Drops in Ulduar.
'Crusader Orb' -- Drops in Trial of the Crusader raid.
);
-- Rare enchantment materials that are harder to find or drop in raids
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
12 AS materialId, -- Example materialId for enchantment items
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic Rare Enchantment Items
'Righteous Orb', -- Drops in Stratholme.
'Lava Core', -- Rare drop in Molten Core.
'Black Diamond', -- Rare drop in Blackrock Depths and related areas.
'Essence of the Red', -- Reward from Vaelastrasz in Blackwing Lair.
'Onyxia Scale', -- Dropped by Onyxia, used in fire resistance recipes.
-- TBC Rare Enchantment Items
'Primal Might', -- Crafted using all Primals, very rare due to material costs.
'Heart of Darkness', -- Rare drop in Black Temple.
'Sunmote', -- Drops in Sunwell Plateau.
'Nether Vortex', -- Raid-exclusive crafting material in TBC.
-- WotLK Rare Enchantment Items
'Eternal Might', -- Custom material replacing Eternal combinations, rare in high-level content.
'Frozen Orb', -- Drops in WotLK heroic dungeons.
'Runed Orb', -- Drops in Ulduar.
'Crusader Orb' -- Drops in Trial of the Crusader raid.
);
-- Common materials that related to water / frost
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
13 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Elemental Water',
'Essence of Water',
'Glacial Fragments',
-- TBC
'Arctic Fur',
'Thick Dawnstone',
-- WotLK
'Frost Lotus',
'Frostweave Cloth'
);
-- Rare materials that related to water / frost
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
14 AS materialId, -- Unique ID for rare frost resistance materials
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Frozen Rune',
'Core of Earth',
-- TBC
'Frost-Infused Shard',
'Nether Residuum',
'Primal Water',
-- WotLK
'Primordial Saronite',
'Icy Dragonscale',
'Eternal Water'
);
-- Common materials that relate to fire
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
15 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Elemental Fire',
'Essence of Fire',
'Heart of Fire',
'Small Flame Sac',
'Core of Flame',
-- TBC
'Mote of Fire',
'Flame Spessarite', -- Common fire-themed gem for jewelcrafting.
'Smoldering Core', -- Fire-themed drop from elementals.
-- WotLK
'Fire Leaf',
'Crystallized Fire'
);
-- Rare materials that relate to fire resistance gear or fire-themed weapons
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
16 AS materialId, -- Unique ID for rare fire resistance and fire weapon crafting materials
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Fiery Core', -- Key material for crafting fire resistance gear in Molten Core.
'Lava Core', -- Used in crafting fire resistance gear and recipes.
'Sulfuron Ingot', -- Rare drop from Molten Core, used for crafting legendary fire weapons.
-- TBC
'Primal Fire', -- Core material for fire crafting in TBC.
'Hardened Adamantite Bar', -- Material for crafting fire-resistant shields and gear.
-- WotLK
'Primordial Saronite', -- Used for crafting high-level resistance and utility gear.
'Eternal Fire', -- Central material for fire-themed crafting.
'Runed Orb', -- Used in crafting fire-related weapons and gear.
'Smouldering Crystals', -- High-value fire crafting material from fire-themed mobs.
'Burning Embers' -- Rare crafting material for WotLK fire-themed items.
);
-- Common materials that relate to nature
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
17 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Elemental Earth',
'Essence of Earth',
'Living Essence',
'Small Venom Sac',
"Un'Goro Soil",
'Ichor of Undeath', -- Used in nature-themed recipes.
-- TBC
'Mote of Earth', -- Combines into Primal Earth.
'Mote of Life', -- Combines into Primal Life.
'Terocone', -- Nature-themed herb used in alchemy.
-- WotLK
'Crystallized Earth', -- Combines into Eternal Earth.
'Crystallized Life', -- Combines into Eternal Life.
'Icethorn', -- Herb with thematic ties to nature resistance potions.
'Ancient Moss'
);
-- Rare Nature resistance materials
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
18 AS materialId, -- Unique ID for rare nature resistance and nature weapon crafting materials
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Heart of the Wild', -- Rare material for crafting nature resistance gear.
'Living Essence', -- Rare crafting material dropped by nature elementals.
"Gahz'rilla's Electrified Scale",-- Rare item from Zul'Farrak for nature resistance gear.
-- TBC
'Primal Earth', -- Central crafting material for resistance and nature-themed items.
'Primal Life', -- Rare material for nature-themed crafting.
-- WotLK
'Eternal Earth', -- Central material for nature-themed crafting.
'Eternal Life', -- Rare material for nature-themed crafting.
'Runed Orb', -- Rare crafting material for nature-themed gear.
"Adder's Tongue" -- Herb used in nature resistance recipes.
);
-- Common materials that relate to shadow
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
19 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Shadowgem', -- Common low-level gem with shadow theme.
'Elemental Shadow', -- Basic crafting reagent from shadow elementals.
'Essence of Shadow', -- Dropped by shadow-themed elementals in high-level zones.
-- TBC
'Mote of Shadow', -- Combines into Primal Shadow, used in crafting.
'Dark Rune', -- Dropped in Scholomance and used for shadow resistance crafting.
-- WotLK
'Crystallized Shadow', -- Combines into Eternal Shadow.
'Deadnettle', -- Herb with thematic ties to shadow crafting.
'Shadowy Essence' -- Rare Northrend material for shadow crafting.
);
-- Rare materials that relate to shadow resistance gear or shadow-themed weapons
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
20 AS materialId, -- Unique ID for rare shadow resistance and shadow weapon crafting materials
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Heart of Darkness', -- Rare drop used for shadow resistance gear in TBC and Classic.
'Shadow Oil', -- Crafted alchemical reagent for shadow resistance.
'Black Lotus', -- Rare herb used in high-level shadow potions.
-- TBC
'Primal Shadow', -- Central crafting material for shadow resistance.
'Nightmare Seed', -- Rare herb used in shadow resistance recipes.
'Felcloth', -- Cloth with shadow resistance used in tailoring.
-- WotLK
'Eternal Shadow', -- Core material for shadow resistance crafting.
'Runed Orb' -- Rare material for shadow-themed gear and weapons.
);
-- Common materials that relate to arcane resistance gear or arcane-themed weapons
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
21 AS materialId,
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Arcane Crystal', -- Rare mining material used in Arcanite Bars.
'Essence of Magic', -- Dropped by arcane elementals.
'Lesser Magic Essence', -- Early enchanting material.
'Greater Magic Essence', -- Enchanting material with arcane ties.
-- TBC
'Mote of Mana', -- Combines into Primal Mana.
-- WotLK
'Crystallized Mana' -- Combines into Eternal Mana.
);
-- Rare materials that relate to arcane resistance gear or arcane-themed weapons
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
22 AS materialId, -- Unique ID for rare arcane resistance and arcane weapon crafting materials
it.entry,
it.name
FROM item_template it
WHERE
it.name IN (
-- Classic
'Golden Pearl', -- Rare material used in crafting arcane resistance gear.
'Arcanite Bar', -- Transmuted from Arcane Crystals, used in crafting high-end gear.
-- TBC
'Primal Mana', -- Essential for arcane resistance crafting.
'Nether Vortex', -- Raid-exclusive crafting material.
'Void Sphere', -- Rare arcane-themed gem obtained through badge purchases or raids.
-- WotLK
'Eternal Mana', -- Central crafting material for arcane resistance gear.
'Saronite Animus' -- Rare drop from arcane-themed enemies in Icecrown Citadel.
);
REPLACE INTO mp_material_types (materialId, entry, name) VALUES (23, 911002, 'Veilstone');

View File

@@ -0,0 +1,152 @@
-- Last Update: 2025/01/17
-- Description: Scale factors for Mythic+ dungeons used to normalize dungeon difficulty across expansions.
-- 1. Pre 60 level dungeons (melee_bonus: 1.9-2.2, spell_bonus: 1.8-1.9, hp_bonus: 2, difficulty: 3)
INSERT INTO mp_scale_factors (mapId, melee_bonus, spell_bonus, heal_bonus, hp_bonus, difficulty)
VALUES
(389, 2.2, 1.9, 1.9, 2, 3), -- Ragefire Chasm
(43, 1.9, 1.8, 1.8, 2, 3), -- Wailing Caverns
(36, 1.9, 1.9, 1.9, 2, 3), -- The Deadmines
(33, 1.9, 1.9, 1.9, 2, 3), -- Shadowfang Keep
(34, 1.9, 1.9, 1.9, 2, 3), -- The Stockade
(48, 1.9, 1.9, 1.9, 2, 3), -- Blackfathom Deeps
(90, 1.9, 1.9, 1.9, 2, 3), -- Gnomeregan
(47, 1.9, 1.9, 1.9, 2, 3), -- Razorfen Kraul
(189, 1.9, 1.9, 1.9, 2, 3), -- Scarlet Monastery (Graveyard)
(129, 1.9, 1.9, 1.9, 2, 3), -- Razorfen Downs
(70, 1.9, 1.9, 1.9, 2, 3), -- Uldaman
(209, 1.9, 1.9, 1.9, 2, 3), -- Zul'Farrak
(349, 1.9, 1.9, 1.9, 2, 3) -- Maraudon
AS new_values
ON DUPLICATE KEY UPDATE
melee_bonus = new_values.melee_bonus,
spell_bonus = new_values.spell_bonus,
heal_bonus = new_values.heal_bonus,
hp_bonus = new_values.hp_bonus,
difficulty = new_values.difficulty;
-- 2. Level 60 dungeons for classic (melee_bonus: 1.7, spell_bonus: 2.0, hp_bonus: 3, difficulty: 3)
INSERT INTO mp_scale_factors (mapId, melee_bonus, spell_bonus, heal_bonus, hp_bonus, difficulty)
VALUES
(289, 1.7, 2.0, 2.0, 3, 3), -- Scholomance
(109, 1.7, 2.0, 2.0, 3, 3), -- Sunken Temple
(329, 1.7, 2.0, 2.0, 3, 3), -- Stratholme
(229, 1.7, 2.0, 2.0, 3, 3), -- Blackrock Spire (Lower)
(230, 1.7, 2.0, 2.0, 3, 3), -- Blackrock Spire (Upper)
(429, 1.7, 2.0, 2.0, 3, 3), -- Dire Maul
(269, 1.7, 2.0, 2.0, 3, 3) -- Temple of Atal'Hakkar
AS new_values
ON DUPLICATE KEY UPDATE
melee_bonus = new_values.melee_bonus,
spell_bonus = new_values.spell_bonus,
heal_bonus = new_values.heal_bonus,
hp_bonus = new_values.hp_bonus,
difficulty = new_values.difficulty;
-- 3. Pre 70 dungeons in Burning Crusade (melee_bonus: 1.6, spell_bonus: 1.4, hp_bonus: 4, difficulty: 3)
INSERT INTO mp_scale_factors (mapId, melee_bonus, spell_bonus, heal_bonus, hp_bonus, difficulty)
VALUES
(542, 1.6, 1.4, 1.4, 4, 3), -- Hellfire The Blood Furnace
(543, 1.6, 1.4, 1.4, 4, 3), -- Hellfire Ramparts
(545, 1.6, 1.4, 1.4, 4, 3), -- Coilfang Steamvaults
(546, 1.6, 1.4, 1.4, 4, 3), -- Coilfang Reservoir: The Underbog
(547, 1.6, 1.4, 1.4, 4, 3), -- Coilfang Reservoir: The Slave Pens
(557, 1.6, 1.4, 1.4, 4, 3), -- Auchindoun: Mana-Tombs
(558, 1.6, 1.4, 1.4, 4, 3), -- Auchindoun: Auchenai Crypts
(560, 1.6, 1.4, 1.4, 4, 3) -- Caverns of Time: Old Hillsbrad Foothills
AS new_values
ON DUPLICATE KEY UPDATE
melee_bonus = new_values.melee_bonus,
spell_bonus = new_values.spell_bonus,
heal_bonus = new_values.heal_bonus,
hp_bonus = new_values.hp_bonus,
difficulty = new_values.difficulty;
-- 4. Level 70 dungeons in Burning Crusade (melee_bonus: 1.4, spell_bonus: 1.3, hp_bonus: 4, difficulty: 3)
INSERT INTO mp_scale_factors (mapId, melee_bonus, spell_bonus, heal_bonus, hp_bonus, difficulty)
VALUES
(540, 1.4, 1.3, 1.3, 4, 3), -- Shattered Halls
(556, 1.4, 1.3, 1.3, 4, 3), -- Auchindoun: Sethekk Halls
(555, 1.4, 1.3, 1.3, 4, 3), -- Auchindoun: Shadow Labyrinth
(553, 1.4, 1.3, 1.3, 4, 3), -- Tempest Keep: The Botanica
(554, 1.4, 1.3, 1.3, 4, 3), -- Tempest Keep: The Mechanar
(552, 1.4, 1.3, 1.3, 4, 3), -- Tempest Keep: The Arcatraz
(585, 1.4, 1.3, 1.3, 4, 3) -- Magisters' Terrace
AS new_values
ON DUPLICATE KEY UPDATE
melee_bonus = new_values.melee_bonus,
spell_bonus = new_values.spell_bonus,
heal_bonus = new_values.heal_bonus,
hp_bonus = new_values.hp_bonus,
difficulty = new_values.difficulty;
-- 5. Pre 80 dungeons in Wrath of the Lich King (melee_bonus: 1.9, spell_bonus: 1.2, hp_bonus: 3, difficulty: 3)
INSERT INTO mp_scale_factors (mapId, melee_bonus, spell_bonus, heal_bonus, hp_bonus, difficulty)
VALUES
(574, 1.9, 1.2, 1.2, 3, 3), -- Utgarde Keep
(619, 1.9, 1.2, 1.2, 3, 3), -- Ahn'kahet: The Old Kingdom
(576, 1.9, 1.2, 1.2, 3, 3), -- The Nexus
(600, 1.9, 1.2, 1.2, 3, 3), -- Drak'Tharon Keep
(601, 1.9, 1.2, 1.2, 3, 3), -- Azjol-Nerub
(608, 1.9, 1.2, 1.2, 3, 3) -- The Violet Hold
AS new_values
ON DUPLICATE KEY UPDATE
melee_bonus = new_values.melee_bonus,
spell_bonus = new_values.spell_bonus,
heal_bonus = new_values.heal_bonus,
hp_bonus = new_values.hp_bonus,
difficulty = new_values.difficulty;
-- 6. Level 80 dungeons in Wrath of the Lich King (melee_bonus: 1.9, spell_bonus: 1.3, hp_bonus: 5, difficulty: 3)
INSERT INTO mp_scale_factors (mapId, melee_bonus, spell_bonus, heal_bonus, hp_bonus, difficulty)
VALUES
(595, 1.9, 1.3, 1.3, 5, 3), -- The Culling of Stratholme
(604, 1.9, 1.3, 1.3, 5, 3), -- Gundrak
(599, 1.9, 1.3, 1.3, 5, 3), -- Halls of Stone
(602, 1.9, 1.3, 1.3, 5, 3), -- Halls of Lightning
(578, 1.9, 1.3, 1.3, 5, 3), -- The Oculus
(650, 1.9, 1.3, 1.3, 5, 3), -- Trial of the Champion
(632, 1.9, 1.3, 1.3, 5, 3), -- The Forge of Souls
(658, 1.9, 1.3, 1.3, 5, 3), -- Pit of Saron
(668, 1.9, 1.3, 1.3, 5, 3) -- Halls of Reflection
AS new_values
ON DUPLICATE KEY UPDATE
melee_bonus = new_values.melee_bonus,
spell_bonus = new_values.spell_bonus,
heal_bonus = new_values.heal_bonus,
hp_bonus = new_values.hp_bonus,
difficulty = new_values.difficulty;
-- 7. Raid instances (melee_bonus: 2.6, spell_bonus: 2.0, heal_bonus: 1.6, hp_bonus: 3, difficulty: 3)
INSERT INTO mp_scale_factors (mapId, melee_bonus, spell_bonus, heal_bonus, hp_bonus, difficulty)
VALUES
(169, 2.6, 2.0, 1.6, 3, 3), -- Emerald Dream
(249, 2.8, 1.6, 1.6, 3, 3), -- Onyxia's Lair
(309, 2.0, 1.3, 1.6, 3, 3), -- Zul'Gurub
(409, 2.2, 1.4, 1.6, 3, 3), -- Molten Core
(469, 2.6, 2.0, 1.6, 3, 3), -- Blackwing Lair
(509, 2.6, 2.0, 1.6, 3, 3), -- Ruins of Ahn'Qiraj
(531, 2.6, 2.0, 1.6, 3, 3), -- Ahn'Qiraj Temple
(532, 2.6, 2.0, 1.6, 3, 3), -- Karazhan
(533, 2.0, 1.8, 1.6, 3, 3), -- Naxxramas
(534, 2.6, 2.0, 1.6, 3, 3), -- The Battle for Mount Hyjal
(544, 2.0, 2.0, 1.6, 3, 3), -- Magtheridon's Lair
(548, 2.6, 2.0, 1.6, 3, 3), -- Coilfang: Serpentshrine Cavern
(550, 2.6, 2.0, 1.6, 3, 3), -- Tempest Keep
(564, 2.9, 2.8, 1.6, 3, 3), -- Black Temple
(565, 2.6, 2.0, 1.6, 3, 3), -- Gruul's Lair
(568, 2.6, 2.0, 1.6, 3, 3), -- Zul'Aman
(580, 2.6, 2.0, 1.6, 3, 3), -- The Sunwell
(603, 2.6, 2.0, 1.6, 3, 3), -- Ulduar
(615, 2.6, 2.0, 1.6, 3, 3), -- The Obsidian Sanctum
(616, 2.6, 2.0, 1.6, 3, 3), -- The Eye of Eternity
(624, 2.6, 2.0, 1.6, 3, 3), -- Vault of Archavon
(631, 2.8, 2.4, 1.6, 5, 3), -- Icecrown Citadel
(649, 3.0, 2.3, 1.6, 4, 3), -- Trial of the Crusader
(724, 2.68, 2.0, 1.6, 3, 3) -- The Ruby Sanctum
AS new_values
ON DUPLICATE KEY UPDATE
melee_bonus = new_values.melee_bonus,
spell_bonus = new_values.spell_bonus,
heal_bonus = new_values.heal_bonus,
hp_bonus = new_values.hp_bonus,
difficulty = new_values.difficulty;

View File

@@ -1,25 +1,4 @@
/**
* This creates the scaled up stats based on polynomial regression of the base stat growth
*/
CREATE TABLE IF NOT EXISTS `mythicplus_classlevelstats` (
`level` tinyint unsigned NOT NULL,
`class` tinyint unsigned NOT NULL,
`basehp0` int unsigned NOT NULL DEFAULT '1',
`basehp1` int unsigned NOT NULL DEFAULT '1',
`basehp2` int unsigned NOT NULL DEFAULT '1',
`basemana` int unsigned NOT NULL DEFAULT '0',
`basearmor` int unsigned NOT NULL DEFAULT '1',
`attackpower` int unsigned NOT NULL DEFAULT '0',
`rangedattackpower` int unsigned NOT NULL DEFAULT '0',
`damage_base` float NOT NULL DEFAULT '0',
`damage_exp1` float NOT NULL DEFAULT '0',
`damage_exp2` float NOT NULL DEFAULT '0',
`comment` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
PRIMARY KEY (`level`,`class`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
;
INSERT IGNORE INTO mythicplus_classlevelstats (class, `level`, basehp0, basehp1, basehp2,
REPLACE creature_classlevelstats (class, `level`, basehp0, basehp1, basehp2,
basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2) VALUES
(1, 81, 5489.19, 9449.55, 12640.32, 0.00, 10033.36, 714.66, 111.97, 47.9043, 131.5509, 166.3098),
(1, 82, 5641.53, 9700.79, 12855.00, 0.00, 10337.65, 790.54, 121.09, 48.5708, 131.9685, 169.2029),

View File

@@ -0,0 +1,247 @@
-- acore_world.pet_levelstats
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (575, 81, 4399, 2307, 53, 112, 68, 39, 148, 96, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (575, 82, 4473, 2349, 53, 114, 70, 40, 151, 98, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (575, 83, 4548, 2390, 52, 116, 71, 41, 154, 100, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (575, 84, 4622, 2432, 51, 118, 72, 41, 156, 102, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (575, 85, 4697, 2473, 50, 120, 73, 42, 159, 103, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (575, 86, 4771, 2515, 49, 121, 74, 43, 162, 105, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (575, 87, 4846, 2556, 49, 123, 75, 43, 164, 107, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1860, 81, 4219, 2751, 11953, 200, 57, 325, 142, 159, 185, 284);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1860, 82, 4280, 2790, 12131, 203, 58, 330, 144, 161, 188, 288);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1860, 83, 4341, 2829, 12308, 205, 59, 334, 146, 163, 191, 293);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1860, 84, 4402, 2868, 12486, 208, 60, 338, 148, 165, 194, 297);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1860, 85, 4463, 2907, 12664, 211, 61, 342, 150, 167, 197, 302);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1860, 86, 4525, 2945, 12841, 213, 61, 347, 152, 169, 200, 306);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1860, 87, 4586, 2984, 13019, 216, 62, 351, 153, 171, 203, 311);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3450, 81, 1279, 2497, 1, 188, 43, 118, 386, 388, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3450, 82, 1297, 2530, 1, 190, 43, 120, 391, 393, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3450, 83, 1315, 2562, 1, 193, 43, 121, 396, 398, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3450, 84, 1333, 2595, 1, 195, 44, 123, 401, 403, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3450, 85, 1351, 2628, 1, 197, 44, 124, 406, 409, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3450, 86, 1368, 2661, 1, 200, 44, 125, 411, 414, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3450, 87, 1386, 2694, 1, 202, 45, 127, 417, 419, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10979, 81, 1279, 2497, 1, 188, 43, 118, 386, 388, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10979, 82, 1297, 2530, 1, 190, 43, 120, 391, 393, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10979, 83, 1315, 2562, 1, 193, 43, 121, 396, 398, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10979, 84, 1333, 2595, 1, 195, 44, 123, 401, 403, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10979, 85, 1351, 2628, 1, 197, 44, 124, 406, 409, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10979, 86, 1368, 2661, 1, 200, 44, 125, 411, 414, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10979, 87, 1386, 2694, 1, 202, 45, 127, 417, 419, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (14385, 81, 4635, 2170, 5204, 180, 97, 94, 101, 89, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (14385, 82, 4693, 2197, 5273, 182, 98, 95, 102, 90, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (14385, 83, 4750, 2223, 5341, 184, 99, 96, 103, 91, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (14385, 84, 4808, 2249, 5410, 186, 100, 97, 104, 92, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (14385, 85, 4865, 2275, 5478, 188, 101, 98, 105, 93, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (14385, 86, 4923, 2301, 5547, 190, 102, 99, 106, 94, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (14385, 87, 4980, 2328, 5616, 192, 103, 100, 107, 95, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15438, 81, 4280, 1253, 601, 139, 86, 65, 211, 233, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15438, 82, 4356, 1275, 612, 142, 88, 66, 214, 237, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15438, 83, 4432, 1297, 622, 144, 89, 67, 218, 241, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15438, 84, 4508, 1319, 633, 147, 91, 68, 222, 245, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15438, 85, 4584, 1341, 644, 149, 92, 69, 225, 249, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15438, 86, 4660, 1364, 654, 152, 94, 71, 229, 253, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15438, 87, 4735, 1386, 665, 154, 95, 72, 233, 257, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (329, 81, 4251, 2478, 1602, 131, 40, 225, 367, 352, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (329, 82, 4319, 2511, 1623, 133, 40, 227, 372, 357, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (329, 83, 4387, 2545, 1644, 134, 41, 230, 377, 361, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (329, 84, 4455, 2578, 1665, 135, 41, 232, 382, 366, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (329, 85, 4523, 2611, 1685, 137, 42, 234, 387, 371, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (329, 86, 4591, 2645, 1706, 138, 42, 237, 392, 376, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (329, 87, 4658, 2678, 1727, 139, 43, 239, 397, 380, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26101, 81, 1045, 1133, 275, 84, 21, 56, 185, 206, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26101, 82, 1064, 1153, 280, 85, 21, 57, 188, 209, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26101, 83, 1082, 1174, 285, 87, 21, 58, 191, 213, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26101, 84, 1100, 1194, 289, 88, 22, 59, 195, 217, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26101, 85, 1119, 1214, 294, 90, 22, 60, 198, 220, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26101, 86, 1137, 1234, 299, 91, 23, 61, 201, 224, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26101, 87, 1155, 1255, 303, 93, 23, 62, 205, 228, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24815, 81, 1279, 2497, 1, 188, 43, 118, 386, 388, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24815, 82, 1297, 2530, 1, 190, 43, 120, 391, 393, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24815, 83, 1315, 2562, 1, 193, 43, 121, 396, 398, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24815, 84, 1333, 2595, 1, 195, 44, 123, 401, 403, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24815, 85, 1351, 2628, 1, 197, 44, 124, 406, 409, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24815, 86, 1368, 2661, 1, 200, 44, 125, 411, 414, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24815, 87, 1386, 2694, 1, 202, 45, 127, 417, 419, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15352, 81, 4774, 1, 4996, 122, 51, 75, 97, 257, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15352, 82, 4858, 1, 5084, 124, 52, 76, 99, 261, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15352, 83, 4942, 1, 5172, 127, 53, 78, 100, 266, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15352, 84, 5026, 1, 5260, 129, 54, 79, 102, 270, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15352, 85, 5111, 1, 5349, 131, 54, 80, 104, 275, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15352, 86, 5195, 1, 5437, 133, 55, 82, 106, 279, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15352, 87, 5279, 1, 5525, 135, 56, 83, 107, 284, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24656, 81, 3348, 2277, 4266, 83, 59, 161, 78, 77, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24656, 82, 3408, 2318, 4343, 84, 60, 164, 79, 78, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24656, 83, 3467, 2358, 4419, 85, 61, 167, 81, 80, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24656, 84, 3527, 2399, 4496, 87, 63, 170, 82, 81, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24656, 85, 3587, 2440, 4572, 88, 64, 173, 83, 82, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24656, 86, 3647, 2481, 4649, 90, 65, 176, 85, 84, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24656, 87, 3707, 2522, 4725, 91, 66, 178, 86, 85, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25566, 81, 3701, 3657, 4117, 168, 80, 219, 265, 259, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25566, 82, 3763, 3711, 4191, 170, 80, 222, 268, 262, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25566, 83, 3824, 3765, 4265, 172, 81, 226, 271, 265, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25566, 84, 3885, 3818, 4338, 174, 82, 229, 274, 268, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25566, 85, 3947, 3872, 4412, 176, 83, 232, 277, 271, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25566, 86, 4008, 3926, 4486, 178, 84, 235, 280, 274, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25566, 87, 4069, 3980, 4560, 180, 85, 238, 283, 276, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26125, 81, 4635, 2170, 5204, 187, 105, 107, 101, 89, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26125, 82, 4693, 2197, 5273, 189, 106, 108, 102, 90, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26125, 83, 4750, 2223, 5341, 192, 107, 109, 103, 91, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26125, 84, 4808, 2249, 5410, 194, 108, 111, 104, 92, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26125, 85, 4865, 2275, 5478, 196, 109, 112, 105, 93, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26125, 86, 4923, 2301, 5547, 198, 110, 113, 106, 94, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (26125, 87, 4980, 2328, 5616, 200, 112, 115, 107, 95, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5766, 81, 2931, 1473, 5001, 178, 88, 327, 226, 210, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5766, 82, 2976, 1488, 5083, 181, 89, 331, 228, 212, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5766, 83, 3020, 1504, 5165, 183, 90, 335, 231, 214, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5766, 84, 3064, 1519, 5247, 185, 91, 340, 233, 217, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5766, 85, 3108, 1534, 5329, 187, 93, 344, 236, 219, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5766, 86, 3152, 1550, 5411, 190, 94, 348, 238, 221, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5766, 87, 3196, 1565, 5492, 192, 95, 352, 241, 223, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (416, 81, 2865, 2704, 4623, 185, 49, 113, 373, 306, 207, 312);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (416, 82, 2906, 2741, 4691, 188, 50, 114, 377, 310, 211, 317);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (416, 83, 2947, 2778, 4758, 190, 50, 116, 382, 314, 214, 322);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (416, 84, 2989, 2815, 4826, 192, 51, 117, 387, 318, 217, 327);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (416, 85, 3030, 2852, 4894, 195, 51, 118, 391, 322, 220, 332);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (416, 86, 3071, 2890, 4962, 197, 51, 119, 396, 326, 224, 337);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (416, 87, 3112, 2927, 5030, 200, 52, 121, 401, 330, 227, 342);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5058, 81, 5070, 2339, 7812, 179, 131, 359, 121, 120, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5058, 82, 5147, 2367, 7932, 181, 133, 364, 123, 121, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5058, 83, 5224, 2396, 8053, 184, 135, 368, 124, 122, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5058, 84, 5300, 2424, 8174, 186, 136, 373, 125, 124, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5058, 85, 5377, 2453, 8295, 188, 138, 378, 127, 125, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5058, 86, 5454, 2481, 8415, 190, 139, 382, 128, 126, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (5058, 87, 5530, 2509, 8536, 193, 141, 387, 130, 127, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (6250, 81, 2931, 1473, 5001, 178, 88, 327, 226, 210, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (6250, 82, 2976, 1488, 5083, 181, 89, 331, 228, 212, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (6250, 83, 3020, 1504, 5165, 183, 90, 335, 231, 214, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (6250, 84, 3064, 1519, 5247, 185, 91, 340, 233, 217, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (6250, 85, 3108, 1534, 5329, 187, 93, 344, 236, 219, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (6250, 86, 3152, 1550, 5411, 190, 94, 348, 238, 221, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (6250, 87, 3196, 1565, 5492, 192, 95, 352, 241, 223, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8996, 81, 3280, 2467, 4389, 197, 90, 244, 252, 310, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8996, 82, 3319, 2500, 4438, 199, 90, 247, 256, 315, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8996, 83, 3357, 2533, 4487, 202, 91, 250, 260, 319, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8996, 84, 3396, 2566, 4536, 205, 92, 253, 264, 324, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8996, 85, 3435, 2600, 4585, 207, 93, 255, 268, 328, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8996, 86, 3473, 2633, 4634, 210, 94, 258, 271, 333, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8996, 87, 3512, 2666, 4683, 212, 95, 261, 275, 337, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (30230, 81, 4635, 2170, 5204, 187, 105, 107, 101, 89, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (30230, 82, 4693, 2197, 5273, 189, 106, 108, 102, 90, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (30230, 83, 4750, 2223, 5341, 192, 107, 109, 103, 91, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (30230, 84, 4808, 2249, 5410, 194, 108, 111, 104, 92, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (30230, 85, 4865, 2275, 5478, 196, 109, 112, 105, 93, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (30230, 86, 4923, 2301, 5547, 198, 110, 113, 106, 94, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (30230, 87, 4980, 2328, 5616, 200, 112, 115, 107, 95, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1, 81, 4531, 1, 7244, 183, 141, 347, 65, 108, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1, 82, 4596, 1, 7351, 185, 143, 352, 66, 109, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1, 83, 4661, 1, 7458, 187, 145, 356, 66, 110, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1, 84, 4725, 1, 7565, 189, 146, 360, 67, 111, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1, 85, 4790, 1, 7671, 192, 148, 365, 67, 113, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1, 86, 4855, 1, 7778, 194, 150, 369, 68, 114, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1, 87, 4920, 1, 7885, 196, 152, 374, 69, 115, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (37994, 81, 6409, 2978, 4804, 177, 126, 128, 311, 215, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (37994, 82, 6505, 3018, 4873, 179, 127, 129, 316, 218, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (37994, 83, 6602, 3057, 4943, 181, 129, 130, 320, 221, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (37994, 84, 6698, 3096, 5013, 184, 131, 131, 325, 223, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (37994, 85, 6794, 3135, 5083, 186, 132, 132, 330, 226, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (37994, 86, 6891, 3175, 5153, 188, 134, 133, 334, 229, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (37994, 87, 6987, 3214, 5223, 190, 135, 134, 339, 232, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (22362, 81, 1279, 2497, 1084, 188, 43, 118, 386, 388, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (22362, 82, 1297, 2530, 1095, 190, 43, 120, 391, 393, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (22362, 83, 1315, 2562, 1107, 193, 43, 121, 396, 398, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (22362, 84, 1333, 2595, 1118, 195, 44, 123, 401, 403, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (22362, 85, 1351, 2628, 1129, 197, 44, 124, 406, 409, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (22362, 86, 1368, 2661, 1141, 200, 44, 125, 411, 414, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (22362, 87, 1386, 2694, 1152, 202, 45, 127, 417, 419, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1863, 81, 3508, 2779, 7257, 204, 59, 330, 146, 162, 240, 361);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1863, 82, 3560, 2819, 7368, 207, 60, 335, 148, 165, 244, 367);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1863, 83, 3612, 2859, 7479, 210, 60, 339, 150, 167, 248, 372);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1863, 84, 3664, 2899, 7589, 213, 61, 344, 152, 169, 252, 378);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1863, 85, 3717, 2940, 7700, 216, 62, 349, 154, 171, 255, 384);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1863, 86, 3769, 2980, 7810, 218, 63, 353, 156, 174, 259, 390);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (1863, 87, 3821, 3020, 7921, 221, 64, 358, 158, 176, 263, 395);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (19668, 81, 1728, 3131, 35, 126, 88, 54, 202, 131, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (19668, 82, 1756, 3186, 34, 128, 90, 55, 206, 133, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (19668, 83, 1785, 3241, 33, 130, 91, 56, 209, 136, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (19668, 84, 1814, 3296, 32, 132, 93, 57, 213, 138, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (19668, 85, 1842, 3351, 30, 134, 94, 58, 217, 140, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (19668, 86, 1871, 3407, 29, 136, 95, 59, 220, 143, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (19668, 87, 1900, 3462, 28, 139, 97, 60, 224, 145, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (89, 81, 16398, 3013, 11256, 186, 54, 296, 132, 148, 823, 1145);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (89, 82, 16677, 3063, 11445, 189, 55, 301, 134, 150, 837, 1165);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (89, 83, 16955, 3113, 11634, 192, 56, 306, 137, 153, 851, 1184);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (89, 84, 17234, 3162, 11823, 195, 56, 311, 139, 155, 865, 1204);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (89, 85, 17512, 3212, 12012, 198, 57, 316, 141, 158, 879, 1223);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (89, 86, 17790, 3262, 12201, 201, 58, 320, 143, 160, 892, 1243);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (89, 87, 18069, 3311, 12390, 204, 59, 325, 145, 163, 906, 1262);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3939, 81, 3783, 3632, 5236, 172, 79, 331, 260, 223, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3939, 82, 3842, 3686, 5322, 175, 80, 335, 263, 226, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3939, 83, 3902, 3740, 5408, 177, 81, 339, 266, 228, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3939, 84, 3961, 3795, 5494, 179, 82, 343, 269, 231, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3939, 85, 4021, 3849, 5580, 181, 83, 348, 272, 233, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3939, 86, 4080, 3903, 5666, 183, 84, 352, 275, 235, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (3939, 87, 4139, 3957, 5752, 185, 85, 356, 278, 238, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10928, 81, 1900, 2464, 2053, 202, 89, 248, 242, 316, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10928, 82, 1924, 2497, 2079, 205, 90, 251, 246, 321, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10928, 83, 1948, 2530, 2105, 207, 91, 254, 250, 326, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10928, 84, 1973, 2564, 2130, 210, 92, 257, 254, 330, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10928, 85, 1997, 2597, 2156, 213, 93, 260, 258, 335, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10928, 86, 2021, 2630, 2182, 216, 94, 263, 262, 340, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (10928, 87, 2046, 2663, 2208, 219, 95, 266, 265, 345, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (12922, 81, 1279, 2497, 1, 188, 43, 118, 386, 388, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (12922, 82, 1297, 2530, 1, 190, 43, 120, 391, 393, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (12922, 83, 1315, 2562, 1, 193, 43, 121, 396, 398, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (12922, 84, 1333, 2595, 1, 195, 44, 123, 401, 403, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (12922, 85, 1351, 2628, 1, 197, 44, 124, 406, 409, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (12922, 86, 1368, 2661, 1, 200, 44, 125, 411, 414, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (12922, 87, 1386, 2694, 1, 202, 45, 127, 417, 419, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (510, 81, 6409, 2978, 4804, 177, 126, 128, 311, 215, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (510, 82, 6505, 3018, 4873, 179, 127, 129, 316, 218, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (510, 83, 6602, 3057, 4943, 181, 129, 130, 320, 221, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (510, 84, 6698, 3096, 5013, 184, 131, 131, 325, 223, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (510, 85, 6794, 3135, 5083, 186, 132, 132, 330, 226, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (510, 86, 6891, 3175, 5153, 188, 134, 133, 334, 229, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (510, 87, 6987, 3214, 5223, 190, 135, 134, 339, 232, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8477, 81, 3280, 2467, 4389, 197, 90, 244, 252, 310, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8477, 82, 3319, 2500, 4438, 199, 90, 247, 256, 315, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8477, 83, 3357, 2533, 4487, 202, 91, 250, 260, 319, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8477, 84, 3396, 2566, 4536, 205, 92, 253, 264, 324, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8477, 85, 3435, 2600, 4585, 207, 93, 255, 268, 328, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8477, 86, 3473, 2633, 4634, 210, 94, 258, 271, 333, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (8477, 87, 3512, 2666, 4683, 212, 95, 261, 275, 337, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15214, 81, 3783, 3632, 5236, 172, 79, 331, 260, 223, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15214, 82, 3842, 3686, 5322, 175, 80, 335, 263, 226, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15214, 83, 3902, 3740, 5408, 177, 81, 339, 266, 228, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15214, 84, 3961, 3795, 5494, 179, 82, 343, 269, 231, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15214, 85, 4021, 3849, 5580, 181, 83, 348, 272, 233, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15214, 86, 4080, 3903, 5666, 183, 84, 352, 275, 235, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (15214, 87, 4139, 3957, 5752, 185, 85, 356, 278, 238, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (17252, 81, 3926, 2540, 9780, 186, 54, 296, 132, 148, 216, 327);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (17252, 82, 3992, 2582, 9944, 189, 55, 301, 134, 150, 219, 333);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (17252, 83, 4057, 2624, 10109, 192, 56, 306, 137, 153, 223, 338);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (17252, 84, 4122, 2666, 10273, 195, 56, 311, 139, 155, 227, 344);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (17252, 85, 4187, 2708, 10437, 198, 57, 316, 141, 158, 230, 349);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (17252, 86, 4253, 2750, 10601, 201, 58, 320, 143, 160, 234, 355);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (17252, 87, 4318, 2792, 10765, 204, 59, 325, 145, 163, 238, 361);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24476, 81, 2931, 1473, 5001, 178, 88, 327, 226, 210, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24476, 82, 2976, 1488, 5083, 181, 89, 331, 228, 212, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24476, 83, 3020, 1504, 5165, 183, 90, 335, 231, 214, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24476, 84, 3064, 1519, 5247, 185, 91, 340, 233, 217, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24476, 85, 3108, 1534, 5329, 187, 93, 344, 236, 219, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24476, 86, 3152, 1550, 5411, 190, 94, 348, 238, 221, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (24476, 87, 3196, 1565, 5492, 192, 95, 352, 241, 223, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25553, 81, 3783, 3632, 5236, 172, 79, 331, 260, 223, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25553, 82, 3842, 3686, 5322, 175, 80, 335, 263, 226, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25553, 83, 3902, 3740, 5408, 177, 81, 339, 266, 228, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25553, 84, 3961, 3795, 5494, 179, 82, 343, 269, 231, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25553, 85, 4021, 3849, 5580, 181, 83, 348, 272, 233, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25553, 86, 4080, 3903, 5666, 183, 84, 352, 275, 235, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (25553, 87, 4139, 3957, 5752, 185, 85, 356, 278, 238, 1, 1);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (417, 81, 3713, 2790, 5836, 205, 59, 332, 147, 163, 170, 262);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (417, 82, 3770, 2832, 5928, 208, 60, 337, 149, 166, 173, 267);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (417, 83, 3827, 2874, 6019, 211, 61, 342, 151, 168, 175, 271);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (417, 84, 3884, 2916, 6111, 214, 62, 347, 153, 171, 178, 275);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (417, 85, 3941, 2958, 6203, 217, 63, 352, 155, 173, 181, 280);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (417, 86, 3998, 3000, 6294, 221, 63, 357, 158, 176, 184, 284);
REPLACE INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) VALUES (417, 87, 4055, 3042, 6386, 224, 64, 361, 160, 178, 187, 295);

View File

@@ -0,0 +1,51 @@
/** Attempts to insert all post-80 player class stats into the database. */
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (1, 81, 9485, 0, 209, 138, 193, 45, 71);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (1, 82, 10434, 0, 211, 139, 195, 45, 72);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (1, 83, 11477, 0, 213, 140, 197, 45, 73);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (1, 84, 12594, 0, 215, 142, 199, 46, 74);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (1, 85, 13793, 0, 218, 143, 201, 46, 75);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (2, 81, 7449, 4564, 166, 100, 158, 109, 112);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (2, 82, 8078, 4693, 169, 101, 161, 111, 113);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (2, 83, 8737, 4822, 172, 103, 164, 112, 115);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (2, 84, 9427, 4951, 175, 104, 166, 114, 116);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (2, 85, 10151, 5080, 178, 106, 169, 116, 118);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (3, 81, 7482, 4916, 78, 189, 134, 94, 102);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (3, 82, 8070, 5084, 79, 192, 136, 95, 103);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (3, 83, 8681, 5252, 80, 195, 138, 97, 105);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (3, 84, 9315, 5419, 81, 198, 140, 98, 107);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (3, 85, 9973, 5587, 82, 201, 142, 100, 108);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (4, 81, 7246, 0, 121, 200, 113, 47, 71);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (4, 82, 7814, 0, 123, 203, 114, 48, 72);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (4, 83, 8407, 0, 124, 206, 116, 48, 73);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (4, 84, 9025, 0, 126, 209, 117, 49, 74);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (4, 85, 9670, 0, 128, 212, 119, 50, 75);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (5, 81, 7395, 4153, 49, 57, 74, 197, 205);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (5, 82, 7975, 4280, 49, 58, 75, 201, 208);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (5, 83, 8581, 4407, 50, 58, 76, 204, 211);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (5, 84, 9215, 4534, 50, 59, 77, 207, 215);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (5, 85, 9876, 4661, 51, 60, 78, 210, 218);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (6, 81, 8118, 0, 176, 114, 166, 37, 58);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (6, 82, 8740, 0, 179, 116, 169, 37, 59);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (6, 83, 9390, 0, 181, 117, 172, 37, 60);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (6, 84, 10070, 0, 184, 119, 175, 38, 61);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (6, 85, 10802, 0, 187, 121, 178, 38, 61);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (7, 81, 7382, 4562, 123, 77, 139, 131, 145);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (7, 82, 7981, 4692, 123, 78, 141, 134, 147);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (7, 83, 8607, 4823, 125, 79, 143, 137, 149);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (7, 84, 9259, 4953, 126, 80, 145, 139, 151);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (7, 85, 9939, 5083, 128, 81, 147, 142, 153);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (8, 81, 7382, 3446, 39, 47, 61, 207, 197);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (8, 82, 7981, 3546, 39, 47, 62, 211, 201);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (8, 83, 8607, 3647, 40, 48, 63, 214, 204);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (8, 84, 9259, 3748, 40, 48, 63, 218, 208);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (8, 85, 9939, 3849, 40, 49, 64, 221, 211);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (9, 81, 7153, 3690, 61, 69, 92, 158, 165);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (9, 82, 7700, 3817, 62, 70, 93, 161, 168);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (9, 83, 8266, 3944, 63, 71, 94, 164, 171);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (9, 84, 8852, 4072, 63, 72, 95, 166, 175);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (9, 85, 9460, 4199, 64, 73, 96, 169, 178);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (11, 81, 5694, 3227, 99, 90, 106, 163, 180);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (11, 82, 6132, 3342, 100, 91, 108, 166, 183);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (11, 83, 6596, 3458, 101, 92, 109, 168, 186);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (11, 84, 7086, 3573, 102, 94, 111, 171, 190);
insert ignore into acore_world.player_class_stats (Class, Level, BaseHP, BaseMana, Strength, Agility, Stamina, Intellect, Spirit) values (11, 85, 7601, 3688, 104, 95, 113, 174, 193);

View File

@@ -0,0 +1,500 @@
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 0, 911005, 0, 0, 5, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 1, 911009, 0, 0, 5, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 2, 911003, 0, 0, 5, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 3, 911007, 0, 0, 5, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 4, 911011, 0, 0, 5, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 5, 911019, 0, 0, 4, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 6, 911017, 0, 0, 4, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 7, 911023, 0, 0, 4, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 8, 911015, 0, 0, 4, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (1, 9, 911021, 0, 0, 4, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 0, 911005, 0, 0, 8, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 1, 911009, 0, 0, 8, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 2, 911003, 0, 0, 8, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 3, 911007, 0, 0, 8, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 4, 911011, 0, 0, 8, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 5, 911019, 0, 0, 6, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 6, 911017, 0, 0, 6, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 7, 911023, 0, 0, 6, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 8, 911015, 0, 0, 6, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (2, 9, 911021, 0, 0, 6, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 0, 911005, 0, 0, 10, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 1, 911009, 0, 0, 10, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 2, 911003, 0, 0, 10, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 3, 911007, 0, 0, 10, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 4, 911011, 0, 0, 10, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 5, 911019, 0, 0, 8, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 6, 911017, 0, 0, 8, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 7, 911023, 0, 0, 8, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 8, 911015, 0, 0, 8, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (3, 9, 911021, 0, 0, 8, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 0, 911005, 0, 0, 13, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 1, 911009, 0, 0, 13, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 2, 911003, 0, 0, 13, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 3, 911007, 0, 0, 13, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 4, 911011, 0, 0, 13, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 5, 911019, 0, 0, 9, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 6, 911017, 0, 0, 9, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 7, 911023, 0, 0, 9, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 8, 911015, 0, 0, 9, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (4, 9, 911021, 0, 0, 9, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 0, 911005, 0, 0, 15, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 1, 911009, 0, 0, 15, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 2, 911003, 0, 0, 15, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 3, 911007, 0, 0, 15, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 4, 911011, 0, 0, 15, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 5, 911019, 0, 0, 11, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 6, 911017, 0, 0, 11, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 7, 911023, 0, 0, 11, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 8, 911015, 0, 0, 11, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (5, 9, 911021, 0, 0, 11, 0, 0, 1, 5, 3, 5, 4, 6, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 0, 911005, 0, 0, 18, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 1, 911009, 0, 0, 18, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 2, 911003, 0, 0, 18, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 3, 911007, 0, 0, 18, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 4, 911011, 0, 0, 18, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 5, 911019, 0, 0, 13, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 6, 911017, 0, 0, 13, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 7, 911023, 0, 0, 13, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 8, 911015, 0, 0, 13, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (6, 9, 911021, 0, 0, 13, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 0, 911005, 0, 0, 20, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 1, 911009, 0, 0, 20, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 2, 911003, 0, 0, 20, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 3, 911007, 0, 0, 20, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 4, 911011, 0, 0, 20, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 5, 911019, 0, 0, 15, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 6, 911017, 0, 0, 15, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 7, 911023, 0, 0, 15, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 8, 911015, 0, 0, 15, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (7, 9, 911021, 0, 0, 15, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 0, 911005, 0, 0, 23, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 1, 911009, 0, 0, 23, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 2, 911003, 0, 0, 23, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 3, 911007, 0, 0, 23, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 4, 911011, 0, 0, 23, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 5, 911019, 0, 0, 16, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 6, 911017, 0, 0, 16, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 7, 911023, 0, 0, 16, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 8, 911015, 0, 0, 16, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (8, 9, 911021, 0, 0, 16, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 0, 911005, 0, 0, 25, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 1, 911009, 0, 0, 25, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 2, 911003, 0, 0, 25, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 3, 911007, 0, 0, 25, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 4, 911011, 0, 0, 25, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 5, 911019, 0, 0, 18, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 6, 911017, 0, 0, 18, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 7, 911023, 0, 0, 18, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 8, 911015, 0, 0, 18, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (9, 9, 911021, 0, 0, 18, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 0, 911005, 0, 0, 28, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 1, 911009, 0, 0, 28, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 2, 911003, 0, 0, 28, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 3, 911007, 0, 0, 28, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 4, 911011, 0, 0, 28, 0, 0, 1, 10, 5, 10, 8, 11, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 5, 911019, 0, 0, 20, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 6, 911017, 0, 0, 20, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 7, 911023, 0, 0, 20, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 8, 911015, 0, 0, 20, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (10, 9, 911021, 0, 0, 20, 0, 0, 3, 7, 5, 7, 8, 10, 25, 50, 75);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 0, 911005, 911006, 0, 25, 0, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 1, 911009, 911010, 0, 25, 0, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 2, 911003, 911004, 0, 25, 0, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 3, 911007, 911008, 0, 25, 0, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 4, 911011, 911012, 0, 25, 0, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 5, 911019, 911020, 0, 18, 0, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 6, 911017, 911018, 0, 18, 0, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 7, 911023, 911024, 0, 18, 0, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 8, 911015, 911016, 0, 18, 0, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (11, 9, 911021, 911022, 0, 18, 0, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 0, 911005, 911006, 0, 27, 2, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 1, 911009, 911010, 0, 27, 2, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 2, 911003, 911004, 0, 27, 2, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 3, 911007, 911008, 0, 27, 2, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 4, 911011, 911012, 0, 27, 2, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 5, 911019, 911020, 0, 19, 2, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 6, 911017, 911018, 0, 19, 2, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 7, 911023, 911024, 0, 19, 2, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 8, 911015, 911016, 0, 19, 2, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (12, 9, 911021, 911022, 0, 19, 2, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 0, 911005, 911006, 0, 28, 4, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 1, 911009, 911010, 0, 28, 4, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 2, 911003, 911004, 0, 28, 4, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 3, 911007, 911008, 0, 28, 4, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 4, 911011, 911012, 0, 28, 4, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 5, 911019, 911020, 0, 20, 4, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 6, 911017, 911018, 0, 20, 4, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 7, 911023, 911024, 0, 20, 4, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 8, 911015, 911016, 0, 20, 4, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (13, 9, 911021, 911022, 0, 20, 4, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 0, 911005, 911006, 0, 29, 6, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 1, 911009, 911010, 0, 29, 6, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 2, 911003, 911004, 0, 29, 6, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 3, 911007, 911008, 0, 29, 6, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 4, 911011, 911012, 0, 29, 6, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 5, 911019, 911020, 0, 22, 6, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 6, 911017, 911018, 0, 22, 6, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 7, 911023, 911024, 0, 22, 6, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 8, 911015, 911016, 0, 22, 6, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (14, 9, 911021, 911022, 0, 22, 6, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 0, 911005, 911006, 0, 30, 8, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 1, 911009, 911010, 0, 30, 8, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 2, 911003, 911004, 0, 30, 8, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 3, 911007, 911008, 0, 30, 8, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 4, 911011, 911012, 0, 30, 8, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 5, 911019, 911020, 0, 23, 8, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 6, 911017, 911018, 0, 23, 8, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 7, 911023, 911024, 0, 23, 8, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 8, 911015, 911016, 0, 23, 8, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (15, 9, 911021, 911022, 0, 23, 8, 0, 5, 9, 7, 9, 12, 14, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 0, 911005, 911006, 0, 32, 10, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 1, 911009, 911010, 0, 32, 10, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 2, 911003, 911004, 0, 32, 10, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 3, 911007, 911008, 0, 32, 10, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 4, 911011, 911012, 0, 32, 10, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 5, 911019, 911020, 0, 24, 10, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 6, 911017, 911018, 0, 24, 10, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 7, 911023, 911024, 0, 24, 10, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 8, 911015, 911016, 0, 24, 10, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (16, 9, 911021, 911022, 0, 24, 10, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 0, 911005, 911006, 0, 33, 12, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 1, 911009, 911010, 0, 33, 12, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 2, 911003, 911004, 0, 33, 12, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 3, 911007, 911008, 0, 33, 12, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 4, 911011, 911012, 0, 33, 12, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 5, 911019, 911020, 0, 25, 12, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 6, 911017, 911018, 0, 25, 12, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 7, 911023, 911024, 0, 25, 12, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 8, 911015, 911016, 0, 25, 12, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (17, 9, 911021, 911022, 0, 25, 12, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 0, 911005, 911006, 0, 34, 14, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 1, 911009, 911010, 0, 34, 14, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 2, 911003, 911004, 0, 34, 14, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 3, 911007, 911008, 0, 34, 14, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 4, 911011, 911012, 0, 34, 14, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 5, 911019, 911020, 0, 27, 14, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 6, 911017, 911018, 0, 27, 14, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 7, 911023, 911024, 0, 27, 14, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 8, 911015, 911016, 0, 27, 14, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (18, 9, 911021, 911022, 0, 27, 14, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 0, 911005, 911006, 0, 35, 16, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 1, 911009, 911010, 0, 35, 16, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 2, 911003, 911004, 0, 35, 16, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 3, 911007, 911008, 0, 35, 16, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 4, 911011, 911012, 0, 35, 16, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 5, 911019, 911020, 0, 28, 16, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 6, 911017, 911018, 0, 28, 16, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 7, 911023, 911024, 0, 28, 16, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 8, 911015, 911016, 0, 28, 16, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (19, 9, 911021, 911022, 0, 28, 16, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 0, 911005, 911006, 0, 37, 18, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 1, 911009, 911010, 0, 37, 18, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 2, 911003, 911004, 0, 37, 18, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 3, 911007, 911008, 0, 37, 18, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 4, 911011, 911012, 0, 37, 18, 0, 3, 12, 7, 12, 12, 15, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 5, 911019, 911020, 0, 29, 18, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 6, 911017, 911018, 0, 29, 18, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 7, 911023, 911024, 0, 29, 18, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 8, 911015, 911016, 0, 29, 18, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (20, 9, 911021, 911022, 0, 29, 18, 0, 7, 11, 9, 11, 16, 18, 50, 75, 100);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 0, 911005, 911006, 0, 38, 20, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 1, 911009, 911010, 0, 38, 20, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 2, 911003, 911004, 0, 38, 20, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 3, 911007, 911008, 0, 38, 20, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 4, 911011, 911012, 0, 38, 20, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 5, 911019, 911020, 0, 30, 20, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 6, 911017, 911018, 0, 30, 20, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 7, 911023, 911024, 0, 30, 20, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 8, 911015, 911016, 0, 30, 20, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (21, 9, 911021, 911022, 0, 30, 20, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 0, 911005, 911006, 0, 39, 22, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 1, 911009, 911010, 0, 39, 22, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 2, 911003, 911004, 0, 39, 22, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 3, 911007, 911008, 0, 39, 22, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 4, 911011, 911012, 0, 39, 22, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 5, 911019, 911020, 0, 32, 22, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 6, 911017, 911018, 0, 32, 22, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 7, 911023, 911024, 0, 32, 22, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 8, 911015, 911016, 0, 32, 22, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (22, 9, 911021, 911022, 0, 32, 22, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 0, 911005, 911006, 0, 40, 24, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 1, 911009, 911010, 0, 40, 24, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 2, 911003, 911004, 0, 40, 24, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 3, 911007, 911008, 0, 40, 24, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 4, 911011, 911012, 0, 40, 24, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 5, 911019, 911020, 0, 33, 24, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 6, 911017, 911018, 0, 33, 24, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 7, 911023, 911024, 0, 33, 24, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 8, 911015, 911016, 0, 33, 24, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (23, 9, 911021, 911022, 0, 33, 24, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 0, 911005, 911006, 0, 42, 26, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 1, 911009, 911010, 0, 42, 26, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 2, 911003, 911004, 0, 42, 26, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 3, 911007, 911008, 0, 42, 26, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 4, 911011, 911012, 0, 42, 26, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 5, 911019, 911020, 0, 34, 26, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 6, 911017, 911018, 0, 34, 26, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 7, 911023, 911024, 0, 34, 26, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 8, 911015, 911016, 0, 34, 26, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (24, 9, 911021, 911022, 0, 34, 26, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 0, 911005, 911006, 0, 43, 28, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 1, 911009, 911010, 0, 43, 28, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 2, 911003, 911004, 0, 43, 28, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 3, 911007, 911008, 0, 43, 28, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 4, 911011, 911012, 0, 43, 28, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 5, 911019, 911020, 0, 35, 28, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 6, 911017, 911018, 0, 35, 28, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 7, 911023, 911024, 0, 35, 28, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 8, 911015, 911016, 0, 35, 28, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (25, 9, 911021, 911022, 0, 35, 28, 0, 9, 13, 11, 13, 20, 22, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 0, 911005, 911006, 0, 44, 30, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 1, 911009, 911010, 0, 44, 30, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 2, 911003, 911004, 0, 44, 30, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 3, 911007, 911008, 0, 44, 30, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 4, 911011, 911012, 0, 44, 30, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 5, 911019, 911020, 0, 37, 30, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 6, 911017, 911018, 0, 37, 30, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 7, 911023, 911024, 0, 37, 30, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 8, 911015, 911016, 0, 37, 30, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (26, 9, 911021, 911022, 0, 37, 30, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 0, 911005, 911006, 0, 45, 32, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 1, 911009, 911010, 0, 45, 32, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 2, 911003, 911004, 0, 45, 32, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 3, 911007, 911008, 0, 45, 32, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 4, 911011, 911012, 0, 45, 32, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 5, 911019, 911020, 0, 38, 32, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 6, 911017, 911018, 0, 38, 32, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 7, 911023, 911024, 0, 38, 32, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 8, 911015, 911016, 0, 38, 32, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (27, 9, 911021, 911022, 0, 38, 32, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 0, 911005, 911006, 0, 47, 34, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 1, 911009, 911010, 0, 47, 34, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 2, 911003, 911004, 0, 47, 34, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 3, 911007, 911008, 0, 47, 34, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 4, 911011, 911012, 0, 47, 34, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 5, 911019, 911020, 0, 39, 34, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 6, 911017, 911018, 0, 39, 34, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 7, 911023, 911024, 0, 39, 34, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 8, 911015, 911016, 0, 39, 34, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (28, 9, 911021, 911022, 0, 39, 34, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 0, 911005, 911006, 0, 48, 36, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 1, 911009, 911010, 0, 48, 36, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 2, 911003, 911004, 0, 48, 36, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 3, 911007, 911008, 0, 48, 36, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 4, 911011, 911012, 0, 48, 36, 0, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 5, 911019, 911020, 0, 40, 36, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 6, 911017, 911018, 0, 40, 36, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 7, 911023, 911024, 0, 40, 36, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 8, 911015, 911016, 0, 40, 36, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (29, 9, 911021, 911022, 0, 40, 36, 0, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 0, 911005, 911006, 911002, 50, 38, 3, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 1, 911009, 911010, 911002, 50, 38, 3, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 2, 911003, 911004, 911002, 50, 38, 3, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 3, 911007, 911008, 911002, 50, 38, 3, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 4, 911011, 911012, 911002, 50, 38, 3, 5, 14, 9, 14, 16, 19, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 5, 911019, 911020, 911002, 35, 38, 3, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 6, 911017, 911018, 911002, 35, 38, 3, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 7, 911023, 911024, 911002, 35, 38, 3, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 8, 911015, 911016, 911002, 35, 38, 3, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (30, 9, 911021, 911022, 911002, 35, 38, 3, 11, 15, 13, 15, 24, 26, 75, 100, 125);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 0, 911005, 911006, 911002, 51, 40, 6, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 1, 911009, 911010, 911002, 51, 40, 6, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 2, 911003, 911004, 911002, 51, 40, 6, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 3, 911007, 911008, 911002, 51, 40, 6, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 4, 911011, 911012, 911002, 51, 40, 6, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 5, 911019, 911020, 911002, 36, 40, 6, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 6, 911017, 911018, 911002, 36, 40, 6, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 7, 911023, 911024, 911002, 36, 40, 6, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 8, 911015, 911016, 911002, 36, 40, 6, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (31, 9, 911021, 911022, 911002, 36, 40, 6, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 0, 911005, 911006, 911002, 52, 42, 9, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 1, 911009, 911010, 911002, 52, 42, 9, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 2, 911003, 911004, 911002, 52, 42, 9, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 3, 911007, 911008, 911002, 52, 42, 9, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 4, 911011, 911012, 911002, 52, 42, 9, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 5, 911019, 911020, 911002, 37, 42, 9, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 6, 911017, 911018, 911002, 37, 42, 9, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 7, 911023, 911024, 911002, 37, 42, 9, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 8, 911015, 911016, 911002, 37, 42, 9, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (32, 9, 911021, 911022, 911002, 37, 42, 9, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 0, 911005, 911006, 911002, 53, 44, 12, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 1, 911009, 911010, 911002, 53, 44, 12, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 2, 911003, 911004, 911002, 53, 44, 12, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 3, 911007, 911008, 911002, 53, 44, 12, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 4, 911011, 911012, 911002, 53, 44, 12, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 5, 911019, 911020, 911002, 38, 44, 12, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 6, 911017, 911018, 911002, 38, 44, 12, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 7, 911023, 911024, 911002, 38, 44, 12, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 8, 911015, 911016, 911002, 38, 44, 12, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (33, 9, 911021, 911022, 911002, 38, 44, 12, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 0, 911005, 911006, 911002, 54, 46, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 1, 911009, 911010, 911002, 54, 46, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 2, 911003, 911004, 911002, 54, 46, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 3, 911007, 911008, 911002, 54, 46, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 4, 911011, 911012, 911002, 54, 46, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 5, 911019, 911020, 911002, 39, 46, 15, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 6, 911017, 911018, 911002, 39, 46, 15, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 7, 911023, 911024, 911002, 39, 46, 15, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 8, 911015, 911016, 911002, 39, 46, 15, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (34, 9, 911021, 911022, 911002, 39, 46, 15, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 0, 911005, 911006, 911002, 55, 48, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 1, 911009, 911010, 911002, 55, 48, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 2, 911003, 911004, 911002, 55, 48, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 3, 911007, 911008, 911002, 55, 48, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 4, 911011, 911012, 911002, 55, 48, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 5, 911019, 911020, 911002, 40, 48, 18, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 6, 911017, 911018, 911002, 40, 48, 18, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 7, 911023, 911024, 911002, 40, 48, 18, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 8, 911015, 911016, 911002, 40, 48, 18, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (35, 9, 911021, 911022, 911002, 40, 48, 18, 13, 17, 15, 17, 28, 30, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 0, 911005, 911006, 911002, 56, 50, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 1, 911009, 911010, 911002, 56, 50, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 2, 911003, 911004, 911002, 56, 50, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 3, 911007, 911008, 911002, 56, 50, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 4, 911011, 911012, 911002, 56, 50, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 5, 911019, 911020, 911002, 41, 50, 21, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 6, 911017, 911018, 911002, 41, 50, 21, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 7, 911023, 911024, 911002, 41, 50, 21, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 8, 911015, 911016, 911002, 41, 50, 21, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (36, 9, 911021, 911022, 911002, 41, 50, 21, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 0, 911005, 911006, 911002, 57, 52, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 1, 911009, 911010, 911002, 57, 52, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 2, 911003, 911004, 911002, 57, 52, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 3, 911007, 911008, 911002, 57, 52, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 4, 911011, 911012, 911002, 57, 52, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 5, 911019, 911020, 911002, 42, 52, 24, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 6, 911017, 911018, 911002, 42, 52, 24, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 7, 911023, 911024, 911002, 42, 52, 24, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 8, 911015, 911016, 911002, 42, 52, 24, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (37, 9, 911021, 911022, 911002, 42, 52, 24, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 0, 911005, 911006, 911002, 58, 54, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 1, 911009, 911010, 911002, 58, 54, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 2, 911003, 911004, 911002, 58, 54, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 3, 911007, 911008, 911002, 58, 54, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 4, 911011, 911012, 911002, 58, 54, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 5, 911019, 911020, 911002, 43, 54, 27, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 6, 911017, 911018, 911002, 43, 54, 27, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 7, 911023, 911024, 911002, 43, 54, 27, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 8, 911015, 911016, 911002, 43, 54, 27, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (38, 9, 911021, 911022, 911002, 43, 54, 27, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 0, 911005, 911006, 911002, 59, 56, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 1, 911009, 911010, 911002, 59, 56, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 2, 911003, 911004, 911002, 59, 56, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 3, 911007, 911008, 911002, 59, 56, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 4, 911011, 911012, 911002, 59, 56, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 5, 911019, 911020, 911002, 44, 56, 30, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 6, 911017, 911018, 911002, 44, 56, 30, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 7, 911023, 911024, 911002, 44, 56, 30, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 8, 911015, 911016, 911002, 44, 56, 30, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (39, 9, 911021, 911022, 911002, 44, 56, 30, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 0, 911005, 911006, 911002, 59, 58, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 1, 911009, 911010, 911002, 59, 58, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 2, 911003, 911004, 911002, 59, 58, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 3, 911007, 911008, 911002, 59, 58, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 4, 911011, 911012, 911002, 59, 58, 15, 7, 16, 11, 16, 20, 23, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 5, 911019, 911020, 911002, 44, 58, 33, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 6, 911017, 911018, 911002, 44, 58, 33, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 7, 911023, 911024, 911002, 44, 58, 33, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 8, 911015, 911016, 911002, 44, 58, 33, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (40, 9, 911021, 911022, 911002, 44, 58, 33, 15, 19, 17, 19, 32, 34, 100, 125, 150);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 0, 911005, 911006, 911002, 60, 60, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 1, 911009, 911010, 911002, 60, 60, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 2, 911003, 911004, 911002, 60, 60, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 3, 911007, 911008, 911002, 60, 60, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 4, 911011, 911012, 911002, 60, 60, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 5, 911019, 911020, 911002, 45, 60, 36, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 6, 911017, 911018, 911002, 45, 60, 36, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 7, 911023, 911024, 911002, 45, 60, 36, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 8, 911015, 911016, 911002, 45, 60, 36, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (41, 9, 911021, 911022, 911002, 45, 60, 36, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 0, 911005, 911006, 911002, 61, 62, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 1, 911009, 911010, 911002, 61, 62, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 2, 911003, 911004, 911002, 61, 62, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 3, 911007, 911008, 911002, 61, 62, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 4, 911011, 911012, 911002, 61, 62, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 5, 911019, 911020, 911002, 46, 62, 39, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 6, 911017, 911018, 911002, 46, 62, 39, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 7, 911023, 911024, 911002, 46, 62, 39, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 8, 911015, 911016, 911002, 46, 62, 39, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (42, 9, 911021, 911022, 911002, 46, 62, 39, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 0, 911005, 911006, 911002, 62, 64, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 1, 911009, 911010, 911002, 62, 64, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 2, 911003, 911004, 911002, 62, 64, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 3, 911007, 911008, 911002, 62, 64, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 4, 911011, 911012, 911002, 62, 64, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 5, 911019, 911020, 911002, 47, 64, 42, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 6, 911017, 911018, 911002, 47, 64, 42, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 7, 911023, 911024, 911002, 47, 64, 42, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 8, 911015, 911016, 911002, 47, 64, 42, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (43, 9, 911021, 911022, 911002, 47, 64, 42, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 0, 911005, 911006, 911002, 63, 66, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 1, 911009, 911010, 911002, 63, 66, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 2, 911003, 911004, 911002, 63, 66, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 3, 911007, 911008, 911002, 63, 66, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 4, 911011, 911012, 911002, 63, 66, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 5, 911019, 911020, 911002, 48, 66, 45, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 6, 911017, 911018, 911002, 48, 66, 45, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 7, 911023, 911024, 911002, 48, 66, 45, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 8, 911015, 911016, 911002, 48, 66, 45, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (44, 9, 911021, 911022, 911002, 48, 66, 45, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 0, 911005, 911006, 911002, 64, 68, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 1, 911009, 911010, 911002, 64, 68, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 2, 911003, 911004, 911002, 64, 68, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 3, 911007, 911008, 911002, 64, 68, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 4, 911011, 911012, 911002, 64, 68, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 5, 911019, 911020, 911002, 49, 68, 48, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 6, 911017, 911018, 911002, 49, 68, 48, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 7, 911023, 911024, 911002, 49, 68, 48, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 8, 911015, 911016, 911002, 49, 68, 48, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (45, 9, 911021, 911022, 911002, 49, 68, 48, 17, 21, 19, 21, 36, 38, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 0, 911005, 911006, 911002, 65, 70, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 1, 911009, 911010, 911002, 65, 70, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 2, 911003, 911004, 911002, 65, 70, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 3, 911007, 911008, 911002, 65, 70, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 4, 911011, 911012, 911002, 65, 70, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 5, 911019, 911020, 911002, 50, 70, 51, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 6, 911017, 911018, 911002, 50, 70, 51, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 7, 911023, 911024, 911002, 50, 70, 51, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 8, 911015, 911016, 911002, 50, 70, 51, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (46, 9, 911021, 911022, 911002, 50, 70, 51, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 0, 911005, 911006, 911002, 66, 72, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 1, 911009, 911010, 911002, 66, 72, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 2, 911003, 911004, 911002, 66, 72, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 3, 911007, 911008, 911002, 66, 72, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 4, 911011, 911012, 911002, 66, 72, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 5, 911019, 911020, 911002, 51, 72, 54, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 6, 911017, 911018, 911002, 51, 72, 54, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 7, 911023, 911024, 911002, 51, 72, 54, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 8, 911015, 911016, 911002, 51, 72, 54, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (47, 9, 911021, 911022, 911002, 51, 72, 54, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 0, 911005, 911006, 911002, 67, 74, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 1, 911009, 911010, 911002, 67, 74, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 2, 911003, 911004, 911002, 67, 74, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 3, 911007, 911008, 911002, 67, 74, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 4, 911011, 911012, 911002, 67, 74, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 5, 911019, 911020, 911002, 52, 74, 57, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 6, 911017, 911018, 911002, 52, 74, 57, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 7, 911023, 911024, 911002, 52, 74, 57, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 8, 911015, 911016, 911002, 52, 74, 57, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (48, 9, 911021, 911022, 911002, 52, 74, 57, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 0, 911005, 911006, 911002, 68, 76, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 1, 911009, 911010, 911002, 68, 76, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 2, 911003, 911004, 911002, 68, 76, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 3, 911007, 911008, 911002, 68, 76, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 4, 911011, 911012, 911002, 68, 76, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 5, 911019, 911020, 911002, 53, 76, 60, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 6, 911017, 911018, 911002, 53, 76, 60, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 7, 911023, 911024, 911002, 53, 76, 60, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 8, 911015, 911016, 911002, 53, 76, 60, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (49, 9, 911021, 911022, 911002, 53, 76, 60, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 0, 911005, 911006, 911002, 68, 78, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 1, 911009, 911010, 911002, 68, 78, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 2, 911003, 911004, 911002, 68, 78, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 3, 911007, 911008, 911002, 68, 78, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 4, 911011, 911012, 911002, 68, 78, 15, 9, 18, 13, 18, 24, 27, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 5, 911019, 911020, 911002, 53, 78, 63, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 6, 911017, 911018, 911002, 53, 78, 63, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 7, 911023, 911024, 911002, 53, 78, 63, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 8, 911015, 911016, 911002, 53, 78, 63, 19, 23, 21, 23, 40, 42, 150, 175, 200);
REPLACE INTO acore_world.mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemEntry2, itemEntry3, itemCost1, itemCost2, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES (50, 9, 911021, 911022, 911002, 53, 78, 63, 19, 23, 21, 23, 40, 42, 150, 175, 200);

View File

@@ -0,0 +1,24 @@
REPLACE INTO acore_world.spell_script_names (spell_id, ScriptName) VALUES
('80000001','spell_mp_titans_strength_aura'),
('80000002','spell_mp_steel_forged_aura'),
('80000003','spell_mp_celestial_grace_aura'),
('80000004','spell_mp_forbidden_knowledge_aura'),
('80000005','spell_mp_spectral_reflexes_aura'),
('80000006','spell_mp_eldritch_barrier_aura'),
('80000007','spell_mp_hellfire_shielding_aura'),
('80000008','spell_mp_primal_endurance_aura'),
('80000009','spell_mp_lichs_bane_aura'),
('80000010','spell_mp_glacial_fortress_aura');
DELETE FROM `spell_dbc` WHERE `ID` IN (80000001, 80000002, 80000003, 80000004, 80000005, 80000006, 80000007, 80000008, 80000009, 80000010);
INSERT INTO `spell_dbc` (`ID`, `Attributes`, `AttributesEx`, `DispelType`, `Effect_1`, `EffectAura_1`,`EffectMiscValue_1`, `Name_Lang_enUS`, `Description_Lang_enUS`) VALUES
(80000001, 192, 0, 0, 6, 29, 0, 'Titan\'s Strength', 'Empowers you with the legendary strength of the Titans, enhancing your physical prowess.'),
(80000002, 192, 0, 0, 6, 29, 2, 'Steel Forged', 'Transforms your skin into an impenetrable steel armor, deflecting all but the mightiest blows.'),
(80000003, 192, 0, 0, 6, 29, 4,'Celestial Grace', 'Blessed with celestial wisdom, you inspire and uplift the spirits of allies around you.'),
(80000004, 192, 0, 0, 6, 29, 3,'Forbidden Knowledge', 'You have delved into the forbidden secrets of Azeroth, unlocking arcane mysteries and hidden powers.'),
(80000005, 192, 0, 0, 6, 29, 1,'Spectral Reflexes', 'You become a phantom, mastering the art of the blade and dagger with unparalleled precision.'),
(80000006, 192, 0, 0, 6, 22, 64,'Eldritch Barrier', 'Erects an eldritch barrier that halts arcane forces in their tracks, shielding you from magical harm.'),
(80000007, 192, 0, 0, 6, 22, 4,'Hellfire Shielding', 'You have learned to withstand the infernal flames of hell, emerging unscathed from fiery assaults.'),
(80000008, 192, 0, 0, 6, 22, 8,'Primal Endurance', 'Your endurance has been toughened to resist pestilence and plague, rendering you immune to their effects.'),
(80000009, 192, 0, 0, 6, 22, 32, 'Lich\'s Bane', 'You possess the knowledge to counter the shadows of the undead, protecting your flesh from their dark touch.'),
(80000010, 192, 0, 0, 6, 22, 16, 'Glacial Fortress', 'You can withstand temperatures far below freezing that no mere mortal can endure, encased in a glacial fortress.');

View File

@@ -0,0 +1,97 @@
-- Common dice for stat roles
DELETE FROM `item_template` WHERE (`entry` = 911000);
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
(911000, 15, 4, -1, 'Ancient Dice', 52015, 3, 163840, 0, 1, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 'Ancient dice from an unknown origin, maybe someone or something is looking for them.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0);
-- Rare Item for reseting AA points
DELETE FROM `item_template` WHERE (`entry` = 911001);
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
(911001, 0, 4, -1, 'Onyx Spike Relic', 33851, 4, 0, 0, 0, 0, 10000000, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0, 0, 65082, 0, 10, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, 'This relic has a dangerous aura. Using this seems fatal', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0);
-- Legendary Veilstone for end game stat upgrades
DELETE FROM `item_template` WHERE (`entry` = 911002);
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
(911002, 15, 4, -1, 'Veilstone', 270622, 5, 0, 0, 1, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, 'A gem that holds together the boundary between dimensions.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0);
-- mythical fusion items
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911003, 7, 1, -1, 'Fused Ore', '', 270620, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 1, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911004, 7, 1, -1, 'Moltenheart Core', 'Mythical ore from high level fusion', 270608, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 1, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911005, 7, 7, -1, 'Fused Cloth', '', 270613, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 7, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911006, 7, 7, -1, 'Soulthread Shroud', 'Mythical cloth from high level fusion', 270601, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 7, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911007, 7, 8, -1, 'Fused Leather', '', 270619, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 8, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911008, 7, 8, -1, 'Ashwild Pelt', 'Mythical leather from high level fusion', 270607, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 8, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911009, 7, 3, -1, 'Fused Compound', '', 270610, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 3, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911010, 7, 3, -1, 'Elixir of Chaos', 'Mythical alchemy component from high level fusion', 270599, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 3, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911011, 7, 4, -1, 'Fused Gem', '', 270616, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 4, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911012, 7, 4, -1, 'Starfused Prism', 'Mythical gemstone from high level fusion', 270604, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 4, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911013, 7, 0, -1, 'Fused Essence', '', 270615, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911014, 7, 0, -1, 'Crystalline Echo', 'Mythical enchanting component from high level fusion', 270603, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911015, 7, 0, -1, 'Fused Frostshard', 'Artifact that emits extreme cold', 270617, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911016, 7, 0, -1, 'Everfrost Crystal', 'Mythical frost component from high level fusion', 270605, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911017, 7, 0, -1, 'Fused Infernostone', 'Artifact that emits extreme heat', 270618, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911018, 7, 0, -1, 'Blazebound Ember', 'Mythical fire component from high level fusion', 270606, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911019, 7, 0, -1, 'Fused Arcane Crystal', 'Artifact of immense arcane power',270611, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911020, 7, 0, -1, 'Spellfire Prism', 'Mythical arcane component from high level fusion', 270600, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911021, 7, 0, -1, 'Fused Shadow Crystal', 'Artifact radiating dark energy', 270621, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911022, 7, 0, -1, 'Eternal Shadow Crystal', 'Mythical shadow component from high level fusion',270609, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911023, 7, 0, -1, 'Fused Earth Shard','Artifact emitting dangerously poisonous vapors',270614, 3, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
REPLACE INTO `item_template` (`entry`, `class`, `subclass`, `SoundOverrideSubclass`, `name`, `Description`, `displayid`, `Quality`, `Flags`, `FlagsExtra`, `BuyCount`, `BuyPrice`, `SellPrice`, `InventoryType`, `AllowableClass`, `AllowableRace`, `ItemLevel`, `RequiredLevel`, `RequiredSkill`, `RequiredSkillRank`, `requiredspell`, `requiredhonorrank`, `RequiredCityRank`, `RequiredReputationFaction`, `RequiredReputationRank`, `maxcount`, `stackable`, `ContainerSlots`, `StatsCount`, `bonding`, `Material`, `VerifiedBuild`) VALUES (911024, 7, 0, -1, 'Verdant Stoneheart', 'Mythical earth component from high level fusion',270602, 4, 262144, 0, 1, 0, 0, 0, -1, -1, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 1, 0, 12340);
-- Flavor Text
DELETE FROM `item_template` WHERE (`entry` = 2595);
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
(2595, 0, 5, -1, 'Jug of Badlands Bourbon', 7921, 1, 0, 0, 1, 50000, 500, 0, -1, -1, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11009, 0, -1, -1, 0, 59, 1000, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 'Mick''s Favorite Drink', 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, 12340);
-- Currency
DELETE FROM `item_template` WHERE (`entry` = 911050);
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
(911050, 10, 0, -1, 'Badge of the Void', 270626, 4, 2048, 0, 1, 0, 0, 0, -1, -1, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 500000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0);
DELETE FROM `item_template` WHERE (`entry` = 911051);
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
(911051, 10, 0, -1, 'Emblem of Undeath', 270628, 4, 2048, 0, 1, 0, 0, 0, -1, -1, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 500000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0);
DELETE FROM `item_template` WHERE (`entry` = 911052);
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
(911052, 10, 0, -1, 'Emblem of Chaos', 270623, 4, 2048, 0, 1, 0, 0, 0, -1, -1, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 500000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0);
DELETE FROM `item_template` WHERE (`entry` = 911053);
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
(911053, 10, 0, -1, 'Emblem Of Veil', 270632, 4, 2048, 0, 1, 0, 0, 0, -1, -1, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 500000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0);
DELETE FROM `item_template` WHERE (`entry` = 911054);
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
(911054, 10, 0, -1, 'Mythic Badge', 270629, 4, 2048, 0, 1, 0, 0, 0, -1, -1, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 500000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8192, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0);
-- Random loot where greens would drop.
DELETE FROM `item_template` WHERE (`entry` = 911100);
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
(911100, 15, 0, -1, 'Shadowy Remains', 270634, 2, 4, 0, 1, 50000000, 12, 0, 32767, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, '', 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, 12340);
DELETE FROM `item_template` WHERE (`entry` = 911101);
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
(911101, 15, 0, -1, 'Veil Fragments', 270635, 2, 0, 0, 1, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, -1, 0, -1, 1, 'valuable fragments of a veil stone.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0);
-- Loot Templates
DELETE FROM `item_loot_template` WHERE (`Entry` = 911100);
INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(911100, 33447, 0, 20, 0, 1, 0, 1, 3, 'Runic Healing Potion'),
(911100, 33448, 0, 20, 0, 1, 0, 1, 3, 'Runic Mana Potion'),
(911100, 910001, 0, 10, 0, 1, 0, 1, 2, 'Araxia Tokens'),
(911100, 911000, 0, 10, 0, 1, 0, 1, 3, 'Ancient Dice'),
(911100, 911003, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Ore'),
(911100, 911005, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Cloth'),
(911100, 911007, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Leather'),
(911100, 911009, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Compound'),
(911100, 911011, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Gem'),
(911100, 911013, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Essence'),
(911100, 911015, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Frostshard'),
(911100, 911017, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Infernostone'),
(911100, 911019, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Arcane Crystal'),
(911100, 911021, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Shadow Crystal'),
(911100, 911023, 0, 0.5, 0, 1, 0, 1, 1, 'Fused Earth Shard'),
(911100, 911101, 0, 35.5, 0, 1, 0, 1, 5, 'Veil Fragments');

View File

@@ -0,0 +1,15 @@
REPLACE INTO
spell_ranks (first_spell_id, spell_id, `rank`)
VALUES
(150000, 150000, 1), (150000, 150011, 2), -- Ore Fusion
(150001, 150001, 1), (150001, 150012, 2), -- Cloth Fusion
(150002, 150002, 1), (150002, 150013, 2), -- Leather Fusion
(150003, 150003, 1), (150003, 150014, 2), -- Alchemy Fusion
(150004, 150004, 1), (150004, 150015, 2), -- Gem Fusion
(150005, 150005, 1), (150005, 150016, 2), -- Essence Fusion
(150006, 150006, 1), (150006, 150017, 2), -- Cold Fusion
(150007, 150007, 1), (150007, 150018, 2), -- Flame Fusion
(150008, 150008, 1), (150008, 150019, 2), -- Arcane Fusion
(150009, 150009, 1), (150009, 150020, 2), -- Dark Fusion
(150010, 150010, 1), (150010, 150021, 2) -- Earth Fusion
;

View File

@@ -0,0 +1,201 @@
-- Mick Ashwild
REPLACE 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
(9500561, 0, 0, 0, 0, 0, 'Mick Ashwild', 'The Mug', NULL, 0, 85, 85, 2, 35, 1, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1.35, 2000, 2000, 1, 1, 1, 33024, 2048, 0, 0, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 0.7, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 12340);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500561);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500561, 0, 9500561, 1, 1, 12340);
DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 9500561);
INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES
(9500561, 1, 4090, 0, 0, 0);
-- Thorin Firehand
DELETE FROM `creature_template` WHERE (`entry` = 9500562);
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
(9500562, 0, 0, 0, 0, 0, 'Thorin Firehand', 'The Hammer', NULL, 0, 85, 85, 2, 35, 1, 0.85, 1.14286, 1, 1, 1, 1.1, 3, 0, 2, 1, 0, 2, 2.5, 1, 33024, 2048, 0, 0, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 3, 2, 10, 1, 0, 0, 1, 0, 0, 0, '', 0);
DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 9500562);
INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES
(9500562, 1, 11684, 2565, 0, 0);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500562);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500562, 0, 9500562, 1, 1, 12340);
-- Elowyn Threadbinder
DELETE FROM `creature_template` WHERE (`entry` = 9500563);
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
(9500563, 0, 0, 0, 0, 0, 'Elowyn Threadbinder', 'Mystic Artisan', NULL, 0, 85, 85, 0, 35, 1, 1, 1.14286, 1, 1, 30, 1, 3, 0, 1, 2000, 2000, 1, 1, 8, 33024, 2048, 0, 0, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 0);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500563);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500563, 0, 9500563, 1, 1, 12340);
-- Shivey
DELETE FROM `creature_template` WHERE (`entry` = 9500564);
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
(9500564, 0, 0, 0, 0, 0, 'Shivey', 'Professional Arson', NULL, 0, 85, 85, 2, 35, 1, 1, 1.14286, 1, 1, 1, 1, 3, 0, 1, 2000, 2500, 1, 1, 4, 33024, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 0);
DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 9500564);
INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES
(9500564, 1, 28648, 2200, 0, 0);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500564);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500564, 0, 9500564, 1, 1, 0);
-- Steve
DELETE FROM `creature_template` WHERE (`entry` = 9500565);
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
(9500565, 0, 0, 0, 0, 0, 'Steve', 'The Indestructible', NULL, 0, 85, 85, 2, 35, 1, 1, 1.14286, 1, 1, 1, 1.25, 3, 0, 100, 2000, 2500, 1, 1, 1, 33024, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 100, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 0);
DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 9500565);
INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES
(9500565, 1, 51869, 38462, 0, 0);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500565);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500565, 0, 9500565, 1.25, 1, 0);
-- Vaeric
DELETE FROM `creature_template` WHERE (`entry` = 9500566);
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
(9500566, 0, 0, 0, 0, 0, 'Vaeric Bloodbane', '', NULL, 0, 85, 85, 2, 35, 1, 1, 1.14286, 1, 1, 1, 1.25, 3, 0, 100, 2000, 2500, 1, 1, 1, 33024, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 100, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 0);
DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 9500566);
INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES
(9500566, 1, 38632, 0, 0, 0);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500566);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500566, 0, 9500566, 1.25, 1, 0);
-- Agatha
DELETE FROM `creature_template` WHERE (`entry` = 9500567);
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
(9500567, 0, 0, 0, 0, 0, 'Agatha Veil', 'The Wise', NULL, 0, 85, 85, 2, 35, 1, 1, 1.14286, 1, 1, 1, 1.25, 3, 0, 100, 2000, 2500, 1, 1, 1, 33024, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 100, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 0);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500567);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500567, 0, 9500567, 1.25, 1, 0);
-- Sylvia
DELETE FROM `creature_template` WHERE (`entry` = 9500568);
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
(9500568, 0, 0, 0, 0, 0, 'Sylvia Steelheart', 'Battle Maiden', NULL, 0, 85, 85, 2, 35, 1, 1, 1.14286, 1, 1, 1, 1.25, 3, 0, 100, 2000, 2500, 1, 1, 1, 33024, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 100, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 0);
DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 9500568);
INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES
(9500568, 1, 38200, 16887, 0, 0);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500568);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500568, 0, 9500568, 1.25, 1, 0);
-- Model Info Updates
REPLACE INTO creature_model_info (DisplayID, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender)
VALUES (9500561, 0.35, 1.25, 0, 0);
REPLACE INTO creature_model_info (DisplayID, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender)
SELECT 9500562, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender
FROM creature_model_info
WHERE DisplayID = 9500561;
REPLACE INTO creature_model_info (DisplayID, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender)
SELECT 9500563, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender
FROM creature_model_info
WHERE DisplayID = 9500561;
REPLACE INTO creature_model_info (DisplayID, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender)
SELECT 9500564, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender
FROM creature_model_info
WHERE DisplayID = 9500561;
REPLACE INTO creature_model_info (DisplayID, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender)
VALUES (9500565, 0.35, 1.25, 0, 0);
REPLACE INTO creature_model_info (DisplayID, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender)
VALUES (9500566, 0.35, 1.25, 0, 0);
REPLACE INTO creature_model_info (DisplayID, BoundingRadius, CombatReach, Gender, DisplayID_Other_Gender)
VALUES (9500567, 0.35, 1.25, 1, 0);
-- Supporting Cast Spawns
-- Agatha
DELETE FROM `creature` WHERE (`id1` = 9500567);
INSERT INTO `creature` (`guid`, `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
(9001011, 9500567, 0, 0, 530, 0, 0, 1, 1, 0, -1990.6, 5214.14, -44.0752, 0.978763, 300, 0, 0, 1333900, 0, 0, 0, 0, 0, '', NULL, 0, NULL),
(9001014, 9500567, 0, 0, 571, 0, 0, 1, 1, 0, 5804.06, 639.865, 609.886, 5.98164, 300, 0, 0, 1333900, 0, 0, 0, 0, 0, '', NULL, 0, NULL);
-- Vaeric
DELETE FROM `creature` WHERE (`id1` = 9500566);
INSERT INTO `creature` (`guid`, `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
(9001013, 9500566, 0, 0, 530, 0, 0, 1, 1, 1, -1989.96, 5225.28, -44.6008, 5.71627, 300, 0, 0, 1333900, 0, 0, 0, 0, 0, '', NULL, 0, NULL),
(9001015, 9500566, 0, 0, 571, 0, 0, 1, 1, 1, 5826.64, 674.772, 609.885, 5.53385, 300, 0, 0, 1333900, 0, 0, 0, 0, 0, '', NULL, 0, NULL);
-- Slyvia
DELETE FROM `creature` WHERE (`id1` = 9500568);
INSERT INTO `creature` (`guid`, `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
(9001010, 9500568, 0, 0, 530, 0, 0, 1, 1, 1, -1994.38, 5219.83, -44.2111, 0.597826, 300, 0, 0, 1333900, 0, 0, 0, 0, 0, '', NULL, 0, NULL),
(9001016, 9500568, 0, 0, 571, 0, 0, 1, 1, 1, 5831.89, 678.204, 609.885, 5.0846, 300, 0, 0, 1333900, 0, 0, 0, 0, 0, '', NULL, 0, NULL);
-- Gossip Texts
-- Vaeric Starter Intro
DELETE FROM `npc_text` WHERE (`ID` = 60566);
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
(60566, 'The Lich King is dead... but his shadow endures.
You led the final blow against Arthas.
You have strength but can grow stronger yet still.
Fragments of his power linger... You must stop KelThuzad.
$n, Return to the battles you thought were finished.
Face the darkness reborn. And return those once dead back
to dust. While we search for a way to end this.
How can I aid you?', '', 0, 0, 0, 1, 1, 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);
-- Agatha Starter Intro
DELETE FROM `npc_text` WHERE (`ID` = 60567);
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
(60567, 'Kel\\Thuzad continues to tear through my domain.
He must be erased from existence.
I offer my knowledge —
ancient powers... forbidden relics...
to strengthen your kind against the unyielding shadows now pouring from my realm into yours.
Be quick, what do you need?', 'Kel\\Thuzad continues to tear through my domain.
He must be erased from existence.
I offer my knowledge —
ancient powers... forbidden relics...
to strengthen your kind against the unyielding shadows now pouring from my realm into yours.
Be quick, what do you need?', 0, 0, 0, 1, 1, 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);
DELETE FROM `npc_text` WHERE (`ID` = 60568);
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
(60568, 'You have bothered my Spirit Healer Goddess enough.
Besides, Vaeric trusts based on your deeds and I trust Vaeric.
I learned enough from Agatha to keep that face of yours upright — ancient powers... blah blah...
Just bring me some dices and fused materials and we can go from there.
', 'You have bothered my Spirit Healer Goddess enough.
Besides, Vaeric trusts based on your deeds and I trust Vaeric.
I learned enough from Agatha to keep that face of yours upright — ancient powers... blah blah...
Just bring me some dices and fused materials and we can go from there.
', 0, 0, 0, 1, 1, 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);

View File

@@ -0,0 +1,6 @@
UPDATE creature_template_npcbot_wander_nodes
SET maxlevel = 85
WHERE maxlevel = 80;
UPDATE battleground_template SET MaxLvl = 85 where MaxLvl = 80;

View File

@@ -0,0 +1,11 @@
-- Supporting Cast Environment items
REPLACE INTO acore_world.gameobject (guid, id, map, zoneId, areaId, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, ScriptName, VerifiedBuild, Comment) VALUES (8001043, 185002, 530, 0, 0, 1, 1, -1992.59, 5211.21, -44.239, 0.985043, -0, -0, -0.472849, -0.881143, 300, 0, 1, '', null, null);
REPLACE INTO acore_world.gameobject (guid, id, map, zoneId, areaId, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, ScriptName, VerifiedBuild, Comment) VALUES (8001046, 190213, 530, 0, 0, 1, 1, -1999.01, 5226.06, -44.2926, 5.86235, -0, -0, -0.20887, 0.977943, 300, 0, 1, '', null, null);
REPLACE INTO acore_world.gameobject (guid, id, map, zoneId, areaId, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, ScriptName, VerifiedBuild, Comment) VALUES (8001047, 182934, 530, 0, 0, 1, 1, -1992.11, 5207.81, -44.7864, 0.95047, -0, -0, -0.457548, -0.889185, 300, 0, 1, '', null, null);
REPLACE INTO acore_world.gameobject (guid, id, map, zoneId, areaId, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, ScriptName, VerifiedBuild, Comment) VALUES (8001050, 192935, 530, 0, 0, 1, 1, -1991.3, 5213.01, -44.0442, 1.02353, -0, -0, -0.489717, -0.871881, 300, 0, 1, '', null, null);
REPLACE INTO acore_world.gameobject (guid, id, map, zoneId, areaId, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, ScriptName, VerifiedBuild, Comment) VALUES (8001051, 194581, 530, 0, 0, 1, 1, -1993.03, 5220.23, -44.2068, 3.67347, -0, -0, -0.964847, 0.262813, 300, 0, 1, '', null, null);
REPLACE INTO acore_world.gameobject (guid, id, map, zoneId, areaId, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, ScriptName, VerifiedBuild, Comment) VALUES (8001052, 182483, 530, 0, 0, 1, 1, -1994.8, 5219.62, -44.2093, 0.71644, -0, -0, -0.350608, -0.936523, 300, 0, 1, '', null, null);
REPLACE INTO acore_world.gameobject (guid, id, map, zoneId, areaId, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, ScriptName, VerifiedBuild, Comment) VALUES (8001055, 179846, 530, 0, 0, 1, 1, -1986.62, 5222.6, -44.6557, 3.55485, -0, -0, -0.978728, 0.205163, 300, 0, 1, '', null, null);
REPLACE INTO acore_world.gameobject (guid, id, map, zoneId, areaId, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, ScriptName, VerifiedBuild, Comment) VALUES (8001057, 192935, 571, 0, 0, 1, 1, 5804.06, 639.865, 609.886, 5.84656, -0, -0, -0.216585, 0.976264, 300, 0, 1, '', null, null);
REPLACE INTO acore_world.gameobject (guid, id, map, zoneId, areaId, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, ScriptName, VerifiedBuild, Comment) VALUES (8001059, 187082, 571, 0, 0, 1, 1, 5829.63, 674.817, 609.886, 5.36498, -0, -0, -0.443142, 0.896452, 300, 0, 1, '', null, null);

View File

@@ -0,0 +1,172 @@
-- This rebalances lower level iLevel gear
UPDATE item_template
SET
stat_value1 = CASE
WHEN stat_type1 IN (38, 45) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value1 * 0.75)
WHEN stat_type1 IN (38, 45) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value1 * 0.80)
WHEN stat_type1 IN (38, 45) AND ItemLevel > 315 AND ItemLevel <= 325 THEN FLOOR(stat_value1 * 0.90)
ELSE stat_value1
END,
stat_value2 = CASE
WHEN stat_type2 IN (38, 45) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value2 * 0.75)
WHEN stat_type2 IN (38, 45) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value2 * 0.80)
WHEN stat_type2 IN (38, 45) AND ItemLevel > 315 AND ItemLevel <= 325 THEN FLOOR(stat_value2 * 0.90)
ELSE stat_value2
END,
stat_value3 = CASE
WHEN stat_type3 IN (38, 45) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value3 * 0.75)
WHEN stat_type3 IN (38, 45) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value3 * 0.80)
WHEN stat_type3 IN (38, 45) AND ItemLevel > 315 AND ItemLevel <= 325 THEN FLOOR(stat_value3 * 0.90)
ELSE stat_value3
END,
stat_value4 = CASE
WHEN stat_type4 IN (38, 45) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value4 * 0.75)
WHEN stat_type4 IN (38, 45) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value4 * 0.80)
WHEN stat_type4 IN (38, 45) AND ItemLevel > 315 AND ItemLevel <= 325 THEN FLOOR(stat_value4 * 0.90)
ELSE stat_value4
END,
stat_value5 = CASE
WHEN stat_type5 IN (38, 45) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value5 * 0.75)
WHEN stat_type5 IN (38, 45) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value5 * 0.80)
WHEN stat_type5 IN (38, 45) AND ItemLevel > 315 AND ItemLevel <= 325 THEN FLOOR(stat_value5 * 0.90)
ELSE stat_value5
END,
stat_value6 = CASE
WHEN stat_type6 IN (38, 45) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value6 * 0.75)
WHEN stat_type6 IN (38, 45) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value6 * 0.80)
WHEN stat_type6 IN (38, 45) AND ItemLevel > 315 AND ItemLevel <= 325 THEN FLOOR(stat_value6 * 0.90)
ELSE stat_value6
END,
stat_value7 = CASE
WHEN stat_type7 IN (38, 45) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value7 * 0.75)
WHEN stat_type7 IN (38, 45) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value7 * 0.80)
WHEN stat_type7 IN (38, 45) AND ItemLevel > 315 AND ItemLevel <= 325 THEN FLOOR(stat_value7 * 0.90) ELSE stat_value7
END,
stat_value8 = CASE
WHEN stat_type8 IN (38, 45) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value8 * 0.75)
WHEN stat_type8 IN (38, 45) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value8 * 0.80)
WHEN stat_type8 IN (38, 45) AND ItemLevel > 315 AND ItemLevel <= 325 THEN FLOOR(stat_value8 * 0.90)
ELSE stat_value8
END
WHERE
entry BETWEEN 20000000 and 21000000;
-- Rebalance primary strength, agi, intellect down for lower ilvl items
UPDATE item_template
SET
stat_value1 = CASE
WHEN stat_type1 IN (3,4,5) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value1 * 0.85)
WHEN stat_type1 IN (3,4,5) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value1 * 0.90)
ELSE stat_value1
END,
stat_value2 = CASE
WHEN stat_type2 IN (3,4,5) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value2 * 0.85)
WHEN stat_type2 IN (3,4,5) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value2 * 0.90)
ELSE stat_value2
END,
stat_value3 = CASE
WHEN stat_type3 IN (3,4,5) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value3 * 0.85)
WHEN stat_type3 IN (3,4,5) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value3 * 0.90)
ELSE stat_value3
END,
stat_value4 = CASE
WHEN stat_type4 IN (3,4,5) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value4 * 0.85)
WHEN stat_type4 IN (3,4,5) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value4 * 0.90)
ELSE stat_value4
END,
stat_value5 = CASE
WHEN stat_type5 IN (3,4,5) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value5 * 0.85)
WHEN stat_type5 IN (3,4,5) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value5 * 0.90)
ELSE stat_value5
END,
stat_value6 = CASE
WHEN stat_type6 IN (3,4,5) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value6 * 0.85)
WHEN stat_type6 IN (3,4,5) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value6 * 0.90)
ELSE stat_value6
END,
stat_value7 = CASE
WHEN stat_type7 IN (3,4,5) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value7 * 0.85)
WHEN stat_type7 IN (3,4,5) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value7 * 0.90)
ELSE stat_value7
END,
stat_value8 = CASE
WHEN stat_type8 IN (3,4,5) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value8 * 0.85)
WHEN stat_type8 IN (3,4,5) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value8 * 0.90)
ELSE stat_value8
END
WHERE
entry BETWEEN 20000000 and 21000000;
-- Nerf hit / spell hit crit rating and others items 300-315 by 15% and 10%
UPDATE item_template
SET
stat_value1 = CASE
WHEN (stat_type1 BETWEEN 16 AND 37 OR stat_type1 = 44) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value1 * 0.85)
WHEN (stat_type1 BETWEEN 16 AND 37 OR stat_type1 = 44) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value1 * 0.90)
ELSE stat_value1
END,
stat_value2 = CASE
WHEN (stat_type2 BETWEEN 16 AND 37 OR stat_type2 = 44) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value2 * 0.85)
WHEN (stat_type2 BETWEEN 16 AND 37 OR stat_type2 = 44) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value2 * 0.90)
ELSE stat_value2
END,
stat_value3 = CASE
WHEN (stat_type3 BETWEEN 16 AND 37 OR stat_type3 = 44) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value3 * 0.85)
WHEN (stat_type3 BETWEEN 16 AND 37 OR stat_type3 = 44) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value3 * 0.90)
ELSE stat_value3
END,
stat_value4 = CASE
WHEN (stat_type4 BETWEEN 16 AND 37 OR stat_type4 = 44) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value4 * 0.85)
WHEN (stat_type4 BETWEEN 16 AND 37 OR stat_type4 = 44) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value4 * 0.90)
ELSE stat_value4
END,
stat_value5 = CASE
WHEN (stat_type5 BETWEEN 16 AND 37 OR stat_type5 = 44) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value5 * 0.85)
WHEN (stat_type5 BETWEEN 16 AND 37 OR stat_type5 = 44) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value5 * 0.90)
ELSE stat_value5
END,
stat_value6 = CASE
WHEN (stat_type6 BETWEEN 16 AND 37 OR stat_type6 = 44) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value6 * 0.85)
WHEN (stat_type6 BETWEEN 16 AND 37 OR stat_type6 = 44) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value6 * 0.90)
ELSE stat_value6
END,
stat_value7 = CASE
WHEN (stat_type7 BETWEEN 16 AND 37 OR stat_type7 = 44) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value7 * 0.85)
WHEN (stat_type7 BETWEEN 16 AND 37 OR stat_type7 = 44) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value7 * 0.90)
ELSE stat_value7
END,
stat_value8 = CASE
WHEN (stat_type8 BETWEEN 16 AND 37 OR stat_type8 = 44) AND ItemLevel BETWEEN 300 AND 305 THEN FLOOR(stat_value8 * 0.85)
WHEN (stat_type8 BETWEEN 16 AND 37 OR stat_type8 = 44) AND ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(stat_value8 * 0.90)
ELSE stat_value8
END
WHERE
entry BETWEEN 20000000 and 21000000;
-- reduce damage on lower level items
UPDATE item_template
SET
dmg_min1 = CASE
WHEN ItemLevel BETWEEN 300 AND 305 THEN FLOOR(dmg_min1 * 0.85)
WHEN ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(dmg_min1 * 0.90)
ELSE dmg_min1
END,
dmg_max1 = CASE
WHEN ItemLevel BETWEEN 300 AND 305 THEN FLOOR(dmg_max1 * 0.85)
WHEN ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(dmg_max1 * 0.90)
ELSE dmg_max1
END,
dmg_min2 = CASE
WHEN ItemLevel BETWEEN 300 AND 305 THEN FLOOR(dmg_min2 * 0.85)
WHEN ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(dmg_min2 * 0.90)
ELSE dmg_min2
END,
dmg_max2 = CASE
WHEN ItemLevel BETWEEN 300 AND 305 THEN FLOOR(dmg_max2 * 0.85)
WHEN ItemLevel > 305 AND ItemLevel <= 315 THEN FLOOR(dmg_max2 * 0.90)
ELSE dmg_max2
END
WHERE
entry BETWEEN 20000000 and 21000000;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
-- Tier 1 and 2 Vendors
DELETE FROM `creature_template` WHERE (`entry` = 9500800);
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
(9500800, 0, 0, 0, 0, 0, 'Champion Miluria', 'Mythic I Weapons and Gear', '', 0, 80, 80, 2, 2027, 128, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1, 2000, 2000, 1, 1, 8, 768, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 10314);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500800);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500800, 0, 29832, 1, 1, 10314);
DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 9500800);
INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES
(9500800, 1, 29405, 6618, 0, 18019);
DELETE FROM `creature_template` WHERE (`entry` = 9500801);
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
(9500801, 0, 0, 0, 0, 0, 'Paldesse', 'Mythic I Cloth Armor', '', 0, 80, 80, 0, 2007, 4224, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1, 2000, 2000, 1, 1, 8, 512, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 12340);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500801);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500801, 0, 25594, 1, 1, 12340);
DELETE FROM `creature_template` WHERE (`entry` = 9500802);
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
(9500802, 0, 0, 0, 0, 0, 'Griselda Hunderland', 'Mythic I Plate Armor', '', 0, 80, 80, 0, 2007, 4224, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1, 2000, 2000, 1, 1, 1, 512, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'SmartAI', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 12340);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500802);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500802, 0, 25881, 1, 1, 12340);
DELETE FROM `creature_template` WHERE (`entry` = 9500803);
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
(9500803, 0, 0, 0, 0, 0, 'Valerie Langrom', 'Mythic I Leather Armor', '', 0, 80, 80, 2, 2007, 4224, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1, 2000, 2000, 1, 1, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 12340);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500803);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500803, 0, 25878, 1, 1, 12340);
DELETE FROM `creature_template` WHERE (`entry` = 9500804);
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
(9500804, 0, 0, 0, 0, 0, 'Bragund Brightlink', 'Mythic I Mail Armor', '', 0, 80, 80, 2, 2007, 4224, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1, 2000, 2000, 1, 1, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'SmartAI', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 12340);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500804);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500804, 0, 26321, 1, 1, 12340);
-- Tiers 3 and 4
DELETE FROM `creature_template` WHERE (`entry` = 9500805);
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
(9500805, 0, 0, 0, 0, 0, 'Captain Dirgehammer', 'Mythic II Weapons and Gear ', NULL, 0, 65, 65, 1, 1078, 4224, 1, 1.14286, 1, 1, 18, 1, 0, 0, 1, 2000, 2000, 1, 1, 1, 4864, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 2, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 12340);
DELETE FROM `creature_template_model` WHERE (`CreatureID` = 9500805);
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`, `VerifiedBuild`) VALUES
(9500805, 0, 12917, 1, 1, 12340);
-- Tier 5
-- Spawns
REPLACE INTO acore_world.creature (guid, 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 (9001025, 9500800, 0, 0, 571, 0, 0, 1, 1, 1, 5738.66, 741.002, 641.74, 4.1062, 300, 0, 0, 10080, 8814, 0, 0, 0, 0, '', null, 0, null);
REPLACE INTO acore_world.creature (guid, 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 (9001026, 9500801, 0, 0, 571, 0, 0, 1, 1, 0, 5736.61, 742.711, 641.75, 4.04965, 300, 0, 0, 3739, 8814, 0, 0, 0, 0, '', null, 0, null);
REPLACE INTO acore_world.creature (guid, 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 (9001027, 9500802, 0, 0, 571, 0, 0, 1, 1, 0, 5732.59, 746.182, 641.762, 4.01431, 300, 0, 0, 5342, 0, 0, 0, 0, 0, '', null, 0, null);
REPLACE INTO acore_world.creature (guid, 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 (9001028, 9500803, 0, 0, 571, 0, 0, 1, 1, 0, 5730.76, 747.711, 641.761, 4.16746, 300, 0, 0, 12600, 0, 0, 0, 0, 0, '', null, 0, null);
REPLACE INTO acore_world.creature (guid, 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 (9001029, 9500804, 0, 0, 571, 0, 0, 1, 1, 0, 5725.58, 750.971, 641.768, 4.48476, 300, 0, 0, 12600, 0, 0, 0, 0, 0, '', null, 0, null);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,253 @@
-- SQL Script to Insert 50 Ranks for Each Stat
INSERT INTO mp_stat_upgrade_ranks (upgradeRank, statTypeId, materialId1, materialCost, materialId2, materialCost2, materialId3, materialCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES
(1, 1, 1001, 100, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 1, 1001, 150, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 1, 1001, 200, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 1, 1001, 250, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 1, 1001, 300, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 1, 1001, 350, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 1, 1001, 400, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 1, 1001, 450, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 1, 1001, 500, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 1, 1001, 550, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 1, 1001, 600, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 1, 1001, 650, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 1, 1001, 700, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 1, 1001, 750, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 1, 1001, 800, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 1, 1001, 850, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 1, 1001, 900, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 1, 1001, 950, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 1, 1001, 1000, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 1, 1001, 1050, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 1, 1001, 1100, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 1, 1001, 1150, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 1, 1001, 1200, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 1, 1001, 1250, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 1, 1001, 1300, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 1, 1001, 1350, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 1, 1001, 1400, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 1, 1001, 1450, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 1, 1001, 1500, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 1, 1001, 1550, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 1, 1001, 1600, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 1, 1001, 1650, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 1, 1001, 1700, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 1, 1001, 1750, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 1, 1001, 1800, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 1, 1001, 1850, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 1, 1001, 1900, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 1, 1001, 1950, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 1, 1001, 2000, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 1, 1001, 2050, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 1, 1001, 2100, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 1, 1001, 2150, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 1, 1001, 2200, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 1, 1001, 2250, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 1, 1001, 2300, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 1, 1001, 2350, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 1, 1001, 2400, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 1, 1001, 2450, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 1, 1001, 2500, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 1, 1001, 2550, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 167, 197, 222),
(1, 2, 1001, 100, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 2, 1001, 150, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 2, 1001, 200, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 2, 1001, 250, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 2, 1001, 300, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 2, 1001, 350, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 2, 1001, 400, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 2, 1001, 450, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 2, 1001, 500, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 2, 1001, 550, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 2, 1001, 600, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 2, 1001, 650, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 2, 1001, 700, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 2, 1001, 750, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 2, 1001, 800, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 2, 1001, 850, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 2, 1001, 900, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 2, 1001, 950, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 2, 1001, 1000, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 2, 1001, 1050, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 2, 1001, 1100, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 2, 1001, 1150, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 2, 1001, 1200, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 2, 1001, 1250, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 2, 1001, 1300, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 2, 1001, 1350, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 2, 1001, 1400, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 2, 1001, 1450, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 2, 1001, 1500, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 2, 1001, 1550, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 2, 1001, 1600, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 2, 1001, 1650, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 2, 1001, 1700, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 2, 1001, 1750, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 2, 1001, 1800, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 2, 1001, 1850, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 2, 1001, 1900, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 2, 1001, 1950, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 2, 1001, 2000, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 2, 1001, 2050, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 2, 1001, 2100, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 2, 1001, 2150, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 2, 1001, 2200, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 2, 1001, 2250, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 2, 1001, 2300, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 2, 1001, 2350, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 2, 1001, 2400, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 2, 1001, 2450, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 2, 1001, 2500, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 2, 1001, 2550, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 167, 197, 222),
(1, 3, 1001, 100, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 3, 1001, 150, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 3, 1001, 200, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 3, 1001, 250, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 3, 1001, 300, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 3, 1001, 350, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 3, 1001, 400, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 3, 1001, 450, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 3, 1001, 500, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 3, 1001, 550, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 3, 1001, 600, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 3, 1001, 650, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 3, 1001, 700, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 3, 1001, 750, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 3, 1001, 800, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 3, 1001, 850, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 3, 1001, 900, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 3, 1001, 950, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 3, 1001, 1000, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 3, 1001, 1050, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 3, 1001, 1100, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 3, 1001, 1150, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 3, 1001, 1200, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 3, 1001, 1250, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 3, 1001, 1300, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 3, 1001, 1350, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 3, 1001, 1400, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 3, 1001, 1450, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 3, 1001, 1500, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 3, 1001, 1550, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 3, 1001, 1600, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 3, 1001, 1650, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 3, 1001, 1700, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 3, 1001, 1750, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 3, 1001, 1800, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 3, 1001, 1850, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 3, 1001, 1900, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 3, 1001, 1950, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 3, 1001, 2000, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 3, 1001, 2050, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 3, 1001, 2100, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 3, 1001, 2150, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 3, 1001, 2200, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 3, 1001, 2250, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 3, 1001, 2300, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 3, 1001, 2350, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 3, 1001, 2400, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 3, 1001, 2450, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 3, 1001, 2500, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 3, 1001, 2550, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 167, 197, 222),
(1, 4, 1001, 100, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 4, 1001, 150, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 4, 1001, 200, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 4, 1001, 250, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 4, 1001, 300, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 4, 1001, 350, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 4, 1001, 400, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 4, 1001, 450, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 4, 1001, 500, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 4, 1001, 550, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 4, 1001, 600, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 4, 1001, 650, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 4, 1001, 700, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 4, 1001, 750, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 4, 1001, 800, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 4, 1001, 850, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 4, 1001, 900, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 4, 1001, 950, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 4, 1001, 1000, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 4, 1001, 1050, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 4, 1001, 1100, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 4, 1001, 1150, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 4, 1001, 1200, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 4, 1001, 1250, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 4, 1001, 1300, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 4, 1001, 1350, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 4, 1001, 1400, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 4, 1001, 1450, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 4, 1001, 1500, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 4, 1001, 1550, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 4, 1001, 1600, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 4, 1001, 1650, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 4, 1001, 1700, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 4, 1001, 1750, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 4, 1001, 1800, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 4, 1001, 1850, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 4, 1001, 1900, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 4, 1001, 1950, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 4, 1001, 2000, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 4, 1001, 2050, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 4, 1001, 2100, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 4, 1001, 2150, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 4, 1001, 2200, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 4, 1001, 2250, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 4, 1001, 2300, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 4, 1001, 2350, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 4, 1001, 2400, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 4, 1001, 2450, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 4, 1001, 2500, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 4, 1001, 2550, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 167, 197, 222)
(1, 0, 1001, 100, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 0, 1001, 150, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 0, 1001, 200, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 0, 1001, 250, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 0, 1001, 300, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 0, 1001, 350, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 0, 1001, 400, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 0, 1001, 450, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 0, 1001, 500, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 0, 1001, 550, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 0, 1001, 600, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 0, 1001, 650, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 0, 1001, 700, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 0, 1001, 750, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 0, 1001, 800, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 0, 1001, 850, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 0, 1001, 900, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 0, 1001, 950, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 0, 1001, 1000, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 0, 1001, 1050, 0, 0, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 0, 1001, 1100, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 0, 1001, 1150, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 0, 1001, 1200, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 0, 1001, 1250, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 0, 1001, 1300, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 0, 1001, 1350, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 0, 1001, 1400, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 0, 1001, 1450, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 0, 1001, 1500, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 0, 1001, 1550, 0, 0, 0, 0, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 0, 1001, 1600, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 0, 1001, 1650, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 0, 1001, 1700, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 0, 1001, 1750, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 0, 1001, 1800, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 0, 1001, 1850, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 0, 1001, 1900, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 0, 1001, 1950, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 0, 1001, 2000, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 0, 1001, 2050, 0, 0, 0, 0, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 0, 1001, 2100, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 0, 1001, 2150, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 0, 1001, 2200, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 0, 1001, 2250, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 0, 1001, 2300, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 0, 1001, 2350, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 0, 1001, 2400, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 0, 1001, 2450, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 0, 1001, 2500, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 0, 1001, 2550, 0, 0, 0, 0, 9, 18, 13, 18, 24, 27, 167, 197, 222),
;

View File

@@ -0,0 +1,77 @@
package main
import (
"fmt"
"os"
)
// Stats enum
const (
STAT_STRENGTH = iota
STAT_AGILITY
STAT_STAMINA
STAT_INTELLECT
STAT_SPIRIT
)
func main() {
// Output file for the SQL script
outputFile, err := os.Create("generate_stat_upgrades.sql")
if err != nil {
fmt.Println("Error creating file:", err)
return
}
defer outputFile.Close()
// Stats names for clarity
stats := map[int]string{
STAT_STRENGTH: "STAT_STRENGTH",
STAT_AGILITY: "STAT_AGILITY",
STAT_STAMINA: "STAT_STAMINA",
STAT_INTELLECT: "STAT_INTELLECT",
STAT_SPIRIT: "STAT_SPIRIT",
}
// Start writing the SQL script
fmt.Fprintln(outputFile, "-- SQL Script to Insert 50 Ranks for Each Stat")
fmt.Fprintln(outputFile, "INSERT INTO mp_stat_upgrade_ranks (upgradeRank, statTypeId, materialId1, materialCost, materialId2, materialCost2, materialId3, materialCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES")
// Iterate over stats
for statID := range stats {
for rank := 1; rank <= 50; rank++ {
// Material cost increases by 50 per rank
materialCost := 100 + (rank-1)*50
// Stat growth
minIncrease1 := 1 + (rank-1)/10*2
maxIncrease1 := 10 + (rank-1)/10*2
minIncrease2 := (minIncrease1 + maxIncrease1) / 2
maxIncrease3Bonus := (rank-1)/10*2 + 1
maxIncrease3 := maxIncrease1 + maxIncrease3Bonus
minIncrease3 := maxIncrease3 - 3
// Dice costs
chanceCost1 := 20 + (rank-1)*3
chanceCost2 := 50 + (rank-1)*3
chanceCost3 := 75 + (rank-1)*3
// Write SQL insert statement for this rank
sql := fmt.Sprintf(
"(%d, %d, 1001, %d, 0, 0, 0, 0, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
rank, statID, materialCost,
minIncrease1, maxIncrease1, minIncrease2, maxIncrease1, minIncrease3, maxIncrease3,
chanceCost1, chanceCost2, chanceCost3,
)
// Add a comma for all but the last line
if !(statID == STAT_SPIRIT && rank == 50) {
sql += ","
}
fmt.Fprintln(outputFile, sql)
}
}
fmt.Fprintln(outputFile, ";")
fmt.Println("SQL script generated: generate_stat_upgrades.sql")
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,153 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"math"
"os"
)
type Creature struct {
CreatureEntry int `json:"creature_entry"`
Level int `json:"level"`
HP int `json:"hp"`
Mana int `json:"mana"`
Armor int `json:"armor"`
Str int `json:"str"`
Agi int `json:"agi"`
Sta int `json:"sta"`
Int int `json:"inte"`
Spi int `json:"spi"`
MinDmg int `json:"min_dmg"`
MaxDmg int `json:"max_dmg"`
}
// RegressionResult stores the slope and intercept of a linear regression
type RegressionResult struct {
Slope float64
Intercept float64
}
// LinearRegression performs a simple linear regression on the given data points
func LinearRegression(levels []float64, stats []float64) RegressionResult {
n := len(levels)
if n != len(stats) {
panic("levels and stats arrays must have the same length")
}
// Calculate averages
var sumX, sumY, sumXY, sumXX float64
for i := 0; i < n; i++ {
sumX += levels[i]
sumY += stats[i]
sumXY += levels[i] * stats[i]
sumXX += levels[i] * levels[i]
}
avgX := sumX / float64(n)
avgY := sumY / float64(n)
// Calculate slope and intercept
slope := (sumXY - float64(n)*avgX*avgY) / (sumXX - float64(n)*avgX*avgX)
intercept := avgY - slope*avgX
return RegressionResult{
Slope: slope,
Intercept: intercept,
}
}
// PredictStat returns the predicted stat value for a given level based on a linear regression model
func PredictStat(reg RegressionResult, level int) float64 {
return reg.Intercept + reg.Slope*float64(level)
}
// ScaleCreatures generates stats for levels 81 to 87 based on linear regression and outputs SQL statements
func ScaleCreatures(creatures []Creature) {
creatureMap := make(map[int][]Creature)
// Group creatures by their creature_entry
for _, creature := range creatures {
creatureMap[creature.CreatureEntry] = append(creatureMap[creature.CreatureEntry], creature)
}
// Process each creature entry independently
for creatureEntry, creatureList := range creatureMap {
var levels []float64
var hp, mana, armor, str, agi, sta, inte, spi, minDmg, maxDmg []float64
// Collect data for linear regression from levels 1 to 80
for _, creature := range creatureList {
if creature.Level <= 80 {
levels = append(levels, float64(creature.Level))
hp = append(hp, float64(creature.HP))
mana = append(mana, float64(creature.Mana))
armor = append(armor, float64(creature.Armor))
str = append(str, float64(creature.Str))
agi = append(agi, float64(creature.Agi))
sta = append(sta, float64(creature.Sta))
inte = append(inte, float64(creature.Int))
spi = append(spi, float64(creature.Spi))
minDmg = append(minDmg, float64(creature.MinDmg))
maxDmg = append(maxDmg, float64(creature.MaxDmg))
}
}
// Perform linear regression on each stat
hpReg := LinearRegression(levels, hp)
manaReg := LinearRegression(levels, mana)
armorReg := LinearRegression(levels, armor)
strReg := LinearRegression(levels, str)
agiReg := LinearRegression(levels, agi)
staReg := LinearRegression(levels, sta)
inteReg := LinearRegression(levels, inte)
spiReg := LinearRegression(levels, spi)
minDmgReg := LinearRegression(levels, minDmg)
maxDmgReg := LinearRegression(levels, maxDmg)
// Generate SQL insert statements for levels 81 to 87 for each creature_entry
for level := 81; level <= 87; level++ {
newCreature := Creature{
CreatureEntry: creatureEntry, // Process per creature_entry
Level: level,
HP: int(math.Round(math.Max(PredictStat(hpReg, level), 1))), // Round and ensure positive
Mana: int(math.Round(math.Max(PredictStat(manaReg, level), 1))),
Armor: int(math.Round(math.Max(PredictStat(armorReg, level), 1))), // Armor scaling
Str: int(math.Round(math.Max(PredictStat(strReg, level), 1))),
Agi: int(math.Round(math.Max(PredictStat(agiReg, level), 1))),
Sta: int(math.Round(math.Max(PredictStat(staReg, level), 1))),
Int: int(math.Round(math.Max(PredictStat(inteReg, level), 1))),
Spi: int(math.Round(math.Max(PredictStat(spiReg, level), 1))),
MinDmg: int(math.Round(math.Max(PredictStat(minDmgReg, level), 1))),
MaxDmg: int(math.Round(math.Max(PredictStat(maxDmgReg, level), 1))),
}
// Output SQL INSERT statement for each creature_entry and level
fmt.Printf("INSERT INTO pet_levelstats (creature_entry, level, hp, mana, armor, str, agi, sta, inte, spi, min_dmg, max_dmg) "+
"VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d);\n",
newCreature.CreatureEntry, newCreature.Level, newCreature.HP, newCreature.Mana, newCreature.Armor,
newCreature.Str, newCreature.Agi, newCreature.Sta, newCreature.Int, newCreature.Spi,
newCreature.MinDmg, newCreature.MaxDmg)
}
}
}
func main() {
// Read the JSON file
file, err := os.Open("creatures.json")
if err != nil {
fmt.Println("Error reading file:", err)
return
}
defer file.Close()
byteValue, _ := ioutil.ReadAll(file)
// Parse the JSON data
var creatures []Creature
json.Unmarshal(byteValue, &creatures)
// Scale creatures and generate SQL for levels 81 to 87
ScaleCreatures(creatures)
}

View File

@@ -0,0 +1,22 @@
module github.com/araxiaonline/mod-mythic-plus
go 1.22.4
require (
git.sr.ht/~sbinet/gg v0.5.0 // indirect
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect
github.com/campoy/embedmd v1.0.0 // indirect
github.com/go-fonts/liberation v0.3.2 // indirect
github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea // indirect
github.com/go-pdf/fpdf v0.9.0 // indirect
github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/image v0.14.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.15.0 // indirect
gonum.org/v1/gonum v0.15.0 // indirect
gonum.org/v1/plot v0.14.0 // indirect
)

View File

@@ -0,0 +1,59 @@
git.sr.ht/~sbinet/gg v0.5.0 h1:6V43j30HM623V329xA9Ntq+WJrMjDxRjuAB1LFWF5m8=
git.sr.ht/~sbinet/gg v0.5.0/go.mod h1:G2C0eRESqlKhS7ErsNey6HHrqU1PwsnCQlekFi9Q2Oo=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw=
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=
github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
github.com/go-fonts/liberation v0.3.2 h1:XuwG0vGHFBPRRI8Qwbi5tIvR3cku9LUfZGq/Ar16wlQ=
github.com/go-fonts/liberation v0.3.2/go.mod h1:N0QsDLVUQPy3UYg9XAc3Uh3UDMp2Z7M1o4+X98dXkmI=
github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea h1:DfZQkvEbdmOe+JK2TMtBM+0I9GSdzE2y/L1/AmD8xKc=
github.com/go-latex/latex v0.0.0-20231108140139-5c1ce85aa4ea/go.mod h1:Y7Vld91/HRbTBm7JwoI7HejdDB0u+e9AUBO9MB7yuZk=
github.com/go-pdf/fpdf v0.9.0 h1:PPvSaUuo1iMi9KkaAn90NuKi+P4gwMedWPHhj8YlJQw=
github.com/go-pdf/fpdf v0.9.0/go.mod h1:oO8N111TkmKb9D7VvWGLvLJlaZUQVPM+6V42pp3iV4Y=
github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198 h1:FSii2UQeSLngl3jFoR4tUKZLprO7qUlh/TKKticc0BM=
github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198/go.mod h1:DTh/Y2+NbnOVVoypCCQrovMPDKUGp4yZpSbWg5D0XIM=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ=
gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo=
gonum.org/v1/plot v0.14.0 h1:+LBDVFYwFe4LHhdP8coW6296MBEY4nQ+Y4vuUpJopcE=
gonum.org/v1/plot v0.14.0/go.mod h1:MLdR9424SJed+5VqC6MsouEpig9pZX2VZ57H9ko2bXU=
honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=

View File

@@ -0,0 +1,209 @@
package main
import (
"fmt"
"log"
"math"
"gonum.org/v1/gonum/mat"
)
// Data structure to hold the input data
type Data struct {
Level float64
Class int
BaseHP0 float64
BaseHP1 float64
BaseHP2 float64
BaseMana float64
BaseArmor float64
AttackPower float64
RangedAttackPower float64
DamageBase float64
DamageExp1 float64
DamageExp2 float64
Comment *string
}
func main() {
// Input data (levels 68 to 80 for each class)
data := []Data{
{68, 1, 3834, 6542, 6986, 0, 6126, 292, 41, 39.2381, 94.4934, 104.527, nil},
{68, 2, 3067, 5233, 6986, 2991, 6116, 276, 31, 36.3244, 87.2677, 104.527, nil},
{68, 4, 3834, 6542, 6986, 0, 5527, 292, 41, 39.2381, 94.4934, 104.527, nil},
{68, 8, 2684, 4580, 5588, 6882, 4928, 130, 27, 33.3048, 80.1061, 96.6868, nil},
{69, 1, 3942, 6761, 7984, 0, 6423, 298, 43, 39.9047, 99.5328, 114.153, nil},
{69, 2, 3153, 5409, 7984, 3080, 6412, 282, 32, 36.974, 91.8916, 114.153, nil},
{69, 4, 3942, 6761, 7984, 0, 5795, 298, 43, 39.9047, 99.5328, 114.153, nil},
{69, 8, 2759, 4733, 6387, 7031, 5167, 133, 28, 33.8695, 84.2722, 105.591, nil},
{70, 1, 4050, 6986, 8982, 0, 6719, 304, 44, 40.5714, 104.527, 123.779, nil},
{70, 2, 3240, 5589, 8982, 3155, 6708, 286, 33, 37.6361, 96.7364, 123.779, nil},
{70, 4, 4050, 6986, 8982, 0, 6062, 304, 44, 40.5714, 104.527, 123.779, nil},
{70, 8, 2835, 4890, 7185, 7196, 5404, 135, 28, 34.4369, 88.3402, 114.496, nil},
{71, 1, 4163, 7181, 9291, 0, 7018, 308, 48, 41.2381, 106.357, 127.382, nil},
{71, 2, 3330, 5744, 9291, 3231, 7007, 290, 37, 38.2899, 98.3977, 127.383, nil},
{71, 4, 4163, 7181, 9291, 0, 6332, 308, 48, 41.2381, 106.357, 127.382, nil},
{71, 8, 2914, 5027, 7432, 7332, 5645, 137, 31, 35.0025, 92.4034, 117.829, nil},
{72, 1, 4278, 7380, 9610, 0, 7318, 314, 53, 41.9047, 108.071, 131.091, nil},
{72, 2, 3422, 5903, 9610, 3309, 7305, 296, 40, 38.9492, 99.8571, 131.092, nil},
{72, 4, 4278, 7380, 9610, 0, 6602, 314, 53, 41.9047, 108.071, 131.091, nil},
{72, 8, 2995, 5166, 7688, 7500, 5886, 140, 34, 35.5693, 96.5068, 121.259, nil},
{73, 1, 4399, 7588, 9940, 0, 7618, 320, 58, 42.5714, 118.643, 134.908, nil},
{73, 2, 3519, 6070, 9940, 3387, 7604, 302, 44, 39.6048, 101.451, 134.908, nil},
{73, 4, 4399, 7580, 9940, 0, 6872, 320, 58, 42.5714, 118.643, 134.908, nil},
{73, 8, 3098, 5311, 7952, 7654, 6126, 143, 37, 36.1353, 100.617, 124.79, nil},
{74, 1, 4524, 7804, 10282, 0, 7918, 354, 63, 43.2381, 120.434, 138.836, nil},
{74, 2, 3619, 6243, 10282, 3466, 7903, 334, 48, 40.2629, 102.955, 138.836, nil},
{74, 4, 4524, 1, 10282, 0, 7143, 354, 63, 43.2381, 120.434, 138.836, nil},
{74, 8, 3186, 1, 8225, 7809, 6368, 158, 41, 36.7018, 104.723, 128.423, nil},
{75, 1, 4652, 8025, 10635, 0, 8219, 392, 68, 43.9047, 122.226, 142.878, nil},
{75, 2, 3722, 6420, 10635, 3561, 8204, 370, 53, 40.9193, 104.52, 142.878, nil},
{75, 4, 4652, 1, 10635, 0, 7415, 392, 68, 43.9047, 122.226, 142.878, nil},
{75, 8, 3256, 5617, 8508, 7981, 6610, 175, 45, 37.268, 108.832, 132.162, nil},
{76, 1, 4781, 8247, 11001, 0, 8520, 432, 74, 44.5713, 124.018, 147.038, nil},
{76, 2, 3825, 6602, 11001, 3643, 8503, 408, 57, 41.5757, 106.085, 147.038, nil},
{76, 4, 4781, 1, 11001, 0, 7686, 432, 74, 44.5713, 124.018, 147.038, nil},
{76, 8, 3367, 1, 8800, 8139, 6851, 193, 49, 37.8342, 112.941, 136.01, nil},
{77, 1, 4916, 8480, 11379, 0, 8822, 478, 81, 45.2379, 125.81, 151.319, nil},
{77, 2, 3933, 6784, 11379, 3725, 8803, 452, 62, 42.2321, 107.65, 151.319, nil},
{77, 4, 4916, 1, 11379, 0, 7958, 478, 81, 45.2379, 125.81, 151.319, nil},
{77, 8, 3462, 1, 9103, 8313, 7094, 214, 54, 38.4004, 117.05, 139.97, nil},
{78, 1, 5052, 8715, 11770, 0, 9124, 528, 88, 45.9045, 127.602, 155.724, nil},
{78, 2, 4042, 6972, 11770, 3809, 9104, 500, 68, 42.8885, 109.215, 155.724, nil},
{78, 4, 5052, 1, 11770, 0, 8230, 528, 88, 45.9045, 127.602, 155.724, nil},
{78, 8, 3558, 1, 9416, 8459, 7335, 236, 58, 38.9666, 121.159, 144.045, nil},
{79, 1, 5194, 8960, 12175, 0, 9426, 582, 95, 46.5711, 129.394, 160.258, nil},
{79, 2, 4155, 7167, 12175, 3893, 9405, 550, 74, 43.5449, 110.78, 160.258, nil},
{79, 4, 5194, 1, 12175, 0, 8503, 582, 95, 46.5711, 129.394, 160.258, nil},
{79, 8, 3658, 1, 9740, 8636, 7579, 260, 64, 39.5328, 125.268, 148.239, nil},
{80, 1, 5342, 9215, 12600, 0, 9729, 642, 103, 47.2377, 131.186, 164.924, nil},
{80, 2, 4274, 7373, 12600, 3994, 9706, 608, 80, 44.2013, 112.345, 164.924, nil},
{80, 4, 5342, 1, 12600, 0, 8776, 642, 103, 47.2377, 131.186, 164.924, nil},
{80, 8, 3739, 1, 10080, 8814, 7822, 287, 69, 40.099, 129.377, 152.555, nil},
}
// Classes to process
classes := []int{1, 2, 4, 8}
// Columns to process
columns := []string{"BaseHP0", "BaseHP1", "BaseHP2", "BaseMana", "BaseArmor", "AttackPower", "RangedAttackPower", "DamageBase", "DamageExp1", "DamageExp2"}
// Fit polynomials for each class and each attribute
classCoefficients := make(map[int]map[string][]float64)
for _, class := range classes {
classData := filterDataByClass(data, class)
// Store coefficients for each column for this class
coefficients := make(map[string][]float64)
for _, column := range columns {
levels := make([]float64, 0)
values := make([]float64, 0)
for _, d := range classData {
var value float64
switch column {
case "BaseHP0":
value = d.BaseHP0
case "BaseHP1":
value = d.BaseHP1
case "BaseHP2":
value = d.BaseHP2
case "BaseMana":
value = d.BaseMana
case "BaseArmor":
value = d.BaseArmor
case "AttackPower":
value = d.AttackPower
case "RangedAttackPower":
value = d.RangedAttackPower
case "DamageBase":
value = d.DamageBase
case "DamageExp1":
value = d.DamageExp1
case "DamageExp2":
value = d.DamageExp2
}
if value > 1 {
levels = append(levels, d.Level)
values = append(values, value)
}
}
if len(levels) == 0 || len(values) == 0 {
continue // skip if no valid data
}
// Perform polynomial regression (degree 2)
coeffs, err := polyFit(levels, values, 2)
if err != nil {
log.Fatalf("Failed to calculate polynomial fit for class %d, %s: %v", class, column, err)
}
coefficients[column] = coeffs
}
classCoefficients[class] = coefficients
}
// Generate SQL insert statements for levels 81 to 100
fmt.Println("INSERT INTO mythicplus_classlevelstats (class, level, basehp0, basehp1, basehp2, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2) VALUES")
for _, class := range classes {
for level := 81.0; level <= 100; level++ {
predictedValues := calculateScaledValues(level, classCoefficients[class])
fmt.Printf("(%d, %.0f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.4f, %.4f, %.4f),\n",
class, level,
predictedValues["BaseHP0"], predictedValues["BaseHP1"], predictedValues["BaseHP2"], predictedValues["BaseMana"],
predictedValues["BaseArmor"], predictedValues["AttackPower"], predictedValues["RangedAttackPower"],
predictedValues["DamageBase"], predictedValues["DamageExp1"], predictedValues["DamageExp2"])
}
}
}
// filterDataByClass filters the dataset by class
func filterDataByClass(data []Data, class int) []Data {
var filtered []Data
for _, d := range data {
if d.Class == class {
filtered = append(filtered, d)
}
}
return filtered
}
// polyFit performs a polynomial fit of the given degree on the data.
func polyFit(x, y []float64, degree int) ([]float64, error) {
// Create the Vandermonde matrix
n := len(x)
vander := mat.NewDense(n, degree+1, nil)
for i := range x {
for j := 0; j <= degree; j++ {
vander.Set(i, j, math.Pow(x[i], float64(j)))
}
}
// Create a vector for the output values
yVec := mat.NewVecDense(len(y), y)
// Solve the least squares problem
var coeffs mat.VecDense
err := coeffs.SolveVec(vander, yVec)
if err != nil {
return nil, err
}
return coeffs.RawVector().Data, nil
}
// calculateScaledValues takes a level and coefficient map to return scaled values
func calculateScaledValues(level float64, coeffs map[string][]float64) map[string]float64 {
values := make(map[string]float64)
for column, c := range coeffs {
// Use the polynomial formula: ax^2 + bx + c
values[column] = c[2]*math.Pow(level, 2) + c[1]*level + c[0]
}
return values
}

View File

@@ -0,0 +1,503 @@
-- SQL Script to Insert 50 Ranks for Each Stat
INSERT INTO mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemCost1, itemEntry2, itemCost2, itemEntry3, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES
(1, 0, 911005, 5, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 0, 911005, 8, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 0, 911005, 10, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 0, 911005, 13, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 0, 911005, 15, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 0, 911005, 18, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 0, 911005, 20, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 0, 911005, 23, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 0, 911005, 25, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 0, 911005, 28, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 0, 911005, 25, 911006, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 0, 911005, 27, 911006, 2, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 0, 911005, 28, 911006, 4, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 0, 911005, 29, 911006, 6, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 0, 911005, 30, 911006, 8, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 0, 911005, 32, 911006, 10, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 0, 911005, 33, 911006, 12, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 0, 911005, 34, 911006, 14, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 0, 911005, 35, 911006, 16, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 0, 911005, 37, 911006, 18, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 0, 911005, 38, 911006, 20, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 0, 911005, 39, 911006, 22, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 0, 911005, 40, 911006, 24, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 0, 911005, 42, 911006, 26, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 0, 911005, 43, 911006, 28, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 0, 911005, 44, 911006, 30, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 0, 911005, 45, 911006, 32, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 0, 911005, 47, 911006, 34, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 0, 911005, 48, 911006, 36, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 0, 911005, 50, 911006, 38, 911002, 3, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 0, 911005, 51, 911006, 40, 911002, 6, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 0, 911005, 52, 911006, 42, 911002, 9, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 0, 911005, 53, 911006, 44, 911002, 12, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 0, 911005, 54, 911006, 46, 911002, 15, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 0, 911005, 55, 911006, 48, 911002, 15, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 0, 911005, 56, 911006, 50, 911002, 15, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 0, 911005, 57, 911006, 52, 911002, 15, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 0, 911005, 58, 911006, 54, 911002, 15, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 0, 911005, 59, 911006, 56, 911002, 15, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 0, 911005, 59, 911006, 58, 911002, 15, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 0, 911005, 60, 911006, 60, 911002, 15, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 0, 911005, 61, 911006, 62, 911002, 15, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 0, 911005, 62, 911006, 64, 911002, 15, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 0, 911005, 63, 911006, 66, 911002, 15, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 0, 911005, 64, 911006, 68, 911002, 15, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 0, 911005, 65, 911006, 70, 911002, 15, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 0, 911005, 66, 911006, 72, 911002, 15, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 0, 911005, 67, 911006, 74, 911002, 15, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 0, 911005, 68, 911006, 76, 911002, 15, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 0, 911005, 68, 911006, 78, 911002, 15, 9, 18, 13, 18, 24, 27, 167, 197, 222),
(1, 1, 911009, 5, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 1, 911009, 8, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 1, 911009, 10, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 1, 911009, 13, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 1, 911009, 15, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 1, 911009, 18, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 1, 911009, 20, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 1, 911009, 23, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 1, 911009, 25, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 1, 911009, 28, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 1, 911009, 25, 911010, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 1, 911009, 27, 911010, 2, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 1, 911009, 28, 911010, 4, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 1, 911009, 29, 911010, 6, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 1, 911009, 30, 911010, 8, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 1, 911009, 32, 911010, 10, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 1, 911009, 33, 911010, 12, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 1, 911009, 34, 911010, 14, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 1, 911009, 35, 911010, 16, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 1, 911009, 37, 911010, 18, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 1, 911009, 38, 911010, 20, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 1, 911009, 39, 911010, 22, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 1, 911009, 40, 911010, 24, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 1, 911009, 42, 911010, 26, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 1, 911009, 43, 911010, 28, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 1, 911009, 44, 911010, 30, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 1, 911009, 45, 911010, 32, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 1, 911009, 47, 911010, 34, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 1, 911009, 48, 911010, 36, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 1, 911009, 50, 911010, 38, 911002, 3, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 1, 911009, 51, 911010, 40, 911002, 6, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 1, 911009, 52, 911010, 42, 911002, 9, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 1, 911009, 53, 911010, 44, 911002, 12, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 1, 911009, 54, 911010, 46, 911002, 15, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 1, 911009, 55, 911010, 48, 911002, 15, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 1, 911009, 56, 911010, 50, 911002, 15, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 1, 911009, 57, 911010, 52, 911002, 15, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 1, 911009, 58, 911010, 54, 911002, 15, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 1, 911009, 59, 911010, 56, 911002, 15, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 1, 911009, 59, 911010, 58, 911002, 15, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 1, 911009, 60, 911010, 60, 911002, 15, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 1, 911009, 61, 911010, 62, 911002, 15, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 1, 911009, 62, 911010, 64, 911002, 15, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 1, 911009, 63, 911010, 66, 911002, 15, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 1, 911009, 64, 911010, 68, 911002, 15, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 1, 911009, 65, 911010, 70, 911002, 15, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 1, 911009, 66, 911010, 72, 911002, 15, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 1, 911009, 67, 911010, 74, 911002, 15, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 1, 911009, 68, 911010, 76, 911002, 15, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 1, 911009, 68, 911010, 78, 911002, 15, 9, 18, 13, 18, 24, 27, 167, 197, 222),
(1, 2, 911003, 5, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 2, 911003, 8, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 2, 911003, 10, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 2, 911003, 13, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 2, 911003, 15, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 2, 911003, 18, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 2, 911003, 20, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 2, 911003, 23, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 2, 911003, 25, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 2, 911003, 28, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 2, 911003, 25, 911004, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 2, 911003, 27, 911004, 2, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 2, 911003, 28, 911004, 4, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 2, 911003, 29, 911004, 6, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 2, 911003, 30, 911004, 8, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 2, 911003, 32, 911004, 10, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 2, 911003, 33, 911004, 12, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 2, 911003, 34, 911004, 14, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 2, 911003, 35, 911004, 16, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 2, 911003, 37, 911004, 18, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 2, 911003, 38, 911004, 20, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 2, 911003, 39, 911004, 22, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 2, 911003, 40, 911004, 24, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 2, 911003, 42, 911004, 26, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 2, 911003, 43, 911004, 28, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 2, 911003, 44, 911004, 30, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 2, 911003, 45, 911004, 32, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 2, 911003, 47, 911004, 34, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 2, 911003, 48, 911004, 36, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 2, 911003, 50, 911004, 38, 911002, 3, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 2, 911003, 51, 911004, 40, 911002, 6, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 2, 911003, 52, 911004, 42, 911002, 9, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 2, 911003, 53, 911004, 44, 911002, 12, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 2, 911003, 54, 911004, 46, 911002, 15, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 2, 911003, 55, 911004, 48, 911002, 15, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 2, 911003, 56, 911004, 50, 911002, 15, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 2, 911003, 57, 911004, 52, 911002, 15, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 2, 911003, 58, 911004, 54, 911002, 15, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 2, 911003, 59, 911004, 56, 911002, 15, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 2, 911003, 59, 911004, 58, 911002, 15, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 2, 911003, 60, 911004, 60, 911002, 15, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 2, 911003, 61, 911004, 62, 911002, 15, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 2, 911003, 62, 911004, 64, 911002, 15, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 2, 911003, 63, 911004, 66, 911002, 15, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 2, 911003, 64, 911004, 68, 911002, 15, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 2, 911003, 65, 911004, 70, 911002, 15, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 2, 911003, 66, 911004, 72, 911002, 15, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 2, 911003, 67, 911004, 74, 911002, 15, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 2, 911003, 68, 911004, 76, 911002, 15, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 2, 911003, 68, 911004, 78, 911002, 15, 9, 18, 13, 18, 24, 27, 167, 197, 222),
(1, 3, 911007, 5, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 3, 911007, 8, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 3, 911007, 10, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 3, 911007, 13, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 3, 911007, 15, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 3, 911007, 18, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 3, 911007, 20, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 3, 911007, 23, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 3, 911007, 25, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 3, 911007, 28, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 3, 911007, 25, 911008, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 3, 911007, 27, 911008, 2, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 3, 911007, 28, 911008, 4, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 3, 911007, 29, 911008, 6, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 3, 911007, 30, 911008, 8, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 3, 911007, 32, 911008, 10, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 3, 911007, 33, 911008, 12, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 3, 911007, 34, 911008, 14, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 3, 911007, 35, 911008, 16, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 3, 911007, 37, 911008, 18, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 3, 911007, 38, 911008, 20, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 3, 911007, 39, 911008, 22, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 3, 911007, 40, 911008, 24, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 3, 911007, 42, 911008, 26, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 3, 911007, 43, 911008, 28, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 3, 911007, 44, 911008, 30, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 3, 911007, 45, 911008, 32, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 3, 911007, 47, 911008, 34, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 3, 911007, 48, 911008, 36, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 3, 911007, 50, 911008, 38, 911002, 3, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 3, 911007, 51, 911008, 40, 911002, 6, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 3, 911007, 52, 911008, 42, 911002, 9, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 3, 911007, 53, 911008, 44, 911002, 12, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 3, 911007, 54, 911008, 46, 911002, 15, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 3, 911007, 55, 911008, 48, 911002, 15, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 3, 911007, 56, 911008, 50, 911002, 15, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 3, 911007, 57, 911008, 52, 911002, 15, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 3, 911007, 58, 911008, 54, 911002, 15, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 3, 911007, 59, 911008, 56, 911002, 15, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 3, 911007, 59, 911008, 58, 911002, 15, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 3, 911007, 60, 911008, 60, 911002, 15, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 3, 911007, 61, 911008, 62, 911002, 15, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 3, 911007, 62, 911008, 64, 911002, 15, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 3, 911007, 63, 911008, 66, 911002, 15, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 3, 911007, 64, 911008, 68, 911002, 15, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 3, 911007, 65, 911008, 70, 911002, 15, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 3, 911007, 66, 911008, 72, 911002, 15, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 3, 911007, 67, 911008, 74, 911002, 15, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 3, 911007, 68, 911008, 76, 911002, 15, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 3, 911007, 68, 911008, 78, 911002, 15, 9, 18, 13, 18, 24, 27, 167, 197, 222),
(1, 4, 911011, 5, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 20, 50, 75),
(2, 4, 911011, 8, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 23, 53, 78),
(3, 4, 911011, 10, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 26, 56, 81),
(4, 4, 911011, 13, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 29, 59, 84),
(5, 4, 911011, 15, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 32, 62, 87),
(6, 4, 911011, 18, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 35, 65, 90),
(7, 4, 911011, 20, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 38, 68, 93),
(8, 4, 911011, 23, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 41, 71, 96),
(9, 4, 911011, 25, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 44, 74, 99),
(10, 4, 911011, 28, 0, 0, 0, 0, 1, 10, 5, 10, 8, 11, 47, 77, 102),
(11, 4, 911011, 25, 911012, 0, 0, 0, 3, 12, 7, 12, 12, 15, 50, 80, 105),
(12, 4, 911011, 27, 911012, 2, 0, 0, 3, 12, 7, 12, 12, 15, 53, 83, 108),
(13, 4, 911011, 28, 911012, 4, 0, 0, 3, 12, 7, 12, 12, 15, 56, 86, 111),
(14, 4, 911011, 29, 911012, 6, 0, 0, 3, 12, 7, 12, 12, 15, 59, 89, 114),
(15, 4, 911011, 30, 911012, 8, 0, 0, 3, 12, 7, 12, 12, 15, 62, 92, 117),
(16, 4, 911011, 32, 911012, 10, 0, 0, 3, 12, 7, 12, 12, 15, 65, 95, 120),
(17, 4, 911011, 33, 911012, 12, 0, 0, 3, 12, 7, 12, 12, 15, 68, 98, 123),
(18, 4, 911011, 34, 911012, 14, 0, 0, 3, 12, 7, 12, 12, 15, 71, 101, 126),
(19, 4, 911011, 35, 911012, 16, 0, 0, 3, 12, 7, 12, 12, 15, 74, 104, 129),
(20, 4, 911011, 37, 911012, 18, 0, 0, 3, 12, 7, 12, 12, 15, 77, 107, 132),
(21, 4, 911011, 38, 911012, 20, 0, 0, 5, 14, 9, 14, 16, 19, 80, 110, 135),
(22, 4, 911011, 39, 911012, 22, 0, 0, 5, 14, 9, 14, 16, 19, 83, 113, 138),
(23, 4, 911011, 40, 911012, 24, 0, 0, 5, 14, 9, 14, 16, 19, 86, 116, 141),
(24, 4, 911011, 42, 911012, 26, 0, 0, 5, 14, 9, 14, 16, 19, 89, 119, 144),
(25, 4, 911011, 43, 911012, 28, 0, 0, 5, 14, 9, 14, 16, 19, 92, 122, 147),
(26, 4, 911011, 44, 911012, 30, 0, 0, 5, 14, 9, 14, 16, 19, 95, 125, 150),
(27, 4, 911011, 45, 911012, 32, 0, 0, 5, 14, 9, 14, 16, 19, 98, 128, 153),
(28, 4, 911011, 47, 911012, 34, 0, 0, 5, 14, 9, 14, 16, 19, 101, 131, 156),
(29, 4, 911011, 48, 911012, 36, 0, 0, 5, 14, 9, 14, 16, 19, 104, 134, 159),
(30, 4, 911011, 50, 911012, 38, 911002, 3, 5, 14, 9, 14, 16, 19, 107, 137, 162),
(31, 4, 911011, 51, 911012, 40, 911002, 6, 7, 16, 11, 16, 20, 23, 110, 140, 165),
(32, 4, 911011, 52, 911012, 42, 911002, 9, 7, 16, 11, 16, 20, 23, 113, 143, 168),
(33, 4, 911011, 53, 911012, 44, 911002, 12, 7, 16, 11, 16, 20, 23, 116, 146, 171),
(34, 4, 911011, 54, 911012, 46, 911002, 15, 7, 16, 11, 16, 20, 23, 119, 149, 174),
(35, 4, 911011, 55, 911012, 48, 911002, 15, 7, 16, 11, 16, 20, 23, 122, 152, 177),
(36, 4, 911011, 56, 911012, 50, 911002, 15, 7, 16, 11, 16, 20, 23, 125, 155, 180),
(37, 4, 911011, 57, 911012, 52, 911002, 15, 7, 16, 11, 16, 20, 23, 128, 158, 183),
(38, 4, 911011, 58, 911012, 54, 911002, 15, 7, 16, 11, 16, 20, 23, 131, 161, 186),
(39, 4, 911011, 59, 911012, 56, 911002, 15, 7, 16, 11, 16, 20, 23, 134, 164, 189),
(40, 4, 911011, 59, 911012, 58, 911002, 15, 7, 16, 11, 16, 20, 23, 137, 167, 192),
(41, 4, 911011, 60, 911012, 60, 911002, 15, 9, 18, 13, 18, 24, 27, 140, 170, 195),
(42, 4, 911011, 61, 911012, 62, 911002, 15, 9, 18, 13, 18, 24, 27, 143, 173, 198),
(43, 4, 911011, 62, 911012, 64, 911002, 15, 9, 18, 13, 18, 24, 27, 146, 176, 201),
(44, 4, 911011, 63, 911012, 66, 911002, 15, 9, 18, 13, 18, 24, 27, 149, 179, 204),
(45, 4, 911011, 64, 911012, 68, 911002, 15, 9, 18, 13, 18, 24, 27, 152, 182, 207),
(46, 4, 911011, 65, 911012, 70, 911002, 15, 9, 18, 13, 18, 24, 27, 155, 185, 210),
(47, 4, 911011, 66, 911012, 72, 911002, 15, 9, 18, 13, 18, 24, 27, 158, 188, 213),
(48, 4, 911011, 67, 911012, 74, 911002, 15, 9, 18, 13, 18, 24, 27, 161, 191, 216),
(49, 4, 911011, 68, 911012, 76, 911002, 15, 9, 18, 13, 18, 24, 27, 164, 194, 219),
(50, 4, 911011, 68, 911012, 78, 911002, 15, 9, 18, 13, 18, 24, 27, 167, 197, 222),
(1, 5, 911019, 4, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 20, 50, 75),
(2, 5, 911019, 6, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 23, 53, 78),
(3, 5, 911019, 8, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 26, 56, 81),
(4, 5, 911019, 9, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 29, 59, 84),
(5, 5, 911019, 11, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 32, 62, 87),
(6, 5, 911019, 13, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 35, 65, 90),
(7, 5, 911019, 15, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 38, 68, 93),
(8, 5, 911019, 16, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 41, 71, 96),
(9, 5, 911019, 18, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 44, 74, 99),
(10, 5, 911019, 20, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 47, 77, 102),
(11, 5, 911019, 18, 911020, 0, 0, 0, 5, 9, 7, 9, 12, 14, 50, 80, 105),
(12, 5, 911019, 19, 911020, 2, 0, 0, 5, 9, 7, 9, 12, 14, 53, 83, 108),
(13, 5, 911019, 20, 911020, 4, 0, 0, 5, 9, 7, 9, 12, 14, 56, 86, 111),
(14, 5, 911019, 22, 911020, 6, 0, 0, 5, 9, 7, 9, 12, 14, 59, 89, 114),
(15, 5, 911019, 23, 911020, 8, 0, 0, 5, 9, 7, 9, 12, 14, 62, 92, 117),
(16, 5, 911019, 24, 911020, 10, 0, 0, 7, 11, 9, 11, 16, 18, 65, 95, 120),
(17, 5, 911019, 25, 911020, 12, 0, 0, 7, 11, 9, 11, 16, 18, 68, 98, 123),
(18, 5, 911019, 27, 911020, 14, 0, 0, 7, 11, 9, 11, 16, 18, 71, 101, 126),
(19, 5, 911019, 28, 911020, 16, 0, 0, 7, 11, 9, 11, 16, 18, 74, 104, 129),
(20, 5, 911019, 29, 911020, 18, 0, 0, 7, 11, 9, 11, 16, 18, 77, 107, 132),
(21, 5, 911019, 30, 911020, 20, 0, 0, 9, 13, 11, 13, 20, 22, 80, 110, 135),
(22, 5, 911019, 32, 911020, 22, 0, 0, 9, 13, 11, 13, 20, 22, 83, 113, 138),
(23, 5, 911019, 33, 911020, 24, 0, 0, 9, 13, 11, 13, 20, 22, 86, 116, 141),
(24, 5, 911019, 34, 911020, 26, 0, 0, 9, 13, 11, 13, 20, 22, 89, 119, 144),
(25, 5, 911019, 35, 911020, 28, 0, 0, 9, 13, 11, 13, 20, 22, 92, 122, 147),
(26, 5, 911019, 37, 911020, 30, 0, 0, 11, 15, 13, 15, 24, 26, 95, 125, 150),
(27, 5, 911019, 38, 911020, 32, 0, 0, 11, 15, 13, 15, 24, 26, 98, 128, 153),
(28, 5, 911019, 39, 911020, 34, 0, 0, 11, 15, 13, 15, 24, 26, 101, 131, 156),
(29, 5, 911019, 40, 911020, 36, 0, 0, 11, 15, 13, 15, 24, 26, 104, 134, 159),
(30, 5, 911019, 35, 911020, 38, 911002, 3, 11, 15, 13, 15, 24, 26, 107, 137, 162),
(31, 5, 911019, 36, 911020, 40, 911002, 6, 13, 17, 15, 17, 28, 30, 110, 140, 165),
(32, 5, 911019, 37, 911020, 42, 911002, 9, 13, 17, 15, 17, 28, 30, 113, 143, 168),
(33, 5, 911019, 38, 911020, 44, 911002, 12, 13, 17, 15, 17, 28, 30, 116, 146, 171),
(34, 5, 911019, 39, 911020, 46, 911002, 15, 13, 17, 15, 17, 28, 30, 119, 149, 174),
(35, 5, 911019, 40, 911020, 48, 911002, 18, 13, 17, 15, 17, 28, 30, 122, 152, 177),
(36, 5, 911019, 41, 911020, 50, 911002, 21, 15, 19, 17, 19, 32, 34, 125, 155, 180),
(37, 5, 911019, 42, 911020, 52, 911002, 24, 15, 19, 17, 19, 32, 34, 128, 158, 183),
(38, 5, 911019, 43, 911020, 54, 911002, 27, 15, 19, 17, 19, 32, 34, 131, 161, 186),
(39, 5, 911019, 44, 911020, 56, 911002, 30, 15, 19, 17, 19, 32, 34, 134, 164, 189),
(40, 5, 911019, 44, 911020, 58, 911002, 33, 15, 19, 17, 19, 32, 34, 137, 167, 192),
(41, 5, 911019, 45, 911020, 60, 911002, 36, 17, 21, 19, 21, 36, 38, 140, 170, 195),
(42, 5, 911019, 46, 911020, 62, 911002, 39, 17, 21, 19, 21, 36, 38, 143, 173, 198),
(43, 5, 911019, 47, 911020, 64, 911002, 42, 17, 21, 19, 21, 36, 38, 146, 176, 201),
(44, 5, 911019, 48, 911020, 66, 911002, 45, 17, 21, 19, 21, 36, 38, 149, 179, 204),
(45, 5, 911019, 49, 911020, 68, 911002, 48, 17, 21, 19, 21, 36, 38, 152, 182, 207),
(46, 5, 911019, 50, 911020, 70, 911002, 51, 19, 23, 21, 23, 40, 42, 155, 185, 210),
(47, 5, 911019, 51, 911020, 72, 911002, 54, 19, 23, 21, 23, 40, 42, 158, 188, 213),
(48, 5, 911019, 52, 911020, 74, 911002, 57, 19, 23, 21, 23, 40, 42, 161, 191, 216),
(49, 5, 911019, 53, 911020, 76, 911002, 60, 19, 23, 21, 23, 40, 42, 164, 194, 219),
(50, 5, 911019, 53, 911020, 78, 911002, 63, 19, 23, 21, 23, 40, 42, 167, 197, 222)
(1, 6, 911017, 4, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 20, 50, 75),
(2, 6, 911017, 6, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 23, 53, 78),
(3, 6, 911017, 8, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 26, 56, 81),
(4, 6, 911017, 9, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 29, 59, 84),
(5, 6, 911017, 11, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 32, 62, 87),
(6, 6, 911017, 13, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 35, 65, 90),
(7, 6, 911017, 15, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 38, 68, 93),
(8, 6, 911017, 16, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 41, 71, 96),
(9, 6, 911017, 18, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 44, 74, 99),
(10, 6, 911017, 20, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 47, 77, 102),
(11, 6, 911017, 18, 911018, 0, 0, 0, 5, 9, 7, 9, 12, 14, 50, 80, 105),
(12, 6, 911017, 19, 911018, 2, 0, 0, 5, 9, 7, 9, 12, 14, 53, 83, 108),
(13, 6, 911017, 20, 911018, 4, 0, 0, 5, 9, 7, 9, 12, 14, 56, 86, 111),
(14, 6, 911017, 22, 911018, 6, 0, 0, 5, 9, 7, 9, 12, 14, 59, 89, 114),
(15, 6, 911017, 23, 911018, 8, 0, 0, 5, 9, 7, 9, 12, 14, 62, 92, 117),
(16, 6, 911017, 24, 911018, 10, 0, 0, 7, 11, 9, 11, 16, 18, 65, 95, 120),
(17, 6, 911017, 25, 911018, 12, 0, 0, 7, 11, 9, 11, 16, 18, 68, 98, 123),
(18, 6, 911017, 27, 911018, 14, 0, 0, 7, 11, 9, 11, 16, 18, 71, 101, 126),
(19, 6, 911017, 28, 911018, 16, 0, 0, 7, 11, 9, 11, 16, 18, 74, 104, 129),
(20, 6, 911017, 29, 911018, 18, 0, 0, 7, 11, 9, 11, 16, 18, 77, 107, 132),
(21, 6, 911017, 30, 911018, 20, 0, 0, 9, 13, 11, 13, 20, 22, 80, 110, 135),
(22, 6, 911017, 32, 911018, 22, 0, 0, 9, 13, 11, 13, 20, 22, 83, 113, 138),
(23, 6, 911017, 33, 911018, 24, 0, 0, 9, 13, 11, 13, 20, 22, 86, 116, 141),
(24, 6, 911017, 34, 911018, 26, 0, 0, 9, 13, 11, 13, 20, 22, 89, 119, 144),
(25, 6, 911017, 35, 911018, 28, 0, 0, 9, 13, 11, 13, 20, 22, 92, 122, 147),
(26, 6, 911017, 37, 911018, 30, 0, 0, 11, 15, 13, 15, 24, 26, 95, 125, 150),
(27, 6, 911017, 38, 911018, 32, 0, 0, 11, 15, 13, 15, 24, 26, 98, 128, 153),
(28, 6, 911017, 39, 911018, 34, 0, 0, 11, 15, 13, 15, 24, 26, 101, 131, 156),
(29, 6, 911017, 40, 911018, 36, 0, 0, 11, 15, 13, 15, 24, 26, 104, 134, 159),
(30, 6, 911017, 35, 911018, 38, 911002, 3, 11, 15, 13, 15, 24, 26, 107, 137, 162),
(31, 6, 911017, 36, 911018, 40, 911002, 6, 13, 17, 15, 17, 28, 30, 110, 140, 165),
(32, 6, 911017, 37, 911018, 42, 911002, 9, 13, 17, 15, 17, 28, 30, 113, 143, 168),
(33, 6, 911017, 38, 911018, 44, 911002, 12, 13, 17, 15, 17, 28, 30, 116, 146, 171),
(34, 6, 911017, 39, 911018, 46, 911002, 15, 13, 17, 15, 17, 28, 30, 119, 149, 174),
(35, 6, 911017, 40, 911018, 48, 911002, 18, 13, 17, 15, 17, 28, 30, 122, 152, 177),
(36, 6, 911017, 41, 911018, 50, 911002, 21, 15, 19, 17, 19, 32, 34, 125, 155, 180),
(37, 6, 911017, 42, 911018, 52, 911002, 24, 15, 19, 17, 19, 32, 34, 128, 158, 183),
(38, 6, 911017, 43, 911018, 54, 911002, 27, 15, 19, 17, 19, 32, 34, 131, 161, 186),
(39, 6, 911017, 44, 911018, 56, 911002, 30, 15, 19, 17, 19, 32, 34, 134, 164, 189),
(40, 6, 911017, 44, 911018, 58, 911002, 33, 15, 19, 17, 19, 32, 34, 137, 167, 192),
(41, 6, 911017, 45, 911018, 60, 911002, 36, 17, 21, 19, 21, 36, 38, 140, 170, 195),
(42, 6, 911017, 46, 911018, 62, 911002, 39, 17, 21, 19, 21, 36, 38, 143, 173, 198),
(43, 6, 911017, 47, 911018, 64, 911002, 42, 17, 21, 19, 21, 36, 38, 146, 176, 201),
(44, 6, 911017, 48, 911018, 66, 911002, 45, 17, 21, 19, 21, 36, 38, 149, 179, 204),
(45, 6, 911017, 49, 911018, 68, 911002, 48, 17, 21, 19, 21, 36, 38, 152, 182, 207),
(46, 6, 911017, 50, 911018, 70, 911002, 51, 19, 23, 21, 23, 40, 42, 155, 185, 210),
(47, 6, 911017, 51, 911018, 72, 911002, 54, 19, 23, 21, 23, 40, 42, 158, 188, 213),
(48, 6, 911017, 52, 911018, 74, 911002, 57, 19, 23, 21, 23, 40, 42, 161, 191, 216),
(49, 6, 911017, 53, 911018, 76, 911002, 60, 19, 23, 21, 23, 40, 42, 164, 194, 219),
(50, 6, 911017, 53, 911018, 78, 911002, 63, 19, 23, 21, 23, 40, 42, 167, 197, 222),
(1, 7, 911023, 4, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 20, 50, 75),
(2, 7, 911023, 6, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 23, 53, 78),
(3, 7, 911023, 8, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 26, 56, 81),
(4, 7, 911023, 9, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 29, 59, 84),
(5, 7, 911023, 11, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 32, 62, 87),
(6, 7, 911023, 13, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 35, 65, 90),
(7, 7, 911023, 15, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 38, 68, 93),
(8, 7, 911023, 16, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 41, 71, 96),
(9, 7, 911023, 18, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 44, 74, 99),
(10, 7, 911023, 20, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 47, 77, 102),
(11, 7, 911023, 18, 911024, 0, 0, 0, 5, 9, 7, 9, 12, 14, 50, 80, 105),
(12, 7, 911023, 19, 911024, 2, 0, 0, 5, 9, 7, 9, 12, 14, 53, 83, 108),
(13, 7, 911023, 20, 911024, 4, 0, 0, 5, 9, 7, 9, 12, 14, 56, 86, 111),
(14, 7, 911023, 22, 911024, 6, 0, 0, 5, 9, 7, 9, 12, 14, 59, 89, 114),
(15, 7, 911023, 23, 911024, 8, 0, 0, 5, 9, 7, 9, 12, 14, 62, 92, 117),
(16, 7, 911023, 24, 911024, 10, 0, 0, 7, 11, 9, 11, 16, 18, 65, 95, 120),
(17, 7, 911023, 25, 911024, 12, 0, 0, 7, 11, 9, 11, 16, 18, 68, 98, 123),
(18, 7, 911023, 27, 911024, 14, 0, 0, 7, 11, 9, 11, 16, 18, 71, 101, 126),
(19, 7, 911023, 28, 911024, 16, 0, 0, 7, 11, 9, 11, 16, 18, 74, 104, 129),
(20, 7, 911023, 29, 911024, 18, 0, 0, 7, 11, 9, 11, 16, 18, 77, 107, 132),
(21, 7, 911023, 30, 911024, 20, 0, 0, 9, 13, 11, 13, 20, 22, 80, 110, 135),
(22, 7, 911023, 32, 911024, 22, 0, 0, 9, 13, 11, 13, 20, 22, 83, 113, 138),
(23, 7, 911023, 33, 911024, 24, 0, 0, 9, 13, 11, 13, 20, 22, 86, 116, 141),
(24, 7, 911023, 34, 911024, 26, 0, 0, 9, 13, 11, 13, 20, 22, 89, 119, 144),
(25, 7, 911023, 35, 911024, 28, 0, 0, 9, 13, 11, 13, 20, 22, 92, 122, 147),
(26, 7, 911023, 37, 911024, 30, 0, 0, 11, 15, 13, 15, 24, 26, 95, 125, 150),
(27, 7, 911023, 38, 911024, 32, 0, 0, 11, 15, 13, 15, 24, 26, 98, 128, 153),
(28, 7, 911023, 39, 911024, 34, 0, 0, 11, 15, 13, 15, 24, 26, 101, 131, 156),
(29, 7, 911023, 40, 911024, 36, 0, 0, 11, 15, 13, 15, 24, 26, 104, 134, 159),
(30, 7, 911023, 35, 911024, 38, 911002, 3, 11, 15, 13, 15, 24, 26, 107, 137, 162),
(31, 7, 911023, 36, 911024, 40, 911002, 6, 13, 17, 15, 17, 28, 30, 110, 140, 165),
(32, 7, 911023, 37, 911024, 42, 911002, 9, 13, 17, 15, 17, 28, 30, 113, 143, 168),
(33, 7, 911023, 38, 911024, 44, 911002, 12, 13, 17, 15, 17, 28, 30, 116, 146, 171),
(34, 7, 911023, 39, 911024, 46, 911002, 15, 13, 17, 15, 17, 28, 30, 119, 149, 174),
(35, 7, 911023, 40, 911024, 48, 911002, 18, 13, 17, 15, 17, 28, 30, 122, 152, 177),
(36, 7, 911023, 41, 911024, 50, 911002, 21, 15, 19, 17, 19, 32, 34, 125, 155, 180),
(37, 7, 911023, 42, 911024, 52, 911002, 24, 15, 19, 17, 19, 32, 34, 128, 158, 183),
(38, 7, 911023, 43, 911024, 54, 911002, 27, 15, 19, 17, 19, 32, 34, 131, 161, 186),
(39, 7, 911023, 44, 911024, 56, 911002, 30, 15, 19, 17, 19, 32, 34, 134, 164, 189),
(40, 7, 911023, 44, 911024, 58, 911002, 33, 15, 19, 17, 19, 32, 34, 137, 167, 192),
(41, 7, 911023, 45, 911024, 60, 911002, 36, 17, 21, 19, 21, 36, 38, 140, 170, 195),
(42, 7, 911023, 46, 911024, 62, 911002, 39, 17, 21, 19, 21, 36, 38, 143, 173, 198),
(43, 7, 911023, 47, 911024, 64, 911002, 42, 17, 21, 19, 21, 36, 38, 146, 176, 201),
(44, 7, 911023, 48, 911024, 66, 911002, 45, 17, 21, 19, 21, 36, 38, 149, 179, 204),
(45, 7, 911023, 49, 911024, 68, 911002, 48, 17, 21, 19, 21, 36, 38, 152, 182, 207),
(46, 7, 911023, 50, 911024, 70, 911002, 51, 19, 23, 21, 23, 40, 42, 155, 185, 210),
(47, 7, 911023, 51, 911024, 72, 911002, 54, 19, 23, 21, 23, 40, 42, 158, 188, 213),
(48, 7, 911023, 52, 911024, 74, 911002, 57, 19, 23, 21, 23, 40, 42, 161, 191, 216),
(49, 7, 911023, 53, 911024, 76, 911002, 60, 19, 23, 21, 23, 40, 42, 164, 194, 219),
(50, 7, 911023, 53, 911024, 78, 911002, 63, 19, 23, 21, 23, 40, 42, 167, 197, 222),
(1, 8, 911015, 4, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 20, 50, 75),
(2, 8, 911015, 6, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 23, 53, 78),
(3, 8, 911015, 8, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 26, 56, 81),
(4, 8, 911015, 9, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 29, 59, 84),
(5, 8, 911015, 11, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 32, 62, 87),
(6, 8, 911015, 13, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 35, 65, 90),
(7, 8, 911015, 15, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 38, 68, 93),
(8, 8, 911015, 16, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 41, 71, 96),
(9, 8, 911015, 18, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 44, 74, 99),
(10, 8, 911015, 20, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 47, 77, 102),
(11, 8, 911015, 18, 911016, 0, 0, 0, 5, 9, 7, 9, 12, 14, 50, 80, 105),
(12, 8, 911015, 19, 911016, 2, 0, 0, 5, 9, 7, 9, 12, 14, 53, 83, 108),
(13, 8, 911015, 20, 911016, 4, 0, 0, 5, 9, 7, 9, 12, 14, 56, 86, 111),
(14, 8, 911015, 22, 911016, 6, 0, 0, 5, 9, 7, 9, 12, 14, 59, 89, 114),
(15, 8, 911015, 23, 911016, 8, 0, 0, 5, 9, 7, 9, 12, 14, 62, 92, 117),
(16, 8, 911015, 24, 911016, 10, 0, 0, 7, 11, 9, 11, 16, 18, 65, 95, 120),
(17, 8, 911015, 25, 911016, 12, 0, 0, 7, 11, 9, 11, 16, 18, 68, 98, 123),
(18, 8, 911015, 27, 911016, 14, 0, 0, 7, 11, 9, 11, 16, 18, 71, 101, 126),
(19, 8, 911015, 28, 911016, 16, 0, 0, 7, 11, 9, 11, 16, 18, 74, 104, 129),
(20, 8, 911015, 29, 911016, 18, 0, 0, 7, 11, 9, 11, 16, 18, 77, 107, 132),
(21, 8, 911015, 30, 911016, 20, 0, 0, 9, 13, 11, 13, 20, 22, 80, 110, 135),
(22, 8, 911015, 32, 911016, 22, 0, 0, 9, 13, 11, 13, 20, 22, 83, 113, 138),
(23, 8, 911015, 33, 911016, 24, 0, 0, 9, 13, 11, 13, 20, 22, 86, 116, 141),
(24, 8, 911015, 34, 911016, 26, 0, 0, 9, 13, 11, 13, 20, 22, 89, 119, 144),
(25, 8, 911015, 35, 911016, 28, 0, 0, 9, 13, 11, 13, 20, 22, 92, 122, 147),
(26, 8, 911015, 37, 911016, 30, 0, 0, 11, 15, 13, 15, 24, 26, 95, 125, 150),
(27, 8, 911015, 38, 911016, 32, 0, 0, 11, 15, 13, 15, 24, 26, 98, 128, 153),
(28, 8, 911015, 39, 911016, 34, 0, 0, 11, 15, 13, 15, 24, 26, 101, 131, 156),
(29, 8, 911015, 40, 911016, 36, 0, 0, 11, 15, 13, 15, 24, 26, 104, 134, 159),
(30, 8, 911015, 35, 911016, 38, 911002, 3, 11, 15, 13, 15, 24, 26, 107, 137, 162),
(31, 8, 911015, 36, 911016, 40, 911002, 6, 13, 17, 15, 17, 28, 30, 110, 140, 165),
(32, 8, 911015, 37, 911016, 42, 911002, 9, 13, 17, 15, 17, 28, 30, 113, 143, 168),
(33, 8, 911015, 38, 911016, 44, 911002, 12, 13, 17, 15, 17, 28, 30, 116, 146, 171),
(34, 8, 911015, 39, 911016, 46, 911002, 15, 13, 17, 15, 17, 28, 30, 119, 149, 174),
(35, 8, 911015, 40, 911016, 48, 911002, 18, 13, 17, 15, 17, 28, 30, 122, 152, 177),
(36, 8, 911015, 41, 911016, 50, 911002, 21, 15, 19, 17, 19, 32, 34, 125, 155, 180),
(37, 8, 911015, 42, 911016, 52, 911002, 24, 15, 19, 17, 19, 32, 34, 128, 158, 183),
(38, 8, 911015, 43, 911016, 54, 911002, 27, 15, 19, 17, 19, 32, 34, 131, 161, 186),
(39, 8, 911015, 44, 911016, 56, 911002, 30, 15, 19, 17, 19, 32, 34, 134, 164, 189),
(40, 8, 911015, 44, 911016, 58, 911002, 33, 15, 19, 17, 19, 32, 34, 137, 167, 192),
(41, 8, 911015, 45, 911016, 60, 911002, 36, 17, 21, 19, 21, 36, 38, 140, 170, 195),
(42, 8, 911015, 46, 911016, 62, 911002, 39, 17, 21, 19, 21, 36, 38, 143, 173, 198),
(43, 8, 911015, 47, 911016, 64, 911002, 42, 17, 21, 19, 21, 36, 38, 146, 176, 201),
(44, 8, 911015, 48, 911016, 66, 911002, 45, 17, 21, 19, 21, 36, 38, 149, 179, 204),
(45, 8, 911015, 49, 911016, 68, 911002, 48, 17, 21, 19, 21, 36, 38, 152, 182, 207),
(46, 8, 911015, 50, 911016, 70, 911002, 51, 19, 23, 21, 23, 40, 42, 155, 185, 210),
(47, 8, 911015, 51, 911016, 72, 911002, 54, 19, 23, 21, 23, 40, 42, 158, 188, 213),
(48, 8, 911015, 52, 911016, 74, 911002, 57, 19, 23, 21, 23, 40, 42, 161, 191, 216),
(49, 8, 911015, 53, 911016, 76, 911002, 60, 19, 23, 21, 23, 40, 42, 164, 194, 219),
(50, 8, 911015, 53, 911016, 78, 911002, 63, 19, 23, 21, 23, 40, 42, 167, 197, 222),
(1, 9, 911021, 4, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 20, 50, 75),
(2, 9, 911021, 6, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 23, 53, 78),
(3, 9, 911021, 8, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 26, 56, 81),
(4, 9, 911021, 9, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 29, 59, 84),
(5, 9, 911021, 11, 0, 0, 0, 0, 1, 5, 3, 5, 4, 6, 32, 62, 87),
(6, 9, 911021, 13, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 35, 65, 90),
(7, 9, 911021, 15, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 38, 68, 93),
(8, 9, 911021, 16, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 41, 71, 96),
(9, 9, 911021, 18, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 44, 74, 99),
(10, 9, 911021, 20, 0, 0, 0, 0, 3, 7, 5, 7, 8, 10, 47, 77, 102),
(11, 9, 911021, 18, 911022, 0, 0, 0, 5, 9, 7, 9, 12, 14, 50, 80, 105),
(12, 9, 911021, 19, 911022, 2, 0, 0, 5, 9, 7, 9, 12, 14, 53, 83, 108),
(13, 9, 911021, 20, 911022, 4, 0, 0, 5, 9, 7, 9, 12, 14, 56, 86, 111),
(14, 9, 911021, 22, 911022, 6, 0, 0, 5, 9, 7, 9, 12, 14, 59, 89, 114),
(15, 9, 911021, 23, 911022, 8, 0, 0, 5, 9, 7, 9, 12, 14, 62, 92, 117),
(16, 9, 911021, 24, 911022, 10, 0, 0, 7, 11, 9, 11, 16, 18, 65, 95, 120),
(17, 9, 911021, 25, 911022, 12, 0, 0, 7, 11, 9, 11, 16, 18, 68, 98, 123),
(18, 9, 911021, 27, 911022, 14, 0, 0, 7, 11, 9, 11, 16, 18, 71, 101, 126),
(19, 9, 911021, 28, 911022, 16, 0, 0, 7, 11, 9, 11, 16, 18, 74, 104, 129),
(20, 9, 911021, 29, 911022, 18, 0, 0, 7, 11, 9, 11, 16, 18, 77, 107, 132),
(21, 9, 911021, 30, 911022, 20, 0, 0, 9, 13, 11, 13, 20, 22, 80, 110, 135),
(22, 9, 911021, 32, 911022, 22, 0, 0, 9, 13, 11, 13, 20, 22, 83, 113, 138),
(23, 9, 911021, 33, 911022, 24, 0, 0, 9, 13, 11, 13, 20, 22, 86, 116, 141),
(24, 9, 911021, 34, 911022, 26, 0, 0, 9, 13, 11, 13, 20, 22, 89, 119, 144),
(25, 9, 911021, 35, 911022, 28, 0, 0, 9, 13, 11, 13, 20, 22, 92, 122, 147),
(26, 9, 911021, 37, 911022, 30, 0, 0, 11, 15, 13, 15, 24, 26, 95, 125, 150),
(27, 9, 911021, 38, 911022, 32, 0, 0, 11, 15, 13, 15, 24, 26, 98, 128, 153),
(28, 9, 911021, 39, 911022, 34, 0, 0, 11, 15, 13, 15, 24, 26, 101, 131, 156),
(29, 9, 911021, 40, 911022, 36, 0, 0, 11, 15, 13, 15, 24, 26, 104, 134, 159),
(30, 9, 911021, 35, 911022, 38, 911002, 3, 11, 15, 13, 15, 24, 26, 107, 137, 162),
(31, 9, 911021, 36, 911022, 40, 911002, 6, 13, 17, 15, 17, 28, 30, 110, 140, 165),
(32, 9, 911021, 37, 911022, 42, 911002, 9, 13, 17, 15, 17, 28, 30, 113, 143, 168),
(33, 9, 911021, 38, 911022, 44, 911002, 12, 13, 17, 15, 17, 28, 30, 116, 146, 171),
(34, 9, 911021, 39, 911022, 46, 911002, 15, 13, 17, 15, 17, 28, 30, 119, 149, 174),
(35, 9, 911021, 40, 911022, 48, 911002, 18, 13, 17, 15, 17, 28, 30, 122, 152, 177),
(36, 9, 911021, 41, 911022, 50, 911002, 21, 15, 19, 17, 19, 32, 34, 125, 155, 180),
(37, 9, 911021, 42, 911022, 52, 911002, 24, 15, 19, 17, 19, 32, 34, 128, 158, 183),
(38, 9, 911021, 43, 911022, 54, 911002, 27, 15, 19, 17, 19, 32, 34, 131, 161, 186),
(39, 9, 911021, 44, 911022, 56, 911002, 30, 15, 19, 17, 19, 32, 34, 134, 164, 189),
(40, 9, 911021, 44, 911022, 58, 911002, 33, 15, 19, 17, 19, 32, 34, 137, 167, 192),
(41, 9, 911021, 45, 911022, 60, 911002, 36, 17, 21, 19, 21, 36, 38, 140, 170, 195),
(42, 9, 911021, 46, 911022, 62, 911002, 39, 17, 21, 19, 21, 36, 38, 143, 173, 198),
(43, 9, 911021, 47, 911022, 64, 911002, 42, 17, 21, 19, 21, 36, 38, 146, 176, 201),
(44, 9, 911021, 48, 911022, 66, 911002, 45, 17, 21, 19, 21, 36, 38, 149, 179, 204),
(45, 9, 911021, 49, 911022, 68, 911002, 48, 17, 21, 19, 21, 36, 38, 152, 182, 207),
(46, 9, 911021, 50, 911022, 70, 911002, 51, 19, 23, 21, 23, 40, 42, 155, 185, 210),
(47, 9, 911021, 51, 911022, 72, 911002, 54, 19, 23, 21, 23, 40, 42, 158, 188, 213),
(48, 9, 911021, 52, 911022, 74, 911002, 57, 19, 23, 21, 23, 40, 42, 161, 191, 216),
(49, 9, 911021, 53, 911022, 76, 911002, 60, 19, 23, 21, 23, 40, 42, 164, 194, 219),
(50, 9, 911021, 53, 911022, 78, 911002, 63, 19, 23, 21, 23, 40, 42, 167, 197, 222),
;

View File

@@ -0,0 +1,270 @@
package main
import (
"fmt"
"math"
"os"
)
// Stats enum
const (
STAT_INTELLECT = iota
STAT_SPIRIT
STAT_STRENGTH
STAT_AGILITY
STAT_STAMINA
)
const (
RESIST_ARCANE = iota
RESIST_FIRE
RESIST_NATURE
RESIST_FROST
RESIST_SHADOW
)
// Return the itemEntry for a state item and based on quality (3 - rare, 4 - epic)
func getStatItemEntry(statID int, quality int) int {
switch statID {
case STAT_INTELLECT:
if quality == 3 {
return 911005
}
return 911006
case STAT_SPIRIT:
if quality == 3 {
return 911009
}
return 911010
case STAT_STRENGTH:
if quality == 3 {
return 911003
}
return 911004
case STAT_AGILITY:
if quality == 3 {
return 911007
}
return 911008
case STAT_STAMINA:
if quality == 3 {
return 911011
}
return 911012
default:
return 0
}
}
func getResistItemEntry(resistID int, quality int) int {
switch resistID {
case RESIST_FROST:
if quality == 3 {
return 911015
}
return 911016
case RESIST_FIRE:
if quality == 3 {
return 911017
}
return 911018
case RESIST_NATURE:
if quality == 3 {
return 911023
}
return 911024
case RESIST_SHADOW:
if quality == 3 {
return 911021
}
return 911022
case RESIST_ARCANE:
if quality == 3 {
return 911019
}
return 911020
default:
return 0
}
}
func main() {
// Output file for the SQL script
outputFile, err := os.Create("generate_stat_upgrades.sql")
if err != nil {
fmt.Println("Error creating file:", err)
return
}
defer outputFile.Close()
// Stats names for clarity
stats := map[int]string{
STAT_INTELLECT: "Intellect",
STAT_SPIRIT: "Spirit",
STAT_STRENGTH: "Strength",
STAT_AGILITY: "Agility",
STAT_STAMINA: "Stamina",
}
resistTypes := map[int]string{
RESIST_ARCANE: "Arcane",
RESIST_FIRE: "Fire",
RESIST_NATURE: "Nature",
RESIST_FROST: "Frost",
RESIST_SHADOW: "Shadow",
}
// Start writing the SQL script
fmt.Fprintln(outputFile, "-- SQL Script to Insert 50 Ranks for Each Stat")
fmt.Fprintln(outputFile, "INSERT INTO mp_upgrade_ranks (upgradeRank, advancementId, itemEntry1, itemCost1, itemEntry2, itemCost2, itemEntry3, itemCost3, minIncrease1, maxIncrease1, minIncrease2, maxIncrease2, minIncrease3, maxIncrease3, chanceCost1, chanceCost2, chanceCost3) VALUES")
// Iterate over stats
for statID := range stats {
for rank := 1; rank <= 50; rank++ {
// Material cost increases by 50 per rank
materialCost := 50
if rank < 11 {
materialCost = 100 + (rank-1)*50
}
if rank >= 11 && rank < 30 {
materialCost = 500 + (rank-11)*25
}
if rank >= 30 {
materialCost = 1000 + (rank-30)*18
}
// Make adjustment for new fusion core types
itemCost1 := int(math.Ceil(float64(materialCost) / 20))
// Stat growth
minIncrease1 := 1 + (rank-1)/10*2
maxIncrease1 := 10 + (rank-1)/10*2
minIncrease2 := (minIncrease1 + maxIncrease1) / 2
maxIncrease3Bonus := (rank-1)/10*2 + 1
maxIncrease3 := maxIncrease1 + maxIncrease3Bonus
minIncrease3 := maxIncrease3 - 3
// Dice costs
chanceCost1 := 20 + (rank-1)*3
chanceCost2 := 50 + (rank-1)*3
chanceCost3 := 75 + (rank-1)*3
// use material ids from the mp_material_types table material1 should be common stuff.
itemEntry1 := getStatItemEntry(statID, 3)
// material2 should be rare stuff only required after rank 10 at growth rate of 5 per rank
itemEntry2, itemCost2 := 0, 0
if rank > 10 {
itemEntry2 = getStatItemEntry(statID, 4)
itemCost2 = (rank - 11) * 10
}
// Adjust from old formula to new mythic fusion core types
itemCost2 = int(math.Ceil(float64(itemCost2) / 5))
itemEntry3, itemCost3 := 0, 0
if rank >= 30 {
itemEntry3 = 911002 // veilstones
itemCost3 = (rank - 29) * 3
if itemCost3 > 15 {
itemCost3 = 15
}
}
// Write SQL insert statement for this rank
sql := fmt.Sprintf(
"(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
rank, statID, itemEntry1, itemCost1, itemEntry2, itemCost2, itemEntry3, itemCost3,
minIncrease1, maxIncrease1, minIncrease2, maxIncrease1, minIncrease3, maxIncrease3,
chanceCost1, chanceCost2, chanceCost3,
)
// Add a comma for all but the last line
isLastStat := statID == STAT_STAMINA && rank == 50
isLastResist := false
isLast := isLastStat && len(resistTypes) == 0 || isLastResist
if !isLast {
sql += ","
}
fmt.Fprintln(outputFile, sql)
}
}
// Iterate over resists
for resistId := range resistTypes {
resistIdbump := resistId + 5
for rank := 1; rank <= 50; rank++ {
// Material cost increases by 50 per rank
materialCost := 50
if rank < 11 {
materialCost = 75 + (rank-1)*35
}
if rank >= 11 && rank < 30 {
materialCost = 350 + (rank-11)*25
}
if rank >= 30 {
materialCost = 700 + (rank-30)*18
}
// Make adjustment for new fusion core types
itemCost1 := int(math.Ceil(float64(materialCost) / 20))
// Stat growth
minIncrease1 := 1 + (rank-1)/5*2
maxIncrease1 := 5 + (rank-1)/5*2
minIncrease2 := (minIncrease1 + maxIncrease1) / 2
maxIncrease3Bonus := (rank-1)/5*2 + 1
maxIncrease3 := maxIncrease1 + maxIncrease3Bonus
minIncrease3 := maxIncrease3 - 2
// Dice costs
chanceCost1 := 20 + (rank-1)*3
chanceCost2 := 50 + (rank-1)*3
chanceCost3 := 75 + (rank-1)*3
// use material ids from the mp_material_types table material1 should be common stuff.
itemEntry1 := getResistItemEntry(resistId, 3)
// material2 should be rare stuff only required after rank 10 at growth rate of 5 per rank
itemEntry2, itemCost2 := 0, 0
if rank > 10 {
itemEntry2 = getResistItemEntry(resistId, 4)
itemCost2 = (rank - 11) * 10
}
// Adjust from old formula to new mythic fusion core types
itemCost2 = int(math.Ceil(float64(itemCost2) / 5))
itemEntry3, itemCost3 := 0, 0
if rank >= 30 {
itemEntry3 = 911002 // veilstones
itemCost3 = (rank - 29) * 3
}
// Write SQL insert statement for this rank
sql := fmt.Sprintf(
"(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
rank, resistIdbump, itemEntry1, itemCost1, itemEntry2, itemCost2, itemEntry3, itemCost3,
minIncrease1, maxIncrease1, minIncrease2, maxIncrease1, minIncrease3, maxIncrease3,
chanceCost1, chanceCost2, chanceCost3,
)
// Add a comma for all but the last line
isLast := resistId == RESIST_ARCANE && rank == 50
if !isLast {
sql += ","
}
fmt.Fprintln(outputFile, sql)
}
}
fmt.Fprintln(outputFile, ";")
fmt.Println("SQL script generated: generate_stat_upgrades.sql")
}

565
src/AdvancementMgr.cpp Normal file
View File

@@ -0,0 +1,565 @@
#include "AdvancementMgr.h"
#include "CharacterDatabase.h"
#include "WorldDatabase.h"
#include "Player.h"
#include "MpLogger.h"
#include "MythicPlus.h"
#include "MpConstants.h"
#include <string_view>
#include <tuple>
#include <mutex>
#include <exception>
std::string MpAdvancementsToString(MpAdvancements advancement)
{
switch (advancement)
{
case MP_ADV_INTELLECT: return "Intellect";
case MP_ADV_SPIRIT: return "Spirit";
case MP_ADV_STRENGTH: return "Strength";
case MP_ADV_AGILITY: return "Agility";
case MP_ADV_STAMINA: return "Stamina";
case MP_ADV_RESIST_ARCANE: return "Arcane Resistance";
case MP_ADV_RESIST_FIRE: return "Fire Resistance";
case MP_ADV_RESIST_NATURE: return "Nature Resistance";
case MP_ADV_RESIST_FROST: return "Frost Resistance";
case MP_ADV_RESIST_SHADOW: return "Shadow Resistance";
default: return "Unknown Advancement";
}
}
/**
* Table schema for upgrade ranks populated by go script:
*
* upgradeRank INT UNSIGNED NOT NULL,
* advancementId INT UNSIGNED NOT NULL,
* itemEntry1 INT UNSIGNED NOT NULL,
* itemEntry2 INT UNSIGNED NOT NULL,
* itemEntry3 INT UNSIGNED NOT NULL,
* itemCost1 INT UNSIGNED NOT NULL,
* itemCost2 INT UNSIGNED NOT NULL,
* itemCost3 INT UNSIGNED NOT NULL,
* minIncrease1 INT UNSIGNED NOT NULL,
* maxIncrease1 INT UNSIGNED NOT NULL,
* minIncrease2 INT UNSIGNED NOT NULL,
* maxIncrease2 INT UNSIGNED NOT NULL,
* minIncrease3 INT UNSIGNED NOT NULL,
* maxIncrease3 INT UNSIGNED NOT NULL,
* chanceCost1 INT UNSIGNED NOT NULL,
* chanceCost2 INT UNSIGNED NOT NULL,
* chanceCost3 INT UNSIGNED NOT NULL,
*
* PRIMARY KEY (upgradeRank, statTypeId)
*
* This loads the ranks from the database and stores them into memory for access. This should only be
* called on server start-up as it is static data that should only change no new builds.
*/
int32 AdvancementMgr::LoadAdvancementRanks() {
_advancementRanks.clear();
//
// const char*
constexpr std::string_view query = R"(
SELECT
upgradeRank,
advancementId,
itemEntry1,
itemEntry2,
itemEntry3,
itemCost1,
itemCost2,
itemCost3,
minIncrease1,
maxIncrease1,
minIncrease2,
maxIncrease2,
minIncrease3,
maxIncrease3,
chanceCost1,
chanceCost2,
chanceCost3
FROM mp_upgrade_ranks
)";
QueryResult result = WorldDatabase.Query(query);
if (!result) {
MpLogger::error("Failed to load advancement ranks from database");
return 0;
}
// Load all the material types into memory for reference
do {
Field* fields = result->Fetch();
uint32 upgradeRank = fields[0].Get<uint32>();
uint32 advancementId = fields[1].Get<uint32>();
uint32 itemEntry1 = fields[2].Get<uint32>();
uint32 itemEntry2 = fields[3].Get<uint32>();
uint32 itemEntry3 = fields[4].Get<uint32>();
uint32 itemCost1 = fields[5].Get<uint32>();
uint32 itemCost2 = fields[6].Get<uint32>();
uint32 itemCost3 = fields[7].Get<uint32>();
uint32 minIncrease1 = fields[8].Get<uint32>();
uint32 maxIncrease1 = fields[9].Get<uint32>();
uint32 minIncrease2 = fields[10].Get<uint32>();
uint32 maxIncrease2 = fields[11].Get<uint32>();
uint32 minIncrease3 = fields[12].Get<uint32>();
uint32 maxIncrease3 = fields[13].Get<uint32>();
uint32 chanceCost1 = fields[14].Get<uint32>();
uint32 chanceCost2 = fields[15].Get<uint32>();
uint32 chanceCost3 = fields[16].Get<uint32>();
// Should add validator... but let's do it without and trust in the o-DB-Wan-kenobe
MpAdvancements advancement = static_cast<MpAdvancements>(advancementId);
// List of all ranks keyed by rank, advancementId
MpAdvancementRank rank = {
.rank = upgradeRank,
.advancementId = advancement,
.materialCost = std::unordered_map<uint32, uint32>(),
.rollCost = {chanceCost1, chanceCost2, chanceCost3},
.lowRange = std::make_pair(minIncrease1, maxIncrease1),
.midRange = std::make_pair(minIncrease2, maxIncrease2),
.highRange = std::make_pair(minIncrease3, maxIncrease3),
.material1 = std::make_pair(itemEntry1, itemCost1),
.material2 = std::make_pair(itemEntry2, itemCost2),
.material3 = std::make_pair(itemEntry3, itemCost3)
};
_advancementRanks.try_emplace(std::make_pair(upgradeRank, advancement), rank);
} while (result->NextRow());
return _advancementRanks.size();
}
/**
* guid INT UNSIGNED NOT NULL,
* advancementId INT UNSIGNED NOT NULL,
* bonus FLOAT NOT NULL,
* upgradeRank INT UNSIGNED NOT NULL,
* diceSpent INT UNSIGNED NOT NULL DEFAULT '0',
*
* PRIMARY KEY (guid, advancementId)
*
* This loads the player advancements when a player logs in stores it into memory for access by spell scripts that
* are applied to the player on login to apply the bonuses.
*/
void AdvancementMgr::LoadPlayerAdvancements(Player* player) {
std::lock_guard<std::mutex> lock(_playerAdvancementMutex);
constexpr std::string_view query = R"(
SELECT
guid,
advancementId,
bonus,
upgradeRank,
diceSpent
FROM mp_player_advancements
WHERE guid = {}
)";
QueryResult result = CharacterDatabase.Query(query, player->GetGUID().GetCounter());
// If the player does not have any upgrades just return perfectly fine not a problem until they purchase one.
if(!result) {
MpLogger::info("Player {} has no advancements", player->GetName());
return;
}
uint32 count = 0;
uint32 guid = player->GetGUID().GetCounter();
// Loop through all results to load all advancements for this player
do {
Field* fields = result->Fetch();
uint32 advancementId = fields[1].Get<uint32>();
float bonus = fields[2].Get<float>();
uint32 upgradeRank = fields[3].Get<uint32>();
uint32 diceSpent = fields[4].Get<uint32>();
MpAdvancements advancement = static_cast<MpAdvancements>(advancementId);
MpPlayerRank playerRank = MpPlayerRank();
playerRank.rank = upgradeRank;
playerRank.advancementId = advancement;
playerRank.diceSpent = diceSpent;
playerRank.bonus = bonus;
// List of all ranks keyed by rank, advancementId
_playerAdvancements[guid][advancement] = playerRank;
MpLogger::debug("Loaded player {} advancement {} rank {} with bonus {}",
player->GetName(), static_cast<int>(advancement), upgradeRank, bonus);
count++;
} while (result->NextRow());
MpLogger::info("Loaded {} advancements for player {}", count, player->GetName());
}
/**
* Load Material Types from the database into memory
*/
int32 AdvancementMgr::LoadMaterialTypes() {
constexpr std::string_view query = R"(
SELECT
materialId,
entry
FROM mp_material_types
)";
if(QueryResult result = WorldDatabase.Query(query)) {
do {
Field* fields = result->Fetch();
uint32 materialId = fields[0].Get<uint32>();
uint32 entry = fields[1].Get<uint32>();
if(!_materialTypes.contains(materialId)) {
_materialTypes.emplace(materialId,std::vector<uint32>());
}
_materialTypes.at(materialId).push_back(entry);
} while (result->NextRow());
return result->GetRowCount();
} else {
MpLogger::error("Query failed to load material types from database");
return 0;
}
}
MpAdvancementRank* AdvancementMgr::GetAdvancementRank(uint32 rank, MpAdvancements advancement)
{
auto key = std::make_pair(rank, advancement);
if (_advancementRanks.contains(key))
{
return &_advancementRanks.at(key);
}
else
{
MpLogger::error("Advancement Id {} and rank {} could not be found", rank, advancement);
return nullptr;
}
}
MpPlayerRank* AdvancementMgr::GetPlayerAdvancementRank(Player* player, MpAdvancements advancement)
{
if(!player) {
MpLogger::error("Could not retrieve player advancement for null player {}", player->GetName());
return nullptr;
}
if (_playerAdvancements.contains(player->GetGUID().GetCounter()) && _playerAdvancements[player->GetGUID().GetCounter()].contains(advancement))
{
return &_playerAdvancements[player->GetGUID().GetCounter()][advancement];
}
return nullptr;
}
uint32 AdvancementMgr::UpgradeAdvancement(Player* player, MpAdvancements advancement, uint32 diceCostLevel)
{
std::lock_guard<std::mutex> lock(_playerAdvancementMutex);
// Validators to make sure inputs are correct to perform the upgrade
if(!player) {
MpLogger::error("Could not upgrade advancement for player, player was nullpointer");
throw new std::runtime_error("Could not upgrade advancement for player, player was nullpointer");
}
if(diceCostLevel < 1 || diceCostLevel > 3) {
throw new std::runtime_error(Acore::StringFormat("Invalid dice cost level valid vales (1,2,3) received {} for player {}", diceCostLevel, player->GetName()));
}
MpPlayerRank* playerRank = GetPlayerAdvancementRank(player, advancement);
// IF there is not create the base struct and add to the player map for this advancement
if(!playerRank) {
MpPlayerRank newPlayerRank;
newPlayerRank.advancementId = advancement;
auto& playerAdvMap = _playerAdvancements[player->GetGUID().GetCounter()];
playerAdvMap.emplace(advancement, newPlayerRank);
playerRank = &playerAdvMap.at(advancement);
}
if(playerRank->rank == MP_MAX_ADVANCEMENT_RANK) {
MpLogger::debug("Player {} has reached the maximum rank for advancement {}", player->GetName(), advancement);
return 0;
}
uint32 newRank = playerRank->rank + 1;
MpAdvancementRank* advancementRank = GetAdvancementRank(newRank, advancement);
if(advancementRank == nullptr || !advancementRank->IsValid()) {
MpLogger::error("Advancement rank could not be found. Rank: {} Advancement: {}", newRank, static_cast<int>(advancement));
return 0;
}
// Get the items needed to upgrade this advancement
uint32 itemEntry1 = advancementRank->material1.first;
uint32 itemEntry2 = advancementRank->material2.first;
uint32 itemEntry3 = advancementRank->material3.first;
// If the player has the items needed to upgrade this advancement, then remove the items from the player inventory and apply the upgrade
if(!_PlayerHasItems(player, advancementRank, diceCostLevel, itemEntry1, itemEntry2, itemEntry3)) {
MpLogger::debug("Player {} does not have the required items to upgrade advancement {}", player->GetName(), advancement);
return 0;
}
// Charge the player the cost of the upgrade
_ChargeItemCost(player, advancementRank, diceCostLevel, itemEntry1, itemEntry2, itemEntry3);
MpLogger::debug("Player {} has upgraded advancement {} to rank {}", player->GetName(), advancement, newRank);
// Finally get the bonus to apply for the player
float roll = round(_RollAdvancement(advancementRank, diceCostLevel));
// Update the player advancement rank in memory and database
playerRank->rank = newRank;
playerRank->diceSpent += advancementRank->rollCost[diceCostLevel-1];
// round the roll to a whole number and add to player rank
playerRank->bonus += roll;
MpLogger::debug("Player {} has upgraded advancement {} to rank {} with bonus {} to new total bonus of {}", player->GetName(), advancement, newRank, roll, playerRank->bonus);
// Save the advancement to the database
_SaveAdvancement(player, advancementRank, playerRank, advancementRank->rollCost[diceCostLevel-1], roll, itemEntry1, itemEntry2, itemEntry3);
// Remove and reapply the aura to refresh the spell with the latest bonuses
uint32 spellId = MpConstants::GetAdvancementAura(advancement);
if (spellId > 0)
{
MpLogger::info("Refreshing advancement aura {} for player {}", spellId, player->GetName());
// First remove the aura completely
player->RemoveAura(spellId);
player->AddAura(spellId, player);
}
return roll;
}
bool AdvancementMgr::ResetPlayerAdvancements(Player* /*player*/)
{
std::lock_guard<std::mutex> lock(_playerAdvancementMutex);
return true;
}
void AdvancementMgr::_ResetPlayerAdvancement(Player* /*player*/, MpAdvancements /*advancement*/)
{
std::lock_guard<std::mutex> lock(_playerAdvancementMutex);
return;
}
// Roll them stats DnD style.
float AdvancementMgr::_RollAdvancement(MpAdvancementRank* advancementRank, uint32 diceCostLevel)
{
uint32 min, max;
min = max = 0;
switch (diceCostLevel)
{
case 1:
min = advancementRank->lowRange.first;
max = advancementRank->lowRange.second;
break;
case 2:
min = advancementRank->midRange.first;
max = advancementRank->midRange.second;
break;
case 3:
min = advancementRank->highRange.first;
max = advancementRank->highRange.second;
break;
default:
MpLogger::error("Invalid dice cost level valid vales (1,2,3) received {} for rank roll {}", diceCostLevel, advancementRank->rank);
break;
}
MpLogger::debug("Rolling for rank {} dice level {} min {} max {}", advancementRank->rank, diceCostLevel, min, max);
return frand(min, max);
}
/**
* Checks the players inventory to validate they have the required items to perform an upgrade based on the set cost for the passed in level.
* @todo refactor this to be more generic
*/
bool AdvancementMgr::_PlayerHasItems(Player* player, MpAdvancementRank* advancementRank, uint32 diceCostLevel, uint32 itemEntry1, uint32 itemEntry2, uint32 itemEntry3)
{
MpLogger::debug("Checking items for player {} dice level {} item1 {} item2 {} item3 {}",
player->GetName(), diceCostLevel, itemEntry1, itemEntry2, itemEntry3);
// Check if player has the required dice to upgrade the advancement
uint32 diceCost = advancementRank->rollCost[diceCostLevel-1];
if(!player->HasItemCount(MpConstants::ANCIENT_DICE, diceCost)) {
MpLogger::info("Player {} does not have enough dice to upgrade advancement {}",
player->GetName(), advancementRank->advancementId);
return false;
}
// Check material 1 (required)
if (advancementRank->material1.first > 0) {
if (itemEntry1 == 0) {
throw std::runtime_error("Primary material entry is required but was not provided");
}
uint32 requiredCount = advancementRank->material1.second;
if (!player->HasItemCount(itemEntry1, requiredCount)) {
MpLogger::info("Player {} does not have enough of item {} for advancement {}, requires: {}",
player->GetName(), itemEntry1, advancementRank->advancementId, requiredCount);
return false;
}
}
// Check material 2 (optional)
if (advancementRank->material2.first > 0) {
if (itemEntry2 == 0) {
MpLogger::debug("Secondary material is required but not provided");
return false;
}
uint32 requiredCount = advancementRank->material2.second;
if (!player->HasItemCount(itemEntry2, requiredCount)) {
MpLogger::info("Player {} does not have enough of item {} for advancement {}, requires: {}",
player->GetName(), itemEntry2, advancementRank->advancementId, requiredCount);
return false;
}
}
// Check material 3 (optional)
if (advancementRank->material3.first > 0) {
if (itemEntry3 == 0) {
MpLogger::debug("Tertiary material is required but not provided");
return false;
}
uint32 requiredCount = advancementRank->material3.second;
if (!player->HasItemCount(itemEntry3, requiredCount)) {
MpLogger::info("Player {} does not have enough of item {} for advancement {}, requires: {}",
player->GetName(), itemEntry3, advancementRank->advancementId, requiredCount);
return false;
}
}
MpLogger::debug("Player {} has all required materials to upgrade advancement {}",
player->GetName(), advancementRank->advancementId);
return true;
}
// Remove all items required for the upgrade.
void AdvancementMgr::_ChargeItemCost(Player *player, MpAdvancementRank* advancementRank, uint32 diceCostLevel, uint32 itemEntry1, uint32 itemEntry2, uint32 itemEntry3)
{
MpLogger::debug("Charging player {} dice level {} item1 {} item2 {} item3 {}",
player->GetName(), diceCostLevel, itemEntry1, itemEntry2, itemEntry3);
// Remove the dice cost
uint32 diceCost = advancementRank->rollCost[diceCostLevel-1];
player->DestroyItemCount(MpConstants::ANCIENT_DICE, diceCost, true);
// Remove material 1 if it exists
if (itemEntry1 > 0 && advancementRank->material1.first > 0) {
player->DestroyItemCount(itemEntry1, advancementRank->material1.second, true);
}
// Remove material 2 if it exists
if (itemEntry2 > 0 && advancementRank->material2.first > 0) {
player->DestroyItemCount(itemEntry2, advancementRank->material2.second, true);
}
// Remove material 3 if it exists
if (itemEntry3 > 0 && advancementRank->material3.first > 0) {
player->DestroyItemCount(itemEntry3, advancementRank->material3.second, true);
}
MpLogger::debug("Successfully charged player {} for advancement upgrade", player->GetName());
}
void AdvancementMgr::_SaveAdvancement(Player* player, MpAdvancementRank* advancementRank, MpPlayerRank* playerRank, uint32 diceCost, float roll, uint32 itemEntry1, uint32 itemEntry2, uint32 itemEntry3)
{
// Save the advancement to the database
try {
constexpr std::string_view insert = R"(
INSERT INTO mp_player_advancements (guid, advancementId, bonus, upgradeRank, diceSpent)
VALUES ({}, {}, {}, {}, {})
ON DUPLICATE KEY UPDATE
bonus = {},
upgradeRank = {},
diceSpent = {}
)";
MpLogger::debug("Saving advancement for player {} bonus {} advancement {} rank {}", player->GetName(), playerRank->bonus, advancementRank->advancementId, playerRank->rank);
CharacterDatabase.DirectExecute(insert,
player->GetGUID().GetCounter(),
advancementRank->advancementId,
playerRank->bonus,
playerRank->rank,
playerRank->diceSpent,
playerRank->bonus,
playerRank->rank,
playerRank->diceSpent
);
} catch (const std::exception& e) {
MpLogger::error("Failed to save advancement for player {}: {}", player->GetName(), e.what());
} catch (...) {
MpLogger::error("Failed to save advancement for player {}: unknown error", player->GetName());
}
try {
constexpr std::string_view insertHistory = R"(
INSERT INTO mp_player_advancement_history (guid, advancementId, bonus, upgradeRank, diceSpent, entryId1, entryId2, entryId3, itemCost1, itemCost2, itemCost3)
VALUES ({}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {})
)";
MpLogger::debug("Saving advancement history for player {} advancement {} rank {}", player->GetName(), advancementRank->advancementId, playerRank->rank);
CharacterDatabase.Execute(insertHistory,
player->GetGUID().GetCounter(),
advancementRank->advancementId,
roll,
playerRank->rank,
diceCost,
itemEntry1,
itemEntry2,
itemEntry3,
advancementRank->material1.second,
advancementRank->material2.second,
advancementRank->material3.second
);
} catch (const std::exception& e) {
MpLogger::error("Failed to save advancement history for player {}: {}", player->GetName(), e.what());
} catch (...) {
MpLogger::error("Failed to save advancement history for player {}: unknown error", player->GetName());
}
}
// void _DBSaveAdvancement(Player* player, MpAdvancementRank* advancementRank, MpPlayerRank* playerRank)
// {
// // Save the advancement to the database
// constexpr std::string_view query = R"(
// INSERT INTO mp_player_advancements (guid, advancementId, bonus, upgradeRank, diceSpent)
// VALUES ({}, {}, {}, {}, {})
// ON DUPLICATE KEY UPDATE
// bonus = {},
// upgradeRank = {},
// diceSpent = {}
// )";
// CharacterDatabase.Execute(query,
// player->GetGUID().GetCounter(),
// advancementRank->advancementId,
// roll,
// playerRank->rank,
// playerRank->diceSpent,
// roll,
// playerRank->rank,
// playerRank->diceSpent
// );
// }

154
src/AdvancementMgr.h Normal file
View File

@@ -0,0 +1,154 @@
#ifndef ADVANCEMENT_MGR_H
#define ADVANCEMENT_MGR_H
#include "SharedDefines.h"
#include "Player.h"
#include <memory>
#include <unordered_map>
#include <map>
#include <mutex>
enum MpAdvancements
{
MP_ADV_INTELLECT = 0,
MP_ADV_SPIRIT = 1,
MP_ADV_STRENGTH = 2,
MP_ADV_AGILITY = 3,
MP_ADV_STAMINA = 4,
MP_ADV_RESIST_ARCANE = 5,
MP_ADV_RESIST_FIRE = 6,
MP_ADV_RESIST_NATURE = 7,
MP_ADV_RESIST_FROST = 8,
MP_ADV_RESIST_SHADOW = 9,
MP_ADV_MAX = 10
};
std::string MpAdvancementsToString(MpAdvancements advancement);
/**
* Advancement Rank represents each level for a stat increase that has can be purchases.
* It includes materials, type, and range of successful roll.
*/
struct MpAdvancementRank
{
uint32 rank;
MpAdvancements advancementId;
std::unordered_map<uint32 /*item_entry*/,uint32 /*quantity*/> materialCost;
std::array<int, 3> rollCost; // 0 = low, 1 = mid, 2 = high
// Range of status based on bet dice roll.
std::pair<uint32 /*min*/, uint32 /*max*/> lowRange;
std::pair<uint32 /*min*/, uint32 /*max*/> midRange;
std::pair<uint32 /*min*/, uint32 /*max*/> highRange;
// materialId levels
std::pair<uint32 /*materialId*/, uint32 /*quantity*/> material1;
std::pair<uint32 /*materialId*/, uint32 /*quantity*/> material2;
std::pair<uint32 /*materialId*/, uint32 /*quantity*/> material3;
// Used to validate this struct is set correctly
bool IsValid() {
return (rank > 0 && advancementId >= 0 && advancementId < MP_ADV_MAX);
}
// Check if the map has an the item entry for the passed in material
bool HasMaterial(uint32 itemEntry) {
return materialCost.contains(itemEntry);
}
};
// Struct is used for tracking player advancement bonuses for improving stats
struct MpPlayerRank
{
uint32 rank;
MpAdvancements advancementId;
uint32 diceSpent;
float bonus;
MpPlayerRank() : rank(0), diceSpent(0), bonus(0.0f) {}
};
/**
* This singleton class is responsible for managing the advancement system
* used to improve player stats enough to challenge harder difficulties on existing dungeons.
*
* Advancements are purchased by players using based on the mp_material_type table with a "bet"
* on dice roll. This enables players to increase their stats in a random way that is not
* guaranteed to be successful. (Similar to how DND stats rolls work on character creation. )
*/
class AdvancementMgr
{
// Shared mutex for handling writes to shared player advancement data
std::mutex _playerAdvancementMutex;
// All advancement levels for each stat [rank][advancement_id] = AdvancementLevel
std::map<std::pair<uint32 /*rank*/, MpAdvancements>, MpAdvancementRank> _advancementRanks;
// Map of player advancements [player_guid][advancement_id] = rank
std::unordered_map<uint32 /*player_guid*/, std::unordered_map<MpAdvancements, MpPlayerRank>> _playerAdvancements;
// Map of different material types used fo advancing stats for players
std::unordered_map<uint32 /*material_id*/, std::vector<uint32> /* item entries */> _materialTypes;
public:
static AdvancementMgr* instance() {
static AdvancementMgr instance;
return &instance;
}
// Loads advancement information from the database into memory when players are logged in or server starts.
int32 LoadAdvancementRanks();
int32 LoadMaterialTypes();
void LoadPlayerAdvancements(Player* player);
// Methods for looking up advancement rank data
MpAdvancementRank* GetAdvancementRank(uint32 rank, MpAdvancements advancement);
// Methods for updating and setting data related to current player advancements
MpPlayerRank* GetPlayerAdvancementRank(Player* player, MpAdvancements advancement);
/**
* This upgrades a player Advancement on the server side, which will handle the following actions:
* 1. Validating player has enough dice and materials to upgrade the advancement
* 2. Rolling the dice to see what bonus is rewarded
* 3. Removing the dice and materials from the player inventory
* 4. Updating the player advancement rank in memory and database
*
* Since different materials can be used for each advancement, at the moment only support one material type from the list. supporting
* mixed materials is more complicated and the UI to support it is much more complex, while this is not as nice it is much simpler to implement.
* That means all materials have to be selected and passed in at the time of making this call.
*/
uint32 UpgradeAdvancement(Player* player, MpAdvancements advancement, uint32 diceCostLevel);
// Used to reset all advancements for a specific player
bool ResetPlayerAdvancements(Player* player);
private:
AdvancementMgr() {}
~AdvancementMgr() {}
// Will reset all the player advancements and refund the spent dice and material with a penalty for the reset.
void _ResetPlayerAdvancement(Player* player, MpAdvancements advancement);
// Rolls the dice to see how much a bonus is given based on the dice spend level
float _RollAdvancement(MpAdvancementRank* advancementRank, uint32 diceCostLevel);
// Determines if a player has required items to upgrade
bool _PlayerHasItems(Player* player, MpAdvancementRank* advancementRank, uint32 diceCostLevel, uint32 itemEntry1, uint32 itemEntry2, uint32 itemEntry3);
// Removes items from player inventory based on the required advancement rank.
void _ChargeItemCost(Player* player, MpAdvancementRank* advancementRank, uint32 diceCostLevel, uint32 itemEntry1, uint32 itemEntry2, uint32 itemEntry3);
// This will save the advancement for the player advancement in memory and database
void _SaveAdvancement(Player* player, MpAdvancementRank* advancementRank, MpPlayerRank* playerRank, uint32 diceCost, float roll, uint32 itemEntry1, uint32 itemEntry2 = 0, uint32 itemEntry3 = 0);
// This will save the advancement purchase to the history database
// void _DBSaveAdvancement(Player* player, MpAdvancementRank* advancementRank, MpPlayerRank* playerRank, uint32 diceCost, float roll);
};
#define sAdvancementMgr AdvancementMgr::instance()
#endif

View File

@@ -1,60 +0,0 @@
#include "ScriptMgr.h"
#include "MythicPlus.h"
#include "MapMgr.h"
class MythicPlus_AllCreatureScript : public AllCreatureScript
{
public:
MythicPlus_AllCreatureScript() : AllCreatureScript("MythicPlus_AllCreatureScript")
{
}
void OnCreatureAddWorld(Creature* creature) override
{
// if (creature->GetMap()->IsDungeon() || creature->GetMap()->IsRaid())
// LOG_DEBUG("module.MythicPlus",
// "MythicPlus_AllCreatureScript::OnCreatureAddWorld(): {} ({})",
// creature->GetName(),
// creature->GetLevel()
// );
}
void OnCreatureRemoveWorld(Creature* creature) override
{
// if (creature->GetMap()->IsDungeon() || creature->GetMap()->IsRaid())
// LOG_DEBUG("module.MythicPlus",
// "MythicPlus_AllCreatureScript::OnCreatureRemoveWorld(): {} ({})",
// creature->GetName(),
// creature->GetLevel()
// );
// // remove the creature from the map's tracking list, if present
// sMythicPlus->RemoveCreatureFromMapData(creature);
}
void OnAllCreatureUpdate(Creature* creature, uint32 /*diff*/) override
{
// If the config is out of date and the creature was reset, run modify against it
// if (ResetCreatureIfNeeded(creature))
// {
// LOG_DEBUG("module.MythicPlus",
// "MythicPlus_AllCreatureScript::OnAllCreatureUpdate(): Creature {} ({}) is reset to its original stats.",
// creature->GetName(),
// creature->GetLevel()
// );
// // Update the map's level if it is out of date
// sMythicPlus->UpdateMapLevelIfNeeded(creature->GetMap());
// ModifyCreatureAttributes(creature);
// }
}
};
void AddAllCreatureScripts()
{
new MythicPlus_AllCreatureScript();
}

View File

@@ -1,47 +0,0 @@
#include "ScriptMgr.h"
#include "Log.h"
#include "Player.h"
#include "MythicPlus.h"
#include "Chat.h"
#include "MapMgr.h"
class MythicPlus_AllMapScript : public AllMapScript
{
public:
MythicPlus_AllMapScript() : AllMapScript("MythicPlus_AllMapScript")
{
}
void OnCreateMap(Map* map)
{
// LOG_DEBUG("module.MythicPlus", "MythicPlus_AllMapScript::OnCreateMap(): {}", map->GetMapName());
// if (!map->IsDungeon() && !map->IsRaid())
// return;
}
void OnPlayerEnterAll(Map* map, Player* player)
{
// LOG_DEBUG("module.MythicPlus", "MythicPlus_AllMapScript::OnPlayerEnterAll(): {}", map->GetMapName());
// if (!map->IsDungeon() && !map->IsRaid())
// return;
// if (player->IsGameMaster())
// return;
}
void OnPlayerLeaveAll(Map* map, Player* player)
{
// LOG_DEBUG("module.MythicPlus", "MythicPlus_AllMapScript::OnPlayerLeaveAll(): {}", map->GetMapName());
// if (!sMythicPlus->EnableGlobal)
// return;
}
};
void AddAllMapScripts()
{
new MythicPlus_AllMapScript();
}

View File

@@ -1,16 +0,0 @@
#include "MythicPlus.h"
#include "ScriptMgr.h"
// make sure this is the new way to do this, i think it's the old busted shit
class MythicPlus_CommandScript : public CommandScript
{
public:
};
void AddCommandScripts()
{
}

View File

@@ -0,0 +1,35 @@
#include "CreatureHooks.h"
#include "MpLogger.h"
class BaseCreatureHandler {
public:
BaseCreatureHandler(uint32 entry) {
ASSERT(entry > 0);
MpLogger::debug("Registering JustDied and OnSpawn events for entry: ", entry);
// Register the JustDied event
sCreatureHooks->RegisterJustDied(entry, [this](Creature* creature, Unit* killer) {
this->OnJustDied(creature, killer);
});
// Register the OnSpawn event
sCreatureHooks->RegisterOnSpawn(entry, [this](Creature* creature) {
this->OnJustSpawned(creature);
});
sCreatureHooks->RegisterOnAddToInstance(entry, [this](Creature* creature) {
this->OnAddToInstance(creature);
});
}
// Virtual event handlers to be overridden by bosses
virtual void OnJustDied(Creature* /*creature*/, Unit* /*killer*/) {}
virtual void OnJustSpawned(Creature* /*creature*/) {}
virtual void OnAddToInstance(Creature* /*creature*/) {}
virtual ~BaseCreatureHandler() {}
};

View File

@@ -0,0 +1,84 @@
#include "CreatureHooks.h"
#include "MythicPlus.h"
#include "MpLogger.h"
void CreatureHooks::RegisterJustDied(uint32 entry, CreatureHook<Creature*, Unit*> callback) {
(*_JustDiedHandlers)[entry].push_back(callback);
}
void CreatureHooks::RegisterOnSpawn(uint32 entry, CreatureHook<Creature*>callback) {
(*_OnSpawnHandlers)[entry].push_back(callback);
}
void CreatureHooks::RegisterOnAddToInstance(uint32 entry, CreatureHook<Creature*> callback) {
(*_OnAddToInstanceHandlers)[entry].push_back(callback);
}
// Call health events if the creature's health is at or below the percentage
// void CheckHealthEvents(Creature* creature) {
// uint32 entry = creature->GetEntry();
// uint32 currentHealthPct = creature->GetHealthPct();
// if (_healthPercentEvents->contains(entry)) {
// for (const auto& [percent, callbacks] : _healthPercentEvents->at(entry)) {
// if (currentHealthPct <= percent) {
// for (auto& callback : callbacks) {
// callback(creature); // Trigger custom behavior
// }
// }
// }
// }
// }
void CreatureHooks::JustDied(Creature* creature, Unit* killer) {
if(!creature) {
MpLogger::debug("JustDied() called with nullptr for creature");
return;
}
if(!killer) {
MpLogger::debug("JustDied() called with nullptr for killer");
return;
}
uint32 entry = creature->GetEntry();
if (_JustDiedHandlers->contains(entry)) {
for (auto& callback : _JustDiedHandlers->at(entry)) {
MpLogger::debug("JustDied() called for creature: {}", entry);
callback(creature, killer);
}
}
}
void CreatureHooks::JustSpawned(Creature* creature) {
if(!creature) {
MpLogger::debug("JustSpawned() called with nullptr for creature");
return;
}
uint32 entry = creature->GetEntry();
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
if(instanceData) {
sMythicPlus->AddScaledCreature(creature, instanceData);
}
if (_OnSpawnHandlers->contains(entry)) {
for (auto& callback : _OnSpawnHandlers->at(entry)) {
callback(creature);
MpLogger::debug("JustSpawned() called in CreatureHook: {}", entry);
}
}
}
void CreatureHooks::AddToInstance(Creature* creature) {
uint32 entry = creature->GetEntry();
if (_OnAddToInstanceHandlers->contains(entry)) {
for (auto& callback : _OnAddToInstanceHandlers->at(entry)) {
callback(creature);
MpLogger::debug("AddedToInstance() called in CreatureHook: {}", entry);
}
}
}

View File

@@ -0,0 +1,92 @@
#ifndef CREATUREHOOKS_H
#define CREATUREHOOKS_H
#include <functional>
#include <unordered_map>
#include <vector>
#include <memory>
#include "Creature.h"
#include "ObjectGuid.h"
// Struct to store the state of which handlers have been fired for a creature
struct CreatureEventState {
bool onDeathEventFired = false;
bool onSpawnEventFired = false;
bool onAddedToInstanceEventFired = false;
uint8 deaths = 0; // Count of deaths
};
// Type aliases for creature event handling
// using CreatureHook = std::function<void(Creature*)>;
// using HookList = std::vector<CreatureHook>;
// using HandlerMap = std::unordered_map<uint32, HookList>;
// Type alias for variadic event hooks
template<typename... Args>
using CreatureHook = std::function<void(Args...)>;
// Type alias for a list of hooks that take varying arguments
template<typename... Args>
using HandlersList = std::vector<CreatureHook<Args...>>;
// HandlerMap using variadic templates
template<typename... Args>
using HandlerMap = std::unordered_map<uint32, HandlersList<Args...>>;
using CreatureEventStateMap = std::map<ObjectGuid, CreatureEventState>;
class CreatureHooks {
private:
CreatureHooks():
_OnSpawnHandlers(std::make_unique<HandlerMap<Creature*>>()),
_JustDiedHandlers(std::make_unique<HandlerMap<Creature*, Unit*>>()),
_OnAddToInstanceHandlers(std::make_unique<HandlerMap<Creature*>>()),
_eventStates(std::make_unique<CreatureEventStateMap>())
{
_OnSpawnHandlers->reserve(128);
_JustDiedHandlers->reserve(128);
_OnAddToInstanceHandlers->reserve(100);
}
~CreatureHooks() {
_OnSpawnHandlers->clear();
_JustDiedHandlers->clear();
_OnAddToInstanceHandlers->clear();
_eventStates->clear();
}
// ensure we only ever have one instance of this class
CreatureHooks(const CreatureHooks&) = delete;
CreatureHooks& operator=(const CreatureHooks&) = delete;
// Data members for storing event handlers
std::unique_ptr<HandlerMap<Creature*>> _OnSpawnHandlers;
std::unique_ptr<HandlerMap<Creature*, Unit*>> _JustDiedHandlers;
std::unique_ptr<HandlerMap<Creature*>> _OnAddToInstanceHandlers;
// Tracks state to know which handlers need to be fired again
std::unique_ptr<CreatureEventStateMap> _eventStates;
public:
static CreatureHooks* instance() {
static CreatureHooks instance;
return &instance;
}
// Register events for specific actions
void RegisterJustDied(uint32 entry, CreatureHook<Creature*, Unit*> callback);
void RegisterOnSpawn(uint32 entry, CreatureHook<Creature*> callback);
void RegisterOnAddToInstance(uint32 entry, CreatureHook<Creature*> callback);
// Event triggers
void JustDied(Creature* creature, Unit* killer);
void JustSpawned(Creature* creature);
void AddToInstance(Creature* creature);
};
#define sCreatureHooks CreatureHooks::instance()
#endif // CREATUREHOOKS_H

View File

@@ -0,0 +1,32 @@
// #include "MpDataStore.h"
// #include "MpLogger.h"
// class CreatureOverride {
// public:
// uint32 entry;
// MpDifficulty difficulty;
// Creature* creature;
// CreatureOverride(uint32 entry): entry(entry), difficulty(difficulty) {
// sMpDataStore->AddCreatureOverride(this->entry, this);
// }
// virtual void Modify(Creature* creature) final {
// this->creature = creature;
// }
// virtual void HandleModify() = 0;
// void ModifyAttackPower(uint32 ap) {
// if(this)
// }
// void ModifyHealth(uint32 health) {}
// void ModifyArmor(uint32 armor) {}
// void ModifySpellPower(uint32 sp) {}
// ~CreatureOverride() {}
// };

View File

@@ -0,0 +1,48 @@
#include "MpClientDispatcher.h"
#include "MpEventProcessor.h"
#include "Player.h"
#include "MpLogger.h"
#include "Chat.h"
#include "WorldPacket.h"
#include <string_view>
#include <string>
/**
* In order to allow communication from client UIs without modifying mod-eluna directly to support
* This sends a packet directly using the AddOn message channel in the background.
*/
bool MpClientDispatcher::Dispatch(MpClientEvent event, Player* player, std::vector<std::string>& args)
{
if(!MpClientEventNames.contains(event)) {
MpLogger::warn("No event registered for event: {}", event);
return false;
}
// Build the message string in same format to send to the client.
std::string_view eventName = MpClientEventNames.at(event);
uint32 playerGuid = player->GetGUID().GetCounter();
std::string message = "s|" + std::to_string(playerGuid) + "|" + std::string(eventName);
for(auto& arg : args) {
message += "|" + arg;
}
std::string prefix = std::string(MP_DATA_CHAT_CHANNEL);
std::string fullmsg = prefix + "\t" + message;
MpLogger::debug("Dispatching client event: {} length {} for event {}", fullmsg, fullmsg.length(), std::string(eventName));
WorldPacket data(SMSG_MESSAGECHAT, 100);
data << uint8(ChatMsg::CHAT_MSG_WHISPER);
data << int32(LANG_ADDON);
data << player->GetGUID();
data << uint32(0);
data << player->GetGUID();
data << uint32(fullmsg.length() + 1);
data << fullmsg;
data << uint8(0);
player->GetSession()->SendPacket(&data);
return true;
}

View File

@@ -0,0 +1,35 @@
#ifndef MYTHIC_PLUS_CLIENT_DISPATCHER_H
#define MYTHIC_PLUS_CLIENT_DISPATCHER_H
#include "MpEvent.h"
#include "Player.h"
#include <string>
#include <string_view>
#include <vector>
class MpClientDispatcher
{
public:
static MpClientDispatcher* instance() {
static MpClientDispatcher instance;
return &instance;
}
MpClientDispatcher(const MpClientDispatcher&) = delete;
MpClientDispatcher& operator=(const MpClientDispatcher&) = delete;
// encode and send a message to the client for an event in the map
bool Dispatch(MpClientEvent event, Player* player, std::vector<std::string>& args);
private:
MpClientDispatcher() {};
~MpClientDispatcher() {};
};
#define sMpClientDispatcher MpClientDispatcher::instance()
#endif

51
src/Event/MpEvent.h Normal file
View File

@@ -0,0 +1,51 @@
#include <array>
#include <string_view>
#include <string>
#include <unordered_map>
#ifndef MP_EVENTS_H
#define MP_EVENTS_H
// This defines list of incoming events typically from the client
enum class MpEvent
{
None, // Default catch all for no event
Invalid, // Used to capture identify error events
UpgradeAdvancement, // Upgrades a player advancement 1 level
ResetAdvancement, // Resets a player Advancement back to 0
ResetAllAdvancements, // Resets all player advancements
GetPlayerRank, // Get the rank requirements for an advancement to the next levels
GetAdvancementRank // Get the details about the rank of a specific advancement (cost, bonus, etc)
};
// Client events that are communicated to the over an addon message to the player client
enum class MpClientEvent
{
Error,
UpgradeAdvancement,
ResetAdvancement,
ResetAllAdvancements,
GetPlayerRank,
GetAdvancementRank
};
// Mapping of Event Strings to EventNames for Event Callbacks from client
inline std::unordered_map<std::string_view, MpEvent> MpEventMap = {{
{"UpgradeAdvancement", MpEvent::UpgradeAdvancement},
{"ResetAdvancement", MpEvent::ResetAdvancement},
{"ResetAllAdvancements", MpEvent::ResetAllAdvancements},
{"GetPlayerRank", MpEvent::GetPlayerRank},
{"GetAdvancementRank", MpEvent::GetAdvancementRank}
}};
inline std::unordered_map<MpClientEvent, std::string_view> MpClientEventNames = {{
{MpClientEvent::Error, "Error"},
{MpClientEvent::UpgradeAdvancement, "UpgradeAdvancement"},
{MpClientEvent::ResetAdvancement, "ResetAdvancement"},
{MpClientEvent::ResetAllAdvancements, "ResetAllAdvancements"},
{MpClientEvent::GetPlayerRank, "GetPlayerRank"},
{MpClientEvent::GetAdvancementRank, "GetAdvancementRank"}
}};
#endif

View File

@@ -0,0 +1,281 @@
#include "MpEvent.h"
#include "MpLogger.h"
#include "../AdvancementMgr.h"
#include "MpEventProcessor.h"
#include "MpClientDispatcher.h"
#include "Player.h"
#include <string>
/**
* All handlers for passed between client and server handlers are managed
* here.
*/
/**
* Handles Updates to a players advancement system
* Event format
*/
enum class MP_EVENT_CODE
{
SUCCESS = 0,
// Message Errors
INVALID_EVENT = 100,
INVALID_ARGUMENT_SIZE = 201,
INVALID_ARGUMENT = 202,
INVALID_ARGUMENT_TYPE = 203,
// Game Response Codes
FAILED_UPGRADE_ADV = 300,
// Unknown Error
UNKNOWN_ERROR = 400,
NO_HANDLER = 401
};
std::string EventCodeToString(MP_EVENT_CODE code)
{
switch(code) {
case MP_EVENT_CODE::SUCCESS: return "Success";
case MP_EVENT_CODE::INVALID_EVENT: return "Invalid event";
case MP_EVENT_CODE::INVALID_ARGUMENT_SIZE: return "Invalid argument size";
case MP_EVENT_CODE::INVALID_ARGUMENT: return "Invalid argument";
case MP_EVENT_CODE::INVALID_ARGUMENT_TYPE: return "Invalid argument type";
case MP_EVENT_CODE::FAILED_UPGRADE_ADV: return "Failed to upgrade advancement";
case MP_EVENT_CODE::NO_HANDLER: return "No handler for event";
default: return "Unknown error";
}
}
// Send an error event to the client
bool SendEventError(Player* player, const std::string& /* method*/, MP_EVENT_CODE code, std::string message)
{
std::vector<std::string> clientError = { std::to_string(static_cast<int>(code)), message };
MpLogger::error("(Event Processor) Sending client error: {} {}", code, message);
sMpClientDispatcher->Dispatch(MpClientEvent::Error, player, clientError);
return false;
}
/**
* Upgrade a Player Advancement
* Message Format:
* p|playerGuid|UpgradeAdvancement|advancementId|diceLevel|itemEntry1|itemEntry2|itemEntry3
*/
class UpgradeAdvancements : public MpEventInterface
{
public:
const std::string EventName() const override
{
return "UpgradeAdvancement";
}
bool Execute(Player* player, std::vector<std::string>& args) override
{
// Store the event data to send back to the client for parsing
std::vector<std::string> eventData;
std::string eventName = EventName();
MpLogger::info("(EventProcessor) Executing {}", eventName.c_str());
for(auto& arg : args) {
MpLogger::info("{} Arg: {}", EventName(), arg);
}
// Validate the message is in the right format
if(args.size() != 2) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT_SIZE, "Invalid number of arguments expected 2, found " + std::to_string(args.size()));
}
uint32 advancementId, diceLevel;
try {
advancementId = std::stoi(args[0]);
} catch (const std::exception& e) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid advancement id format: " + args[0]);
}
if(advancementId >= MpAdvancements::MP_ADV_MAX) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid advancement id " + args[0] + " max valid id is " + std::to_string(MpAdvancements::MP_ADV_MAX - 1));
}
try {
diceLevel = std::stoi(args[1]);
} catch (const std::exception& e) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid dice level format: " + args[1]);
}
if(diceLevel < 1 || diceLevel > 3) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid dice level " + args[1] + " valid values are 1,2,3");
}
uint32 increase;
try {
increase = sAdvancementMgr->UpgradeAdvancement(player, static_cast<MpAdvancements>(advancementId), diceLevel);
if(increase == 0) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT, "Failed to upgrade advancement invalid request see error logs for player " + player->GetName());
}
} catch(const std::exception& e) {
return SendEventError(player, EventName(), MP_EVENT_CODE::FAILED_UPGRADE_ADV, "Failed to upgrade: " + std::string(e.what()) + " for player " + player->GetName());
}
// Only proceed to here if no errors occurred
MpPlayerRank* playerRank = sAdvancementMgr->GetPlayerAdvancementRank(player, static_cast<MpAdvancements>(advancementId));
if (!playerRank) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT, "Failed to get advancement rank for player " + player->GetName());
}
// Format the success event data for client increase|newrank|bonus
eventData = {
EventCodeToString(MP_EVENT_CODE::SUCCESS),
std::to_string(increase),
std::to_string(playerRank->rank),
std::to_string(playerRank->bonus)
};
// Send response back to the client
sMpClientDispatcher->Dispatch(MpClientEvent::UpgradeAdvancement, player, eventData);
return true;
}
};
/**
* @brief Event is used to get the rank requirements for an advancement to the next levels
*
* Message Format:
* p|playerGuid|GetPlayerRank|advancementId
*
* Returns:
* p|playerGuid|GetPlayerRank|rank|bonus|spentDice
*/
class GetPlayerRank : public MpEventInterface
{
public:
const std::string EventName() const override
{
return "GetPlayerRank";
}
bool Execute(Player* player, std::vector<std::string>& args) override
{
// Store the event data to send back to the client for parsing
std::vector<std::string> eventData;
MpLogger::info("(EventProcessor) Executing {}}", EventName());
for(auto& arg : args) {
MpLogger::info("{} Arg: {}", EventName(), arg);
}
// Validate the message is int he right format
if(args.size() != 1) {
return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT_SIZE, "Invalid number of arguments expected 1, found " + std::to_string(args.size()));
}
uint32 advancementId;
try {
advancementId = std::stoi(args[0]);
} catch (const std::exception& e) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid advancement id format: " + args[0]);
}
if(advancementId >= MpAdvancements::MP_ADV_MAX) {
return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid advancement id " + args[0] + " max valid id is " + std::to_string(MpAdvancements::MP_ADV_MAX - 1));
}
MpPlayerRank* playerRank = sAdvancementMgr->GetPlayerAdvancementRank(player, static_cast<MpAdvancements>(advancementId));
if(!playerRank) {
return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Failed to get advancement rank for player " + player->GetName());
}
eventData = {
EventCodeToString(MP_EVENT_CODE::SUCCESS),
std::to_string(playerRank->rank),
std::to_string(playerRank->bonus),
std::to_string(playerRank->diceSpent)
};
// Send response back to the client
sMpClientDispatcher->Dispatch(MpClientEvent::GetPlayerRank, player, eventData);
return true;
}
};
/**
* @brief Event is used to get the rank requirements for an advancement to the next levels
*
* Message Format:
* p|playerGuid|GetAdvancmentRank|advancementId|rank
*
* Returns:
* p|playerGuid|GetAdvancementRank|advancementId|rank|min1|max1|min2|max2|min3|max3|itemEntry1|itemEntryCost1|itemEntry2|itemEntryCost2|itemEntry3|itemEntryCost3
*/
class GetAdvancementRank : public MpEventInterface {
public:
const std::string EventName() const override
{
return "GetAdvancementRank";
}
bool Execute(Player* player, std::vector<std::string>& args) override
{
if(args.size() != 2) {
return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT_SIZE, "Invalid number of arguments expected 2, found " + std::to_string(args.size()));
}
uint32 advancementId, rank;
try {
advancementId = std::stoi(args[0]);
} catch (const std::exception& e) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid advancement id format: " + args[0]);
}
if(advancementId >= MpAdvancements::MP_ADV_MAX) {
return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid advancement id " + args[0] + " max valid id is " + std::to_string(MpAdvancements::MP_ADV_MAX - 1));
}
try {
rank = std::stoi(args[1]);
} catch (const std::exception& e) {
return SendEventError(player, EventName(), MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid rank format: " + args[1]);
}
if(rank == 0) {
return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Invalid rank " + args[1] + " can not be empty");
}
MpAdvancementRank* advRank = sAdvancementMgr->GetAdvancementRank(rank, static_cast<MpAdvancements>(advancementId));
if(!advRank) {
return SendEventError(player, EventName(),MP_EVENT_CODE::INVALID_ARGUMENT, "Failed to get advancement rank for player " + player->GetName());
}
std::vector<std::string> eventData = {
EventCodeToString(MP_EVENT_CODE::SUCCESS),
std::to_string(advRank->advancementId),
std::to_string(advRank->rank),
std::to_string(advRank->lowRange.first),
std::to_string(advRank->lowRange.second),
std::to_string(advRank->midRange.first),
std::to_string(advRank->midRange.second),
std::to_string(advRank->highRange.first),
std::to_string(advRank->highRange.second),
std::to_string(advRank->material1.first),
std::to_string(advRank->material1.second),
std::to_string(advRank->material2.first),
std::to_string(advRank->material2.second),
std::to_string(advRank->material3.first),
std::to_string(advRank->material3.second)
};
// Send response back to the client
sMpClientDispatcher->Dispatch(MpClientEvent::GetAdvancementRank, player, eventData);
return true;
}
};
void MP_Register_EventHandlers()
{
sMpEventProcessor->RegisterHandler(MpEvent::UpgradeAdvancement, std::make_shared<UpgradeAdvancements>());
sMpEventProcessor->RegisterHandler(MpEvent::GetPlayerRank, std::make_shared<GetPlayerRank>());
sMpEventProcessor->RegisterHandler(MpEvent::GetAdvancementRank, std::make_shared<GetAdvancementRank>());
}

View File

@@ -0,0 +1,136 @@
#include "MpEventProcessor.h"
#include "MythicPlus.h"
#include "MpLogger.h"
#include "MpClientDispatcher.h"
#include "Player.h"
#include <boost/algorithm/string/replace.hpp>
#include <string_view>
#include <string>
#include <vector>
bool MpEventProcessor::ProcessMessage(Player* player, const std::string& msg) {
if(!player) {
MpLogger::error("Null player passed to processMessage");
return false;
}
// check prefix of message channel is formatted correctly
if(! msg.starts_with(MP_DATA_CHAT_CHANNEL)) {
MpLogger::error("Invalid message format received from player {} message: {}", player->GetName(), msg);
return false;
}
std::string message = msg;
// shift the message identifier off the front including first '|' character
message.erase(0, MP_DATA_CHAT_CHANNEL.size()+1);
// clean up the message before passing it to the parser
boost::replace_all(message, "||", "|");
EventParseRslt result = _parsePlayerMessage(player, message);
MpEvent event = std::get<0>(result);
uint32 guid = std::get<1>(result);
std::vector<std::string> args = std::get<2>(result);
MpLogger::info("MpEvent Processor - event: {} guid: {} args: {}", event, guid, args.size());
// If th message was not able to be parsed it is a failure
if(event == MpEvent::Invalid) {
MpLogger::warn("Invalid event, could not be parsed for player {} message: {}", player->GetName(), message);
return false;
}
// if the message is not from the same player who called it ignore it as it is attempt to hack the system
if(player->GetGUID().GetCounter() != guid) {
MpLogger::warn("Player {} sent a message {} for eventId: {} player guid does not match", player->GetName(), message, event);
return false;
}
// If the event is not registered ignore it
if(!_eventHandlers.contains(event)) {
MpLogger::info("No handler registered for event: {}", event);
return false;
}
return Dispatch(event, player, args);
}
void MpEventProcessor::RegisterHandler(MpEvent event, std::shared_ptr<MpEventInterface> handler) {
_eventHandlers[event] = handler;
}
// This fires the execution to the actual event.
bool MpEventProcessor::Dispatch(MpEvent event, Player* player, std::vector<std::string>& args) {
if(!_eventHandlers.contains(event)) {
// Send a client message back also to the player
std::vector<std::string> clientError = { "Error", "No handler registered for event: " + std::to_string(static_cast<int>(event)) };
sMpClientDispatcher->Dispatch(MpClientEvent::Error, player, clientError);
MpLogger::warn("No handler registered for event: {}", event);
return false;
}
return _eventHandlers[event]->Execute(player, args);
}
// Find our eventId using the string name
MpEvent MpEventProcessor::_getEventByName(std::string_view eventName)
{
auto it = MpEventMap.find(eventName);
return (it != MpEventMap.end()) ? it->second : MpEvent::None;
}
/**
* Parse the incoming message into id, event, and handler arguments
*/
EventParseRslt MpEventProcessor::_parsePlayerMessage(Player* player, const std::string& msg)
{
if(msg[0] != 'p') {
MpLogger::warn("Invalid player message format received from player {} message: {}", player->GetName(), msg);
return EventParseRslt{MpEvent::Invalid, 0, {}};
}
std::vector<std::string> handlerArgs;
char delimiter = '|';
// split the protocol into valid parts
std::vector<std::string> parts = _splitString(msg, delimiter);
if (parts.size() < 3) {
MpLogger::warn("Malformed player message received from player {}: {}", player->GetName(), msg);
return EventParseRslt{MpEvent::Invalid, 0, {}};
}
MpEvent event = _getEventByName(parts[2]);
handlerArgs.assign(parts.begin() + 3, parts.end());
MpLogger::info("Player {} sent a client event message {} for event: {} eventId: {} ", player->GetName(), msg, MP_DATA_CHAT_CHANNEL, parts[2], event);
return EventParseRslt{event, player->GetGUID().GetCounter(), std::move(handlerArgs)};
}
// Split the string passed in by delimiters
std::vector<std::string> MpEventProcessor::_splitString(const std::string& s, char delimiter) {
std::vector<std::string> tokens;
size_t start = 0;
size_t end = s.find(delimiter);
while (end != std::string::npos) {
if (end != start) {
tokens.emplace_back(s.substr(start, end - start));
}
start = end + 1;
end = s.find(delimiter, start);
}
// Add the last token if it's not empty
if (start < s.length()) {
tokens.emplace_back(s.substr(start));
}
return tokens;
}

View File

@@ -0,0 +1,86 @@
#ifndef MYTHIC_PLUS_EVENT_PROCESSOR_H
#define MYTHIC_PLUS_EVENT_PROCESSOR_H
#include "MpEvent.h"
#include "Player.h"
#include <string>
#include <string_view>
#include <vector>
/**
* In order to allow communication from client UIs without modifying mod-eluna directly to support
* this mods functionality the following custom chat channel below is for all MP UI Client interactions.
*
* p|playerGuid|action|input1|input2|input3...
*/
inline const std::string_view MP_DATA_CHAT_CHANNEL = "MPUi";
/**
* Interface for all Mythic+ Event communication between client and server
*/
class MpEventInterface
{
public:
MpEventInterface() = default;
virtual ~MpEventInterface() = default;
[[nodiscard]] virtual bool Execute(Player* player, std::vector<std::string>& args) = 0;
[[nodiscard]] virtual const std::string EventName() const = 0;
};
using EventParseRslt = std::tuple<MpEvent, uint32_t, std::vector<std::string>>;
/**
* This class is responsible for processing events that are send from the client. Events
* are processed FIFO and executed. This is specifically to allow AddOn or AIO
* communication to this module without requiring additional changes to mod-eluna or the core.
*
* Message Body Format
* Client Player Events
* - p|playerGuid|action|input1|input2|input3...
* i.e) p|5793|UpgradeAdvancement|0|10|2
*/
class MpEventProcessor
{
public:
static MpEventProcessor* instance() {
static MpEventProcessor instance;
return &instance;
}
MpEventProcessor(const MpEventProcessor&) = delete;
MpEventProcessor& operator=(const MpEventProcessor&) = delete;
// Process a message from a specific player
bool ProcessMessage(Player* player, const std::string& msg);
// Registers a handler for a valid MpEvent specified in the MpEvent enum
// In this design Event:Handler is 1:1
void RegisterHandler(MpEvent event, std::shared_ptr<MpEventInterface> handler);
// Dispatch will execute the event handler
bool Dispatch(MpEvent event, Player* player, std::vector<std::string>& args);
private:
MpEventProcessor() {}
~MpEventProcessor() {}
// List of registered handlers for event management
std::unordered_map<MpEvent, std::shared_ptr<MpEventInterface>> _eventHandlers;
// Get the correct Event associated to handlers by the message strong
MpEvent _getEventByName(std::string_view eventName);
// Parse a message from the player
EventParseRslt _parsePlayerMessage(Player* player, const std::string& msg);
// Helper to break up a string into pieces used in parsing the message
std::vector<std::string> _splitString(const std::string& s, char delimiter = '|');
};
#define sMpEventProcessor MpEventProcessor::instance()
#endif // MYTHIC_PLUS_EVENT_PROCESSOR_H

View File

@@ -1,31 +0,0 @@
#include "MythicPlus.h"
#include "ScriptMgr.h"
class MythicPlus_GlobalScript : public GlobalScript
{
public:
MythicPlus_GlobalScript() : GlobalScript("MythicPlus_GlobalScript") { }
void OnAfterUpdateEncounterState(Map* map, EncounterCreditType type, uint32 /*creditEntry*/, Unit* /*source*/, Difficulty /*difficulty_fixed*/, DungeonEncounterList const* /*encounters*/, uint32 /*dungeonCompleted*/, bool updated) override
{
}
/**
* This is used to provide better rewards to players when they complete a dungeon.
* The rewards are scaled up versions of the original drop.
* @brief Called after a player has looted an item from a creature.
*/
void OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store) override
{
}
};
void AddGlobalScripts()
{
new MythicPlus_GlobalScript();
}

View File

@@ -1,34 +0,0 @@
#include "ScriptMgr.h"
#include "MythicPlus.h"
// this handles updating custom group difficulties used in auto balancing mobs and
// scripts that enable buffs on mobs randomly
class MythicPlus_GroupScript : public GroupScript
{
public:
MythicPlus_GroupScript() : GroupScript("MythicPlus_GroupScript") { }
void OnCreate(Group* group, Player* leader) override {
if (!group) {
return;
}
if(!leader) {
return;
}
}
void OnDisband(Group* group) override {
if (!group) {
return;
}
}
};
void AddGroupScripts()
{
new MythicPlus_GroupScript();
}

View File

@@ -0,0 +1,26 @@
// #include "BaseCreatureHandler.h"
// #include "Spell.h"
// /**
// * Bazzalan need some upgrades so made him more formidable
// */
// class Ragefire_Bazzalan_Mythic : public BaseCreatureHandler
// {
// public:
// Ragefire_Bazzalan_Mythic() : BaseCreatureHandler(11519) {}
// void OnAddToInstance(Creature* creature) override {
// uint32 health = creature->GetMaxHealth() * 2;
// creature->SetCreateHealth(health);
// creature->SetMaxHealth(health);
// creature->SetHealth(health);
// creature->ResetPlayerDamageReq();
// creature->SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
// creature->AddExtraAttacks(3);
// creature->SetObjectScale(2.0f);
// }
// };

112
src/MpConstants.h Normal file
View File

@@ -0,0 +1,112 @@
#ifndef MP_CONSTANTS_H
#define MP_CONSTANTS_H
#include "AdvancementMgr.h"
namespace MpConstants
{
// Spell IDs for passive stat and resist bonuses
constexpr int TITANS_STRENGTH_AURA = 80000001; // strength
constexpr int STEEL_FORGED_AURA = 80000002; // stamina
constexpr int CELESTIAL_GRACE_AURA = 80000003; // spirit
constexpr int FORBIDDEN_KNOWLEDGE_AURA = 80000004; // intellect
constexpr int SPECTRAL_REFLEXES_AURA = 80000005; // agility
constexpr int ELDRITCH_BARRIER_AURA = 80000006; // arcane resistance
constexpr int HELLFIRE_SHIELDING_AURA = 80000007; // fire resistance
constexpr int PRIMAL_ENDURACE_AURA = 80000008; // nature resistance
constexpr int LICHS_BANE_AURA = 80000009; // shadow resistance
constexpr int GLACIAL_FORTRESS_AURA = 80000010; // frost resistance
/**
* @brief Adds a static method for looking up the corect advancement aura based on the advancement type.
*
* @param advancement
* @return int
*/
static int GetAdvancementAura(MpAdvancements advancement)
{
switch (advancement)
{
case MpAdvancements::MP_ADV_INTELLECT:
return MpConstants::FORBIDDEN_KNOWLEDGE_AURA;
case MpAdvancements::MP_ADV_SPIRIT:
return MpConstants::CELESTIAL_GRACE_AURA;
case MpAdvancements::MP_ADV_STRENGTH:
return MpConstants::TITANS_STRENGTH_AURA;
case MpAdvancements::MP_ADV_AGILITY:
return MpConstants::SPECTRAL_REFLEXES_AURA;
case MpAdvancements::MP_ADV_STAMINA:
return MpConstants::STEEL_FORGED_AURA;
case MpAdvancements::MP_ADV_RESIST_ARCANE:
return MpConstants::ELDRITCH_BARRIER_AURA;
case MpAdvancements::MP_ADV_RESIST_FIRE:
return MpConstants::HELLFIRE_SHIELDING_AURA;
case MpAdvancements::MP_ADV_RESIST_NATURE:
return MpConstants::PRIMAL_ENDURACE_AURA;
case MpAdvancements::MP_ADV_RESIST_FROST:
return MpConstants::GLACIAL_FORTRESS_AURA;
case MpAdvancements::MP_ADV_RESIST_SHADOW:
return MpConstants::LICHS_BANE_AURA;
default:
return 0;
}
}
// Spells used for learning how to make items used for advancement.
constexpr int SPELL_ORE_FUSION = 150000;
constexpr int SPELL_CLOTH_FUSION = 150001;
constexpr int SPELL_LEATHER_FUSION = 150002;
constexpr int SPELL_ALCHEMY_FUSION = 150003;
constexpr int SPELL_GEM_FUSION = 150004;
constexpr int SPELL_ESSENCE_FUSION = 150005;
constexpr int SPELL_COLD_FUSION = 150006;
constexpr int SPELL_FLAME_FUSION = 150007;
constexpr int SPELL_ARCANE_FUSION = 150008;
constexpr int SPELL_DARK_FUSION = 150009;
constexpr int SPELL_EARTH_FUSION = 150010;
constexpr int SPELL_ORE_FUSION_RANK_2 = 150011;
constexpr int SPELL_CLOTH_FUSION_RANK_2 = 150012;
constexpr int SPELL_LEATHER_FUSION_RANK_2 = 150013;
constexpr int SPELL_ALCHEMY_FUSION_RANK_2 = 150014;
constexpr int SPELL_GEM_FUSION_RANK_2 = 150015;
constexpr int SPELL_ESSENCE_FUSION_RANK_2 = 150016;
constexpr int SPELL_COLD_FUSION_RANK_2 = 150017;
constexpr int SPELL_FLAME_FUSION_RANK_2 = 150018;
constexpr int SPELL_ARCANE_FUSION_RANK_2 = 150019;
constexpr int SPELL_DARK_FUSION_RANK_2 = 150020;
constexpr int SPELL_EARTH_FUSION_RANK_2 = 150021;
// New dropping unique items for mythic plus
constexpr int ANCIENT_DICE = 911000;
constexpr int DARK_SPIKE = 911001;
constexpr int VEILSTONE = 911002;
// Item IDs for fused materials used in advancement crafting
constexpr int FUSED_RARE_ORE = 911003;
constexpr int FUSED_MYTHIC_ORE = 911004;
constexpr int FUSED_RARE_CLOTH = 911005;
constexpr int FUSED_MYTHIC_CLOTH = 911006;
constexpr int FUSED_RARE_LEATHER = 911007;
constexpr int FUSED_MYTHIC_LEATHER = 911008;
constexpr int FUSED_RARE_ALCHEMY = 911009;
constexpr int FUSED_MYTHIC_ALCHEMY = 911010;
constexpr int FUSED_RARE_GEM = 911011;
constexpr int FUSED_MYTHIC_GEM = 911012;
constexpr int FUSED_RARE_ESSENCE = 911013;
constexpr int FUSED_MYTHIC_ESSENCE = 911014;
constexpr int FUSED_RARE_ICE_STONE = 911015;
constexpr int FUSED_MYTHIC_ICE_STONE = 911016;
constexpr int FUSED_RARE_INFERNAL_STONE = 911017;
constexpr int FUSED_MYTHIC_INFERNAL_STONE = 911018;
constexpr int FUSED_RARE_ARCANE_CRYSTAL = 911019;
constexpr int FUSED_MYTHIC_ARCANE_CRYSTAL = 911020;
constexpr int FUSED_RARE_DARK_CRYSTAL = 911021;
constexpr int FUSED_MYTHIC_DARK_CRYSTAL = 911022;
constexpr int FUSED_RARE_EARTH_STONE = 911023;
constexpr int FUSED_MYTHIC_EARTH_STONE = 911024;
// Shadowy Remains
constexpr int SHADOWY_REMAINS = 911100;
}
#endif

513
src/MpDataStore.cpp Normal file
View File

@@ -0,0 +1,513 @@
#include "CharacterDatabase.h"
#include "MpDataStore.h"
#include "Chat.h"
#include "Group.h"
#include "MpLogger.h"
#include "Chat.h"
// Adds an entry for the group difficult to memory and updats database
void MpDataStore::AddGroupData(Group *group, MpGroupData groupData) {
if(!group) {
MpLogger::error("AddGroupData called with null group pointer");
return;
}
ObjectGuid guid = group->GetGUID();
if (!guid) {
MpLogger::error("AddGroupData called with invalid group GUID");
return;
}
if (!groupData.difficulty) {
MpLogger::error("AddGroupData called with invalid difficulty");
return;
}
Player* leader = group->GetLeader();
if(!leader) {
MpLogger::error("AddGroupData called with null group leader");
return;
}
Map* map = leader->GetMap();
if (!map) {
MpLogger::error("AddGroupData called with null map for group leader");
return;
}
auto instance = map->ToInstanceMap();
// if we already have data override it
if (_groupData->contains(guid)) {
MpGroupData existingData = _groupData->at(guid);
if(groupData.difficulty == MP_DIFFICULTY_HEROIC || groupData.difficulty == MP_DIFFICULTY_NORMAL || groupData.difficulty != existingData.difficulty) {
// if we set a lower difficulty and we are in an instance we need to kick the group out and reset the instance.
if(instance && instance->HavePlayers()) {
instance->Reset(2); // 2 = reset all
const Map::PlayerList players = map->GetPlayers();
for (auto itr = players.begin(); itr != players.end(); ++itr) {
Player* player = itr->GetSource();
if(!player) {
MpLogger::error("AddGroupData called with null player in instance");
}
ChatHandler(player->GetSession()).SendNotification("The group leader has changed the difficulty setting. You have been removed from the instance.");
}
}
}
_groupData->at(guid) = groupData;
} else {
if(instance && instance->HavePlayers()) {
instance->Reset(2); // 2 = reset all
const Map::PlayerList players = map->GetPlayers();
for (auto itr = players.begin(); itr != players.end(); ++itr) {
Player* player = itr->GetSource();
if(!player) {
MpLogger::error("AddGroupData called with null player in instance");
}
ChatHandler(player->GetSession()).SendNotification("The group leader has changed the difficulty setting. You have been removed from the instance.");
}
}
_groupData->emplace(guid, groupData);
}
const Group::MemberSlotList members = group->GetMemberSlots();
for (const auto &memberSlot : members) {
Player* player = ObjectAccessor::FindPlayer(memberSlot.guid);
if (player) {
DBUpdatePlayerInstanceData(player->GetGUID(), groupData.difficulty);
}
}
}
MpGroupData* MpDataStore::GetGroupData(Group* group) {
if (auto it = _groupData->find(group->GetGUID()); it != _groupData->end()) {
return &(it->second);
}
return nullptr;
}
/**
* This keeps track of instance keys (mapId, instanceId) for a group this can be used to
* reset instance settings in the instanceData store when a difficulty is changed by the group leader.
*/
void MpDataStore::PushGroupInstanceKey(Group *group, uint32 mapId, uint32 instanceId) {
ObjectGuid guid = group->GetGUID();
if (!guid) {
MpLogger::error("PushGroupInstanceKey called with invalid group GUID");
return;
}
if (!mapId || !instanceId) {
MpLogger::error("PushGroupInstanceKey called with invalid mapId or instanceId");
return;
}
if (!_groupData->contains(guid)) {
MpLogger::error("PushGroupInstanceKey called with invalid group GUID");
return;
}
// Need to potentialy reset here?
}
// This clears out any group data from memory and the database
void MpDataStore::RemoveGroupData(Group *group) {
MpLogger::debug("RemoveGroupData for group {}", group->GetGUID().GetCounter());
_groupData->erase(group->GetGUID());
CharacterDatabase.Execute("DELETE FROM group_difficulty WHERE guid = {}", group->GetGUID().GetCounter());
}
// Adds PlayerData related to MythicRun Status to map
void MpDataStore::AddPlayerData(ObjectGuid guid, MpPlayerData* pd) {
_playerData->emplace(guid, pd);
}
void MpDataStore::RemovePlayerData(ObjectGuid guid) {
MpLogger::debug("RemovePlayerData for player {}", guid.GetCounter());
_playerData->erase(guid);
}
void MpDataStore::ResetPlayerData(ObjectGuid guid) {
MpLogger::debug("ResetPlayerData for player {}", guid.GetCounter());
_playerData->erase(guid);
}
void MpDataStore::AddInstanceData(uint32 mapId, uint32 instanceId, MpInstanceData instanceSettings) {
_instanceData->emplace(GetInstanceDataKey(mapId, instanceId), instanceSettings);
}
MpInstanceData* MpDataStore::GetInstanceData(uint32 mapId, uint32 instanceId) {
if (!_instanceData->contains(GetInstanceDataKey(mapId, instanceId))) {
return nullptr;
}
return &_instanceData->at(GetInstanceDataKey(mapId, instanceId));
}
void MpDataStore::RemoveInstanceData(uint32 mapId, uint32 instanceId) {
_instanceData->erase(GetInstanceDataKey(mapId, instanceId));
}
void MpDataStore::AddCreatureData(ObjectGuid guid, MpCreatureData creatureData) {
// MpLogger::debug("AddInstanceCreatureData for creature {}", guid.GetCounter());
_instanceCreatureData->insert_or_assign(guid, std::move(creatureData));
}
MpCreatureData* MpDataStore::GetCreatureData(ObjectGuid guid) {
if (!_instanceCreatureData->contains(guid)) {
return nullptr;
}
return &_instanceCreatureData->at(guid);
}
std::vector<MpCreatureData*> MpDataStore::GetInstanceCreatures(uint32 mapId, uint32 instanceId) {
std::vector<MpCreatureData*> creatures;
for (auto& [guid, creatureData] : *_instanceCreatureData) {
Creature* creature = creatureData.creature;
if (creature->GetMapId() == mapId && creature->GetInstanceId() == instanceId) {
creatures.push_back(&creatureData);
}
}
return creatures;
}
std::vector<MpCreatureData*> MpDataStore::GetUnscaledCreatures(uint32 mapId, uint32 instanceId) {
std::vector<MpCreatureData*> creatures;
for (auto& [guid, creatureData] : *_instanceCreatureData) {
Creature* creature = creatureData.creature;
if (creature->GetMapId() == mapId && creature->GetInstanceId() == instanceId && !creatureData.IsScaled()) {
creatures.push_back(&creatureData);
}
}
return creatures;
}
void MpDataStore::RemoveCreatureData(ObjectGuid guid) {
// MpLogger::debug("RemoveInstanceCreatureData data for creature {}", guid.GetCounter());
_instanceCreatureData->erase(guid);
}
MpScaleFactor MpDataStore::GetScaleFactor(int32 mapId, int32 difficulty) const {
auto key = GetScaleFactorKey(mapId, difficulty);
if (_scaleFactors->contains(key)) {
return _scaleFactors->at(key);
}
// Just send back untouched bonus database will override.
return MpScaleFactor{
.meleeBonus = 1.0f,
.spellBonus = 1.0f,
.healBonus = 1.0f,
.healthBonus = 1.0f
};
}
float MpDataStore::GetHealthScaleFactor(int32 mapId, int32 difficulty) const {
return GetScaleFactor(mapId, difficulty).healthBonus;
}
float MpDataStore::GetMeleeScaleFactor(int32 mapId, int32 difficulty) const {
return GetScaleFactor(mapId, difficulty).meleeBonus;
}
float MpDataStore::GetSpellScaleFactor(int32 mapId, int32 difficulty) const {
return GetScaleFactor(mapId, difficulty).spellBonus;
}
float MpDataStore::GetHealScaleFactor(int32 mapId, int32 difficulty) const {
return GetScaleFactor(mapId, difficulty).healBonus;
}
uint32 MpDataStore::GetPlayerHealthAvg(uint32 level) const {
if (_playerHealthAvg.contains(level)) {
return _playerHealthAvg.at(level);
}
return 0;
}
void MpDataStore::SetHealScaleFactor(int32 mapId, int32 difficulty, float newValue) {
auto key = GetScaleFactorKey(mapId, difficulty);
if (_scaleFactors && _scaleFactors->contains(key)) {
_scaleFactors->at(key).healBonus = newValue;
}
}
void MpDataStore::SetHealthScaleFactor(int32 mapId, int32 difficulty, float newValue) {
auto key = GetScaleFactorKey(mapId, difficulty);
if (_scaleFactors && _scaleFactors->contains(key)) {
_scaleFactors->at(key).healthBonus = newValue;
}
}
void MpDataStore::SetMeleeScaleFactor(int32 mapId, int32 difficulty, float newValue) {
auto key = GetScaleFactorKey(mapId, difficulty);
if (_scaleFactors && _scaleFactors->contains(key)) {
_scaleFactors->at(key).meleeBonus = newValue;
}
}
void MpDataStore::SetSpellScaleFactor(int32 mapId, int32 difficulty, float newValue) {
auto key = GetScaleFactorKey(mapId, difficulty);
if (_scaleFactors && _scaleFactors->contains(key)) {
_scaleFactors->at(key).spellBonus = newValue;
}
}
int32 MpDataStore::LoadScaleFactors() {
_scaleFactors->clear();
// 0 1 2 3 4 5
QueryResult result = WorldDatabase.Query("SELECT mapId, melee_bonus, spell_bonus, heal_bonus, hp_bonus, difficulty FROM mp_scale_factors");
if (!result) {
MpLogger::error("Failed to load mythic scale factors from database");
return 0;
}
do {
Field* fields = result->Fetch();
uint32 mapId = fields[0].Get<uint32>();
float meleeBonus = fields[1].Get<float>();
float spellBonus = fields[2].Get<float>();
float healBonus = fields[3].Get<float>();
float healthBonus = fields[4].Get<float>();
int32 difficulty = fields[5].Get<int32>();
MpScaleFactor scaleFactor = {
.meleeBonus = meleeBonus,
.spellBonus = spellBonus,
.healBonus = healBonus,
.healthBonus = healthBonus
};
_scaleFactors->emplace(GetScaleFactorKey(mapId, difficulty), scaleFactor);
} while (result->NextRow());
return int32(_scaleFactors->size());
}
void MpDataStore::LoadPlayerHealthAvg() {
_playerHealthAvg.clear();
std::string_view query = R"(
SELECT
Level,
ROUND(CASE
WHEN Level BETWEEN 1 AND 30 THEN ((AVG(Stamina) - 20) * 10 + AVG(BaseHP) + 20) * 1.5
WHEN Level BETWEEN 31 AND 50 THEN ((AVG(Stamina) - 20) * 10 + AVG(BaseHP) + 20) * 1.7
WHEN Level BETWEEN 51 AND 59 THEN ((AVG(Stamina) - 20) * 10 + AVG(BaseHP) + 20) * 2.0
WHEN Level BETWEEN 60 AND 69 THEN ((AVG(Stamina) - 20) * 10 + AVG(BaseHP) + 20) * 2.3
WHEN Level BETWEEN 70 AND 79 THEN ((AVG(Stamina) - 20) * 10 + AVG(BaseHP) + 20) * 2.6
WHEN Level BETWEEN 80 AND 84 THEN ((AVG(Stamina) - 20) * 10 + AVG(BaseHP) + 20) * 3.0
WHEN Level >= 85 THEN ((AVG(Stamina) - 20) * 10 + AVG(BaseHP) + 20) * 4.0
ELSE ((AVG(Stamina) - 20) * 10 + AVG(BaseHP) + 20)
END) AS BaseHealth
FROM
player_class_stats
GROUP BY
Level
ORDER BY
Level;
)";
if (QueryResult result = WorldDatabase.Query(query.data())) {
do {
Field* fields = result->Fetch();
uint32 level = fields[0].Get<uint32>();
uint32 baseHealth = fields[1].Get<uint32>();
_playerHealthAvg[level] = baseHealth;
} while (result->NextRow());
} else {
MpLogger::error("Failed to load player health averages from database");
}
}
/**
* Database Calls below for storing player data.
* @todo refactor to use prepared statements
*/
void MpDataStore::DBUpdatePlayerInstanceData(ObjectGuid playerGuid, MpDifficulty difficulty, uint32 mapId, uint32 instanceId, uint32 deaths) {
if (!playerGuid) {
MpLogger::error("DBAddPlayerData called with invalid playerData");
return;
}
CharacterDatabase.Execute("REPLACE INTO mp_player_instance_data (guid, difficulty, mapId, instanceId, deaths) VALUES ({},{},{},{},{}) ",
playerGuid.GetCounter(),
difficulty,
mapId,
instanceId,
deaths
);
}
void MpDataStore::DBResetPlayerDeaths(Player* player) {
if (!player) {
MpLogger::error("DBUpdateDeaths called with invalid playerId");
return;
}
CharacterDatabase.Execute("UPDATE mp_player_instance_data SET deaths = 0 WHERE guid = {} and mapId = {} and instanceId = {}",
player->GetGUID().GetCounter(),
player->GetMapId(),
player->GetInstanceId()
);
}
void MpDataStore::DBAddPlayerDeath(Player* player) {
if (!player) {
MpLogger::error("DBAddPlayerDeath called with invalid player");
return;
}
CharacterDatabase.Execute("UPDATE mp_player_instance_data SET deaths = deaths + 1 WHERE guid = {} and mapId = {} and instanceId = {}",
player->GetGUID().GetCounter(),
player->GetMapId(),
player->GetInstanceId()
);
}
// Logs death for player that occurs by a creature directly.
void MpDataStore::DBAddPlayerDeath(Player* player, Creature* creature, MpDifficulty difficulty) {
if (!player) {
MpLogger::error("DBAddPlayerDeath called with invalid player");
return;
}
CharacterDatabase.Execute("UPDATE mp_player_instance_data SET deaths = deaths + 1 WHERE guid = {} and mapId = {} and instanceId = {}",
player->GetGUID().GetCounter(),
player->GetMapId(),
player->GetInstanceId()
);
CharacterDatabase.Execute(
"INSERT INTO mp_player_death_stats (guid, creatureEntry, difficulty, numDeaths, lastUpdated) "
"VALUES ({}, {}, {}, 1, CURRENT_TIMESTAMP) "
"ON DUPLICATE KEY UPDATE numDeaths = numDeaths + 1, lastUpdated = CURRENT_TIMESTAMP",
player->GetGUID().GetCounter(),
creature->GetEntry(),
difficulty
);
}
void MpDataStore::DBUpdateGroupData(ObjectGuid groupGuid, MpDifficulty difficulty, uint32 mapId, uint32 instanceId, uint32 deaths) {
if (!groupGuid) {
MpLogger::error("DBUpdateGroupData called with invalid groupGuid");
return;
}
CharacterDatabase.Execute("REPLACE INTO mp_group_data (groupId, difficulty, mapId, instanceId, deaths) VALUES ({},{},{},{},{}) ",
groupGuid.GetCounter(),
difficulty,
mapId,
instanceId,
deaths
);
}
void MpDataStore::DBAddGroupDeath(Group* group, uint32 mapId, uint32 instanceId, MpDifficulty difficulty) {
if (!group) {
MpLogger::error("DBAddGroupDeath called with invalid group");
return;
}
if(!difficulty) {
MpLogger::error("DBAddGroupDeath called with invalid difficulty");
return;
}
if(!mapId || !instanceId) {
MpLogger::error("DBAddGroupDeath called with invalid mapId or instanceId");
return;
}
CharacterDatabase.Execute("UPDATE mp_group_data SET deaths = deaths + 1 WHERE groupId = {} and mapId = {} and instanceId = {} and difficulty = {}",
group->GetGUID().GetCounter(),
mapId,
instanceId,
difficulty
);
}
void MpDataStore::DBRemovePlayerData(ObjectGuid playerGuid) {
if (!playerGuid) {
MpLogger::error("DBRemovePlayerData called with invalid playerGuid");
return;
}
CharacterDatabase.Execute("DELETE FROM mp_player_instance_data WHERE guid = {} ", playerGuid.GetCounter());
}
void MpDataStore::DBRemovePlayerInstanceData(uint32 instanceId) {
if (!instanceId) {
MpLogger::error("DBRemovePlayerInstanceData: missing instanceId to remove player instance ");
return;
}
CharacterDatabase.Execute("DELETE FROM mp_player_instance_data WHERE instanceId = {} ", instanceId);
}
void MpDataStore::DBUpdateGroupTimerDeaths(ObjectGuid groupGuid, uint32 mapId, uint32 instanceId, uint32 timer, uint32 deaths) {
if (!groupGuid) {
MpLogger::error("DBUpdateGroupTimerDeaths called with invalid groupGuid");
return;
}
CharacterDatabase.Execute("REPLACE INTO mp_group_data (groupId, mapId, instanceId, instanceTimer, deaths) VALUES ({},{},{},{},{}) ",
groupGuid.GetCounter(),
mapId,
instanceId,
timer,
deaths
);
}
void MpDataStore::DBRemoveGroupData(ObjectGuid groupGuid) {
if (!groupGuid) {
MpLogger::error("DBRemoveGroupData called with invalid groupGuid");
return;
}
CharacterDatabase.Execute("DELETE FROM mp_group_data WHERE groupId = {} ", groupGuid.GetCounter());
}
// Remove instance data using the instanceId
void MpDataStore::DBRemoveGroupInstanceData(uint32 instanceId) {
if (!instanceId) {
MpLogger::error("DBRemoveGroupData called with invalid groupGuid");
return;
}
CharacterDatabase.Execute("DELETE FROM mp_group_data WHERE instanceId = {} ", instanceId);
}

450
src/MpDataStore.h Normal file
View File

@@ -0,0 +1,450 @@
#ifndef MYTHICPLUS_DATASTORE_H
#define MYTHICPLUS_DATASTORE_H
#include "Creature.h"
// #include "CreatureOverride.h"
#include "Group.h"
#include "MapMgr.h"
#include "Player.h"
#include "MpLogger.h"
#include "ObjectGuid.h"
#include <unordered_map>
#include <map>
#include <string>
#include <vector>
#include <memory>
enum MpDifficulty
{
MP_DIFFICULTY_NORMAL = 0,
MP_DIFFICULTY_HEROIC = 1,
MP_DIFFICULTY_EPIC = 2,
MP_DIFFICULTY_MYTHIC = 3,
MP_DIFFICULTY_LEGENDARY = 4,
MP_DIFFICULTY_ASCENDANT = 5
};
class MpDataStore;
struct MpPlayerInstanceData
{
uint32 deaths = 0;
};
// struct used to track player performance in an instance.
struct MpPlayerData
{
Player* player;
MpDifficulty difficulty;
uint32 groupId;
// list of maps and instance player is bound to and mythic data related to it
std::map<std::pair<uint32,uint32>,MpPlayerInstanceData> instanceData;
MpPlayerData(Player* p, MpDifficulty diff, uint32_t groupId)
: player(p), difficulty(diff), groupId(groupId) {
}
void AddDeath(uint32 mapId, uint32 instanceId) {
auto key = std::make_pair(mapId, instanceId);
if(instanceData.contains(key)) {
instanceData[key].deaths++;
} else {
instanceData[key] = MpPlayerInstanceData{.deaths = 1};
}
MpLogger::info("========= Player {} added death to instance data {}", player->GetName(), instanceData[key].deaths);
}
uint32 GetDeaths(uint32 mapId, uint32 instanceId) const {
auto key = std::make_pair(mapId, instanceId);
if(instanceData.contains(key)) {
return instanceData.at(key).deaths;
}
return 0;
}
void ResetDeathCount(uint32 mapId, uint32 instanceId) {
auto key = std::make_pair(mapId, instanceId);
if(instanceData.contains(key)) {
instanceData[key].deaths = 0;
}
}
void ResetAllDeathCounts() {
for(auto& [key, data] : instanceData) {
data.deaths = 0;
}
}
};
// Struct used to track entire group performance.
struct MpGroupData
{
Group* group;
MpDifficulty difficulty;
std::vector<MpPlayerData*> players;
MpGroupData() : group(nullptr), difficulty(MpDifficulty{}) {
players.reserve(5);
}
MpGroupData(Group* group, MpDifficulty difficulty)
: group(group), difficulty(difficulty) {
players.reserve(5);
}
uint32 GetDeaths(uint32 mapId, uint32 instanceId) const {
uint32 deaths = 0;
for (const MpPlayerData* player : players) {
deaths += player->GetDeaths(mapId, instanceId);
}
return deaths;
}
void ResetGroupDeaths(uint32 mapId, uint32 instanceId) {
for (MpPlayerData* player : players) {
player->ResetDeathCount(mapId, instanceId);
}
}
void AddPlayerData(MpPlayerData* playerData) {
// Check if the playerData is already in the vector
if (std::any_of(players.begin(), players.end(), [playerData](MpPlayerData* existingData) {
return existingData->player == playerData->player;
})) {
MpLogger::warn("PlayerData for player {} is already in the players vector", playerData->player->GetName());
return;
}
// Add playerData to the vector
players.push_back(playerData);
}
std::string ToString() const {
Map* map = group->GetLeader()->GetMap();
uint32 deaths = 0;
if(map) {
deaths = GetDeaths(map->GetId(), map->GetInstanceId());
}
return "MpGroupData: { group: " + std::to_string(group->GetGUID().GetCounter()) +
", difficulty: " + std::to_string(difficulty) +
", deaths: " + std::to_string(deaths) + " }";
}
};
/**
* @brief Struct used for internal scaling of mythic+ difficulty. Fine-tuned in
* database.
*/
struct MpScaleFactor
{
float meleeBonus;
float spellBonus;
float healBonus;
float healthBonus;
std::string ToString() const {
return "MpScaleFactor: { meleeBonus: " + std::to_string(meleeBonus) +
", healthBonus: " + std::to_string(healthBonus) +
", spellBonus: " + std::to_string(spellBonus) +
", healBonus: " + std::to_string(healBonus) + "}";
}
};
struct MpMultipliers
{
float health;
float melee;
float baseDamage;
float spell;
float armor;
uint8 avgLevel;
std::string ToString() const {
return "MpMultipliers: { health: " + std::to_string(health) +
", melee: " + std::to_string(melee) +
", melee: " + std::to_string(baseDamage) +
", spell: " + std::to_string(spell) +
", armor: " + std::to_string(armor) +
", avgLevel: " + std::to_string(avgLevel) + " }";
}
};
struct MpInstanceData
{
InstanceMap* instance;
MpDifficulty difficulty;
// Enemy data
MpMultipliers boss;
MpMultipliers creature;
// Instance Settings
bool itemRewards;
uint32 deathLimits;
uint32 itemOffset;
std::string ToString() const {
return "MpInstanceData: { " +
std::string("instance: ") + (instance ? "valid instance" : "nullptr") +
", boss: " + boss.ToString() +
", creature: " + creature.ToString() +
", itemRewards: " + (itemRewards ? "true" : "false") +
", deathLimits: " + std::to_string(deathLimits) +
", itemOffset: " + std::to_string(itemOffset) + " }";
}
};
/**
* Simple struct for managing information about creatures that
* are in a mythic+ instance.
*/
struct MpCreatureData
{
Creature* creature;
bool scaled;
DeathState lastDeathState; // used to determine if a creature has been respawned
// AttackPower calculated based on settings
uint32 NewAttackPower;
// New Scaling Multiplier based on database factors + level growth formula
float AttackPowerScaleMultiplier;
// Original information about the creature that was altered.
uint8 originalLevel;
uint32 originalInstanceHealth; // Health the creature would have in instance before Mythic+ scaling
CreatureBaseStats const* originalStats;
MpDifficulty difficulty;
// Custom difficulty modifiers to creatures at higher difficulties.
std::vector<uint32> auras;
std::vector<std::string> affixes;
MpCreatureData(Creature* creature)
: creature(creature), scaled(false), originalInstanceHealth(0)
{
if(creature) {
originalLevel = creature->GetLevel();
originalStats = sObjectMgr->GetCreatureBaseStats(
originalLevel,
creature->GetCreatureTemplate()->unit_class
);
originalInstanceHealth = creature->GetMaxHealth();
}
auras.reserve(3);
affixes.reserve(3);
}
void SetScaled(bool scaled) {
this->scaled = scaled;
}
void SetDifficulty(MpDifficulty difficulty) {
this->difficulty = difficulty;
}
bool IsScaled() {
return scaled;
}
std::string ToString() const {
std::string origStatsStr;
if(originalStats) {
uint32 health = originalInstanceHealth;
uint32 mana = originalStats->BaseMana;
uint32 armor = originalStats->BaseArmor;
uint32 ap = originalStats->AttackPower;
origStatsStr = "Original Stats: \n Health: " + std::to_string(health) + "\n" +
"Mana: " + std::to_string(mana) + "\n" +
"Armor: " + std::to_string(armor) + "\n" +
"Attack Power: " + std::to_string(ap) + "\n";
} else {
origStatsStr = "Original Stats Display Failed: \n Did you select target or in an non-scaled instance? \n";
}
return " MpCreatureData: \n Original level: " + std::to_string(originalLevel) + "\n" +
origStatsStr +
" NewAttackPower: " + std::to_string(NewAttackPower) + "\n" +
" AttackPowerScaleMultiplier: " + std::to_string(AttackPowerScaleMultiplier) + "\n" +
" Difficulty: " + std::to_string(difficulty) + "\n" +
" Scaled: " + (scaled ? "true" : "false") + "\n";
}
/**@todo Add Affixes and Aura Spell methods */
};
class MpDataStore
{
private:
MpDataStore()
: _playerData(std::make_unique<std::unordered_map<ObjectGuid, MpPlayerData*>>()),
_instanceData(std::make_unique<std::map<std::pair<uint32, uint32>, MpInstanceData>>()),
_groupData(std::make_unique<std::unordered_map<ObjectGuid, MpGroupData>>()),
_instanceCreatureData(std::make_unique<std::unordered_map<ObjectGuid, MpCreatureData>>()),
_scaleFactors(std::make_unique<std::map<std::pair<int32, int32>,MpScaleFactor>>())
{
_playerData->reserve(32);
_groupData->reserve(32);
_instanceCreatureData->reserve(500);
};
inline ~MpDataStore() {
for (auto& [guid, playerData] : *_playerData) {
delete playerData;
}
_playerData->clear();
}
std::unique_ptr<std::unordered_map<ObjectGuid, MpPlayerData*>> _playerData;
// Instance data containes information about how to scale creatures
std::unique_ptr<std::map<std::pair<uint32,uint32>,MpInstanceData>> _instanceData; // {mapId,instanceId}
// Group data stored current group difficulty setting, and stats of group
std::unique_ptr<std::unordered_map<ObjectGuid, MpGroupData>> _groupData;
// This is all creatures that have been scaled used for determining what has been scaled
std::unique_ptr<std::unordered_map<ObjectGuid, MpCreatureData>> _instanceCreatureData;
// use to mimic pattern normals scale to heroic (loaded at server start)
std::unique_ptr<std::map<std::pair<int32,int32>,MpScaleFactor>> _scaleFactors; // {mapId,difficulty}
// Player mapping of level to average amount of health for that level, this is used for scaling against
// percentages to more consistently scale damage from spells and healing from creatures.
std::unordered_map<uint32, uint32> _playerHealthAvg; // level -> avg health
// Single creature multipliers used to scale creatures individually that may need tuned up or down.
// std::unique_ptr<std::unordered_map<uint32, CreatureOverride>> _creatureOverrides;
public:
// ensure we only ever have one instance of this class
MpDataStore(const MpDataStore&) = delete;
MpDataStore& operator=(const MpDataStore&) = delete;
MpPlayerData* GetPlayerData(ObjectGuid guid) {
try {
return _playerData->at(guid);
} catch (const std::out_of_range& oor) {
return nullptr;
}
}
MpGroupData* GetGroupData(ObjectGuid guid) {
if (_groupData->contains(guid)) {
return &_groupData->at(guid);
} else {
return nullptr;
}
}
MpGroupData* GetGroupData(Player *player) {
return GetGroupData(player->GetGroup()->GetGUID());
};
// Set and remove settigs for a group options (difficulty, deaths, stats, etc)
void AddGroupData(Group *group, MpGroupData groupData);
void RemoveGroupData(Group *group);
MpGroupData* GetGroupData(Group *group);
void PushGroupInstanceKey(Group *group, uint32 mapId, uint32 instanceId);
// Data related to player settings and stags
void AddPlayerData(ObjectGuid guid, MpPlayerData* pd);
void RemovePlayerData(ObjectGuid guid);
void ResetPlayerData(ObjectGuid guid);
// Each Map/Instance is a unique key that contains scaling information based on difficulty
void AddInstanceData(uint32 mapId, uint32 instanceId, MpInstanceData );
MpInstanceData* GetInstanceData(uint32 mapId, uint32 instanceId);
void RemoveInstanceData(uint32 mapId, uint32 instanceId);
// Methods for interacting with the map of creatures in a mythic instances
void AddCreatureData(ObjectGuid guid, MpCreatureData creatureData);
MpCreatureData* GetCreatureData(ObjectGuid guid);
void RemoveCreatureData(ObjectGuid guid);
std::vector<MpCreatureData*> GetInstanceCreatures(uint32 mapId, uint32 instanceId);
std::vector<MpCreatureData*> GetUnscaledCreatures(uint32 mapId, uint32 instanceId);
// Scale factors are used to determine a base bonus for enemies base on the instance difficulty
float GetHealthScaleFactor(int32 mapId, int32 difficulty) const;
float GetMeleeScaleFactor(int32 mapId, int32 difficulty) const;
float GetSpellScaleFactor(int32 mapId, int32 difficulty) const;
float GetHealScaleFactor(int32 mapId, int32 difficulty) const;
MpScaleFactor GetScaleFactor(int32 mapId, int32 difficulty) const;
void SetMeleeScaleFactor(int32 mapId, int32 difficulty, float value);
void SetHealthScaleFactor(int32 mapId, int32 difficulty, float value);
void SetSpellScaleFactor(int32 mapId, int32 difficulty, float value);
void SetHealScaleFactor(int32 mapId, int32 difficulty, float value);
// Retrieves the average players hp pool for a player level
uint32 GetPlayerHealthAvg(uint32 level) const;
// Individual Creature Scaling Multipliers
// void AddCreatureOverride(uint32 entry, CreatureOverride* override);
// MpMultipliers* GetCreatureOverride(uint32 entry);
auto GetInstanceDataKey(uint32 mapId, uint32 instanceId) const {
return std::make_pair(mapId, instanceId);
}
auto GetScaleFactorKey(int32 mapId, int32 difficulty) const {
return std::make_pair(mapId, difficulty);
}
// Used at initial server load
int32 LoadScaleFactors();
// Load the player health average from the database
void LoadPlayerHealthAvg();
// Database API calls
void DBUpdatePlayerInstanceData(ObjectGuid playerGuid, MpDifficulty difficulty, uint32 mapId = 0, uint32 instanceId = 0, uint32 deaths = 0);
void DBResetPlayerDeaths(Player* player);
void DBAddPlayerDeath(Player* player, Creature* killer, MpDifficulty difficulty);
void DBAddPlayerDeath(Player* player);
void DBRemovePlayerData(ObjectGuid playerGuid);
void DBRemovePlayerInstanceData(uint32 instanceId);
void DBRemoveGroupInstanceData(uint32 instanceId);
void DBUpdateGroupData(ObjectGuid groupGuid, MpDifficulty difficulty, uint32 mapId, uint32 instanceId, uint32 deaths);
void DBUpdateGroupTimerDeaths(ObjectGuid groupGuid, uint32 mapId, uint32 instanceId, uint32 timer, uint32 deaths);
void DBRemoveGroupData(ObjectGuid groupGuid);
void DBAddGroupDeath(Group* group, uint32 mapId, uint32 instanceId, MpDifficulty difficulty);
//SavePlayerDungeonStats(Group* group, MpGroupData const* groupData);
static MpDataStore* instance() {
static MpDataStore instance;
return &instance;
}
};
#define sMpDataStore MpDataStore::instance()
#endif // MpDataStore_DATASTORE_H

75
src/MpLogger.h Normal file
View File

@@ -0,0 +1,75 @@
#ifndef MP_LOGGER_H
#define MP_LOGGER_H
#include "Log.h"
#include <exception>
#include <iostream>
#include <boost/stacktrace.hpp>
class MpLogger
{
public:
template<typename... Args>
static void debug(const char* fmt, Args&&... args) {
try {
LOG_DEBUG("module.MythicPlus", "[MythicPlus] DEBUG " + std::string(fmt), std::forward<Args>(args)...);
} catch (const std::exception& e) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] DEBUG EXCEPTION: " + std::string(e.what()) +
"\nStack trace: " + boost::stacktrace::to_string(boost::stacktrace::stacktrace()));
} catch (...) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] DEBUG NON-STANDARD EXCEPTION");
}
}
template<typename... Args>
static void error(const char* fmt, Args&&... args) {
try {
LOG_ERROR("module.MythicPlus", "[MythicPlus] ERROR " + std::string(fmt), std::forward<Args>(args)...);
} catch (const std::exception& e) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] ERROR EXCEPTION: " + std::string(e.what()) +
"\nStack trace: " + boost::stacktrace::to_string(boost::stacktrace::stacktrace()));
} catch (...) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] ERROR NON-STANDARD EXCEPTION");
}
}
template<typename... Args>
static void info(const char* fmt, Args&&... args) {
try {
LOG_INFO("module.MythicPlus", "[MythicPlus] INFO " + std::string(fmt), std::forward<Args>(args)...);
} catch (const std::exception& e) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] INFO EXCEPTION: " + std::string(e.what()) +
"\nStack trace: " + boost::stacktrace::to_string(boost::stacktrace::stacktrace()));
} catch (...) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] INFO NON-STANDARD EXCEPTION");
}
}
template<typename... Args>
static void warn(const char* fmt, Args&&... args) {
try {
LOG_WARN("module.MythicPlus", "[MythicPlus] WARN " + std::string(fmt), std::forward<Args>(args)...);
} catch (const std::exception& e) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] WARN EXCEPTION: " + std::string(e.what()) +
"\nStack trace: " + boost::stacktrace::to_string(boost::stacktrace::stacktrace()));
} catch (...) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] WARN NON-STANDARD EXCEPTION");
}
}
template<typename... Args>
static void trace(const char* fmt, Args&&... args) {
try {
LOG_TRACE("module.MythicPlus", "[MythicPlus] TRACE " + std::string(fmt), std::forward<Args>(args)...);
} catch (const std::exception& e) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] TRACE EXCEPTION: " + std::string(e.what()) +
"\nStack trace: " + boost::stacktrace::to_string(boost::stacktrace::stacktrace()));
} catch (...) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] TRACE NON-STANDARD EXCEPTION");
}
}
};
#endif // MP_LOGGER_H

61
src/MpScheduler.h Normal file
View File

@@ -0,0 +1,61 @@
#ifndef MYTHICPLUS_SCHEDULER_H
#define MYTHICPLUS_SCHEDULER_H
#include "MpLogger.h"
#include "ScriptMgr.h"
#include "TaskScheduler.h"
#include <chrono>
enum MP_SCHEDULE_GROUP
{
MP_WORLD_TASK_GROUP = 100
};
/**
* Global scheduler specifically for handling events fired inside of mythic
* scripts
*
* Example usage:
* void ScheduleWorldTask(std::chrono::nanoseconds const& time, std::function<void (TaskContext)> task) {
* sMpScheduler.Schedule(time, MP_WORLD_TASK_GROUP, [](TaskContext ctx) {
* // do the things you want for Mp Task Group
* return;
* });
* }
*/
class MpScheduler
{
public:
static MpScheduler* instance () {
static MpScheduler instance;
return &instance;
}
MpScheduler(const MpScheduler&) = delete;
MpScheduler& operator=(const MpScheduler&) = delete;
TaskScheduler& GetWorldScheduler() {
return _worldScheduler;
}
private:
MpScheduler() {}
~MpScheduler() {}
TaskScheduler _worldScheduler;
};
#define sMpScheduler MpScheduler::instance()
#endif // MYTHICPLUS_SCHEDULER_H
// Attach the world scheduler to listen to world events
class MpScheduler_WorldScript : public WorldScript
{
public:
MpScheduler_WorldScript() : WorldScript("MpScheduler_GlobalScript") { }
void OnUpdate(uint32 diff) override {
sMpScheduler->GetWorldScheduler().Update(diff);
}
};

39
src/MpScriptAI.h Normal file
View File

@@ -0,0 +1,39 @@
#include "Creature.h"
#include "CreatureAI.h"
// #include "CreatureHooks.h"
#include "MpLogger.h"
#include "MythicPlus.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#ifdef _ELUNA_CREATURE_AI_H
#include "ElunaCreatureAI.h"
using BaseAI = ElunaCreatureAI;
#else
using BaseAI = ScriptedAI;
#endif
class MpScriptAI : public BaseAI
{
MpDifficulty _difficulty;
public:
MpScriptAI(Creature* creature, MpDifficulty difficulty) : BaseAI(creature) {
_difficulty = difficulty;
}
MpScriptAI(Creature* creature) : BaseAI(creature) {
_difficulty = MpDifficulty::MP_DIFFICULTY_MYTHIC;
}
void JustDied(Unit* killer) override {
// sCreatureHooks->JustDied(me->ToCreature(), killer);
BaseAI::JustDied(killer);
}
void Reset() override {
// sCreatureHooks->JustSpawned(me->ToCreature());
BaseAI::Reset();
}
};

View File

@@ -1,11 +1,906 @@
#include "MythicPlus.h"
#include "MpLogger.h"
#include "ObjectMgr.h"
#include "MapMgr.h"
#include "ScriptMgr.h"
#include "Group.h"
#include "Unit.h"
#include "WorldPacket.h"
#include "UpdateMask.h"
#include "MpScriptAI.h"
MythicPlus::MythicPlus()
#include <algorithm>
#include <cmath>
// Special case for Headless Horseman Event
const uint32 HEADLESS_HORSEMAN = 23682;
bool MythicPlus::IsMapEligible(Map* map)
{
if (!Enabled) {
return false;
}
if (map->IsDungeon()) {
return true;
}
return false;
}
MythicPlus::~MythicPlus()
bool MythicPlus::IsDifficultySet(Player const* player)
{
Group const* group = player->GetGroup();
if (!group) {
return false;
}
MpGroupData const* groupData = sMpDataStore->GetGroupData(group->GetGUID());
if (!groupData) {
return false;
}
return true;
}
bool MythicPlus::IsDifficultyEnabled(std::string difficulty)
{
return std::find(enabledDifficulties.begin(), enabledDifficulties.end(), difficulty) != enabledDifficulties.end();
}
bool MythicPlus::IsDungeonDisabled(uint32 dungeon)
{
return std::find(disabledDungeons.begin(), disabledDungeons.end(), dungeon) != disabledDungeons.end();
}
bool MythicPlus::EligibleHealTarget(Unit* target)
{
if (!target) {
return false;
}
if (target->GetTypeId() == TYPEID_CORPSE || target->GetTypeId() == TYPEID_GAMEOBJECT) {
return false;
}
#if defined(MOD_PRESENT_NPCBOTS)
if (target->IsNPCBot()) {
return false;
}
// Null check for GetOwner to avoid dereferencing a null pointer
if ((target->IsPet() || target->IsSummon() || target->IsHunterPet()) && target->GetOwner() && target->GetOwner()->IsNPCBot()) {
return false;
}
#endif
// Ensure target is a valid creature before checking eligibility
Creature* creatureTarget = target->ToCreature();
if (creatureTarget && sMythicPlus->IsCreatureEligible(creatureTarget)) {
return true;
}
return false;
}
bool MythicPlus::EligibleDamageTarget(Unit* target)
{
if (!target) {
return false;
}
if (target->GetTypeId() == TYPEID_PLAYER) {
return true;
}
#if defined(MOD_PRESENT_NPCBOTS)
if (target->IsNPCBot()) {
return true;
}
if ((target->IsPet() || target->IsSummon() || target->IsHunterPet()) && target->GetOwner() && target->GetOwner()->IsNPCBot()) {
return true;
}
#endif
Creature* creature = target->ToCreature();
if (creature && (creature->IsPet() || creature->IsSummon() || creature->IsHunterPet()) && creature->GetOwner() && creature->IsControlledByPlayer()) {
return true;
}
return false;
}
bool MythicPlus::IsCreatureEligible(Creature* creature)
{
if (!creature) {
return false;
}
std::string scriptName = creature->GetScriptName();
if(scriptName.starts_with("boss_")) {
return true;
}
if (creature->IsDungeonBoss()) {
return true;
}
if (creature->GetEntry() == HEADLESS_HORSEMAN) {
return true;
}
// Check if the creature is a pet or summon controlled by a player
if ((creature->IsHunterPet() || creature->IsPet() || creature->IsSummon()) && creature->IsControlledByPlayer()) {
return false;
}
// Skip critters, totems, and triggers
if (creature->IsCritter() || creature->IsTotem() || creature->IsTrigger()) {
return false;
}
#if defined(MOD_PRESENT_NPCBOTS)
// Safely check if the creature is an NPC Bot
if (creature->IsNPCBot()) {
return false;
}
if(creature->GetBotOwner()) {
return false;
}
#endif
// Check for NPC-related flags (vendor, gossip, quest giver, trainer, etc.)
if ((creature->IsVendor() ||
creature->HasNpcFlag(UNIT_NPC_FLAG_GOSSIP) ||
creature->HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER) ||
creature->HasNpcFlag(UNIT_NPC_FLAG_TRAINER) ||
creature->HasNpcFlag(UNIT_NPC_FLAG_TRAINER_PROFESSION) ||
creature->HasNpcFlag(UNIT_NPC_FLAG_REPAIR) ||
creature->HasUnitFlag(UNIT_FLAG_IMMUNE_TO_PC) ||
creature->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) &&
(!creature->IsDungeonBoss()))
{
return false;
}
return true;
}
void MythicPlus::AddCreatureForScaling(Creature* creature)
{
if (!IsCreatureEligible(creature)) {
return;
}
sMpDataStore->AddCreatureData(creature->GetGUID(), MpCreatureData(creature));
// MpLogger::debug("Added creature {} to instance data for instance {}",
// creature->GetName(),
// creature->GetMap()->GetMapName()
// );
}
void MythicPlus::AddScaledCreature(Creature* creature, MpInstanceData* instanceData)
{
MpCreatureData creatureData = MpCreatureData(creature);
creatureData.SetScaled(true);
creatureData.SetDifficulty(instanceData->difficulty);
creatureData.lastDeathState = creature->getDeathState();
sMpDataStore->AddCreatureData(creature->GetGUID(), creatureData);
// allow small variance in level for non-boss creatures
uint8 level = uint8(urand(instanceData->creature.avgLevel - 1, instanceData->creature.avgLevel + 1));
if(creature->IsDungeonBoss() || creature->GetEntry() == 23682) {
ScaleCreature(instanceData->boss.avgLevel, creature, &instanceData->boss, instanceData->difficulty);
} else {
ScaleCreature(level, creature, &instanceData->creature, instanceData->difficulty);
}
// Update AI now the creature has been scaled.
// auto ai = new MpScriptAI(creature, instanceData->difficulty);
// creature->SetAI(ai);
// We know the creature is scaled and in the instance to fire the event.
// sCreatureHooks->AddToInstance(creature);
// MpLogger::debug("Scaled Creature {} Entry {} Id {} level from {} to {}",
// creature->GetName(),
// creature->GetEntry(),
// creature->GetGUID().GetCounter(),
// creature->GetLevel(),
// level
// );
}
void MythicPlus::ScaleRemaining(Player* player, MpInstanceData* instanceData)
{
std::vector<MpCreatureData*> creatures = sMpDataStore->GetUnscaledCreatures(player->GetMapId(), player->GetInstanceId());
for (MpCreatureData* creatureData : creatures) {
AddScaledCreature(creatureData->creature, instanceData);
}
}
void MythicPlus::ScaleAll(Player* player, MpInstanceData* instanceData)
{
std::vector<MpCreatureData*> creatures = sMpDataStore->GetInstanceCreatures(player->GetMapId(), player->GetInstanceId());
for (MpCreatureData* creatureData : creatures) {
// Only scale living creatures
if (creatureData->creature && creatureData->creature->IsAlive()) {
ScaleCreature(creatureData->creature->GetLevel(), creatureData->creature, &instanceData->creature, instanceData->difficulty);
}
}
}
// Perform any memory cleanup when the creature is removed from the world and no longer needed.
void MythicPlus::RemoveCreature(Creature* creature)
{
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creature->GetGUID());
if (!creatureData) {
return;
}
sMpDataStore->RemoveCreatureData(creature->GetGUID());
}
void MythicPlus::ScaleCreature(uint8 level, Creature* creature, MpMultipliers* multipliers, MpDifficulty difficulty)
{
CreatureTemplate const* cInfo = creature->GetCreatureTemplate();
uint32 mapId = creature->GetMapId();
// get the map difficulty from the map instance to see if it is a heroic or normal set instance
InstanceMap *instanceMap = creature->GetMap()->ToInstanceMap();
if (!instanceMap) {
MpLogger::error("Invalid instance map ScaleCreature()");
return;
}
creature->SetLevel(level);
CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(
level,
cInfo->unit_class
);
// Scale the creatures base health
uint32 basehp = stats->BaseHealth[EXPANSION_WRATH_OF_THE_LICH_KING];
uint32 health = CalculateNewHealth(creature, cInfo, mapId, difficulty, basehp, multipliers->health);
creature->SetCreateHealth(health);
creature->SetMaxHealth(health);
creature->SetHealth(health);
creature->ResetPlayerDamageReq();
creature->SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
/**
* @TODO: Figure out mana later for unit_types 2 and 8
*/
// Scale the creatures mana pool
uint32 mana = uint32(std::ceil(stats->BaseMana * cInfo->ModMana));
creature->SetCreateMana(mana);
creature->SetMaxPower(POWER_MANA, mana);
creature->SetPower(POWER_MANA, mana);
if(cInfo->unit_class == UNIT_CLASS_MAGE) {
creature->SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana * 10.0f);
}
if(cInfo->unit_class == UNIT_CLASS_PALADIN) {
creature->SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana * 3.0f);
}
MpInstanceData *instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
// Handle new melee/range scaling with simple formula (for simplicity range will just be 80% of melee bonus)
float meleeMultiplier = sMpDataStore->GetMeleeScaleFactor(creature->GetMapId(), instanceData->difficulty);
// Since Heroic Scaling can get out of hand. Reduce the instance multiplier by way too much 10%
if(instanceMap->IsHeroic() || instanceMap->Is25ManRaid()) {
// if the enemy is a boss reduce it by less
meleeMultiplier *= 0.9f;
}
// Scale up the attack power based on the instance set in the database difficulty table.
uint32 ap = std::ceil(stats->AttackPower * meleeMultiplier);
uint32 rangeAp = std::ceil(stats->RangedAttackPower * meleeMultiplier * 0.4f);
// Additionally need to add in a decrease in attack power for normal non elite enemies
if (creature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
// Reduced scaling for elite/boss spells to prevent them from hitting too hard
ap *= normalEnemyReducer;
rangeAp *= normalEnemyReducer;
}
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creature->GetGUID());
if(creatureData) {
creatureData->NewAttackPower = ap;
creatureData->AttackPowerScaleMultiplier = meleeMultiplier;
}
// Set scaled attack power
creature->SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, ap);
creature->SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, rangeAp);
// set the base weapon damage
creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, stats->BaseDamage[EXPANSION_WRATH_OF_THE_LICH_KING], 0);
creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, stats->BaseDamage[EXPANSION_WRATH_OF_THE_LICH_KING] * 1.5f, 0);
creature->SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, stats->BaseDamage[EXPANSION_WRATH_OF_THE_LICH_KING] * 0.5f, 0);
creature->SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, stats->BaseDamage[EXPANSION_WRATH_OF_THE_LICH_KING] * 0.8f, 0);
// Update all stats to apply the new damage values
creature->UpdateAllStats();
// Scale up the armor with some variance also to make some tougher enemies in the mix
uint32 armor = uint32(std::ceil(stats->BaseArmor * multipliers->armor * cInfo->ModArmor));
creature->SetArmor(armor);
float updatedAp = creature->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE);
float updatedRangeAp = creature->GetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE);
MpLogger::debug("Updated Attack Powers: {} {}", updatedAp, updatedRangeAp);
}
int32 MythicPlus::CalculateSpellDamage(uint32 baseDamage, int originalLevel, int targetLevel) {
float origHpPool = sMpDataStore->GetPlayerHealthAvg(originalLevel);
float targetHpPool = sMpDataStore->GetPlayerHealthAvg(targetLevel);
// Using a % of expected damage of the average player pool creates a better consistent experience when scaling spells
float percentDamage = baseDamage / origHpPool;
// If the percentage damage is less than 2% cap it at 2% to prevent spells from being too powerful
if(percentDamage < 0.02f) {
percentDamage = 0.02f;
}
MpLogger::debug("OrigHpPool: {} TargetHpPool: {} Percent Damage: {}", origHpPool, targetHpPool, percentDamage);
MpLogger::debug("Original Damage: {} Scaled Damage: {}", baseDamage, static_cast<int32>(std::ceil(percentDamage * targetHpPool)));
int32 scaledDamage = static_cast<int32>(std::ceil(percentDamage * targetHpPool));
return scaledDamage;
}
int32 MythicPlus::CalculateHealScaling(uint32 baseHeal, uint32 originalTargetHealth, uint32 targetMaxHealth) {
if (originalTargetHealth == 0) {
MpLogger::debug("Original target health is 0, returning base heal: {}", baseHeal);
return baseHeal;
}
// Calculate the percentage of the original heal relative to original creature health
float percentHeal = static_cast<float>(baseHeal) / static_cast<float>(originalTargetHealth);
if (percentHeal < 0.01f) {
percentHeal = 0.01f;
}
// Cap the percentage at 100% aka full heal of current max health of caster
if (percentHeal > 1.0f) {
percentHeal = 1.0f;
}
// Scale the heal based on the current creature's max health
int32 scaledHeal = static_cast<int32>(std::ceil(percentHeal * targetMaxHealth));
MpLogger::debug("HEALING: >>> OrigHealth: {} CurrentMaxHealth: {} Percent Heal: {} Original Heal: {} Scaled Heal: {}",
originalTargetHealth, targetMaxHealth, percentHeal, baseHeal, scaledHeal);
return scaledHeal;
}
int32 MythicPlus::ScaleDamageSpell(SpellInfo const * spellInfo, uint32 damage, MpCreatureData* creatureData, Creature* creature, Unit* /* target */, float damageMultiplier)
{
if (!spellInfo) {
MpLogger::error("Invalid spell info ScaleDamageSpell()");
return damage;
}
MpInstanceData *instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
if (!instanceData) {
MpLogger::debug("No instance data found for spell scaling, using original damage");
return damage;
}
float scaleFactor = sMpDataStore->GetSpellScaleFactor(creature->GetMapId(), instanceData->difficulty);
MpLogger::debug("DAMAGE SPELL: >> ScaleFactor: {} DamageMultiplier: {}", scaleFactor, damageMultiplier);
// calculate the global modifier x instance modifier
float totalModifier = damageMultiplier * scaleFactor;
// If for some reason there is not a creature, just use the global modifier x instance modifier
if(!creature) {
MpLogger::error("Invalid creature ScaleDamageSpell()");
return damage * totalModifier;
}
// Use the already calculated damage as the base for scaling
int32 newDamage = damage;
// Handle Summoned unit modifiers as
if(!creatureData) {
// handle if bot pets if NPCBot is installed.
#ifdef NPCBOT
if(creature->IsNPCBotOrPet()) {
return damage;
}
#endif
// Handle totems and summons - scale based on owner's details because they will not have creature data
if(creature->IsTotem() || creature->IsSummon()) {
Unit* owner = creature->GetOwner();
if(owner && owner->IsCreature()) {
Creature* ownerCreature = owner->ToCreature();
// Look up the owner creature's original level from MpDataStore
MpCreatureData* ownerCreatureData = sMpDataStore->GetCreatureData(ownerCreature->GetGUID());
if (ownerCreatureData) {
MpLogger::debug("DAMAGE SPELL: >> Creature is a totem or summon Creature Name {} and owner {} owner original level {} owner level {}", creature->GetName(), ownerCreature->GetName(), ownerCreatureData->originalLevel, ownerCreature->GetLevel());
int32 ownerOriginalLevel = ownerCreatureData->originalLevel;
if (ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
totalModifier = totalModifier * normalEnemyReducer;
}
newDamage = CalculateSpellDamage(damage, ownerOriginalLevel, ownerCreature->GetLevel());
} else {
// Fallback if no creature data found - use current level
if(ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
totalModifier = totalModifier * normalEnemyReducer;
}
newDamage = CalculateSpellDamage(damage, ownerCreature->GetLevel(), ownerCreature->GetLevel());
MpLogger::debug("No creature data found for owner {}, using current level for scaling", ownerCreature->GetGUID().ToString());
}
}
}
else {
MpLogger::error("Invalid creature data ScaleDamageSpell()");
return damage * totalModifier;
}
} else {
newDamage = CalculateSpellDamage(damage, creatureData->originalLevel, creature->GetLevel());
if (creature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
// Reduced scaling for elite/boss spells to prevent them from hitting too hard
totalModifier = totalModifier * 0.85f;
}
}
// Calculate the additional damage from scaling (scaled damage - original damage)
int32 additionalDamage = newDamage - damage;
// Apply the scaling modifier to the additional damage only
int32 scaledAdditionalDamage = additionalDamage * totalModifier;
// Use the diminishing return values from the configuration
uint32 threshold = sMythicPlus->diminishingThresholds[instanceData->difficulty];
float diminishingExponent = sMythicPlus->diminishingExponent;
// Apply diminishing returns only to the additional scaled damage if it exceeds threshold
if (static_cast<uint32>(scaledAdditionalDamage) > threshold) {
// Calculate the diminished excess additional damage
float excess = scaledAdditionalDamage - threshold;
float diminishedExcess = pow(excess, diminishingExponent);
scaledAdditionalDamage = threshold + diminishedExcess;
MpLogger::debug("DAMAGE SPELL: >> Above Diminishing Threshold for Spell {} - Original: {}, Additional: {}, Diminished Additional: {}, Final: {}",
spellInfo->SpellName[0], damage, additionalDamage * totalModifier, scaledAdditionalDamage, damage + scaledAdditionalDamage);
} else {
MpLogger::debug("DAMAGE SPELL: >> Below Diminishing Threshold for Spell {} - Original: {}, Additional: {}, Final: {}",
spellInfo->SpellName[0], damage, scaledAdditionalDamage, damage + scaledAdditionalDamage);
}
// If this is a heroic instance the additional spell damage should be increased by 50%
InstanceMap* instanceMap = creature->GetMap()->ToInstanceMap();
if (instanceMap && (instanceMap->IsHeroic() || instanceMap->Is25ManRaid())) {
scaledAdditionalDamage = scaledAdditionalDamage * 1.5f;
}
// Return original damage + scaled additional damage (with potential diminishing returns)
return damage + scaledAdditionalDamage;
}
int32 MythicPlus::ScaleHealSpell(SpellInfo const * spellInfo, uint32 heal, MpCreatureData* creatureData, Creature* creature, Creature* target, float healMultiplier)
{
if (!spellInfo) {
MpLogger::error("Invalid spell info ScaleHealSpell()");
return heal;
}
MpInstanceData *instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
if (!instanceData) {
MpLogger::debug("No instance data found for heal scaling, using original heal");
return heal;
}
float scaleFactor = sMpDataStore->GetHealScaleFactor(creature->GetMapId(), instanceData->difficulty);
MpLogger::debug("HEALING: >>> HealScaleFactor: {} HealMultiplier: {}", scaleFactor, healMultiplier);
// calculate the global modifier x instance modifier
float totalModifier = healMultiplier * scaleFactor;
// If for some reason there is not a creature, just use the global modifier x instance modifier
if(!creature) {
MpLogger::error("Invalid creature ScaleHealSpell()");
return heal * totalModifier;
}
// Use the already calculated heal as the base for scaling
int32 newHeal = heal;
// Handle Summoned unit modifiers
if(!creatureData) {
// handle if bot pets if NPCBot is installed.
#ifdef NPCBOT
if(creature->IsNPCBotOrPet()) {
return heal;
}
#endif
MpLogger::debug("HEALING: >>> Scaling heal to target: {} with spell: {}", target->GetName(), spellInfo->SpellName[0]);
// Handle totems and summons - scale based on owner's details because they will not have creature data
if(creature->IsTotem() || creature->IsSummon()) {
Unit* owner = creature->GetOwner();
if(owner && owner->IsCreature()) {
Creature* ownerCreature = owner->ToCreature();
// Look up the owner creature's original level from MpDataStore
MpCreatureData* ownerCreatureData = sMpDataStore->GetCreatureData(ownerCreature->GetGUID());
if (ownerCreatureData) {
if (ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
totalModifier = totalModifier * normalEnemyReducer; // Less reduction for heals than damage
}
// Scale heal based on target's health, not caster's health
if (target) {
MpCreatureData* targetCreatureData = sMpDataStore->GetCreatureData(target->GetGUID());
uint32 targetOriginalHealth = targetCreatureData && targetCreatureData->originalInstanceHealth > 0 ?
targetCreatureData->originalInstanceHealth : target->GetMaxHealth();
MpLogger::debug("HEALING: >>> Scaling heal to target: {} Original Instance Health: {} New Health: {}", target->GetName(), targetOriginalHealth, target->GetMaxHealth());
newHeal = CalculateHealScaling(heal, targetOriginalHealth, target->GetMaxHealth());
} else {
newHeal = heal;
}
} else {
// Fallback if no creature data found - use current level
if(ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
totalModifier = totalModifier * normalEnemyReducer; // Less reduction for heals than damage
}
// Scale heal based on target's health, not caster's health
if (target) {
MpCreatureData* targetCreatureData = sMpDataStore->GetCreatureData(target->GetGUID());
uint32 targetOriginalHealth = targetCreatureData && targetCreatureData->originalInstanceHealth > 0 ?
targetCreatureData->originalInstanceHealth : target->GetMaxHealth();
MpLogger::debug("HEALING: >>> Scaling heal to target: {} Original Instance Health: {} New Health: {}", target->GetName(), targetOriginalHealth, target->GetMaxHealth());
newHeal = CalculateHealScaling(heal, targetOriginalHealth, target->GetMaxHealth());
} else {
newHeal = heal;
}
MpLogger::debug("No creature data found for owner {}, using current level for scaling", ownerCreature->GetGUID().ToString());
}
}
}
else {
MpLogger::error("Invalid creature data ScaleHealSpell()");
return heal * totalModifier;
}
} else {
// Scale heal based on target's health, not caster's health
if (target) {
// Get target's original instance health for scaling comparison
MpCreatureData* targetCreatureData = sMpDataStore->GetCreatureData(target->GetGUID());
uint32 targetOriginalHealth = targetCreatureData && targetCreatureData->originalInstanceHealth > 0 ?
targetCreatureData->originalInstanceHealth : target->GetMaxHealth();
MpLogger::debug("HEALING: >>> Scaling heal to target: {} Original Instance Health: {} New Health: {}", target->GetName(), targetOriginalHealth, target->GetMaxHealth());
newHeal = CalculateHealScaling(heal, targetOriginalHealth, target->GetMaxHealth());
} else {
// No target available, use original heal
newHeal = heal;
}
}
// Calculate the additional heal from scaling (scaled heal - original heal)
int32 additionalHeal = newHeal - heal;
// Apply the scaling modifier to the additional heal only
int32 scaledAdditionalHeal = additionalHeal * totalModifier;
// Use the diminishing return values from the configuration (same as damage)
uint32 threshold = sMythicPlus->diminishingThresholds[instanceData->difficulty];
float diminishingExponent = sMythicPlus->diminishingExponent;
// Apply diminishing returns only to the additional scaled heal if it exceeds threshold * 2 since enemies have much more health.
if (scaledAdditionalHeal > threshold * 2.0f) {
// Calculate the diminished excess additional heal
float excess = scaledAdditionalHeal - threshold;
float diminishedExcess = pow(excess, diminishingExponent * 0.95f); // slightly reduce the diminishing returns for heals
scaledAdditionalHeal = threshold + diminishedExcess;
MpLogger::debug("HEALING: >>> Above Diminishing Threshold for Heal Spell {} - Original: {}, Additional: {}, Diminished Additional: {}, Final: {}",
spellInfo->SpellName[0], heal, additionalHeal * totalModifier, scaledAdditionalHeal, heal + scaledAdditionalHeal);
} else {
MpLogger::debug("HEALING: >>> Below Diminishing Threshold for Heal Spell {} - Original: {}, Additional: {}, Final: {}",
spellInfo->SpellName[0], heal, scaledAdditionalHeal, heal + scaledAdditionalHeal);
}
// If this is a heroic instance the additional heal be only slightly increased
InstanceMap* instanceMap = creature->GetMap()->ToInstanceMap();
if (instanceMap && (instanceMap->IsHeroic() || instanceMap->Is25ManRaid())) {
scaledAdditionalHeal = scaledAdditionalHeal * 1.15f;
}
// Return original heal + scaled additional heal (with potential diminishing returns)
return heal + scaledAdditionalHeal;
}
void MythicPlus::GroupReset(Group* /*group*/, Map* /* map */) {
// Stubbed out for later implementation
}
bool MythicPlus::IsFinalBoss(Creature* creature) {
std::array<uint32, 128> finalBosses = {
// --- WoW Classic Dungeons ---
11519, /* Bazzalan Ragefire */
639, /* Edwin VanCleef Deadmines */
3654, /* Mutanus the Devourer Wailing Caverns */
4275, /* Archmage Arugal Shadowfang Keep */
1716, /* Bazil Thredd Stockades */
4829, /* Aku'mai blackfathom Deeps */
7800, /* Mekgineer Thermaplugg Gnomeregan */
4421, /* Charlga Razorflank Razorfen Kraul */
4543, /* Bloodmage Thalnos Scarlet Monastery */
3975, /* Herod Scarlet Monastery */
3977, /* High Inquisitor Whitemane Scarlet Monastery */
7350, /* Amnennar the Coldbringer Razorfen Downs */
2748, /* Archaedas Uldaman */
7267, /* Chief Ukorz Sandscalp Zul'Farrak */
12201, /* Princess Theradras Maraudon */
5709, /* Shade of Eranikus Sunken Temple */
9019, /* Emperor Dagran Thaurissan Blackrock Depths */
9568, /* Overlord Wyrmthalak Lower Blackrock Spire */
10363, /* General Drakkisath Upper Blackrock Spire */
11492, /* alzzin the Wildshaper Dire Maul */
11496, /* Immol'thar Dire Maul */
11501, /* King Gordok Dire Maul */
1853, /* Darkmaster Gandling Scholomance */
10812, /* Grand Crusader Dathrohan Stratholme */
10440, /* Baron Rivendare Stratholme */
// --- WoW Classic Raids ---
11583, /* Nefarian Blackwing Lair */
11502, /* Ragnaros Molten Core */
14834, /* Hakkar Zul'Gurub */
15727, /* C'Thun Temple of Ahn'Qiraj */
15339, /* Ossirian the Unscarred Ruins of Ahn'Qiraj */
// --- The Burning Crusade ---
17536, /* Nazan - Hellfire Ramparts Normal */
17536, /* Nazan - Hellfire Ramparts Normal */
17377, /* Kelidan the Breaker - Blood Furnace Normal */
18607, /* Kelidan the Breaker - Blood Furnace Heroic */
17942, /* Quagmirran - The Slave Pens Normal */
19894, /* Quagmirran - The Slave Pens Heoric */
17882, /* The Black Stalker - The Underbog Normal */
20184, /* The Black Stalker - The Underbog Heroic */
24420, /* The Black Stalker - The Underbog Heroic(2) */
18344, /* Nexus-Prince Shaffar - Mana-Tombs Normal */
20256, /* Nexus-Prince Shaffar - Mana-Tombs Heroic */
18373, /* Exarch Maladaar - Auchenai Crypts Normal */
20306, /* Exarch Maladaar - Auchenai Crypts Heoric */
18096, /* Epoch Hunter - Old Hillsbrad Foothills Normal */
20531, /* Epoch Hunter - Old Hillsbrad Foothills Heroic */
18473, /* Talon King Ikiss - Sethekk Halls Normal */
20706, /* Talon King Ikiss - Sethekk Halls Heroic */
17798, /* Warlord Kalithresh - The Steamvault Normal */
20633, /* Warlord Kalithresh - The Steamvault Heroic */
18708, /* Murmur - Shadow Labyrinth Normal */
20657, /* Murmur - Shadow Labyrinth Heroic */
16808, /* Warchief Kargath Bladefist - The Shattered Halls Normal */
20597, /* Warchief Kargath Bladefist - The Shattered Halls Heroic */
17881, /* Aeonus - The Black Morass Normal */
20737, /* Aeonus - The Black Morass Heroic */
17977, /* Warp Splinter - The Botanica Normal */
21582, /* Warp Splinter - The Botanica Heroic */
19220, /* Pathaleon the Calculator - The Mechanar Normal */
21537, /* Pathaleon the Calculator - The Mechanar Heroic */
20912, /* Harbinger Skyriss - The Arcatraz Normal */
21601, /* Harbinger Skyriss - The Arcatraz Heroic */
19622, /* Kael'thas Sunstrider - Magisters' Terrace Normal */
24857, /* Kael'thas Sunstrider - Magisters' Terrace Heroic */
// --- Burning Crusade Raids ---
15690, /* Prince Malchezaar - Karazhan */
23863, /* Zul'jin - Zul'Aman */
19044, /* Gruul the Dragonkiller - Gruul's Lair */
17257, /* Magtheridon - Magtheridon's Lair */
21212, /* Lady Vashj - Serpentshrine Cavern */
24664, /* Kael'thas Sunstrider - The Eye */
24855, /* Kael'thas Sunstrider - The Eye */
17968, /* Archimonde - Hyjal Summit */
22917, /* Illidan Stormrage - Black Temple */
25315, /* Kil'jaeden - Sunwell Plateau */
// --- Wrath of the Lich King ---
23954, /* Ingvar the Plunderer - Utgarde Keep Normal */
31673, /* Ingvar the Plunderer - Utgarde Keep Heroic */
26861, /* King Ymiron - Utgarde Pinnacle Normal */
30788, /* King Ymiron - Utgarde Pinnacle Heroic */
26723, /* Keristrasza - The Nexus Normal */
30540, /* Keristrasza - The Nexus Heroic */
26632, /* The Prophet Tharon'ja - Drak'Tharon Keep Normal */
31360, /* The Prophet Tharon'ja - Drak'Tharon Keep Heroic */
27656, /* Ley-Guardian Eregos - The Oculus Normal */
31561, /* Ley-Guardian Eregos - The Oculus Heroic */
29311, /* Herald Volazj - Ahn'kahet: The Old Kingdom Normal */
31464, /* Herald Volazj - Ahn'kahet: The Old Kingdom Heroic */
29120, /* Anub'arak - Azjol-Nerub Normal */
31610, /* Anub'arak - Azjol-Nerub Heroic */
29306, /* Gal'darah - Gundrak Normal */
31368, /* Gal'darah - Gundrak Heroic */
26533, /* Mal'Ganis - Culling of Stratholme Normal */
31217, /* Mal'Ganis - Culling of Stratholme Heroic */
31134, /* Cyanigosa - Violet Hold Normal */
31506, /* Cyanigosa - Violet Hold Heroic */
27978, /* Sjonnir the Ironshaper - Halls of Stone Normal */
31386, /* Sjonnir the Ironshaper - Halls of Stone Heroic */
28923, /* Loken - Halls of Lightning Normal */
31538, /* Loken - Halls of Lightning Heroic */
35451, /* The Black Knight - Trial of the Champion Normal */
35490, /* The Black Knight - Trial of the Champion Heroic */
36502, /* Devourer of Souls - The Forge of Souls Normal */
37677, /* Devourer of Souls - The Forge of Souls Heroic */
36658, /* Scourgelord Tyrannus - Pit of Saron Normal */
36938, /* Scourgelord Tyrannus - Pit of Saron Heroic */
37226, /* The Lich King Encounter - Halls of Reflection Normal */
39166, /* The Lich King Encounter - Halls of Reflection Heroic */
// --- Wrath of the Lich King Raids ---
15990, /* Kel'Thuzad - Naxxramas */
28859, /* Malygos - The Eye of Eternity */
28860, /* Sartharion - Obsidian Sanctum */
31125, /* Archavon the Stone Watcher - Vault of Archavon */
33993, /* Emalon the Storm Watcher - Vault of Archavon */
35013, /* Koralon the Flame Watcher - Vault of Archavon */
38433, /* Toravon the Ice Watcher - Vault of Archavon */
33288, /* Yogg-Saron - Ulduar */
34564, /* Anub'arak - Trial of the Crusader */
10184, /* Onyxia - Onyxia's Lair (re-released in Wrath) */
36597, /* The Lich King - Icecrown Citadel */
39863, /* Halion - Ruby Sanctum */
};
return std::find(finalBosses.begin(), finalBosses.end(), creature->GetEntry()) != finalBosses.end();
}
/**
* Function is copied because was not accessible in core creature class
*/
float GetTypeHealthModifier(int32 Rank)
{
switch (Rank)
{
case CREATURE_ELITE_NORMAL:
return sWorld->getRate(RATE_CREATURE_NORMAL_HP);
case CREATURE_ELITE_ELITE:
return sWorld->getRate(RATE_CREATURE_ELITE_ELITE_HP);
case CREATURE_ELITE_RAREELITE:
return sWorld->getRate(RATE_CREATURE_ELITE_RAREELITE_HP);
case CREATURE_ELITE_WORLDBOSS:
return sWorld->getRate(RATE_CREATURE_ELITE_WORLDBOSS_HP);
case CREATURE_ELITE_RARE:
return sWorld->getRate(RATE_CREATURE_ELITE_RARE_HP);
default:
return sWorld->getRate(RATE_CREATURE_ELITE_ELITE_HP);
}
}
// This takes the orignal health and scales flat based on the factor then applies the configuration modifier from the conf file
uint32 CalculateNewHealth(Creature* creature, CreatureTemplate const* cInfo, uint32 mapId, MpDifficulty difficulty, uint32 origHealth, float confHPMod)
{
//
int32 rank = 0;
if(cInfo && cInfo->rank > 0) {
rank = cInfo->rank;
}
// These Factors that increase or decrease health based on different settings applied to the creature
// Health Variation is used to create some random element to HP so not all creatures of the same level
// have the same HP for more variety.
float healthVariation;
// This is the fine grained hpScaleFactor set for the instance (and/or) creature overrides in the database.
int32 hpScaleFactor = sMpDataStore->GetHealthScaleFactor(mapId, difficulty);
// Add some variance to the healthpool so enemies are not all the same
if(creature->IsDungeonBoss() || creature->isWorldBoss() || creature->isElite() || cInfo->rank == CREATURE_ELITE_RARE) {
healthVariation = frand(1.0f, 1.15f);
} else { // This addresses Normals and other trash from getting to big a HP bonus
healthVariation = frand(1.0f, 1.05f);
hpScaleFactor *= 0.50;
}
// Add in special overrides here as necessary:
if(creature->GetEntry() == HEADLESS_HORSEMAN) {
healthVariation = frand(1.0f, 1.1f);
}
float unitTypeMod = GetTypeHealthModifier(rank);
uint32 basehp;
// Only apply unitTypeMod for non-normal enemies
if (rank != CREATURE_ELITE_NORMAL) {
basehp = uint32(std::ceil(origHealth * healthVariation * unitTypeMod));
} else {
basehp = uint32(std::ceil(origHealth * healthVariation));
}
// if it is a heroic instance give the enemy an additional 20% boost
InstanceMap* instanceMap = creature->GetMap()->ToInstanceMap();
if (instanceMap && instanceMap->IsRaidOrHeroicDungeon()) {
basehp *= 1.25f;
}
/**
* @brief Calculating the final creature health encompasses all the potential modifiers
* CreatureTemplate.HealthModifier (ModHealth) - Creatures that are capable of being in a Heroic instance get a boost here
* even though they are the same. In this case we allow
*
* hpScaleFactor: allows to tweak the bonus modifier more directly at a creature or instance level, since
* you can not override it in cInfo directly as it is loaded statically from database
*
* confHPMod: is from the mythic settings directly.
*/
if(cInfo->ModHealth > 0.0f) {
return uint32(basehp * (cInfo->ModHealth + hpScaleFactor) * confHPMod);
} else {
return uint32(basehp * hpScaleFactor * confHPMod);
}
}
// Calculates a balanced growth curve that provides good scaling across all level ranges
float CalculateScaling(int levelDifference, float scaleFactor, float constant, float /*growthFactor*/) {
float levelMultiplier;
if (levelDifference <= 0) {
// High-level creatures need a minimum boost
levelMultiplier = 1.5f; // Minimum 50% boost for near-level or higher creatures
} else if (levelDifference <= 10) {
// Moderate scaling for small level differences
levelMultiplier = 1.5f + (levelDifference * 0.2f); // 1.5x to 3.5x
} else if (levelDifference <= 30) {
// Higher scaling for medium level differences
levelMultiplier = 3.5f + ((levelDifference - 10) * 0.15f); // 3.5x to 6.5x
} else {
// Cap extreme scaling for very low level creatures
levelMultiplier = 6.5f + std::min((levelDifference - 30) * 0.05f, 3.5f); // Cap at 10x
}
float scaling = constant * levelMultiplier * (1 + (scaleFactor / 100.0f));
return scaling;
}
float GetTypeDamageModifier(int32 Rank)
{
switch (Rank)
{
case CREATURE_ELITE_NORMAL:
return sWorld->getRate(RATE_CREATURE_NORMAL_DAMAGE);
case CREATURE_ELITE_ELITE:
return sWorld->getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE);
case CREATURE_ELITE_RAREELITE:
return sWorld->getRate(RATE_CREATURE_ELITE_RAREELITE_DAMAGE);
case CREATURE_ELITE_WORLDBOSS:
return sWorld->getRate(RATE_CREATURE_ELITE_WORLDBOSS_DAMAGE);
case CREATURE_ELITE_RARE:
return sWorld->getRate(RATE_CREATURE_ELITE_RARE_DAMAGE);
default:
return sWorld->getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE);
}
}

View File

@@ -1,19 +1,169 @@
#ifndef MYTHICPLUS_H
#define MYTHICPLUS_H
class MythicPlus {
private:
MythicPlus();
~MythicPlus();
#include "Creature.h"
#include "Define.h"
#include "Map.h"
#include "MpDataStore.h"
#include "Player.h"
#include "SpellInfo.h"
#include "Unit.h"
#include "TaskScheduler.h"
#include <map>
#include <string>
#include <vector>
#include <unordered_map>
// Used to limit the total advancment rank and allow for changing the max rank in one place.
inline const uint8 MP_MAX_ADVANCEMENT_RANK = 50;
/**
* Main Class for the mod responsible for controls related to scaling instances,
* handling logic related to setting up instances for MythicPlus to work.
*
* MpDataStore is heavily used as well for storing data in memory and interactions with
* database storage.
*
* This is a singleton instance that can be accessed through sMythicPlus.
*/
class MythicPlus
{
public:
static MythicPlus * getInstance() {
// accessor for this singleton
static MythicPlus* instance()
{
static MythicPlus instance;
return &instance;
}
// ensure we only ever have one instance of this class
MythicPlus(const MythicPlus&) = delete;
MythicPlus& operator=(const MythicPlus&) = delete;
// Global Settings
bool Enabled;
bool EnableItemRewards;
bool EnableDeathLimits;
// Turn off specific features of mythic+
std::vector<std::string> enabledDifficulties;
std::vector<uint32> disabledDungeons;
// Difficulty Modifiers
MpMultipliers mythicDungeonModifiers;
MpMultipliers mythicBossModifiers;
MpMultipliers legendaryDungeonModifiers;
MpMultipliers legendaryBossModifiers;
MpMultipliers ascendantDungeonModifiers;
MpMultipliers ascendantBossModifiers;
// Death Allowances
uint32 mythicDeathAllowance;
uint32 legendaryDeathAllowance;
uint32 ascendantDeathAllowance;
// Itemization Offsets
uint32 mythicItemOffset;
uint32 legendaryItemOffset;
uint32 ascendantItemOffset;
// Scaling modifiers (Deprecated)
uint32 meleeAttackPowerDampener;
uint32 meleeAttackPowerStart;
// Spell Damage Diminishing Returns
float diminishingExponent;
std::unordered_map<MpDifficulty, uint32> diminishingThresholds;
// Specialized variables used in calculations
float elementalMeleeReducer;
float normalEnemyReducer;
float nonCreatureSpellReducer;
enum MP_UNIT_EVENT_TYPE
{
UNIT_EVENT_MELEE,
UNIT_EVENT_HEAL,
UNIT_EVENT_DOT,
UNIT_EVENT_SPELL,
UNIT_EVENT_HOT
};
// Map is eligible for mythic+ scaling
bool IsMapEligible(Map* map);
// If a player difficulty is set that is eligible for mythic+ scaling
bool IsDifficultySet(Player const* player);
// Check is difficulty is enabled in the configuration
bool IsDifficultyEnabled(std::string difficulty);
// if configuration has disabled the specific dungeon return false
bool IsDungeonDisabled(uint32 dungeonId);
// Is it a scaled creature that is being healed
bool EligibleHealTarget(Unit* target);
// Validates if the target of an attack should receive mythic+ damage/heal/dot scaling
bool EligibleDamageTarget(Unit* target);
// The creature should be given Mythic+ scaling and powers check for pets, npcs, etc
bool IsCreatureEligible(Creature* creature);
// Adds the creature if eligible to be scaled
void AddCreatureForScaling(Creature* creature);
// Removes the creature from the scaling list and cleans up memory
void RemoveCreature(Creature* creature);
/**
* Creatures are added to an instance before a player enter event is fired
* therefore it is necessary to scan the instance creature information and
* and scale any creatures that were loaded before the first player using
* the instance data from the group settings.
*/
void ScaleRemaining(Player* player, MpInstanceData* instanceData);
// Rescales all creatures for an instance based on set data
void ScaleAll(Player* player, MpInstanceData* instanceData);
// This will attempt to scale a creature using instancedata
void AddScaledCreature(Creature* creature, MpInstanceData* instanceData);
// Scales the creature based on the level and the creature base stats
void ScaleCreature(uint8 level, Creature* creature, MpMultipliers* multipliers, MpDifficulty difficulty);
// Scales a damage spell up based on the level increase
int32 ScaleDamageSpell(SpellInfo const * spellInfo, uint32 damage, MpCreatureData* creatureData, Creature* creature, Unit* target, float damageMultiplier);
// This scales a heal spell up based on the how much % the original heal spell was
int32 ScaleHealSpell(SpellInfo const * spellInfo, uint32 heal, MpCreatureData* creatureData, Creature* creature, Creature* target, float healMultiplier);
// Calculate spell damage based on player health pools
int32 CalculateSpellDamage(uint32 baseDamage, int originalLevel, int targetLevel);
// Calculate heal scaling based on creature health percentages
int32 CalculateHealScaling(uint32 baseHeal, uint32 originalHealth, uint32 currentMaxHealth);
static bool IsFinalBoss(Creature* creature);
static void GroupReset(Group* group, Map* map);
private:
MythicPlus() { }
~MythicPlus() { }
};
#define sMythicPlus MythicPlus::getInstance()
float GetTypeHealthModifier(int32 rank);
float GetTypeDamageModifier(int32 rank);
float CalculateScaling(int levelDifference, float scaleFactor, float constant = 1.25f, float growthFactor = 20.0f);
uint32 CalculateNewHealth(Creature* creature, CreatureTemplate const* cInfo, uint32 mapId, MpDifficulty difficulty, uint32 origHealth, float confHPMod);
float CalculateNewBaseDamage(CreatureTemplate const* cInfo, uint32 mapId, MpDifficulty difficulty, float origDamage);
#endif
#define sMythicPlus MythicPlus::instance()
#endif // MYTHICPLUS_H

View File

@@ -1,22 +1,48 @@
#include "MpScheduler.h"
#include "MpLogger.h"
#include "Spells/AdvancmentSpells.cpp"
// Creature Overrides
enum {
RAGEFIRE_BAZZALAN = 11519
};
// This adds schedulers for use across scripts scoped to MythicPlus
void Add_MP_Schedulers() {
new MpScheduler_WorldScript();
}
void Addmod_mythic_plusScripts();
void AddAllCreatureScripts();
void AddAllMapScripts();
void AddCommandScripts();
void AddGlobalScripts();
void AddGroupScripts();
void AddPlayerScripts();
void AddUnitScripts();
void AddWorldScripts();
void Add_MP_AllCreatureScripts();
void Add_MP_AllMapScripts();
void Add_MP_CommandScripts();
void Add_MP_GlobalScripts();
void Add_MP_GroupScripts();
void Add_MP_PlayerScripts();
void Add_MP_UnitScripts();
void Add_MP_WorldScripts();
void Add_MP_PlayerMessageEvents();
// Spell Scripts
void AddSC_AdvancementSpells();
void Addmod_mythic_plusScripts() {
Add_MP_AllCreatureScripts();
Add_MP_AllMapScripts();
Add_MP_CommandScripts();
Add_MP_GlobalScripts();
Add_MP_PlayerScripts();
Add_MP_UnitScripts();
Add_MP_WorldScripts();
Add_MP_Schedulers();
Add_MP_PlayerMessageEvents();
// Spell Scripts
AddSC_AdvancementSpells();
// new Ragefire_Bazzalan_Mythic();
// Add_MP_GroupScripts();
// list of boss / creature event handlers
// new Ragefire_Bazzalan_Mythic(RAGEFIRE_BAZZALAN);
void Addmod_mythic_plusScripts()
{
AddAllCreatureScripts();
AddAllMapScripts();
AddCommandScripts();
AddGlobalScripts();
AddGroupScripts();
AddPlayerScripts();
AddUnitScripts();
AddWorldScripts();
}

View File

@@ -1,56 +0,0 @@
#include "ScriptMgr.h"
#include "MythicPlus.h"
#include "Player.h"
class MythicPlus_PlayerScript : public PlayerScript
{
public:
MythicPlus_PlayerScript() : PlayerScript("MythicPlus_PlayerScript") { }
void OnLogin(Player *Player) override
{
// if (sMythicPlus->EnableGlobal && sMythicPlus->Announcement) {
// ChatHandler(Player->GetSession()).SendSysMessage("This server is running the |cff4CFF00MythicPlus |rmodule.");
// }
}
virtual void OnLevelChanged(Player* player, uint8 oldlevel) override
{
// Map* map = player->GetMap();
// if (!map || !map->IsDungeon())
// return;
// first update the map's player stats
// sMythicPlus->UpdateMapPlayerStats(map);
// // schedule all creatures for an update
// sMythicPlus->lastConfigTime =
// std::chrono::duration_cast<std::chrono::microseconds>(
// std::chrono::system_clock::now().time_since_epoch()
// ).count();
}
void OnGiveXP(Player* player, uint32& amount, Unit* victim, uint8 /*xpSource*/) override
{
// Map* map = player->GetMap();
}
// void OnBeforeDropAddItem
void OnBeforeLootMoney(Player* player, Loot* loot) override
{
// Map* map = player->GetMap();
// // If this isn't a dungeon, make no changes
// if (!map->IsDungeon())
// return;
}
};
void AddPlayerScripts()
{
new MythicPlus_PlayerScript();
}

View File

@@ -0,0 +1,138 @@
#include "CreatureAI.h"
#include "MpDataStore.h"
#include "MpLogger.h"
#include "MythicPlus.h"
#include "MpScriptAI.h"
#include "ScriptMgr.h"
class MythicPlus_AllCreatureScript : public AllCreatureScript
{
private:
std::unordered_map<ObjectGuid, uint32> m_creatureUpdateTimers;
public:
MythicPlus_AllCreatureScript() : AllCreatureScript("MythicPlus_AllCreatureScript") {}
// void OnBeforeCreatureSelectLevel(const CreatureTemplate* /*creatureTemplate*/, Creature* creature, uint8& level) override
// {
// }
void OnCreatureRespawn(Creature* creature)
{
Map* map = creature->GetMap();
if (!sMythicPlus->IsMapEligible(map)) {
return;
}
if (!sMythicPlus->IsCreatureEligible(creature)) {
return;
}
// If we have instance data, scale the creature, otherwise add it to be scaled later
if (MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId())) {
sMythicPlus->AddScaledCreature(creature, instanceData);
} else {
sMythicPlus->AddCreatureForScaling(creature);
}
}
/**
* @brief This hook runs every update for all creatures in the world.
* We only need to concern ourselves with creatures in the scope of our mythic+ instances.
* Need to detect the following changes:
* - Creature Death State - to trigger respawn scaling.
* - Other events where a creature enters the instance that is not scaled, then should be scaled up. Some special events normal enemies will be scripted
* to show up in encounters these will not trigger the OnCreatureAddWorld, because they were not during the initial load of the instance. (Though sometimes summons do trigger this?)
*
* @param creature
* @param diff
*/
void OnAllCreatureUpdate(Creature* creature, uint32 diff) override
{
// Skip any creatures not in an instance we are scaling first to avoid unnecessary work
if (!sMythicPlus->IsMapEligible(creature->GetMap())) {
return;
}
if (!sMythicPlus->IsCreatureEligible(creature)) {
return;
}
// throttle this check per creature to only run if more than 20ms has passed since last check
ObjectGuid creatureGuid = creature->GetGUID();
m_creatureUpdateTimers[creatureGuid] += diff;
if(m_creatureUpdateTimers[creatureGuid] < 20) {
return;
}
m_creatureUpdateTimers[creatureGuid] = 0;
auto instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
// no instance data yet means dont scale.
if(!instanceData) {
return;
}
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creature->GetGUID());
// this is a creature that was not scaled at instance load time, we need to scale it now.
if(!creatureData) {
MpLogger::debug("OnAllCreatureUpdate: Unknown Creature Add event scaling creature: {}", creature->GetName());
sMythicPlus->AddScaledCreature(creature, sMpDataStore->GetInstanceData(creature->GetMap()->GetId(), creature->GetMap()->GetInstanceId()));
return;
}
DeathState currentState = creature->getDeathState();
// record the death of our scaled creature
if(currentState == DeathState::Corpse && creatureData->lastDeathState != DeathState::Corpse) {
creatureData->lastDeathState = currentState;
return;
}
if(currentState == DeathState::Alive && creatureData->lastDeathState == DeathState::Corpse) {
MpLogger::debug("OnAllCreatureUpdate: Creature Death event scaling creature: {} level: {} guid: {} event: {}", creature->GetName(), creatureData->creature->GetLevel(), creature->GetGUID().ToString(), creature->getDeathState());
if(creature->IsDungeonBoss() || creature->GetEntry() == 23682) {
sMythicPlus->AddScaledCreature(creature, instanceData);
} else {
sMythicPlus->AddScaledCreature(creature, instanceData);
}
}
}
// When a new creature is added into a mythic+ map add it to the list of creatures to scale later.
void OnCreatureAddWorld(Creature* creature) override
{
Map* map = creature->GetMap();
if (!sMythicPlus->IsMapEligible(map)) {
return;
}
if (!sMythicPlus->IsCreatureEligible(creature)) {
return;
}
// if we have instance data about zone then just scale the creature otherwise add to be scaled once we do.
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
if(instanceData) {
sMythicPlus->AddScaledCreature(creature, instanceData);
} else {
sMythicPlus->AddCreatureForScaling(creature);
}
}
// Cleanup the creature from custom data used for mythic+ mod
void OnCreatureRemoveWorld(Creature* creature) override
{
sMythicPlus->RemoveCreature(creature);
}
};
void Add_MP_AllCreatureScripts()
{
MpLogger::debug("Add_MP_AllCreatureScripts");
new MythicPlus_AllCreatureScript();
}

View File

@@ -0,0 +1,133 @@
#include "Chat.h"
#include "MpLogger.h"
#include "Map.h"
#include "MpDataStore.h"
#include "MythicPlus.h"
#include "Player.h"
#include "ScriptMgr.h"
class MythicPlus_AllMapScript : public AllMapScript
{
public:
MythicPlus_AllMapScript() : AllMapScript("MythicPlus_AllMapScript")
{
}
void OnCreateMap(Map* /*map*/) { }
/**
* When a player enters the map check it needs to set up the instance data
*/
void OnPlayerEnterAll(Map* map, Player* player)
{
if (!sMythicPlus->IsMapEligible(map)) {
return;
}
if(!sMythicPlus->IsDifficultySet(player)) {
return;
}
Group* group = player->GetGroup();
if (group) {
MpLogger::debug("Player {} entered map {} in groupLeader {}", player->GetName(), map->GetMapName(), group->GetLeaderName());
} else {
return;
}
// if there is not any group data for this group then just bail
const MpGroupData* groupData = sMpDataStore->GetGroupData(group->GetGUID());
if (!groupData) {
return;
}
// Check if we already have mythic instance data set for this map and group
MpInstanceData* existingData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
if (existingData) {
if(player->GetName() == group->GetLeaderName()) {
MpLogger::debug("Instance data already set for Map: {} InstanceId: {} for GroupLeader: {} ",
map->GetMapName(),
map->GetInstanceId(),
group->GetLeaderName()
);
}
return;
}
MpInstanceData instanceData;
switch(groupData->difficulty) {
case MP_DIFFICULTY_MYTHIC:
instanceData.boss = sMythicPlus->mythicBossModifiers;
instanceData.creature = sMythicPlus->mythicDungeonModifiers;
instanceData.itemRewards = sMythicPlus->EnableItemRewards;
instanceData.deathLimits = sMythicPlus->mythicDeathAllowance;
instanceData.itemOffset = sMythicPlus->mythicItemOffset;
break;
case MP_DIFFICULTY_LEGENDARY:
instanceData.boss = sMythicPlus->legendaryBossModifiers;
instanceData.creature = sMythicPlus->legendaryDungeonModifiers;
instanceData.itemRewards = sMythicPlus->EnableItemRewards;
instanceData.deathLimits = sMythicPlus->legendaryDeathAllowance;
instanceData.itemOffset = sMythicPlus->legendaryItemOffset;
break;
case MP_DIFFICULTY_ASCENDANT:
instanceData.boss = sMythicPlus->ascendantBossModifiers;
instanceData.creature = sMythicPlus->ascendantDungeonModifiers;
instanceData.itemRewards = sMythicPlus->EnableItemRewards;
instanceData.deathLimits = sMythicPlus->ascendantDeathAllowance;
instanceData.itemOffset = sMythicPlus->ascendantItemOffset;
break;
default:
MpLogger::debug("No difficulty set for group {}", group->GetGUID().GetCounter());
return;
}
instanceData.difficulty = groupData->difficulty;
// Attempt to cast map to InstanceMap, making sure it is not null
instanceData.instance = dynamic_cast<InstanceMap*>(sMapMgr->FindMap(map->GetId(), map->GetInstanceId()));
if (!instanceData.instance)
{
MpLogger::error("Failed to find InstanceMap for map ID {} and instance ID {}.", map->GetId(), map->GetInstanceId());
return;
}
MpLogger::debug("Setting up instance data for group {} for map {} instance {} data {}",
group->GetGUID().GetCounter(),
map->GetMapName(),
map->GetInstanceId(),
instanceData.ToString()
);
sMpDataStore->AddInstanceData(map->GetId(), map->GetInstanceId(), instanceData);
// Save the instance data for the user to the database
if (player) {
sMpDataStore->DBUpdatePlayerInstanceData(player->GetGUID(), groupData->difficulty, map->GetId(), map->GetInstanceId(), 0);
}
// Once we have instance data set we can scale the remaining characters in our instance
sMythicPlus->ScaleRemaining(player, &instanceData);
}
// When an instance is destroyed remove the instance data from the data store
virtual void OnDestroyInstance(MapInstanced* /*mapInstanced*/, Map* map)
{
if (!sMythicPlus->IsMapEligible(map)) {
return;
}
// Removes currenct GroupData Instance Data and removes from database storage
sMpDataStore->RemoveInstanceData(map->GetId(), map->GetInstanceId());
// remove group instance and group instance data from database during a reset
sMpDataStore->DBRemovePlayerInstanceData(map->GetInstanceId());
sMpDataStore->DBRemoveGroupInstanceData(map->GetInstanceId());
}
};
void Add_MP_AllMapScripts()
{
MpLogger::debug("Add_MP_AllMapScripts()");
new MythicPlus_AllMapScript();
}

View File

@@ -0,0 +1,410 @@
#include "Chat.h"
#include "AdvancementMgr.h"
#include "MpDataStore.h"
#include "MythicPlus.h"
#include "MpDataStore.h"
#include "MpLogger.h"
#include "Player.h"
#include "ScriptMgr.h"
using namespace Acore::ChatCommands;
// make sure this is the new way to do this, i think it's the old busted shit
class MythicPlus_CommandScript : public CommandScript
{
public:
MythicPlus_CommandScript() : CommandScript("MythicPlus_CommandScript")
{
}
ChatCommandTable GetCommands() const override
{
static ChatCommandTable commandTableMain =
{
{"", HandleHelp, SEC_PLAYER, Console::No},
{"status", HandleStatus, SEC_PLAYER, Console::No},
{"set", HandleSetDifficulty, SEC_PLAYER, Console::No},
{"disable", HandleDisable, SEC_ADMINISTRATOR, Console::Yes},
{"enable", HandleEnable, SEC_ADMINISTRATOR, Console::Yes},
{"rescale", HandleReScale, SEC_GAMEMASTER, Console::No},
{"rescale all", HandleReScaleAll, SEC_GAMEMASTER, Console::No},
{"change melee", HandleChangeMelee, SEC_ADMINISTRATOR, Console::Yes},
{"change spell", HandleChangeSpell, SEC_ADMINISTRATOR, Console::Yes},
{"change health", HandleChangeHealth, SEC_ADMINISTRATOR, Console::Yes}
};
static ChatCommandTable commandTable =
{
{"mp", commandTableMain},
{"mythicplus", commandTableMain},
{"mp debug", HandleDebug, SEC_PLAYER, Console::No},
{"mp reload", HandleReload, SEC_GAMEMASTER, Console::No},
{"advancement", HandleAdvancement, SEC_PLAYER, Console::No}
};
return commandTable;
}
static bool HandleHelp(ChatHandler* handler, const std::vector<std::string>& /*args*/)
{
std::string helpText = "Mythic+ Commands:\n"
" .mp status - show current global settings of Mythic+ mod\n"
" .mp set [normal, heroic, mythic,legendary,ascendant] - Set Mythic+ difficulty in current beta only supports mythic.\n"
" .mp [enable,disable] - enable or disable this mod\n"
" .mp - Show this help message\n";
handler->PSendSysMessage(helpText);
return true;
}
static bool HandleReload(ChatHandler* handler)
{
sMpDataStore->LoadScaleFactors();
handler->PSendSysMessage("Mythic+ scale factors updated.");
return true;
}
static bool HandleDebug(ChatHandler* handler)
{
Creature* target = handler->getSelectedCreature();
if(!target) {
handler->PSendSysMessage("You must select a creature to debug.");
return true;
}
CreatureTemplate const* creatureTemplate = target->GetCreatureTemplate();
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(target->GetGUID());
handler->PSendSysMessage(LANG_NPCINFO_LEVEL, target->GetLevel());
handler->PSendSysMessage(LANG_NPCINFO_HEALTH, target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
handler->PSendSysMessage("WeaponDmg Main {} - {}",
target->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE),
target->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE)
);
handler->PSendSysMessage("WeaponDmg Range {} - {}",
target->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE),
target->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE)
);
handler->PSendSysMessage("WeaponDmg Offhand {} - {}",
target->GetWeaponDamageRange(OFF_ATTACK, MINDAMAGE),
target->GetWeaponDamageRange(OFF_ATTACK, MAXDAMAGE)
);
handler->PSendSysMessage("Attack Power Main {}", target->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE));
handler->PSendSysMessage("Attack Power Ranged {}", target->GetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE));
handler->PSendSysMessage("Armor {}", target->GetArmor());
handler->PSendSysMessage("Damage Modifier on template {}",creatureTemplate->DamageModifier);
if(creatureData) {
handler->PSendSysMessage("CreatureData: {}", creatureData->ToString());
}
return true;
}
// sets the difficluty for the group
static bool HandleSetDifficulty(ChatHandler* handler, const std::vector<std::string>& args)
{
Player* player = handler->GetSession()->GetPlayer();
Group* group = player->GetGroup();
if (!group) {
MpLogger::debug("HandleSetMythic() No Group for player: {}", player->GetName());
handler->PSendSysMessage("|cFFFF0000 You must be in a group to be able to set a Mythic+ difficulty.");
return true;
}
if (args.empty()) {
handler->PSendSysMessage("|cFFFF0000 You must specify a difficulty level. Expected values are 'mythic', 'legendary', or 'ascendant'.");
return true;
}
std::string difficulty = args[0];
// if(!sMythicPlus->IsDifficultyEnabled(difficulty)) {
// handler->PSendSysMessage("|cFFFF0000 The difficulty level you have selected is not enabled.");
// return true;
// }
if (!group->IsLeader(player->GetGUID())) {
handler->PSendSysMessage("|cFFFF0000 You must be the group leader to set a Mythic+ difficulty.");
return true;
}
if (player->GetMap()->IsDungeon()) {
player->ResetInstances(player->GetGUID(), INSTANCE_RESET_CHANGE_DIFFICULTY, false);
player->SendResetInstanceSuccess(player->GetMap()->GetId());
return true;
}
if (difficulty == "mythic") {
sMpDataStore->AddGroupData(group, MpGroupData(group, MP_DIFFICULTY_MYTHIC));
}
else if (difficulty == "legendary") {
sMpDataStore->AddGroupData(group,MpGroupData(group, MP_DIFFICULTY_LEGENDARY));
}
else if (difficulty == "ascendant") {
sMpDataStore->AddGroupData(group, MpGroupData(group, MP_DIFFICULTY_ASCENDANT));
}
else if (difficulty == "heroic") {
sMpDataStore->RemoveGroupData(group);
group->SetDungeonDifficulty(DUNGEON_DIFFICULTY_HEROIC);
}
else if (difficulty == "normal") {
sMpDataStore->RemoveGroupData(group);
group->SetDungeonDifficulty(DUNGEON_DIFFICULTY_NORMAL);
}
else {
handler->PSendSysMessage("|cFFFF0000 Invalid difficulty level. Expected values are 'normal', 'heroic', 'mythic', 'legendary', or 'ascendant'.");
return true;
}
handler->PSendSysMessage("Mythic+ difficulty set to: " + difficulty);
return true;
}
static bool HandleMythic(ChatHandler* handler, const std::vector<std::string>& /*args*/)
{
return HandleSetDifficulty(handler, {"mythic"});
}
static bool HandleLegendary(ChatHandler* handler, const std::vector<std::string>& /*args*/)
{
return HandleSetDifficulty(handler, {"legendary"});
}
static bool HandleAscendant(ChatHandler* handler, const std::vector<std::string>& /*args*/)
{
return HandleSetDifficulty(handler, {"ascendant"});
}
static bool HandleStatus(ChatHandler* handler)
{
Player* player = handler->GetPlayer();
Map* map = player->GetMap();
uint32 mapId = player->GetMapId();
std::string status = Acore::StringFormat("Mythic+ Status:\n Mythic+ Enabled: {}\n Mythic+ Item Rewards: {}\n Mythic+ DeathLimits: {}\n",
std::string((sMythicPlus->Enabled) ? "Yes" : "No"),
std::string((sMythicPlus->EnableItemRewards) ? "Yes" : "No"),
std::string((sMythicPlus->EnableDeathLimits) ? "Yes" : "No")
);
if (player->GetGroup()) {
auto groupData = sMpDataStore->GetGroupData(player->GetGroup()->GetGUID());
if (groupData) {
MpScaleFactor scaleFactors;
if(map->IsDungeon()) {
scaleFactors = sMpDataStore->GetScaleFactor(mapId, groupData->difficulty);
}
status += Acore::StringFormat(" Group Difficulty: {}\n Group Deaths: {}\n Scale FactorStr {}\n",
(groupData->difficulty) ? groupData->difficulty : 0,
(groupData->GetDeaths(player->GetMapId(), player->GetInstanceId())),
scaleFactors.ToString()
);
} else {
status += " Group Difficulty: Not Set\n";
}
}
handler->PSendSysMessage(status);
return true;
}
static bool HandleReScale(ChatHandler* handler)
{
Creature* creature = handler->getSelectedCreature();
if(!creature) {
handler->PSendSysMessage("You must select a creature to rescale.");
return true;
}
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creature->GetGUID());
if(!creatureData) {
handler->PSendSysMessage("Creature is not eligible for rescaling.");
return true;
}
auto instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
if(!instanceData) {
handler->PSendSysMessage("No instance data found for this creature.");
return true;
}
if(creature->IsDungeonBoss() || creature->GetEntry() == 23682) {
sMythicPlus->ScaleCreature(creature->GetLevel(), creature, &instanceData->boss, instanceData->difficulty);
} else {
sMythicPlus->ScaleCreature(creature->GetLevel(), creature, &instanceData->creature, instanceData->difficulty);
}
handler->PSendSysMessage("Creature rescaled: %s", creature->GetName());
return true;
}
static bool HandleReScaleAll(ChatHandler* handler)
{
Player* player = handler->GetPlayer();
if(!player) {
handler->PSendSysMessage("You must be a player to rescale all creatures.");
return true;
}
Map* map = player->GetMap();
if(!map) {
handler->PSendSysMessage("You must be in a map to rescale all creatures.");
return true;
}
int32 mapId = map->GetId();
int32 instanceId = map->GetInstanceId();
auto instanceData = sMpDataStore->GetInstanceData(mapId, instanceId);
if(!instanceData) {
handler->PSendSysMessage("No mythic instance data found for this map.");
return true;
}
sMythicPlus->ScaleAll(player, instanceData);
handler->PSendSysMessage("All creatures rescaled.");
return true;
}
static bool HandleDisable(ChatHandler* handler)
{
MpLogger::debug("HandleDisable()");
sMythicPlus->Enabled = false;
handler->SendSysMessage("Mythic+ mod has been disabled.");
return true;
}
static bool HandleEnable(ChatHandler* handler)
{
MpLogger::debug("HandleEnable()");
sMythicPlus->Enabled = false;
handler->SendSysMessage("Mythic+ mod has been enabled.");
return true;
}
static bool HandleChangeMelee(ChatHandler* handler, const std::vector<std::string>& args)
{
if (args.empty()) {
handler->PSendSysMessage("|cFFFF0000 You must specify a value to set the melee scale factor.");
return true;
}
Player* player = handler->GetSession()->GetPlayer();
if (!player) {
handler->PSendSysMessage("|cFFFF0000 Invalid session or player.");
return true;
}
if (player->GetGroup()) {
auto groupData = sMpDataStore->GetGroupData(player->GetGroup()->GetGUID());
if(groupData) {
float value = std::stof(args[0]);
sMpDataStore->SetMeleeScaleFactor(player->GetMapId(), groupData->difficulty, value);
handler->PSendSysMessage(Acore::StringFormat("Melee scale factor set to: {}", value));
return true;
}
}
handler->PSendSysMessage("|cFFFF0000 You must be in a group and mythic+ instance to set a melee scale factor.");
return true;
}
static bool HandleChangeSpell(ChatHandler* handler, const std::vector<std::string>& args)
{
if (args.empty()) {
handler->PSendSysMessage("|cFFFF0000 You must specify a value to set the spell scale factor.");
return true;
}
Player* player = handler->GetSession()->GetPlayer();
if (!player) {
handler->PSendSysMessage("|cFFFF0000 Invalid session or player.");
return true;
}
if (player->GetGroup()) {
auto groupData = sMpDataStore->GetGroupData(player->GetGroup()->GetGUID());
if(groupData) {
float value = std::stof(args[0]);
sMpDataStore->SetSpellScaleFactor(player->GetMapId(), groupData->difficulty, value);
handler->PSendSysMessage(Acore::StringFormat("Spell scale factor set to: {}", value));
return true;
}
}
handler->PSendSysMessage("|cFFFF0000 You must be in a group and mythic+ instance to set a melee scale factor.");
return true;
}
static bool HandleChangeHealth(ChatHandler* handler, const std::vector<std::string>& args)
{
if (args.empty()) {
handler->PSendSysMessage("|cFFFF0000 You must specify a value to set the health scale factor.");
return true;
}
Player* player = handler->GetSession()->GetPlayer();
if (!player) {
handler->PSendSysMessage("|cFFFF0000 Invalid session or player.");
return true;
}
if (player->GetGroup()) {
auto groupData = sMpDataStore->GetGroupData(player->GetGroup()->GetGUID());
if(groupData) {
float value = std::stof(args[0]);
sMpDataStore->SetHealthScaleFactor(player->GetMapId(), groupData->difficulty, value);
handler->PSendSysMessage(Acore::StringFormat("Health scale factor set to: {}", value));
return true;
}
}
handler->PSendSysMessage("|cFFFF0000 You must be in a group and mythic+ instance to set a melee scale factor.");
return true;
}
static bool HandleAdvancement(ChatHandler* handler)
{
Player* player = handler->GetSession()->GetPlayer();
std::string message = "";
for(int i =0; i < MpAdvancements::MP_ADV_MAX; i++) {
MpPlayerRank* playerRank = sAdvancementMgr->GetPlayerAdvancementRank(player, static_cast<MpAdvancements>(i));
if(!playerRank) {
continue;
}
message += Acore::StringFormat("Your Advancement Bonuses: \n {}: {} bonus: {}", MpAdvancementsToString(static_cast<MpAdvancements>(i)), playerRank->rank, playerRank->bonus);
}
if(message.empty()) {
message = "You have no advancements.";
}
handler->PSendSysMessage(message);
return true;
}
};
void Add_MP_CommandScripts()
{
MpLogger::debug("Add_MP_CommandScripts()");
new MythicPlus_CommandScript();
}

View File

@@ -0,0 +1,97 @@
#include "MpLogger.h"
#include "MythicPlus.h"
#include "MpConstants.h"
#include "ScriptMgr.h"
#include "Player.h"
#include "Map.h"
class MythicPlus_GlobalScript : public GlobalScript
{
public:
MythicPlus_GlobalScript() : GlobalScript("MythicPlus_GlobalScript") { }
// This adds the mythic+ item scaling to the loot table for enemies
void OnBeforeDropAddItem(Player const* player, Loot& loot, bool /*canRate*/, uint16 /*lootMode*/, LootStoreItem* LootStoreItem, LootStore const& store) override {
if(LootStoreItem->itemid == 0) {
return;
}
// Not playing on mythic+ difficulty skip doing loot
if(!sMythicPlus->IsDifficultySet(player)) {
return;
}
// Not on an eligible map skip doing loot
Map* map = player->GetMap();
if (!sMythicPlus->IsMapEligible(map)) {
return;
}
MpInstanceData* mythicSettings = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
// if there are not mythic settings set for this group and map skip
if (!mythicSettings) {
MpLogger::warn("No mythic settings found for map {} instance {}", map->GetMapName(), map->GetInstanceId());
return;
}
// if the item rewards are disabled skip
if (mythicSettings->itemRewards == false ) {
return;
}
// get the item to scale up
ItemTemplate const* origItem = sObjectMgr->GetItemTemplate(LootStoreItem->itemid);
if (!origItem) {
// If there is not a scaled up item and the item is a below quality green then set an invalid item_id so it is not added to loot
ItemTemplate const* nonMythicItem = sObjectMgr->GetItemTemplate(LootStoreItem->itemid);
if (nonMythicItem->Quality < 2) {
LootStoreItem->itemid = 0;
return;
}
// otherwise roll a chance to see a shadowy remains item is provided instead only if there is not already a shadowy remains item on the corpse
bool hasShadowyRemains = false;
for (auto& item : loot.items) {
if(item.itemid == MpConstants::SHADOWY_REMAINS) {
hasShadowyRemains = true;
break;
}
}
if (!hasShadowyRemains) {
LootStoreItem->itemid = MpConstants::SHADOWY_REMAINS;
return;
} else {
LootStoreItem->itemid = 0;
return;
}
}
uint32 newItemId = origItem->ItemId + mythicSettings->itemOffset;
ItemTemplate const* newItemTempl = sObjectMgr->GetItemTemplate(newItemId);
if(!newItemTempl) {
MpLogger::warn("New Loot Item not found for itemid {} original item: {} ({})", newItemId, origItem->Name1, origItem->ItemId);
return;
}
LootStoreItem->itemid = newItemId;
// Revalidate the LootStoreItem to ensure consistency
if (!LootStoreItem->IsValid(store, newItemId)) {
MpLogger::info("LootStoreItem is not valid after updating itemid to {} in OnBeforeDropAddItem()", newItemId);
return;
}
}
};
void Add_MP_GlobalScripts()
{
MpLogger::debug("Add_MP_GlobalScripts()");
new MythicPlus_GlobalScript();
}

100
src/Scripts/GroupScript.cpp Normal file
View File

@@ -0,0 +1,100 @@
#include "MpDataStore.h"
#include "MpLogger.h"
#include "ScriptMgr.h"
#include "Group.h"
// this handles updating custom group difficulties used in auto balancing mobs and
// scripts that enable buffs on mobs randomly
class MythicPlus_GroupScript : public GroupScript
{
public:
MythicPlus_GroupScript() : GroupScript("MythicPlus_GroupScript") { }
void OnAddMember(Group* group, ObjectGuid guid) override {
if (!group || !guid) {
return;
}
Player* player = ObjectAccessor::FindPlayer(guid);
if (!player) {
MpLogger::warn("Player not found for guid {}", guid.GetCounter());
return;
}
MpGroupData *gd = sMpDataStore->GetGroupData(group->GetGUID());
MpPlayerData* pd = sMpDataStore->GetPlayerData(guid);
if(!pd) {
MpDifficulty difficulty = GetPlayerDifficulty(player);
MpPlayerData playerData = MpPlayerData(player, difficulty, group->GetGUID().GetCounter());
sMpDataStore->AddPlayerData(guid, &playerData);
} else {
// If the player is joining a new group then reset the death counters otherwise let them ride
if (pd->groupId != group->GetGUID().GetCounter()) {
pd->groupId = group->GetGUID().GetCounter();
pd->ResetAllDeathCounts();
}
}
if(!gd) {
MpLogger::warn("Group data not found for group {}", group->GetGUID().GetCounter());
return;
}
gd->AddPlayerData(pd);
}
void OnCreate(Group* group, Player* leader) override {
if (!group) {
return;
}
if(!leader) {
return;
}
// Start a group and set the data up for the group
MpDifficulty difficulty = GetPlayerDifficulty(leader);
MpGroupData gd = MpGroupData(group, difficulty);
// Insert the leader of the group after group data struct is built
MpPlayerData* pd = sMpDataStore->GetPlayerData(leader->GetGUID());
if(pd) {
gd.AddPlayerData(pd);
} else {
MpPlayerData playerData = MpPlayerData(leader, difficulty, group->GetGUID().GetCounter());
gd.AddPlayerData(&playerData);
}
// Store the data into our memory store
sMpDataStore->AddGroupData(group, gd);
}
void OnDisband(Group* group) override {
sMpDataStore->RemoveGroupData(group);
}
// Get the difficulty for a player that is assigned
MpDifficulty GetPlayerDifficulty(Player* player) {
if(!player) {
return MP_DIFFICULTY_NORMAL;
}
MpPlayerData* pd = sMpDataStore->GetPlayerData(player->GetGUID());
if(pd) {
return pd->difficulty;
} else {
return player->GetDifficulty(false) == Difficulty::DUNGEON_DIFFICULTY_NORMAL ? MP_DIFFICULTY_NORMAL : MP_DIFFICULTY_HEROIC;
}
return MP_DIFFICULTY_NORMAL;
}
};
void Add_MP_GroupScripts()
{
MpLogger::debug("Add_MP_GroupScripts()");
new MythicPlus_GroupScript();
}

View File

@@ -0,0 +1,91 @@
#include "MpLogger.h"
#include "MythicPlus.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "AdvancementMgr.h"
#include "Chat.h"
#include "Channel.h"
#include "ChannelMgr.h"
#include "MpEventProcessor.h"
#include <boost/algorithm/string/predicate.hpp> // For starts_with
#include <vector>
#include <string>
#include <ranges>
/**
* This script file is a special event handler attached to the chat channel for MythicPlus to intercept
* message events from the client hidden chat channel and process them, as well as return events back to
* the client. It's a very simplified version of how Eluna / AIO manage messages from UI to C++ mods.
*
* All Messages come into a chat channel from a specific user on a hidden channel with details in the MythicPlus.h
* class for the protocol data definition.
*/
class MythicPlus_PlayerMessageEvents : public PlayerScript
{
public:
MythicPlus_PlayerMessageEvents() : PlayerScript("MythicPlus_PlayerMessageEvents") {}
/**
* Listens to AddOn Chat channel for Mythic+ communication between UI and server mythic+ functionality
*/
void OnChat(Player* player, uint32 type, uint32 lang, std::string& msg, Player* receiver) override
{
// All communication from the client should be a whisper to themselves over tha addon channel
if(!player || !receiver) {
return;
}
if(lang == LANG_ADDON) {
if(msg.empty()) {
MpLogger::info("Empty AddOn message received from player: {}", player->GetName());
return;
}
// if the message begins with our prefix for our data channel then process the event
if(boost::starts_with(msg, MP_DATA_CHAT_CHANNEL)) {
sMpEventProcessor->ProcessMessage(player, msg);
}
}
}
/**
* When a player logs in add them to the data channel specifically for Mythic+ communication
* between UI and server module.
*
* Load advancement data for the player at load time used to apply buffs.
*/
// void OnLogin(Player* player) override
// {
// if(!player) {
// return;
// }
// // Create a channel called MpEx if it does not exist
// MpLogger::info("Player {} logged in on team {}", player->GetName(), player->GetTeamId());
// ChannelMgr* cmg = ChannelMgr::forTeam(player->GetTeamId());
// if(!cmg) {
// MpLogger::error("Failed to get channel manager for team {}", player->GetTeamId());
// return;
// }
// Channel* channel = cmg->GetChannel(static_cast<std::string>(MP_DATA_CHAT_CHANNEL), player);
// if(!channel) {
// MpLogger::error("Failed to get mythic data channel for player {}", player->GetName());
// Channel* nchan = new Channel(static_cast<std::string>(MP_DATA_CHAT_CHANNEL), 17, 0, player->GetTeamId());
// if(!nchan) {
// MpLogger::error("Failed to create mythic data channel for player {}", player->GetName());
// return;
// }
// }
// }
};
void Add_MP_PlayerMessageEvents()
{
MpLogger::debug("Add_MP_PlayerEventMessages");
new MythicPlus_PlayerMessageEvents();
}

View File

@@ -0,0 +1,285 @@
#include "MpLogger.h"
#include "MpDataStore.h"
#include "MpScheduler.h"
#include "MythicPlus.h"
#include "Player.h"
#include "Group.h"
#include "ScriptMgr.h"
#include "TaskScheduler.h"
#include "AdvancementMgr.h"
#include "Formulas.h"
class MythicPlus_PlayerScript : public PlayerScript
{
public:
MythicPlus_PlayerScript() : PlayerScript("MythicPlus_PlayerScript") {}
/**
* Mythic+ special actions when a player dies:
* - Track the death for the group
* - Update the player death stats
* - Determine whether or not the Group failed the instance due to death count setting.
*/
void OnPlayerKilledByCreature(Creature* killer, Player* player) override
{
Map* map = player->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
if (!player) {
return;
}
Group* group = player->GetGroup();
if(!group) {
MpLogger::warn("Missing group data for player {}", player->GetName());
return;
}
MpGroupData *data = sMpDataStore->GetGroupData(player->GetGroup());
if (!data) {
MpLogger::warn("Missing group data for player {}", player->GetName());
return;
}
MpPlayerData *playerData = sMpDataStore->GetPlayerData(player->GetGUID());
if (!playerData) {
MpLogger::warn("Missing player data for player {}", player->GetName());
return;
}
playerData->AddDeath(map->GetId(), map->GetInstanceId());
if(killer) {
sMpDataStore->DBAddPlayerDeath(player, killer, data->difficulty);
} else {
sMpDataStore->DBAddPlayerDeath(player);
}
sMpDataStore->DBAddGroupDeath(group, player->GetMapId(), player->GetInstanceId(), data->difficulty);
uint32 totalDeaths = data->GetDeaths(player->GetMapId(), player->GetInstanceId());
MpLogger::info("Total Deaths: {}", totalDeaths);
if(totalDeaths > 1) {
MpLogger::debug(" :::: Player Deaths for Group too high! ::::::");
TaskScheduler& wScheduler = sMpScheduler->GetWorldScheduler();
wScheduler.Schedule(10s, MP_WORLD_TASK_GROUP, [player, map](TaskContext /*ctx*/) {
Group* group = player->GetGroup();
if(!group) {
return;
}
MythicPlus::GroupReset(group, map);
});
}
// if(totalDeaths > 1) {
// Map* map = player->GetMap();
// if(!map) {
// return;
// }
// Group* group = player->GetGroup();
// if(!group) {
// MpLogger::warn("Player {} is not in a group.", player->GetName());
// return;
// }
// // map->RemoveAllPlayers();
// MpLogger::info("Starting scheduled failure notification");
// // auto testlambda = [](TaskContext ctx) { return; };
// sMpScheduler->ScheduleWorldTask(1s, [](TaskContext ctx) {
// MpLogger::info("<<<<<<<<<<< Player Death Scheduler fire >>>>>>>>>>>>>");
// });
// sMpScheduler->GetWorldScheduler().Schedule(1s, [playerName = player->GetName()](TaskContext ctx) {
// MpLogger::info("<<<<<<<<<<< Player Death Scheduler fire {} >>>>>>>>>>>>>", playerName);
// return;
// });
// std::vector<Player*> players = GetGroupMembers(player);
// MpLogger::info("Failed mythic+ instance run notification fired. ");
// WorldPacket data;
// for(Player* player : players)
// {
// MpLogger::info("Seding notification of failure to player: {}", player->GetName());
// player->GetSession()->SendShowBank(player->GetGUID());
// // player->GetSession()->SendNotification("Your group has died too many time to continue.");
// // ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, nullptr, player, message);
// // player->GetSession()->SendPacket(&data);
// }
}
void OnBeforeLootMoney(Player* player, Loot* loot) override
{
if (!loot->sourceWorldObjectGUID.IsCreature()) return;
Creature* creature = player->GetMap()->GetCreature(loot->sourceWorldObjectGUID);
if (!creature) return;
#ifdef NPC_BOT
if(creature->IsNPCBotOrPet()) {
return;
}
#endif
// Check if this is a Mythic+ scaled creature
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creature->GetGUID());
if (!creatureData || !creatureData->IsScaled()) return;
// Different gold ranges based on creature rank
uint32 bossMinGold = 10000;
uint32 bossMaxGold = 13500;
uint32 minGold, maxGold;
// Determine gold range based on creature rank
if (creature->isWorldBoss() || creature->IsDungeonBoss())
{
// Boss: full range
minGold = bossMinGold;
maxGold = bossMaxGold;
}
else if (creature->GetCreatureTemplate()->rank == CREATURE_ELITE_RARE ||
creature->GetCreatureTemplate()->rank == CREATURE_ELITE_ELITE)
{
// Elite: 70% of boss range
minGold = uint32(bossMinGold * 0.7f);
maxGold = uint32(bossMaxGold * 0.7f);
}
else
{
// Normal: 40% of boss range
minGold = uint32(bossMinGold * 0.4f);
maxGold = uint32(bossMaxGold * 0.4f);
}
// Generate random gold amount in appropriate range
uint32 newGold = urand(minGold, maxGold);
// Apply server money rate
newGold = uint32(newGold * sWorld->getRate(RATE_DROP_MONEY));
loot->gold = newGold;
}
void OnGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override
{
if (xpSource != XPSOURCE_KILL || !victim) return;
Creature* creature = victim->ToCreature();
if (!creature) return;
#ifdef NPC_BOT
if(creature->IsNPCBotOrPet()) {
return;
}
#endif
// Check if this is a Mythic+ scaled creature
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creature->GetGUID());
if (!creatureData || !creatureData->IsScaled()) return;
// Recalculate XP using scaled level instead of original level
uint32 newBaseXP = Acore::XP::BaseGain(
player->GetLevel(),
creature->GetLevel(), // This is now the scaled level
GetContentLevelsForMapAndZone(creature->GetMapId(), creature->GetZoneId())
);
// Apply same modifiers as original calculation
float xpMod = 1.0f;
if (creature->isElite()) {
xpMod *= creature->GetMap()->IsDungeon() ? 2.75f : 2.0f;
}
xpMod *= creature->GetCreatureTemplate()->ModExperience;
amount = uint32(newBaseXP * xpMod * 1.5f); // flat bonus modifier for mythic dungeons
}
void OnLogin(Player* player) override
{
MpLogger::info("Player {} logged in", player->GetName());
// Load the player advancement data for the player when they login
sAdvancementMgr->LoadPlayerAdvancements(player);
// Cast all unique advancement spells
for(uint32 i = 1; i <= 10; ++i) {
uint32 spellId = 80000000 + i;
MpLogger::info("Casting spell {} to player {}", spellId, player->GetName());
player->AddAura(spellId, player);
}
}
// When a player is bound to an instance need to make sure they are saved in the data soure to retrieve later.
void OnBindToInstance(Player* player, Difficulty /*difficulty*/, uint32 mapId, bool /*permanent*/) override
{
if(!player) {
return;
}
Group* group = player->GetGroup();
// If they are not in a group do nothing.
if(!group) {
return;
}
MpGroupData* data = sMpDataStore->GetGroupData(group);
// If there is not any mythic+ data set for this group do nothing.
if(!data) {
return;
}
Map* map = player->GetMap();
if(!map) {
MpLogger::warn("Player {} is not in a map", player->GetName());
return;
}
// get the player data or set it up
MpPlayerData* playerData = sMpDataStore->GetPlayerData(player->GetGUID());
if(!playerData) {
playerData = new MpPlayerData(player, data->difficulty, group->GetGUID().GetCounter());
sMpDataStore->AddPlayerData(player->GetGUID(), playerData);
}
// Add this players data to the group data
data->AddPlayerData(playerData);
auto mapKey = sMpDataStore->GetInstanceDataKey(mapId, player->GetInstanceId());
playerData->instanceData.emplace(mapKey, MpPlayerInstanceData{
.deaths = 0,
});
sMpDataStore->DBUpdatePlayerInstanceData(player->GetGUID(), data->difficulty, map->GetId(), map->GetInstanceId());
sMpDataStore->DBUpdateGroupData(group->GetGUID(), data->difficulty, map->GetId(), map->GetInstanceId(), 0);
}
std::vector<Player*> GetGroupMembers(Player* currentPlayer)
{
std::vector<Player*> groupPlayers;
Group* group = currentPlayer->GetGroup();
if (!group)
{
MpLogger::warn("Player is not in a group.");
return groupPlayers;
}
group->DoForAllMembers([&](Player* member) {
groupPlayers.push_back(member);
});
return groupPlayers;
}
};
void Add_MP_PlayerScripts()
{
MpLogger::debug("Add_MP_PlayerScripts()");
new MythicPlus_PlayerScript();
}

476
src/Scripts/UnitScript.cpp Normal file
View File

@@ -0,0 +1,476 @@
#include "MpLogger.h"
#include "Player.h"
#include "MythicPlus.h"
#include "ScriptMgr.h"
#include "SpellAuraEffects.h"
class MythicPlus_UnitScript : public UnitScript
{
public:
MythicPlus_UnitScript() : UnitScript("MythicPlus_UnitScript", true) { }
private:
/**
* Handles damage from non-creature sources (GameObjects, Players, etc.)
* @tparam DamageType Type of damage (int32/float)
* @param target Target of the damage
* @param attacker The non-creature attacker (passed by reference and may be modified)
* @param damage Reference to damage value (will be modified)
* @param spellInfo The spell being cast
* @param eventType Type of event (spell/melee/etc)
*/
template<typename DamageType>
void HandleNonCreatureAttacker(Unit* target, Unit*& attacker, DamageType& damage,
SpellInfo const* spellInfo, MythicPlus::MP_UNIT_EVENT_TYPE eventType)
{
Map* map = target ? target->GetMap() : nullptr;
std::string attackerType = "nullptr";
std::string attackerName = "unknown";
uint32 entry = 0;
if (attacker) {
if (attacker->GetTypeId() == TYPEID_GAMEOBJECT) {
attackerType = "GameObject";
if (GameObject* go = attacker->ToGameObject()) {
entry = go->GetEntry();
if (GameObjectTemplate const* goInfo = go->GetGOInfo()) {
attackerName = goInfo->name;
}
}
} else if (attacker->GetTypeId() == TYPEID_PLAYER) {
attackerType = "Player";
attackerName = attacker->GetName();
} else if (attacker->GetTypeId() == TYPEID_UNIT) {
attackerType = "Unit (non-creature)";
attackerName = attacker->GetName();
} else {
attackerType = "Unknown Type";
}
}
// Try to find a creature attacker from target's attackers list if we have one use it for scaling
Unit::AttackerSet const& attackers = target ? target->getAttackers() : Unit::AttackerSet();
if (!attackers.empty()) {
attacker = *attackers.begin();
if (Creature* creatureAttacker = attacker->ToCreature()) {
if (MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creatureAttacker->GetGUID())) {
damage = static_cast<DamageType>(modifyIncomingDmgHeal(eventType, target, creatureAttacker,
static_cast<uint32>(damage), spellInfo)) * sMythicPlus->nonCreatureSpellReducer;
return;
}
} else {
MpLogger::debug("====== SPELL SCALING: Non-Creature attacker - Name: {}, Spell: {}({}), Damage: {}",
attackerName,
spellInfo ? spellInfo->SpellName[0] : "No Spell",
spellInfo ? spellInfo->Id : 0,
damage);
if (map) {
if (MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId())) {
damage = static_cast<DamageType>(damage * instanceData->creature.spell * sMythicPlus->nonCreatureSpellReducer);
return;
}
}
}
}
// Fallback to instance-based scaling if we can't find a nearest creature
else if (map) {
if (MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId())) {
damage = static_cast<DamageType>(damage * instanceData->creature.spell * sMythicPlus->nonCreatureSpellReducer);
return;
}
}
// Default scaling if no specific handler applied
return;
}
// Helper function to determine if a spell scales with Attack Power
bool IsAttackPowerScalingSpell(SpellInfo const* spellInfo) {
if (!spellInfo || spellInfo->Effects.empty()) {
return false;
}
auto mainEffect = spellInfo->Effects[0];
// Check 1: Direct weapon damage effects
bool isWeaponEffect = (mainEffect.Effect == SPELL_EFFECT_WEAPON_DAMAGE ||
mainEffect.Effect == SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL ||
mainEffect.Effect == SPELL_EFFECT_NORMALIZED_WEAPON_DMG ||
mainEffect.Effect == SPELL_EFFECT_WEAPON_PERCENT_DAMAGE);
// Check 2: Damage class indicates melee/ranged (scales with AP)
bool isMeleeOrRanged = (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE ||
spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED);
// Check 3: Requires weapon equipment
bool requiresWeapon = (spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON);
// Check 4: Specific spell families known to scale with AP
bool isKnownAPSpell = false;
if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE) {
// Rogue poisons and weapon-based abilities
isKnownAPSpell = (spellInfo->SpellFamilyFlags[0] & 0x10000) || // Deadly Poison flag
(spellInfo->SpellFamilyFlags[1] & 0x80000); // Other poison flags
}
// Return true if any indicator suggests AP scaling
return (isWeaponEffect || isMeleeOrRanged || requiresWeapon || isKnownAPSpell);
}
/**
* @brief This functions processes spell damage for DOTs and Direct Damage Spells it
* handles special cases for Melee scaling spells and AP scaling spells also so they
* are not scaled up twice and murder all my friends
*
* @tparam DamageType
* @param target
* @param attacker
* @param damage
* @param spellInfo
* @param eventType
* @param logPrefix
*/
template<typename DamageType>
void ProcessSpellDamage(Unit* target, Unit* attacker, DamageType& damage, SpellInfo const* spellInfo, MythicPlus::MP_UNIT_EVENT_TYPE eventType, const std::string& logPrefix) {
if(damage == 0) {
return;
}
// If this is a special case where the attacker is not a creature
if (!attacker || !attacker->ToCreature()) {
return HandleNonCreatureAttacker(target, attacker, damage, spellInfo, eventType);
}
Creature* creatureCaster = attacker->ToCreature();
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creatureCaster->GetGUID());
if (!creatureCaster) {
MpLogger::error("Creature caster is null in map {}", attacker ? attacker->GetMap()->GetId() : 0);
return;
}
if (!creatureData) {
MpLogger::error("Failed to get creature data for {} in map {}", creatureCaster->GetName(), attacker ? attacker->GetMap()->GetId() : 0);
return;
}
// Check if this spell scales with Attack Power
if (IsAttackPowerScalingSpell(spellInfo)) {
// need another special case here to determine if a spell was not scaled up by AP meaning the incoming damage is close to the
// original effect of the spell and therefore should instead use spell effect scaling it should be no more than 15% of the original effect
bool notScaledByAP = false;
if (spellInfo && !spellInfo->Effects.empty()) {
int32 baseEffect = spellInfo->Effects[0].CalcValue(attacker, nullptr, nullptr);
if (damage <= (baseEffect * 1.15f)) {
// MpLogger::debug(">>>> MELEE SPELL SCALING: Spell {} (ID: {}) is not scaled by AP damage: {} vs originalEffect: {}",
// spellInfo->SpellName[0], spellInfo->Id, damage, baseEffect);
notScaledByAP = true;
}
} else {
// If we can't determine the base effect, default to treating it as not AP-scaled
notScaledByAP = true;
// MpLogger::debug(">>>> MELEE SPELL SCALING: Could not determine base effect for spell, defaulting to spell scaling");
}
// if the effect type of the spell is not physical (aka not mitigated by armor/defense) then it needs to instead have the typical
// spell damage multiplier applied instead of melee damage scaling
if (! notScaledByAP && (spellInfo->SchoolMask == SPELL_SCHOOL_NORMAL || spellInfo->SchoolMask == SPELL_SCHOOL_MASK_NORMAL)) {
uint32 meleeDamage = static_cast<uint32>(std::max(0, static_cast<int32>(damage)));
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_MELEE, target, attacker, meleeDamage);
// MpLogger::debug(">>MELEE SPELL SCALING: {} hits with spell: {} ID: {} meleeDamage: {} damage: {}", attacker->GetName(), spellInfo->SpellName[0], spellInfo->Id, meleeDamage, damage);
} else {
// get the creatures original attack power
SpellEffectInfo const& effect = spellInfo->Effects[0];
uint32 spellDmg = static_cast<uint32>(effect.CalcValue(attacker, nullptr, nullptr) * effect.CalcDamageMultiplier(attacker, nullptr));
// now take the original attack power * 0.08 and add it to the spell damage
uint32 apDmg = static_cast<uint32>(creatureData->originalStats->AttackPower * 0.10f);
uint32 finalDmg = spellDmg + apDmg;
// MpLogger::debug(">> AP BASED DAMAGE Scaledown: origDamage: {} | spellDmg: {} | apDmg: {} | finalDmg: {}", static_cast<int32>(damage), spellDmg, apDmg, finalDmg);
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_SPELL, target, attacker, finalDmg, spellInfo);
// need to take into consideration if this is a stacking spell and multiply the final damage by the number of stacks
if(spellInfo->AttributesEx3 & SPELL_ATTR3_DOT_STACKING_RULE) {
Aura* aura = target->GetAura(spellInfo->Id, attacker->GetGUID());
uint32 stacks = aura ? aura->GetStackAmount() : 1;
if(aura) {
damage *= stacks;
}
}
}
return;
}
// Reverse the CalcValue scaling to get original base damage
int32 originalDamage = static_cast<int32>(damage);
if (creatureCaster && creatureData && creatureData->originalLevel < 70) {
CreatureTemplate const* cInfo = creatureCaster->GetCreatureTemplate();
// Get the scaling factors used in CalcValue
CreatureBaseStats const* pCBS = sObjectMgr->GetCreatureBaseStats(creatureCaster->GetLevel(), creatureCaster->getClass());
float CBSPowerCreature = pCBS->BaseDamage[cInfo->expansion];
uint32 tempLevel = spellInfo->SpellLevel;
if(tempLevel == 0) {
tempLevel = creatureData->originalLevel;
}
CreatureBaseStats const* spellCBS = sObjectMgr->GetCreatureBaseStats(tempLevel, creatureCaster->getClass());
float CBSPowerSpell = spellCBS->BaseDamage[cInfo->expansion];
// MpLogger::debug("SPELL SCALING: Creature Lvl {} -> {} | Spell Lvl {} | tempLevel: {} | CBSPowerCreature: {} CBSPowerSpell: {}",
// creatureData->originalLevel, creatureCaster->GetLevel(), tempLevel, CBSPowerCreature, CBSPowerSpell);
// Reverse the CalcValue scaling: originalDamage = scaledDamage / (CBSPowerCreature / CBSPowerSpell)
if (CBSPowerCreature > 0.0f) {
originalDamage = static_cast<int32>(static_cast<int32>(damage) * (CBSPowerSpell / CBSPowerCreature));
// MpLogger::debug("SPELL SCALING: Reversed CalcValue scaling - Scaled: {} -> Original: {} (Factor: {:.2f})",
// damage, originalDamage, CBSPowerSpell / CBSPowerCreature);
}
}
// Apply Mythic+ scaling to the original base damage
damage = static_cast<DamageType>(modifyIncomingDmgHeal(eventType, target, attacker, static_cast<uint32>(originalDamage), spellInfo));
}
public:
void ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage, SpellInfo const* spellInfo) override {
if (!target && !attacker) {
return;
}
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
auto effects = spellInfo->Effects;
bool isHot = false;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) {
switch(effects[i].Effect) {
case SPELL_EFFECT_HEAL:
case SPELL_EFFECT_HEAL_MAX_HEALTH:
case SPELL_EFFECT_HEAL_MECHANICAL:
case SPELL_EFFECT_HEAL_PCT:
case SPELL_EFFECT_SPIRIT_HEAL:
isHot = true;
break;
}
}
if(isHot) {
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_HOT, target, attacker, damage, spellInfo);
} else {
ProcessSpellDamage(target, attacker, damage, spellInfo, MythicPlus::UNIT_EVENT_DOT, "DOT DAMAGE");
}
}
void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage, SpellInfo const* spellInfo) override {
if (!target && !attacker) {
if(spellInfo) {
// MpLogger::info("ModifySpellDamageTaken: Target and attacker are null for spell: {} ID: {}", spellInfo->SpellName[0], spellInfo->Id);
}
return;
}
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
if(!sMythicPlus->EligibleDamageTarget(target)) {
if(spellInfo) {
// MpLogger::info("ModifySpellDamageTaken: Target is not eligible for spell: {} ID: {}", spellInfo->SpellName[0], spellInfo->Id);
}
return;
}
// MpLogger::debug("ModifySpellDamageTaken: {} hits {} with spell: {} ID: {}", attacker ? attacker->GetName() : "[null]", target ? target->GetName() : "[null]", spellInfo ? spellInfo->SpellName[0] : "[no spell]", spellInfo ? spellInfo->Id : 0);
// Use the generic ProcessSpellDamage function
ProcessSpellDamage(target, attacker, damage, spellInfo, MythicPlus::UNIT_EVENT_SPELL, "SPELL DAMAGE");
}
/**
* Directly Modify the melee damage characters and allied creatures will
* receive from mythic+ scaled enemies.
*/
void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage) override {
if (!target && !attacker) {
return;
}
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_MELEE, target, attacker, damage);
}
// When a healing spell hits a mythic+ enemy modify based on the modifiers for the difficulty
void ModifyHealReceived(Unit* target, Unit* healer, uint32& healing, SpellInfo const* spellInfo) override {
if (!target && !healer) {
return;
}
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
healing = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_HEAL, target, healer, healing, spellInfo);
}
uint32 modifyIncomingDmgHeal(MythicPlus::MP_UNIT_EVENT_TYPE eventType,Unit* target, Unit* attacker, uint32 damageOrHeal, SpellInfo const* spellInfo = nullptr) {
if (!target && !attacker) {
// MpLogger::info("modifyIncomingDmgHeal: Target and attacker are null for event {}", eventType);
return damageOrHeal;
}
int32 alteredDmgHeal = 0;
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return damageOrHeal;
}
if(attacker && attacker->IsPlayer()) {
return damageOrHeal;
}
#if defined(MOD_PRESENT_NPCBOTS)
if (attacker && attacker->IsNPCBotOrPet()) {
return damageOrHeal;
}
#endif
Creature* creature = attacker ? attacker->ToCreature() : nullptr;
if (!creature) {
MpLogger::debug("Attacker was considered not a creature");
return damageOrHeal;
}
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
if(!instanceData) {
return damageOrHeal;
}
std::string eventName = "";
switch (eventType) {
case MythicPlus::UNIT_EVENT_MELEE:
eventName = "Melee";
break;
case MythicPlus::UNIT_EVENT_HEAL:
eventName = "Heal";
break;
case MythicPlus::UNIT_EVENT_DOT:
eventName = "DOT";
break;
case MythicPlus::UNIT_EVENT_SPELL:
eventName = "Spell";
break;
case MythicPlus::UNIT_EVENT_HOT:
eventName = "HOT";
break;
}
// If the target is the enemy then increase the amount of healing by the instance data modifier for spell output.
if(sMythicPlus->EligibleDamageTarget(target)) {
/**
* @TODO: Allow more granular control over the scaling of DOT, HOT, and other spell effects
* in the future if needed
*/
switch (eventType) {
case MythicPlus::UNIT_EVENT_MELEE:
// Damage that is not mitigated by armor needs to be debuffed as it hits too hard and without resists
// it hits too hard give everyone a benefit of 30% armor reduction
MpLogger::debug(">>> Modify Melee Damage: Creature Name: {} alteredDmgHeal: {} School Mask: {}", creature->GetName(), alteredDmgHeal, creature->GetMeleeDamageSchoolMask());
if(creature->GetMeleeDamageSchoolMask() != SPELL_SCHOOL_MASK_NORMAL && creature->GetMeleeDamageSchoolMask() != SPELL_SCHOOL_MASK_NONE) {
damageOrHeal = damageOrHeal * 0.50f;
}
if(creature->IsDungeonBoss() || creature->isWorldBoss() || creature->GetEntry() == 23682) {
alteredDmgHeal = damageOrHeal * instanceData->boss.melee;
} else {
alteredDmgHeal = damageOrHeal * instanceData->creature.melee;
}
// MpLogger::debug(">>>>>>>>>>>> Incoming Melee New Damage: {}({}) {} hits {}", alteredDmgHeal, damageOrHeal, attacker->GetName(), target->GetName());
break;
case MythicPlus::UNIT_EVENT_DOT:
case MythicPlus::UNIT_EVENT_SPELL:
if(creature->IsDungeonBoss() || creature->isWorldBoss() || creature->GetEntry() == 23682) {
if(spellInfo) {
// MpLogger::debug("Scaling spell {} using ScaleDamageSpell() Original Damage: {} New Damage: {}", spellInfo->SpellName[0], damageOrHeal, alteredDmgHeal);
alteredDmgHeal = sMythicPlus->ScaleDamageSpell(spellInfo, damageOrHeal, sMpDataStore->GetCreatureData(attacker->GetGUID()), creature, target, instanceData->boss.spell);
} else {
alteredDmgHeal = damageOrHeal * instanceData->boss.spell;
// MpLogger::debug("Scaling spell {} using flat modifier Original Damage: {} New Damage: {}", spellInfo->SpellName[0], damageOrHeal, alteredDmgHeal);
}
} else {
if(spellInfo) {
// MpLogger::debug("Scaling spell {} using ScaleDamageSpell() Original Damage: {} New Damage: {}", spellInfo->SpellName[0], damageOrHeal, alteredDmgHeal);
alteredDmgHeal = sMythicPlus->ScaleDamageSpell(spellInfo, damageOrHeal, sMpDataStore->GetCreatureData(attacker->GetGUID()), creature, target, instanceData->creature.spell);
} else {
// MpLogger::debug("Scaling spell {} using flat modifier Original Damage: {} New Damage: {}", spellInfo->SpellName[0], damageOrHeal, alteredDmgHeal);
alteredDmgHeal = damageOrHeal * instanceData->creature.spell;
}
}
break;
case MythicPlus::UNIT_EVENT_HEAL:
case MythicPlus::UNIT_EVENT_HOT:
break;
}
}
/**
* @TODO: Add more granular control over the scaling of healing spells
*/
if(sMythicPlus->EligibleHealTarget(target) && (eventType == MythicPlus::UNIT_EVENT_HEAL || eventType == MythicPlus::UNIT_EVENT_HOT)) {
if(creature->IsDungeonBoss()) {
if(spellInfo) {
alteredDmgHeal = sMythicPlus->ScaleHealSpell(spellInfo, damageOrHeal, sMpDataStore->GetCreatureData(attacker->GetGUID()), creature, attacker->ToCreature(), instanceData->boss.spell * 0.7f);
} else {
alteredDmgHeal = damageOrHeal * instanceData->boss.spell * 0.7f;
}
} else {
if(spellInfo) {
alteredDmgHeal = sMythicPlus->ScaleHealSpell(spellInfo, damageOrHeal, sMpDataStore->GetCreatureData(attacker->GetGUID()), creature, attacker->ToCreature(), instanceData->creature.spell * 0.7f);
} else {
alteredDmgHeal = damageOrHeal * instanceData->creature.spell * 0.70f;
}
}
MpLogger::debug("Incoming heal: {}({}) {} hits {}",
alteredDmgHeal,
damageOrHeal,
attacker ? attacker->GetName() : "[null]",
target ? target->GetName() : "[null]");
}
return alteredDmgHeal > 0 ? alteredDmgHeal : damageOrHeal;
}
};
void Add_MP_UnitScripts()
{
new MythicPlus_UnitScript();
}

129
src/Scripts/WorldScript.cpp Normal file
View File

@@ -0,0 +1,129 @@
#include "Config.h"
#include "MythicPlus.h"
#include "MpDataStore.h"
#include "AdvancementMgr.h"
#include "MpLogger.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "MpEventHandlers.cpp"
class MythicPlus_WorldScript : public WorldScript
{
public:
MythicPlus_WorldScript() : WorldScript("MythicPlus_WorldScript") { }
void OnAfterConfigLoad(bool /*reload*/) override
{
// Global Settings
sMythicPlus->Enabled = sConfigMgr->GetOption<bool>("MythicPlus.Enabled", 1);
sMythicPlus->EnableItemRewards = sConfigMgr->GetOption<bool>("MythicPlus.EnableItemRewards", 1);
sMythicPlus->EnableDeathLimits = sConfigMgr->GetOption<bool>("MythicPlus.EnableDeathLimits", 1);
/** @todo Add these back in once I write the parsers for handling the different configuration values. */
// sMythicPlus->enabledDifficulties = sConfigMgr->GetOption<std::vector<std::string>>("MythicPlus.EnabledDifficulties", {"mythic", "legendary", "ascendant"});
// sMythicPlus->disabledDungeons = sConfigMgr->GetOption<std::vector<uint32>>("MythicPlus.DisabledDungeons", {});
// Mythic Difficulty Modifiers
sMythicPlus->mythicDungeonModifiers = {
.health = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonHealth", 1.25f),
.melee = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonMelee", 1.25f),
.baseDamage = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonBaseDamage", 1.5f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonSpell", 1.15f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonArmor", 1.25f),
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Mythic.DungeonAvgLevel", 83)
};
sMythicPlus->mythicBossModifiers = {
.health = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonBossHealth", 1.50f),
.melee = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonBossMelee", 1.35f),
.baseDamage = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonBossBaseDamage", 2.0f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonBossSpell", 1.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonBossArmor", 1.35f),
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Mythic.DungeonBossLevel", 85)
};
// Legendary Difficulty Modifiers
sMythicPlus->legendaryDungeonModifiers = {
.health = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonHealth", 2.25f),
.melee = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonMelee", 2.25f),
.baseDamage = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonBaseDamage", 2.75f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonSpell", 2.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonArmor", 2.25f),
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Legendary.DungeonAvgLevel", 85)
};
sMythicPlus->legendaryBossModifiers = {
.health = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonBossHealth", 2.25f),
.melee = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonBossMelee", 2.25f),
.baseDamage = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonBossBaseDamage", 4.0f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonBossSpell", 2.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonBossArmor", 3.25f),
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Legendary.DungeonBossLevel", 87)
};
sMythicPlus->ascendantDungeonModifiers = {
.health = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonHealth", 3.25f),
.melee = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonMelee", 3.25f),
.baseDamage = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonBaseDamage", 4.75f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonSpell", 3.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonArmor", 3.25f),
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Ascendant.DungeonAvgLevel", 87)
};
sMythicPlus->ascendantBossModifiers = {
.health = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonBossHealth", 3.25f),
.melee = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonBossMelee", 3.25f),
.baseDamage = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonBossBaseDamage", 6.0f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonBossSpell", 3.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonBossArmor", 3.25f),
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Ascendant.DungeonBossLevel", 90)
};
// Death Allowances
sMythicPlus->mythicDeathAllowance = sConfigMgr->GetOption<uint32>("MythicPlus.Mythic.DeathAllowance", 1000);
sMythicPlus->legendaryDeathAllowance = sConfigMgr->GetOption<uint32>("MythicPlus.Legendary.DeathAllowance", 30);
sMythicPlus->ascendantDeathAllowance = sConfigMgr->GetOption<uint32>("MythicPlus.Ascendant.DeathAllowance", 15);
// Itemization Offsets
sMythicPlus->mythicItemOffset = sConfigMgr->GetOption<uint32>("MythicPlus.Mythic.ItemOffset", 20000000);
sMythicPlus->legendaryItemOffset = sConfigMgr->GetOption<uint32>("MythicPlus.Legendary.ItemOffset", 21000000);
sMythicPlus->ascendantItemOffset = sConfigMgr->GetOption<uint32>("MythicPlus.Ascendant.ItemOffset", 22000000);
// Get diminishing returns from configuration
sMythicPlus->diminishingExponent = sConfigMgr->GetOption<float>("MythicPlus.DiminishingExponent", 0.975f);
sMythicPlus->diminishingThresholds = {
{MpDifficulty::MP_DIFFICULTY_MYTHIC, sConfigMgr->GetOption<uint32>("MythicPlus.DiminishingThreshold.Mythic", 10000)},
{MpDifficulty::MP_DIFFICULTY_LEGENDARY, sConfigMgr->GetOption<uint32>("MythicPlus.DiminishingThreshold.Legendary", 20000)},
{MpDifficulty::MP_DIFFICULTY_ASCENDANT, sConfigMgr->GetOption<uint32>("MythicPlus.DiminishingThreshold.Ascendant", 40000)}
};
sMythicPlus->elementalMeleeReducer = sConfigMgr->GetOption<float>("MythicPlus.ElementalMeleeReducer", 0.50f);
sMythicPlus->normalEnemyReducer = sConfigMgr->GetOption<float>("MythicPlus.NormalEnemyReducer", 0.50f);
sMythicPlus->nonCreatureSpellReducer = sConfigMgr->GetOption<float>("MythicPlus.NonCreatureSpellReducer", 0.50f);
}
void OnStartup() override
{
int32 size = sMpDataStore->LoadScaleFactors();
MpLogger::info("Loaded {} Mythic+ Scaling Factors from database...", size);
size = sAdvancementMgr->LoadAdvancementRanks();
MpLogger::info("Loaded {} advancement ranks...", size);
size = sAdvancementMgr->LoadMaterialTypes();
MpLogger::info("Loaded {} material types...", size);
sMpDataStore->LoadPlayerHealthAvg();
MpLogger::info("Loaded player health averages used for scaling calculations...");
// Registering event handlers for the Mythic+ events from client
MP_Register_EventHandlers();
MpLogger::info("Registered Mythic+ Event Handlers...");
}
};
void Add_MP_WorldScripts()
{
MpLogger::debug("Add_MP_WorldScripts()");
new MythicPlus_WorldScript();
}

View File

@@ -0,0 +1,277 @@
#include "CreatureScript.h"
#include "MpConstants.h"
#include "PetDefines.h"
#include "Player.h"
#include "AdvancementMgr.h"
#include "MpLogger.h"
#include "SpellAuraEffects.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "UnitAI.h"
#include "World.h"
class spell_mp_titans_strength_aura : public AuraScript
{
PrepareAuraScript(spell_mp_titans_strength_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_STRENGTH);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Titans Strength to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_titans_strength_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_titans_strength_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
}
};
class spell_mp_steel_forged_aura : public AuraScript
{
PrepareAuraScript(spell_mp_steel_forged_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_STAMINA);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Steel Forged to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_steel_forged_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_steel_forged_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
}
};
class spell_mp_celestial_grace_aura : public AuraScript
{
PrepareAuraScript(spell_mp_celestial_grace_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_SPIRIT);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Celestial Grace to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_celestial_grace_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_celestial_grace_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
}
};
class spell_mp_forbidden_knowledge_aura : public AuraScript
{
PrepareAuraScript(spell_mp_forbidden_knowledge_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_INTELLECT);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Forbidden Knowledge to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_forbidden_knowledge_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_forbidden_knowledge_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
}
};
class spell_mp_spectral_reflexes_aura : public AuraScript
{
PrepareAuraScript(spell_mp_spectral_reflexes_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_AGILITY);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Spectral Reflexes to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_spectral_reflexes_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_spectral_reflexes_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
}
};
class spell_mp_eldritch_barrier_aura : public AuraScript
{
PrepareAuraScript(spell_mp_eldritch_barrier_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_RESIST_ARCANE);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Eldritch Barrier to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_eldritch_barrier_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_eldritch_barrier_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
}
};
class spell_mp_hellfire_shielding_aura : public AuraScript
{
PrepareAuraScript(spell_mp_hellfire_shielding_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_RESIST_FIRE);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Hellfire Shielding to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_hellfire_shielding_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_hellfire_shielding_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
}
};
class spell_mp_primal_endurance_aura : public AuraScript
{
PrepareAuraScript(spell_mp_primal_endurance_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_RESIST_NATURE);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Primal Endurance to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_primal_endurance_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_primal_endurance_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
}
};
class spell_mp_lichs_bane_aura : public AuraScript
{
PrepareAuraScript(spell_mp_lichs_bane_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_RESIST_SHADOW);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Lich's Bane to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_lichs_bane_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_lichs_bane_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
}
};
class spell_mp_glacial_fortress_aura : public AuraScript
{
PrepareAuraScript(spell_mp_glacial_fortress_aura);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
Player* player = GetCaster()->ToPlayer();
auto rank = sAdvancementMgr->GetPlayerAdvancementRank(player, MpAdvancements::MP_ADV_RESIST_FROST);
if(!rank) {
amount = 0; // player does not have an advancement
return;
}
amount = static_cast<int32>(rank->bonus);
MpLogger::info("In Calc Amount Advancement Glacial Fortress to Player {} bonus {}", player->GetName(), amount);
}
void Register() override
{
MpLogger::info("Registering spell_mp_glacial_fortress_aura");
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mp_glacial_fortress_aura::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
}
};
void AddSC_AdvancementSpells()
{
RegisterSpellScript(spell_mp_titans_strength_aura);
RegisterSpellScript(spell_mp_steel_forged_aura);
RegisterSpellScript(spell_mp_celestial_grace_aura);
RegisterSpellScript(spell_mp_forbidden_knowledge_aura);
RegisterSpellScript(spell_mp_spectral_reflexes_aura);
RegisterSpellScript(spell_mp_eldritch_barrier_aura);
RegisterSpellScript(spell_mp_hellfire_shielding_aura);
RegisterSpellScript(spell_mp_primal_endurance_aura);
RegisterSpellScript(spell_mp_lichs_bane_aura);
RegisterSpellScript(spell_mp_glacial_fortress_aura);
}

View File

@@ -1,20 +0,0 @@
#include "ScriptMgr.h"
#include "MythicPlus.h"
#include "Player.h"
class MythicPlus_UnitScript : public UnitScript
{
public:
MythicPlus_UnitScript() : UnitScript("MythicPlus_UnitScript", true) { }
void OnAuraApply(Unit* unit, Aura* aura) override {
}
};
void AddUnitScripts()
{
new MythicPlus_UnitScript();
}

View File

@@ -1,32 +0,0 @@
#include "ScriptMgr.h"
#include "MythicPlus.h"
#include "Config.h"
#include "Player.h"
class MythicPlus_WorldScript : public WorldScript
{
public:
MythicPlus_WorldScript() : WorldScript("MythicPlus_WorldScript") { }
void OnBeforeConfigLoad(bool /*reload*/) override
{
SetInitialWorldSettings();
// sMythicPlus->lastConfigTime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
void OnStartup() override
{
}
void SetInitialWorldSettings()
{
// sMythicPlus->configValue = sConfigMgr->GetOption<float>("MythicPlus.ConfigValue", 1.0f, false);
}
};
void AddWorldScripts()
{
new MythicPlus_WorldScript();
}