Hex Editing - Guide: Difference between revisions

From Heroes 3 wiki
Jump to navigation Jump to search
(→‎Hex value tables: pretty interesting that you can actually get a "stone gaze" spell scrolls with some hacking, at least in HotA.)
 
(56 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{wip}}
{{wip}}
<span style="float:right; margin-left:8px;">__TOC__</span>


The following article describes some basics of hex edition. Offsets (and code itself in some locations) may vary based on game version.  
The following article describes some basics of hex edition. Offsets (and code itself in some locations) may vary based on game version.  
Line 7: Line 8:
Upper majority of creature stats, abilities, etc. is coded within the *.exe. While it may not be readable or understandable to a layman, in short time one can comprehend a lot of the code and find reason and rhyme in it (or at least, parts of it).  
Upper majority of creature stats, abilities, etc. is coded within the *.exe. While it may not be readable or understandable to a layman, in short time one can comprehend a lot of the code and find reason and rhyme in it (or at least, parts of it).  


To open (and edit) the *.exe files, one needs a hex editor, f.e. [https://sourceforge.net/projects/frhed/ frhed] or another similar software.   
To open (and edit) the *.exe files, one needs a hex editor, f.e. [https://sourceforge.net/projects/frhed/ frhed] or another similar software. I recommend [https://github.com/WerWolv/ImHex ImHex], as it comes with a handy disassembler function built in, as well as a base converter, and similar useful tools.   


== Basics ==
Some data is located with the *.lod files. To open them, you need to use [[Tools#MMArchive|MMArchive]].


= Basics =
Majority of HotA {{wh}} additions are not directly in the h3hota.exe (or h3hota HD.exe), but instead in Hota.dat (and partly in HotA.dll).  
Majority of HotA {{wh}} additions are not directly in the h3hota.exe (or h3hota HD.exe), but instead in Hota.dat (and partly in HotA.dll).  


=== Numbers ===
== Numbers ==
 
All (or almost all) numbers are written in Little Endian - the bytes are placed in reverse order. As an example, 0xA624C (0x before a number signifies it's hexadecimal) in Little Endian is written as 4C 62 0A 00. Note, that the system recognizes that a number is negative based on the fact that it's greater than half the number range: greater than 0x80 for a single byte, and greater than 0x80000000 for a 4-byte value.  
All (or almost all) numbers are written in Little Endian - the bytes are placed in reverse order. As an example, 0xA624C (0x before a number signifies it's hexadecimal) in Little Endian is written as 4C 62 0A 00. Note, that the system recognizes that a number is negative based on the fact that it's greater than half the number range: greater than 0x80 for a single byte, and greater than 0x80000000 for a 4-byte value.  


Line 21: Line 22:
Keep in mind that most (but, surprisingly, not all) lists start at 0, not at 1, so the first element is element 0 and not element 1.
Keep in mind that most (but, surprisingly, not all) lists start at 0, not at 1, so the first element is element 0 and not element 1.


QWORD and DWORD pointers are Little Endian representations of an address within the *.exe file, with 0x400000 added to them because of the way the game reads the code. Therefore if you want the DWORD pointer to find 0x27e484, you write it as 84 e4 67 00. DWORDs use IEE-754, while QWORDs use an 8-byte double-precision IEE-754 value.  
QWORD and DWORD pointers are Little Endian representations of an address within the *.exe file, with 0x400000 added to them because of the way the game reads the code. Therefore if you want the DWORD pointer to find 0x27e484, you write it as 84 e4 27 00. DWORDs use IEE-754, while QWORDs use an 8-byte double-precision IEE-754 value.  


Values followed by zeroes in the same block are 4-byte numbers - this essentially increases their available number range from (in decimal) 0-127 to 0-2147483647.  
Values followed by zeroes in the same block are 4-byte numbers - this essentially increases their available number range from (in decimal) 0-127 to 0-2147483647.  


== Heroes ==
= Heroes =
Heroes are very easy to edit. Hero data is stored in two sets, one containing general hero data and the other containing only hero specialties. Heroes are generally ordered by their faction (Castle, Rampart, Tower, etc.) and then their class (might or magic). Following standard heroes, are all campaign heroes.  
Heroes are very easy to edit. Hero data is stored in two sets, one containing general hero data and the other containing only hero specialties. Heroes are generally ordered by their faction (Castle, Rampart, Tower, etc.) and then their class (might or magic). Following standard heroes, are all campaign heroes.  


=== Hero Data ===
== Hero Data ==
{| class="wikitable"
|-
! colspan=99 | Hex String (Start: {{unk}}, End: {{unk}})


Hero data is written as follows:
|-
| colspan=99 | <span style="color:orange">GG</span>000000 <span style="color:orange">RR</span>000000 <span style="color:blue">HH</span>000000 <span style="color:green">SO</span>000000 <span style="color:green">OL</span>000000 <span style="color:lightgreen">ST</span>000000 <span style="color:lightgreen">TL</span>000000 <span style="color:brown">SB</span>000000 <span style="color:brown">SP</span>000000 <span style="color:gold">U1</span>000000 <span style="color:gold">U2</span>000000 <span style="color:gold">U3</span>000000 <span style="color:teal">PS</span>000000 <span style="color:teal">PL</span>000000 <span style="color:silver">R0 AS CO</span> 00


<span style="color:orange">GG</span>000000 <span style="color:red">RR</span>000000 <span style="color:blue">HH</span>000000 <span style="color:green">SO</span>000000 <span style="color:turquoise">OL</span>000000 <span style="color:teal">ST</span>000000 <span style="color:pink">TL</span>000000 <span style="color:brown">SB</span>000000 <span style="color:grey">SP</span>000000 <span style="color:gold">U1</span>000000 <span style="color:gold">U2</span>000000 <span style="color:gold">U3</span>000000 PS000000 PL000000 <span style="color:silver">R0 </span><span style="color:silver">AS </span><span style="color:silver">CO</span> 00,
|-
! colspan=99 | Description


where:
{{HEXrow|c=orange   |GG| Gender: 00: male, 01: female.}}
* <span style="color:orange">GG</span> = Gender: 00 is male, 01 is female.
{{HEXrow|c=orange    |RR| [[Hero race|Race]]. These are listed alphabetically, from Demon to Vampire. This has no in-game effect or visibility and the extensions preferred to default everyone to human, except [[Gelu]] who gets to be an elf.}}
* <span style="color:red">RR</span> = [[Hero race|Race]]. These are listed alphabetically, from Demon to Vampire. This has no in-game effect or visibility and the extensions preferred to default everyone to human, except [[Gelu]] who gets to be an elf.
{{HEXrow|c=blue     |HH| [[Hero class|Class]]: Classes go in order of factions, and within a faction the might class is listed first. Therefore, 00: Knight, 01: Cleric, 02: Ranger, 03: Druid, etc. Note, that HotA classes essentially "follow" this encoding.}}
* <span style="color:blue">HH</span> = [[Hero class|Class]]. Classes go in order of factions, and within a faction the might class is listed first. Therefore 00 = Knight, 01 = Cleric, 02 = Ranger, 03 = Druid, etc. Note, that HotA classes essentially "follow" this encoding.  
{{HEXrow|c=green     |SO| 1st [[Secondary skill]] ([[Reference IDs#Secondary Skill Reference IDs|ref. ID]]).}}
* <span style="color:green">SO</span> = First skill (ref. ID).
{{HEXrow|c=green    |OL| 1st [[Secondary skill]]'s proficiency level (00: Basic, 01: Advanced, 02: Expert).}}
* <span style="color:turquoise">OL</span> = First skill's proficiency level (00 = Basic, * 01 = Advanced, 02 = Expert).
{{HEXrow|c=lightgreen|ST| 2nd [[Secondary skill]] ([[Reference IDs#Secondary Skill Reference IDs|ref. ID]]). If there is no second skill, instead, FFFFFFFF is used, replacing ST and the zeroes following it.}}
* <span style="color:teal">ST</span> = Second skill (ref. ID). If there is no second skill, instead, FFFFFFFF is used, replacing ST and the zeroes following it.  
{{HEXrow|c=lightgreen|TL| 2nd [[Secondary skill]] level. If there is no second skill, 00 is used (Basic).}}
* <span style="color:pink">TL</span> = Second skill level. If there is no second skill, 00 is used (Basic).  
{{HEXrow|c=brown     |SB| Spell Book. 00: absent, 01: present.}}
* <span style="color:brown">SB</span> = Spell Book. 00 = absent, 01 = present.  
{{HEXrow|c=brown    |SP| Starting [[Spell]] ([[Reference IDs#Spell Reference IDs|ref. ID]]). If no spell is present, FFFFFFFF is used instead.}}
* <span style="color:grey">SP</span> = Spell (ref. ID). If no spell is present, FFFFFFFF is used instead.  
{{HEXrow|c=gold     |U1<br>U2<br>U3| Starting [[creature]] reference IDs.}}
* <span style="color:gold">U1</span>, <span style="color:gold">U2</span>, <span style="color:gold">U3</span> = Starting army unit reference IDs.  
{{HEXrow|c=teal      |PS| Small Portrait DWORD pointer, which leads to plain text name of the portrait in the H3bitmap.lod.}}
* PS = Small Portrait DWORD pointer, which leads to plain text name of the portrait in the H3bitmap.lod.
{{HEXrow|c=teal      |PL| Large Portrait, same as above.}}
* PL = Large Portrait, same as above.  
{{HEXrow|c=silver   |R0| Present by default in all RoE maps. 00: false, 01: true.}}
* <span style="color:silver">R0</span> = allowed in RoE maps by default. 00 = false, 01 = true.  
{{HEXrow|c=silver   |AS| Present by default in all non-RoE maps. 00: false, 01: true.}}
* <span style="color:silver">AS</span> = Present by default in all non-RoE maps. 00 = false, 01 = true.  
{{HEXrow|c=silver   |CO| Campaign-only. 00: false, 01: true.}}
* <span style="color:silver">CO</span> = Campaign-only. 00 = false, 01 = true.
|}


=== Hero Specialties ===
=== Editing HotA Heroes ===
Hota heroes are coded in the HotA.dat. Names written in quotes are coded in plain text. Note, that for editing text itself it's best to use programs such as [https://github.com/sake12/HotA-editor/releases HotA Editor], instead of a direct hex-editing.


Hero specialties are written one by one in the same order as heroes appear in, starting from 0x00278420.
{| class="wikitable"
|-
! colspan=99 | Hex String (Start: 0x23dd, End: 0x9886)


The specialties look as follows:
|-
| colspan=99 | 07 000000 <span style="color:orange">"hero<ref_id>"</span> 12 000000 <span style="color:red">"Heroes\hero_<ref_id>.str"</span> <span style="color:orange">FACTION</span> <span style="color:teal">"#large_portrait_file_name.pcx"</span> 0c000000 <span style="color:teal">"#small_portrait_file_name.pcx"</span> <span style="color:red">XX</span> 000000 <span style="color:turquoise">"Specialty_Name"</span> <span style="color:red">YY</span> 000000 <span style="color:turquoise">"Specialty Bonus: Object"</span> <span style="color:red">ZZ</span>000000 <span style="color:turquoise">"{Full Object}"</span> 0d 0a 0d 0a (number of 0a 0d repetitions may differ) <span style="color:turquoise">"specialty_description"</span> <span style="color:blue">PP</span>000000 <span style="color:blue">"HeroName"</span> <span style="color:red">QQQQQQQQ</span> <span style="color:blue">"Biography"</span> 00000000 01 5c 0000 (number of zeroes may vary) <span style="color:red">GG</span>000000 <span style="color:red">RR</span>000000 <span style="color:red">HH</span>000000 <span style="color:red">SO</span>000000 <span style="color:red">OL</span>000000 <span style="color:red">ST</span>000000 <span style="color:red">TL</span>000000 <span style="color:red">SB</span>000000 <span style="color:red">SP</span>000000 <span style="color:red">U1</span>000000 <span style="color:red">U2</span>000000 <span style="color:red">U3</span>000000 <span style="color:red">PS</span>000000 <span style="color:red">PL</span>000000 <span style="color:red">R0 AS</span> C0 00 00000000 00000000 <span style="color:gold">1m</span>000000 <span style="color:gold">1M</span>000000 <span style="color:gold">2m</span>000000 <span style="color:gold">2M</span>000000 <span style="color:gold">3m</span>000000 <span style="color:gold">3M</span>000000 08000000 <span style="color:orange">I8</span>000000 <span style="color:red">TT</span>000000 <span style="color:red">ID</span>000000 <span style="color:red">AA</span>000000 <span style="color:red">DD</span>000000 <span style="color:red">DM</span>000000 <span style="color:red">U4</span>000000 <span style="color:red">U5</span>000000


<span style="color:red">TT</span>000000 <span style="color:black">ID</span>000000 <span style="color:blue">AA</span>000000 <span style="color:blue">DD</span>000000 <span style="color:blue">DM</span>000000 <span style="color:gold">U4</span>000000 <span style="color:gold">U5</span>000000
|-
! colspan=99 | Description
{{HEXrow|c=orange    |hero<ref_id>| The hero's reference id in decimal, f.e. hero154}}
{{HEXrow|c=red       |Heroes\hero_<ref_id>.str| {{unk}}}}
{{HEXrow|c=orange    |FACTION| Cove heroes: 09 000000 00000000 0b 000000<br>Factory heroes: 09 000000 00000000 00000000 07 000000}}
{{HEXrow|c=teal      |#large_portrait_file_name.pcx<br>#small_portrait_file_name.pcx| # and the appropriate file name, e.g. #HPLP06.pcx}}
{{HEXrow|c=red      |XX| {{unk}}}}
{{HEXrow|c=turquoise |Specialty_Name| e.g. "Sea Dogs" or "Nix"}}
{{HEXrow|c=red      |YY| {{unk}}}}
{{HEXrow|c=turquoise |Specialty Bonus: Object| Refers to the following types of text: "Spell Bonus: Air Shield", "Creature Bonus: Sea Dogs", etc.}}
{{HEXrow|c=red      |ZZ| {{unk}}}}
{{HEXrow|c=turquoise |{Full Object}| Text in curly parentheses {} stating again the specialty, e.g. "{Estates}", or "{Pirates, Corsairs and Sea Dogs}".}}
{{HEXrow|c=turquoise |specialty_description| Text string describing the hero specialty.}}
{{HEXrow|c=blue      |PP| Hero's name's length.}}
{{HEXrow|c=blue      |HeroName| Text string of the hero's name.}}
{{HEXrow|c=red      |QQQQQQQQ| {{unk}}, seems to be some sort of an ID as it seems to be unique for each hero; it is not, however, the reference ID. All QQ values are around 300 (dec).}}
{{HEXrow|c=blue      |Biography| Text string containing the hero's biography.}}
{{HEXrow|c=red      |GG| {{unk}}}}
{{HEXrow|c=red      |RR| {{unk}}}}
{{HEXrow|c=red      |HH| {{unk}}}}
{{HEXrow|c=red      |SO| {{unk}}}}
{{HEXrow|c=red      |OL| {{unk}}}}
{{HEXrow|c=red      |ST| {{unk}}}}
{{HEXrow|c=red      |TL| {{unk}}}}
{{HEXrow|c=red      |SB| {{unk}}}}
{{HEXrow|c=red      |SP| {{unk}}}}
{{HEXrow|c=red      |U1| {{unk}}}}
{{HEXrow|c=red      |U2| {{unk}}}}
{{HEXrow|c=red      |U3| {{unk}}}}
{{HEXrow|c=red      |PS| {{unk}}}}
{{HEXrow|c=red      |PL| {{unk}}}}
{{HEXrow|c=red      |YY| {{unk}}}}
{{HEXrow|c=red      |R0| {{unk}}}}
{{HEXrow|c=red      |AS| {{unk}}}}
{{HEXrow|c=gold      |1m| minimum number of the first creature type in hero's starting army}}
{{HEXrow|c=gold      |1M| maximum number of the first creature type in hero's starting army}}
{{HEXrow|c=gold      |2m| minimum number of the second creature type in hero's starting army}}
{{HEXrow|c=gold      |2M| maximum number of the second creature type in hero's starting army}}
{{HEXrow|c=gold      |3m| minimum number of the third creature type in hero's starting army}}
{{HEXrow|c=gold     |3M| maximum number of the third creature type in hero's starting army}}
{{HEXrow|c=orange    |I8| reference ID + 8 for heroes before ref ID 178 and reference ID + 7 for heroes after ref ID 178 (essentially, 0xb9 is skipped)}}
{{HEXrow|c=red      |TT| {{unk}}}}
{{HEXrow|c=red      |ID| {{unk}}}}
{{HEXrow|c=red      |AA| {{unk}}}}
{{HEXrow|c=red      |DD| {{unk}}}}
{{HEXrow|c=red      |DM| {{unk}}}}
{{HEXrow|c=red      |U4| {{unk}}}}
{{HEXrow|c=red      |U5| {{unk}}}}
|}


<span style="color:red">TT</span> - Specialty type. The following specialty types exist:
== Hero Specialties ==
* 00 = Skill specialty (+5% skill effect per level)
Hero specialties are written one by one in the same order as heroes appear in. Note: Many "possible" specialties don't exist and simply won't do anything; examples include Tactics specialty, Teleport specialty, etc.
* 01 = Basic Unit specialty (+1 speed, +1 Attack and Defense every <unit level> levels)
* 02 = Resource (+1 gems per day, etc.)
* 03 = Spell (+3% efficiency per level for most spells, sometimes special bonuses instead)
* 04 = Static Unit specialty (static bonus to attack, defense, damage, speed, or any combination of them), f.e. Xeron, Kalt, Haart Lich, etc.
* 05 = Speed (Sir Mullich only)
* 06 = Unit Upgrade specialty (Gelu, Dracon, Bidley, etc.)
* 07 = Dragon Specialty (Mutare, Mutare Drake)


<span style="color:black">ID</span> = Reference ID of the specialized in Skill,  Unit, Resource or Spell. (Not needed for Dragon and Speed specialties, where it is 00 and an unnecessary, unused 02, respectively).
{| class="wikitable"
|-
! colspan=99 | Hex String (Start: 0x00278420, End: {{unk}})


<span style="color:blue">AA</span> = Attack bonus for Static Unit specialists (and Mutare).
|-
| colspan=99 | <span style="color:turquoise">TT</span>000000 <span style="color:orange">ID</span>000000 <span style="color:blue">AA</span>000000 <span style="color:blue">DD</span>000000 <span style="color:blue">DM</span>000000 <span style="color:gold">U4</span>000000 <span style="color:gold">U5</span>000000


<span style="color:blue">DD</span> = Defense bonus for Static Unit specialists (and Mutare).
|-
! colspan=99 | Description


<span style="color:blue">DM</span> = Damage bonus for Static Unit specialists (and probably Mutare).  
{{HEXrow|c=turquoise |TT| Specialty type. Specialty types are described in greater detail in the sections below. The following specialty types exist:  
* 00: Skill specialty (+5% skill effect per level)
* 01: Basic Unit specialty (+1 speed, +1 Attack and Defense every <unit level> levels)
* 02: Resource (+1 gems per day, etc.)
* 03: Spell (+3% efficiency per level for most spells, sometimes special bonuses instead)
* 04: Static Unit specialty (static bonus to attack, defense, damage, speed, or any combination of them), e.g. Xeron, Kalt, Haart Lich, etc.
* 05: Speed (Sir Mullich only)
* 06: Unit Upgrade specialty (Gelu, Dracon, Bidley, etc.)
* 07: Dragon Specialty (Mutare, Mutare Drake)
* 08: Frederick's Automaton Explosion specialty.


<span style="color:gold">U4</span> = Second unit (ref. ID) that can be upgraded (only used by Unit Upgrade specialists; otherwise left as 00. Note, that using the same unit twice for Unit Upgrade specialty essentially removes second unit from being upgradable; meanwhile using 00 sets the ID to Pikemen.)
Note: Setting the first byte (TT000000) to FFFFFFFF will ensure the hero has no specialty. This is only used for Adrienne (yes, she ''technically'' has no hero specialty).}}
{{HEXrow|c=orange    |ID| Reference ID of the specialized in Skill,  Unit, Resource or Spell. (Not needed for Dragon and Speed specialties, where it is 00 and an unnecessary, unused 02, respectively).}}
{{HEXrow|c=blue      |AA| Attack bonus for Static Unit specialists (and Mutare).}}
{{HEXrow|c=blue      |DD| Defense bonus for Static Unit specialists (and Mutare).}}
{{HEXrow|c=blue      |DM| Damage bonus for Static Unit specialists (and probably Mutare).}}
{{HEXrow|c=gold     |U4| Second unit (ref. ID) that can be upgraded (only used by Unit Upgrade specialists; otherwise left as 00. Note, that using the same unit twice for Unit Upgrade specialty essentially removes second unit from being upgradable; meanwhile using 00 sets the ID to Pikemen.<br>Note: When using a Unit Upgrade specialist, the reference ID of un-upgraded creatures ought to be used. e.g. Gelu references Archers and Wood Elves, but code naturally allows also for their upgrades to be improved with his specialty. This does not occur the other way around; specifying ID or U2 as an upgraded creature, will make the upgrade impossible for un-upgraded creatures. )}}
{{HEXrow|c=gold      |U5| Resulting unit ref. ID from the upgrade (only for Unit Upgrade specialists).}}
|}


<span style="color:gold">U5</span> = Resulting unit ref. ID from the upgrade (only for Unit Upgrade specialists).
=== 00 - Skill Specialty ===
The code for skill specialties works as follows:
<span style="color:turquoise">XXXXXXXX</span> D805 <span style="color:blue">YYYYYYYY</span> D8 4D FC
where <span style="color:turquoise">XXXXXXXX</span> is a DWORD pointer to a 5% value (in IEEE-754), <span style="color:blue">YYYYYYYY</span> is a DWORD pointer to a value of 1 (again, in IEEE-754)


==== How it works ====
The number of levels is multiplied by the <span style="color:turquoise">XXXXXXXX</span> DWORD pointer, added to the <span style="color:blue">YYYYYYYY</span> DWORD pointer and then the skill bonus is multiplied by it (D8 4D FC).


Note, that using a Unit Upgrade specialist, reference ID of unupgraded creatures ought to be used. F.e., Gelu references Archers and Wood Elves, but code naturally allows also for their upgrades to be improved with his specialty. This does not occur the other way around; specifying ID or U2 as an upgraded creature, will make the upgrade impossible for unupgraded creatures.  
If we want to change the % gain per level, we only need to change the XX value. If we want to instead make the bonus additive (say x% per level, regardless of how much skill itself adds), we can replace the D805YYYYYYYY with 909090909090 (NOP) and replace the D8 4D FC with D8 45 FC.  


Sir Mullich's unit specialty amount (0x02) is located at 0x0E6669.  
Therefore it is possible to have a different bonus for one skill than another.
 
==== Offsets ====
The offsets for each skill specialty bonus are as follows:
: Archery - 0x0E4420
: Armorer - 0x0E45C9
: Diplomacy - 0x0E483C
: Eagle Eye - 0x0E46E0
: Estates - 0x0E464F
: First Aid - 0x0E4BD9
: Intelligence - 0x0E4B69
: Leadership - 0x0E3C81
: Learning - 0x0E4AF9
: Logistics - 0x0E4F1E
: Luck - 0x0E3A2B
: Mysticism - 0x0E41FE
: Necromancy - 0x0E3F92
: Offense - 0x0E4569
: Resistance - 0x0E499C
: Scouting - 0x0E432E
: Sorcery - 0x0E5B61
 
==== Exceptions ====
Specialties for integer-bonuses (Luck, Logistics, Scouting) only have their effect when a full integer is gained from their % bonus.
 
Diplomacy specialty only affects surrender costs.
 
Learning specialty is fully over-written by the Hota.dll.
 
=== 01 - Unit Specialty ===
The scaling factor for a unit specialty is a DWORD pointing to a 5% value (in IEEE-754), located at 0x0e6548.
 
Setting the unit IDs to an upgraded unit will ensure only the upgraded units are affected by the specialty.
 
Ballista and Cannon specialty are Unit specialties.  


=== 02 - Resource Specialty ===
The amount of resources obtained from a gold specialty is saved at 0x0E4681 (as 350).  
The amount of resources obtained from a gold specialty is saved at 0x0E4681 (as 350).  


Only Xyron is specified to add speed thanks to his static unit specialty. This is (most likely) saved at the following address: 0x4b1b3 {{unk}}.  
The code for other resource specialties is possible to edit, but it checks for each resource together and then adds 1 to their growth (therefore its only possible to make all resource specialists increase resource gain by 2, unless a complete re-write of the function is performed).
 
=== 03 - Spell Specialists ===
==== Spell specialty types ====
Spell specialty type table starts at 0x0e6358 (with Fire Wall specialty). Each consecutive byte is then the next spell by spell ID (Firewall, Earthquake, Magic Arrow, etc.) up to Slayer. Each spell specialty can take 6 types:
: 00 - +100% damage (Luna). Note that Hota.dll overwrites this +100% damage with a much more sensible 25%.
: 01 - +50% damage (Ciele).
: 02 - Tier bonus A (+3/+3/+2/+2/+1/+1/+0), such as Weakness specialty or Haste specialty.  
: 03 - Static bonus +2 (Aenain)
: 04 - This one is only used by Fortune (Daremyth, Melodia). In contrary to what BTB claims, it sets the value of the spells effect to 3, regardless of spell's level.
: 05 - Tier bonus B (+4/+3/+2/+1/+0/+0/+0), only used by Coronius as far as I know.
: 06 - Scaling bonus.  


Note, that many "possible" specialties don't exist and simply won't do anything; examples include Tactics specialty, Teleport specialty, etc.  
If a spell does not belong to the spell table, the scaling bonus is applied (for example this applies to the Hypnotize specialist, Astral).  


"But what if we want to change the specialty type for a spell like Hypnotize?"


== Editing HotA Heroes ==
We can extend the table by changing 0x0e6296 (equal to 0x2a by default) to a different value, which corresponds to the number of spells in the table -1. If we extend the table, the next specialties will be those for the next spells by spell ID. We have a total of 13 bytes of nop (90), so the last spell specialty we can code this way is Summon Air Elemental. Remember to update all specialties created this way! You shouldn't just leave the nops (90) in the middle of the table!


Hota heroes are coded in the HotA.dat, in the following order: (names written in quotes are coded in plain text)
"But what about Victoria, the Land Mine specialist?", you may ask. Well, I'm here to give answers:  


07 000000 "hero<ref_id>" 12 000000 "Heroes\hero_<ref_id>.str" FACTION "#large_portrait_file_name.pcx" 0c000000 "#small_portrait_file_name.pcx" XX 000000 "Specialty_Name" YY 000000 "Specialty Bonus: Object" ZZ000000 "{Full Object}" 0d 0a 0d 0a (number of 0a 0d repetitions may differ) "specialty_description" PP000000 "HeroName" QQQQQQQQ "Biography" 00000000 01 5c 0000 (number of zeroes may vary) GG000000 RR000000 HH000000 SO000000 OL000000 ST000000 TL000000 SB000000 SP000000 U1000000 U2000000 U3000000 PS000000 PL000000 R0 AS C0 00 00000000 00000000 1m000000 1M000000 2m000000 2M000000 3m000000 3M000000 08000000 I8000000 TT000000 ID000000 AA000000 DD000000 DM000000 U4000000 U5000000, where:
The command '''lea eax, [esi-0Dh]''' located at 0x0e6291 finds the spell ID of firewall (0d) and chooses it as the first spell on the list of specialties ''(remember? The one that starts at 0x0e6358?)''. By changing it to '''lea eax, [esi-0Bh]''', we can change the first spell ID to 0x0B, or Land Mine. ''Notice, that this reduces the last spell specialty to Summon Earth Elemental, but I doubt anyone will miss the Summon Water Elemental and Summon Air Elemental specialties.''


* FACTION = 09 000000 00000000 0b 000000 for Cove heroes and 09 000000 00000000 00000000 07 000000 for Factory heroes,
Next, we have to increase the number of spells in the list by 2 (located at 0x0e6296), and then move the entire spell specialty table, 2 bytes each, because now it starts at 0x0e6358 with Land Mine (and still follows by spell ID).
* #large_portrait_file_name.pcx, #small_portrait_file_name.pcx: # and the appropriate file name, f.e. #HPLP06.pcx 
* XX = {{unk}}
* Specialty_Name is f.e. "Sea Dogs" or "Nix".
* YY = {{unk}}
* Specialty Bonus: Object refers to the following types of text: "Spell Bonus: Air Shield", "Creature Bonus: Sea Dogs", etc.
* ZZ = {{unk}}
* {Full Object} is a text in curly parentheses {} stating again the specialty, f.e. "{Estates}", or "{Pirates, Corsairs and Sea Dogs}".
* specialty_description: Plain text description.
* PP = Hero's name's length.
* QQQQQQQQ = {{unk}}, seems to be some sort of an ID as it seems to be unique for each hero; it is not, however, the reference ID. All QQ values are around 300 (dec).
* 1m = minimum number of the first creature type in hero's starting army
* 1M = maximum number of the first creature type in hero's starting army
* 2m = minimum number of the second creature type in hero's starting army
* 2M = maximum number of the second creature type in hero's starting army
* 3m = minimum number of the third creature type in hero's starting army
* 3M = maximum number of the third creature type in hero's starting army
* I8 = reference ID + 8 for heroes before ref ID 178 and reference ID + 7 for heroes after ref ID 178 (essentially, 0xb9 is skipped)


Heroes in HotA.dat start at 0x23dd and end at 0x9886. Note, that for editing text itself it's best to use programs such as [https://github.com/sake12/HotA-editor/releases HotA Editor], instead of a direct hex-editing.
"And what about Eovacius? And Zilare?"


Haven't looked at them yet but I believe they may be hard-coded.


== Editing HotA Creatures ==
The specialty types can be changed by altering their commands. Each specialty type (00, 01, and so on) have a DWORD pointer to their appropriate code located in a 28-byte long table starting at 0x0e633c.
 
==== Changing Tier bonuses ====
Let's say we want to make Olema's Weakness specialty remotely usable, but we still want it to be a tier-based specialty. We can change the bonuses the spell provides for each unit tier in a 28-byte long table that starts at 0x23eaa8. Each 4 bytes corresponds to the next unit level.
 
A similar table for Coronius' specialty type starts at 0x23eac4 (immediately afterwards) and works the same way.
 
==== Changing the static bonus ====
At 0x0e62e6 the value 0x02 determines the static bonus (such as the one Disrupting Ray specialists get).
 
==== Changing the scaling bonus ====
At 0x0e631f the DWORD pointer finds an IEEE-754 double precision value for 3% (base game). Replacing this pointer with another one finds a different % bonus.
 
If you don't want the scaling specialties to divide their bonus by unit level, replace f7 f9 at 0xe630b with 90 90 (nop-ing out the division).
 
==== Specialties that don't work ====
Several specialties don't work because no specialty type can increase their bonus:
* Curse
* Anti-Magic
* Dispel
* Slow {{unk}}, but it would probably be way too strong anyway;
* Berserk
* Blind
* Teleport
* Remove Obstacle.
 
=== 04 - Unit (static) ===
Only Xeron is specified to add speed thanks to his static unit specialty. This is (most likely) saved at the following address: 0x4b1b3 {{unk}}.
 
Setting the unit IDs to an upgraded unit will ensure only the upgraded units are affected by the specialty.


While most statistics of base game creatures can be edited rather effortlessly (using MMArchive to unpack H3bitmap.lod or HotA_lng.lod), HotA creatures cannot be edited this way. Their data is stored at the beginning of HotA.dat, as follows:
=== 05 - Speed specialty ===
Sir Mullich's unit specialty amount (0x02) is located at 0x0E6669.  


08 000000 "most<ref_id>" 17 000000 "Monsters\monster<ref_id>.str" 09 000000 00000000 04 000000 "name_abbreviation" KK000000 "<animation_filename>.def" L1000000 "Monster_name (singular)" L2000000  "Monster name (plural)" 00000000 00000000 00000000 00000000 01 74 0000 TT 000000 UL 000000 0c556700  00556700 NNNNNNNN 80da9e03 60da9e03 30da9e03 WC000000 MC000000 OC000000 SC000000 CC000000 GeC000000 GC000000 FV000000 AV000000 GV000000 HG000000 HP000000 SP000000 AT000000 DF000000 DmgL000000 DmgH000000 SH000000 SN000000 OO000000 PP000000 QQ000000 RR000000 VV000000 WW000000 XX000000 YY000000 ZZ000000
=== 06 - Unit Upgrade specialty ===
These specialties calculate the upgrade cost automatically, with the same function that calculates upgrade costs in all other cases. If "unupgraded" unit is more expensive than the upgraded one, the message about necessary costs wil appear, but no cost will be stated and the conversion will be free.  


* monst<ref_id> is monster's reference id in decimal, f.e. monst154
Setting the unit IDs to an upgraded unit will ensure only the upgraded units are affected by the specialty.  
* name_abbreviation is a 4 letter abbreviation of the monster name. Never appears anywhere ever again. Note that not all abbreviations are just beginning or consonants, f.e. Haspids are written as "aspi" and nix as "nixx". This abbreviation doesn't seem to have to be unique, as Sea Serpent and Haspids have the same 4 letters here.  It is worth pointing out, that base game creatures also use 4-letter abbreviations in a similar table located in h3hota HD.exe around 0x275500
* KK is the length of the animation_filename + 4 (and therefore the length of the entire "animation_filename.def"
* <animation_filename>.def  is the file name of the set of animations, saved as .def in HotA.lod or HotA.lod.
* L1 is the length of the monster name (singular)
* L2 is the length of the monster name (plural)
* 0x74 codes as "t" in ASCII
* TT is the reference id of the town the monster belongs to. 0x09 for Cove, 0x0a for Factory, FFFFFFFF for Neutrals and I bet if HotA ever releases a new town, it will have 0x0b as its faction code.
* UL is the unit level -1 (sidenote: this is an example of numbers being used in a list with a zero-based numbering). FFFFFFFF for monsters with no level (f.e. Citadel / Castle Towers)
* 0c556700 (and 00556700) point to a similar table with creature sprite, text and other references in h3hota HD.exe and is probably used to insert the HotA.dat's creature table into this part of the exe.
* NNNNNNNN is equal to 0x10 for all Cove creatures (except the Sea Dog), Leprechauns and Satyrs, but can take different values: f.e. 65040200 for Cannon, 14100100 for Sea Dogs, 12040000 for Fangarms, 00040200 for Steel Golems... I don't know what these values represent, especially since they have such different magnitudes. (Perhaps they're a bitwise monster description being encoded into bytes.) {{unk}}
* 80da9e03, 60da9e03, 30da9e03 - {{unk}}
* WC is the cost of wood necessary to recruit the creature
* MC is the cost of mercury necessary to recruit the creature
* OC is the cost of ore necessary to recruit the creature
* SC is the cost of sulphur necessary to recruit the creature
* CC is the cost of crystals necessary to recruit the creature
* GeC is the cost of gems necessary to recruit the creature
* GC is the cost of gold necessary to recruit the creature. Note that all aforementioned cost values have 4 bytes to play with, so the maximum unit cost is 2147483647 gold (or of any resource).
* FV is the Fight Value
* AV is the AI Value
* GV is the Growth
* HG is the Horde Growth
* HP is, surprisingly, hit points
* SP is speed
* AT is attack
* DF is defense
* DmgL is low end of the damage range
* DmgH is the high end of the damage range
* SH is the number of shots per battle
* SN is the number of spell casts per battle
* OO, PP, QQ, RR, VV, WW, XX, YY, ZZ - {{unk}}. Sometimes they take up 36 (!) bytes (such as for Ayssids), and sometimes only 8. I suspect they reference some sort of abilities the creatures have, or their descriptions.  


=== 07 - Dragon specialty ===
I believe Mutare's bonus is specified within her specialty block.


When using custom functions or editing original code, note that all HotA (as well as some SoD monsters) have reference ID above 80, and therefore cannot be checked for using a simple check command, such as 83 FA ID. Instead, you have to use a longer command that accepts a 4-byte value (for EDX that would be 81 FA ID000000).  
= Creatures =
== Editing HotA Creatures ==
While most statistics of base game creatures can be edited rather effortlessly (using MMArchive to unpack H3bitmap.lod or HotA_lng.lod), HotA creatures cannot be edited this way. Their data is stored at the beginning of HotA.dat. When using custom functions or editing original code, note that all HotA (as well as some SoD monsters) have reference ID above 80, and therefore cannot be checked for using a simple check command, such as 83 FA ID. Instead, you have to use a longer command that accepts a 4-byte value (for EDX that would be 81 FA ID000000).


{| class="wikitable"
|-
! colspan=99 | Hex String (Start: {{unk}}, End: {{unk}})


== Editing Creature Abilities ==
|-
| colspan=99 | 08 000000 <span style="color:orange">"monst<ref_id>"</span> 17 000000 <span style="color:red">"Monsters\monster<ref_id>.str"</span> 09 000000 00000000 04 000000 <span style="color:orange">"name_abbreviation"</span> <span style="color:teal">KK</span>000000 <span style="color:teal">"<animation_filename>.def"</span> <span style="color:blue">L1</span>000000 <span style="color:blue">"Monster_name (singular)"</span> <span style="color:blue">L2</span>000000  <span style="color:blue">"Monster name (plural)"</span> 00000000 00000000 00000000 00000000 01 74 0000 <span style="color:orange">TT</span> 000000 <span style="color:green">UL</span> 000000 <span style="color:grey">0c556700  00556700</span> <span style="color:turquoise">F1 F2 F3 F4</span> <span style="color:red">80da9e03 60da9e03 30da9e03</span> <span style="color:gold">WC</span>000000 <span style="color:gold">MC</span>000000 <span style="color:gold">OC</span>000000 <span style="color:gold">SC</span>000000 <span style="color:gold">CC</span>000000 <span style="color:gold">GeC</span>000000 <span style="color:gold">GC</span>000000 <span style="color:green">FV</span>000000 <span style="color:green">AV</span>000000 <span style="color:green">GV</span>000000 <span style="color:green">HG</span>000000 <span style="color:green">HP</span>000000 <span style="color:green">SP</span>000000 <span style="color:green">AT</span>000000 <span style="color:green">DF</span>000000 <span style="color:green">DmgL</span>000000 <span style="color:green">DmgH</span>000000 <span style="color:green">SH</span>000000 <span style="color:green">SN</span>000000 <span style="color:red">OO</span>000000 <span style="color:purple">mm</span>000000 <span style="color:purple">MM</span>000000 <span style="color:red">RR</span>000000 <span style="color:red">VV</span>000000 <span style="color:red">WW</span>000000 <span style="color:red">XX</span>000000 <span style="color:red">YY</span>000000 <span style="color:red">ZZ</span>000000
 
|-
! colspan=99 | Description


=== Magic Channel ([[Familiars]]) ===  
{{HEXrow|c=orange    |monst<ref_id>| The monster's reference id in decimal, f.e. monst154}}
{{HEXrow|c=red      |Monsters\monster<ref_id>.str| {{unk}}}}
{{HEXrow|c=orange    |name_abbreviation| The 4 letter abbreviation of the monster name. Never appears anywhere ever again. Note that not all abbreviations are just beginning or consonants, f.e. Haspids are written as "aspi" and nix as "nixx". This abbreviation doesn't seem to have to be unique, as Sea Serpent and Haspids have the same 4 letters here.  It is worth pointing out, that base game creatures also use 4-letter abbreviations in a similar table located in h3hota HD.exe around 0x275500}}
{{HEXrow|c=teal      |KK| The length of the animation_filename + 4 (and therefore the length of the entire "animation_filename.def"}}
{{HEXrow|c=teal      |<animation_filename>.def| The file name of the set of animations, saved as .def in HotA.lod or HotA.lod.}}
{{HEXrow|c=blue      |L1| The length of the monster name (singular)}}
{{HEXrow|c=blue      |Monster_name (singular)| Text string of the singular monster's name.}}
{{HEXrow|c=blue      |L2| The length of the monster name (plural)}}
{{HEXrow|c=blue      |Monster_name (plural)| Text string of the plural monster's name.}}
{{HEXrow|c=orange    |TT| The reference id of the town the monster belongs to. 0x09 for Cove, 0x0a for Factory, FFFFFFFF for Neutrals and I bet if HotA ever releases a new town, it will have 0x0b as its faction code.}}
{{HEXrow|c=green    |UL| The unit level -1 (sidenote: this is an example of numbers being used in a list with a zero-based numbering). FFFFFFFF for monsters with no level (f.e. Citadel / Castle Towers)}}
{{HEXrow|c=grey      |0c556700<br>(and 00556700)| These point to a similar table with creature sprite, text and other references in h3hota HD.exe and is probably used to insert the HotA.dat's creature table into this part of the exe.}}
{{HEXrow|c=turquoise |F1| The first creature ability flag
* 01: 2-hex unit
* 02: Flying
* 04: Ranged Attack
* 08: Fire breath
* 10: Living
* 20: Can attack city walls (cyclops, cannon)
* 40: War machine
* 80: Slayer (Basic)}}
{{HEXrow|c=turquoise |F2| The second creature ability flag
* 01: Slayer (advanced)
* 02: Slayer (expert)
* 04: Mind immunity
* 08: shoots beam (?)
* 10: No melee penalty
* 20: {{unk}}
* 40: Fire immunity
* 80: Attacks twice}}
{{HEXrow|c=turquoise |F3| The third creature ability flag
* 01: No enemy retaliation
* 02: Morale has no effect
* 04: Undead
* 08: AOE melee attack (Hydra)
* 10: AOE ranged attack (Magog), AI flag only.
* 20: {{unk}}
* 40: {{unk}}
* 80: {{unk}}}}
{{HEXrow|c=turquoise |F4| The fourth creature ability flag
* 01: {{unk}}
* 02: {{unk}}
* 04: {{unk}}
* 08: {{unk}}
* 10: {{unk}}
* 20: {{unk}}
* 40: {{unk}}
* 80: Dragon (for the sake of Mutare's specialty and vial of dragon blood)}}
{{HEXrow|c=red      |80da9e03<br>60da9e03<br>30da9e03|{{unk}}}}
{{HEXrow|c=gold      |WC| Wood Cost to recruit the creature}}
{{HEXrow|c=gold      |MC| Mercury Cost to recruit the creature}}
{{HEXrow|c=gold      |OC| Ore Cost to recruit the creature}}
{{HEXrow|c=gold      |SC| Sulfur Cost to recruit the creature}}
{{HEXrow|c=gold      |CC| Crystal Cost to recruit the creature}}
{{HEXrow|c=gold      |GeC|Gem Cost to recruit the creature}}
{{HEXrow|c=gold      |GC| Gold Cost to recruit the creature. Note that all aforementioned cost values have 4 bytes to play with, so the maximum unit cost is 2147483647 gold (or of any resource).}}
{{HEXrow|c=green    |FV| Fight Value}}
{{HEXrow|c=green    |AV| AI Value}}
{{HEXrow|c=green    |GV| Growth}}
{{HEXrow|c=green    |HG| Horde Growth}}
{{HEXrow|c=green    |HP| Hit Points}}
{{HEXrow|c=green    |SP| Speed}}
{{HEXrow|c=green    |AT| Attack}}
{{HEXrow|c=green    |DF| Defense}}
{{HEXrow|c=green    |DmgL| The low end of the damage range}}
{{HEXrow|c=green    |DmgH| The high end of the damage range}}
{{HEXrow|c=green    |SH| Number of shots per battle}}
{{HEXrow|c=green    |SN| Number of spell casts per battle}}
{{HEXrow|c=red      |OO| {{unk}}}}
{{HEXrow|c=purple    |mm| Minimum number of units when randomly spawned by the map generator}}
{{HEXrow|c=purple    |MM| Maximum number of units when randomly spawned by the map generator.}}
{{HEXrow|c=red      |QQ<br>RR<br>VV<br>WW<br>XX<br>YY<br>ZZ| {{unk}}. Sometimes they take up 28 (!) bytes (such as for Ayssids), and sometimes don't appear at all. I suspect they reference some sort of abilities the creatures have, or their descriptions.}}
|}


== Editing Creature Abilities ==
=== Magic Channel ([[Familiars]]) ===
Magic channel's applicable unit ID is defined at 0x1a24f6. The game uses a frankly ridiculous method of dividing by 5 (let's just say that it purposefully calls and uses a value 1717986919 to calculate 20%). Btb2 analyzed it and found a way to alter the percentage to 50% or 100% (by ignoring the horrible function before it and simply taking the mana value or moving it by 1 byte). Replace:  
Magic channel's applicable unit ID is defined at 0x1a24f6. The game uses a frankly ridiculous method of dividing by 5 (let's just say that it purposefully calls and uses a value 1717986919 to calculate 20%). Btb2 analyzed it and found a way to alter the percentage to 50% or 100% (by ignoring the horrible function before it and simply taking the mana value or moving it by 1 byte). Replace:  


Line 176: Line 368:
* 0x1A249F:  b8 *67666666* c7 45 1c 02000000 f7 e9 8b 4d 9c *d1 fa* 8b c2 c1 e8 1f 03 d0
* 0x1A249F:  b8 *67666666* c7 45 1c 02000000 f7 e9 8b 4d 9c *d1 fa* 8b c2 c1 e8 1f 03 d0


The b8 XXXXXXXX (bolded above) function calls a hexadecimal value (note that it's in Little Endian) and saves it. The code then uses "d1 fa" (bolded above) to divide edx by 2 before it is further used. C1 E8 1F is simply a division by 2^31 of the value. Yes, that is why the rounding may be a bit off for Magic Channel. Now let's consider replacing:  
The b8 XXXXXXXX (bolded above) function calls a hexadecimal value (note that it's in Little Endian) and saves it. The code then uses "d1 fa" (emboldened above) to divide edx by 2 before it is further used. C1 E8 1F is simply a division by 2^31 of the value. Yes, that is why the rounding may be a bit off for Magic Channel. Now let's consider replacing:  
* 67666666 with our custom value (for now let's imagine it's 56555555)
* 67666666 with our custom value (for now let's imagine it's 56555555)
* d1 fa with 90 90 (two nop or non-coding functions, so we basically removed this part of the code)
* d1 fa with 90 90 (two nop or non-coding functions, so we basically removed this part of the code)
Line 186: Line 378:
The function also calls 0x1A2498 for the minimum mana value for which Magic Channel may apply. This is equal to the value of D (0x05 in base game, 0x03 in the example above).  
The function also calls 0x1A2498 for the minimum mana value for which Magic Channel may apply. This is equal to the value of D (0x05 in base game, 0x03 in the example above).  


 
= Buildings =
== Editing Buildings ==
 
Building names and descriptions (excluding HotA) are saved in BldgSpec.txt and BldgNeut.txt. Building requirements can be altered by changing their dependency tables. Address of each dependency table is located at:  
Building names and descriptions (excluding HotA) are saved in BldgSpec.txt and BldgNeut.txt. Building requirements can be altered by changing their dependency tables. Address of each dependency table is located at:  
* 0x0EB816 - Castle
* 0x0EB816 - Castle
Line 204: Line 394:
Building costs can be changed in Building.txt.  
Building costs can be changed in Building.txt.  


=== HotA buildings ===
== HotA buildings ==
 
Building names and descriptions for HotA are saved in HotA.dat and can be edited as a text edit using f.e. the aforementioned HotA Editor.  
Building names and descriptions for HotA are saved in HotA.dat and can be edited as a text edit using f.e. the aforementioned HotA Editor.  


Building costs for HotA are saved in HotA.dat. The building names appear before the building costs. Each building cost contains of 28 bytes, each 4 bytes representing a 4-byte little endian number of cost for each resource (Wood, Mercury, Ore, Sulfur, Crystal, Gems, Gold). Note, that some buildings have text and description, but no written cost (either replaced with 0s or simply not having any space devoted to them). An example is Mana Generator. For now it is not known how to edit the cost of these buildings (and therefore the cost of the Mana Generator remains a mystery).   
Building costs for HotA are saved in HotA.dat. The building names appear before the building costs. Each building cost contains of 28 bytes, each 4 bytes representing a 4-byte little endian number of cost for each resource (Wood, Mercury, Ore, Sulfur, Crystal, Gems, Gold). Note, that some buildings have text and description, but no written cost (either replaced with 0s or simply not having any space devoted to them). An example is Mana Generator. For now it is not known how to edit the cost of these buildings (and therefore the cost of the Mana Generator remains a mystery).   


 
== Resource Silos ==
=== Resource Silos ===
 
Resource Silo yield tables are located at 0x288F04. Each resource value is mentioned for each town, one by one, in 4-byte values (order of resources is Wood, Mercury, Ore, Sulphur, Crystal, Gems, Gold) with towns going in order.  
Resource Silo yield tables are located at 0x288F04. Each resource value is mentioned for each town, one by one, in 4-byte values (order of resources is Wood, Mercury, Ore, Sulphur, Crystal, Gems, Gold) with towns going in order.  


Line 219: Line 406:
The Resource Silo table is called for in exe a few times, but HotA.dll overwrites all (or most) of these calls at 0xd37ae and 0xd37ce.  As of 12:19, 19 September 2024 (UTC), it is not known how to alter the Resource Silo values for Cove and Factory. No specific offset or function have been identified.  {{unk}}.  
The Resource Silo table is called for in exe a few times, but HotA.dll overwrites all (or most) of these calls at 0xd37ae and 0xd37ce.  As of 12:19, 19 September 2024 (UTC), it is not known how to alter the Resource Silo values for Cove and Factory. No specific offset or function have been identified.  {{unk}}.  


 
= Artifacts =
 
== Artifacts ==
 
All stats given by artifacts are written into a table at 0x23e758, 4 bytes for each artifact (Attack, Defense, Power, Knowledge).  
All stats given by artifacts are written into a table at 0x23e758, 4 bytes for each artifact (Attack, Defense, Power, Knowledge).  


The artifact traits are specified in artitrats.txt, while artifact pick-up events are defined in artevent.txt (both im Hota_lng.lod).  
The artifact traits are specified in artraits.txt, while artifact pick-up events are defined in artevent.txt (both in Hota_lng.lod).  


=== Combination Artifacts ===
Interference amount of the Plate of the Dying Light is specified as a IEE-754 floating point value at 0x1d40c8 in Hota.dll


== Combination Artifacts ==
Combination artifact's components are specified at a few functions, starting at 0x04c63d. For further reading see BTB2's guide (linked below, as External Link #3). Be aware! BTB2's guide is either wrong or outdated! His method of removing components seems to work correctly, however, most likely due to HotA putting their combination artifacts in HotA.dll to push them in between base game combination artifacts, or for another reason, ''his method of increasing the number of items does NOT work''.  
Combination artifact's components are specified at a few functions, starting at 0x04c63d. For further reading see BTB2's guide (linked below, as External Link #3). Be aware! BTB2's guide is either wrong or outdated! His method of removing components seems to work correctly, however, most likely due to HotA putting their combination artifacts in HotA.dll to push them in between base game combination artifacts, or for another reason, ''his method of increasing the number of items does NOT work''.  


Line 235: Line 420:
:0x4c8c8 90909090 90909090  -> eb 06..(skip following code)...6a '''XX''' (ref item ID) 6a '''YY''' (2nd ref item ID).....eb 8d (jump backwards 115 bytes)
:0x4c8c8 90909090 90909090  -> eb 06..(skip following code)...6a '''XX''' (ref item ID) 6a '''YY''' (2nd ref item ID).....eb 8d (jump backwards 115 bytes)


Replace bolded text with your appropriate artifact IDs. Remember to also update the number of components (in this example at 0x04C861).  
Replace emboldened text with your appropriate artifact IDs. Remember to also update the number of components (in this example at 0x04C861).  


Note, that the method described above only works for a jump of 125 bytes or less. Gladly, there's a few other empty spaces that can be used for adding extra components:  
Note, that the method described above only works for a jump of 125 bytes or less. Gladly, there's a few other empty spaces that can be used for adding extra components:  
Line 251: Line 436:
Note, that if you're using HotA, it's much safer to just edit appropriate artifact reference IDs and add other appropriate components (or replace the resulting artifact) by editing Hota.dat (see: [https://heroes.thelazy.net/index.php?title=Hex_Editing_-_Guide/artsinfo0|HotA Artifacts - artsinfo0]
Note, that if you're using HotA, it's much safer to just edit appropriate artifact reference IDs and add other appropriate components (or replace the resulting artifact) by editing Hota.dat (see: [https://heroes.thelazy.net/index.php?title=Hex_Editing_-_Guide/artsinfo0|HotA Artifacts - artsinfo0]


=== Making new Combination Artifacts ===
== Making new Combination Artifacts ==


For now it is wholly unknown how to do it. HotA devs seem to now their way around it.{{unk}} See below.  
For now it is wholly unknown how to do it. HotA devs seem to know their way around it.{{unk}} See below.  


What might work is repeating a function identical to that of another artifact with different properties using some empty space. Requires further testing.  
What might work is repeating a function identical to that of another artifact with different properties using some empty space. Requires further testing.  


 
== HotA Artifacts ==
=== HotA Artifacts ===
 
Hota's new artifacts are coded in the Hota.dat. To edit their properties, you need to edit their text (or use hexadecimal values for ASCII to match their text in hex editing). Artifacts are coded as follows:  
Hota's new artifacts are coded in the Hota.dat. To edit their properties, you need to edit their text (or use hexadecimal values for ASCII to match their text in hex editing). Artifacts are coded as follows:  


==== artsinfo0 ====
=== artsinfo0 ===
 
This part of the file includes partial data on all HotA artifacts, written as follows:  
This part of the file includes partial data on all HotA artifacts, written as follows:  


Line 279: Line 461:
* 2 - Add Knowledge
* 2 - Add Knowledge
* 7 - Different Ability, Y = AI value {{unk}} (it's described as "points")
* 7 - Different Ability, Y = AI value {{unk}} (it's described as "points")
* 8 - Movement artefact?
* 8 - Movement artifact?
* 13 - Restrict spells; Y = 1 for Cloak of Silence, 4 for Ring of Oblivion
* 13 - Restrict spells; Y = 1 for Cloak of Silence, 4 for Ring of Oblivion
* 16 - Add daily resource growth, Y = amount, Z = resource type (0 = wood, 6 = gold)
* 16 - Add daily resource growth, Y = amount, Z = resource type (0 = wood, 6 = gold)
Line 312: Line 494:
Sadly, new combination artifacts can't simply be added this way.
Sadly, new combination artifacts can't simply be added this way.


=== art<ref_ID> ===
== art<ref_ID> ==
 
art<ref_ID> entries in HotA.dat (as visible in the Hota.editor.exe) can be used to alter an artifact's name, adventure map event text, description, slot type and rarity class (treasure, minor, major, relic). Here is also the true artifact bonus data coded. Note that the Reference ID is in decimal.  
art<ref_ID> entries in HotA.dat (as visible in the Hota.edtior.exe) can be used to alter an artifact's name, adventure map event text, description, slot type and rarity class (treasure, minor, major, relic). Here is also the true artifact bonus data coded. Note that the Reference ID is in decimal.  


:gold_price <nowiki>#</nowiki> cost - (cost of 0 is used if an artifact cannot normally appear, f.e. if it's a Combination Artifact.  
:gold_price <nowiki>#</nowiki> cost - (cost of 0 is used if an artifact cannot normally appear, f.e. if it's a Combination Artifact.  
Line 325: Line 506:
:0 <nowiki>#</nowiki> spell power bonus (_int8_)
:0 <nowiki>#</nowiki> spell power bonus (_int8_)
:0 <nowiki>#</nowiki> knowledge bonus (_int8_)
:0 <nowiki>#</nowiki> knowledge bonus (_int8_)
= Creature Banks =
The order the banks appear in is as follows:
# Cyclops Stockpile
# Dwarven Treasury
# Griffin Conservatory
# Imp Cache
# Medusa Stores
# Naga Bank
# Dragon Fly Hive
# Shipwreck
# Derelict Ship
# Crypt
# Dragon Utopia
Note, that after changing these values, you still have to edit the remaining bank data in CrBanks.txt. HotA banks, except for the Ancient Altar, are all defined within the Hota.dat file, as crbank21, 22, and so on.
{| class="wikitable"
|-
! colspan=99 | Hex String (Start: 0x2702A0, End: {{unk}})
|-
| colspan=99 | <span style="color:orange">U1</span>000000 <span style="color:orange">U2</span>000000 <span style="color:orange">U3</span>000000 <span style="color:orange">U4</span>000000 ... FFFFFFFF 00000000 00000000 00000000
|-
! colspan=99 | Description
{{HEXrow|c=orange    |U1<br>U2<br>U3<br>U4...| Unit IDs for guards. U2-U4 etc. are optional. Note, that the 12 bytes of 00 do not appear after the last defined creature bank (Dragon Utopia).}}
|}
After all of the creature banks have been defined, the reward creatures (and creatures only!) are defined as follows:
{| class="wikitable"
|-
! colspan=99 | Hex String (Start: {{unk}}, End: {{unk}})
|-
| colspan=99 | FFFFFFFF <span style="color:blue">R1</span>000000 <span style="color:blue">R2</span>000000 <span style="color:blue">R3</span>000000 ...
|-
! colspan=99 | Description
{{HEXrow|c=blue      |R1<br>R2<br>R3...| Unit IDs for reward creature for the first bank. R2-R3 etc. are the reward creatures for subsequent creature banks.}}
|}
== The Pyramid ==
The pyramid is defined separately:
: 0xa3fa2:6a '''02''' 6a '''14''' 6a '''7d''' (52 8d4508 53 50) 6a '''74''';
: 0xa3fb6: '''28''' 00 00 00
Where:
* 02 is the number of stacks of Diamond Golems
* 14 is the number of Diamond Golems (in total)
* 7d is the unit ID of Diamond Golems,
* 74 is the unit ID of Gold Golems and
* 28 is the number of Gold Golems.
BTB2 suggested replacing Diamond Golems with Mummies - this however, requires using a creature ID above 80, and therefore a long push (6B 8D000000 for mummies). However, to do that we would need to use some empty space. He suggested removing the -2 Luck on empty Pyramid subroutine. I decided to instead use some empty space I got from a different change, keeping the -2 Luck penalty. The result is as follows:
: 0x0A3FA6 → ebdf (jumps to overwrite -2 luck on empty Pyramid),
: 0x0A3F82 → e9 89c10100 (jump to free space 0xc0110)
::::: 68 8d000000 (Mummies)
:::::EB 1A 90 90 (jump back to A3FA8),
: 0xc0110 (Free) → 8a 87 1b 01 00 00 04 fe 88 87 1b 01 00 00 (displaced code: -2 Luck on empty Pyramid),
: 0xc011d (Free) → E9 6b3efeff(jump to 0x0A3F8F (end of F8E))
Note, that this method assumes you have empty space at 0xc0110 (by forcing rumors to always show rumors defined by the mapmaker). If you have empty space elsewhere, simply move the function, altering the jumps appropriately.
= Editing h3hota_maped =
All heroes are defined one by one in the h3hota_maped starting from 0x186800.
<span style="color:orange">GG</span>000000 <span style="color:red">RR</span>000000 <span style="color:blue">HH</span>000000 <span style="color:green">SO</span>000000 <span style="color:turquoise">OL</span>000000 <span style="color:teal">ST</span>000000 <span style="color:pink">TL</span>000000 ''SB'' 000000 <span style="color:grey">SP</span>000000 <span style="color:gold">U1</span>000000 <span style="color:gold">U2</span>000000 <span style="color:gold">U3</span>000000 PS000000 PL000000 <span style="color:silver">R0 </span><span style="color:silver">AS </span><span style="color:silver">CO</span> 00
Note, that some HotA heroes use some data from HotA.dat
= Game Mechanics =
== Starting Resources ==
Table with the starting resources starts at 0x278170. Each 4 bytes are the next resource (Wood, Mercury, Ore, Sulfur, Crystal, Gems, Gold). Each 28 bytes is the next difficulty - Easy, Normal, Expert, etc. At 0x2781FC the AI resources start and follow the same order of resources and difficulties. The whole table thus takes 280 bytes.
== Starting Bonuses ==
=== Gold Bonus ===
The starting gold bonus chooses a random value between the value written at 0x0C0002 and the value at 0x0BFFFD, and then multiplies it by 100. To change the multiplication, simply edit 0x0C000B (multiplying by 25) and 0x0C0016 (moving the value by 2 bits, so multiplying it by 4).
=== Resource Bonuses ===
The starting resource bonuses use DWORD pointers to find their appropriate code to run:
* Wood and Ore - AF FF 4B 00
* Crystals - D6 FF 4B 00
* Gems - E1 FF 4B 00
* Mercury - EC FF 4B 00
* Sulfur - F4 FF 4B 00
These DWORD pointers are located at the following addresses:
* Castle - 0x0C01B4
* Rampart - 0x0C01B8
* Tower - 0x0C01BC
* Inferno - 0x0C01C0
* Necropolis - 0x0C01C4
* Dungeon - 0x0C01C8
* Stronghold - 0x0C01CC
* Fortress - 0x0C01D0
* Conflux - 0x0C01D4
Note, that you need to edit ScnrStar.def to reflect any altered resources.
The amount for each rare resource is most likely determined by the function at 0xc009e: {{unk}}
: minimum: c745f0 33333333 ''(mov [ebp-0x10], 0x33333333)'' c745f0 3333EB3F  ''(mov [ebp-0x1c], 0x3feb3333)''
: break between the two: eb 0e ''(jmp 0x0e)''
: maximum: c745f0 66666666 ''(mov [ebp-0x10], 0x66666666)'' c745f0 6666E63F  ''(mov [ebp-0x10], 0x3FE66666)''
The amount of wood and ore are most likely specified at 0xbffaf: BA 0a000000 ''(mov edx, 0x0a)'' B9 05000000 ''(mov ecx, 0x05)''
== Movement point reminder ==
The movement point reminder is located at 0x9c91. It checks if movement points are 0 (using a 2-byte ''test eax, eax'') and then proceeds to different code if movement points are (or not) zero. If one wants to change it to a higher number (to avoid reminding of movement for heroes that can't actually move anymore), the following code can be used:
:0x9c91: {{---}}{{---}}a1 c8876900 ''mov eax, [0x6987c8]'' e9 849d0d00 (jump to some arbitrary free space) 90909090
: free space: {{-}}3d XY000000 ''cmp eax, XY'' - compare movement points with value XY.
:::: {{---}}7F 0A ''jg 0x0a'' - jump 10 bytes if the value is greater.
:::: {{---}}A1 C4 5d 6A 00 - displaced code
:::: {{---}}e9 6f62f2ff - jump to 0x9c9f (or 49C9F)
:::: {{---}}e9 a462f2ff - jump to 0x9cd9 (or 49CD9).
==Hex value tables==
{| class="wikitable" style="float: right; margin-left:8px;"
! Hex !! Creature
|-
|00000000 || {{cn|Pikeman}}
|-
|01000000 || {{cn|Halberdier}}
|-
|02000000 || {{cn|Archer}}
|-
|03000000 || {{cn|Marksman}}
|-
|04000000 || {{cn|Griffin}}
|-
|05000000 || {{cn|Royal Griffin}}
|-
|06000000 || {{cn|Swordsman}}
|-
|07000000 || {{cn|Crusader}}
|-
|08000000 || {{cn|Monk}}
|-
|09000000 || {{cn|Zealot}}
|-
|0A000000 || {{cn|Cavalier}}
|-
|0B000000 || {{cn|Champion}}
|-
|0C000000 || {{cn|Angel}}
|-
|0D000000 || {{cn|Archangel}}
|-
|0E000000 || {{cn|Centaur}}
|-
|0F000000 || {{cn|Centaur Captain}}
|-
|10000000 || {{cn|Dwarf}}
|-
|11000000 || {{cn|Battle Dwarf}}
|-
|12000000 || {{cn|Wood Elf}}
|-
|13000000 || {{cn|Grand Elf}}
|-
|14000000 || {{cn|Pegasus}}
|-
|15000000 || {{cn|Silver Pegasus}}
|-
|16000000 || {{cn|Dendroid Guard}}
|-
|17000000 || {{cn|Dendroid Soldier}}
|-
|18000000 || {{cn|Unicorn}}
|-
|19000000 || {{cn|War Unicorn}}
|-
|1A000000 || {{cn|Green Dragon}}
|-
|1B000000 || {{cn|Gold Dragon}}
|-
|1C000000 || {{cn|Gremlin}}
|-
|1D000000 || {{cn|Master Gremlin}}
|-
|1E000000 || {{cn|Stone Gargoyle}}
|-
|1F000000 || {{cn|Obsidian Gargoyle}}
|-
|20000000 || {{cn|Stone Golem}}
|-
|21000000 || {{cn|Iron Golem}}
|-
|22000000 || {{cn|Mage}}
|-
|23000000 || {{cn|Arch Mage}}
|-
|24000000 || {{cn|Genie}}
|-
|25000000 || {{cn|Master Genie}}
|-
|26000000 || {{cn|Naga}}
|-
|27000000 || {{cn|Naga Queen}}
|-
|28000000 || {{cn|Giant}}
|-
|29000000 || {{cn|Titan}}
|-
|2A000000 || {{cn|Imp}}
|-
|2B000000 || {{cn|Familiar}}
|-
|2C000000 || {{cn|Gog}}
|-
|2D000000 || {{cn|Magog}}
|-
|2E000000 || {{cn|Hell Hound}}
|-
|2F000000 || {{cn|Cerberus}}
|-
|30000000 || {{cn|Demon}}
|-
|31000000 || {{cn|Horned Demon}}
|-
|32000000 || {{cn|Pit Fiend}}
|-
|33000000 || {{cn|Pit Lord}}
|-
|34000000 || {{cn|Efreet}}
|-
|35000000 || {{cn|Efreet Sultan}}
|-
|36000000 || {{cn|Devil}}
|-
|37000000 || {{cn|Arch Devil}}
|-
|38000000 || {{cn|Skeleton}}
|-
|39000000 || {{cn|Skeleton Warrior}}
|-
|3A000000 || {{cn|Walking Dead}}
|-
|3B000000 || {{cn|Zombie}}
|-
|3C000000 || {{cn|Wight}}
|-
|3D000000 || {{cn|Wraith}}
|-
|3E000000 || {{cn|Vampire}}
|-
|3FD00000 || {{cn|Vampire Lord}}
|-
|40000000 || {{cn|Lich}}
|-
|41000000 || {{cn|Power Lich}}
|-
|42000000 || {{cn|Black Knight}}
|-
|43000000 || {{cn|Dread Knight}}
|-
|44000000 || {{cn|Bone Dragon}}
|-
|45000000 || {{cn|Ghost Dragon}}
|-
|46000000 || {{cn|Troglodyte}}
|-
|47000000 || {{cn|Infernal Troglodyte}}
|-
|48000000 || {{cn|Harpy}}
|-
|49000000 || {{cn|Harpy Hag}}
|-
|4A000000 || {{cn|Beholder}}
|-
|4B000000 || {{cn|Evil Eye}}
|-
|4C000000 || {{cn|Medusa}}
|-
|4D000000 || {{cn|Medusa Queen}}
|-
|4E000000 || {{cn|Minotaur}}
|-
|4F000000 || {{cn|Minotaur King}}
|-
|50000000 || {{cn|Manticore}}
|-
|51000000 || {{cn|Scorpicore}}
|-
|52000000 || {{cn|Red Dragon}}
|-
|53000000 || {{cn|Black Dragon}}
|-
|54000000 || {{cn|Goblin}}
|-
|55000000 || {{cn|Hobgoblin}}
|-
|56000000 || {{cn|Wolf Rider}}
|-
|57000000 || {{cn|Wolf Raider}}
|-
|58000000 || {{cn|Orc}}
|-
|59000000 || {{cn|Orc Chieftain}}
|-
|5A000000 || {{cn|Ogre}}
|-
|5B000000 || {{cn|Ogre Mage}}
|-
|5C000000 || {{cn|Roc}}
|-
|5D000000 || {{cn|Thunderbird}}
|-
|5E000000 || {{cn|Cyclops}}
|-
|5F000000 || {{cn|Cyclops King}}
|-
|60000000 || {{cn|Behemoth}}
|-
|61000000 || {{cn|Ancient Behemoth}}
|-
|62000000 || {{cn|Gnoll}}
|-
|63000000 || {{cn|Gnoll Marauder}}
|-
|64000000 || {{cn|Lizardman}}
|-
|65000000 || {{cn|Lizard Warrior}}
|-
|66000000 || {{cn|Gorgon}}
|-
|67000000 || {{cn|Mighty Gorgon}}
|-
|68000000 || {{cn|Serpent Fly}}
|-
|69000000 || {{cn|Dragon Fly}}
|-
|6A000000 || {{cn|Basilisk}}
|-
|6B000000 || {{cn|Greater Basilisk}}
|-
|6C000000 || {{cn|Wyvern}}
|-
|6D000000 || {{cn|Wyvern Monarch}}
|-
|6E000000 || {{cn|Hydra}}
|-
|6F000000 || {{cn|Chaos Hydra}}
|-
|70000000 || {{cn|Air Elemental}}
|-
|71000000 || {{cn|Earth Elemental}}
|-
|72000000 || {{cn|Fire Elemental}}
|-
|73000000 || {{cn|Water Elemental}}
|-
|74000000 || {{cn|Gold Golem}}
|-
|75000000 || {{cn|Diamond Golem}}
|-
|76000000 || {{cn|Pixie}}
|-
|77000000 || {{cn|Sprite}}
|-
|78000000 || {{cn|Psychic Elemental}}
|-
|79000000 || {{cn|Magic Elemental}}
|-
|7A000000 || NOT USED (1)
|-
|7B000000 || {{Cn|Ice Elemental}}
|-
|7C000000 || NOT USED (2)
|-
|7D000000 || {{Cn|Magma Elemental}}
|-
|7E000000 || NOT USED (3)
|-
|7F000000 || {{Cn|Storm Elemental}}
|-
|80000000 || NOT USED (4)
|-
|81000000 || {{Cn|Energy Elemental}}
|-
|82000000 || {{Cn|Firebird}}
|-
|83000000 || {{Cn|Phoenix}}
|-
|84000000 || {{Cn|Azure Dragon}}
|-
|85000000 || {{cn|Crystal Dragon}}
|-
|86000000 || {{cn|Faerie Dragon}}
|-
|87000000 || {{cn|Rust Dragon}}
|-
|88000000 || {{cn|Enchanter}}
|-
|89000000 || {{cn|Sharpshooter}}
|-
|8A000000 || {{cn|Halfling}}
|-
|8B000000 || {{cn|Peasant}}
|-
|8C000000 || {{cn|Boar}}
|-
|8D000000 || {{cn|Mummy}}
|-
|8E000000 || {{cn|Nomad}}
|-
|8F000000 || {{cn|Rogue}}
|-
|90000000 || {{cn|Troll}}
|-
|91000000 || {{cn|Catapult}}
|-
|92000000 || {{Cn|Ballista}}
|-
|93000000 || {{Cn|First Aid Tent}}
|-
|94000000 || {{Cn|Ammo Cart}}
|-
|95000000 || [[Arrow Tower]]
|-
|96000000 || {{Cn|Cannon}}
|-
|97000000 || {{cn|Sea Dog}}
|-
|98000000 || Electric Tower
|-
|99000000 || {{cn|Nymph}}
|-
|9A000000 || {{cn|Oceanid}}
|-
|9B000000 || {{cn|Crew Mate}}
|-
|9C000000 || {{cn|Seaman}}
|-
|9D000000 || {{cn|Pirate}}
|-
|9E000000 || {{cn|Corsair}}
|-
|9F000000 || {{cn|Stormbird}}
|-
|A0000000 || {{cn|Ayssid}}
|-
|A1000000 || {{cn|Sea Witch}}
|-
|A2000000 || {{cn|Sorceress}}
|-
|A3000000 || {{cn|Nix}}
|-
|A4000000 || {{cn|Nix Warrior}}
|-
|A5000000 || {{cn|Sea Serpent}}
|-
|A6000000 || {{cn|Haspid}}
|-
|A7000000 || {{cn|Satyr}}
|-
|A8000000 || {{cn|Fangarm}}
|-
|A9000000 || {{cn|Leprechaun}}
|-
|AA000000 || {{cn|Steel Golem}}
|-
|AB000000 || {{cn|Halfling Grenadier}}
|-
|AC000000 || {{cn|Mechanic}}
|-
|AD000000 || {{cn|Engineer}}
|-
|AE000000 || {{cn|Armadillo}}
|-
|AF000000 || {{cn|Bellwether Armadillo}}
|-
|B0000000 || {{cn|Automaton}}
|-
|B1000000 || {{cn|Sentinel Automaton}}
|-
|B2000000 || {{cn|Sandworm}}
|-
|B3000000 || {{cn|Olgoi-Khorkhoi}}
|-
|B4000000 || {{cn|Gunslinger}}
|-
|B5000000 || {{cn|Bounty Hunter}}
|-
|B6000000 || {{cn|Couatl}}
|-
|B7000000 || {{cn|Crimson Couatl}}
|-
|B8000000 || {{cn|Dreadnought}}
|-
|B9000000 || {{cn|Juggernaut}}
|}
{| class="wikitable" style="float: right; margin-left:8px;"
! Hex !! Artifact
|-
|01000000 || {{an|Spell Scroll}} - Next four bytes are for Spell ID
|-
|02000000 || {{an|The Grail}}
|-
|03000000 || {{Cn|Catapult}}
|-
|04000000 || {{Cn|Ballista}}
|-
|05000000 || {{Cn|Ammo Cart}}
|-
|06000000 || {{Cn|First Aid Tent}}
|-
|07000000 || {{an|Centaur's Axe}}
|-
|08000000 || {{an|Blackshard of the Dead Knight}}
|-
|09000000 || {{an|Greater Gnoll's Flail}}
|-
|0A000000 || {{an|Ogre's Club of Havoc}}
|-
|0B000000 || {{an|Sword of Hellfire}}
|-
|0C000000 || {{an|Titan's Gladius}}
|-
|0D000000 || {{an|Shield of the Dwarven Lords}}
|-
|0E000000 || {{an|Shield of the Yawning Dead}}
|-
|0F000000 || {{an|Buckler of the Gnoll King}}
|-
|10000000 || {{an|Targ of the Rampaging Ogre}}
|-
|11000000 || {{an|Shield of the Damned}}
|-
|12000000 || {{an|Sentinel's Shield}}
|-
|13000000 || {{an|Helm of the Alabaster Unicorn}}
|-
|14000000 || {{an|Skull Helmet}}
|-
|15000000 || {{an|Helm of Chaos}}
|-
|16000000 || {{an|Crown of the Supreme Magi}}
|-
|17000000 || {{an|Hellstorm Helmet}}
|-
|18000000 || {{an|Thunder Helmet}}
|-
|19000000 || {{an|Breastplate of Petrified Wood}}
|-
|1A000000 || {{an|Rib Cage}}
|-
|1B000000 || {{an|Scales of the Greater Basilisk}}
|-
|1C000000 || {{an|Tunic of the Cyclops King}}
|-
|1D000000 || {{an|Breastplate of Brimstone}}
|-
|1E000000 || {{an|Titan's Cuirass}}
|-
|1F000000 || {{an|Armor of Wonder}}
|-
|20000000 || {{an|Sandals of the Saint}}
|-
|21000000 || {{an|Celestial Necklace of Bliss}}
|-
|22000000 || {{an|Lion's Shield of Courage}}
|-
|23000000 || {{an|Sword of Judgement}}
|-
|24000000 || {{an|Helm of Heavenly Enlightenment}}
|-
|25000000 || {{an|Quiet Eye of the Dragon}}
|-
|26000000 || {{an|Red Dragon Flame Tongue}}
|-
|27000000 || {{an|Dragon Scale Shield}}
|-
|28000000 || {{an|Dragon Scale Armor}}
|-
|29000000 || {{an|Dragonbone Greaves}}
|-
|2A000000 || {{an|Dragon Wing Tabard}}
|-
|2B000000 || {{an|Necklace of Dragonteeth}}
|-
|2C000000 || {{an|Crown of Dragontooth}}
|-
|2D000000 || {{an|Still Eye of the Dragon}}
|-
|2E000000 || {{an|Clover of Fortune}}
|-
|2F000000 || {{an|Cards of Prophecy}}
|-
|30000000 || {{an|Ladybird of Luck}}
|-
|31000000 || {{an|Badge of Courage}}
|-
|32000000 || {{an|Crest of Valor}}
|-
|33000000 || {{an|Glyph of Gallantry}}
|-
|34000000 || {{an|Speculum}}
|-
|35000000 || {{an|Spyglass}}
|-
|36000000 || {{an|Amulet of the Undertaker}}
|-
|37000000 || {{an|Vampire's Cowl}}
|-
|38000000 || {{an|Dead Man's Boots}}
|-
|39000000 || {{an|Garniture of Interference}}
|-
|3A000000 || {{an|Surcoat of Counterpoise}}
|-
|3B000000 || {{an|Boots of Polarity}}
|-
|3C000000 || {{an|Bow of Elven Cherrywood}}
|-
|3D000000 || {{an|Bowstring of the Unicorn's Mane}}
|-
|3E000000 || {{an|Angel Feather Arrows}}
|-
|3F000000 || {{an|Bird of Perception}}
|-
|40000000 || {{an|Stoic Watchman}}
|-
|41000000 || {{an|Emblem of Cognizance}}
|-
|42000000 || {{an|Statesman's Medal}}
|-
|43000000 || {{an|Diplomat's Ring}}
|-
|44000000 || {{an|Ambassador's Sash}}
|-
|45000000 || {{an|Ring of the Wayfarer}}
|-
|46000000 || {{an|Equestrian's Gloves}}
|-
|47000000 || {{an|Necklace of Ocean Guidance}}
|-
|48000000 || {{an|Angel Wings}}
|-
|49000000 || {{an|Charm of Mana}}
|-
|4A000000 || {{an|Talisman of Mana}}
|-
|4B000000 || {{an|Mystic Orb of Mana}}
|-
|4C000000 || {{an|Collar of Conjuring}}
|-
|4D000000 || {{an|Ring of Conjuring}}
|-
|4E000000 || {{an|Cape of Conjuring}}
|-
|4F000000 || {{an|Orb of the Firmament}}
|-
|50000000 || {{an|Orb of Silt}}
|-
|51000000 || {{an|Orb of Tempestuous Fire}}
|-
|52000000 || {{an|Orb of Driving Rain}}
|-
|53000000 || {{an|Recanter's Cloak}}
|-
|54000000 || {{an|Spirit of Oppression}}
|-
|55000000 || {{an|Hourglass of the Evil Hour}}
|-
|56000000 || {{an|Tome of Fire}}
|-
|57000000 || {{an|Tome of Air}}
|-
|58000000 || {{an|Tome of Water}}
|-
|59000000 || {{an|Tome of Earth}}
|-
|5A000000 || {{an|Boots of Levitation}}
|-
|5B000000 || {{an|Golden Bow}}
|-
|5C000000 || {{an|Sphere of Permanence}}
|-
|5D000000 || {{an|Orb of Vulnerability}}
|-
|5E000000 || {{an|Ring of Vitality}}
|-
|5F000000 || {{an|Ring of Life}}
|-
|60000000 || {{an|Vial of Lifeblood}}
|-
|61000000 || {{an|Necklace of Swiftness}}
|-
|62000000 || {{an|Boots of Speed}}
|-
|63000000 || {{an|Cape of Velocity}}
|-
|64000000 || {{an|Pendant of Dispassion}}
|-
|65000000 || {{an|Pendant of Second Sight}}
|-
|66000000 || {{an|Pendant of Holiness}}
|-
|67000000 || {{an|Pendant of Life}}
|-
|68000000 || {{an|Pendant of Death}}
|-
|69000000 || {{an|Pendant of Free Will}}
|-
|6A000000 || {{an|Pendant of Negativity}}
|-
|6B000000 || {{an|Pendant of Total Recall}}
|-
|6C000000 || {{an|Pendant of Courage}}
|-
|6D000000 || {{an|Everflowing Crystal Cloak}}
|-
|6E000000 || {{an|Ring of Infinite Gems}}
|-
|6F000000 || {{an|Everpouring Vial of Mercury}}
|-
|70000000 || {{an|Inexhaustible Cart of Ore}}
|-
|71000000 || {{an|Eversmoking Ring of Sulfur}}
|-
|72000000 || {{an|Inexhaustible Cart of Lumber}}
|-
|73000000 || {{an|Endless Sack of Gold}}
|-
|74000000 || {{an|Endless Bag of Gold}}
|-
|75000000 || {{an|Endless Purse of Gold}}
|-
|76000000 || {{an|Legs of Legion}}
|-
|77000000 || {{an|Loins of Legion}}
|-
|78000000 || {{an|Torso of Legion}}
|-
|79000000 || {{an|Arms of Legion}}
|-
|7A000000 || {{an|Head of Legion}}
|-
|7B000000 || {{an|Sea Captain's Hat}}
|-
|7C000000 || {{an|Spellbinder's Hat}}
|-
|7D000000 || {{an|Shackles of War}}
|-
|7E000000 || {{an|Orb of Inhibition}}
|-
|7F000000 || {{an|Vial of Dragon Blood}}
|-
|80000000 || {{an|Armageddon's Blade}}
|-
|81000000 || {{an|Angelic Alliance}}
|-
|82000000 || {{an|Cloak of the Undead King}}
|-
|83000000 || {{an|Elixir of Life}}
|-
|84000000 || {{an|Armor of the Damned}}
|-
|85000000 || {{an|Statue of Legion}}
|-
|86000000 || {{an|Power of the Dragon Father}}
|-
|87000000 || {{an|Titan's Thunder}}
|-
|88000000 || {{an|Admiral's Hat}}
|-
|89000000 || {{an|Bow of the Sharpshooter}}
|-
|8A000000 || {{an|Wizard's Well}}
|-
|8B000000 || {{an|Ring of the Magi}}
|-
|8C000000 || {{an|Cornucopia}}
|-
|8D000000 || {{an|Diplomat's Cloak}}
|-
|8E000000 || {{an|Pendant of Reflection}}
|-
|8F000000 || {{an|Ironfist of the Ogre}}
|-
|90000000 || Invalid
|-
|91000000 || Invalid
|-
|92000000 || {{Cn|Cannon}}
|-
|93000000 || {{an|Trident of Dominion}}
|-
|94000000 || {{an|Shield of Naval Glory}}
|-
|95000000 || {{an|Royal Armor of Nix}}
|-
|96000000 || {{an|Crown of the Five Seas}}
|-
|97000000 || {{an|Wayfarer's Boots}}
|-
|98000000 || {{an|Runes of Imminency}}
|-
|99000000 || {{an|Demon's Horseshoe}}
|-
|9A000000 || {{an|Shaman's Puppet}}
|-
|9B000000 || {{an|Hideous Mask}}
|-
|9C000000 || {{an|Ring of Suppression}}
|-
|9D000000 || {{an|Pendant of Downfall}}
|-
|9E000000 || {{an|Ring of Oblivion}}
|-
|9F000000 || {{an|Cape of Silence}}
|-
|A0000000 || {{an|Golden Goose}}
|-
|A1000000 || {{an|Horn of the Abyss}}
|-
|A2000000 || {{an|Charm of Eclipse}}
|-
|A3000000 || {{an|Seal of Sunset}}
|-
|A4000000 || {{an|Plate of Dying Light}}
|-
|A5000000 || {{an|Sleepkeeper}}
|}
{| class="wikitable" style="float: right; margin-left:8px;"
! Hex !! Spell
|-
|01000000 || {{sn|Scuttle Boat}}
|-
|02000000 || {{sn|Visions}}
|-
|03000000 || {{sn|View Earth}}
|-
|04000000 || {{sn|Disguise}}
|-
|05000000 || {{sn|View Air}}
|-
|06000000 || {{sn|Fly}}
|-
|07000000 || {{sn|Water Walk}}
|-
|08000000 || {{sn|Dimension Door}}
|-
|09000000 || {{sn|Town Portal}}
|-
|0A000000 || {{sn|Quicksand}}
|-
|0B000000 || {{sn|Land Mine}}
|-
|0C000000 || {{sn|Force Field}}
|-
|0D000000 || {{sn|Fire Wall}}
|-
|0E000000 || {{sn|Earthquake}}
|-
|0F000000 || {{sn|Magic Arrow}}
|-
|10000000 || {{sn|Ice Bolt}}
|-
|11000000 || {{sn|Lightning Bolt}}
|-
|12000000 || {{sn|Implosion}}
|-
|13000000 || {{sn|Chain Lightning}}
|-
|14000000 || {{sn|Frost Ring}}
|-
|15000000 || {{sn|Fireball}}
|-
|16000000 || {{sn|Inferno}}
|-
|17000000 || {{sn|Meteor Shower}}
|-
|18000000 || {{sn|Death Ripple}}
|-
|19000000 || {{sn|Destroy Undead}}
|-
|1A000000 || {{sn|Armageddon}}
|-
|1B000000 || {{sn|Shield}}
|-
|1C000000 || {{sn|Air Shield}}
|-
|1D000000 || {{sn|Fire Shield}}
|-
|1E000000 || {{sn|Protection from Air}}
|-
|1F000000 || {{sn|Protection from Fire}}
|-
|20000000 || {{sn|Protection from Water}}
|-
|21000000 || {{sn|Protection from Earth}}
|-
|22000000 || {{sn|Anti-Magic}}
|-
|23000000 || {{sn|Dispel}}
|-
|24000000 || {{sn|Magic Mirror}}
|-
|25000000 || {{sn|Cure}}
|-
|26000000 || {{sn|Resurrection}}
|-
|27000000 || {{sn|Animate Dead}}
|-
|28000000 || {{sn|Sacrifice}}
|-
|29000000 || {{sn|Bless}}
|-
|2A000000 || {{sn|Curse}}
|-
|2B000000 || {{sn|Bloodlust}}
|-
|2C000000 || {{sn|Precision}}
|-
|2D000000 || {{sn|Weakness}}
|-
|2E000000 || {{sn|Stone Skin}}
|-
|2F000000 || {{sn|Disrupting Ray}}
|-
|30000000 || {{sn|Prayer}}
|-
|31000000 || {{sn|Mirth}}
|-
|32000000 || {{sn|Sorrow}}
|-
|33000000 || {{sn|Fortune}}
|-
|34000000 || {{sn|Misfortune}}
|-
|35000000 || {{sn|Haste}}
|-
|36000000 || {{sn|Slow}}
|-
|37000000 || {{sn|Slayer}}
|-
|38000000 || {{sn|Frenzy}}
|-
|39000000 || {{sn|Titan's Lightning Bolt}}
|-
|3A000000 || {{sn|Counterstrike}}
|-
|3B000000 || {{sn|Berserk}}
|-
|3C000000 || {{sn|Hypnotize}}
|-
|3D000000 || {{sn|Forgetfulness}}
|-
|3E000000 || {{sn|Blind}}
|-
|3F000000 || {{sn|Teleport}}
|-
|40000000 || {{sn|Remove Obstacle}}
|-
|41000000 || {{sn|Clone}}
|-
|42000000 || {{sn|Summon Fire Elemental}}
|-
|43000000 || {{sn|Summon Earth Elemental}}
|-
|44000000 || {{sn|Summon Water Elemental}}
|-
|45000000 || {{sn|Summon Air Elemental}}
|-
|46000000 || Stone Gaze
|}
{{clear|both}}


= External links =
= External links =
Line 330: Line 1,489:
#  [http://heroescommunity.com/viewthread.php3?TID=42152&pagenumber=1 heroescommunity.com - How to edit Hota?] - Thread with majority of useful information, scrambled across 112 forum pages.  
#  [http://heroescommunity.com/viewthread.php3?TID=42152&pagenumber=1 heroescommunity.com - How to edit Hota?] - Thread with majority of useful information, scrambled across 112 forum pages.  
#  [http://btb2.free.fr/mods/h3/hacking.txt BTB2's hacking guide] - primarily detailing creation of his own mod, but including tips, explanations and some of the Reference IDs
#  [http://btb2.free.fr/mods/h3/hacking.txt BTB2's hacking guide] - primarily detailing creation of his own mod, but including tips, explanations and some of the Reference IDs
 
# [https://handbookhmm.ru/forum/viewtopic.php?f=56&t=968 void_17's database] - this database describes most or all of the functions in the base game of heroes 3.
#* [https://drive.google.com/file/d/1MY28K8cVbAeBzAbBBBf5ZeK-0aLMfz_d/view void_17's database] (link 2).
[[Category:Guides]]
[[Category:Guides]]

Latest revision as of 18:16, 13 February 2025

This page is a work-in-progress. Details listed here may not be 100% accurate.

The following article describes some basics of hex edition. Offsets (and code itself in some locations) may vary based on game version.

Heroes of Might and Magic III is coded in Assembly x86. Each byte (a set of 2 hexadecimal characters) corresponds to either a function, or a value for an already determined function. The only exception is byte 0x90, which is non-coding and may be used to f.e. fill empty space.

Upper majority of creature stats, abilities, etc. is coded within the *.exe. While it may not be readable or understandable to a layman, in short time one can comprehend a lot of the code and find reason and rhyme in it (or at least, parts of it).

To open (and edit) the *.exe files, one needs a hex editor, f.e. frhed or another similar software. I recommend ImHex, as it comes with a handy disassembler function built in, as well as a base converter, and similar useful tools.

Some data is located with the *.lod files. To open them, you need to use MMArchive.

Basics[edit | hide | hide all]

Majority of HotA Horn of the Abyss additions are not directly in the h3hota.exe (or h3hota HD.exe), but instead in Hota.dat (and partly in HotA.dll).

Numbers[edit | hide]

All (or almost all) numbers are written in Little Endian - the bytes are placed in reverse order. As an example, 0xA624C (0x before a number signifies it's hexadecimal) in Little Endian is written as 4C 62 0A 00. Note, that the system recognizes that a number is negative based on the fact that it's greater than half the number range: greater than 0x80 for a single byte, and greater than 0x80000000 for a 4-byte value.

Some numbers use a IEE-754 coding. It is recommended to use a calculator for such values, such as the one available on save-editor.com.

Keep in mind that most (but, surprisingly, not all) lists start at 0, not at 1, so the first element is element 0 and not element 1.

QWORD and DWORD pointers are Little Endian representations of an address within the *.exe file, with 0x400000 added to them because of the way the game reads the code. Therefore if you want the DWORD pointer to find 0x27e484, you write it as 84 e4 27 00. DWORDs use IEE-754, while QWORDs use an 8-byte double-precision IEE-754 value.

Values followed by zeroes in the same block are 4-byte numbers - this essentially increases their available number range from (in decimal) 0-127 to 0-2147483647.

Heroes[edit | hide]

Heroes are very easy to edit. Hero data is stored in two sets, one containing general hero data and the other containing only hero specialties. Heroes are generally ordered by their faction (Castle, Rampart, Tower, etc.) and then their class (might or magic). Following standard heroes, are all campaign heroes.

Hero Data[edit | hide]

Hex String (Start: ???, End: ???)
GG000000 RR000000 HH000000 SO000000 OL000000 ST000000 TL000000 SB000000 SP000000 U1000000 U2000000 U3000000 PS000000 PL000000 R0 AS CO 00
Description
GG Gender: 00: male, 01: female.
RR Race. These are listed alphabetically, from Demon to Vampire. This has no in-game effect or visibility and the extensions preferred to default everyone to human, except Gelu who gets to be an elf.
HH Class: Classes go in order of factions, and within a faction the might class is listed first. Therefore, 00: Knight, 01: Cleric, 02: Ranger, 03: Druid, etc. Note, that HotA classes essentially "follow" this encoding.
SO 1st Secondary skill (ref. ID).
OL 1st Secondary skill's proficiency level (00: Basic, 01: Advanced, 02: Expert).
ST 2nd Secondary skill (ref. ID). If there is no second skill, instead, FFFFFFFF is used, replacing ST and the zeroes following it.
TL 2nd Secondary skill level. If there is no second skill, 00 is used (Basic).
SB Spell Book. 00: absent, 01: present.
SP Starting Spell (ref. ID). If no spell is present, FFFFFFFF is used instead.
U1
U2
U3
Starting creature reference IDs.
PS Small Portrait DWORD pointer, which leads to plain text name of the portrait in the H3bitmap.lod.
PL Large Portrait, same as above.
R0 Present by default in all RoE maps. 00: false, 01: true.
AS Present by default in all non-RoE maps. 00: false, 01: true.
CO Campaign-only. 00: false, 01: true.

Editing HotA Heroes[edit | hide]

Hota heroes are coded in the HotA.dat. Names written in quotes are coded in plain text. Note, that for editing text itself it's best to use programs such as HotA Editor, instead of a direct hex-editing.

Hex String (Start: 0x23dd, End: 0x9886)
07 000000 "hero<ref_id>" 12 000000 "Heroes\hero_<ref_id>.str" FACTION "#large_portrait_file_name.pcx" 0c000000 "#small_portrait_file_name.pcx" XX 000000 "Specialty_Name" YY 000000 "Specialty Bonus: Object" ZZ000000 "{Full Object}" 0d 0a 0d 0a (number of 0a 0d repetitions may differ) "specialty_description" PP000000 "HeroName" QQQQQQQQ "Biography" 00000000 01 5c 0000 (number of zeroes may vary) GG000000 RR000000 HH000000 SO000000 OL000000 ST000000 TL000000 SB000000 SP000000 U1000000 U2000000 U3000000 PS000000 PL000000 R0 AS C0 00 00000000 00000000 1m000000 1M000000 2m000000 2M000000 3m000000 3M000000 08000000 I8000000 TT000000 ID000000 AA000000 DD000000 DM000000 U4000000 U5000000
Description
hero<ref_id> The hero's reference id in decimal, f.e. hero154
Heroes\hero_<ref_id>.str ???
FACTION Cove heroes: 09 000000 00000000 0b 000000
Factory heroes: 09 000000 00000000 00000000 07 000000
#large_portrait_file_name.pcx
#small_portrait_file_name.pcx
# and the appropriate file name, e.g. #HPLP06.pcx
XX ???
Specialty_Name e.g. "Sea Dogs" or "Nix"
YY ???
Specialty Bonus: Object Refers to the following types of text: "Spell Bonus: Air Shield", "Creature Bonus: Sea Dogs", etc.
ZZ ???
{Full Object} Text in curly parentheses {} stating again the specialty, e.g. "{Estates}", or "{Pirates, Corsairs and Sea Dogs}".
specialty_description Text string describing the hero specialty.
PP Hero's name's length.
HeroName Text string of the hero's name.
QQQQQQQQ ???, seems to be some sort of an ID as it seems to be unique for each hero; it is not, however, the reference ID. All QQ values are around 300 (dec).
Biography Text string containing the hero's biography.
GG ???
RR ???
HH ???
SO ???
OL ???
ST ???
TL ???
SB ???
SP ???
U1 ???
U2 ???
U3 ???
PS ???
PL ???
YY ???
R0 ???
AS ???
1m minimum number of the first creature type in hero's starting army
1M maximum number of the first creature type in hero's starting army
2m minimum number of the second creature type in hero's starting army
2M maximum number of the second creature type in hero's starting army
3m minimum number of the third creature type in hero's starting army
3M maximum number of the third creature type in hero's starting army
I8 reference ID + 8 for heroes before ref ID 178 and reference ID + 7 for heroes after ref ID 178 (essentially, 0xb9 is skipped)
TT ???
ID ???
AA ???
DD ???
DM ???
U4 ???
U5 ???

Hero Specialties[edit | hide]

Hero specialties are written one by one in the same order as heroes appear in. Note: Many "possible" specialties don't exist and simply won't do anything; examples include Tactics specialty, Teleport specialty, etc.

Hex String (Start: 0x00278420, End: ???)
TT000000 ID000000 AA000000 DD000000 DM000000 U4000000 U5000000
Description
TT Specialty type. Specialty types are described in greater detail in the sections below. The following specialty types exist:
  • 00: Skill specialty (+5% skill effect per level)
  • 01: Basic Unit specialty (+1 speed, +1 Attack and Defense every <unit level> levels)
  • 02: Resource (+1 gems per day, etc.)
  • 03: Spell (+3% efficiency per level for most spells, sometimes special bonuses instead)
  • 04: Static Unit specialty (static bonus to attack, defense, damage, speed, or any combination of them), e.g. Xeron, Kalt, Haart Lich, etc.
  • 05: Speed (Sir Mullich only)
  • 06: Unit Upgrade specialty (Gelu, Dracon, Bidley, etc.)
  • 07: Dragon Specialty (Mutare, Mutare Drake)
  • 08: Frederick's Automaton Explosion specialty.

Note: Setting the first byte (TT000000) to FFFFFFFF will ensure the hero has no specialty. This is only used for Adrienne (yes, she technically has no hero specialty).

ID Reference ID of the specialized in Skill, Unit, Resource or Spell. (Not needed for Dragon and Speed specialties, where it is 00 and an unnecessary, unused 02, respectively).
AA Attack bonus for Static Unit specialists (and Mutare).
DD Defense bonus for Static Unit specialists (and Mutare).
DM Damage bonus for Static Unit specialists (and probably Mutare).
U4 Second unit (ref. ID) that can be upgraded (only used by Unit Upgrade specialists; otherwise left as 00. Note, that using the same unit twice for Unit Upgrade specialty essentially removes second unit from being upgradable; meanwhile using 00 sets the ID to Pikemen.
Note: When using a Unit Upgrade specialist, the reference ID of un-upgraded creatures ought to be used. e.g. Gelu references Archers and Wood Elves, but code naturally allows also for their upgrades to be improved with his specialty. This does not occur the other way around; specifying ID or U2 as an upgraded creature, will make the upgrade impossible for un-upgraded creatures. )
U5 Resulting unit ref. ID from the upgrade (only for Unit Upgrade specialists).

00 - Skill Specialty[edit | hide]

The code for skill specialties works as follows: XXXXXXXX D805 YYYYYYYY D8 4D FC where XXXXXXXX is a DWORD pointer to a 5% value (in IEEE-754), YYYYYYYY is a DWORD pointer to a value of 1 (again, in IEEE-754)

How it works[edit | hide]

The number of levels is multiplied by the XXXXXXXX DWORD pointer, added to the YYYYYYYY DWORD pointer and then the skill bonus is multiplied by it (D8 4D FC).

If we want to change the % gain per level, we only need to change the XX value. If we want to instead make the bonus additive (say x% per level, regardless of how much skill itself adds), we can replace the D805YYYYYYYY with 909090909090 (NOP) and replace the D8 4D FC with D8 45 FC.

Therefore it is possible to have a different bonus for one skill than another.

Offsets[edit | hide]

The offsets for each skill specialty bonus are as follows:

Archery - 0x0E4420
Armorer - 0x0E45C9
Diplomacy - 0x0E483C
Eagle Eye - 0x0E46E0
Estates - 0x0E464F
First Aid - 0x0E4BD9
Intelligence - 0x0E4B69
Leadership - 0x0E3C81
Learning - 0x0E4AF9
Logistics - 0x0E4F1E
Luck - 0x0E3A2B
Mysticism - 0x0E41FE
Necromancy - 0x0E3F92
Offense - 0x0E4569
Resistance - 0x0E499C
Scouting - 0x0E432E
Sorcery - 0x0E5B61

Exceptions[edit | hide]

Specialties for integer-bonuses (Luck, Logistics, Scouting) only have their effect when a full integer is gained from their % bonus.

Diplomacy specialty only affects surrender costs.

Learning specialty is fully over-written by the Hota.dll.

01 - Unit Specialty[edit | hide]

The scaling factor for a unit specialty is a DWORD pointing to a 5% value (in IEEE-754), located at 0x0e6548.

Setting the unit IDs to an upgraded unit will ensure only the upgraded units are affected by the specialty.

Ballista and Cannon specialty are Unit specialties.

02 - Resource Specialty[edit | hide]

The amount of resources obtained from a gold specialty is saved at 0x0E4681 (as 350).

The code for other resource specialties is possible to edit, but it checks for each resource together and then adds 1 to their growth (therefore its only possible to make all resource specialists increase resource gain by 2, unless a complete re-write of the function is performed).

03 - Spell Specialists[edit | hide]

Spell specialty types[edit | hide]

Spell specialty type table starts at 0x0e6358 (with Fire Wall specialty). Each consecutive byte is then the next spell by spell ID (Firewall, Earthquake, Magic Arrow, etc.) up to Slayer. Each spell specialty can take 6 types:

00 - +100% damage (Luna). Note that Hota.dll overwrites this +100% damage with a much more sensible 25%.
01 - +50% damage (Ciele).
02 - Tier bonus A (+3/+3/+2/+2/+1/+1/+0), such as Weakness specialty or Haste specialty.
03 - Static bonus +2 (Aenain)
04 - This one is only used by Fortune (Daremyth, Melodia). In contrary to what BTB claims, it sets the value of the spells effect to 3, regardless of spell's level.
05 - Tier bonus B (+4/+3/+2/+1/+0/+0/+0), only used by Coronius as far as I know.
06 - Scaling bonus.

If a spell does not belong to the spell table, the scaling bonus is applied (for example this applies to the Hypnotize specialist, Astral).

"But what if we want to change the specialty type for a spell like Hypnotize?"

We can extend the table by changing 0x0e6296 (equal to 0x2a by default) to a different value, which corresponds to the number of spells in the table -1. If we extend the table, the next specialties will be those for the next spells by spell ID. We have a total of 13 bytes of nop (90), so the last spell specialty we can code this way is Summon Air Elemental. Remember to update all specialties created this way! You shouldn't just leave the nops (90) in the middle of the table!

"But what about Victoria, the Land Mine specialist?", you may ask. Well, I'm here to give answers:

The command lea eax, [esi-0Dh] located at 0x0e6291 finds the spell ID of firewall (0d) and chooses it as the first spell on the list of specialties (remember? The one that starts at 0x0e6358?). By changing it to lea eax, [esi-0Bh], we can change the first spell ID to 0x0B, or Land Mine. Notice, that this reduces the last spell specialty to Summon Earth Elemental, but I doubt anyone will miss the Summon Water Elemental and Summon Air Elemental specialties.

Next, we have to increase the number of spells in the list by 2 (located at 0x0e6296), and then move the entire spell specialty table, 2 bytes each, because now it starts at 0x0e6358 with Land Mine (and still follows by spell ID).

"And what about Eovacius? And Zilare?"

Haven't looked at them yet but I believe they may be hard-coded.

The specialty types can be changed by altering their commands. Each specialty type (00, 01, and so on) have a DWORD pointer to their appropriate code located in a 28-byte long table starting at 0x0e633c.

Changing Tier bonuses[edit | hide]

Let's say we want to make Olema's Weakness specialty remotely usable, but we still want it to be a tier-based specialty. We can change the bonuses the spell provides for each unit tier in a 28-byte long table that starts at 0x23eaa8. Each 4 bytes corresponds to the next unit level.

A similar table for Coronius' specialty type starts at 0x23eac4 (immediately afterwards) and works the same way.

Changing the static bonus[edit | hide]

At 0x0e62e6 the value 0x02 determines the static bonus (such as the one Disrupting Ray specialists get).

Changing the scaling bonus[edit | hide]

At 0x0e631f the DWORD pointer finds an IEEE-754 double precision value for 3% (base game). Replacing this pointer with another one finds a different % bonus.

If you don't want the scaling specialties to divide their bonus by unit level, replace f7 f9 at 0xe630b with 90 90 (nop-ing out the division).

Specialties that don't work[edit | hide]

Several specialties don't work because no specialty type can increase their bonus:

  • Curse
  • Anti-Magic
  • Dispel
  • Slow ???, but it would probably be way too strong anyway;
  • Berserk
  • Blind
  • Teleport
  • Remove Obstacle.

04 - Unit (static)[edit | hide]

Only Xeron is specified to add speed thanks to his static unit specialty. This is (most likely) saved at the following address: 0x4b1b3 ???.

Setting the unit IDs to an upgraded unit will ensure only the upgraded units are affected by the specialty.

05 - Speed specialty[edit | hide]

Sir Mullich's unit specialty amount (0x02) is located at 0x0E6669.

06 - Unit Upgrade specialty[edit | hide]

These specialties calculate the upgrade cost automatically, with the same function that calculates upgrade costs in all other cases. If "unupgraded" unit is more expensive than the upgraded one, the message about necessary costs wil appear, but no cost will be stated and the conversion will be free.

Setting the unit IDs to an upgraded unit will ensure only the upgraded units are affected by the specialty.

07 - Dragon specialty[edit | hide]

I believe Mutare's bonus is specified within her specialty block.

Creatures[edit | hide]

Editing HotA Creatures[edit | hide]

While most statistics of base game creatures can be edited rather effortlessly (using MMArchive to unpack H3bitmap.lod or HotA_lng.lod), HotA creatures cannot be edited this way. Their data is stored at the beginning of HotA.dat. When using custom functions or editing original code, note that all HotA (as well as some SoD monsters) have reference ID above 80, and therefore cannot be checked for using a simple check command, such as 83 FA ID. Instead, you have to use a longer command that accepts a 4-byte value (for EDX that would be 81 FA ID000000).

Hex String (Start: ???, End: ???)
08 000000 "monst<ref_id>" 17 000000 "Monsters\monster<ref_id>.str" 09 000000 00000000 04 000000 "name_abbreviation" KK000000 "<animation_filename>.def" L1000000 "Monster_name (singular)" L2000000 "Monster name (plural)" 00000000 00000000 00000000 00000000 01 74 0000 TT 000000 UL 000000 0c556700 00556700 F1 F2 F3 F4 80da9e03 60da9e03 30da9e03 WC000000 MC000000 OC000000 SC000000 CC000000 GeC000000 GC000000 FV000000 AV000000 GV000000 HG000000 HP000000 SP000000 AT000000 DF000000 DmgL000000 DmgH000000 SH000000 SN000000 OO000000 mm000000 MM000000 RR000000 VV000000 WW000000 XX000000 YY000000 ZZ000000
Description
monst<ref_id> The monster's reference id in decimal, f.e. monst154
Monsters\monster<ref_id>.str ???
name_abbreviation The 4 letter abbreviation of the monster name. Never appears anywhere ever again. Note that not all abbreviations are just beginning or consonants, f.e. Haspids are written as "aspi" and nix as "nixx". This abbreviation doesn't seem to have to be unique, as Sea Serpent and Haspids have the same 4 letters here. It is worth pointing out, that base game creatures also use 4-letter abbreviations in a similar table located in h3hota HD.exe around 0x275500
KK The length of the animation_filename + 4 (and therefore the length of the entire "animation_filename.def"
<animation_filename>.def The file name of the set of animations, saved as .def in HotA.lod or HotA.lod.
L1 The length of the monster name (singular)
Monster_name (singular) Text string of the singular monster's name.
L2 The length of the monster name (plural)
Monster_name (plural) Text string of the plural monster's name.
TT The reference id of the town the monster belongs to. 0x09 for Cove, 0x0a for Factory, FFFFFFFF for Neutrals and I bet if HotA ever releases a new town, it will have 0x0b as its faction code.
UL The unit level -1 (sidenote: this is an example of numbers being used in a list with a zero-based numbering). FFFFFFFF for monsters with no level (f.e. Citadel / Castle Towers)
0c556700
(and 00556700)
These point to a similar table with creature sprite, text and other references in h3hota HD.exe and is probably used to insert the HotA.dat's creature table into this part of the exe.
F1 The first creature ability flag
  • 01: 2-hex unit
  • 02: Flying
  • 04: Ranged Attack
  • 08: Fire breath
  • 10: Living
  • 20: Can attack city walls (cyclops, cannon)
  • 40: War machine
  • 80: Slayer (Basic)
F2 The second creature ability flag
  • 01: Slayer (advanced)
  • 02: Slayer (expert)
  • 04: Mind immunity
  • 08: shoots beam (?)
  • 10: No melee penalty
  • 20: ???
  • 40: Fire immunity
  • 80: Attacks twice
F3 The third creature ability flag
  • 01: No enemy retaliation
  • 02: Morale has no effect
  • 04: Undead
  • 08: AOE melee attack (Hydra)
  • 10: AOE ranged attack (Magog), AI flag only.
  • 20: ???
  • 40: ???
  • 80: ???
F4 The fourth creature ability flag
  • 01: ???
  • 02: ???
  • 04: ???
  • 08: ???
  • 10: ???
  • 20: ???
  • 40: ???
  • 80: Dragon (for the sake of Mutare's specialty and vial of dragon blood)
80da9e03
60da9e03
30da9e03
???
WC Wood Cost to recruit the creature
MC Mercury Cost to recruit the creature
OC Ore Cost to recruit the creature
SC Sulfur Cost to recruit the creature
CC Crystal Cost to recruit the creature
GeC Gem Cost to recruit the creature
GC Gold Cost to recruit the creature. Note that all aforementioned cost values have 4 bytes to play with, so the maximum unit cost is 2147483647 gold (or of any resource).
FV Fight Value
AV AI Value
GV Growth
HG Horde Growth
HP Hit Points
SP Speed
AT Attack
DF Defense
DmgL The low end of the damage range
DmgH The high end of the damage range
SH Number of shots per battle
SN Number of spell casts per battle
OO ???
mm Minimum number of units when randomly spawned by the map generator
MM Maximum number of units when randomly spawned by the map generator.
QQ
RR
VV
WW
XX
YY
ZZ
???. Sometimes they take up 28 (!) bytes (such as for Ayssids), and sometimes don't appear at all. I suspect they reference some sort of abilities the creatures have, or their descriptions.

Editing Creature Abilities[edit | hide]

Magic Channel (Familiars)[edit | hide]

Magic channel's applicable unit ID is defined at 0x1a24f6. The game uses a frankly ridiculous method of dividing by 5 (let's just say that it purposefully calls and uses a value 1717986919 to calculate 20%). Btb2 analyzed it and found a way to alter the percentage to 50% or 100% (by ignoring the horrible function before it and simply taking the mana value or moving it by 1 byte). Replace:

  • 0x1A24B4 -> 8b 55 98 d1 ea (for 50%, since d1 ea is a single bitwise shift to the right
  • 0x1A24b4 -> 8b 55 98 90 90 (no division).

Let's take a look at the function. The following offset reads:

  • 0x1A249F: b8 *67666666* c7 45 1c 02000000 f7 e9 8b 4d 9c *d1 fa* 8b c2 c1 e8 1f 03 d0

The b8 XXXXXXXX (bolded above) function calls a hexadecimal value (note that it's in Little Endian) and saves it. The code then uses "d1 fa" (emboldened above) to divide edx by 2 before it is further used. C1 E8 1F is simply a division by 2^31 of the value. Yes, that is why the rounding may be a bit off for Magic Channel. Now let's consider replacing:

  • 67666666 with our custom value (for now let's imagine it's 56555555)
  • d1 fa with 90 90 (two nop or non-coding functions, so we basically removed this part of the code)

The result is... Division by 3. Now the Magic Channel grants 33% mana return.

To obtain a different value, we need to replace XXXXXXXX with another number. This has to be (2^33 / D) +1, where D is our divisor (3 for 1/3, 5 for 1/5, etc.). The 2^33 is multiplied with the variable (mana cost), but is then divided by 2^31 and moves by two bits elsewhere to account for the differences. The number is greater than the quotient by 1, to avoid the rounding downwards removing 1 mana point incorrectly. Note, that XXXXXXXX cannot be equal to or greater than 00000080 (0x80000000), as then the value will be negative.

The function also calls 0x1A2498 for the minimum mana value for which Magic Channel may apply. This is equal to the value of D (0x05 in base game, 0x03 in the example above).

Buildings[edit | hide]

Building names and descriptions (excluding HotA) are saved in BldgSpec.txt and BldgNeut.txt. Building requirements can be altered by changing their dependency tables. Address of each dependency table is located at:

  • 0x0EB816 - Castle
  • 0x0EB8B3 - Rampart
  • 0x0EB971 - Tower
  • 0x0EBA39 - Inferno
  • 0x0EBA48 - Necropolis
  • 0x0EBA5C - Dungeon
  • 0x0EBA70 - Stronghold
  • 0x0EBA84 - Fortress
  • 0x0EBA98 - Conflux

Note, that some building requirements are changed in HotA.dll. While it shouldn't be too difficult to determine their location in that file, (look for appropriate DWORDs in HotA.dll) for now these offsets are unknown. The requirement table for Cove and Factory may be coded differently and as far as I know, haven't been found yet.

Building costs can be changed in Building.txt.

HotA buildings[edit | hide]

Building names and descriptions for HotA are saved in HotA.dat and can be edited as a text edit using f.e. the aforementioned HotA Editor.

Building costs for HotA are saved in HotA.dat. The building names appear before the building costs. Each building cost contains of 28 bytes, each 4 bytes representing a 4-byte little endian number of cost for each resource (Wood, Mercury, Ore, Sulfur, Crystal, Gems, Gold). Note, that some buildings have text and description, but no written cost (either replaced with 0s or simply not having any space devoted to them). An example is Mana Generator. For now it is not known how to edit the cost of these buildings (and therefore the cost of the Mana Generator remains a mystery).

Resource Silos[edit | hide]

Resource Silo yield tables are located at 0x288F04. Each resource value is mentioned for each town, one by one, in 4-byte values (order of resources is Wood, Mercury, Ore, Sulphur, Crystal, Gems, Gold) with towns going in order.

Cove's Resource Silo simply copies the one from the Dungeon, while Factory copies Rampart.

The Resource Silo table is called for in exe a few times, but HotA.dll overwrites all (or most) of these calls at 0xd37ae and 0xd37ce. As of 12:19, 19 September 2024 (UTC), it is not known how to alter the Resource Silo values for Cove and Factory. No specific offset or function have been identified. ???.

Artifacts[edit | hide]

All stats given by artifacts are written into a table at 0x23e758, 4 bytes for each artifact (Attack, Defense, Power, Knowledge).

The artifact traits are specified in artraits.txt, while artifact pick-up events are defined in artevent.txt (both in Hota_lng.lod).

Interference amount of the Plate of the Dying Light is specified as a IEE-754 floating point value at 0x1d40c8 in Hota.dll

Combination Artifacts[edit | hide]

Combination artifact's components are specified at a few functions, starting at 0x04c63d. For further reading see BTB2's guide (linked below, as External Link #3). Be aware! BTB2's guide is either wrong or outdated! His method of removing components seems to work correctly, however, most likely due to HotA putting their combination artifacts in HotA.dll to push them in between base game combination artifacts, or for another reason, his method of increasing the number of items does NOT work.

However, not all is lost. There's 8 bytes of nop (90) commands starting at 0x4c8c8, and we can use them to add an extra item (to showcase it, I'll present a code for adding an extra item to the Ring of the Magi's requirements. This seems a safe method, since only a short push is used, and therefore I advise changes to 3-piece combination artifacts to simply copy this method and swap Ring of the Magi with their edited artifact).

0x4c85b 6a XX (ref item ID) -> eb 6d (jump 109 bytes forward)
0x4c8c8 90909090 90909090 -> eb 06..(skip following code)...6a XX (ref item ID) 6a YY (2nd ref item ID).....eb 8d (jump backwards 115 bytes)

Replace emboldened text with your appropriate artifact IDs. Remember to also update the number of components (in this example at 0x04C861).

Note, that the method described above only works for a jump of 125 bytes or less. Gladly, there's a few other empty spaces that can be used for adding extra components:

  • 0x4c25c (11 bytes of nop)
  • 0x4c2d6 (10 bytes)
  • 0x4c347 (9 bytes)
  • 0x4c3c7 (9 bytes)
  • 0x4c622 (14 bytes)
  • 0x4c8c8 (8 bytes)
  • 0x4ca15 (11 bytes)
  • 0x4d008 (8 bytes)

Simply use the available space within 125 bytes of the definition of any of the original components. If this can't be done, swap your artifact with another, which can be edited.

Note, that if you're using HotA, it's much safer to just edit appropriate artifact reference IDs and add other appropriate components (or replace the resulting artifact) by editing Hota.dat (see: Artifacts - artsinfo0

Making new Combination Artifacts[edit | hide]

For now it is wholly unknown how to do it. HotA devs seem to know their way around it.??? See below.

What might work is repeating a function identical to that of another artifact with different properties using some empty space. Requires further testing.

HotA Artifacts[edit | hide]

Hota's new artifacts are coded in the Hota.dat. To edit their properties, you need to edit their text (or use hexadecimal values for ASCII to match their text in hex editing). Artifacts are coded as follows:

artsinfo0[edit | hide]

This part of the file includes partial data on all HotA artifacts, written as follows:

#Artifact Name
<ref_ID>
X Y Z # Description:
P Q R # Dif abl, S points
-1

Note, that the ref_ID above is written in decimal system.

The X Y Z applies a buff to the artifact, seemingly by coding first the bonus type with X, amount with Y and optional specification with Z.

  • 0 - Increase Attack / Defense
  • 1 - Add Spell Power
  • 2 - Add Knowledge
  • 7 - Different Ability, Y = AI value ??? (it's described as "points")
  • 8 - Movement artifact?
  • 13 - Restrict spells; Y = 1 for Cloak of Silence, 4 for Ring of Oblivion
  • 16 - Add daily resource growth, Y = amount, Z = resource type (0 = wood, 6 = gold)
  • 24 - Enemy morale bonus
  • 25 - Enemy luck bonus

The P Q R are coded in the same way as above and refer to a second ability.

However, the method above seems to suggest some artifacts have different bonuses than they actually possess: Ironfist of the Ogre doesn't increase either attack or defense; Trident of Dominion increases attack by 6, etc.

This part of the file also includes definitions of all combo artifacts and their components. F.e. Diplomat's Cloak:

# Diplomat's Cloak
12 141 3 66 67 68
  • 12 is the number of the combination artifact (including SoD ones)
  • 141 is the decimal reference ID of the Diplomat's Cloak
  • 3 is the number of components
  • 66 67 68 are the reference IDs of components (decimal)

Note, that this can be used to effectively alter any base-game combination artifact! Simply add a line before these artifact definitions

# Sample Text
N RIF C R+ R++ R+++ R++++,

where N is the number of combination artifact (counting the way they're placed in the .exe code), RIF is the reference ID of the final artifact, R+, R++ and so on are the additional components. To showcase adding an extra requirement to the Ring of the Magi (since a similar concept was used above) and replacing the Ring of the Magi with the AB blade and requiring a Sword of Hellfire:

# Armageddon's Blade
10 128 1 11

(11 is the reference ID of the new item - Sword of Hellfire).

Sadly, new combination artifacts can't simply be added this way.

art<ref_ID>[edit | hide]

art<ref_ID> entries in HotA.dat (as visible in the Hota.editor.exe) can be used to alter an artifact's name, adventure map event text, description, slot type and rarity class (treasure, minor, major, relic). Here is also the true artifact bonus data coded. Note that the Reference ID is in decimal.

gold_price # cost - (cost of 0 is used if an artifact cannot normally appear, f.e. if it's a Combination Artifact.
slot # slot type (0 - none, 1 - head, 2 - shoulders, 3 - neck, 4 - right hand, 5 - left hand, 6 - torso, 7 - ring, 8 - feet, 9 - misc, 10 - ballista, 11 - ammo cart, 12 - first aid tent, 13 - catapult, 14 - spell book)
class # type (1 - none, 2 - treasure, 4 - minor, 8 - major, 16 - relic)
0 # disabled as defaults (0 - no, 1 - yes)
0 # add new spells (0 - no, 1 - yes)
0 # attack bonus (_int8_)
0 # defense bonus (_int8_)
0 # spell power bonus (_int8_)
0 # knowledge bonus (_int8_)

Creature Banks[edit | hide]

The order the banks appear in is as follows:

  1. Cyclops Stockpile
  2. Dwarven Treasury
  3. Griffin Conservatory
  4. Imp Cache
  5. Medusa Stores
  6. Naga Bank
  7. Dragon Fly Hive
  8. Shipwreck
  9. Derelict Ship
  10. Crypt
  11. Dragon Utopia

Note, that after changing these values, you still have to edit the remaining bank data in CrBanks.txt. HotA banks, except for the Ancient Altar, are all defined within the Hota.dat file, as crbank21, 22, and so on.

Hex String (Start: 0x2702A0, End: ???)
U1000000 U2000000 U3000000 U4000000 ... FFFFFFFF 00000000 00000000 00000000
Description
U1
U2
U3
U4...
Unit IDs for guards. U2-U4 etc. are optional. Note, that the 12 bytes of 00 do not appear after the last defined creature bank (Dragon Utopia).

After all of the creature banks have been defined, the reward creatures (and creatures only!) are defined as follows:

Hex String (Start: ???, End: ???)
FFFFFFFF R1000000 R2000000 R3000000 ...
Description
R1
R2
R3...
Unit IDs for reward creature for the first bank. R2-R3 etc. are the reward creatures for subsequent creature banks.

The Pyramid[edit | hide]

The pyramid is defined separately:

0xa3fa2:6a 02 6a 14 6a 7d (52 8d4508 53 50) 6a 74;
0xa3fb6: 28 00 00 00

Where:

  • 02 is the number of stacks of Diamond Golems
  • 14 is the number of Diamond Golems (in total)
  • 7d is the unit ID of Diamond Golems,
  • 74 is the unit ID of Gold Golems and
  • 28 is the number of Gold Golems.

BTB2 suggested replacing Diamond Golems with Mummies - this however, requires using a creature ID above 80, and therefore a long push (6B 8D000000 for mummies). However, to do that we would need to use some empty space. He suggested removing the -2 Luck on empty Pyramid subroutine. I decided to instead use some empty space I got from a different change, keeping the -2 Luck penalty. The result is as follows:

0x0A3FA6 → ebdf (jumps to overwrite -2 luck on empty Pyramid),
0x0A3F82 → e9 89c10100 (jump to free space 0xc0110)
68 8d000000 (Mummies)
EB 1A 90 90 (jump back to A3FA8),
0xc0110 (Free) → 8a 87 1b 01 00 00 04 fe 88 87 1b 01 00 00 (displaced code: -2 Luck on empty Pyramid),
0xc011d (Free) → E9 6b3efeff(jump to 0x0A3F8F (end of F8E))

Note, that this method assumes you have empty space at 0xc0110 (by forcing rumors to always show rumors defined by the mapmaker). If you have empty space elsewhere, simply move the function, altering the jumps appropriately.

Editing h3hota_maped[edit | hide]

All heroes are defined one by one in the h3hota_maped starting from 0x186800.

GG000000 RR000000 HH000000 SO000000 OL000000 ST000000 TL000000 SB 000000 SP000000 U1000000 U2000000 U3000000 PS000000 PL000000 R0 AS CO 00

Note, that some HotA heroes use some data from HotA.dat

Game Mechanics[edit | hide]

Starting Resources[edit | hide]

Table with the starting resources starts at 0x278170. Each 4 bytes are the next resource (Wood, Mercury, Ore, Sulfur, Crystal, Gems, Gold). Each 28 bytes is the next difficulty - Easy, Normal, Expert, etc. At 0x2781FC the AI resources start and follow the same order of resources and difficulties. The whole table thus takes 280 bytes.

Starting Bonuses[edit | hide]

Gold Bonus[edit | hide]

The starting gold bonus chooses a random value between the value written at 0x0C0002 and the value at 0x0BFFFD, and then multiplies it by 100. To change the multiplication, simply edit 0x0C000B (multiplying by 25) and 0x0C0016 (moving the value by 2 bits, so multiplying it by 4).

Resource Bonuses[edit | hide]

The starting resource bonuses use DWORD pointers to find their appropriate code to run:

  • Wood and Ore - AF FF 4B 00
  • Crystals - D6 FF 4B 00
  • Gems - E1 FF 4B 00
  • Mercury - EC FF 4B 00
  • Sulfur - F4 FF 4B 00

These DWORD pointers are located at the following addresses:

  • Castle - 0x0C01B4
  • Rampart - 0x0C01B8
  • Tower - 0x0C01BC
  • Inferno - 0x0C01C0
  • Necropolis - 0x0C01C4
  • Dungeon - 0x0C01C8
  • Stronghold - 0x0C01CC
  • Fortress - 0x0C01D0
  • Conflux - 0x0C01D4

Note, that you need to edit ScnrStar.def to reflect any altered resources.

The amount for each rare resource is most likely determined by the function at 0xc009e: ???

minimum: c745f0 33333333 (mov [ebp-0x10], 0x33333333) c745f0 3333EB3F (mov [ebp-0x1c], 0x3feb3333)
break between the two: eb 0e (jmp 0x0e)
maximum: c745f0 66666666 (mov [ebp-0x10], 0x66666666) c745f0 6666E63F (mov [ebp-0x10], 0x3FE66666)

The amount of wood and ore are most likely specified at 0xbffaf: BA 0a000000 (mov edx, 0x0a) B9 05000000 (mov ecx, 0x05)

Movement point reminder[edit | hide]

The movement point reminder is located at 0x9c91. It checks if movement points are 0 (using a 2-byte test eax, eax) and then proceeds to different code if movement points are (or not) zero. If one wants to change it to a higher number (to avoid reminding of movement for heroes that can't actually move anymore), the following code can be used:

0x9c91:       a1 c8876900 mov eax, [0x6987c8] e9 849d0d00 (jump to some arbitrary free space) 90909090
free space:  3d XY000000 cmp eax, XY - compare movement points with value XY.
   7F 0A jg 0x0a - jump 10 bytes if the value is greater.
   A1 C4 5d 6A 00 - displaced code
   e9 6f62f2ff - jump to 0x9c9f (or 49C9F)
   e9 a462f2ff - jump to 0x9cd9 (or 49CD9).

Hex value tables[edit | hide]

Hex Creature
00000000 Pikeman Pikeman
01000000 Halberdier Halberdier
02000000 Archer Archer
03000000 Marksman Marksman
04000000 Griffin Griffin
05000000 Royal Griffin Royal Griffin
06000000 Swordsman Swordsman
07000000 Crusader Crusader
08000000 Monk Monk
09000000 Zealot Zealot
0A000000 Cavalier Cavalier
0B000000 Champion Champion
0C000000 Angel Angel
0D000000 Archangel Archangel
0E000000 Centaur Centaur
0F000000 Centaur Captain Centaur Captain
10000000 Dwarf Dwarf
11000000 Battle Dwarf Battle Dwarf
12000000 Wood Elf Wood Elf
13000000 Grand Elf Grand Elf
14000000 Pegasus Pegasus
15000000 Silver Pegasus Silver Pegasus
16000000 Dendroid Guard Dendroid Guard
17000000 Dendroid Soldier Dendroid Soldier
18000000 Unicorn Unicorn
19000000 War Unicorn War Unicorn
1A000000 Green Dragon Green Dragon
1B000000 Gold Dragon Gold Dragon
1C000000 Gremlin Gremlin
1D000000 Master Gremlin Master Gremlin
1E000000 Stone Gargoyle Stone Gargoyle
1F000000 Obsidian Gargoyle Obsidian Gargoyle
20000000 Stone Golem Stone Golem
21000000 Iron Golem Iron Golem
22000000 Mage Mage
23000000 Arch Mage Arch Mage
24000000 Genie Genie
25000000 Master Genie Master Genie
26000000 Naga Naga
27000000 Naga Queen Naga Queen
28000000 Giant Giant
29000000 Titan Titan
2A000000 Imp Imp
2B000000 Familiar Familiar
2C000000 Gog Gog
2D000000 Magog Magog
2E000000 Hell Hound Hell Hound
2F000000 Cerberus Cerberus
30000000 Demon Demon
31000000 Horned Demon Horned Demon
32000000 Pit Fiend Pit Fiend
33000000 Pit Lord Pit Lord
34000000 Efreet Efreet
35000000 Efreet Sultan Efreet Sultan
36000000 Devil Devil
37000000 Arch Devil Arch Devil
38000000 Skeleton Skeleton
39000000 Skeleton Warrior Skeleton Warrior
3A000000 Walking Dead Walking Dead
3B000000 Zombie Zombie
3C000000 Wight Wight
3D000000 Wraith Wraith
3E000000 Vampire Vampire
3FD00000 Vampire Lord Vampire Lord
40000000 Lich Lich
41000000 Power Lich Power Lich
42000000 Black Knight Black Knight
43000000 Dread Knight Dread Knight
44000000 Bone Dragon Bone Dragon
45000000 Ghost Dragon Ghost Dragon
46000000 Troglodyte Troglodyte
47000000 Infernal Troglodyte Infernal Troglodyte
48000000 Harpy Harpy
49000000 Harpy Hag Harpy Hag
4A000000 Beholder Beholder
4B000000 Evil Eye Evil Eye
4C000000 Medusa Medusa
4D000000 Medusa Queen Medusa Queen
4E000000 Minotaur Minotaur
4F000000 Minotaur King Minotaur King
50000000 Manticore Manticore
51000000 Scorpicore Scorpicore
52000000 Red Dragon Red Dragon
53000000 Black Dragon Black Dragon
54000000 Goblin Goblin
55000000 Hobgoblin Hobgoblin
56000000 Wolf Rider Wolf Rider
57000000 Wolf Raider Wolf Raider
58000000 Orc Orc
59000000 Orc Chieftain Orc Chieftain
5A000000 Ogre Ogre
5B000000 Ogre Mage Ogre Mage
5C000000 Roc Roc
5D000000 Thunderbird Thunderbird
5E000000 Cyclops Cyclops
5F000000 Cyclops King Cyclops King
60000000 Behemoth Behemoth
61000000 Ancient Behemoth Ancient Behemoth
62000000 Gnoll Gnoll
63000000 Gnoll Marauder Gnoll Marauder
64000000 Lizardman Lizardman
65000000 Lizard Warrior Lizard Warrior
66000000 Gorgon Gorgon
67000000 Mighty Gorgon Mighty Gorgon
68000000 Serpent Fly Serpent Fly
69000000 Dragon Fly Dragon Fly
6A000000 Basilisk Basilisk
6B000000 Greater Basilisk Greater Basilisk
6C000000 Wyvern Wyvern
6D000000 Wyvern Monarch Wyvern Monarch
6E000000 Hydra Hydra
6F000000 Chaos Hydra Chaos Hydra
70000000 Air Elemental Air Elemental
71000000 Earth Elemental Earth Elemental
72000000 Fire Elemental Fire Elemental
73000000 Water Elemental Water Elemental
74000000 Gold Golem Gold Golem
75000000 Diamond Golem Diamond Golem
76000000 Pixie Pixie
77000000 Sprite Sprite
78000000 Psychic Elemental Psychic Elemental
79000000 Magic Elemental Magic Elemental
7A000000 NOT USED (1)
7B000000 Ice Elemental Ice Elemental
7C000000 NOT USED (2)
7D000000 Magma Elemental Magma Elemental
7E000000 NOT USED (3)
7F000000 Storm Elemental Storm Elemental
80000000 NOT USED (4)
81000000 Energy Elemental Energy Elemental
82000000 Firebird Firebird
83000000 Phoenix Phoenix
84000000 Azure Dragon Azure Dragon
85000000 Crystal Dragon Crystal Dragon
86000000 Faerie Dragon Faerie Dragon
87000000 Rust Dragon Rust Dragon
88000000 Enchanter Enchanter
89000000 Sharpshooter Sharpshooter
8A000000 Halfling Halfling
8B000000 Peasant Peasant
8C000000 Boar Boar
8D000000 Mummy Mummy
8E000000 Nomad Nomad
8F000000 Rogue Rogue
90000000 Troll Troll
91000000 Catapult Catapult
92000000 Ballista Ballista
93000000 First Aid Tent First Aid Tent
94000000 Ammo Cart Ammo Cart
95000000 Arrow Tower
96000000 Cannon Cannon
97000000 Sea Dog Sea Dog
98000000 Electric Tower
99000000 Nymph Nymph
9A000000 Oceanid Oceanid
9B000000 Crew Mate Crew Mate
9C000000 Seaman Seaman
9D000000 Pirate Pirate
9E000000 Corsair Corsair
9F000000 Stormbird Stormbird
A0000000 Ayssid Ayssid
A1000000 Sea Witch Sea Witch
A2000000 Sorceress Sorceress
A3000000 Nix Nix
A4000000 Nix Warrior Nix Warrior
A5000000 Sea Serpent Sea Serpent
A6000000 Haspid Haspid
A7000000 Satyr Satyr
A8000000 Fangarm Fangarm
A9000000 Leprechaun Leprechaun
AA000000 Steel Golem Steel Golem
AB000000 Halfling Grenadier Halfling Grenadier
AC000000 Mechanic Mechanic
AD000000 Engineer Engineer
AE000000 Armadillo Armadillo
AF000000 Bellwether Armadillo Bellwether Armadillo
B0000000 Automaton Automaton
B1000000 Sentinel Automaton Sentinel Automaton
B2000000 Sandworm Sandworm
B3000000 Olgoi-Khorkhoi Olgoi-Khorkhoi
B4000000 Gunslinger Gunslinger
B5000000 Bounty Hunter Bounty Hunter
B6000000 Couatl Couatl
B7000000 Crimson Couatl Crimson Couatl
B8000000 Dreadnought Dreadnought
B9000000 Juggernaut Juggernaut
Hex Artifact
01000000 Spell ScrollSpell Scroll - Next four bytes are for Spell ID
02000000 The GrailThe Grail
03000000 Catapult Catapult
04000000 Ballista Ballista
05000000 Ammo Cart Ammo Cart
06000000 First Aid Tent First Aid Tent
07000000 Centaur's AxeCentaur's Axe
08000000 Blackshard of the Dead KnightBlackshard of the Dead Knight
09000000 Greater Gnoll's FlailGreater Gnoll's Flail
0A000000 Ogre's Club of HavocOgre's Club of Havoc
0B000000 Sword of HellfireSword of Hellfire
0C000000 Titan's GladiusTitan's Gladius
0D000000 Shield of the Dwarven LordsShield of the Dwarven Lords
0E000000 Shield of the Yawning DeadShield of the Yawning Dead
0F000000 Buckler of the Gnoll KingBuckler of the Gnoll King
10000000 Targ of the Rampaging OgreTarg of the Rampaging Ogre
11000000 Shield of the DamnedShield of the Damned
12000000 Sentinel's ShieldSentinel's Shield
13000000 Helm of the Alabaster UnicornHelm of the Alabaster Unicorn
14000000 Skull HelmetSkull Helmet
15000000 Helm of ChaosHelm of Chaos
16000000 Crown of the Supreme MagiCrown of the Supreme Magi
17000000 Hellstorm HelmetHellstorm Helmet
18000000 Thunder HelmetThunder Helmet
19000000 Breastplate of Petrified WoodBreastplate of Petrified Wood
1A000000 Rib CageRib Cage
1B000000 Scales of the Greater BasiliskScales of the Greater Basilisk
1C000000 Tunic of the Cyclops KingTunic of the Cyclops King
1D000000 Breastplate of BrimstoneBreastplate of Brimstone
1E000000 Titan's CuirassTitan's Cuirass
1F000000 Armor of WonderArmor of Wonder
20000000 Sandals of the SaintSandals of the Saint
21000000 Celestial Necklace of BlissCelestial Necklace of Bliss
22000000 Lion's Shield of CourageLion's Shield of Courage
23000000 Sword of JudgementSword of Judgement
24000000 Helm of Heavenly EnlightenmentHelm of Heavenly Enlightenment
25000000 Quiet Eye of the DragonQuiet Eye of the Dragon
26000000 Red Dragon Flame TongueRed Dragon Flame Tongue
27000000 Dragon Scale ShieldDragon Scale Shield
28000000 Dragon Scale ArmorDragon Scale Armor
29000000 Dragonbone GreavesDragonbone Greaves
2A000000 Dragon Wing TabardDragon Wing Tabard
2B000000 Necklace of DragonteethNecklace of Dragonteeth
2C000000 Crown of DragontoothCrown of Dragontooth
2D000000 Still Eye of the DragonStill Eye of the Dragon
2E000000 Clover of FortuneClover of Fortune
2F000000 Cards of ProphecyCards of Prophecy
30000000 Ladybird of LuckLadybird of Luck
31000000 Badge of CourageBadge of Courage
32000000 Crest of ValorCrest of Valor
33000000 Glyph of GallantryGlyph of Gallantry
34000000 SpeculumSpeculum
35000000 SpyglassSpyglass
36000000 Amulet of the UndertakerAmulet of the Undertaker
37000000 Vampire's CowlVampire's Cowl
38000000 Dead Man's BootsDead Man's Boots
39000000 Garniture of InterferenceGarniture of Interference
3A000000 Surcoat of CounterpoiseSurcoat of Counterpoise
3B000000 Boots of PolarityBoots of Polarity
3C000000 Bow of Elven CherrywoodBow of Elven Cherrywood
3D000000 Bowstring of the Unicorn's ManeBowstring of the Unicorn's Mane
3E000000 Angel Feather ArrowsAngel Feather Arrows
3F000000 Bird of PerceptionBird of Perception
40000000 Stoic WatchmanStoic Watchman
41000000 Emblem of CognizanceEmblem of Cognizance
42000000 Statesman's MedalStatesman's Medal
43000000 Diplomat's RingDiplomat's Ring
44000000 Ambassador's SashAmbassador's Sash
45000000 Ring of the WayfarerRing of the Wayfarer
46000000 Equestrian's GlovesEquestrian's Gloves
47000000 Necklace of Ocean GuidanceNecklace of Ocean Guidance
48000000 Angel WingsAngel Wings
49000000 Charm of ManaCharm of Mana
4A000000 Talisman of ManaTalisman of Mana
4B000000 Mystic Orb of ManaMystic Orb of Mana
4C000000 Collar of ConjuringCollar of Conjuring
4D000000 Ring of ConjuringRing of Conjuring
4E000000 Cape of ConjuringCape of Conjuring
4F000000 Orb of the FirmamentOrb of the Firmament
50000000 Orb of SiltOrb of Silt
51000000 Orb of Tempestuous FireOrb of Tempestuous Fire
52000000 Orb of Driving RainOrb of Driving Rain
53000000 Recanter's CloakRecanter's Cloak
54000000 Spirit of OppressionSpirit of Oppression
55000000 Hourglass of the Evil HourHourglass of the Evil Hour
56000000 Tome of FireTome of Fire
57000000 Tome of AirTome of Air
58000000 Tome of WaterTome of Water
59000000 Tome of EarthTome of Earth
5A000000 Boots of LevitationBoots of Levitation
5B000000 Golden BowGolden Bow
5C000000 Sphere of PermanenceSphere of Permanence
5D000000 Orb of VulnerabilityOrb of Vulnerability
5E000000 Ring of VitalityRing of Vitality
5F000000 Ring of LifeRing of Life
60000000 Vial of LifebloodVial of Lifeblood
61000000 Necklace of SwiftnessNecklace of Swiftness
62000000 Boots of SpeedBoots of Speed
63000000 Cape of VelocityCape of Velocity
64000000 Pendant of DispassionPendant of Dispassion
65000000 Pendant of Second SightPendant of Second Sight
66000000 Pendant of HolinessPendant of Holiness
67000000 Pendant of LifePendant of Life
68000000 Pendant of DeathPendant of Death
69000000 Pendant of Free WillPendant of Free Will
6A000000 Pendant of NegativityPendant of Negativity
6B000000 Pendant of Total RecallPendant of Total Recall
6C000000 Pendant of CouragePendant of Courage
6D000000 Everflowing Crystal CloakEverflowing Crystal Cloak
6E000000 Ring of Infinite GemsRing of Infinite Gems
6F000000 Everpouring Vial of MercuryEverpouring Vial of Mercury
70000000 Inexhaustible Cart of OreInexhaustible Cart of Ore
71000000 Eversmoking Ring of SulfurEversmoking Ring of Sulfur
72000000 Inexhaustible Cart of LumberInexhaustible Cart of Lumber
73000000 Endless Sack of GoldEndless Sack of Gold
74000000 Endless Bag of GoldEndless Bag of Gold
75000000 Endless Purse of GoldEndless Purse of Gold
76000000 Legs of LegionLegs of Legion
77000000 Loins of LegionLoins of Legion
78000000 Torso of LegionTorso of Legion
79000000 Arms of LegionArms of Legion
7A000000 Head of LegionHead of Legion
7B000000 Sea Captain's HatSea Captain's Hat
7C000000 Spellbinder's HatSpellbinder's Hat
7D000000 Shackles of WarShackles of War
7E000000 Orb of InhibitionOrb of Inhibition
7F000000 Vial of Dragon BloodVial of Dragon Blood
80000000 Armageddon's BladeArmageddon's Blade
81000000 Angelic AllianceAngelic Alliance
82000000 Cloak of the Undead KingCloak of the Undead King
83000000 Elixir of LifeElixir of Life
84000000 Armor of the DamnedArmor of the Damned
85000000 Statue of LegionStatue of Legion
86000000 Power of the Dragon FatherPower of the Dragon Father
87000000 Titan's ThunderTitan's Thunder
88000000 Admiral's HatAdmiral's Hat
89000000 Bow of the SharpshooterBow of the Sharpshooter
8A000000 Wizard's WellWizard's Well
8B000000 Ring of the MagiRing of the Magi
8C000000 CornucopiaCornucopia
8D000000 Diplomat's CloakDiplomat's Cloak
8E000000 Pendant of ReflectionPendant of Reflection
8F000000 Ironfist of the OgreIronfist of the Ogre
90000000 Invalid
91000000 Invalid
92000000 Cannon Cannon
93000000 Trident of DominionTrident of Dominion
94000000 Shield of Naval GloryShield of Naval Glory
95000000 Royal Armor of NixRoyal Armor of Nix
96000000 Crown of the Five SeasCrown of the Five Seas
97000000 Wayfarer's BootsWayfarer's Boots
98000000 Runes of ImminencyRunes of Imminency
99000000 Demon's HorseshoeDemon's Horseshoe
9A000000 Shaman's PuppetShaman's Puppet
9B000000 Hideous MaskHideous Mask
9C000000 Ring of SuppressionRing of Suppression
9D000000 Pendant of DownfallPendant of Downfall
9E000000 Ring of OblivionRing of Oblivion
9F000000 Cape of SilenceCape of Silence
A0000000 Golden GooseGolden Goose
A1000000 Horn of the AbyssHorn of the Abyss
A2000000 Charm of EclipseCharm of Eclipse
A3000000 Seal of SunsetSeal of Sunset
A4000000 Plate of Dying LightPlate of Dying Light
A5000000 SleepkeeperSleepkeeper
Hex Spell
01000000  Scuttle Boat
02000000  Visions
03000000  View Earth
04000000  Disguise
05000000  View Air
06000000  Fly
07000000  Water Walk
08000000  Dimension Door
09000000  Town Portal
0A000000  Quicksand
0B000000  Land Mine
0C000000  Force Field
0D000000  Fire Wall
0E000000  Earthquake
0F000000  Magic Arrow
10000000  Ice Bolt
11000000  Lightning Bolt
12000000  Implosion
13000000  Chain Lightning
14000000  Frost Ring
15000000  Fireball
16000000  Inferno
17000000  Meteor Shower
18000000  Death Ripple
19000000  Destroy Undead
1A000000  Armageddon
1B000000  Shield
1C000000  Air Shield
1D000000  Fire Shield
1E000000  Protection from Air
1F000000  Protection from Fire
20000000  Protection from Water
21000000  Protection from Earth
22000000  Anti-Magic
23000000  Dispel
24000000  Magic Mirror
25000000  Cure
26000000  Resurrection
27000000  Animate Dead
28000000  Sacrifice
29000000  Bless
2A000000  Curse
2B000000  Bloodlust
2C000000  Precision
2D000000  Weakness
2E000000  Stone Skin
2F000000  Disrupting Ray
30000000  Prayer
31000000  Mirth
32000000  Sorrow
33000000  Fortune
34000000  Misfortune
35000000  Haste
36000000  Slow
37000000  Slayer
38000000  Frenzy
39000000  Titan's Lightning Bolt
3A000000  Counterstrike
3B000000  Berserk
3C000000  Hypnotize
3D000000  Forgetfulness
3E000000  Blind
3F000000  Teleport
40000000  Remove Obstacle
41000000  Clone
42000000  Summon Fire Elemental
43000000  Summon Earth Elemental
44000000  Summon Water Elemental
45000000  Summon Air Elemental
46000000 Stone Gaze

External links[edit | hide]

  1. heroescommunity.com - Editing heroes in memory - Includes a large number of various Reference IDs
  2. heroescommunity.com - How to edit Hota? - Thread with majority of useful information, scrambled across 112 forum pages.
  3. BTB2's hacking guide - primarily detailing creation of his own mod, but including tips, explanations and some of the Reference IDs
  4. void_17's database - this database describes most or all of the functions in the base game of heroes 3.