|
|
phoenix4ever
Legendary Hero
Heroes is love, Heroes is life
|
posted September 29, 2017 06:56 PM |
|
|
Keep in mind Gold Dragons are affected by ageing, but can't be healed...
|
|
Serp
Known Hero
|
posted September 30, 2017 12:25 PM |
|
|
Hi
Modding with help of baratorchs patcher sound interesting, better than changing files directly
I guess all the hex editor knowledge is still needed? Or works it differently?
And where can I download the patcher? And do I have to update it everytime the HD mod updates ? (the dropbox link in russian forum says file was deleted)
It would be super cool to have an english thread explaining the patcher thing.
And also complete explanation of every line code eg. for the EagleEye mod. Or is there something like a documentation to learn how to write code and what use to change what?
As FfuzzyLogik already suggested, a thread with all explanations only would be great.
|
|
Serp
Known Hero
|
posted September 30, 2017 12:31 PM |
|
|
And is it possible to enable the "confirmation window" for witch huts and scholar with help of the patcher? HD mod already had this active in one version, but disabled it again in all updates afterwards. Maybe it also was a plugin baratorch developed.
(sorry for double post, can not edit post above, cause forum does not let me login... only posting with same username+password works for some reason)
|
|
RoseKavalier
Admirable
Supreme Hero
|
posted September 30, 2017 02:25 PM |
|
|
Patcher_x86 is included as part of HDmod, you can see it in your C:/.../Heroes3/ folder (patcher_x86.dll).
To use it for making your own plugins, you simply need the project's header file. I spent some time running it through translators to get it in English.
As I previously posted, you also need a code compiler for example Visual Studio (I think the Community version is free and should do the job?) or Code::Blocks, ... the list goes on. Writing code is not enough, you actually need to compile it so that patcher_x86 can tell the game what to do
I think making a thread explaining how to use it in English is a cool idea, but it's a lot of work for both thread contributors and also learners: to be able to do stuff by yourself, you need to learn Assembly and a higher language like C++. There are other options than C++ but 99% of the H3 modders seem to be using C++ so it's probably a good idea to go that way. It's not impossible if you are not a programmer, I went from ~0 knowledge to being relatively at ease with this stuff in less than a year.
There are resources available to help you figure out what part of the code you're looking at and also existing documents to help you code H3-related stuff but before I delve into that, it's best to at least get the basics of what is posted before this. Also, Russian H3/WoG forums are incredible sources of knowledge. Don't be turned away by the language barrier, there are automatic translators out there and willing people)))
Making a plugin for Witch Hut is very easy with patcher_x86, here are the basics:
int __stdcall Witch_Hut_Choice(LoHook* h, HookContext* c)
{
int choice = *(int*)(*(int*)0x6992D0 + 0x38) - 0x7805; // grab user's decision
if (choice != 0) { // clicked "refuse"
c->return_address = 0x4A7E8F; // skip over "give secondary skill procedure"
return NO_EXEC_DEFAULT; // do not execute original code
}
return EXEC_DEFAULT; // execute original code because user did not refuse secondary skill
}
Patcher* _P; // required for every plugin
_PI = _P->CreateInstance("Witch_Hut"); // required for every plugin
_PI->WriteHexPatch(0x4A7E64, "02"); // add Cancel button to textbox
_PI->WriteLoHook(0x4A7E85, Witch_Hut_Choice); // adds the Witch_Hut_Choice function to the code @ 0x4A7E85
You still need to create the project and do some basic stuff, but it's the same thing AlexSpl already wrote.
The code required is even more painless when you will have access to other some H3 modding resources as the "choice" value is a well-defined region of memory.
EDIT: this forum is terrible for code format
|
|
Serp
Known Hero
|
posted October 01, 2017 12:34 AM |
|
|
@RoseKavalier: Thank you very much, especially for the patcher with english comments
I know lua and Python, and I think learning C++ (at least some parts that are necessary) might not be that hard.
But this Assembly stuff... I'm totally puzzeled I read the past pages were you explained some stuff about it and it sounds extremely complicated I am sure I will never understand it
But with this Plugin Method... Isn't it possible now to create several independent mods and upload them somewhere? I mean there are mods for ERA to download here and at other websites.
So maybe some of you who are able to mod and have fun to create some, could upload their mods at one location?
And we users can then download and combine them, so a plugin for better eagleeye, one for confirmation window and more
Only problem could be compatibility issues with mods? I guess mods are incompatible, if they change the same value? So better modders should write in description of mods, which values are changed, so also non-modders can see if mods are compatible or not.
|
|
RoseKavalier
Admirable
Supreme Hero
|
posted October 01, 2017 01:52 AM |
|
|
Assembly isn't the end of the world especially if you already know some programming! Also, it helps if you have an idea of what the code is supposed to be/do, that helps you determine what is what.
In any case, Assembly is mostly useful here to grab initial data... after that you can use another language to do all you need.
Of course you can make separate plugins and use all of them together with HD_Launcher. In theory, plugins can conflict with each other (or one plugin could disable another) but there are also situations where two plugins modifying the same code area can work together with no problems at all. For instance, SoD_SP "interacts" with HDmod in some cases.
One of the largest repository of plugins atm is at DF2. It's nice because they have [code] format, which is not available here
Personally, my biggest worry regarding "compatibility" of plugins and such is for multiplayer. For example, if the Witch Hut plugin works in multiplayer, some player can take advantage of it compared to another player who doesn't have it. Seeing as there's a relatively healthy multiplayer scene, it's a bit tricky.
Another example that may highlight this issue better: recreating 'Map Advanced Infos' by Salamandre for SoD.
Fantastic for single player maps where you can save/load.... but would be terrible if used in multiplayer.
|
|
Serp
Known Hero
|
posted October 01, 2017 01:37 PM |
|
|
@AlexSpl:
What is the difference between the "NewEagleEye.dll" you uploaded here at heroescommunity and the "NewEagleEyeAlex.dll" from the russian forum? The second dll is much bigger.
@RoseKavalier:
thank you
I don't see any problem with multiplayer. baratorch can simply add a check if all players have the same plugins installed (check content, not only names of plugins). If yes, everything is fine. If not it prints a message that they all should disable/enable plugin x, before able to start.
A reason like "unfair in MP" should never be a reason for anything. There are always solutions for it .
First page of thread is hard to understand... but most mods from the second page of thread contain info, that they are for HD-Mod and are also better understandable
The EaglyEye mod at that forum contains info "works in multiplayer".
Does this mean all plugins before do not work in Multiplayer? Eg. Better Learning and so on?
I guess they are working, and of course everyone should have same plugins installed.
But are there plugin mods that are not MP compatible, even if all have them installed?
Are there problems when writing code, where you have to make sure tha your code is MP compatible?
What are examples for this? In other games eg. I saw that "ThePlayer" always returns the player who is executing the code. So if any code gives some ressources to "ThePlayer", it will give a different result at all PCs -> not MP compatible.
Can you explain more, when plugins are compatible or incompatible to each other?
I mean if two plugins are changing the Mana costs of fireball, these are obviously not compatible.
But if one is changing mana cost and the other changing the range of fireball and another the magic school, are these three plugins compatible?
I downloaded now: TownPortal, QuicksandMines, LearningSkill and NewEaglyEye. Are these compatible? I guess yes.
And are there problems when two plugins have the same name? Eg. all three plugins of the above fireball example "BetterFireball"?
What about ingame descriptions? If secondary skills are changed, do I still have to change ingame desription myself? Or is this also done with plugin? Can it be done with plugin at all?
|
|
AlexSpl
Responsible
Supreme Hero
|
posted October 01, 2017 03:08 PM |
|
Edited by AlexSpl at 15:16, 01 Oct 2017.
|
Quote: @AlexSpl:
What is the difference between the "NewEagleEye.dll" you uploaded here at heroescommunity and the "NewEagleEyeAlex.dll" from the russian forum? The second dll is much bigger.
"NewEagleEyeAlex.dll" was not compiled by me. Probably it contains some extra stuff like debug info.
Quote: The EaglyEye mod at that forum contains info "works in multiplayer".
Does this mean all plugins before do not work in Multiplayer? Eg. Better Learning and so on?
It means that this plugin had been tested in multiplayer before it was shared.
Quote: But are there plugin mods that are not MP compatible, even if all have them installed?
Sometimes you need to write a line or two to adjust your code for multiplayer. You have to make sure that it runs correctly for all players (instances of the game).
Quote: Can you explain more, when plugins are compatible or incompatible to each other?
As far as I know, plugins are stacked. As long as they don't change the same things, they do their work just fine.
Quote: And are there problems when two plugins have the same name? Eg. all three plugins of the above fireball example "BetterFireball"?
You can always create different folders for different plugins, even if dlls have identical names. Make sure to give a unique patcher instance name to your plugin, though. Don't use short or common names like in the following example: _PI->CreateInstance("test");
Quote: What about ingame descriptions? If secondary skills are changed, do I still have to change ingame desription myself? Or is this also done with plugin? Can it be done with plugin at all?
If needed, descriptions can be changed by a plugin as well.
|
|
Serp
Known Hero
|
posted October 01, 2017 03:22 PM |
|
|
After enabling a plugin, do I have to start a new game or can I load a savegame?
I tried the plugins mentioned above, put them into _HD3_Data Packs {Name of Plugin}.
The folder contains the dll with the same name as the folder.
I enabled the plugins in HD Launcher with the "add" button and hit play.
I tried it with h3hota.exe and h3blade.exe. I tried it with loading a savegame and also starting a new game.
None of the plugins are working =/
I thought maybe it has to do with line:
#include "....includehomm3.h"
instead of
#include "HotAhomm3.h"
Therefore I also tried the h3blade.exe.
All of the plugins from russian forum use the first include. Maybe thats why they do not work at all, even if I start h3blade.exe?
Quote: "NewEagleEyeAlex.dll" was not compiled by me. Probably it contains some extra stuff like debug info.
I noticed the NewEagleEyeAlex is with "....includehomm3.h", while NewEagleEye is with "HotAhomm3.h" , that is the only difference.
But testing eagle eye is not that easy, therefore I don't know if NewEagleEye is working or not.
Should it? So I need to change that include line for all the other plugins and recompile them again?
Quote: Sometimes you need to write a line or two to adjust your code for multiplayer. You have to make sure that it runs correctly for all players (instances of the game).
Are there common lines/commands to watch out? I would like to be able to see with one glance, if a mod is MP compatible or not.
Quote: You can always create different folders for different plugins, even if dlls have identical names. Make sure to give a unique patcher instance name to your plugin, though. Don't use short or common names like in the following example: _P->CreateInstance("test");
okay... so folder name, dll name and instance name can be completely different? Of course it is easier if all of them have same name, but it is not mandatory?
Quote: If needed, the descriptions can be changed by a plugin as well.
Is it also possible to add several different translations (russian/english)? Does the NewEagleEye plugin changes description?
|
|
Serp
Known Hero
|
posted October 01, 2017 03:24 PM |
|
|
(obviously backslash \ is removed by the forum... =/ )
|
|
AlexSpl
Responsible
Supreme Hero
|
posted October 01, 2017 03:32 PM |
|
|
You should run HD_Launcher.exe and add a plugin to the Plugins list. And I don't think that plugins are compatible with AB or RoE.
|
|
Serp
Known Hero
|
posted October 01, 2017 04:34 PM |
|
|
AlexSpl said: You should run HD_Launcher.exe and add a plugin to the Plugins list. And I don't think that plugins are compatible with AB or RoE.
Of course I did, the h3hota.exe/h3blade.exe was chosen in the HD_Launcher.
|
|
AlexSpl
Responsible
Supreme Hero
|
posted October 01, 2017 04:39 PM |
|
|
Well, then I don't understand why the plugin failed to work for you. Did you see its name in the Plugins list at the right?
|
|
Serp
Known Hero
|
posted October 01, 2017 05:00 PM |
|
|
AlexSpl said: Well, then I don't understand why the plugin failed to work for you. Did you see its name in the Plugins list at the right?
Yes. I will explain more detailed:
Lets test it with the LearningSkill.dll
Download from here (second download link) http://forum.df2.ru/index.php?s=&showtopic=30848&view=findpost&p=744755
In
3DO\Heroes 3 Complete\_HD3_Data\Packs\LearningSkill
I put the LearningSkill.dll and a "info.txt" file where I described what the plugin does (just for personal use, so I can remember).
Now I start the HD_Launcher from the Heroes 3 complete folder (5.0 Beta 10), h3hota.exe selected, HD+ active and hit "add" from the plugins window. I select the LearningSkill and add it. Now the plugins window contains LearningSkill.
Now I simply hit "play" and start a new game. I get a hero with learning skill and level him with help of learning stones. Everytime he gets +5%. I tested it until level 4, all the time just 5%.
So what is the difference between:
#include "..\..\include\homm3.h"
and
#include "HotA\homm3.h"
Could it be the reason for the problem? Do I need #include "HotA\homm3.h" ?
|
|
AlexSpl
Responsible
Supreme Hero
|
posted October 01, 2017 05:13 PM |
|
|
What about newEagleEye? I am not the author of the plugin you mentioned. Also make sure that you are not running under virtual OS.
|
|
RoseKavalier
Admirable
Supreme Hero
|
posted October 01, 2017 05:19 PM |
|
|
Serp said:
So what is the difference between:
#include "....includehomm3.h"
and
#include "HotAhomm3.h"
Could it be the reason for the problem? Do I need #include "HotAhomm3.h" ?
This is just when you create the project in (this case) Visual Studio... a lot of pre-defined structures and functions for H3 are available in that header. In those 2 examples, the project format was changed and/or file storage on author's computer was different.
You don't need the original code for it to work, just the .dll. Unless you want to compile it yourself, you shouldn't worry about this.
For install, make sure you see the dll directly in the _HD3_Data/Packs/Plugin_name/ folder ... not in another folder within there (which often happens when unzipping).
There are not too many examples where plugins can be incompatible, but if you really like to know here are two examples:
1- you partly overwrite an existing plugin's trampoline (crash)
2- the return address (see c->return address = 0x4A.... from Eagle Eye) of one plugin skips over another plugin's start (one plugin doesn't work)
|
|
Serp
Known Hero
|
posted October 01, 2017 06:10 PM |
|
|
I don't know an easy way to test eagleeye, because of KI.
How about logfiles?
In Heroes folder there is a patcher_x86 log file, which is empty (expect one line with 0)
Even if I set logging to 1 in the patcher_x86.ini, the file is still empty.
Should it contain something when plugins are enabled?
Btw what to do with the patcher_x86.hpp file? Do I have to add it to the heroes folder? Or is it only for creating dll files?
|
|
RoseKavalier
Admirable
Supreme Hero
|
posted October 01, 2017 06:24 PM |
|
|
Serp said: I don't know an easy way to test eagleeye, because of KI.
Create a map, place your hero with Eagle Eye and some artifacts (or specialty so %learn is high)and another hero with a bunch of spells you can learn. Start fight.
Or you can download a disassembler (like OllyDbg) and check the address modified by the plugin to make sure something is changed:
Quote:
_PI-> WriteDword (0x63EA2C, (int & eagleEyeCoefs [1]);
_PI-> WriteDword (0x63EA30, (int & eagleEyeCoefs [2]);
_PI-> WriteDword (0x63EA34, (int & eagleEyeCoefs [3]);
// Remove the original effect
_PI-> WriteHexPatch (0x469C23, "EB");
_PI-> WriteHexPatch (0x476996, "E9 DD 01 00 00");
// Fix the title of the dialog
_PI-> WriteLoHook (0x4F7D49, saveCaption);
_PI-> WriteLoHook (0x4F7D54, captionFix);
_PI-> WriteLoHook (0x462C7D, eagleEyeSetGlobalFlags);
_PI-> WriteLoHook (0x477C00, eagleEyeMain);
Serp said: Btw what to do with the patcher_x86.hpp file? Do I have to add it to the heroes folder? Or is it only for creating dll files?
For creating plugins only.
|
|
Serp
Known Hero
|
posted October 01, 2017 06:35 PM |
|
|
Thanks for the hint with just creating a testmap
And the result is:
NewEagleEye works!
NewEagleEyeAlex does not work!
And according to the source codes, the only difference is, as I already wrote, this include line. So obviously this is indeed important... or does anyone see another difference?
NewEagleEyeAlex version:
http://forum.df2.ru/index.php?s=&showtopic=30848&view=findpost&p=744804
NewEagleEye version:
http://handbookhmm.ru/forum/viewtopic.php?f=56&t=518&start=240#p16494
|
|
Serp
Known Hero
|
posted October 01, 2017 09:02 PM |
|
|
I tried now to add the "basics" to the witch hut confirmation code from RoseKavalier.
This is the result:
Quote:
#include "HotA\homm3.h"
Patcher* _P; // required for every plugin
PatcherInstance* _PI;
static _bool_ plugin_On = 0;
int __stdcall Witch_Hut_Choice(LoHook* h, HookContext* c)
{
int choice = *(int*)(*(int*)0x6992D0 + 0x38) - 0x7805; // grab user's decision
if (choice != 0) { // clicked "refuse"
c->return_address = 0x4A7E8F; // skip over "give secondary skill procedure"
return NO_EXEC_DEFAULT; // do not execute original code
}
return EXEC_DEFAULT; // execute original code because user did not refuse secondary skill
}
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.Witch_Hut_Choice"); // required for every plugin
_PI->WriteHexPatch(0x4A7E64, "02"); // add Cancel button to textbox
_PI->WriteLoHook(0x4A7E85, Witch_Hut_Choice); // adds the Witch_Hut_Choice function to the code @ 0x4A7E85
}
}
return TRUE;
}
(Visual Studio Community is installing at the moment.. takes very long unfortunately, so I was not able to test yet ... I chose the first and 3rd "workload" for windows. I hope these are correct?)
But I wonder:
1) The example test code here http://handbookhmm.ru/forum/viewtopic.php?f=56&t=518 contains this:
#include "patcher_x86.hpp"
But why does not a single source code from the downloaded plugins contains this line?
2) I noticed the plugin mods in russian forum (and also the test code) have a slightly different form to add the hooks:
Quote:
BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
static _bool_ plugin_On = 0;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
if (!plugin_On)
{
plugin_On = 1;
_P = GetPatcher();
_PI = _P->CreateInstance("HD.Plugin.QuicksandMines");
_PI->WriteLoHook(0x5A066B, quicksandSpell);
_PI->WriteLoHook(0x5A0852, minesSpell);
}
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
While the eagleye mod is doing:
Quote:
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.NewEagleEye");
float eagleEyeCoefs[] = {0.00f, 0.30f, 0.35f, 0.40f};
_PI->WriteDword(0x63EA2C, (int&eagleEyeCoefs[1]);
// and so on...
}
}
return TRUE;
}
I understand the code from eagleeye mod. But the other code with this "case" I do not understand.
But that is not important, as long both codes result in the same. Do they?
Especially I wonder about the lines:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
Aren't these attach/detach things not needed in the eagleeye code? Are they ever needed?
I think an equivalent would be this?:
if ( DLL_THREAD_ATTACH == ul_reason_for_call ) {}
So they basically do nothing, even in the code with "case"? But are there mods where they are needed? And how to know?
@RoseKavalier:
Can you also give me code for scholar choice (when it is a secondary skill)? (when denying, scholar still disappears)
A explantion would be also good I mean the past pages of the thread you and others always mentioned "this hex ... is responsible for this and that". And my goal would be to be able to at least be able to create my own plugins, when you or anyone else is telling me the assembly hex to change.
So I need to know: When to use a patch and when a hook and when something else? And eg how can I develope on my own this line: "*(int*)(*(int*)0x6992D0 + 0x38) - 0x7805; // grab user's decision" Why so many "*" and why + and - ?
|
|
|
|