Current time: 25.11.2024, 18:46 Hello There, Guest! (LoginRegister)
Language: english | russian  

Post Reply 
Threaded Mode | Linear Mode
Исследование героев
» туториал(ы)
Author Message
feanor Offline

Posts: 624
Post: #571

Quote:Вообще польза от использования патчера в этом конкретном случае достаточно сомнительна.

Чтоб не на ассемблере писать, тащемта
11.03.2015 16:00
Find all posts by this user Quote this message in a reply
gamecreator Offline

Posts: 7107
Post: #572

Ну это уже личный выбор каждого.


When all gods have burnt to ashes in eternity of sorrow,
Demons gonna tear your soul because there is no tomorrow.
11.03.2015 17:37
Find all posts by this user Quote this message in a reply
major Offline

Posts: 146
Post: #573

Вроде бы немного разобрался, спасибо.
(This post was last modified: 15.03.2015 19:12 by major.)
13.03.2015 21:30
Find all posts by this user Quote this message in a reply
major Offline

Posts: 146
Post: #574

Немного переделал регенерацию.
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
Find all posts by this user Quote this message in a reply
feanor Offline

Posts: 624
Post: #575

Quote:1. Как добавить проверку на эликсир жизни, чтоб он добавлял еще 50 хп к регену.

o_BattleMgr->hero[((_BattleStack_*)c->esi)->side]->DoesWearArtifact(ID), как-то так
15.03.2015 19:30
Find all posts by this user Quote this message in a reply
gamecreator Offline

Posts: 7107
Post: #576

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
Find all posts by this user Quote this message in a reply
feanor Offline

Posts: 624
Post: #577

Как можно перебрать все объекты определенного типа/подтипа кодом?
ну, то бишь, как это делает Вог в UN:U?)

..эм
пробегать всю карту каждый раз? серьезно?
(This post was last modified: 17.03.2015 03:45 by feanor.)
17.03.2015 03:41
Find all posts by this user Quote this message in a reply
Дьякон Offline

Posts: 395
Post: #578

feanor, думаю серьезно.
------------------------------------------------------------------
63E9B8 - % для навыков некромантии/чародейства (массив из 4 dword)
476DA0 - воскрешение нечести после боя
4E3F40 - расчет % чародейства(некромантии) с учетом артефактов и специальностей


Страус труп (с) Бьерн
17.03.2015 12:56
Find all posts by this user Quote this message in a reply
gamecreator Offline

Posts: 7107
Post: #579

Конечно же, если нужны не сами объекты, а только их структуры (если есть), то тут уже можно найти их список.


When all gods have burnt to ashes in eternity of sorrow,
Demons gonna tear your soul because there is no tomorrow.
17.03.2015 13:36
Find all posts by this user Quote this message in a reply
Algor Away
Administrators

Posts: 3881
Post: #580

(17.03.2015 12:56)Дьякон Wrote:  63E9B8 - % для навыков некромантии/чародейства (массив из 4 dword)
476DA0 - воскрешение нечести после боя
4E3F40 - расчет % чародейства(некромантии) с учетом артефактов и специальностей
А как при помощи ERM отключить навык Некромантии (со всеми артефактами, ПКН'ами и пр. усилителями некромантии)?


BattleHeroes Rus/Eng | ERA scripts (+ReMagic) Rus/Eng
17.03.2015 16:47
Visit this user's website Find all posts by this user Quote this message in a reply
Дьякон Offline

Posts: 395
Post: #581

Через UN:C забиваешь для всех уровней некромантии 0, соответственно воскрешаться никто не будет.


Хотя не, нужно еще артефакты все отключать, т.к. там абсолютное приращение идет к %. Если нужно, то найду и выложу все адреса по некромантии.


Страус труп (с) Бьерн
(This post was last modified: 17.03.2015 17:13 by Дьякон.)
17.03.2015 17:06
Find all posts by this user Quote this message in a reply
Дьякон Offline

Posts: 395
Post: #582

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
Find all posts by this user Quote this message in a reply
Дьякон Offline

Posts: 395
Post: #583

Вот так будет (должно) работать и не нужно трогать константы:


И да константы универсальные и их правка не рекомендуется.


Страус труп (с) Бьерн
(This post was last modified: 17.03.2015 21:05 by Дьякон.)
17.03.2015 17:40
Find all posts by this user Quote this message in a reply
Algor Away
Administrators

Posts: 3881
Post: #584

Спасибо, проверю на днях.


BattleHeroes Rus/Eng | ERA scripts (+ReMagic) Rus/Eng
18.03.2015 01:15
Visit this user's website Find all posts by this user Quote this message in a reply
Дьякон Offline

Posts: 395
Post: #585

4A7530 - jmp определяющий вступят в бой или другие условия присоединиться. Отключение jmp - отключает дипломатию,т.е.


Страус труп (с) Бьерн
19.03.2015 15:16
Find all posts by this user Quote this message in a reply
« Next Oldest | Next Newest »
Post Reply 


Forum Jump:

Powered by MyBB Copyright © 2002-2024 MyBB Group