feanor
Posts: 624
|
Quote:Вообще польза от использования патчера в этом конкретном случае достаточно сомнительна.
Чтоб не на ассемблере писать, тащемта
|
|
11.03.2015 16:00 |
|
major
Posts: 146
|
Вроде бы немного разобрался, спасибо.
(This post was last modified: 15.03.2015 19:12 by major.)
|
|
13.03.2015 21:30 |
|
major
Posts: 146
|
Немного переделал регенерацию.
Code:
// 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;
}
Подскажите по двум вопросам.
1. Как добавить проверку на эликсир жизни, чтоб он добавлял еще 50 хп к регену.
2. Регенерация от опыта существ работает как-то по-другому? Этот хук не срабатывает, реген проходит без воскрешения. Как это можно исправить?
|
|
15.03.2015 19:16 |
|
feanor
Posts: 624
|
Quote:1. Как добавить проверку на эликсир жизни, чтоб он добавлял еще 50 хп к регену.
o_BattleMgr->hero[((_BattleStack_*)c->esi)->side]->DoesWearArtifact(ID), как-то так
|
|
15.03.2015 19:30 |
|
gamecreator
Posts: 7107
|
1. Что-то типа (с указанием героя, конечно)
Code:
Era::ExecErmCmd("HE:A2/131/?v1/?v1;");
if (Era::v[1]>0) ...
2. Выдержка из исходников Вога:
Code:
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
}
Это та функция, что перезаписывается по 0x446BD6.
CrExpBon::Regenerate - это стандартная регенерация от опыта.
When all gods have burnt to ashes in eternity of sorrow,
Demons gonna tear your soul because there is no tomorrow.
|
|
15.03.2015 20:15 |
|
feanor
Posts: 624
|
Как можно перебрать все объекты определенного типа/подтипа кодом?
ну, то бишь, как это делает Вог в UN:U?)
..эм
пробегать всю карту каждый раз? серьезно?
(This post was last modified: 17.03.2015 03:45 by feanor.)
|
|
17.03.2015 03:41 |
|
Дьякон
Posts: 395
|
feanor, думаю серьезно.
------------------------------------------------------------------
63E9B8 - % для навыков некромантии/чародейства (массив из 4 dword)
476DA0 - воскрешение нечести после боя
4E3F40 - расчет % чародейства(некромантии) с учетом артефактов и специальностей
Страус труп (с) Бьерн
|
|
17.03.2015 12:56 |
|
gamecreator
Posts: 7107
|
|
17.03.2015 13:36 |
|
Дьякон
Posts: 395
|
Через UN:C забиваешь для всех уровней некромантии 0, соответственно воскрешаться никто не будет.
Хотя не, нужно еще артефакты все отключать, т.к. там абсолютное приращение идет к %. Если нужно, то найду и выложу все адреса по некромантии.
Страус труп (с) Бьерн
(This post was last modified: 17.03.2015 17:13 by Дьякон.)
|
|
17.03.2015 17:06 |
|
Дьякон
Posts: 395
|
Code:
0x63EAE4 - амулет гробовщика 5%
0x63B8D0 - мантия и усилители 10%
0x63EB28 - сапоги 15%
0x63B8B4 - грааль 20%
0x63EB24 - плащ 30%
Все обнулить и по идее будет счастье
Хотя можно сделать еще проще. Задать максимальный % воскресших 0%, который сейчас 100%. Но возможно с ним могут быть проблемы, т.к. данная константа может использоваться и в других расчетах, например как 0x63B8D0 одновременно отвечает и за мантию и за усилители.
Страус труп (с) Бьерн
(This post was last modified: 17.03.2015 17:23 by Дьякон.)
|
|
17.03.2015 17:20 |
|
Дьякон
Posts: 395
|
Вот так будет (должно) работать и не нужно трогать константы:
И да константы универсальные и их правка не рекомендуется.
Страус труп (с) Бьерн
(This post was last modified: 17.03.2015 21:05 by Дьякон.)
|
|
17.03.2015 17:40 |
|
Дьякон
Posts: 395
|
4A7530 - jmp определяющий вступят в бой или другие условия присоединиться. Отключение jmp - отключает дипломатию,т.е.
Страус труп (с) Бьерн
|
|
19.03.2015 15:16 |
|