11.03.2015, 16:00
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
11.03.2015, 17:37
Ну это уже личный выбор каждого.
13.03.2015, 21:30
Вроде бы немного разобрался, спасибо.
15.03.2015, 19:16
Немного переделал регенерацию.
Подскажите по двум вопросам.
1. Как добавить проверку на эликсир жизни, чтоб он добавлял еще 50 хп к регену.
2. Регенерация от опыта существ работает как-то по-другому? Этот хук не срабатывает, реген проходит без воскрешения. Как это можно исправить?
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:30
Quote:1. Как добавить проверку на эликсир жизни, чтоб он добавлял еще 50 хп к регену.
o_BattleMgr->hero[((_BattleStack_*)c->esi)->side]->DoesWearArtifact(ID), как-то так
15.03.2015, 20:15
1. Что-то типа (с указанием героя, конечно)
2. Выдержка из исходников Вога:
Это та функция, что перезаписывается по 0x446BD6.
CrExpBon::Regenerate - это стандартная регенерация от опыта.
Code:
Era::ExecErmCmd("HE:A2/131/?v1/?v1;");
if (Era::v[1]>0) ...
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
}
CrExpBon::Regenerate - это стандартная регенерация от опыта.
17.03.2015, 03:41
Как можно перебрать все объекты определенного типа/подтипа кодом?
ну, то бишь, как это делает Вог в UN:U?)
..эм
пробегать всю карту каждый раз? серьезно?
ну, то бишь, как это делает Вог в UN:U?)
..эм
пробегать всю карту каждый раз? серьезно?
17.03.2015, 12:56
feanor, думаю серьезно.
------------------------------------------------------------------
63E9B8 - % для навыков некромантии/чародейства (массив из 4 dword)
476DA0 - воскрешение нечести после боя
4E3F40 - расчет % чародейства(некромантии) с учетом артефактов и специальностей
------------------------------------------------------------------
63E9B8 - % для навыков некромантии/чародейства (массив из 4 dword)
476DA0 - воскрешение нечести после боя
4E3F40 - расчет % чародейства(некромантии) с учетом артефактов и специальностей
17.03.2015, 13:36
Конечно же, если нужны не сами объекты, а только их структуры (если есть), то тут уже можно найти их список.
17.03.2015, 16:47
(17.03.2015 12:56)Дьякон Wrote: [ -> ]63E9B8 - % для навыков некромантии/чародейства (массив из 4 dword)А как при помощи ERM отключить навык Некромантии (со всеми артефактами, ПКН'ами и пр. усилителями некромантии)?
476DA0 - воскрешение нечести после боя
4E3F40 - расчет % чародейства(некромантии) с учетом артефактов и специальностей
17.03.2015, 17:06
Через UN:C забиваешь для всех уровней некромантии 0, соответственно воскрешаться никто не будет.
Хотя не, нужно еще артефакты все отключать, т.к. там абсолютное приращение идет к %. Если нужно, то найду и выложу все адреса по некромантии.
Хотя не, нужно еще артефакты все отключать, т.к. там абсолютное приращение идет к %. Если нужно, то найду и выложу все адреса по некромантии.
17.03.2015, 17:20
Code:
0x63EAE4 - амулет гробовщика 5%
0x63B8D0 - мантия и усилители 10%
0x63EB28 - сапоги 15%
0x63B8B4 - грааль 20%
0x63EB24 - плащ 30%
Хотя можно сделать еще проще. Задать максимальный % воскресших 0%, который сейчас 100%. Но возможно с ним могут быть проблемы, т.к. данная константа может использоваться и в других расчетах, например как 0x63B8D0 одновременно отвечает и за мантию и за усилители.
17.03.2015, 17:40
Вот так будет (должно) работать и не нужно трогать константы:
И да константы универсальные и их правка не рекомендуется.
И да константы универсальные и их правка не рекомендуется.
18.03.2015, 01:15
Спасибо, проверю на днях.
19.03.2015, 15:16
4A7530 - jmp определяющий вступят в бой или другие условия присоединиться. Отключение jmp - отключает дипломатию,т.е.