feanor 
 
 
		
		
		
			
			
			 
			
Posts: 624 
	
		
	 | 
	
		
			
			 
			
				Quote:Вообще польза от использования патчера в этом конкретном случае достаточно сомнительна. 
Чтоб не на ассемблере писать, тащемта
			  
			
			
			
		 |  
	 
 | 
	| 11.03.2015 16:00 | 
	
		
	 | 
	
		
		major 
 
 
		
		
		
			
			
			 
			
Posts: 147 
	
		
	 | 
	
		
			
			 
			
				Вроде бы немного разобрался, спасибо.
			 
			
			
			
				
(This post was last modified: 15.03.2015 19:12 by major.)
 
			 
		 |  
	 
 | 
	| 13.03.2015 21:30 | 
	
		
	 | 
	
		
		major 
 
 
		
		
		
			
			
			 
			
Posts: 147 
	
		
	 | 
	
		
			
			 
			
				Немного переделал регенерацию. 
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 | 
	
		
	 |