Current time: 26.06.2019, 03:35 Hello There, Guest! (LoginRegister)
Language: english | russian  

Post Reply 
Threaded Mode | Linear Mode
Решение багов ERA/WOG
» Примеры решения багов ERA/WOG на уровне кода.
Author Message
igrik Offline
Administrators

Posts: 1715
Post: #1

Данная тема предназначена только для выкладывания кода лечения багов (непосредственно касающихся Вога или Эры) на программном уровне, для того чтобы Berserker мог их включать в состав era.dll
Любые сообщения, не содержащие указание бага совместно с его решением на Ассамблере, Delphi или С++ будут безжалостно уничтожаться.
01.02.2019 15:40
Visit this user's website Find all posts by this user Quote this message in a reply
igrik Offline
Administrators

Posts: 1715
Post: #2

Решение бага Вога, когда в бою накладывается опыт через 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);


Скачать HoMM3 ERA 2.8.3 (Repack: Rus & HD)
01.02.2019 15:48
Visit this user's website Find all posts by this user Quote this message in a reply
igrik Offline
Administrators

Posts: 1715
Post: #3

Решение багов ИИ, когда тот может (© 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);


Скачать HoMM3 ERA 2.8.3 (Repack: Rus & HD)
01.02.2019 17:21
Visit this user's website Find all posts by this user Quote this message in a reply
igrik Offline
Administrators

Posts: 1715
Post: #4

Исправление бага с исчезновением стартового героя при переигрывании
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);

Исправление багов описания и хинта кнопки Сказочного Дракона и заодно меняем её месторасположение
Но тут нужно быть осторожным, потому что есть конфликты с аналогичной правкой хинтов и описаний данной кнопки, с плагином RoseKavalier "game bug fixes.dll"
Code:
// исправление хинта и описания кнопки колдовства
int dlgMonInfoHints[32];
_PI->WriteDword(0x5F5320 +3, (unsigned int)&dlgMonInfoHints);
_PI->WriteDword(0x5B9DC0 +1, (unsigned int)&dlgMonInfoHints +4);
_PI->WriteDword(0x5F4C99 +3, (unsigned int)&dlgMonInfoHints +4);
_PI->WriteDword(0x521A49 +3, (unsigned int)&dlgMonInfoHints +4);
_PI->WriteDword(0x5B9DCF +2, (unsigned int)&dlgMonInfoHints +124);

// исправить координаты кнопки
_PI->WriteDword(0x5F3D9F, 235); // подложка поз.Y
_PI->WriteByte(0x5F3DA4, 21);    // подложка поз.X
_PI->WriteDword(0x5F3DF5, 235); // кнопка   поз.Y
_PI->WriteByte(0x5F3DFA, 21);    // кнопка   поз.X


Скачать HoMM3 ERA 2.8.3 (Repack: Rus & HD)
01.02.2019 17:27
Visit this user's website Find all posts by this user Quote this message in a reply
igrik Offline
Administrators

Posts: 1715
Post: #5

Решение недочёта отображения увеличенного урона от кавалерийского бонуса если у существо летает.
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); // не считать кавалерийский бонус при полете


Скачать HoMM3 ERA 2.8.3 (Repack: Rus & HD)
01.02.2019 17:40
Visit this user's website Find all posts by this user Quote this message in a reply
« Next Oldest | Next Newest »
Post Reply 


Forum Jump:

Powered by MyBB Copyright © 2002-2019 MyBB Group