mirror of
https://github.com/araxiaonline/mod-mythic-plus.git
synced 2026-06-13 03:02:24 -04:00
Compare commits
39 Commits
test-v2
...
feat/add-d
| Author | SHA1 | Date | |
|---|---|---|---|
| 73018100ac | |||
| fbcb218dd6 | |||
| 322243abf4 | |||
| 9d009d0feb | |||
| a0fdfc9836 | |||
| a6de416efb | |||
| 1695f33f68 | |||
| 88d894eaaf | |||
| f66b861079 | |||
| 79cb4d9835 | |||
| c32b64bb1f | |||
| f083748c4a | |||
| 3cf1e17c99 | |||
| 0a0236b273 | |||
| 8942d53b13 | |||
| 41819432e9 | |||
| d35a934b8a | |||
| 46d5a99f04 | |||
| f8ecc0d1b9 | |||
| fcce3a0453 | |||
| 68efd1a732 | |||
| 9f4ea9d539 | |||
| 803cb246bf | |||
| 1bd94e56fa | |||
| 0ee3ead805 | |||
| ec1663aa34 | |||
| 3d0f314c39 | |||
| 5877e9122c | |||
| 5847754197 | |||
| 6936f8b73e | |||
| a35e4b646d | |||
| a4d7b00036 | |||
| 73c2b8923b | |||
| d3af7990cb | |||
| 25f74e1b5a | |||
| cbec66031d | |||
| 4a8731c876 | |||
| a62df56099 | |||
| 7f78971e49 |
@@ -112,3 +112,8 @@ MythicPlus.Mythic.ItemOffset = 20000000
|
||||
MythicPlus.Legendary.ItemOffset = 21000000
|
||||
MythicPlus.Ascendant.ItemOffset = 22000000
|
||||
|
||||
##############
|
||||
# Scaling Adjusters
|
||||
#############
|
||||
MythicPlus.MeleeAttackPowerDampener = 800
|
||||
MythicPlus.MeleeAttackPowerStart = 3000
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
80
data/sql/db-characters/base/mp_schema.sql
Normal file
80
data/sql/db-characters/base/mp_schema.sql
Normal 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)
|
||||
);
|
||||
255
data/sql/db-world/base/mp_material_types.sql
Normal file
255
data/sql/db-world/base/mp_material_types.sql
Normal 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'
|
||||
);
|
||||
45
data/sql/db-world/base/mp_world_schema.sql
Normal file
45
data/sql/db-world/base/mp_world_schema.sql
Normal 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
|
||||
);
|
||||
@@ -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)
|
||||
|
||||
247
data/sql/db-world/base/pet_levelstats.sql
Normal file
247
data/sql/db-world/base/pet_levelstats.sql
Normal 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);
|
||||
253
scripts/advancement_stats_ranks/generate_stat_upgrades.sql
Normal file
253
scripts/advancement_stats_ranks/generate_stat_upgrades.sql
Normal 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),
|
||||
;
|
||||
77
scripts/advancement_stats_ranks/main.go
Normal file
77
scripts/advancement_stats_ranks/main.go
Normal 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")
|
||||
}
|
||||
77
scripts/upgrade_ranks/main.go
Normal file
77
scripts/upgrade_ranks/main.go
Normal 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")
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
35
src/BaseCreatureHandler.h
Normal 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() {}
|
||||
};
|
||||
@@ -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
84
src/CreatureHooks.cpp
Normal 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
92
src/CreatureHooks.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
26
src/Instances/Ragefire/boss_bazzalan.cpp
Normal file
26
src/Instances/Ragefire/boss_bazzalan.cpp
Normal 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);
|
||||
|
||||
// }
|
||||
// };
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
39
src/MpScriptAI.h
Normal 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();
|
||||
}
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user