| 
 
				Смысл в том, что главная функция dll aka DLLMain вызывается при присоединении DLL к процессу, выгрузке из процесса, создании и удалении каждого потока. Событий много, а инициализацию нужно выполнить в самый первый раз. 
Заменённая главная DLLMain:
 
Code:
 _OnAfterWoG           db 'OnAfterWoG', 0_OnCustomDialogEvent  db 'OnCustomDialogEvent', 0
 _OnBeforeBattleAction db 'OnBeforeBattleAction', 0
 _OnAfterBattleAction  db 'OnAfterBattleAction', 0
 
 DLL_PROCESS_ATTACH = 1
 
 match =FALSE, COPYMODE
 {
 proc TYPHON, hDll, Reason, Reserved
 ; только при подключении dll к процессу, не к потокам
 .if dword [Reason] = DLL_PROCESS_ATTACH
 ; регистрируем обработчики событий
 stdcall [RegisterHandler], OnAfterWoG,           _OnAfterWoG
 stdcall [RegisterHandler], OnCustomDialogEvent,  _OnCustomDialogEvent
 stdcall [RegisterHandler], OnBeforeBattleAction, _OnBeforeBattleAction
 stdcall [RegisterHandler], OnAfterBattleAction,  _OnAfterBattleAction
 
 mov dword [761381h], 39859587; Заглушить вог-функцию ResetMonTable,
 mov dword [761385h], 3271623302; мешающую редактору существ
 mov dword [71180Fh+1], LoadCreatures
 .endif
 
 ; возвращаем успех инициализации dll
 xor eax, eax
 inc eax
 ret
 endp
 }
 
Заменённая процедура установки хуков и патчей:
 
Code:
 ; ГЛАВНАЯ ПРОЦЕДУРАproc OnAfterWoG uses esi edi ebx, Event ; после инициализации WoG
 ; ставим хуки
 mov esi, Table_Hooks
 ...
 ; Возврат:
 ret
 endp
 
Хук на ProcessErm рушит вообще всё ядро интерпретатора (ускорение, поддержку циклов, !!re, работу с контекстом). Потому его заменил на нормальные три обработчика событий:
 
Code:
 proc OnCustomDialogEvent uses esi edi ebx, Event.if dword [27F9964h] = 1986; диалог №1986
 mov eax, dword [27F9968h]
 
 .if signed eax > 4 & signed eax < 9 & dword [27F996Ch] <> 13
 sub eax, 5
 mov ecx, [Адрес_параметров_альтерветки_для_диалога_постройки_альтерветок]
 mov eax, [eax * 4 + ecx]
 xor ecx, ecx
 xor edx, edx
 inc edx
 cmp dword [27F996Ch], 12
 jnz .правый_клик
 xchg ecx, edx
 .правый_клик:
 stdcall OpenCreatureWindow, eax, 119, 20, ecx, edx
 .elseif (eax = 11 | eax = 13) & dword [27F996Ch] = 13
 mov dword [887658h], 1; CloseDialog
 .endif
 .endif
 
 ret
 endp
 
 proc OnBeforeBattleAction uses esi edi ebx, Event
 mov ebx, dword [699420h]; COMBAT_MANAGER; ebx теперь хранит CombatManager
 mov eax, [ebx + 3Ch]; Тип_действия
 mov [Тип_действия_в_бою], eax
 call Получить_адрес_структуры_стека_совершающего_действие
 mov [Адрес_структуры_стека_совершающего_действие], eax
 call Получить_адрес_структуры_стека_на_которого_направлено_действие
 mov [Адрес_структуры_стека_на_которого_направлено_действие], eax
 ret
 endp
 
 proc OnAfterBattleAction uses esi edi ebx, Event
 mov ebx, dword [699420h]; COMBAT_MANAGER; ebx теперь хранит CombatManager
 mov edi, [Адрес_структуры_стека_совершающего_действие]
 mov esi, [Адрес_структуры_стека_на_которого_направлено_действие]
 
 .if [Тип_действия_в_бою] = 7 & signed esi > -1 & signed [esi + Структура_стека.Текущее_количество] > 0 & [edi + Структура_стека.Тип_существа] <> 149; CR_Стрелковая_Башня
 mov eax, [esi + Структура_стека.Тип_существа]
 cmp byte [eax + RangeRetaliation_Table], 0
 je .нет_способности
 .есть_способность:
 push 0
 mov ecx, esi
 mov eax, 442610h; проверка возможности стрельбы
 call eax
 test al, al
 je .нет_способности
 push edi
 mov ecx, esi
 mov eax, 43F620h; Стрельба_отряда_по_отряду
 call eax
 
 ; фикс бага стрельбы уже в мёртвом состоянии, если стеку выпала Мораль
 .if signed [edi + Структура_стека.Текущее_количество] < 1; стек убит
 bt [edi + Структура_стека.Флаги], 24; Флаг_Отряду_выпала_Мораль; проверка на выпавшую мораль
 jnb .нет_Морали
 mov dword [ebx + 3Ch], 12; Отмена_действия_отряда
 .нет_Морали:
 .endif
 .нет_способности:
 .endif
 
 ret
 endp
 Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
 Поддержать проект
 
 |