|
Моды Неофициальная модификация ядра MaNGOS, собственные наработки, расширение функционала |
|
Опции темы | Поиск в этой теме | Опции просмотра |
21.06.2010, 12:11 | #1 |
Пользователь
Регистрация: 09.03.2010
Сообщений: 37
Сказал(а) спасибо: 4
Поблагодарили 63 раз(а) в 21 сообщениях
|
[mod] DBC_Patcher
При работе с DBC часто выясняется, что данные в них не всегда правильные.
Так как на клиенте во многих случаях достаточно правильно отобразить урон, вероятность и т.д. , то другие параметры заклинаний разработчикам были не важны, их корректности никто не добивался. Т.к. Mangos использует данные DBC как основные, получается что некорректные данные не могут быть "стандартно" реализованы через обработчики эффектов заклинаний , либо требуют отдельного кода для реализации. Некоторые заклинания легко могут быть починены заменой эффектов, значений, масок и т.д. Патч изменяет значения в памяти после загрузки DBC. Размер всех в структуре SpellEntry (DBCStructure.h) кратен 4 байтам, поэтому проще всего патчить типом данных uint32. Патч реализован на уровне идеи, не реализована проверка ошибок. Код:
diff --git a/src/shared/Database/DBCFileLoader.cpp b/src/shared/Database/DBCFileLoader.cpp index 613a87e..616d1f7 100644 --- a/src/shared/Database/DBCFileLoader.cpp +++ b/src/shared/Database/DBCFileLoader.cpp @@ -21,6 +21,8 @@ #include <string.h> #include "DBCFileLoader.h" +#include "Database/SQLStorage.h" +#include "Util.h" DBCFileLoader::DBCFileLoader() { @@ -84,6 +86,50 @@ bool DBCFileLoader::Load(const char *filename, const char *fmt) if(fread(data,recordSize*recordCount+stringSize,1,f)!=1) return false; + //DBC Patch + const char* dbc_name=strrchr(filename,'/')+1; + QueryResult *result = WorldDatabase.PQuery("SELECT entry, data FROM spell_patch WHERE DBC='%s' ORDER BY entry",dbc_name); + if(result) + { uint32 *patched_record=(uint32*)data; + do + { + Field *fields = result->Fetch(); + + uint32 entry = fields[0].GetUInt32(); + std::string patch_data = fields[1].GetString(); + + Tokens tokens = StrSplit(patch_data, " "); + int32 m_valuesCount=tokens.size(); + if(m_valuesCount & 1) + continue; //нечетное число - ошибка + + + //Пропускаем ненужные записи + while( *patched_record < entry) + { + patched_record+=recordSize / sizeof(uint32); + } + //Ошибка, больше не найдеться записей для патчей + if (*patched_record > entry) + break; + + sLog.outError ("patch entry=%u ,%s",entry,patch_data.c_str()); + Tokens::iterator iter; + int index; + for (iter = tokens.begin(), index = 0; index < m_valuesCount; ++iter, index+=2) + { + uint32 addr = atol((*iter).c_str()); + ++iter; + uint32 val = atol((*iter).c_str()); + *(patched_record+addr)=val; + } + + + } + while (result->NextRow()); + delete result; + + } fclose(f); return true; Код:
CREATE TABLE spell_patch( entry INT(11) NOT NULL, dbc VARCHAR(255) DEFAULT NULL, `data` VARCHAR(255) DEFAULT NULL, `comment` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (entry) ) ; -- -- INSERT INTO spell_patch VALUES (50508, 'Spell.dbc', '101 255', 'Crypt Fever'), (50509, 'Spell.dbc', '101 255', 'Crypt Fever'), (50510, 'Spell.dbc', '101 255', 'Crypt Fever'), (51726, 'Spell.dbc', '101 255 102 87', 'Ebon Plague'), (51734, 'Spell.dbc', '101 255 102 87', 'Ebon Plague'), (51735, 'Spell.dbc', '101 255 102 87', 'Ebon Plague'), (69412, 'Spell.dbc', '113 49640', 'Abyssal Shatter(69412)'); В патче 3.3.2 перестало работать заклинание 69412 (Abyssal Shatter). По данным spell_works в данных пропал предмет, который создается при использовании Abyssal Shatter. Код:
ID - 69412 Abyssal Shatter () -------------------------- Disenchants an Abyss Crystal into Greater Cosmic Essence or Infinite Dust. -------------------------- Category = 0, SpellIconID = 4061, activeIconID = 0, SpellVisual_0 = 563, SpellVisual_1 = 0 Family SPELLFAMILY_GENERIC, flag 0x00000000 00000000 00000000 School = SPELL_SCHOOL_NORMAL, DamageClass = SPELL_DAMAGE_CLASS_NONE, PreventionType = NONE Skill (333) Enchanting, Min Value 445, Max Value 450 Attributes 0x00010020, Ex 0x00000400, Ex2 0x00000000, Ex3 0x00000000, Ex4 0x00000000, Ex5 0x00000000, Ex6 0x00000000 CastingTime = 3.00 Interrupt Flags: 0x0000000F, AuraIF 0x00000000, ChannelIF 0x00000000 Chance = 101, charges - 0 Effect: (157) SPELL_EFFECT_157 Base point = 0 Target A (TARGET_SELF), Target B (No target) EffectMiscValue = 27716 Effect: NO EFFECT Effect: NO EFFECT Код:
ID - 69412 Abyssal Shatter () -------------------------- Disenchants an Abyss Crystal into Greater Cosmic Essence or Infinite Dust. -------------------------- Category = 0, SpellIconID = 4061, activeIconID = 0, SpellVisual_0 = 563, SpellVisual_1 = 0 Family SPELLFAMILY_GENERIC, flag 0x00000000 00000000 00000000 School = SPELL_SCHOOL_NORMAL, DamageClass = SPELL_DAMAGE_CLASS_NONE, PreventionType = NONE Skill (333) Enchanting, Min Value 445, Max Value 450 Attributes 0x00010020, Ex 0x00000400, Ex2 0x00000000, Ex3 0x00000000, Ex4 0x00000000, Ex5 0x00000000, Ex6 0x00000000 CastingTime = 3.00 Interrupt Flags: 0x0000000F, AuraIF 0x00000000, ChannelIF 0x00000000 Chance = 101, charges - 0 Effect: (157) SPELL_EFFECT_157 Base point = 1 Target A (TARGET_SELF), Target B (No target) EffectMiscValue = 27716 EffectItemType = 49640 Меняем значение 0 на 49640 по смещению 113. Заклинание начинает работать. Талант Ebon Plaguebringer(51161) вешает дебафф Ebon Plague (51735) который должен увеличивать урон от болезней и от всего магического урона. В заклинании используется спелл 65142, о котором ничего не известно. Код:
ID - 51735 Ebon Plague () -------------------------- Your Crypt Fever morphs into Ebon Plague, which increases magic damage taken by $s2% in addition to increasing disease damage taken by $s1%. ToolTip: Increases disease damage taken by $s1%. Increases magic damage taken by $s2%. -------------------------- Category = 0, SpellIconID = 1933, activeIconID = 0, SpellVisual_0 = 0, SpellVisual_1 = 0 Family SPELLFAMILY_DEATHKNIGHT, flag 0x00000040 00000800 00000000 School = SPELL_SCHOOL_SHADOW, DamageClass = SPELL_DAMAGE_CLASS_NONE, PreventionType = NONE Spell level = 1 Dispel - 3 Mechanic - 22 - MECHANIC_PERSUADED Range 50000.00 - 50000.00 yards Attributes 0x00040000, Ex 0x00000088, Ex2 0x00000000, Ex3 0x00000000, Ex4 0x00000000, Ex5 0x00000000, Ex6 0x00000000 Duration = 15000, 0, 15000 Interrupt Flags: 0x00000000, AuraIF 0x00000000, ChannelIF 0x00000000 Chance = 101, charges - 0 Effect: (006) SPELL_EFFECT_APPLY_AURA Base point = 30 Target A (TARGET_CHAIN_DAMAGE), Target B (No target) Aura 284, value = 30, misc = 22, miscB = 0, periodic = 0 Trigger spell (65142) Not found, Chance = 101 Effect: (006) SPELL_EFFECT_APPLY_AURA Base point = 13 Target A (TARGET_CHAIN_DAMAGE), Target B (No target) Aura (004) SPELL_AURA_DUMMY, value = 13, misc = 126, miscB = 0, periodic = 0 Код:
ID - 47865 Curse of the Elements (Rank 5) -------------------------- Curses the target for $d, reducing Arcane, Fire, Frost, Nature, and Shadow resistances by $s1 and increasing magic damage taken by $s2%. Only one Curse per Warlock can be active on any one target. ToolTip: Reduces Arcane, Fire, Frost, Nature and Shadow resistances by $s1. Increases magic damage taken by $s2%. -------------------------- Effect: (006) SPELL_EFFECT_APPLY_AURA Base point = 13 Target A (TARGET_CHAIN_DAMAGE), Target B (No target) Aura (087) SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, value = 13, misc = 126, miscB = 0, periodic = 0 Код:
ID - 46857 Trauma (Rank 2) -------------------------- Your normal melee critical strikes increase the effectiveness of Bleed effects on the target by $46857s1% for $46857d. ToolTip: Bleed effects cause an additional $s1% damage. ------------------------- Effect: (006) SPELL_EFFECT_APPLY_AURA Base point = 30 Target A (TARGET_CHAIN_DAMAGE), Target B (No target) Aura (255) SPELL_AURA_255, value = 30, misc = 15, miscB = 0, periodic = 0 SpellClassMask = 00000000 00000008 00002010 |