Объявления

Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

Как создать плагин для HD мода

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1315
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Как создать плагин для HD мода

Сообщение Ben80 » 26 окт 2020, 13:05

Rolex писал(а):

Интересно, как думаете почему же тогда разрабочтики не сделали изначально для Удачи удваивание суммы бросков вместо прибавки?


Наверно, чтобы уменьшить влияние случайности на ход/исход битв. В HotA же постоянно этим занимаются - Сопротивление, например, им не нравилось.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5547
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2161 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 26 окт 2020, 13:09

Цитата:
В первой части по Морали тоже есть баг, где отрицательная Мораль -1 приравнивается к 0 и тд?

С Моралью во всех трёх частях всё в порядке.

Цитата:
Вот думаю, раз так более правильно, наверное, неплохо было бы тогда запилить еще и плагин для положительной Удачи с удваиванием суммы бросков кости (взамен оригинальному с прибавкой).

Обе версии - в теме с готовыми плагинами.
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 890
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 49 раз.

Re: Как создать плагин для HD мода

Сообщение Rolex » 26 окт 2020, 13:16

AlexSpl писал(а):

Обе версии - в теме с готовыми плагинами.

Может я что-то путаю, но в теме с готовыми плагинами только отрицательная удача. Я же говорил за положительную, которая работает в оригинале, только с прибавкой.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5547
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2161 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 26 окт 2020, 13:48

Удача с уполовиниванием/удваиванием базового урона:

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include "..\..\HotA\homm3.h"

Patcher* _P;
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

int __stdcall BadLuckAnim(LoHook* h, HookContext* c)
{
    int Luck = *(int*)(c->esi + 0x4EC);
       
    if ( Luck < 0 )
    {
        if ( Luck < -3 ) Luck = -3;

        if ( Randint(1, 12) <= -Luck )
        {
            _BattleStack_* stack = (_BattleStack_*)c->esi;
            // Setting Luck flag to Bad Luck state (-1)
            stack->field_70 = -1;
            // Is battle visible?
            if ( !o_BattleMgr->ShouldNotRenderBattle() )
            {
                // Play sound
                CALL_3(void, __fastcall, 0x59A890, (const char*)"badluck.82m", -1, 3);
                // Show message
                sprintf(o_TextBuffer, o_GENRLTXT_TXT->GetString(45),
                    GetCreatureName(stack->creature_id, stack->count_current));
                CALL_4(void, __thiscall, 0x4729D0, o_BattleMgr->dlg, o_TextBuffer, 1, 0);
                // Play animation
                CALL_5(void, __thiscall, 0x4963C0, o_BattleMgr, 48, stack, 100, 0);
            }
        }
    }

    return EXEC_DEFAULT;
}

int __stdcall ModifyBasicDamage(HiHook* hook, _BattleStack_* stack, int a1)
{
    int BasicDamage = CALL_2(int, __thiscall, hook->GetDefaultFunc(), stack, a1);
   
    int LuckFlag = stack->field_70;
   
    switch ( LuckFlag ) {
        case -1: BasicDamage /= 2; break;
        case 1:  BasicDamage *= 2; break;
    }

    if ( BasicDamage < 1 ) BasicDamage = 1;

    return BasicDamage;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = 1;
            _P = GetPatcher();
            _PI = _P->CreateInstance((char*)"HD.Plugin.LuckAsItIs");
            _PI->WriteCodePatch(0x43F635, "%n", 13);
            _PI->WriteCodePatch(0x44151D, "%n", 13);
            _PI->WriteLoHook(0x43F635, BadLuckAnim);
            _PI->WriteLoHook(0x44151D, BadLuckAnim);
            _PI->WriteHexPatch(0x4430A3, "EB 10");
            _PI->WriteHiHook(0x442E80, SPLICE_, EXTENDED_, THISCALL_, ModifyBasicDamage);
        }
    }

    return TRUE;
}
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 890
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 49 раз.

Re: Как создать плагин для HD мода

Сообщение Rolex » 26 окт 2020, 20:22

Код: Выделить всё
 
_PI->WriteHexPatch(0x43F642, "90 90 90 90 90 90");
_PI->WriteHexPatch(0x441524, "90 90 90 90 90 90");
_PI->WriteLoHook(0x43F64E, BadLuckAnim);
_PI->WriteLoHook(0x441530, BadLuckAnim);



Код: Выделить всё
 
_PI->WriteCodePatch(0x43F635, "%n", 13);
_PI->WriteCodePatch(0x44151D, "%n", 13);
_PI->WriteLoHook(0x43F635, BadLuckAnim);
_PI->WriteLoHook(0x44151D, BadLuckAnim);
_PI->WriteHexPatch(0x4430A3, "EB 10");


Сравнивал новый код с вашим старым. Заметил, что HexPatch фикса для нейтралов сменился на CodePatch. И адреса немного изменились. Кстати, а почему другие адреса?
Вижу вы ставите лоухук в место установки патча уже по новым адресам.
А что делает вот этот новый Хекс патч: _PI->WriteHexPatch(0x4430A3, "EB 10") ?

Кстати, а изменить описание специализации героя из плагина сложно будет? Надо бы адрес на таблицу с описаниями специализаций отыскать. Это вроде бы файл HEROSPEC.TXT.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5547
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2161 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 27 окт 2020, 10:54

Цитата:
Сравнивал новый код с вашим старым. Заметил, что HexPatch фикса для нейтралов сменился на CodePatch. И адреса немного изменились. Кстати, а почему другие адреса?
Вижу вы ставите лоухук в место установки патча уже по новым адресам.
А что делает вот этот новый Хекс патч: _PI->WriteHexPatch(0x4430A3, "EB 10") ?


Все три команды делают почти одно и то же: убирают ненужный код. _PI->WriteCodePatch(0x43F635, "%n", 13); эквивалентен _PI->WriteHexPatch(0x43F635, "90 90 90 90 90 90 90 90 90 90 90 90 90"); _PI->WriteHexPatch(0x4430A3, "EB 10"); эквивалентен _PI->WriteHexPatch(0x4430A3, "90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90"; или WriteCodePatch(0x4430A3, "%n", 18); "EB 10" удобнее тем, что при просмотре дизассеблированного кода в режиме блок-схем у нас будет красивый jmp, а не 18 nop'ов.

Изменение названия и описания специализации:

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include "..\..\HotA\homm3.h"

Patcher* _P;
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

struct SpecDesc
{
   char* shortName;
   char* fullName;
   char* desc;
} mySpecDesc;

char __stdcall ChangeSpecDesc(HiHook* hook)
{
    char res = CALL_0(char, __cdecl, hook->GetDefaultFunc());

    int heroID = 15; // for Caitlin
    *(SpecDesc*)(*(int*)0x679C80 + heroID * 40 + 0x1C) = mySpecDesc;

    return res;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = 1;
            _P = GetPatcher();
            _PI = _P->CreateInstance((char*)"HD.Plugin.SpecDesc");
           
            mySpecDesc.shortName = "Specialty name (short) here.";
            mySpecDesc.fullName = "Specialty name (full) here.";
            mySpecDesc.desc = "Your description here.";
            _PI->WriteHiHook(0x4D7410, SPLICE_, EXTENDED_, CDECL_, ChangeSpecDesc);
        }
    }

    return TRUE;
}
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 890
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 49 раз.

Re: Как создать плагин для HD мода

Сообщение Rolex » 27 окт 2020, 14:42

1) Есть код (модифицированный и дополненный), который вы писали для Ben80 более 3 лет назад. Суть была вот в чем:

Там нужно было сделать Слабость, Забывчивость, Радость, Удачу, Печаль, Неудачу масс. спеллами на любом уровне магии, даже на основном.

Я убрал Слабость и Забывчивость и поставил Ускорение и Медлительность. Айдишки взял с гайда, ссылку на который вы бросали. Так вот задача сейчас состоит в том, чтобы написать лоухук(и) (или, если возможно, через WriteDword/WriteHexPatch), который эффект Радости и Удачи подымет до +3, а Печали и Неудачи опустит до -3 на Экспертном уровне.
Ускорение нужно увеличить с 5 до 7 на Эксперте. А вот Медлительность хотелось бы подправить на всех уровнях вместо 25%/25%/50%/50% ---> 20%/20%/40%/60%. Нужна ваша помощь.

С описанием заклов разобрался. Помогло опять же ваше сообщение 3-летней давности.

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS

#include "stdafx.h"
// dllmain.cpp: определяет точку входа для приложения DLL.
#define _CRT_SECURE_NO_WARNINGS

#include "stdafx.h"
#include "HotA\patcher_x86.hpp"
#include "HotA\homm3.h"

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;

struct SpellDesc
{
   char* DefaultDesc;
   char* BasicDesc;
   char* AdvancedDesc;
   char* ExpertDesc;
};

SpellDesc MirthDesc =
{
   "{Радость}\n\n+1 к боевому духу всех дружественных отрядов.",
   "{Базовая Радость}\n\n+1 к боевому духу всех дружественных отрядов.",
   "{Продвинутая Радость}\n\n+2 к боевому духу всех дружественных отрядов.",
   "{Экспертная Радость}\n\n+3 к боевому духу всех дружественных отрядов."
};

SpellDesc SorrowDesc =
{
   "{Печаль}\n\n-1 к боевому духу всех вражеских отрядов.",
   "{Базовая Печаль}\n\n-1 к боевому духу всех вражеских отрядов.",
   "{Продвинутая Печаль}\n\n-2 к боевому духу всех вражеских отрядов.",
   "{Экспертная Печаль}\n\n-3 к боевому духу всех вражеских отрядов."
};

SpellDesc FortuneDesc =
{
   "{Удача}\n\n+1 к удаче всех дружественных отрядов.",
   "{Базовая Удача}\n\n+1 к удаче всех дружественных отрядов.",
   "{Продвинутая Удача}\n\n+2 к удаче всех дружественных отрядов.",
   "{Экспертная Удача}\n\n+3 к удаче всех дружественных отрядов."
};

SpellDesc MisfortuneDesc =
{
   "{Неудача}\n\n-1 к удаче всех вражеских отрядов.",
   "{Базовая Неудача}\n\n-1 к удаче всех вражеских отрядов.",
   "{Продвинутая Неудача}\n\n-2 к удаче всех вражеских отрядов.",
   "{Экспертная Неудача}\n\n-3 к удаче всех вражеских отрядов."
};

SpellDesc HasteDesc =
{
   "{Ускорение}\n\n+3 к скорости всех дружественных отрядов.",
   "{Базовое Ускорение}\n\n+3 к скорости всех дружественных отрядов.",
   "{Продвинутое Ускорение}\n\n+5 к скорости всех дружественных отрядов.",
   "{Экспертное Ускорение}\n\n+7 к скорости всех дружественных отрядов."
};

SpellDesc SlowDesc =
{
   "{Медлительность}\n\n-20% к скорости всех вражеских отрядов.",
   "{Базовая Медлительность}\n\n-20% к скорости всех вражеских отрядов.",
   "{Продвинутая Медлительность}\n\n-40% к скорости всех вражеских отрядов.",
   "{Экспертная Медлительность}\n\n-60% к скорости всех вражеских отрядов."
};

int __stdcall changeSpellDesc(LoHook* h, HookContext* c)
{
   *(SpellDesc*)(o_Spell + SPL_MIRTH)->description = MirthDesc;
   *(SpellDesc*)(o_Spell + SPL_SORROW)->description = SorrowDesc;
   *(SpellDesc*)(o_Spell + SPL_FORTUNE)->description = FortuneDesc;
   *(SpellDesc*)(o_Spell + SPL_MISFORTUNE)->description = MisfortuneDesc;
   *(SpellDesc*)(o_Spell + SPL_HASTE)->description = HasteDesc;
   *(SpellDesc*)(o_Spell + SPL_SLOW)->description = SlowDesc;

   return EXEC_DEFAULT;
}

int __stdcall massSpell(LoHook* h, HookContext* c)
{
   int spells[] = { 49, 50, 51, 52, 53, 54 };
   int spellID = c->ebx;

   for (int i = 0; i < sizeof(spells) / sizeof(int); ++i)
   {
      if (spellID == spells[i])
      {
         c->eax = 0;
         break;
      }
   }

   return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
   if (DLL_PROCESS_ATTACH == ul_reason_for_call)
   {
      if (!plugin_On)
      {
         plugin_On = 1;
         _P = GetPatcher();
         _PI = _P->CreateInstance("HD.Plugin.massSpell");

         _PI->WriteLoHook(0x59F136, massSpell);
         _PI->WriteLoHook(0x59E437, changeSpellDesc);
      }
   }

   return TRUE;
}


2) И еще хочу прокачать бесполезный вторичный навык - "Первая помощь". _PI->WriteDword закоментил, оно не работает. С Имуществом и Разветкой подобное работает, но там фиксированные значения, а здесь диапазон. Хотелось бы убрать этот рандом, увеличить и зафиксировать верхнее значение.
То есть, чтобы Палатка Первой Помощи восст. без навыка Первая помощь фиксированные 50 ед. (вместо случайных от 1 до 25 ед), а с навыком Первая Помощь фиксированные 100/200/300 соответственно (в оригинале случайное число от 1 до 50/75/100).
Контроля Палатки нет. Игрок не управляет палаткой, все идет автоматически как и без навыка Первая помощь, только Палатка лечит не один случайно выбранный отряд, а сразу все отряды героя. Плюс увеличить здоровье Палатки до 300.

И еще так подумал, надо бы сделать, чтобы Палатка восст. еще и свое здоровье (в кол-ве соотв развитию навыка), а также здоровье всех орудий (Баллисты, Тележки, Катапульты). В оригинале можно восстановить только здоровье существ.

В гайде нашел кое-что:
Of course, the First Aid skill is going to be pretty bad no matter how high we set it unless we remove
the random dice roll and have it always heal for the maximum amount. To do this, set 07852C~D to EB 0A.

0x07852C + 0x400000 = 0x47852C

Но вот это мне не совсем понятно "~D". Что в данном случае значит тильда D? В математике это, вроде как, подобие. В плюсах "Побитовое НЕ". Через Хекс Патч ничего из закоментированного не работает. Либо краш, либо без изменений.

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include "HotA\homm3.h"

Patcher* _P; // required for every plugin
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

struct SecSkillDesc
{
   char* Name;
   char* BasicDesc;
   char* AdvancedDesc;
   char* ExpertDesc;
};

SecSkillDesc FirstAidDesc =
{
   "{Первая помощь}",
   "{Базовая Первая помощь}\n\nВосстанавливает 100 единиц здоровья у всех отрядов в армии героя.",
   "{Продвинутая Первая помощь}\n\nВосстанавливает 200 единиц здоровья у всех отрядов в армии героя.",
   "{Экспертная Первая помощь}\n\nВосстанавливает 300 единиц здоровья у всех отрядов в армии героя."
};

int __stdcall changeFirstAidDesc(LoHook* h, HookContext* c)
{
   *(SecSkillDesc*)(*(int*)0x67DCF0 + 27 * 16) = FirstAidDesc;
   return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
   if (DLL_PROCESS_ATTACH == ul_reason_for_call)
   {
      if (!plugin_On)
      {
         plugin_On = 1;
         _P = GetPatcher();
         _PI = _P->CreateInstance("HD.Plugin.FirstAid");

                //   _PI->WriteHexPatch(0x47852C, "EB 0A");
                //      _PI->WriteHexPatch(0x47852C + 0xFFF2, "EB 0A");
                //      _PI->WriteHexPatch(0x47852C + 13, "EB 0A");
                //      _PI->WriteHexPatch(0x47852C - 14, "EB 0A");

      //   _PI->WriteDword(0x63EA98, 50);
      //   _PI->WriteDword(0x63EA98 + 4, 100);
      //   _PI->WriteDword(0x63EA98 + 8, 200);
      //   _PI->WriteDword(0x63EA98 + 12, 300);

         _PI->WriteLoHook(0x4E6D77, changeFirstAidDesc);
      }
   }
   return TRUE;
}


3) Есть еще такой малополезный навык, как Артиллерия. В нем бы всего один параметр изменить, а все отсальное оставить как есть. Базовый урон Баллисты составляет 8-12 ед, его бы поднять в 2 раза, то есть сделать 16-24 ед. Но сделать это нужно не правкой и перепаковкой TXT, а именно посредством подключаемого плагина к моду.
Последний раз редактировалось Rolex 27 окт 2020, 16:10, всего редактировалось 1 раз.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5547
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2161 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 27 окт 2020, 16:01

Цитата:
1) Есть код (модифицированный и дополненный), который вы писали для Ben80 более 3 лет назад. Суть была вот в чем:

Там нужно было сделать Слабость, Забывчивость, Радость, Удачу, Печаль, Неудачу масс. спеллами на любом уровне магии, даже на основном.

Этот код, как оказалось, работает только для игроков-людей, но не для AI. См. следующий пост с правильной реализацией: https://handbookhmm.ru/forum/viewtopic.php?f=56&t=518&start=930#p18872

Цитата:
Но вот это мне не совсем понятно "~D". Что в данном случае значит тильда D?

Автор так обозначил диапазон адресов: 07852C~D = 07852C - 07852D. Вот это:

Код: Выделить всё
//   _PI->WriteHexPatch(0x47852C, "EB 0A");

должно работать. Убирает рандом и ставит максимальный хил.
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 890
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 49 раз.

Re: Как создать плагин для HD мода

Сообщение Rolex » 27 окт 2020, 17:40

AlexSpl писал(а):

Этот код, как оказалось, работает только для игроков-людей, но не для AI.

Переписал с HiHook:
Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS

#include "stdafx.h"
#include "HotA\patcher_x86.hpp"
#include "HotA\homm3.h"

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;

struct SpellDesc
{
   char* DefaultDesc;
   char* BasicDesc;
   char* AdvancedDesc;
   char* ExpertDesc;
};

SpellDesc MirthDesc =
{
   "{Радость}\n\n+1 к боевому духу всех дружественных отрядов.",
   "{Базовая Радость}\n\n+1 к боевому духу всех дружественных отрядов.",
   "{Продвинутая Радость}\n\n+2 к боевому духу всех дружественных отрядов.",
   "{Экспертная Радость}\n\n+3 к боевому духу всех дружественных отрядов."
};

SpellDesc SorrowDesc =
{
   "{Печаль}\n\n-1 к боевому духу всех вражеских отрядов.",
   "{Базовая Печаль}\n\n-1 к боевому духу всех вражеских отрядов.",
   "{Продвинутая Печаль}\n\n-2 к боевому духу всех вражеских отрядов.",
   "{Экспертная Печаль}\n\n-3 к боевому духу всех вражеских отрядов."
};

SpellDesc FortuneDesc =
{
   "{Удача}\n\n+1 к удаче всех дружественных отрядов.",
   "{Базовая Удача}\n\n+1 к удаче всех дружественных отрядов.",
   "{Продвинутая Удача}\n\n+2 к удаче всех дружественных отрядов.",
   "{Экспертная Удача}\n\n+3 к удаче всех дружественных отрядов."
};

SpellDesc MisfortuneDesc =
{
   "{Неудача}\n\n-1 к удаче всех вражеских отрядов.",
   "{Базовая Неудача}\n\n-1 к удаче всех вражеских отрядов.",
   "{Продвинутая Неудача}\n\n-2 к удаче всех вражеских отрядов.",
   "{Экспертная Неудача}\n\n-3 к удаче всех вражеских отрядов."
};

SpellDesc HasteDesc =
{
   "{Ускорение}\n\n+3 к скорости всех дружественных отрядов.",
   "{Базовое Ускорение}\n\n+3 к скорости всех дружественных отрядов.",
   "{Продвинутое Ускорение}\n\n+5 к скорости всех дружественных отрядов.",
   "{Экспертное Ускорение}\n\n+7 к скорости всех дружественных отрядов."
};

SpellDesc SlowDesc =
{
   "{Медлительность}\n\n-20% к скорости всех вражеских отрядов.",
   "{Базовая Медлительность}\n\n-20% к скорости всех вражеских отрядов.",
   "{Продвинутая Медлительность}\n\n-40% к скорости всех вражеских отрядов.",
   "{Экспертная Медлительность}\n\n-60% к скорости всех вражеских отрядов."
};

int __stdcall changeSpellDesc(LoHook* h, HookContext* c)
{
   *(SpellDesc*)(o_Spell + SPL_MIRTH)->description = MirthDesc;
   *(SpellDesc*)(o_Spell + SPL_SORROW)->description = SorrowDesc;
   *(SpellDesc*)(o_Spell + SPL_FORTUNE)->description = FortuneDesc;
   *(SpellDesc*)(o_Spell + SPL_MISFORTUNE)->description = MisfortuneDesc;
   *(SpellDesc*)(o_Spell + SPL_HASTE)->description = HasteDesc;
   *(SpellDesc*)(o_Spell + SPL_SLOW)->description = SlowDesc;

   return EXEC_DEFAULT;
}

char __stdcall IsSpellSingleTarget(HiHook *h, int spell, int ssLevel)
{
   switch (spell)
   {
   case 49: case 50: case 51: case 52: case 53: case 54:
      return FALSE;
      break;
   default:
      return CALL_2(char, __fastcall, h->GetDefaultFunc(), spell, ssLevel);
   }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
   if (DLL_PROCESS_ATTACH == ul_reason_for_call)
   {
      if (!plugin_On)
      {
         plugin_On = 1;
         _P = GetPatcher();
         _PI = _P->CreateInstance("HD.Plugin.massSpell");

         _PI->WriteHiHook(0x59E360, SPLICE_, EXTENDED_, FASTCALL_, IsSpellSingleTarget);
         _PI->WriteLoHook(0x59E437, changeSpellDesc);
      }
   }

   return TRUE;
}

Rolex писал(а):

Так вот задача сейчас состоит в том, чтобы написать лоухук(и) (или, если возможно, через WriteDword/WriteHexPatch), который эффект Радости и Удачи подымет до +3, а Печали и Неудачи опустит до -3 на Экспертном уровне.
Ускорение нужно увеличить с 5 до 7 на Эксперте. А вот Медлительность хотелось бы подправить на всех уровнях вместо 25%/25%/50%/50% ---> 20%/20%/40%/60%. Нужна ваша помощь.


AlexSpl писал(а):

Код: Выделить всё
//   _PI->WriteHexPatch(0x47852C, "EB 0A");


должно работать. Убирает рандом и ставит максимальный хил.

_PI->WriteHexPatch(0x47852C, "EB 0A") - да, действительно, так работает, видимо я криво потестил.

Кстати, а зачем тогда нужен вот этот адрес: 0x47852D, если по первому работает? Я так понимаю, что патчить можно по любому адресу из диапазона и результат будет один и тот же. И все адреса из диапазона патчить ненужно, а достаточно взять какой-то один, верно?

Но вот повысить макс хил не выходит. Вот так почему-то не работает:

Код: Выделить всё
_PI->WriteDword(0x63EA98, 50);
_PI->WriteDword(0x63EA98 + 4, 100);
_PI->WriteDword(0x63EA98 + 8, 200);
_PI->WriteDword(0x63EA98 + 12, 300);


Rolex писал(а):

То есть, чтобы Палатка Первой Помощи восст. без навыка Первая помощь фиксированные 50 ед (вместо случайных от 1 до 25 ед), а с навыком Первая Помощь фиксированные 100/200/300 соответственно (в оригинале случайное число от 1 до 50/75/100).

Контроля Палатки нет. Игрок не управляет палаткой, все идет автоматически как и без навыка Первая помощь, только Палатка лечит не один случайно выбранный отряд, а сразу все отряды героя. Плюс увеличить здоровье Палатки до 300.

И еще так подумал, надо бы сделать, чтобы Палатка восст. еще и свое здоровье (в кол-ве соотв развитию навыка), а также здоровье всех орудий (Баллисты, Тележки, Катапульты). В оригинале можно восстановить только здоровье существ.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5547
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2161 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 28 окт 2020, 12:13

Цитата:
Кстати, а зачем тогда нужен вот этот адрес: 0x47852D, если по первому работает? Я так понимаю, что патчить можно по любому адресу из диапазона и результат будет один и тот же. И все адреса из диапазона патчить ненужно, а достаточно взять какой-то один, верно?

Нет. Длина патча 2 байта (EB 0A), байт EB прописывается по адресу 0x47852С, а байт 0A - по следующему за ним адресу 0x47852С + 1 = 0x47852D. Указывать диапазон почти всегда не имеет смысла, т.к. известен размер (длина) патча в байтах. Достаточно указать начальный адрес.

Цитата:
Но вот повысить макс хил не выходит.

Чтобы изменить эффект First Aid, Вам потребуется изменить базовый хил и коэффициенты. Базовый хил (25.0f) здесь: 0x63B76C, коэффициенты (0.0f, 1.0f, 2.0f, 3.0f) здесь: 0x63EA98. Базовый хил просто так менять нельзя (константа 25.0f используется в других алгоритмах), но мы уже обсуждали, что нужно делать в таких случаях. Базовый хил и коэффициенты - вещественные числа с плавающей точкой типа float (ссылку на конвертер float to hex я давал выше). Можно и без конвертера обойтись. Тоже пример выше был.
Вернуться к началу

Пред.След.

Вернуться в Общий раздел

Кто сейчас на конференции

Сейчас этот форум просматривают: Bing [Bot] и гости: 17

cron