| 
 Решение багов ERA/WOG - igrik -  21.09.2011 22:09
 
 Данная тема предназначена только для выкладывания кода лечения багов (непосредственно касающихся Вога или Эры) на программном уровне, для того чтобы Berserker мог их включать в состав era.dll
 Любые сообщения, не содержащие указание бага совместно с его решением на Ассамблере, Delphi или С++ будут безжалостно уничтожаться.
 
 
 Я буду данные фиксы включать в плагин game bug fixes extended.dll
 Исходник можно увидеть тут: github.com
 
 [+] работающая кнопка Отмена в Арене[+] кнопка Отмена у Хижины ведьм
 [+] кнопка отмены у ученого, предлагающего втор.навык
 [+] фикс некоторых операций со стеками
 [+] исправление бага посещения банков в которых дают существ (вылет в диалоге присоедиенния монстров)
 [+] исправление некоторых багов ИИ: хождение по воде (без заклинания) и возможность колдовать заклы выше 1-го уровня на проклятой земле
 [+] фикс урона стрелковых башен при Доспехах и заклинании "Воздушный щит"
 [+] исправление перепутаных бонусов атаки и защиты в спецстроениях Крепости
 [+] исправление бага заклинания Землетрясение, когда оно могло убить верхний стек защитника
 [+] центрирование изображения по ПКМ в городе на иконке найма войск (ранее уходило сильно влево)
 [+] исправление координат кнопки Сказочных Драконов
 [+] исправление ошибки ERM в командре IF:N1, теперь командра работает со всеми локальными, глобальными и отрицательными переменными z, а не только с z1
 [+] исправление неправильных иконок специализаций героев Инферно (Ксерафакс и Ксерон)
 [+] исправление некоторых кнопок в таверне, в окне разделения отряда, в диалоге преобразователя скелетов
 [+] правильное смещение портрета героя в диалоге повышения уровня героя
 [+] исправление отключения тени курсора при автобитве
 [+] фикс вылета в быстрой битве: проверка скорости монстра на 0
 [+] фикс вылета в быстрой битве: при касте заклинания Воскрешение и Поднятие Мертвецов
 [+] фикс вылета при удалении препятствия в битве
 [+] отключение показа входа Двеллинга 8-го уровня существ, при его захвате ИИ
 [+] ненависть существ теперь считается и на существ 8-го уровня
 [+] бонусы специалистов героев теперь действуюи и существ 8-го уровня
 [+] отключение псевдорасчета урона на существ с полётом и кавалерийским бонусом одновременно
 [+] добавление динамического Fight_Value командира
 [+] исправление бага блока командира, когда защита падала из-за флага "в защите"
 [+] исправление бага блока существ (опыт монстров), когда игра падала в бесконечный цикл
 [+] исправление критического бага Астрального духа
 [+] полноценный хинт колдовства для описаний командиров и монстров с номером больше 134
 [+] исправление бага палатки, когда на её ходу невозможно убежать или сделать другие действия
 [+] критический вылет на ходу палатки
 [+] возможность заходить в гильдию магов без наличия книги и денег у героя-гостя
 [+] исправление бага с исчезновением стартового героя при переигрывании новой карты
 [+] запрет стрельбы при отрицат.боезапасе
 [+] решение бага (еще с SoD) исчезновения улучшенного стека при битве с даунгрейдом нейтралов
 [+] фикс отлета гарпий, когда после удара они связаны корнями дендроидов
 [+] не считать предварительный бонус урона от кавалерии при полете (он всё равно не работает)
 [+] решение бага Вога, когда в бою накладывается опыт через EA:E и атака, защита, уроны, скорость, боезапасы и т.п. заново пересчитываются. Из-за этого терялись бонусы наложенных заклинаний (например бонус скорости от ускорения)
 [+] фикс когда бонусы специалистов не считались существам 8-го уровня
 [+] исправление созданий WoG'ом корявых пакованых координат
 [+] корректировка WoG ненависти существ (добавление и существ 8-го уровня)
 [+] вызовы драконов от артефакта сердце дракона, чтобы в банках существ не перекрывался стек №3
 [+] фикс выбора типа атаки при битве ИИ vs человек (человек не мог выбрать тип атаки)
 [+] решение проблемы отображения некоторых строк (в русской локализации) в диалоге опыта монстров.
 [+] корректировка описаний заклинаний в книге (не учитывались бонусы специалистов по заклинаниям)
 [+] фикс неотображения Монолитов и Подземных врат в диалоге заклинания Просмотр Земли и Воздуха
 [+] фикс неправильного отображения величины урона в окне статуса битвы при касте заклинания Армагеддон
 [+] решение бага ERM: триггер MA:U#/-2 приводил к тому, что любое существо при установке такой команды улучшалось в копейщика
 [+] фикс расстановки клонов от заклинания Клон
 [+] фикс расстановки клонов от опыта монстров
 [+] отображение тени установки заклинания Силовое Поле
 [+] рабочий запрет выдачи заклинаний у артефактов, если они запрещены через UN:J0/spell_id/1
 
 Решение багов ERA/WOG - Sav -  06.07.2012 18:55
 
 Я всё-таки разобрался со шрифтами.
 Вот патч:
 
 PHP Code:
 // Исправляем обработку отрицательного отступа шрифта (ошибку приведения типов)._PI->WriteByte(0x4B5349 + 1, 0xB6); // (mov)zx
 _PI->WriteByte(0x4B53E5 + 1, 0xB6); // (mov)zx
 
Ошибка эта была не в алгоритме, а в приведении типов, поэтому её не видно в выложенном мной декомпилированном коде.
 
 Вот код, содержащий ошибку:
 
 
Тут левый отступ первого символа строки сравнивается с 0, а потом, если он отрицательный, ecx устанавливается в -него (чтобы потом, когда он в цикле прибавится, скомпенсировать его, чтобы таким образом игнорировать отрицательный отступ первого символа строки).Code:
 .text:004B5335 ; 109:             if ( *((_DWORD *)&this_v11->v_table + 3 * (symbol_v21 + 5)) < 0 )// fnt->char_sizes[symbol].width.text:004B5335                 mov     edx, eax
 .text:004B5337                 and     edx, 0FFh
 .text:004B533D                 add     edx, 5
 .text:004B5340                 lea     edx, [edx+edx*2]
 .text:004B5343                 cmp     dword ptr [ebx+edx*4], 0
 .text:004B5347
 .text:004B5347 loc_4B5347:                             ; DATA XREF: 0138630Ao
 .text:004B5347                 jge     short loc_4B5357
 .text:004B5349 ; 110:               symbols_width_v19 = -*((_DWORD *)&this_v11->v_table + 3 * ((char)symbol_v21 + 5));// fnt->char_sizes[symbol].width
 .text:004B5349                 movsx   ecx, al
 .text:004B534C
 .text:004B534C loc_4B534C:                             ; DATA XREF: 018ECE8Co
 .text:004B534C                 add     ecx, 5
 .text:004B534F                 lea     ecx, [ecx+ecx*2]
 .text:004B5352                 mov     ecx, [ebx+ecx*4]
 .text:004B5355                 neg     ecx
 Проблема в строке ".text:004B5349                 movsx   ecx, al". Ведь если символ русский, al будет отрицательной и в ecx запишется отрицательное число, которое потом будет использоваться как индекс. В результате, вместо отступа будет взят мусор (например, 0xBAADF00D), из-за которого строка уползёт чёрт знает куда. Ну или там может лежать 0 и недочёт не будет заметен.
 Такая же вещь с правым отступом последнего символа строки.
 
 Патч правит movsx на movzx, в результате чего знак игнорируется и для русских букв генерируются нормальные индексы.
 
 
 RE: ERA II - Sav -  11.07.2012 20:36
 
 Исправление одного из вылетов при загрузке карты / наступлении новой недели.
 
 PHP Code:
 _PI->WriteDword(0x4CCC43, IntAt(0x4CCC43) - 4); 
Этот вылет связан с содовским багом (возможно, только 3.2) генерации слуха в таверне. Там берётся случайное число от 1 до 256 и по нему как по индексу берётся значение (адрес строки слуха) из 256-элементного массива. Соответственно, первый слух никогда не берётся, зато иногда берётся элемент "за последним", он равен 0, и происходит вылет.
 Раньше мне казалось, что в Воге что-то намутили с таблицей слухов и там этого вылета нет, но теперь я поймал его в Эре.
 
 Этот баг фактически обеспечивал 0.4% шанса вылететь каждую неделю.
   
 
 RE: ERA II - MOP -  20.09.2012 21:27
 
 Исправление бага отображения русских букв в диалоге опыта существ (некоторые способности - чёрточки вместо слов):
 
 
 
 
 RE: ERA II - MOP -  28.09.2012 07:27
 
 деактивация вог-проверок, вызывающих потерю опыта последнего отряда (exe-адреса):
 
 
 
Code:
 2F3C55 EB0C2F3BEC EB0C
 2F42E6 EB0C
 2F4356 EB0C
 Исходники WoG, Monsters.cpp - поиск по фразе "хочет перенести последний стэк - не получится".
   
 
 RE: ERA II - Sav -  14.04.2013 20:33
 
 Некоторое время назад я исправлял вылеты, связанные со слухами в таверне. Сейчас я подробно исследовал тот код и понял, что прошлый мой фикс был не совсем правильным: вылет-то он исправлял, но не исправлял нарушенный механизм генерации слухов, делающий некоторые из них недоступными, а некоторые генерирующимися слишком часто, особенно через большое количество недель после начала игры.
 Вместо
 
 
Следует вставитьCode:
 _PI->WriteDword(0x4CCC43, 0x696DE8);
 
 PHP Code:
 _PI->WriteHexPatch(0x4CCC40 + 2, "8D"); // mov ..., ...[ecx*4] 
 
 RE: ERA Scripts 1.15 Rus - gamecreator -  07.04.2015 02:19
 
 
  (07.04.2015 00:51)Elzivir Wrote:  при нападении героя AI на человека в режиме одиночной игры и при попытке последнего путем нажатия ПКМ на кнопку Defend (оборона) поменять тип атаки лучников/командира со стрельбы на рукопашную, выдается сообщение: "This feature does not work in Human vs Human network baced battle", т.е. если стрелки никем не заблокированы им остается лишь дистанционная атака, а переход в режим рукопашного боя невозможен, даже если вражеский юнит находится в пределах досягаемости. Причем, если на стороне атакующего героя будет человек, то данной проблемы не возникает 
  (07.04.2015 01:16)Berserker Wrote:  Может быть кто-нибудь напишет патч, отключающий проверку. Лучше. Меняем проверку флага 997 на 998 (патч для памяти):
 
 
 
 RE: Тема модераторов - gamecreator -  31.05.2016 02:48
 
 Ok, I found the problem. There is a fatal flaw in the hint system, making so that no hint can be set twice. I can imagine how ZVS / sergroj / whoever else made WoG T1 managed to compile this incorrect code. A good example of why one shouldn't use outdated compilers they don't understand.
 Anyhow, here is the fix (hopefully without errors, because I didn't test it):
 
 
Code:
 72982C FC729835 FC
 72983B FC
 729843 FC
 729859 FC
 72987B FC
 72988F FC
 
 
 Решение багов ERA/WOG - igrik -  01.02.2019 15:40
 
 Решение бага Вога, когда в бою накладывается опыт через EA:E и атака, защита, уроны, скорость, боезапасы и т.п. заново пересчитываются.
 Из-за этого теряются бонусы наложенных заклинаний (например бонус скорости от ускорения)
 
 Сама функция пересчета параметров стека из исходников WoG:
 0x726DE4 тут вызывается функция установки опыта в бою (и этот баг) через EA:E = CrExpBon::Apply(MonPos(Type)); (стр.4886)
 int CrExpBon::Apply(Byte *Mon){ // настройка бонусов на поле боя один раз (стр 1495 crexpo.cpp)
 
 
 
Code:
 int __stdcall ERM_Fix_EA_E(HiHook* hook, _BattleStack_* stack ){
 int ret = 0;
 _int32_ spell_duration[81]; // для сохранения длительности заклинаний
 _int32_ spells_power[81];   // для сохранения силы действия заклинания
 
 if (stack) {
 for (int i=0; i<80; i++) {
 spell_duration[i] = stack->active_spell_duration[i];
 spells_power[i] = stack->active_spells_power[i];
 
 if (spell_duration[i] > 0 ) // если заклинание наложено на стек, то сбрасываем его эффект
 CALL_2(int, __thiscall, 0x444230, stack, i); // ResetSpellFromStack 0x444230
 }
 }
 
 ret = CALL_1(int, __cdecl, hook->GetDefaultFunc(), stack);
 
 for (int i=0; i<80; i++) {
 if (spell_duration[i] > 0) { // если заклинание ранее было наложено, то восстанавливаем его
 CALL_5(int, __thiscall, 0x444610, stack, i, spell_duration[i], spells_power[i], 0); // ApplySpell 0x444610
 }
 }
 
 return ret;
 }
 /////////////////////////////////////////////////////////////
 _PI->WriteHiHook(0x726DE4, CALL_, EXTENDED_, CDECL_, ERM_Fix_EA_E);
 
 
 RE: Решение багов ERA/WOG - igrik -  01.02.2019 17:21
 
 Решение багов ИИ, когда тот может (© RoseKavalier):
 1. Использовать заклинание полёт когда у него нет Крыльев Ангела или Полёта
 2. Использовать заклинания на Проклятой Земле, которые на ней запрещены
 
 
Code:
 int __stdcall AI_waterwalk_fly(LoHook *h, HookContext *c){
 if (c->eax == 0) // no angel wings
 {
 _Hero_ *hero = (_Hero_ *)(c->esi);
 if (hero->spell[6] == 0 && hero->spell_level[6] == 0) // this AI hero does not have the means to cast fly (id = 6)
 {
 if (hero->spell[7] != 0 || hero->spell_level[7] != 0) // this AI hero has access to waterwalk (id = 7)
 {
 if (hero->waterwalk_cast == -1) // waterwalk is not cast ~ waterwalk field is *(&hero + 0x116) (see 0x4E6040 Cast_waterwalk function)
 c->return_address = 0x430231; // try to cast waterwalk instead (code checks for Boots of Levitation first...)
 else
 c->return_address = 0x430540; // skip procedure
 return NO_EXEC_DEFAULT;
 }
 }
 }
 return EXEC_DEFAULT;
 }
 
 int __stdcall AI_TP_cursed_check(LoHook *h, HookContext *c)
 {
 _Hero_ *hero = (_Hero_*)c->esi;
 if (hero->GetSpecialTerrain() == 0x15) // 0x15 = cursed ground, 0x4E5130: __thiscall GetSpecialTerrain()
 {
 c->return_address = 0x56B6F4;
 return NO_EXEC_DEFAULT;
 }
 return EXEC_DEFAULT;
 }
 
 _PI->WriteLoHook(0x56B344, AI_TP_cursed_check);
 _PI->WriteLoHook(0x43020E, AI_waterwalk_fly);
 
 Решение бага (еще с SoD) исчезновения улучшенного стека при битве с  даунгрейдом нейтралов
 
 
Code:
 _int_ __stdcall Y_FixBagCreatureGredeOfNeutrals(HiHook* hook, _Army_* army, _int_ creature_id) {
 _int_ count = 0;
 _int_ i = 0;
 _int_ crGrade_id = GetCreatureGrade(creature_id);
 do {
 if (army->type[i] == creature_id || army->type[i] == crGrade_id) {
 count += army->count[i];
 }
 i++;
 } while ( i<7 );
 
 return count;
 }
 
 //////////////////////////////////////////////////////////////
 
 _PI->WriteHiHook(0x4AC5F5, CALL_, EXTENDED_, THISCALL_, Y_FixBagCreatureGredeOfNeutrals);
 
 
 RE: Решение багов ERA/WOG - igrik -  01.02.2019 17:27
 
 Исправление бага с исчезновением стартового героя при переигрывании
 
 
Code:
 _PI->WriteByte(0x5029C0, 0xEB);
 Исправление бага палатки, когда на её ходу невозможно убежать или сделать другие действия
 
 
Code:
 _PI->WriteByte(0x75C82C, 0xEB);
 Исправление недочета WoGа на расширение свитча хинтов колдовства для описаний командиров и монстров с номером больше 134
 
 
Code:
 _PI->WriteHexPatch(0x492A56, "81FF B7000000 90 7747");_PI->WriteDword(0x492A63, *(_int_*)0x44825F);
 Исправление одного из багов Астрального духа
 Т.е. убираем WoG сообщение, которое вызывает неизвестную ошибку в малочисленном ряде случаев
 
 
Code:
 _PI->WriteHexPatch(0x76D4B3, "EB17");
 Исправление бага блока командира, когда защита падала из-за флага "в защите"
 
 
Code:
 _PI->WriteCodePatch(0x76E7D7, "%n", 24); // 15 nop _PI->WriteCodePatch(0x76E80B, "%n", 13); // 13 nop
 _PI->WriteHexPatch(0x76E7D7, "8B4D 08 C601 01 C641 02 04");
 Исправление ошибки ERM (видимо опечатки Славы ZVS) в командре IF:N1.
 Теперь команда работает со всеми локальными, глобальными и отрицательными переменными z, а не только с z1
 
 
Code:
 _PI->WriteByte(0x749093, 0xB0);_PI->WriteByte(0x74909C, 0xB0);
 _PI->WriteByte(0x7490B0, 0xB0);
 _PI->WriteByte(0x7490B6, 0xB0);
 _PI->WriteByte(0x7490CD, 0xB0);
 Меняем месторасположение кнопки Сказочного Дракона
 
 
Code:
 // исправить координаты кнопки_PI->WriteDword(0x5F3D9F, 235); // подложка поз.Y
 _PI->WriteByte(0x5F3DA4, 21);    // подложка поз.X
 _PI->WriteDword(0x5F3DF5, 235); // кнопка   поз.Y
 _PI->WriteByte(0x5F3DFA, 21);    // кнопка   поз.X
 
 
 RE: Решение багов ERA/WOG - igrik -  01.02.2019 17:40
 
 Убираем показ (предварительного расчета в строке состояния битвы) увеличенного урона от кавалерийского бонуса, если существо летает.
 Потому что в оригинале бонус кавалерии не действует (при нанесении фактического урона) у летающих существ.
 
 
Code:
 // не считать кавалерийский бонус при полете_int_ __stdcall Y_AntiKavalierAndFly(LoHook* h, HookContext* c)
 {
 if ( *(_dword_*)(c->ebx +132) >> 1 & 1 ) { // проверить флаг атакующего на полет
 c->return_address = 0x4430A3; // обходим расчет кавалерийского бонуса (он всё равно не работает)
 return NO_EXEC_DEFAULT;
 }
 return EXEC_DEFAULT;
 }
 ///////////////////////////////////////////////
 
 _PI->WriteLoHook(0x44307A, Y_AntiKavalierAndFly); // не считать кавалерийский бонус при полете
 
 
 RE: Решение багов ERA/WOG - igrik -  03.09.2019 11:56
 
 Решение бага ERM: триггер MA:U#/-2 приводил к тому, что любое существо при установке такой команды улучшалось в копейщика. Подробнее тут
 Плагин: скачать
 
 
 
Code:
 int __stdcall Fix_WoG_GetCreatureGrade_Expo(LoHook* h, HookContext* c){
 if ( *(int*)(c->ebp -4) < -1) {
 *(int*)(c->ebp -4) = -1;
 }
 return EXEC_DEFAULT;
 }
 
 int __stdcall Fix_WoG_GetCreatureGrade_Town(LoHook* h, HookContext* c)
 {
 if (*(int*)0x27F93B0 < -1) { // FOH_ret < -1
 *(int*)0x27F93B0 = -1;
 }
 return EXEC_DEFAULT;
 }
 ///////////////////////////////////////////////
 _PI->WriteDword(0x724A9F, -2);
 _PI->WriteLoHook(0x724AC5, Fix_WoG_GetCreatureGrade_Expo);
 
 _PI->WriteDword(0x74ED27, -2);
 _PI->WriteLoHook(0x74ED5C, Fix_WoG_GetCreatureGrade_Town);
 
 
 RE: Решение багов ERA/WOG - igrik -  11.10.2020 19:37
 
 Решение нескольких крит.вылетов в игре в режиме битвы
 
 
Code:
 // фикс вылета: АИ битва (просчёт)// проверка на скорость монстра и когда он дойдет до защиты стрелка.
 // Убираем из проверки существ с нулевой скоростью и боевые машины
 _int_ __stdcall Y_AIMgr_Stack_MinRoundToReachHex(HiHook* hook, _dword_ this_, _BattleStack_* stack, _int_ a3)
 {
 if (stack->creature.flags == BCF_CANT_MOVE || stack->creature.speed < 1)
 return 99; // 99 раундов необходимо, чтобы добраться до стрелка
 
 return CALL_3(_int_, __thiscall, hook->GetDefaultFunc(), this_, stack, a3);
 }
 
 _PI->WriteHiHook(0x4B3C80, SPLICE_, EXTENDED_, THISCALL_, Y_AIMgr_Stack_MinRoundToReachHex);
 
 
Code:
 // фикс вылета: нет проверки на наличие стуктуры целевого стека при воскрешении// тут не хватает проверки на c->edi
 int __stdcall Y_FixCrash_CastSpell_38(LoHook* h, HookContext* c)
 {
 if ( c->edi )
 {
 c->eax = *(int*)(c->edi + 0x38);
 c->ecx = *(int*)(c->ebx + 0x132C0);
 c->return_address = 0x5A1C20;
 
 }  else c->return_address = 0x5A2368;
 
 return NO_EXEC_DEFAULT;
 }
 
 _PI->WriteLoHook(0x5A1C17, Y_FixCrash_CastSpell_38);
 
 
Code:
 // фикс вылета: при удалении препятствия в битве нет проверки на наличие стуктуры его дефа// (привет WoG и его стена огня у Огненных Лошадей)
 int __stdcall Y_FixCrash_RemoveObstackle(LoHook* h, HookContext* c)
 {
 // проверяем на пустую структуру боевого пропятствия
 // чтобы пропустить код обращения к ней и как следствие крит.краш.игры
 if ( !c->ecx || !c->edi )
 {
 c->return_address = 0x466826;
 return NO_EXEC_DEFAULT;
 }
 
 return EXEC_DEFAULT;
 }
 
 _PI->WriteLoHook(0x46681B, Y_FixCrash_RemoveObstackle);
 
 
 RE: Решение багов ERA/WOG - slater777 -  08.01.2023 06:37
 
 Фикс бага WOG'a
 
 
 
Code:
 _LHF_(HooksInit){
 // Фикс Димера - герой имеет продвинутую разведку на старте
 h3::H3HeroInfo* hero_info_table = P_HeroInfo->Get();
 hero_info_table[eHero::DEEMER].sskills[1].level = eSecSkillLevel::BASIC;
 }
 
 _PI->WriteLoHook(0x4EEAF2, HooksInit);
 
 
 RE: Решение багов ERA/WOG - daemon_n -  08.01.2023 08:22
 
 slater777, адрес хука?
 
 
 RE: Решение багов ERA/WOG - slater777 -  08.01.2023 09:57
 
 
  (08.01.2023 08:22)daemon_n Wrote:  slater777, адрес хука? Поправил пост.
 
 
 
 |