Объявления

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

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

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 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)
Поблагодарили: 2185 раз.

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

Сообщение AlexSpl » 16 июл 2017, 13:06

Краткое step-by-step руководство для начинающих мододелов

Плагины на C++

0. Установите Microsoft Visual Studio. Бесплатная версия Microsoft Visual Studio 2008 Express Edition здесь: https://go.microsoft.com/fwlink/?LinkId=104679 (895 МБ). При установке выберите Microsoft Visual C++ 2008 Express Edition.

 О бесплатной Microsoft Visual Studio Community 2019
:!: Если Вы совсем не знакомы с Microsoft Visual Studio, рекомендую устанавливать Microsoft Visual Studio 2008 Express Edition.

Скачать Microsoft Visual Studio Community 2019 можно с официального сайта: https://visualstudio.microsoft.com/ru/downloads/

Можно создать оффлайн-установщик, если запустить скачанный экзешник со следующими параметрами (если нужен только С++):
Код: Выделить всё
vs_community.exe --layout c:\vslayout --add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --lang en-US

Язык можно поменять на русский: --lang ru-RU

Для развёртывания на любой машине (включая те, которые не подключены к сети Интернет) нужно скопировать папку c:\vslayout на другой компьютер и запустить экзешник vs_setup.exe, находящийся в этой папке, с параметрами:
Код: Выделить всё
vs_setup --add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended

1. Скачайте заголовочный файл patcher_x86.hpp (его нужно будет скопировать в папку, где лежит dllmain.cpp, см. далее):

patcher_x86.zip
(11.6 КБ) Скачиваний: 1454

2. Создайте новый проект: Файл -> Создать -> Проект... (Ctrl + Shift + N), выберите шаблон Visual C++/Win32/Проект Win32, дайте ему какое-нибудь осмысленное название, запомните полный путь к Вашему проекту и смело жмите OK :smile20:
3. Откроется мастер приложения Win32. Жмите "Далее >".
4. Выберите тип приложения: "Библиотека DLL" и жмите "Готово".
5. В левой части экрана появилось окошко "Обозреватель решений". Делаем двойной клик на dllmain.cpp и меняем код на следующий:

Код: Выделить всё
// Раскомментируйте строчку ниже, если у Вас Microsoft Visual Studio 2017 или новее
// #include "pch.h"

// Раскомментируйте строчку ниже, если у Вас более старая версия Microsoft Visual Studio
// #include "stdafx.h"

// Следующая строчка нужна для для функции sprintf()
// Можно удалить, если не используете в Вашем плагине
#include <stdio.h>

// Здесь указываем относительный путь к библиотеке патчера
#include "patcher_x86.hpp"

Patcher* _P;
PatcherInstance* _PI;

int __stdcall TestLoHook(LoHook* h, HookContext* c)
{
    char TextBuffer[256];
   
    DWORD GameMgr = *(DWORD*)0x699538;
    short Day = *(short*)(GameMgr + 0x1F63E);
    short Week = *(short*)(GameMgr + 0x1F640);
    short Month = *(short*)(GameMgr + 0x1F642);

    sprintf(TextBuffer, "Hello, World!\n\nDays passed: %d", Day + 7 * Week + 28 * Month - 36);
    CALL_12(void, __fastcall, 0x4F6C00, TextBuffer, 1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0);
   
    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    static bool plugin_On = false;

    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = true;
            _P = GetPatcher();
            _PI = _P->CreateInstance((char*)"HD.Plugin.TestPlugin");
            _PI->WriteLoHook(0x4C80F4, TestLoHook);
        }
    }

    return TRUE;
}

 Обладателям Microsoft Visual Studio Community 2019
Добавьте строчку #define _CRT_SECURE_NO_WARNINGS в заголовочный файл framework.h перед строчкой #include <windows.h>:
Код: Выделить всё
#pragma once

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_WARNINGS
// Windows Header Files
#include <windows.h>

6. Сохраняем решение (Ctrl + S).
7. Выбираем конфигурацию решения "Release" (Просто выбираем "Release" из списка вверху окна рядом со значком "Начать отладку (F5)" или жмём Alt + F7, в левой части окна выбираем "Свойства конфигурации", жмём кнопку "Диспетчер конфигураций..." и выбираем вверху - "Активная конфигурация решения: Release", Закрыть, OK), теперь жмём F7 (Построение -> Построить решение).

 7а
Если Вы используете в Вашем решении заголовочный файл homm3.h, дополнительно проделайте следующее: жмём Alt + F7, в левой части окна выбираем "Свойства конфигурации" -> "C/C++" -> "Создание кода" и ставим "Выравнивание членов структур" в "1 байт (/Zp1)".

8. Идём в папку проектов, открываем папку с названием Вашего проекта -> Release и копируем dll оттуда прямо в папку _HD3_Data\Packs\{Название Вашего плагина}.
9. Запускаем HD Launcher, добавляем плагин (Окошко "Плагины", кнопка "Подключить") и жмём "Играть".

A. Поздравляю! Только что Вы создали свой первый плагин для HD мода.

P. S. Теперь Вам только осталось разобраться, какие изменения вносит плагин и как их делать самостоятельно, и Вы - полноценный начинающий мододел.



Плагины на Delphi

0. Скачайте PatchAPI:

PatchApi.zip
(10.11 КБ) Скачиваний: 1044

1. Создайте DLL (File -> New -> Other..., Dynamic-link Library) со следующим кодом (код приведён в качестве примера):

Код: Выделить всё
library MyFirstDelphiPlugin;

uses System.SysUtils, Windows, PatchApi;

var _P: TPatcher;
    _PI: TPatcherInstance;

function TestHook(h: TLoHook; c: PHookContext): Integer; stdcall;
var TextBuffer: string[200];
    GameMgr: PDWORD;
    Day, Week, Month: Word;
begin
  GameMgr := Ptr($699538);
  Day := Word(Ptr(GameMgr^ + $1F63E)^);
  Week := Word(Ptr(GameMgr^ + $1F640)^);
  Month := Word(Ptr(GameMgr^ + $1F642)^);

  TextBuffer := ShortString('Hello, World!'#13#10'Days passed: ' +
    IntToStr(Day + 7 * Week + 28 * Month - 36));

  Call(FASTCALL_, $4F6C00, [TextBuffer, 1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0]);
  Result := EXEC_DEFAULT;
end;

procedure DLLMain(Reason: Integer);
begin
  if DLL_PROCESS_ATTACH = Reason then
  begin
    _P := GetPatcher;
    _PI := _P.CreateInstance('HD.Plugin.DelphiTest');
    _PI.WriteLoHook($4C80F4, @TestHook);
  end;
end;

begin
  DLLProc := @DLLMain;
  DLLMain(DLL_PROCESS_ATTACH);
end.


:!: Примеры готовых плагинов Вы можете найти в этой теме: Пользовательские плагины для HD мода :!:

 Downloads
newEagleEye.zip
(6.31 КБ) Скачиваний: 1437

newEagleEye5.zip
(6.3 КБ) Скачиваний: 1181

newEagleEye5Adv.zip
(6.31 КБ) Скачиваний: 1204

newEagleEye5_EN.zip
(6.26 КБ) Скачиваний: 1213

newEagleEye5Adv_EN.zip
(6.27 КБ) Скачиваний: 1233

H3 Buildings.pdf
(526.05 КБ) Скачиваний: 1457

 Интересные посты этой темы
Сюда буду добавлять интересные посты, чтобы к ним всегда можно было быстро перейти.

Оптимизация целочисленного деления, или "очень странные числа"
Небольшой, но очень полезный пример условного брейкпоинта на запись в текстовый буфер. Поможет сэкономить время
Делаем заклинания массовыми
Как создать дополнительное окно. Может пригодиться при поиске багов, а также для вывода на экран разной полезной информации
Запрещаем заклинания
Запрещаем вторичные навыки
То и другое вместе
Ограничиваем количество героев у игрока
Битовые поля. Логический и арифметический битовый сдвиг. Распаковка и запаковка свойств объекта в битовое поле на примере Учёного
Добавляем новые заклинания. Начало разработки
Добавляем новые заклинания. Добавлено 16 новых заклинаний. Актуальная версия плагина
Краткий гайд по добавлению новых заклинаний с помощью плагина NewSpells. Бафы и дебафы
Последний раз редактировалось AlexSpl 24 окт 2022, 17:23, всего редактировалось 91 раз(а).
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 28 июл 2017, 20:05

Спасибо !

В выходные начну разбирать заголовочные файлы патчера и пробовать. Что-нибудь :)
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 30 июл 2017, 20:40

Поисследовал, как изменить коэффициент первичного навыка защиты.
По ряду соображений хочется сделать его не 2,5%, а 3% - снижение ущерба от атаки.

В воговской базе соответствующих комментариев нет.

Обнаружилось, что коэффициент 0.025 нужно менять по адресу 0x0063B8C0

Ограничение на общее снижение ущерба (сейчас 70%) правится по адресу 0x0063B8B8.
Величину 0.3 (то есть 30%) меняю на 0.25 (25%).
Дополнительно это дело (30%) захардкожено в одной процедуре (2 ассемблерных мува со значениями).
Нужно поправить значения в 0x00443913 и 0x00443918

Стоимость Героя находится по адресу 0х0067814С
Меняю с 2500 на 6000.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 01 авг 2017, 17:56

Хотел бы попросить подсказки у AlexSpl, если возможно.

По адресу 004E6260 есть процедура HeroSpellSpecialityEffect.

Как можно ее использовать, чтобы поменять у героев бонусы по специальностям заклинания ?
(например, на Кольцо холода дать бонус не 5%, а 7% на уровень)

Или это делается не с помощью этой процедуры ?

И где можно подправить бонусы по специальностям существ (например, бонус гномам от Уфретина) ?
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 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)
Поблагодарили: 2185 раз.

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

Сообщение AlexSpl » 02 авг 2017, 08:35

Цитата:
Хотел бы попросить подсказки у AlexSpl, если возможно.

По адресу 004E6260 есть процедура HeroSpellSpecialityEffect.

Как можно ее использовать, чтобы поменять у героев бонусы по специальностям заклинания ?
(например, на Кольцо холода дать бонус не 5%, а 7% на уровень)

Или это делается не с помощью этой процедуры ?

Да, дополнительный урон заклинаний героев-специалистов считает именно эта функция. Только почему 5%? В оригинале же 3% за каждый уровень, кратный уровню монстров.

Изменить можно, например, так (LoHook на 4E631Dh):

Код: Выделить всё
int __stdcall applyMultiplier(LoHook* h, HookContext* c)
{
   const double multiplier = 0.07;
   
   if ( *(int*)(c->ebp + 8) == 20 ) { // Frost Ring?
      *(double*)c->esp = *(double*)(c->ebp - 8) * multiplier;
      
      c->return_address = 0x4E6326;
      return NO_EXEC_DEFAULT;
   }
   
   return EXEC_DEFAULT; // иначе стандартный множитель
}


На второй вопрос тоже постараюсь ответить, но позже.

* * *

Бонусы специалистов по монстрам раздаёт функция sub_4E6390. Множитель меняется аналогично (см. инструкцию по адресу 4E6546h).
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 02 авг 2017, 18:08

Прекрасно. Для специализаций по существам планируется для всех увеличить с 5% до 8,5%.
Соответственно, все очень просто - изменю значение константы по адресу 0x0063AC58.

А вот насчет заклинаний еще не все понятно - как быть, если бонус к заклинанию не зависит от уровня героя ?
(например, +3/+2/+1 к Каменной коже в зависимости от уровня существа или 50% к Магической стреле у Циэль)
Как в этих случаях подкрутить ?
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 02 авг 2017, 18:25

Хотя вообще-то 63AC58 используется еще и в ряде процедур битвы, например в loc_004E56BF и loc_004430B5.
В этих процедурах это наверно уже не бонус для существ, а бонус для первичного навыка Атака, так ?
Если так, то 63AC58 я подменять не буду, а сделаю аналог хука, указанный вами выше, да.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 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)
Поблагодарили: 2185 раз.

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

Сообщение AlexSpl » 02 авг 2017, 18:25

Менять константу не самое удачное решение, т.к., во-первых, она может использоваться (и используется) другими функциями, а во-вторых, может понадобиться сделать разные бонусы для разных существ.

Цитата:
например, +3/+2/+1 к Каменной коже в зависимости от уровня существа или 50% к Магической стреле у Циэль

Полагаю, нужно добавить соответствующие хуки в ту же функцию (sub_4E6260). Могу помочь с конкретными изменениями.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 02 авг 2017, 19:23

AlexSpl писал(а):

Менять константу не самое удачное решение, т.к., во-первых, она может использоваться (и используется) другими функциями, а во-вторых, может понадобиться сделать разные бонусы для разных существ.


Насчет бонусов - пожалуй, да. Поскольку формула из ФизМига как-то не совсем работает:

Атака = Атака(базовая) * (1+ N/n * 0.05)

Для 1-4 уровней работает, дальше значение Атаки (или Защиты) ниже, чем дает формула.
Например, Тамика с черными рыцарями. Поднимаем ее до 11 уровня.

Считаем Атаку:
ceil (16* (1+11*0.05/6)) = 18

В реальности имеем 17, а не 18, то есть Атаку нам увеличили только на 1, а не на 2.
А вот с гномами формула сработала, с крестоносцами тоже сработала.

Есть какие-то мысли, почему формула не работает ?
Или я неправильно беру Атака(базовая) ?
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 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)
Поблагодарили: 2185 раз.

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

Сообщение AlexSpl » 02 авг 2017, 19:47

Цитата:
Атака = Атака(базовая) * (1+ N/n * 0.05)

Здесь деление целочисленное. Т.е. правильно Атака = ceil(Атака(базовая) * (1+ [N/n] * 0.05))
Вернуться к началу

След.

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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 21