Ru-MaNGOS

Вернуться   Ru-MaNGOS > Ядро > Патчи

Важная информация

Патчи Если кто-то хочет выложить не свой готовый патч - не забудьте указать автора и источник.

Если кто-то хочет задать вопрос по патчу - велкам.

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 31.10.2010, 15:23   #1
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию [patch/dev] Замена бонусов аур более сильными

Суть проблемы: спеллы с флагом SPELL_ATTR_EXG_UNK28 не подавляют более слабые эффекты спеллов с тем же аттрибутом, которые уже наложены на цели.

Автор: я, но с данными для DBCStructure и т.п. помог nos4r2zod

Одна из первых и самых сырых версий патча

полная работоспособная версия http://paste2.org/p/1064859
укороченная версия - только для просмотра проблеммного кода!
Код:
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 5b95452..5f2e690 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -5745,7 +5745,8 @@ void Aura::HandleRangedAmmoHaste(bool apply, bool /*Real*/)
 
 void Aura::HandleAuraModAttackPower(bool apply, bool /*Real*/)
 {
-    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+	float value = ReplaceByMorePowerfulAura(m_modifier.m_auraname, m_modifier.m_amount);
+    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, value, apply);
 }
 
 void Aura::HandleAuraModRangedAttackPower(bool apply, bool /*Real*/)
@@ -5753,13 +5754,15 @@ void Aura::HandleAuraModRangedAttackPower(bool apply, bool /*Real*/)
     if((GetTarget()->getClassMask() & CLASSMASK_WAND_USERS)!=0)
         return;
 
-    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+	float value = ReplaceByMorePowerfulAura(m_modifier.m_auraname, m_modifier.m_amount);
+    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, value, apply);
 }
 
 void Aura::HandleAuraModAttackPowerPercent(bool apply, bool /*Real*/)
 {
+	float value = ReplaceByMorePowerfulAura(m_modifier.m_auraname, m_modifier.m_amount);
     //UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
-    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(m_modifier.m_amount), apply);
+    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, value, apply);
 }
 
 void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool /*Real*/)
@@ -5767,8 +5770,9 @@ void Aura::HandleAuraModRangedAttackPowerPercent(bool apply, bool /*Real*/)
     if((GetTarget()->getClassMask() & CLASSMASK_WAND_USERS)!=0)
         return;
 
+	float value = ReplaceByMorePowerfulAura(m_modifier.m_auraname, m_modifier.m_amount);
     //UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
-    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(m_modifier.m_amount), apply);
+    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, value, apply);
 }
 
 void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool /*apply*/, bool Real)
@@ -8058,6 +8062,24 @@ void Aura::HandleAuraModAllCritChance(bool apply, bool Real)
     ((Player*)target)->UpdateAllSpellCritChances();
 }
 
+float Aura::ReplaceByMorePowerfulAura(AuraType type, float newValue)
+{
+    if (GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_UNK28)
+    {
+        int32 oldMaxValue = 0;
+        Unit::AuraList const& APPauras = GetTarget()->GetAurasByType(type);
+        for (Unit::AuraList::const_iterator i = APPauras.begin(); i != APPauras.end(); ++i)
+            if ((*i)->GetSpellProto()->Id != GetSpellProto()->Id && (*i)->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_UNK28)
+            {
+                if (oldMaxValue < (*i)->GetModifier()->m_amount)
+                    oldMaxValue = (*i)->GetModifier()->m_amount;
+            }
+
+        return (newValue > oldMaxValue) ? newValue - oldMaxValue : 0.0f;
+    }
+    return newValue;
+}
+
 void Aura::SetAuraMaxDuration( int32 duration )
 {
 	m_maxduration = duration;
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index bb17cc4..cd9d353 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -365,6 +365,7 @@ class MANGOS_DLL_SPEC Aura
         void HandleAuraModAllCritChance(bool Apply, bool Real);
         void HandleAuraLinked(bool Apply, bool Real);
         void HandleAuraOpenStable(bool apply, bool Real);
+        float ReplaceByMorePowerfulAura(AuraType type, float newValue);
 
         virtual ~Aura();
За основу взят код из одного древнего патча на замену резистов xD

Жду подмоги, сам уже замаялся этот патч мучить... тут как минимум нужно упростить код, но на это врятли способен, ибо не особо шарю в составлении функций мангоса :/
__________________
Если ты видишь это сообщение то ты просто обязан нажать "Спасибо"

Последний раз редактировалось Insider42; 31.10.2010 в 15:42.
Insider42 вне форума   Ответить с цитированием
Старый 31.10.2010, 15:27   #2
SeT
Ученый
 
Аватар для SeT
 
Регистрация: 13.03.2010
Сообщений: 110
Сказал(а) спасибо: 55
Поблагодарили 23 раз(а) в 14 сообщениях
SeT На верном пути
По умолчанию

http://github.com/stcore/mangos/comm...71e58126a46b3e
на досуге надо переписать с использованием флага.

Последний раз редактировалось SeT; 31.10.2010 в 15:31.
SeT вне форума   Ответить с цитированием
Старый 31.10.2010, 15:40   #3
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Мой вариант мне нравится больше... уж слишком громоздко всё у вас и пугающе
И похоже я нашёл почему происходит, описанная мною в начале темы, проблема - исправил, в 1 посту новый патч...

В моем патче я также не стал затрагивать тотемы, свитки и прочую лабуду:/ т.к. незнаю как воздействуют бафы, меняющие все статы на % вместе с бафами, которые меняют конкретную стату на оффе

А то что уже реализовано - протестировал и не обнаружил проблем.

ЗЫ: тому кто поможет упростить патч (там явно не нужно столько параметров в функции, да и float в мангосе как вижу не популярен - это просто я ничего лучше не придумал) нажму "Спасибо"
__________________
Если ты видишь это сообщение то ты просто обязан нажать "Спасибо"

Последний раз редактировалось Insider42; 31.10.2010 в 15:47.
Insider42 вне форума   Ответить с цитированием
Старый 31.10.2010, 15:44   #4
SeT
Ученый
 
Аватар для SeT
 
Регистрация: 13.03.2010
Сообщений: 110
Сказал(а) спасибо: 55
Поблагодарили 23 раз(а) в 14 сообщениях
SeT На верном пути
По умолчанию

Цитата:
Сообщение от Insider42 Посмотреть сообщение
Мой вариант мне нравится больше... уж слишком громоздко всё у вас и пугающе
И похоже я нашёл почему происходит, описанная мною в начале темы, проблема.
Я же говорю переписать надо. Все это писалось год назад, без использования аттрибута, поэтому пришлось как то фильтровать ауры. Если использовать аттрибут, то можно избавится от перечисления аур и проверок - на каст с итема\пассивных аур\элексиров.
Но пока действую по правилу - "зачем трогать то, что и так хорошо работает".
SeT вне форума   Ответить с цитированием
Старый 31.10.2010, 16:14   #5
virusav
Администратор
 
Аватар для virusav
 
Регистрация: 19.02.2010
Сообщений: 492
Сказал(а) спасибо: 55
Поблагодарили 341 раз(а) в 154 сообщениях
virusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человек
Отправить сообщение для virusav с помощью ICQ
По умолчанию

По идее, можно
Код:
-    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+	float value = ReplaceByMorePowerfulAura(m_modifier.m_auraname, m_modifier.m_amount);
+    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, value, apply);
заменить на
Код:
-    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(ReplaceByMorePowerfulAura(m_modifier.m_auraname, m_modifier.m_amount)), apply);
И так в каждой функции.

Не совсем понял насчет float Aura::ReplaceByMorePowerfulAura(AuraType type, float newValue).
Если newValue = 1.05f, есть аура с (*i)->GetModifier()->m_amount = 1.03f.
По функции получается:
int32 oldMaxValue = 0;
if (0 < 1.03f) oldMaxValue = 1.03f;
return (1.05f > 1.03f) ? 1.05f - 1.03f : 0.0f;

В итоге при новом значении 1.05f и старом 1.03f получим 0.02f.
Если есть только новое значение, то 1.05f.

Или я не догнал суть функции.

Кроме того, вызов новой функции идет в HandleStatModifier.
Может, там логичнее разместить обработку, если, конечно, все данные для этого в HandleStatModifier будут?
virusav вне форума   Ответить с цитированием
Старый 31.10.2010, 16:25   #6
virusav
Администратор
 
Аватар для virusav
 
Регистрация: 19.02.2010
Сообщений: 492
Сказал(а) спасибо: 55
Поблагодарили 341 раз(а) в 154 сообщениях
virusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человек
Отправить сообщение для virusav с помощью ICQ
По умолчанию

Насчет разницы, вроде, понял: уже есть старое значение 1.03f, поэтому прибавляем только 0.02f, чтобы в конечном итоге получить 1.05f.
virusav вне форума   Ответить с цитированием
Старый 31.10.2010, 16:25   #7
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от virusav Посмотреть сообщение
В итоге при новом значении 1.05f и старом 1.03f получим 0.02f.
Если есть только новое значение, то 1.05f.
Всё верно, так и задумано. Дело в том, что если у нас есть старая аура, то мы попросту добавляем разницу между ними (т.к. новая более сильная)

Цитата:
Сообщение от virusav Посмотреть сообщение
По идее, можно
Код:
-    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+	float value = ReplaceByMorePowerfulAura(m_modifier.m_auraname, m_modifier.m_amount);
+    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, value, apply);
заменить на
Код:
-    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_modifier.m_amount), apply);
+    GetTarget()->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(ReplaceByMorePowerfulAura(m_modifier.m_auraname, m_modifier.m_amount)), apply);
И так в каждой функции.
я тоже об этом подумывал, но пугала слишком длинная строчка которая получалсь в итоге %)
У меня просто до сих пор сомнения о надобности параметров тут вообще, но и проверять этот вариант поленился :/ я до сих пор не понял, наследует ли вызванная функция все известное той из которой была вызвана... тут сыграло роль моё нупство в C++
__________________
Если ты видишь это сообщение то ты просто обязан нажать "Спасибо"

Последний раз редактировалось Insider42; 31.10.2010 в 16:29.
Insider42 вне форума   Ответить с цитированием
Старый 31.10.2010, 16:28   #8
virusav
Администратор
 
Аватар для virusav
 
Регистрация: 19.02.2010
Сообщений: 492
Сказал(а) спасибо: 55
Поблагодарили 341 раз(а) в 154 сообщениях
virusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человек
Отправить сообщение для virusav с помощью ICQ
По умолчанию

Логичнее было бы в HandleStatModifier перенести, если данных хватает.
virusav вне форума   Ответить с цитированием
Старый 31.10.2010, 17:27   #9
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от virusav Посмотреть сообщение
Логичнее было бы в HandleStatModifier перенести, если данных хватает.
на такое сообразить пока не получается... да и по-моему не место ему там, как минимум придётся switch фтыкать

Мне бы кто по стаку бафов на статы инфу дал

Кстати тут ещё с аурами на крит (Буйство и Лидер стаи) нада тоже самое провернуть
__________________
Если ты видишь это сообщение то ты просто обязан нажать "Спасибо"

Последний раз редактировалось Insider42; 31.10.2010 в 17:32.
Insider42 вне форума   Ответить с цитированием
Старый 31.10.2010, 17:44   #10
virusav
Администратор
 
Аватар для virusav
 
Регистрация: 19.02.2010
Сообщений: 492
Сказал(а) спасибо: 55
Поблагодарили 341 раз(а) в 154 сообщениях
virusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человек
Отправить сообщение для virusav с помощью ICQ
По умолчанию

Перенес вычисление amount в HandleStatModifier.
На каких двух спеллах можно проверить работу патча?
virusav вне форума   Ответить с цитированием
Старый 31.10.2010, 17:57   #11
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от virusav Посмотреть сообщение
Перенес вычисление amount в HandleStatModifier.
На каких двух спеллах можно проверить работу патча?
Trueshot Aura у хантов и Unleashed Rage у шаманов (обязательно проверить с разными рангами)
__________________
Если ты видишь это сообщение то ты просто обязан нажать "Спасибо"
Insider42 вне форума   Ответить с цитированием
Старый 31.10.2010, 18:03   #12
SeT
Ученый
 
Аватар для SeT
 
Регистрация: 13.03.2010
Сообщений: 110
Сказал(а) спасибо: 55
Поблагодарили 23 раз(а) в 14 сообщениях
SeT На верном пути
По умолчанию

А как же другие ауры? На статы допустим.
SeT вне форума   Ответить с цитированием
Старый 31.10.2010, 18:37   #13
virusav
Администратор
 
Аватар для virusav
 
Регистрация: 19.02.2010
Сообщений: 492
Сказал(а) спасибо: 55
Поблагодарили 341 раз(а) в 154 сообщениях
virusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человек
Отправить сообщение для virusav с помощью ICQ
По умолчанию

С кодом в HandleStatModifier:
создал нового перса:
1. Каст только 19506:
Код:
2010-10-31 19:24:20 ERROR:1. newValue=10.000000
2010-10-31 19:24:20 ERROR:2. spellId1=19506
2010-10-31 19:24:20 ERROR:4. oldMaxValue=0.000000
2010-10-31 19:24:20 ERROR:5. amount=10.000000
2. Каст только 30802:
Код:
2010-10-31 19:28:11 ERROR:1. newValue=4.000000
2010-10-31 19:28:11 ERROR:2. spellId1=30802
2010-10-31 19:28:11 ERROR:4. oldMaxValue=0.000000
2010-10-31 19:28:11 ERROR:5. amount=4.000000
3. Каст 30802 после 19506:
Код:
2010-10-31 19:24:27 ERROR:1. newValue=4.000000
2010-10-31 19:24:27 ERROR:2. spellId1=30802
2010-10-31 19:24:27 ERROR:3. spellId2=19506
2010-10-31 19:24:27 ERROR:4. oldMaxValue=10.000000
2010-10-31 19:24:27 ERROR:5. amount=0.000000
4. Каст 19506 после 30802:
Код:
2010-10-31 19:28:19 ERROR:1. newValue=10.000000
2010-10-31 19:28:19 ERROR:2. spellId1=19506
2010-10-31 19:28:19 ERROR:3. spellId2=30802
2010-10-31 19:28:19 ERROR:4. oldMaxValue=4.000000
2010-10-31 19:28:19 ERROR:5. amount=6.000000
virusav вне форума   Ответить с цитированием
Старый 31.10.2010, 18:58   #14
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию

Цитата:
Сообщение от virusav Посмотреть сообщение
С кодом в HandleStatModifier:
создал нового перса:
1. Каст только 19506:
Код:
2010-10-31 19:24:20 ERROR:1. newValue=10.000000
2010-10-31 19:24:20 ERROR:2. spellId1=19506
2010-10-31 19:24:20 ERROR:4. oldMaxValue=0.000000
2010-10-31 19:24:20 ERROR:5. amount=10.000000
2. Каст только 30802:
Код:
2010-10-31 19:28:11 ERROR:1. newValue=4.000000
2010-10-31 19:28:11 ERROR:2. spellId1=30802
2010-10-31 19:28:11 ERROR:4. oldMaxValue=0.000000
2010-10-31 19:28:11 ERROR:5. amount=4.000000
3. Каст 30802 после 19506:
Код:
2010-10-31 19:24:27 ERROR:1. newValue=4.000000
2010-10-31 19:24:27 ERROR:2. spellId1=30802
2010-10-31 19:24:27 ERROR:3. spellId2=19506
2010-10-31 19:24:27 ERROR:4. oldMaxValue=10.000000
2010-10-31 19:24:27 ERROR:5. amount=0.000000
4. Каст 19506 после 30802:
Код:
2010-10-31 19:28:19 ERROR:1. newValue=10.000000
2010-10-31 19:28:19 ERROR:2. spellId1=19506
2010-10-31 19:28:19 ERROR:3. spellId2=30802
2010-10-31 19:28:19 ERROR:4. oldMaxValue=4.000000
2010-10-31 19:28:19 ERROR:5. amount=6.000000
также стоит попробовать наложить оба, затем наложить 53434 и отменить сильнейшую из предыдущих двух, если стата уменьшиться на разницу в "силе" между первыми двумя то всё ок, если же ничего не изменится - баг, и по окончании 53434 мы будем иметь неверное количество этой статы, в общем забажили (у меня так было пока не добавил дополнительный return.
__________________
Если ты видишь это сообщение то ты просто обязан нажать "Спасибо"
Insider42 вне форума   Ответить с цитированием
Старый 31.10.2010, 21:10   #15
virusav
Администратор
 
Аватар для virusav
 
Регистрация: 19.02.2010
Сообщений: 492
Сказал(а) спасибо: 55
Поблагодарили 341 раз(а) в 154 сообщениях
virusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человекvirusav Реально хороший человек
Отправить сообщение для virusav с помощью ICQ
По умолчанию

Еще бы как-нибудь получить ауру при apply = false.
virusav вне форума   Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Реализация Death Knight T8 Melee 4P Bonus + упрощение расчетов бонусов от болезней ДК Warlord123 Патчи на рассмотрении 0 22.10.2010 19:01
каким образом можно получить более 60 000 хитов в форме медведя? tempura Флудильня 25 04.07.2010 15:11
Реализация системы бонусов Max Z. Корзина 3 24.05.2010 18:45


Текущее время: 04:54. Часовой пояс GMT +3.


ru-mangos.ru - Русское сообщество MaNGOS
Главная цель проекта MaNGOS - обучающая, поэтому разрешается использовать исходный код и собранную программу только для образовательных целей.
Вы не можете использовать MaNGOS в коммерческих целях, а также не разрешается устанавливать публичные серверы на базе MaNGOS.
Любое копирование материалов, информации в любом виде без указания источника - форума Ru-MaNGOS будет считаться нарушением авторских прав и нарушением Уголовного Кодекса РФ, ст. 146 ст. 147.
Перевод vBulletin: zCarot