Решение багов 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 
 
  
 
Ошибка эта была не в алгоритме, а в приведении типов, поэтому её не видно в выложенном мной декомпилированном коде. 
 
Вот код, содержащий ошибку: 
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
  
Тут левый отступ первого символа строки сравнивается с 0, а потом, если он отрицательный, 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 EB0C 
2F3BEC 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 FC 
729835 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, адрес хука? 
 
Поправил пост.
 
 
 
 |