Heroes of Might and Magic Community
visiting hero! Register | Today's Posts | Games | Search! | FAQ/Rules | AvatarList | MemberList | Profile


Age of Heroes Headlines:  
5 Oct 2016: Heroes VII development comes to an end.. - read more
6 Aug 2016: Troubled Heroes VII Expansion Release - read more
26 Apr 2016: Heroes VII XPack - Trial by Fire - Coming out in June! - read more
17 Apr 2016: Global Alternative Creatures MOD for H7 after 1.8 Patch! - read more
7 Mar 2016: Romero launches a Piano Sonata Album Kickstarter! - read more
19 Feb 2016: Heroes 5.5 RC6, Heroes VII patch 1.7 are out! - read more
13 Jan 2016: Horn of the Abyss 1.4 Available for Download! - read more
17 Dec 2015: Heroes 5.5 update, 1.6 out for H7 - read more
23 Nov 2015: H7 1.4 & 1.5 patches Released - read more
31 Oct 2015: First H7 patches are out, End of DoC development - read more
5 Oct 2016: Heroes VII development comes to an end.. - read more
[X] Remove Ads
LOGIN:     Username:     Password:         [ Register ]
New Server | HOMM1: info forum | HOMM2: info forum | HOMM3: info forum | HOMM4: info forum | HOMM5: info forum | MMH6: wiki forum | MMH7: wiki forum
Heroes Community > Heroes 3.5 - WoG and Beyond > Thread: How to edit HotA?
Thread: How to edit HotA? This thread is 29 pages long: 1 2 3 4 5 ... 10 20 ... 25 26 27 28 29 · «PREV / NEXT»
Ben80
Ben80

Tavern Dweller
posted October 04, 2017 05:36 PM

Serp said:
@Ben:
I wonder why in your townportal and also the QuicksandMines plugin, "no magic school" is identical to "basic magic school" ? (townportal both require 1200 movement points and qicksandmines both will cast 6). Maybe 4 mines/quciksand for no school would fit better?
This is just a suggestion, especially for future plugins made by you



Because of in original game spell effect at no magic school always equivalent to spell effect at basic magic school. Different only spell costs.

Other secondary skill plugins will be published.


____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 04, 2017 06:28 PM

@AlexSpl:
Thanks I already saw it
Is this a one time change (at game start), or is this code executed everytime someone checks the description?

@Ben:
Ah, yes, thank you

@RoseKavalier:
The ScholerChoice code does not work 100% correct.
The scholar gives Leadership. But for some reason "skill_level" is the the level of my Learning skill. I tested all constellations, so I'm quite sure it is the Learning skill. The result is that the picture and also the Skill_level==3 check fail, according to my Learning level.
But skill_id is correct, at least the LearnSecondarySkill(skill_id,1); is working fine and gives Leadership.

The code is:
Quote:
#include "HotA\homm3.h"

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

#define o_ADVEVENT_TXT (*(_TXT_**)0x696A68)
#define Show_SSKill_MSG_YES_NO(frame)
CALL_12(void, __fastcall, 0x4F6C00,o_ADVEVENT_TXT->GetString(115), MBX_OKCANCEL, -1, -1, 0x14, frame, -1, 0, -1, 0, -1, 0);

int __stdcall wandering_scholar_sskill_choice(LoHook *h, HookContext *c)
{
   int skill_id = c->eax; // grab skill to learn
   _Hero_* hero = (_Hero_*)c->ebx; // grab current hero structure
   int skill_level = hero->second_skill[skill_id]; // current skill level
   if (*(BYTE*)(c->ebp + 0x14) == 0 ) // || o_IsMultiPlayerGame // disable for AI
       return EXEC_DEFAULT;
   
   if (hero->second_skill_count == 8 || skill_level==3) // if hero can not learn skill
   {
       c->return_address = 0x4A4B3F; // change return address to learn primary skill
       return NO_EXEC_DEFAULT; // do not execute original code that was overwritten
   }
   
   Show_SSKill_MSG_YES_NO(skill_id * 3 + skill_level + 2 + 1); // is the ID of the frame to use from .DEF file.
   // The extra + 1 is because the skill is not yet increased!
   // equivalent to ... MOVSX ECX,BYTE PTR DS:[EBX+EDI+0C9] ... LEA EDX, [EDI*2 + EDI] ... LEA EAX, [EDX+ECX+2]
   
   if (o_WndMgr->result_dlg_item_id == DIID_OK) // did user click ok?
       hero->LearnSecondarySkill(skill_id,1); // then leanr the skill
   
   c->return_address = 0x4A4B86; // go to exit procedure
   return NO_EXEC_DEFAULT; // do not execute original code that was overwritten
}

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.ScholarChoice_HotA");
           
           _PI-> WriteLoHook (0x4A4AE4, wandering_scholar_sskill_choice);
       }
   }
   return TRUE;
}



After this is fixed, I think I will also upload the mods to the handbook forum. there I can also edit my posts if update is required (here I can not)

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 04, 2017 07:21 PM

@AlexSpl:
I wanted to try your description code...
The source code you have in your post is exactly the code from the dll?
And this is changing every secondary skill description to "Your description here".
So to change eg. only the learningskill description, I have to adjust the code. But to do it I need to understand it first.
I know structures like for loops and arrays (lists/tables). But I'm not familiar with those (int& or char*.

So what exactly does this line?:
char* NewSecSkillDesc[][4] =
I thought it creates an array. But why "[][4]" ? The code would make sense in other languages, without this [][4].

To only change learning description I would do sth like this:
Quote:
char* NewSecSkillDesc[][4] =
{
   "Learning",
   "{Basic Learning}\n\nincreases a hero's earned experience by: HeroLevel / 0.15.",
   "{Advanced Learning}\n\nincreases a hero's earned experience by: 2 * HeroLevel / 0.15.",
   "{Expert Learning}\n\nincreases a hero's earned experience by: 3 * HeroLevel / 0.15."
};

int __stdcall changeLearningDesc(LoHook* h, HookContext* c)
{
int iSkill = 21;
   for (int iLevel = 0; iLevel < 4; ++iLevel)
   {
       *(int*)(0x698D88 + iSkill * 16 + iLevel * 4) = (int&NewSecSkillDesc[iSkill][iLevel];
   }
   return EXEC_DEFAULT;
}

But of course the [][4] thing can not work that way, cause the list does not contain all the skills, it only contains 1 entry. So I thought I could try "[][4][21] = " but that crashed

I even tried this (crashed):
Quote:
int __stdcall changeLearningDesc(LoHook* h, HookContext* c)
{
int iSkill = 21;
*(int*)(0x698D88 + iSkill * 16 + 1 * 4) = (int&"{Basic Learning}\n\nincreases a hero's earned experience by: HeroLevel / 0.15."
*(int*)(0x698D88 + iSkill * 16 + 2 * 4) = (int&"{Basic Learning}\n\nincreases a hero's earned experience by: 2 * HeroLevel / 0.15."
*(int*)(0x698D88 + iSkill * 16 + 3 * 4) = (int&"{Basic Learning}\n\nincreases a hero's earned experience by: 3 * HeroLevel / 0.15."
   return EXEC_DEFAULT;
}


So what is wrong with the codes?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted October 04, 2017 07:40 PM
Edited by AlexSpl at 20:01, 04 Oct 2017.

Try

int __stdcall changeSecSkillDesc(LoHook* h, HookContext* c)
{
   *(int*)0x67DCF0 = (int)NewSecSkillDesc;

   return EXEC_DEFAULT;
}


to replace all descriptions (in this case you need that big array [][4]), or

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

SecSkillDesc LogisticsDesc =
{
   "Logistics",
   "{Basic Logistics}n\nYour description here",
   "{Advanced Logistics}\n\nYour description here",
   "{Expert Logistics}\n\nYour description here"
};

SecSkillDesc EagleEyeDesc =
{
   "Eagle Eye",
   "{Basic Eagle Eye}\n\nYour description here",
   "{Advanced Eagle Eye}\n\nYour description here",
   "{Expert Eagle Eye}\n\nYour description here"
};

int __stdcall changeSecSkillDesc(LoHook* h, HookContext* c)
{
   *(SecSkillDesc*)(*(int*)0x67DCF0 + 2 * 16) = LogisticsDesc;
   *(SecSkillDesc*)(*(int*)0x67DCF0 + 11 * 16) = EagleEyeDesc;

   return EXEC_DEFAULT;
}


to replace some of them (in this case you can delete the array [][4]).

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 04, 2017 11:52 PM

@AlexSpl: Thank you that worked fine

But when I tried to change description in your NewEaglyEye plugin, I noticed the new eagleeye does not work, when I compile it here with your source code =/
For testing I simply copied your code 1:1 added the HotA and patcher stuff to the folder and successfully compiled the dll.
But for some reason it does not work, in combat I get no spells.
When I add the description change, only the description change is active (so the dll is active), but no spells were transfered in combat.

It is set on Release and I did everything the same as for other plugins (and it worked there). So what did you do different?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted October 05, 2017 12:07 AM

For every project where you use homm3.h you should do the following:

Go to Project -> Properties -> Configuration Properties -> C/C++ -> Code Generation, and set Struct Member Alignment to "1 Byte (/Zp1)".

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 05, 2017 01:42 AM

AlexSpl said:
For every project where you use homm3.h you should do the following:
Go to Project -> Properties -> Configuration Properties -> C/C++ -> Code Generation, and set Struct Member Alignment to "1 Byte (/Zp1)".

worked, great

If you have some time left, could you also add example code at handbook forum for:
1) changing spells description
2) adding variable numbers to descrpitions (eg. for ressurection how many hitpoints. I think this is already part of hota/hd, but just to explain what I mean)
3) change colour of text (eg. in WOG the secondary skill name of an modded skill is ~gold colour, so the users can directly see "ah that skill was modded, I should read description again")

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 05, 2017 01:58 AM

@RoseKavalier:
This
Quote:
Properties -> Configuration Properties -> C/C++ -> Code Generation, and set Struct Member Alignment to "1 Byte (/Zp1)".

Also solved the problem with the ScholarChoice plugin

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 05, 2017 02:07 AM

@AlexSpl:
I would like to register at handbook forum.
At the registration page I can set language to english. Is there also another button somewhere to change language to english?

And I can not complete registration, cause I don't know the answer to the security question "&#1053;a&#1087;&#1080;&#1096;&#1080;&#1090;e &#1085;&#1080;&#1082; &#1072;&#1076;&#1084;&#1080;&#1085;&#1072; &#1092;&#1086;&#1088;&#1091;&#1084;&#1072;:" (name of admin). I tried "Bergmann" (saw it often as thread poster) and "admin")

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
RoseKavalier
RoseKavalier


Honorable
Famous Hero
posted October 05, 2017 02:32 AM

admin is VDV_forever

Regarding structure alignment:
I modified homm3.h (and all includes) to have structure alignment (pragma pack/push/pop) so it is not necessary to do set your project every time. When I get a bit more time I will make a repository with them.
____________
My Let's Plays: Metataxer's Revenge - The Empire of The World 2

 Send Instant Message | Send E-Mail | View Profile | PP | Quote Reply | Link
Ben80
Ben80

Tavern Dweller
posted October 05, 2017 05:37 AM

RoseKavalier said:
admin is VDV_forever

Regarding structure alignment:
I modified homm3.h (and all includes) to have structure alignment (pragma pack/push/pop) so it is not necessary to do set your project every time. When I get a bit more time I will make a repository with them.


It would be interesting to see.
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 05, 2017 05:41 PM

I uploaded the plugins ScholarChoice and WitchHutChoice here:
http://handbookhmm.ru/forum/viewtopic.php?p=16693#p16693

Would be great if we would see tons of other plugins
Everything previously done by editing the files itself here in the thread, should be converted to plugins, o you can enable/disable anything you like


@AlexSpl:
If you have time, you could also add a description how to read "settings" from a txt file.
I think it was mentioned in this thread few times. Like for the Plugin "NewTownPortal" we can could the moventpoints costs in within a text file or similar.

And I wonder if baratorch, or someone else, can develope a memory check for multiplayer? For multiplayer it is important that all players are using same plugins with same settings. So I think we need to compare all the memory?
I would like to write to baratorch and request such a feature, but it would be better to directly present him a solution for that, that's why I'm asking here

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Ben80
Ben80

Tavern Dweller
posted October 05, 2017 05:52 PM

Serp said:


And I wonder if baratorch, or someone else, can develope a memory check for multiplayer? For multiplayer it is important that all players are using same plugins with same settings. So I think we need to compare all the memory?
I would like to write to baratorch and request such a feature, but it would be better to directly present him a solution for that, that's why I'm asking here



Mainly he is communicating only with his team members
____________

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 05, 2017 06:15 PM

@Ben80:
Yes he does not reply often. But I reported some HD bugs and sometimes he answered.
So at least he will read my request about this plugin check and the better it is, the higher are chances he will work on it

Since I only play with my friends in LAN, this memory check would not be important for me. But it is important for everyone who is playing online with "strangers" where you can't know what plugins they have installed. And to disable all plugins in multiplayer would be rubbish.
So I hope, even if I do not succeed to convince him, someone else will do



@AlexSpl and RoseKavalier:
I would like to change Estates and Mysticism.
At handbookforum I already found a post of igrik, where I get the hex code to hook into:
_PI->WriteDword(0x63E9C8 + 4, 5);
_PI->WriteDword(0x63E9C8 + 8, 10);
_PI->WriteDword(0x63E9C8 + 12, 15);
link: http://handbookhmm.ru/forum/viewtopic.php?p=16558#p16558
But now I would like to have a percentage value of the total manapoints the hero has.
So eg with expert mysticism he regenerates 10%+5 of his total mana points per day.

So for basic I would do now:
_PI->WriteLoHook(0x63E9C8 + 4, BaseMysticism);

In the link above, igrik is changing the standard mana regeneration to 1 point per hero level per day.
Quote:

// The standard regeneration of the hero's mana is equal to the hero's level (instead of +1)
int __stdcall Y_New_BaseRestoreMana(LoHook* h, HookContext* c)
{
   c->ebx += ((_Hero_*)c->edi)->level;
  return EXEC_DEFAULT;
}
_PI->WriteLoHook(0x4E42D7, Y_New_BaseRestoreMana);


Can someone please explain this code? I would like to be able to use similar code to change mysticism.
What is c? and what is ebx and edi ? How to know when to use what? And how to know when to use * and those brackets?
I also tested what happens when I do
c->ebx += (((_Hero_*)c->edi)->level)*2;
but for some reason it was not the hero_level*2, but some very high number (mana was always filled completely).
Is there a log function? Eg. I would like to print this (((_Hero_*)c->edi)->level)*2 to a logfile, so I can directly see what number it is.

With homm3.h I can get "spell_points", but how exactly put this into the code above? Just replace level with "spell_points/10" ?
And I think "spell_points" is not the max spell points value, right? How to get the max value? Is it always knowledge*10? What if a mod changes max spell_points generation.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
phoenix4ever
phoenix4ever


Supreme Hero
Heroes is love, Heroes is life
posted October 05, 2017 06:23 PM

I love the Witch Hut plug-in, it was something I was sad to see disappear from HD Mod.
Witch Hut and Eagle Eye plug-ins is what I use for now.
Would be great if someone could create a plug-in allowing for 10 skills per hero, but I guess that takes some graphic skills too.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
RoseKavalier
RoseKavalier


Honorable
Famous Hero
posted October 05, 2017 07:35 PM

Serp said:

If you have time, you could also add a description how to read "settings" from a txt file.
I think it was mentioned in this thread few times. Like for the Plugin "NewTownPortal" we can could the moventpoints costs in within a text file or similar.


There are a few ways that I know of.

One is to use the H3 txt loading function. However you need to place the text file in H3/Data/ directory unless you can find a way to tell the game to check in another Directory... I have not yet managed to find how to do this but I know HDmod does it. Maybe Alex has a clue.

The other ways mainly consist of variants of text parsers using fopen() and whatnot.

Serp said:

And I wonder if baratorch, or someone else, can develope a memory check for multiplayer? For multiplayer it is important that all players are using same plugins with same settings. So I think we need to compare all the memory?


You'd pretty much need this

Anyway, this is why my plugins have !Multiplayer

Serp said:

I also tested what happens when I do
c->ebx += (((_Hero_*)c->edi)->level)*2;
but for some reason it was not the hero_level*2, but some very high number (mana was always filled completely).
Is there a log function? Eg. I would like to print this (((_Hero_*)c->edi)->level)*2 to a logfile, so I can directly see what number it is.

To log stuff, the easiest is always to create a textbox and sprintf whatever value you want to look at.

Assembly language works with "registers"...
EAX, EBX, ECX, EDX, EDI, ESI, ESP, EBP
...that each have specific roles in any given function.

What is 'c'?
This is what baratorch programmed as "HookContext". It lets you access each of the registers as well as some other things from within your Hook as they exist before your new function.
You can see the structure definition by looking it up in  patcher_x86.hpp.
c->eax corresponds to EAX register pre-hook
and so on.

What about *?
I already explained a bit, it's used for pointers, for casting in C/C++ etc... I don't have great enough understanding of this to explain well, your best bet is to research it a bit through Google or something.
There are many situations where this is used, try to understand one at a time and go from there.
e.g.
char is used for a single character.
char* is a pointer to a string.
char c = 'a'; // is valid
char* c = "aaaaaa"; // is also valid


If it's not working, either you need to set alignment again or there is a mistake in code or something else I'm not thinking of right now.

Estates values are stored at 0x63EA18 +0 +1 +2 +3.
While I was checking that, the +350 gold bonus is at 0x4E4681. (4 bytes)
____________
My Let's Plays: Metataxer's Revenge - The Empire of The World 2

 Send Instant Message | Send E-Mail | View Profile | PP | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted October 05, 2017 07:40 PM
Edited by AlexSpl at 19:45, 05 Oct 2017.

Quote:
If you have some time left, could you also add example code at handbook forum for:
1) changing spells description

#include "HotA\homm3.h"

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;

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

SpellDesc DisguiseDesc =
{
   "{Disguise}n\nYour description here",
   "{Basic Disguise}\n\nYour description here",
   "{Advanced Disguise}\n\nYour description here",
   "{Expert Disguise}\n\nYour description here"
};

int __stdcall changeSpellDesc(LoHook* h, HookContext* c)
{
   *(SpellDesc*)(o_Spell + SPL_DISGUISE)->description = DisguiseDesc;

   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.NewSpellDescriptions");

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

   return TRUE;
}


Quote:
2) adding variable numbers to descrpitions (eg. for ressurection how many hitpoints. I think this is already part of hota/hd, but just to explain what I mean)

You have to use directives like %s for variable strings, and %d for variable integers in your decription. Make sure that the function, which prints a decription, knows how to handle those directives.

Quote:
3) change colour of text (eg. in WOG the secondary skill name of an modded skill is ~gold colour, so the users can directly see "ah that skill was modded, I should read description again")

You can enclose {your text} in braces.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 05, 2017 07:53 PM

@RoseKavalier:
Thank you.

yes, patcher_x86 was the place were I looked for "ebx" and so on. But it does not help much to see that "ebx" registers "EBX", I still don't know when to use what

And do you have an explanation why
c->ebx += (((_Hero_*)c->edi)->level)*2;
is not herolevel*2 ?
What else to do, to multiply it with 2?

When looking at your scholar code, we could get the hero level with this, right? (not sure about spaces in "_Hero_*hero")
_Hero_*hero = (_Hero_*)c->ebx;
int level = hero->level;
(same for getting spell_points or any other thing contained in the _Hero_ object)

but in both codes we are using c->ebx ... so what is this now?
In second code I would guess c->ebx is something where we can get the hero stats.  But in first code there is "c->ebx +=" so it looks like c->ebx is a number where we simply can add the level from the hero...

Hm.. thinking about it also could be a hex number in both cases, storing all the hero stats. And when we do += we do not simply add the hero level, we add another strange number we got with c->edi, so in the end we have a hex number which contains updated spell point regeneration...

Or are all of my thoughts rubbish?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted October 05, 2017 07:58 PM

Quote:
And do you have an explanation why
c->ebx += (((_Hero_*)c->edi)->level)*2;
is not herolevel*2 ?
What else to do, to multiply it with 2?

What plugin you are talking about?

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Serp
Serp


Known Hero
posted October 05, 2017 08:03 PM

AlexSpl said:
Quote:
And do you have an explanation why
c->ebx += (((_Hero_*)c->edi)->level)*2;
is not herolevel*2 ?
What else to do, to multiply it with 2?

What plugin you are talking about?

see my post from "posted October 05, 2017 06:15 PM"
there I also linked from where I got the code:
http://handbookhmm.ru/forum/viewtopic.php?p=16558#p16558

It is just a code to make standard spell points regeneration equal to hero level. And for testing purpose I wanted to see, if I'm able to multiply it with 2 or add +2 or do any modification of this. But even this "simple task" failed

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Jump To: « Prev Thread . . . Next Thread » This thread is 29 pages long: 1 2 3 4 5 ... 10 20 ... 25 26 27 28 29 · «PREV / NEXT»
Post New Poll    Post New Topic    Post New Reply

Page compiled in 0.1195 seconds