39 Commits

Author SHA1 Message Date
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
33 changed files with 2417 additions and 176 deletions

View File

@@ -112,3 +112,8 @@ MythicPlus.Mythic.ItemOffset = 20000000
MythicPlus.Legendary.ItemOffset = 21000000
MythicPlus.Ascendant.ItemOffset = 22000000
##############
# Scaling Adjusters
#############
MythicPlus.MeleeAttackPowerDampener = 800
MythicPlus.MeleeAttackPowerStart = 3000

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,80 @@
-- 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,
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,
numDeaths INT UNSIGNED NOT NULL DEFAULT '0',
lastUpdated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (guid),
INDEX idx_creature (creatureEntry)
);
--- 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,
groupDeaths INT UNSIGNED,
personalDeaths INT UNSIGNED,
completeTime INT UNSIGNED,
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 upgrads from materials and drops in mythic dungeons
DROP TABLE IF EXISTS mp_player_stat_upgrades;
CREATE TABLE mp_player_stat_upgrades
(
guid INT UNSIGNED NOT NULL,
statTypeId INT UNSIGNED NOT NULL,
bonus Float NOT NULL,
upgradeRank INT UNSIGNED NOT NULL,
materialSpent INT UNSIGNED NOT NULL DEFAULT '0',
diceSpent INT UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (guid, statTypeId)
);

View File

@@ -0,0 +1,255 @@
-- MaterialID for all droppable cloth items
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
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 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
OR name = 'Mageroyal'
ORDER BY it.RequiredSkillRank, it.name;
-- 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.class = 7
AND it.subclass = 9
AND it.VerifiedBuild = 12340
AND it.RequiredSkillRank = 0
OR name != 'Mageroyal'
ORDER BY it.RequiredSkillRank, it.name;
-- Common ores that are easy to find in the world
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
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', 'Khorium Ore')
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 materials that related to water / frost
REPLACE INTO mp_material_types (materialId, entry, name)
SELECT
11 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
12 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',
'Titanium Frostguard Ring',
'Icy Dragonscale',
'Eternal Water'
);

View File

@@ -0,0 +1,45 @@
--- Used to track upgrade ranks for stat improvements and min/max values
DROP TABLE IF EXISTS mp_stat_upgrade_ranks;
CREATE TABLE mp_stat_upgrade_ranks
(
upgradeRank INT UNSIGNED NOT NULL,
statTypeId INT UNSIGNED NOT NULL,
materialId1 INT UNSIGNED NOT NULL,
materialId2 INT UNSIGNED NOT NULL,
materialId3 INT UNSIGNED NOT NULL,
materialCost INT UNSIGNED NOT NULL,
materialCost2 INT UNSIGNED NOT NULL,
materialCost3 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)
);
-- Used to allocate trade materials based on slot upgrades
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 IF NOT EXISTS mp_scale_factors (
mapId SMALLINT PRIMARY KEY,
dmg_bonus INT,
spell_bonus INT,
hp_bonus INT,
difficulty INT,
max INT
);

View File

@@ -3,11 +3,11 @@
DROP TABLE IF EXISTS mythic_plus_scale_factors;
CREATE TABLE IF NOT EXISTS mythic_plus_scale_factors (
mapId SMALLINT PRIMARY KEY,
dmg_bonus TINYINT,
spell_bonus TINYINT,
hp_bonus TINYINT,
difficulty TINYINT,
max TINYINT
dmg_bonus INT,
spell_bonus INT,
hp_bonus INT,
difficulty INT,
max INT
);
-- 1. Pre 60 level dungeons (13 dmg_bonus, 2 hp_bonus, max 23, difficulty 3)

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,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")
}

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")
}

View File

@@ -1,6 +1,8 @@
#include "CreatureAI.h"
#include "MpDataStore.h"
#include "MpLogger.h"
#include "MythicPlus.h"
#include "MpScriptAI.h"
#include "ScriptMgr.h"
class MythicPlus_AllCreatureScript : public AllCreatureScript

View File

@@ -14,7 +14,7 @@ public:
{
}
void OnCreateMap(Map* map) { }
void OnCreateMap(Map* /*map*/) { }
/**
* When a player enters the map check it needs to set up the instance data
@@ -101,6 +101,11 @@ public:
);
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);
}
@@ -112,6 +117,10 @@ public:
return;
}
sMpDataStore->RemoveInstanceData(map->GetId(), map->GetInstanceId());
// If there is player data for this map reset it to default values
}
};

35
src/BaseCreatureHandler.h Normal file
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

@@ -23,20 +23,22 @@ public:
{
{"", HandleHelp, SEC_PLAYER, Console::No},
{"status", HandleStatus, SEC_PLAYER, Console::No},
{"showstats", HandleDebug, SEC_PLAYER, Console::No},
// {"mythic",HandleMythic, SEC_PLAYER, Console::No},
// {"legendary",HandleLegendary, SEC_PLAYER, Console::No},
// {"ascendant",HandleAscendant, SEC_PLAYER, Console::No},
{"set", HandleSetDifficulty, SEC_PLAYER, Console::No},
{"disable", HandleDisable, SEC_ADMINISTRATOR, Console::Yes},
{"enable", HandleEnable, 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 debug", HandleDebug, SEC_PLAYER, Console::No},
{"mp reload", HandleReload, SEC_GAMEMASTER, Console::No}
};
return commandTable;
@@ -46,14 +48,22 @@ public:
{
std::string helpText = "Mythic+ Commands:\n"
" .mp status - show current global settings of Mythic+ mod\n"
" .mp set [mythic,legendary,ascendant] - Set Mythic+ difficulty in current beta only supports mythic.\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 HandleDebug(ChatHandler* handler, const std::vector<std::string>& args)
static bool HandleReload(ChatHandler* handler)
{
sMpDataStore->LoadScaleFactors();
handler->PSendSysMessage("Mythic+ scale factors updated.");
return true;
}
static bool HandleDebug(ChatHandler* handler)
{
Creature* target = handler->getSelectedCreature();
@@ -62,6 +72,10 @@ public:
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 {} - {}",
@@ -78,10 +92,12 @@ public:
);
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(LANG_NPCINFO_ARMOR, target->GetArmor());
handler->PSendSysMessage("Damage Modifier {}", target->GetModifierValue(UNIT_MOD_DAMAGE_MAINHAND, BASE_VALUE));
handler->PSendSysMessage("Armor {}", target->GetArmor());
handler->PSendSysMessage("Damage Modifier on template {}",creatureTemplate->DamageModifier);
if(creatureData) {
handler->PSendSysMessage("CreatureData: {}", creatureData->ToString());
}
return true;
@@ -90,7 +106,6 @@ public:
// 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();
@@ -123,13 +138,21 @@ public:
}
if (difficulty == "mythic") {
sMpDataStore->AddGroupData(group, MpGroupData(group, MP_DIFFICULTY_MYTHIC, 0));
sMpDataStore->AddGroupData(group, MpGroupData(group, MP_DIFFICULTY_MYTHIC));
}
else if (difficulty == "legendary") {
sMpDataStore->AddGroupData(group,MpGroupData(group, MP_DIFFICULTY_LEGENDARY, 0));
sMpDataStore->AddGroupData(group,MpGroupData(group, MP_DIFFICULTY_LEGENDARY));
}
else if (difficulty == "ascendant") {
sMpDataStore->AddGroupData(group, MpGroupData(group, MP_DIFFICULTY_ASCENDANT, 0));
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 'mythic', 'legendary', or 'ascendant'.");
@@ -138,8 +161,6 @@ public:
handler->PSendSysMessage("Mythic+ difficulty set to: " + difficulty);
MpLogger::debug("HandleSetMythic() Set difficulty player: {} {}", player->GetName(), difficulty);
return true;
}
@@ -162,6 +183,9 @@ public:
{
Player* player = handler->GetPlayer();
Map* map = player->GetMap();
uint32 mapId = player->GetMapId();
std::string status = Acore::StringFormat(
"Mythic+ Status:\n"
" Mythic+ Enabled: %s\n"
@@ -174,21 +198,89 @@ public:
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: %u\n"
" Group Deaths: %u\n",
groupData->difficulty,
groupData->deaths);
" Group Deaths: %u\n"
" Scale FactorStr %s\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()");
@@ -205,6 +297,91 @@ public:
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) {
uint32 value = std::stoi(args[0]);
sMpDataStore->SetDamageScaleFactor(player->GetMapId(), groupData->difficulty, value);
handler->PSendSysMessage(Acore::StringFormat("Melee scale factor set to: %u", 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) {
uint32 value = std::stoi(args[0]);
sMpDataStore->SetSpellScaleFactor(player->GetMapId(), groupData->difficulty, value);
handler->PSendSysMessage(Acore::StringFormat("Spell scale factor set to: %u", 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) {
uint32 value = std::stoi(args[0]);
sMpDataStore->SetHealthScaleFactor(player->GetMapId(), groupData->difficulty, value);
handler->PSendSysMessage(Acore::StringFormat("Health scale factor set to: %u", value));
return true;
}
}
handler->PSendSysMessage("|cFFFF0000 You must be in a group and mythic+ instance to set a melee scale factor.");
return true;
}
};
void Add_MP_CommandScripts()

84
src/CreatureHooks.cpp Normal file
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);
}
}
}

92
src/CreatureHooks.h Normal file
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

@@ -11,7 +11,7 @@ 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 {
void OnBeforeDropAddItem(Player const* player, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, LootStoreItem* LootStoreItem, LootStore const& store) override {
if(LootStoreItem->itemid == 0) {
return;

View File

@@ -11,6 +11,42 @@ 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());
pd = &playerData;
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;
@@ -20,12 +56,42 @@ class MythicPlus_GroupScript : public GroupScript
return;
}
// sMpDataStore->AddGroupData(group->GetGUID(), gd);
// 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()

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);
// }
// };

View File

@@ -1,9 +1,15 @@
#include "CharacterDatabase.h"
#include "MpDataStore.h"
#include "Group.h"
#include "MpLogger.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) {
@@ -15,19 +21,77 @@ void MpDataStore::AddGroupData(Group *group, MpGroupData groupData) {
MpLogger::error("AddGroupData called with invalid difficulty");
return;
}
// if we already have data override it
if (_groupData->contains(guid)) {
_groupData->at(guid) = groupData;
} else {
_groupData->emplace(guid, groupData);
Player* leader = group->GetLeader();
if(!leader) {
MpLogger::error("AddGroupData called with null group leader");
return;
}
MpLogger::debug("Add Group difficulty for group {} to {}", guid.GetCounter());
Map* map = leader->GetMap();
if (!map) {
MpLogger::error("AddGroupData called with null map for group leader");
return;
}
CharacterDatabase.Execute("REPLACE INTO group_difficulty (guid, difficulty) VALUES ({},{}) ",
guid.GetCounter(),
groupData.difficulty
);
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");
}
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");
}
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) {
@@ -61,7 +125,7 @@ void MpDataStore::PushGroupInstanceKey(Group *group, uint32 mapId, uint32 instan
return;
}
_groupData->at(guid).instanceDataKeys.push_back(GetInstanceDataKey(mapId, instanceId));
// Need to potentialy reset here?
}
// This clears out any group data from memory and the database
@@ -75,6 +139,13 @@ void MpDataStore::RemoveGroupData(Group *group) {
void MpDataStore::AddPlayerData(ObjectGuid guid, MpPlayerData pd) {
MpLogger::debug("AddPlayerData for player {}", guid.GetCounter());
_playerData->emplace(guid, pd);
// get the player
Player* player = ObjectAccessor::FindPlayer(guid);
}
void MpDataStore::UpdatePlayerData(ObjectGuid guid, MpPlayerData /*pd*/) {
// _playerData->at(guid) = pd;
}
void MpDataStore::RemovePlayerData(ObjectGuid guid) {
@@ -82,6 +153,11 @@ void MpDataStore::RemovePlayerData(ObjectGuid guid) {
_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);
}
@@ -100,7 +176,7 @@ void MpDataStore::RemoveInstanceData(uint32 mapId, uint32 instanceId) {
}
void MpDataStore::AddCreatureData(ObjectGuid guid, MpCreatureData creatureData) {
MpLogger::debug("AddInstanceCreatureData for creature {}", guid.GetCounter());
// MpLogger::debug("AddInstanceCreatureData for creature {}", guid.GetCounter());
_instanceCreatureData->emplace(guid, creatureData);
}
@@ -112,6 +188,18 @@ MpCreatureData* MpDataStore::GetCreatureData(ObjectGuid guid) {
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) {
@@ -159,7 +247,31 @@ int32 MpDataStore::GetMaxDamageScaleFactor(int32 mapId, int32 difficulty) const
return GetScaleFactor(mapId, difficulty).maxDamageBonus;
}
void MpDataStore::SetHealthScaleFactor(int32 mapId, int32 difficulty, int32 newValue) {
auto key = GetScaleFactorKey(mapId, difficulty);
if (_scaleFactors && _scaleFactors->contains(key)) {
_scaleFactors->at(key).healthBonus = newValue;
}
}
void MpDataStore::SetDamageScaleFactor(int32 mapId, int32 difficulty, int32 newValue) {
auto key = GetScaleFactorKey(mapId, difficulty);
if (_scaleFactors && _scaleFactors->contains(key)) {
_scaleFactors->at(key).dmgBonus = newValue;
}
}
void MpDataStore::SetSpellScaleFactor(int32 mapId, int32 difficulty, int32 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, dmg_bonus, spell_bonus, hp_bonus, difficulty, max FROM mythic_plus_scale_factors");
if (!result) {
@@ -183,12 +295,149 @@ int32 MpDataStore::LoadScaleFactors() {
.maxDamageBonus = maxDamageBonus
};
_mutableScaleFactors->emplace(GetScaleFactorKey(mapId, difficulty), scaleFactor);
_scaleFactors->emplace(GetScaleFactorKey(mapId, difficulty), scaleFactor);
} while (result->NextRow());
// move to const map one loaded so can not be changed after
_scaleFactors = std::move(_mutableScaleFactors);
return int32(_scaleFactors->size());
}
/**
* 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) {
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("REPLACE INTO mp_player_death_stats (guid, mapId, instanceId, creatureId) VALUES ({},{},{},{}) ",
player->GetGUID().GetCounter(),
player->GetMapId(),
player->GetInstanceId(),
creature->GetEntry()
);
}
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 (guid, 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 guid = {} 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::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 (guid, 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 guid = {} ", groupGuid.GetCounter());
}

View File

@@ -2,6 +2,7 @@
#define MYTHICPLUS_DATASTORE_H
#include "Creature.h"
// #include "CreatureOverride.h"
#include "Group.h"
#include "MapMgr.h"
#include "Player.h"
@@ -21,22 +22,105 @@ enum MpDifficulty {
MP_DIFFICULTY_LEGENDARY = 4,
MP_DIFFICULTY_ASCENDANT = 5
};
class MpDataStore;
struct MpPlayerInstanceData {
uint32 deaths;
};
// 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};
}
}
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;
uint32 deaths;
std::vector<MpPlayerData*> players;
MpGroupData() : group(nullptr), difficulty(MpDifficulty{}) {
players.reserve(5);
std::vector<std::pair<uint32,uint32>> instanceDataKeys;
MpGroupData() : group(nullptr), difficulty(MpDifficulty{}), deaths(0) {
instanceDataKeys.reserve(32);
}
MpGroupData(Group* group, MpDifficulty difficulty, uint32 deaths)
: group(group), difficulty(difficulty), deaths(deaths) {
instanceDataKeys.reserve(32);
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) {
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) + " }";
@@ -44,13 +128,6 @@ struct MpGroupData
};
struct MpPlayerData
{
Player* player;
uint8 difficulty;
uint32 deaths;
};
struct MpScaleFactor
{
int32 dmgBonus;
@@ -112,8 +189,6 @@ struct MpInstanceData
};
/**
* Simple struct for managing information about creatures that
* are in a mythic+ instance.
@@ -123,9 +198,17 @@ struct MpCreatureData
Creature* creature;
bool scaled;
// 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;
CreatureBaseStats const* originalStats;
MpDifficulty difficulty;
// Custom difficulty modifiers to creatures at higher difficulties.
std::vector<uint32> auras;
@@ -150,10 +233,42 @@ struct MpCreatureData
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 = *originalStats->BaseHealth;
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 */
};
@@ -164,7 +279,7 @@ private:
_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>>()),
_mutableScaleFactors(std::make_unique<std::map<std::pair<int32, int32>,MpScaleFactor>>())
_scaleFactors(std::make_unique<std::map<std::pair<int32, int32>,MpScaleFactor>>())
{
_playerData->reserve(32);
_groupData->reserve(32);
@@ -185,9 +300,10 @@ private:
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>> _mutableScaleFactors; // {mapId,difficulty}
std::unique_ptr<const std::map<std::pair<int32,int32>,MpScaleFactor>> _scaleFactors; // {mapId,difficulty}
std::unique_ptr<std::map<std::pair<int32,int32>,MpScaleFactor>> _scaleFactors; // {mapId,difficulty}
// 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:
@@ -195,7 +311,7 @@ public:
MpDataStore(const MpDataStore&) = delete;
MpDataStore& operator=(const MpDataStore&) = delete;
const MpPlayerData* GetPlayerData(ObjectGuid guid) const {
MpPlayerData* GetPlayerData(ObjectGuid guid) {
try {
return &_playerData->at(guid);
} catch (const std::out_of_range& oor) {
@@ -203,7 +319,7 @@ public:
}
}
const MpGroupData* GetGroupData(ObjectGuid guid) const {
MpGroupData* GetGroupData(ObjectGuid guid) {
if (_groupData->contains(guid)) {
return &_groupData->at(guid);
@@ -212,7 +328,7 @@ public:
}
}
const MpGroupData* GetGroupData(Player *player) const {
MpGroupData* GetGroupData(Player *player) {
return GetGroupData(player->GetGroup()->GetGUID());
};
@@ -222,8 +338,11 @@ public:
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 UpdatePlayerData(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 );
@@ -234,6 +353,7 @@ public:
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
@@ -243,6 +363,14 @@ public:
int32 GetSpellScaleFactor(int32 mapId, int32 difficulty) const;
MpScaleFactor GetScaleFactor(int32 mapId, int32 difficulty) const;
void SetDamageScaleFactor(int32 mapId, int32 difficulty, int32 value);
void SetHealthScaleFactor(int32 mapId, int32 difficulty, int32 value);
void SetSpellScaleFactor(int32 mapId, int32 difficulty, int32 value);
// 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);
}
@@ -253,6 +381,20 @@ public:
// Used at initial server load
int32 LoadScaleFactors();
// 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);
void DBAddPlayerDeath(Player* player);
void DBRemovePlayerData(ObjectGuid playerGuid);
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;

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

@@ -5,10 +5,16 @@
#include "ScriptMgr.h"
#include "Group.h"
#include "Unit.h"
#include "WorldPacket.h"
#include "UpdateMask.h"
#include "MpScriptAI.h"
#include <algorithm>
#include <cmath>
// Special case for Headless Horseman Event
const uint32 HEADLESS_HORSEMAN = 23682;
bool MythicPlus::IsMapEligible(Map* map)
{
if (!Enabled) {
@@ -62,12 +68,15 @@ bool MythicPlus::EligibleHealTarget(Unit* target)
return false;
}
if ((target->IsPet() || target->IsSummon() || target->IsHunterPet()) && target->GetOwner()->IsNPCBot()) {
// 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
if(sMythicPlus->IsCreatureEligible(target->ToCreature())) {
// Ensure target is a valid creature before checking eligibility
Creature* creatureTarget = target->ToCreature();
if (creatureTarget && sMythicPlus->IsCreatureEligible(creatureTarget)) {
return true;
}
@@ -81,7 +90,6 @@ bool MythicPlus::EligibleDamageTarget(Unit* target)
}
if (target->GetTypeId() == TYPEID_PLAYER) {
MpLogger::debug("Target {} is a player", target->GetName());
return true;
}
@@ -105,14 +113,25 @@ bool MythicPlus::EligibleDamageTarget(Unit* target)
bool MythicPlus::IsCreatureEligible(Creature* creature)
{
CreatureTemplate const * cInfo = creature->GetCreatureTemplate();
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;
@@ -155,26 +174,49 @@ void MythicPlus::AddCreatureForScaling(Creature* creature)
}
sMpDataStore->AddCreatureData(creature->GetGUID(), MpCreatureData(creature));
MpLogger::debug("Added creature {} to instance data for instance {}",
creature->GetName(),
creature->GetMap()->GetMapName()
);
// 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);
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()) {
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);
std::string name = creature->GetName();
// Assign random affix for now.
if (roll_chance_i(50)) {
uint32 irand = urand(0, 2);
if(irand == 0) {
creature->AddAura(23341, creature);
} else if(irand == 1) {
creature->AddAura(34711, creature);
} else {
creature->AddAura(774, creature);
}
}
creatureData.SetScaled(true);
sMpDataStore->AddCreatureData(creature->GetGUID(), creatureData);
creatureData.SetDifficulty(instanceData->difficulty);
// MpLogger::debug("Scaled Creature {} Entry {} Id {} level from {} to {}",
// creature->GetName(),
@@ -193,6 +235,14 @@ void MythicPlus::ScaleRemaining(Player* player, MpInstanceData* instanceData)
}
}
void MythicPlus::ScaleAll(Player* player, MpInstanceData* instanceData)
{
std::vector<MpCreatureData*> creatures = sMpDataStore->GetInstanceCreatures(player->GetMapId(), player->GetInstanceId());
for (MpCreatureData* creatureData : creatures) {
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)
{
@@ -217,13 +267,7 @@ void MythicPlus::ScaleCreature(uint8 level, Creature* creature, MpMultipliers* m
);
uint32 basehp = stats->BaseHealth[EXPANSION_WRATH_OF_THE_LICH_KING];
uint32 health = CalculateNewHealth(cInfo, mapId, difficulty, basehp, multipliers->health);
MpLogger::debug("Creature {} base health scaled from {} to {}",
creature->GetName(),
basehp,
health
);
uint32 health = CalculateNewHealth(creature, cInfo, mapId, difficulty, basehp, multipliers->health);
creature->SetCreateHealth(health);
creature->SetMaxHealth(health);
@@ -247,52 +291,47 @@ void MythicPlus::ScaleCreature(uint8 level, Creature* creature, MpMultipliers* m
creature->SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana * 3.0f);
}
float oldAp = stats->AttackPower;
float oldRangeAp = stats->RangedAttackPower;
uint32 rangeAp = irand(215, 357);
float ap; // = ((85 - origLevel) * APratio); // * 100;
int32 damageBonus = sMpDataStore->GetDamageScaleFactor(mapId, difficulty);
float dmgMod = cInfo->DamageModifier + damageBonus;
ap = dmgMod * 80 + oldAp;
if (creature->GetLevel() >= 60) {
ap = ap * 1.25f;
rangeAp = rangeAp * 1.25f;
MpInstanceData *instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
int32 meleeDamage = sMpDataStore->GetDamageScaleFactor(creature->GetMapId(), instanceData->difficulty);
if(creature->IsDungeonBoss() || creature->GetEntry() == 23682) {
// Give the boss an increase in casting speed.
creature->SetFloatValue(UNIT_MOD_CAST_SPEED, 1.20f);
}
// Calculate the level difference
float levelDifference = creature->GetLevel() - origLevel;
// New formula with adjusted divisor for smoother scaling
float scalingFactor;
uint32 ap = uint32(sMythicPlus->meleeAttackPowerStart - sMythicPlus->meleeAttackPowerDampener);
uint32 rangeAp = irand(215, 357);
scalingFactor = CalculateScaling(levelDifference, meleeDamage);
ap = uint32(stats->AttackPower * scalingFactor);
rangeAp = uint32(rangeAp * scalingFactor);
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creature->GetGUID());
if(creatureData) {
creatureData->NewAttackPower = ap;
creatureData->AttackPowerScaleMultiplier = scalingFactor;
}
// Set scaled attack power
creature->SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, ap);
creature->SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, rangeAp);
// MpLogger::debug("Creature {} base attack power {} new ap {}",
// creature->GetName(),
// oldAp,
// ap
// );
// This works out a bonus damage to apply to the mob using the database and original mod settings.
// the thought behind this is some mobs in dungeons are intended to hit harder than others
// so applying a flat bonus keeps the ratios the same but increases the overall difficulty.
// Of course within reason.
// 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], 0);
int32 maxBonus = sMpDataStore->GetMaxDamageScaleFactor(mapId, difficulty);
// Allow bosses to scale as high as they want but limit non-bosses to a max bonus
if(!creature->IsDungeonBoss() && damageBonus > maxBonus) {
dmgMod = maxBonus;
}
float oldDmgModifier = creature->GetModifierValue(UNIT_MOD_DAMAGE_MAINHAND, BASE_VALUE);
creature->SetModifierValue(UNIT_MOD_DAMAGE_MAINHAND,BASE_PCT, dmgMod);
creature->SetModifierValue(UNIT_MOD_DAMAGE_OFFHAND,BASE_PCT, dmgMod*0.85f);
creature->SetModifierValue(UNIT_MOD_DAMAGE_RANGED,BASE_PCT, dmgMod);
// 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);
// ap = pow(float((creature->GetLevel() - origLevel) / 5), 1.8f) * 1000
}
int32 MythicPlus::ScaleDamageSpell(SpellInfo const * spellInfo, uint32 damage, MpCreatureData* creatureData, Creature* creature, Unit* target, float damageMultiplier)
@@ -310,7 +349,7 @@ int32 MythicPlus::ScaleDamageSpell(SpellInfo const * spellInfo, uint32 damage, M
if(creature->IsTotem()) {
Unit* owner = creature->GetOwner();
if(owner) {
float lvlDmgBonus = float(85 - owner->GetLevel() / 5.0f);
float lvlDmgBonus = float(85 - owner->GetLevel() / 10.0f);
return int32(damage * lvlDmgBonus * damageMultiplier);
} else {
return damage * damageMultiplier;
@@ -330,14 +369,20 @@ int32 MythicPlus::ScaleDamageSpell(SpellInfo const * spellInfo, uint32 damage, M
MpInstanceData *instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
int32 spellBonus = sMpDataStore->GetSpellScaleFactor(creature->GetMapId(), instanceData->difficulty);
if(creature->IsDungeonBoss()) {
spellBonus *= 1.25;
}
// if((creature->IsDungeonBoss() && creature->isElite()) || creature->GetEntry() == 23682) {
// spellBonus *= 1.15;
// }
// since we are using logrithmic operation divide the level by the original level
// Calculate the level difference
float levelDifference = creature->GetLevel() - originalLevel;
float scalingFactor = pow(float((creature->GetLevel() - originalLevel) / 10.0f ), float(spellBonus) / 5.0f);
MpLogger::debug("Creature {} original level: {} New Level{} and Scaling level {}", creature->GetName(), originalLevel, creature->GetLevel(), scalingFactor);
// New formula with adjusted divisor for smoother scaling
// float scalingFactor = 1 + (std::log2(levelDifference + 1) * (float(spellBonus)));
float scalingFactor = CalculateScaling(levelDifference, spellBonus);
// float scalingFactor = pow(float((creature->GetLevel() - originalLevel) / 10.0f ), float(spellBonus) / 5.0f);
// MpLogger::debug("Creature {} original level: {} New Level{} and Scaling level {}", creature->GetName(), originalLevel, creature->GetLevel(), scalingFactor);
int32 totalDamage = 0;
auto effects = spellInfo->GetEffects();
@@ -386,15 +431,18 @@ int32 MythicPlus::ScaleDamageSpell(SpellInfo const * spellInfo, uint32 damage, M
return damage;
}
MpLogger::debug(" >>> Spell {} damage scaled from for spell New Damage: {} using: scaling Factor: {} and damage Multi: {}",spellInfo->SpellName[0], totalDamage, scalingFactor, damageMultiplier);
// Apply scaling factor and the set multiplier from the instance data
totalDamage = int32(totalDamage * scalingFactor * damageMultiplier);
MpLogger::debug("Spell {} damage scaled from for spell New Damage: {} using: scaling Factor: {} and damage Multi: {}",spellInfo->SpellName[0], totalDamage, scalingFactor, damageMultiplier);
// MpLogger::debug("Spell {} damage scaled from for spell New Damage: {} using: scaling Factor: {} and damage Multi: {}",spellInfo->SpellName[0], totalDamage, scalingFactor, damageMultiplier);
return totalDamage;
}
int32 MythicPlus::ScaleHealSpell(SpellInfo const * spellInfo, MpCreatureData* creatureData, Creature* creature, Creature* target, float healMultiplier)
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 0;
@@ -410,26 +458,157 @@ int32 MythicPlus::ScaleHealSpell(SpellInfo const * spellInfo, MpCreatureData* cr
return 0;
}
if(!target) {
MpLogger::error("Invalid target ScaleHealSpell()");
return 0;
}
int32 originalHp = creatureData->originalStats->BaseHealth[EXPANSION_WRATH_OF_THE_LICH_KING];
int32 currentHealth = creature->GetHealth();
int32 totalHeal = 0;
auto effects = spellInfo->GetEffects();
// Loop through all spell effects to scale their base healing
for (uint8 i = 0; i < effects.size(); ++i)
{
SpellEffectInfo effect = effects[i];
totalHeal += effect.CalcValue(creature, nullptr, target);
MpLogger::debug(" >>> Spell {} effect {} value: {} by creature {}", spellInfo->SpellName[i], effects[i].Effect, heal, creature->GetName());
}
// Apply scaling factor and the set multiplier from the instance data
MpLogger::debug("Spell healing scaled from for spell New Damage: {}", totalHeal);
return pow((totalHeal / originalHp) * currentHealth, 0.8f) * healMultiplier;
int32 originalLevel = creatureData->originalLevel;
float levelDifference = creature->GetLevel() - originalLevel;
float spellBonus = sMpDataStore->GetSpellScaleFactor(creature->GetMapId(), creature->GetInstanceId());
float scalingFactor = CalculateScaling(levelDifference, spellBonus, 2.5f);
MpLogger::debug(" >>> Spell {} healed scaled from for spell New Heal: {} using: scaling Factor: {} and damage Multi: {}",spellInfo->SpellName[0], heal, scalingFactor, healMultiplier);
return int32(heal * scalingFactor * healMultiplier);
}
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();
}
/**
@@ -455,19 +634,38 @@ float GetTypeHealthModifier(int32 Rank)
}
// This takes the orignal health and scales flat based on the factor then applies the configuration modifier from the conf file
uint32 CalculateNewHealth(CreatureTemplate const* cInfo, uint32 mapId, MpDifficulty difficulty, uint32 origHealth, float confHPMod)
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;
}
float healthVariation;
// if(creature->IsPet() || creature->IsSummon() || creature->IsTotem()) {
// return origHealth;
// }
int32 hpScaleFactor = sMpDataStore->GetHealthScaleFactor(mapId, difficulty);
// Add some variance to the healthpool so enemies are not all the same
float healthVariation = frand(0.85f, 1.15f);
if(creature->IsDungeonBoss() || creature->GetEntry() == HEADLESS_HORSEMAN || creature->isWorldBoss()) { // Is a boss of some kind
healthVariation = frand(1.1f, 1.2f);
} else if(creature->isElite() || cInfo->rank == CREATURE_ELITE_RARE) { // Is Elite Mob
healthVariation = frand(1.0f, 1.10f);
hpScaleFactor *= 0.90;
} else if(creature->IsSummon() || creature->IsPet() || creature->IsTotem()) { // Is a pet or summon
healthVariation = frand(1.0f, 1.05f);
hpScaleFactor *= 0.65;
} else {
healthVariation = frand(1.0f, 1.1f);
hpScaleFactor *= 0.55;
}
float unitTypeMod = GetTypeHealthModifier(rank);
uint32 basehp = uint32(std::ceil(origHealth * unitTypeMod * healthVariation));
int32 hpScaleFactor = sMpDataStore->GetHealthScaleFactor(mapId, difficulty);
if(cInfo->ModHealth > 0.0f) {
return uint32(basehp * (cInfo->ModHealth + hpScaleFactor) * confHPMod);
} else {
@@ -475,6 +673,12 @@ uint32 CalculateNewHealth(CreatureTemplate const* cInfo, uint32 mapId, MpDifficu
}
}
// Calculates a logarithmic growth curve using scaling factor of percentages increase 50 = 1.5, 100 = 2.0,... this allows for fine grain tuning per instance.
float CalculateScaling(int levelDifference, float scaleFactor, float constant, float growthFactor) {
float scaling = constant * std::pow(2.0f, levelDifference / growthFactor) * (1 + (scaleFactor / 100.0f));
return scaling;
}
float GetTypeDamageModifier(int32 Rank)
{
switch (Rank)
@@ -493,3 +697,4 @@ float GetTypeDamageModifier(int32 Rank)
return sWorld->getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE);
}
}

View File

@@ -56,6 +56,11 @@ public:
uint32 legendaryItemOffset;
uint32 ascendantItemOffset;
// Scaling modifiers
uint32 meleeAttackPowerDampener;
uint32 meleeAttackPowerStart;
enum MP_UNIT_EVENT_TYPE
{
UNIT_EVENT_MELEE,
@@ -100,6 +105,9 @@ public:
*/
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);
@@ -110,7 +118,9 @@ public:
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, MpCreatureData* creatureData, Creature* creature, Creature* target, float healMultiplier);
int32 ScaleHealSpell(SpellInfo const * spellInfo, uint32 heal, MpCreatureData* creatureData, Creature* creature, Creature* target, float healMultiplier);
static bool IsFinalBoss(Creature* creature);
private:
MythicPlus() { }
@@ -119,7 +129,8 @@ public:
float GetTypeHealthModifier(int32 rank);
float GetTypeDamageModifier(int32 rank);
uint32 CalculateNewHealth(CreatureTemplate const* cInfo, uint32 mapId, MpDifficulty difficulty, uint32 origHealth, float confHPMod);
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);
#define sMythicPlus MythicPlus::instance()

View File

@@ -1,3 +1,9 @@
#include "Instances/Ragefire/boss_bazzalan.cpp"
// Creature Overrides
enum {
RAGEFIRE_BAZZALAN = 11519
};
void Addmod_mythic_plusScripts();
void Add_MP_AllCreatureScripts();
@@ -9,6 +15,9 @@ void Add_MP_PlayerScripts();
void Add_MP_UnitScripts();
void Add_MP_WorldScripts();
// Mythic custom encounters for mythic+ dungeons
void Addmod_mythic_plusScripts()
{
Add_MP_AllCreatureScripts();
@@ -16,7 +25,13 @@ void Addmod_mythic_plusScripts()
Add_MP_CommandScripts();
Add_MP_GlobalScripts();
// Add_MP_GroupScripts();
// Add_MP_PlayerScripts();
Add_MP_PlayerScripts();
Add_MP_UnitScripts();
Add_MP_WorldScripts();
// new Ragefire_Bazzalan_Mythic();
// list of boss / creature event handlers
// new Ragefire_Bazzalan_Mythic(RAGEFIRE_BAZZALAN);
}

View File

@@ -2,15 +2,17 @@
#include "MpDataStore.h"
#include "MythicPlus.h"
#include "Player.h"
#include "Group.h"
#include "ScriptMgr.h"
class MythicPlus_PlayerScript : public PlayerScript
{
public:
MythicPlus_PlayerScript() : PlayerScript("MythicPlus_PlayerScript") { }
void OnPlayerJustDied(Player* player, Unit* killer)
void OnPlayerKilledByCreature(Player* player, Unit* killer)
{
MpLogger::debug("OnPlayerJustDied: %s", player->GetName());
Map* map = player->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
@@ -20,15 +22,78 @@ public:
return;
}
if (!killer) {
MpGroupData *data = sMpDataStore->GetGroupData(player->GetGroup());
if (!data) {
MpLogger::error("OnPlayerJustDied: No group data found for %s", player->GetName());
return;
}
MpGroupData *data = sMpDataStore->GetGroupData(player->GetGroup());
if (player->GetMap()->IsDungeon()) {
MpLogger::debug("Player {} just died in dungeon {} by {}", player->GetName(), player->GetMap()->GetMapName(), killer->GetName());
MpPlayerData *playerData = sMpDataStore->GetPlayerData(player->GetGUID());
if (!playerData) {
MpLogger::error("OnPlayerJustDied: No player data found for %s", player->GetName());
return;
}
// Update in memory store
playerData->AddDeath(map->GetId(), map->GetInstanceId());
// Track deaths and add to mp_player_death_stats
Creature* creature = killer->ToCreature();
if(creature) {
sMpDataStore->DBAddPlayerDeath(player, creature);
} else {
sMpDataStore->DBAddPlayerDeath(player);
}
// update that group data in the database
sMpDataStore->DBAddGroupDeath(data->group, map->GetId(), map->GetInstanceId(), data->difficulty);
}
void OnSave(Player* player) override { }
// 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;
}
MpPlayerData* playerData = sMpDataStore->GetPlayerData(player->GetGUID());
if(!playerData) {
MpLogger::warn("PlayerData not found for player {} perhaps not in mythic+ group, bad player state?", player->GetName());
}
auto mapKey = sMpDataStore->GetInstanceDataKey(mapId, player->GetInstanceId());
playerData->instanceData.emplace(mapKey, MpPlayerInstanceData{
.deaths = 0,
});
sMpDataStore->DBUpdatePlayerInstanceData(player->GetGUID(), data->difficulty, map->GetId(), player->GetInstanceId(), 0);
if(group->GetLeaderGUID() == player->GetGUID()) {
sMpDataStore->DBUpdateGroupData(group->GetGUID(), data->difficulty, map->GetId(), player->GetInstanceId(), 0);
}
}
};

View File

@@ -32,7 +32,6 @@ public:
}
}
if(isHot) {
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_HOT, target, attacker, damage, spellInfo);
} else {
@@ -140,15 +139,6 @@ public:
break;
}
if(eventType != MythicPlus::UNIT_EVENT_MELEE) {
MpLogger::debug("Incoming Event Type ({}): {} hits {} before mod: {} spell: ", eventName, attacker->GetName(), target->GetName(), damageOrHeal, spellInfo ? spellInfo->SpellName[0] : "none");
if(creature->IsDungeonBoss()) {
alteredDmgHeal = damageOrHeal * instanceData->boss.melee;
} else {
alteredDmgHeal = damageOrHeal * instanceData->creature.melee;
}
}
// If the target is the enemy then increase the amount of healing by the instance data modifier for spell output.
if(sMythicPlus->EligibleDamageTarget(target)) {
/**
@@ -157,7 +147,7 @@ public:
*/
switch (eventType) {
case MythicPlus::UNIT_EVENT_MELEE:
if(creature->IsDungeonBoss()) {
if(creature->IsDungeonBoss() || creature->GetEntry() == 23682) {
alteredDmgHeal = damageOrHeal * instanceData->boss.melee;
} else {
alteredDmgHeal = damageOrHeal * instanceData->creature.melee;
@@ -166,7 +156,7 @@ public:
break;
case MythicPlus::UNIT_EVENT_DOT:
case MythicPlus::UNIT_EVENT_SPELL:
if(creature->IsDungeonBoss()) {
if(creature->IsDungeonBoss() || creature->GetEntry() == 23682) {
if(spellInfo) {
alteredDmgHeal = sMythicPlus->ScaleDamageSpell(spellInfo, damageOrHeal, sMpDataStore->GetCreatureData(attacker->GetGUID()), creature, target, instanceData->boss.spell);
} else {
@@ -186,8 +176,8 @@ public:
MpLogger::debug("Incoming spell New Damage: {}({}) {} hits {}", alteredDmgHeal, damageOrHeal, attacker->GetName(), target->GetName());
}
break;
case MythicPlus::UNIT_EVENT_HOT:
case MythicPlus::UNIT_EVENT_HEAL:
case MythicPlus::UNIT_EVENT_HOT:
break;
}
}
@@ -199,13 +189,13 @@ public:
bool isHeal = true;
if(creature->IsDungeonBoss()) {
if(spellInfo) {
alteredDmgHeal = sMythicPlus->ScaleHealSpell(spellInfo, sMpDataStore->GetCreatureData(attacker->GetGUID()), creature, attacker->ToCreature(), instanceData->boss.spell);
alteredDmgHeal = sMythicPlus->ScaleHealSpell(spellInfo, damageOrHeal, sMpDataStore->GetCreatureData(attacker->GetGUID()), creature, attacker->ToCreature(), instanceData->boss.spell);
} else {
alteredDmgHeal = damageOrHeal * instanceData->boss.spell;
}
} else {
if(spellInfo) {
alteredDmgHeal = sMythicPlus->ScaleHealSpell(spellInfo, sMpDataStore->GetCreatureData(attacker->GetGUID()), creature, attacker->ToCreature(), instanceData->creature.spell);
alteredDmgHeal = sMythicPlus->ScaleHealSpell(spellInfo, damageOrHeal, sMpDataStore->GetCreatureData(attacker->GetGUID()), creature, attacker->ToCreature(), instanceData->creature.spell);
} else {
alteredDmgHeal = damageOrHeal * instanceData->creature.spell;
}

View File

@@ -86,13 +86,15 @@ public:
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);
sMythicPlus->meleeAttackPowerDampener = sConfigMgr->GetOption<uint32>("MythicPlus.MeleeAttackPowerDampener", 2000);
sMythicPlus->meleeAttackPowerStart = sConfigMgr->GetOption<uint32>("MythicPlus.MeleeAttackPowerStart", 10000);
}
void OnStartup() override
{
int32 size = sMpDataStore->LoadScaleFactors();
MpLogger::info("Loaded {} Mythic+ Scaling Factors from database...", size);
}
};