11.03.2015, 16:00
Quote:Вообще польза от использования патчера в этом конкретном случае достаточно сомнительна.
Чтоб не на ассемблере писать, тащемта
Quote:Вообще польза от использования патчера в этом конкретном случае достаточно сомнительна.
// dllmain.cpp: определяет точку входа для приложения DLL.
#include "stdafx.h"
#include "..\..\include\patcher_x86_commented.hpp"
#include "..\..\include\HotA\HoMM3.h"
#include "..\..\include\era.h"
Patcher * globalPatcher;
PatcherInstance *patcher;
int __stdcall RegenerationCheck (LoHook* h, HookContext* c)
{
if (((_BattleStack_*)c->esi)->count_current < ((_BattleStack_*)c->esi)->count_at_start)
{
c->return_address = 0x446BD3;
}
else
{
if (((_BattleStack_*)c->esi)->lost_hp > 0)
{
c->return_address = 0x446BD3;
}
else
{
c->return_address = 0x446DF1;
}
}
return NO_EXEC_DEFAULT;
}
int __stdcall RegenerationFull (LoHook* h, HookContext* c)
{
int regen = *(int*)0x2846BC8;
int number = ((_BattleStack_*)c->esi)->count_current;
int bnumber = ((_BattleStack_*)c->esi)->count_at_start;
int lowhp = ((_BattleStack_*)c->esi)->lost_hp;
int hp = ((_BattleStack_*)c->esi)->full_hp;
if (regen <= lowhp)
{
lowhp -= regen;
((_BattleStack_*)c->esi)->lost_hp = lowhp;
}
else
{
regen -= lowhp;
int count = 1;
while (regen > hp)
{
regen -= hp;
count += 1;
}
number += count;
if (number > bnumber)
{
number = bnumber;
lowhp = 0;
}
else
{
lowhp = hp - regen;
}
((_BattleStack_*)c->esi)->lost_hp = lowhp;
((_BattleStack_*)c->esi)->count_current = number;
}
c->return_address = 0x446C3F;
return NO_EXEC_DEFAULT;
}
int __stdcall Regeneration (LoHook* h, HookContext* c)
{
int unit = c->eax;
int regenhp = 0;
if (unit == 4 || unit == 46 || unit == 47 || unit == 61)
{
regenhp += 40;
}
if (unit == 5)
{
regenhp += 50;
}
if (unit == 60)
{
regenhp += 30;
}
if (unit == 80 || unit == 81 || unit == 144)
{
regenhp += 80;
}
if (unit == 110 || unit == 193)
{
regenhp += 100;
}
if (unit == 111 || unit == 168)
{
regenhp += 150;
}
if (unit == 157)
{
regenhp += 200;
}
// if (unit == 159)
// {
// regenhp += 40;
// }
if (regenhp > 0)
{
*(int*)0x2846BC8 = regenhp;
c->return_address = 0x75DF2A;
}
else
{
c->return_address = 0x75DE8E;
}
return NO_EXEC_DEFAULT;
}
void __stdcall PatchIt (PEvent e)
{
patcher->WriteLoHook(0x75DE66,(void*)Regeneration);
patcher->WriteLoHook(0x446BCD,(void*)RegenerationCheck);
patcher->WriteLoHook(0x446C2B,(void*)RegenerationFull);
}
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
globalPatcher = GetPatcher();
patcher = globalPatcher->CreateInstance("abilities");
ConnectEra();
RegisterHandler(PatchIt,"OnAfterCreateWindow");
}
return TRUE;
}Quote:1. Как добавить проверку на эликсир жизни, чтоб он добавлял еще 50 хп к регену.
Era::ExecErmCmd("HE:A2/131/?v1/?v1;");
if (Era::v[1]>0) ...void IsTroll(void)
{
__asm{
mov IT_Mon,esi
mov edx,50 // умолчательное восстановление здоровья
mov IT_Edx,edx
cmp eax,0x3C
je l_Ok
cmp eax,0x3D
je l_Ok
cmp eax,0x90
je l_Ok
cmp eax,157 // гидра
je l_Ok_check
// jmp l_Exit
pusha
}
__asm mov IDummy,eax
#include "templ.h"
IT_Ret=CanNPCRegenerate(IDummy,IT_Mon);
if(IT_Ret!=-1){
IT_Ret=CrExpBon::Regenerate(IT_Mon,*(int *)&IT_Mon[0x58]);
if(IT_Ret==0){ // no reg
IT_Ret=0;
}else{ // yes
IT_Edx=IT_Ret;
IT_Ret=-1;
}
}
STOP
__asm{
popa
mov eax,IT_Ret
// je _Ok_check
jmp l_Exit
}
l_Ok_check:
CalcRand100();
__asm{
cmp eax,40 // 40%
ja l_Exit
}
l_Ok:
__asm mov eax,-1
l_Exit:
__asm mov edx,IT_Edx
}(17.03.2015 12:56)Дьякон Wrote: [ -> ]63E9B8 - % для навыков некромантии/чародейства (массив из 4 dword)А как при помощи ERM отключить навык Некромантии (со всеми артефактами, ПКН'ами и пр. усилителями некромантии)?
476DA0 - воскрешение нечести после боя
4E3F40 - расчет % чародейства(некромантии) с учетом артефактов и специальностей
0x63EAE4 - амулет гробовщика 5%
0x63B8D0 - мантия и усилители 10%
0x63EB28 - сапоги 15%
0x63B8B4 - грааль 20%
0x63EB24 - плащ 30%