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


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


Supreme Hero
Heroes is love, Heroes is life
posted September 28, 2016 12:11 PM

Thanks that worked, but if it changes Stronghold's ballista yard, I won't change Castle's blacksmith.

How about switching Dungeons ballista with Infernos ammo cart, would that be possible?

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

Hero of Order
Part of the furniture
posted September 28, 2016 12:33 PM

I think you're confusing things, Phoenix .

All Town types have their own Warfare unit, whether that's the Ballista, the Ammo Cart or the First Aid Tent. You should be able to set this for each Town type individually.

Stronghold, however, has a Ballista Yard in addition to the Blacksmith. While the Blacksmith produces Ammo Carts, the Ballista Yard provides Ballistae (as the name would imply ). Apparently, they simply hard-coded the Ballista Yard to provide the player with the same warmachine as provided by the Castle Blacksmith.

So if you only change the Castle to give First Aid Tents instead of Ballistae, then the Ballista Yard in Stronghold will also give First Aid Tents - in addition to the Ammo Carts provided by the Stronghold Blacksmith.
____________
The last Reasonable Steward of Good Game Design and a Responsible Hero of HC. - Verriker

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


Supreme Hero
Heroes is love, Heroes is life
posted September 28, 2016 12:43 PM
Edited by phoenix4ever at 12:46, 28 Sep 2016.

Oh yeah, I know that Maurice, just tested it.
And that is the problem, I can't change Castle's war machine, cause then I will also change Stronghold's ballista yard, to give first aid tent also.
Still think I will give Necropolis ballista and if I could give Dungeon ammo cart and Inferno ballista it would be perfect.  

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


Supreme Hero
Heroes is love, Heroes is life
posted September 29, 2016 12:57 PM

OxFEA said:
*001C322F: 80
*001C325F: 60


OxFEA do you know the offsets and what to input if I wan't Inferno to have ballista and Dungeon to have ammo cart?

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

Hero of Order
Part of the furniture
posted September 29, 2016 01:24 PM

I didn't check the H3HotA.exe with the latest addresses posted by 0xFEA, but aren't they simply in the same general area, Phoenix?

Overview:
Castle: Ballista
Tower: Ammo Cart
Inferno: Ammo Cart
Fortress: First Aid Tent
Rampart: First Aid Tent
Dungeon: Ballista
Stronghold: Ammo Cart
Necropolis: First Aid Tent
Conflux: Ballista
Cove: Cannon

Taking 0xFEA's entry:
*001C322F: 80
*001C325F: 60

I assume the 80 is for the Castle Blacksmith, with the value 80 representing the First Aid Tent, while the Ballista has a value of 60. If so, the unedited h3hota.exe file should show the value 80 three times around the memory address 001C322F (and further, I assume these 10 factions each have 4 bytes representing the respective warmachine?), while the value 60 occurs three times as well. Whatever other value occurs three times there then has to be the Ammo Cart. Cove is the last one, with its Cannon being only sold in the Cove Town.

I'll take a look at it tonight if I get around to it, hopefully getting a better understanding of how the game handles it.
____________
The last Reasonable Steward of Good Game Design and a Responsible Hero of HC. - Verriker

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


Supreme Hero
Heroes is love, Heroes is life
posted September 29, 2016 01:33 PM
Edited by phoenix4ever at 14:06, 29 Sep 2016.

Yeah I came to that conslusion too Maurice, but the numbers does'nt make much sense to me there, for example I can only find "60" once at 1C322F and no where else.
But I would be happy if you would take a look at it and maybe make some sense of it or if OxFEA comes around.  

Edit:
Hmm for some reason I can't just change Necropolis' blacksmith, when I enter the two inputs for the two offsets in the exe and test it, it shows the ballista in their blacksmith, but the "buy button" is inactive and it can't be bought. (?)
This is more complex than I initially thought...

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


Promising
Famous Hero
feanor on DF2.ru
posted September 29, 2016 02:43 PM
Edited by OxFEA at 14:46, 29 Sep 2016.

No, it's not a data array.
It's a assembler code that fills a data array at the start of game.
It'll be not so bad if compiler didn't make some optimizations.

Quote:
[smileys]
CPU Disasm
Address   Hex dump                      Command                                  Comments
005C3220  /.  83C8 FF                   OR EAX,FFFFFFFF
005C3223  |.  BA 06000000               MOV EDX,6
005C3228  |.  B9 05000000               MOV ECX,5
005C322D  |.  C705 60AA6A00 04000000    MOV DWORD PTR DS:[6AAA60],4 ;Castle
005C3237  |.  A3 64AA6A00               MOV DWORD PTR DS:[6AAA64],EAX
005C323C  |.  8915 68AA6A00             MOV DWORD PTR DS:[6AAA68],EDX ;Rampart
005C3242  |.  A3 6CAA6A00               MOV DWORD PTR DS:[6AAA6C],EAX
005C3247  |.  890D 70AA6A00             MOV DWORD PTR DS:[6AAA70],ECX ;Tower
005C324D  |.  A3 74AA6A00               MOV DWORD PTR DS:[6AAA74],EAX
005C3252  |.  890D 78AA6A00             MOV DWORD PTR DS:[6AAA78],ECX ;Inferno
005C3258  |.  A3 7CAA6A00               MOV DWORD PTR DS:[6AAA7C],EAX
005C325D  |.  8915 80AA6A00             MOV DWORD PTR DS:[6AAA80],EDX ;Necropolis
005C3263  |.  A3 84AA6A00               MOV DWORD PTR DS:[6AAA84],EAX
005C3268  |.  C705 88AA6A00 04000000    MOV DWORD PTR DS:[6AAA88],4 ;Dungeon
005C3272  |.  A3 8CAA6A00               MOV DWORD PTR DS:[6AAA8C],EAX
005C3277  |.  890D 90AA6A00             MOV DWORD PTR DS:[6AAA90],ECX ;Barbs
005C327D  |.  A3 94AA6A00               MOV DWORD PTR DS:[6AAA94],EAX
005C3282  |.  8915 98AA6A00             MOV DWORD PTR DS:[6AAA98],EDX ;Fortress
005C3288  |.  A3 9CAA6A00               MOV DWORD PTR DS:[6AAA9C],EAX
005C328D  |.  C705 A0AA6A00 04000000    MOV DWORD PTR DS:[6AAAA0],4 ;Flux
005C3297  |.  A3 A4AA6A00               MOV DWORD PTR DS:[6AAAA4],EAX
005C329C  .  C3                        RETN
005C329D      90                        NOP
005C329E      90                        NOP
005C329F      90                        NOP


(all addresses are in-mem, for exe offsets substract 0x400000)

So, for placing ballista to any other town (without exchanging, as I did earlier) we should replace mov addr, register command with longer mov addr, const and fill remains of lower commands with nops (it's useless in this code, so in this case it's safe)

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

Hero of Order
Part of the furniture
posted September 29, 2016 04:54 PM
Edited by Maurice at 17:03, 29 Sep 2016.

OxFEA said:
No, it's not a data array.
It's a assembler code that fills a data array at the start of game.
It'll be not so bad if compiler didn't make some optimizations.

Quote:

CPU Disasm
Address   Hex dump                      Command                                  Comments
005C3220  /.  83C8 FF                   OR EAX,FFFFFFFF
005C3223  |.  BA 06000000               MOV EDX,6
005C3228  |.  B9 05000000               MOV ECX,5
005C322D  |.  C705 60AA6A00 04000000    MOV DWORD PTR DS:[6AAA60],4 ;Castle
005C3237  |.  A3 64AA6A00               MOV DWORD PTR DS:[6AAA64],EAX
005C323C  |.  8915 68AA6A00             MOV DWORD PTR DS:[6AAA68],EDX ;Rampart
005C3242  |.  A3 6CAA6A00               MOV DWORD PTR DS:[6AAA6C],EAX
005C3247  |.  890D 70AA6A00             MOV DWORD PTR DS:[6AAA70],ECX ;Tower
005C324D  |.  A3 74AA6A00               MOV DWORD PTR DS:[6AAA74],EAX
005C3252  |.  890D 78AA6A00             MOV DWORD PTR DS:[6AAA78],ECX ;Inferno
005C3258  |.  A3 7CAA6A00               MOV DWORD PTR DS:[6AAA7C],EAX
005C325D  |.  8915 80AA6A00             MOV DWORD PTR DS:[6AAA80],EDX ;Necropolis
005C3263  |.  A3 84AA6A00               MOV DWORD PTR DS:[6AAA84],EAX
005C3268  |.  C705 88AA6A00 04000000    MOV DWORD PTR DS:[6AAA88],4 ;Dungeon
005C3272  |.  A3 8CAA6A00               MOV DWORD PTR DS:[6AAA8C],EAX
005C3277  |.  890D 90AA6A00             MOV DWORD PTR DS:[6AAA90],ECX ;Barbs
005C327D  |.  A3 94AA6A00               MOV DWORD PTR DS:[6AAA94],EAX
005C3282  |.  8915 98AA6A00             MOV DWORD PTR DS:[6AAA98],EDX ;Fortress
005C3288  |.  A3 9CAA6A00               MOV DWORD PTR DS:[6AAA9C],EAX
005C328D  |.  C705 A0AA6A00 04000000    MOV DWORD PTR DS:[6AAAA0],4 ;Flux
005C3297  |.  A3 A4AA6A00               MOV DWORD PTR DS:[6AAAA4],EAX
005C329C  .  C3                        RETN
005C329D      90                        NOP
005C329E      90                        NOP
005C329F      90                        NOP


(all addresses are in-mem, for exe offsets substract 0x400000)

So, for placing ballista to any other town (without exchanging, as I did earlier) we should replace mov addr, register command with longer mov addr, const and fill remains of lower commands with nops (it's useless in this code, so in this case it's safe)


Actually, you may not need to. You just need to replace the ECX and EDX references OR the pointer addresses, as each is specific for a given Town type. Apparently, for Castle, Dungeon and Conflux, the hard-coded value of 4 is moved into the pointer address mentioned (incidently, the Artifact code for the Ballista is 4!), while for the other Town Types, it's the values held by the ECX and EDX registers. If I recall my disassembly stuff from a year ago (on X-Com: Terror From The Deep), that should be possible without changing too much.

The assembly instruction 890D performs a move of the value in register ECX into the pointer address that follows it, while 8915 does it for the value held in the EDX register. That means it's at least possible to swap the Ammo Carts and First Aid Tents at will. For Ballistae it's a bit harder as they apparently don't have a register holding the value, but rather move a hard value into those areas.

The instructions to fill the ECX and EDX registers precede the filling of the Town Types. If I am not mistaken, the artifact ID of the Ammo Cart is 5 and the First Aid Tent is 6. Heck, I would even think it's possible that way to add any Artifact :P. It wouldn't surprise me if below the surface, the Blacksmith and the Artifact Merchant work very similar.
____________
The last Reasonable Steward of Good Game Design and a Responsible Hero of HC. - Verriker

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


Supreme Hero
Heroes is love, Heroes is life
posted September 29, 2016 05:35 PM

Sorry you guys, I did'nt understand much of the last two posts.

But can you tell me where and what I need to input for Necropolis and Inferno to have ballista, Dungeon to have ammo cart (and Castle to have First Aid Tent, but I guess that's impossible without ruining Strongholds ballista yard?)

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

Hero of Order
Part of the furniture
posted September 29, 2016 07:08 PM
Edited by Maurice at 13:24, 30 Sep 2016.

Basically, the values are filled through some assembly code. I'll try to disect it for you, since assembly isn't trivial to understand.

Starting from address 001C3220 up to address 001C329F within the h3hota.exe, you can find the following set of hex values:

83 C8 FF BA 06 00 00 00 B9 05 00 00 00 C7 05 60 AA 6A 00 04 00 00 00 A3 64 AA 6A 00 89 15 68 AA 6A 00 A3 6C AA 6A 00 89 0D 70 AA 6A 00 A3 74 AA 6A 00 89 0D 78 AA 6A 00 A3 7C AA 6A 00 89 15 80 AA 6A 00 A3 84 AA 6A 00 C7 05 88 AA 6A 00 04 00 00 00 A3 8C AA 6A 00 89 0D 90 AA 6A 00 A3 94 AA 6A 00 89 15 98 AA 6A 00 A3 9C AA 6A 00 C7 05 A0 AA 6A 00 04 00 00 00 A3 A4 AA 6A 00 C3 90 90 90

These are assembly instructions, telling the game to initialize specific values at game start. In this very particular case, it tells the game which Warmachine to provide through the Blacksmith of each Town type. Assembly works through various registers, moving and manipulating values held in each, based on various logic operations. Commonly used registers (which have a special purpose within assembly for ease of use) are EAX, ECX and EDX. Breaking down the above into the relevant assembly segments (color coded, red are assembly instructions, while blue are values and green are memory pointer addresses), we get:

83 C8 FF
Tells the game to initialize the EAX register, basically writing 'FFFFFFFF' (32 bits in total, binary 1111 1111 1111 1111 1111 1111 1111 1111) into it. Don't ask me the purpose of this value, but the game apparently needs it (edit: I suspect it has to do with the Spell Scroll. All Artifacts on a Hero have this value after the ID, except the Spell Scroll. In that case, this value holds the Spell ID for the spell on the scroll).

BA 06 00 00 00
Moves the value 6 into register EDX. Note that 6 is the Artifact ID for the First Aid Tent.

B9 05 00 00 00
Likewise, this instruction moves the value 5 into the register ECX. Note that 5 is the Artifact ID for the Ammo Cart.

C7 05 60 AA 6A 00 04 00 00 00
C7 05 is the instruction that moves a hard value (the 04 00 00 00 at the end) into the memory location referenced by the pointer. Note that the value 4 is the Artifact ID for the Ballista. According to 0xFEA's list, this memory address is used for the Castle Town type - as well as the Stronghold Ballista Yard.

A3 64 AA 6A 00
A3 is the instruction to move the contents of register EAX into the memory address pointed to by the pointer. Note that this pointer is 32 bits ahead of the address for the Castle warmachine. Similar counts for the other Town types, below.

89 15 68 AA 6A 00
This instruction moves the contents of the EDX register into the memory location pointed at. EDX contains the Artifact ID of the First Aid Tent, while the memory location is for Rampart.

A3 6C AA 6A 00
Like the previous A3 instruction, but different location. Will not further explain these in the list below, should be obvious .

89 0D 70 AA 6A 00
Like the 89 15 instruction above, this instruction also moves the register contents into a memory location. In this case it's the value held by the register ECX, which holds the Artifact ID of the Ammo Cart. This one refers to Tower.

A3 74 AA 6A 00

89 0D 78 AA 6A 00
Fills the Blacksmith of Inferno with an Ammo Cart.

A3 7C AA 6A 00

89 15 80 AA 6A 00
This one is for Necropolis, putting a First Aid Tent there.

A3 84 AA 6A 00

C7 05 88 AA 6A 00 04 00 00 00
Dungeon gets a Ballista.

A3 8C AA 6A 00

89 0D 90 AA 6A 00
Stronghold gets an Ammo Cart.

A3 94 AA 6A 00

89 15 98 AA 6A 00
Fortress gets a First Aid Tent.

A3 9C AA 6A 00

C7 05 A0 AA 6A 00 04 00 00 00
Conflux gets a Ballista.

A3 A4 AA 6A 00

C3 - tells the code to exit this subroutine and return to the spot in the code from where it was called.

90 90 90 - does nothing, these are just filler bytes, used to fill up the instruction set to a length of binary dimensions.

Note that by changing instructions 89 0D to 89 15, you assign that particular Town type the First Aid Tent, instead of the Ammo Cart. Likewise, if you change 89 15 to 89 0D, you swap the Ammo Cart for a First Aid Tent, for that Town.

Of course, you might want to add a Ballista to a Town that by default holds a First Aid Tent or an Ammo Cart. You can't just change the 89 0D / 89 15 instruction by a C7 05 instruction, since the length that follows after it is different. If you were to insert it anyway, you'd mess up the offset of all other instructions following it in the .exe file.

What you can do, though, is swap the pointer addresses for the various Towns. That's basically what 0xFEA did, when he instructed you on those 60 and 80 values; the locations he pointed at are within the memory location pointers. For instance, you can swap the pointer address for Rampart and Castle. That way, you're free to choose an Artifact ID you wish to present in Rampart Towns, while you restrict Castle to one of the two values held in either register ECX or EDX.

Basically, you have 3 Town Types where you can freely assign an Artifact ID to be provided through the Blacksmith, while the other 6 have to derive it either from the value held in ECX or EDX.

The funny thing is: since the game assigns Artifact ID's to the various Blacksmiths, you could also insert any other Artifact ID and you'd be able to buy that one from the Blacksmith instead .

One thing to keep in mind when swapping Warmachines around: the War Machine Factory map object. If it works like the Ballista Yard from Stronghold, you might get interesting results when you swap stuff. As for a full Artifact ID listing, below are all the ID's for the Artifacts up to and including SoD (I don't have a list for Horn of the Abyss, though trial and error should yield them fast enough):

Artifacts-
00 - Spellbook
01 - Spell scroll*
02 - The Grail
03 - Catapult
04 - Ballista
05 - Ammo Cart
06 - First Aid Tent
07 - Centaur's axe
08 - Blackshard of the dead knight
09 - Greater Gnoll's Fail
0A - Ogre's club of havoc
0B - Sword of Hellfire
0C - Titan's gladius
0D - Shield of the dwarven lords
0E - Shield of the yawning dead
0F - Buckler of the gnoll king
10 - Targ of the rampaging ogre
11 - Shield of the dammed
12 - Sentinel's Shield
13 - Helm of the alabaster unicorn
14 - Skull helmet
15 - Helm of chaos
16 - Crown of the supreme magi
17 - Hellstorm helmet
18 - Thunder helmet
19 - Beastplate of petrified wood
1A - Rib cage
1B - Scales of the greater balilisk
1C - Tunic of the cyclops king
1D - Breastplate of brimstone
1E - Titan's cuirass
1F - Armor of wonder
20 - Sandals of the saint
21 - Celestial necklace of bliss
22 - Lion's shield of courage
23 - Sword of judgement
24 - Helm of hevenly enlightenment
25 - Quiet eye of the dragon
26 - Red dragon flame tongue
27 - Dragon scale shield
28 - Dragon scale armor
29 - Dragonbone greaves
2A - Dragon wing tabard
2B - Neckace of dragonteeth
2C - Crown of dragontooth
2D - Still eye of the dragon
2E - Clover of fortune
2F - Cards of prophecy
30 - Ladybird of luck
31 - Badge of courage
32 - Crest of valor
33 - Gryph of gallantry
34 - Speculum
35 - Spyglass
36 - Amulet of the undertaker
37 - Vampire's cowl
38 - Dead men's boots
39 - Garniture of interference
3A - Surcoat of counterpoise
3B - Boots of polarity
3C - Bow of elven cherrywood
3D - Bowstring of the unicorns's mane
3E - Angel feather arrows
3F - Bird of perception
40 - Stoic watchman
41 - Emblem of cognizance
42 - Statesmen's medal
43 - Diplomat Ring
44 - Ambassador's sash
45 - Ring of the wayfarer
46 - Equestrian's gloves
47 - Necklace of ocean guidance
48 - Angel wings
49 - Charm of mana
4A - Talisman of mana
4B - Mystic orb of mana
4C - Collar of conjuring
4D - Ring of conjuring
4E - Cape of conjuring
4F - Orb of firmament
50 - Orb of silt
51 - Orb of tempestous fire
52 - Orb of driving rain
53 - Recanter's cloak
54 - Spirit of opression
55 - Hourglass of the evil hour
56 - Tome of fire magic
57 - Tome of wind magic
58 - Tome of water magic
59 - Tome of earth magic
5A - Boots of levitation
5B - Golden bow
5C - Sphere of permanence
5D - Orb of vulnerability
5E - Ring of vitality
5F - Ring of life
60 - Vail of lifeblood
61 - Necklace of swiftness
62 - Boots of speed
63 - Cape of velocity
64 - Pendant of dispassion
65 - Pendant of second sight
66 - Pendant of holiness
67 - Pendant of life
68 - Pendant of death
69 - Pendant of free will
6A - Pendant of agitation
6B - Pendant of total recall
6C - Pendant of courage
6D - Everflowing cristal cloak
6E - Ring of infinite gems
6F - Everpouring vial of mercury
70 - Inexhaustable cart of ore
71 - Eversmoking ring of sulfur
72 - Inexhaustable cart of lumber
73 - Endless sack of gold
74 - Endless bag of gold
75 - Endless purse of gold
76 - Legs of legion
77 - Loins of legion
78 - Torso of legion
79 - Arms of legion
7A - Head of legion
7B - Sea capitan's hat
7C - Spellbinder's hat
7D - Shackles of war
7E - Orb of inhibition

(combine artifacts and specials)
7F - vial of dragonblood
80 - Armageddon's blade
81 - angelic alliance
82 - Cloak of undead king
83 - Elixir of life
84 - Armor of the dammed
85 - Statue of legions
86 - Power of the dragon father
87 - Titans lightning
88 - Admiral's hat
89 - Archer's bow

Update: I just tried to swap stuff around and put the Armageddon's Blade into the Castle Blacksmith. Sure enough I could buy it .

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


Supreme Hero
Heroes is love, Heroes is life
posted September 29, 2016 07:49 PM
Edited by phoenix4ever at 19:53, 29 Sep 2016.

Wow Maurice you really are a genius.
I'm not sure I understood much of that or I really wan't to understand it.
This is by far the most complex thing to change in Heroes 3 so far and I'm not sure I wanna bother with it, at least not right now.
I wish there was an easier solution or maybe I'm just stupid. Either way thanks for that excessive explanation.    

Btw pretty funny you can put artifacts in blacksmiths, I'm sure some map-makers could make good use of that.

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

Hero of Order
Part of the furniture
posted September 30, 2016 01:41 AM
Edited by Maurice at 01:49, 30 Sep 2016.

In all honesty, it's not that hard to understand what the subroutine does, with the explanation I gave above. At run time, as it initializes a map for play, it reserves a memory section for the generic Town stuff. Part of that is the Warmachine being offered for each of the 9 Town types (I am excluding Cove here, they must have implemented in a different way).

Based on the pointers to the memory locations, we can see that the code reserves a section from 60 AA 6A 00 through A7 AA 6A 00 for this purpose (note that the final section starts at A4 AA 6A 00, but since each section is 4 bytes in size, the final byte will be at memory location A7 AA 6A 00).

It's a total of 72 bytes, 8 bytes per Town type. Differentiating between Town types, we get the following memory addresses:

Castle:     60 AA 6A 00 - 67 AA 6A 00
Rampart:    68 AA 6A 00 - 6F AA 6A 00
Tower:      70 AA 6A 00 - 77 AA 6A 00
Inferno:    78 AA 6A 00 - 7F AA 6A 00
Necropolis: 80 AA 6A 00 - 87 AA 6A 00
Dungeon:    88 AA 6A 00 - 8F AA 6A 00
Stronghold: 90 AA 6A 00 - 97 AA 6A 00
Fortress:   98 AA 6A 00 - 9F AA 6A 00
Conflux:    A0 AA 6A 00 - A7 AA 6A 00


At runtime, the game fills these 9 sets of 8 bytes with the proper Artifact information. The assembly code that does this makes use of 3 registers initially, EAX, ECX and EDX. The register EBX exists as well, but since they're not using that one here, I can only guess it is holding onto some other variable that they need to keep track of.

Artifact information consists of two parts, each 4 bytes in length. The first 4 bytes contain the Artifact ID. The next 4 bytes are always FF FF FF FF, except for Spell Scrolls. For Spell Scrolls, the second set of 4 bytes contains the Spell ID of the spell that's on the scroll. Since we're dealing with Warmachines here and not Spell Scrolls, the second set of 4 bytes are FF FF FF FF for all Town Types.

This value is stored in register EAX before the above locations get filled. Registers ECX and EDX are filled with respectively the ID for the Ammo Cart and the First Aid Tent. With those values set, the code then starts to fill the memory locations with the proper information:

- Since it lacks a register with the ID for the Ballista, this value is inserted as a hard value into the memory location;
- Next, it completes the Castle entry by adding the contents of register EAX, so the full Castle Artifact section of the Blacksmith will read 04 00 00 00 FF FF FF FF in memory;
- It then fills the first part of the Rampart Warmachine by copying the value held in the register EDX into that first part;
- Like with the Castle, the 8 bytes are completed by copying the contents of register EAX into the final 4 bytes;
- Next it addresses Tower, filling the first 4 bytes with the contents of register ECX;
- The second set of 4 bytes is once again copied from register EAX;
Etc ...

In the end, the 72 bytes in memory, starting from address 60 AA 6A 00 will look like this:

Castle:     04 00 00 00 FF FF FF FF
Rampart:    06 00 00 00 FF FF FF FF
Tower:      05 00 00 00 FF FF FF FF
Inferno:    05 00 00 00 FF FF FF FF
Necropolis: 06 00 00 00 FF FF FF FF
Dungeon:    04 00 00 00 FF FF FF FF
Stronghold: 05 00 00 00 FF FF FF FF
Fortress:   06 00 00 00 FF FF FF FF
Conflux:    04 00 00 00 FF FF FF FF


You can manipulate the build-up of these 72 bytes, by changing the assembly instructions that refer the various registers and/or the memory location pointers. With the latter, you need to make sure you still cover all Town types, otherwise you're probably getting one or more Town types with an invalid Artifact ID entry for the Blacksmith, potentially crashing your game when you (or the AI) tries to access it.

Let's take a look at Castle, Rampart and Tower, from my previous post. The assembly instructions read:

Castle:
C7 05 60 AA 6A 00 04 00 00 00 A3 64 AA 6A 00

Rampart:
89 15 68 AA 6A 00 A3 6C AA 6A 00

Tower:
89 0D 70 AA 6A 00 A3 74 AA 6A 00

Let's say I want to add Ballista to Tower and First Aid Tent to Castle, while I also want to change Rampart's First Aid Tent to Ammo Cart. Starting with the latter one, it's a simple matter of changing the instruction 89 15 to 89 0D. As I already detailed, instruction 89 15 instructs the game to put the contents of register EDX (which contains the Artifact ID for the First Aid Tent) into the first 4 bytes for that Town Type. In contrast, instruction 89 0D does the same, except then from register ECX, which is what I wanted to achieve. The code for Rampart then changes to:

Rampart:
89 0D 68 AA 6A 00 A3 6C AA 6A 00

With this change, Rampart towns will now provide Ammo Carts instead of First Aid Tents.

The other one - putting Ballista in Tower and First Aid Tent in Castle - is a bit more elaborate. That's because there's no register holding the Artifact ID for the Ballista, so if we want to get it into Tower, we'll have to swap the memory location pointers of Tower with another Town type - in this case I choose Castle. The instructions then become:

Tower:
C7 05 70 AA 6A 00 04 00 00 00 A3 74 AA 6A 00

Castle:
89 0D 60 AA 6A 00 A3 64 AA 6A 00

Note that I swapped the name as well as the memory location pointers. While technically you don't need to swap the location in the A3 section, it's cleaner to keep everything of a given Town together.

With this change, the Tower Blacksmith will now provide Ballistae ingame. Castle still needs a change, because in this form, it still inserts the contents of register ECX into the Castle Blacksmith, which contains the Artifact ID of the Ammo Cart while I want to have the Town provide First Aid Tents. We do this by swapping the instruction 89 0D for 89 15, which is the instruction that looks at the contents of register EDX instead.

With these changes, we end up with:

Tower:
C7 05 70 AA 6A 00 04 00 00 00 A3 74 AA 6A 00

Rampart:
89 0D 68 AA 6A 00 A3 6C AA 6A 00

Castle:
89 15 60 AA 6A 00 A3 64 AA 6A 00

We're flexible in how we assign the 9 Town types a value. Three can be determined individually, as the code inserts a hard value into them, but by swapping around memory location pointers, we're free to choose which 3 Town types will make use of that. The other 6 are restricted to the contents of registers ECX and EDX, of which we can choose one for any of those 6 Town types. We can set those at the very beginning of the subroutine, that's the only freedom we have. Note, though, that we're free to choose what to put into ECX and EDX, like I already proved by having Armageddon's Blade from the Castle Blacksmith . Even if we stick with the Warmachines, we can still swap them around and for instance put the Artifact ID for Ballistae into register ECX, while we're pulling out the Ammo Cart, to be inserted as a hard value instead of the Ballista.

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


Supreme Hero
Heroes is love, Heroes is life
posted September 30, 2016 08:22 AM

Okay thanks for another excessive explanation.
I kinda get it know.
Would it even be possible to give Necropolis and Inferno ballista and Dungeon ammo cart when there is one more ballista and one less first aid tent than normally?
Or maybe I could just swap Infernos ammo cart with Dungeons ballista for a start?

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

Hero of Order
Part of the furniture
posted September 30, 2016 08:50 AM

You could just swap those, by swapping the memory location pointers of those two towns. Just use the above explanation, but then for Dungeon and Inferno .

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


Supreme Hero
Heroes is love, Heroes is life
posted September 30, 2016 09:10 AM

Okay I'll try that and forget about Castle and Necropolis, I guess.
Thanks.

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

Hero of Order
Part of the furniture
posted September 30, 2016 02:16 PM
Edited by Maurice at 14:39, 30 Sep 2016.

I think you need to take a step back and try to see what you want to achieve from a somewhat more distant perspective. Once you have a clear image of what you want to achieve, you can zoom in on the details to make the changes.

The above assembly instructions fill the Artifact ID of each of the 9 Town types in the proper memory location for that Town. As such, you should start with the Town type list and design it from there.

Current set of assembly instructions:

Initial register values:
83 C8 FF - EAX is filled with 'FF FF FF FF'
BA 06 00 00 00 - EDX is filled with '06 00 00 00' (Artifact ID of the First Aid Tent)
B9 05 00 00 00 - ECX is filled with '05 00 00 00' (Artifact ID of the Ammo Cart)

The rest of the instructions fill the 72 byte array that holds the 9 Artifact ID's for each of the 9 Town types:
C7 05 60 AA 6A 00 04 00 00 00 - Castle gets '04 00 00 00' (hard value, Artifact ID of the Ballista)
A3 64 AA 6A 00 - Completed with EAX
89 15 68 AA 6A 00 - Rampart gets contents of EDX
A3 6C AA 6A 00 - Completed with EAX
89 0D 70 AA 6A 00 - Tower gets contents of ECX
A3 74 AA 6A 00 - Completed with EAX
89 0D 78 AA 6A 00 - Inferno gets contents of ECX
A3 7C AA 6A 00 - Completed with EAX
89 15 80 AA 6A 00 - Necropolis gets contents of EDX
A3 84 AA 6A 00 - Completed with EAX
C7 05 88 AA 6A 00 04 00 00 00 - Dungeon gets '04 00 00 00' (hard value, Artifact ID of the Ballista)
A3 8C AA 6A 00 - Completed with EAX
89 0D 90 AA 6A 00 - Stronghold gets contents of ECX
A3 94 AA 6A 00 - Completed with EAX
89 15 98 AA 6A 00 - Fortress gets contents of EDX
A3 9C AA 6A 00 - Completed with EAX
C7 05 A0 AA 6A 00 04 00 00 00 - Conflux gets '04 00 00 00' (hard value, Artifact ID of the Ballista)
A3 A4 AA 6A 00 - Completed with EAX
C3 - return code
90 90 90 - filler bytes

Let's say I want to have the following setup:

Castle: First Aid Tent
Tower: First Aid Tent
Rampart: Ammo Cart
Inferno: Ballista
Necropolis: Ballista
Dungeon: Ammo Cart
Stronghold: Ballista
Fortress: Ballista
Conflux: The Grail (just because I want to be able to buy a Grail )

We see that I want to have 2 First Aid Tents, 2 Ammo Carts, 4 Ballistae and 1 Grail. The Ballistae are currently provided by inserting the value '04 00 00 00' hard into the proper memory location, of which I only have 3 instructions. As such, I am going to have to move the Ballista over to one of the two registers. Let's take ECX for that. In that case, I have to put the value '04 00 00 00' into it, instead of the current value '05 00 00 00', which is the Ammo Cart.

In the above listed subroutine, that's the instruction

B9 05 00 00 00

which we need to replace with

B9 04 00 00 00

For readability, I've bolded the byte you need to change to make this happen.

For Conflux, I am going to insert the Grail. Since it already uses a free value, I can simply change that one. The Grail has Artifact ID 02, the instruction for Conflux changes as follows:

The Conflux entry:
C7 05 A0 AA 6A 00 04 00 00 00 -> C7 05 A0 AA 6A 00 02 00 00 00

We have two Warmachines left to consider, the Ammo Cart (which is currently not assigned at all) and the First Aid Tent, which is still getting stored in the EDX register. We have two free values left and since the Ammo Cart is only assigned twice, we will use the two free values for the Ammo Cart. That covers all Town types and Warmachines.

In my setup, the Ammo Cart is assigned to Dungeon and Rampart. Dungeon already uses a free value to assign the Ballista, so that one is changed easily:

The Dungeon entry:
C7 05 88 AA 6A 00 04 00 00 00 -> C7 05 88 AA 6A 00 05 00 00 00

For Rampart, however, we need to swap it with Castle, since that's the only Town type left with a free value. As such, we need to perform the following transformations:

The original Castle entries:
C7 05 60 AA 6A 00 04 00 00 00 -> C7 05 68 AA 6A 00 05 00 00 00
A3 64 AA 6A 00 -> A3 6C AA 6A 00

The original Rampart entries:
89 15 68 AA 6A 00 -> 89 15 60 AA 6A 00
A3 6C AA 6A 00 -> A3 64 AA 6A 00

This basically swaps Castle and Rampart in the list, so the original Castle entry has now become the new Rampart entry and vice versa.

With the Grail and the Ammo Cart assigned to the three free values, it's time to take a look at the current ECX and EDX register value assignments to the remaining six Town types:
Castle: First Aid Tent -> held in register EDX
Tower: First Aid Tent -> held in register EDX
Inferno: Ballista -> held in register ECX (after I changed the contents of that register earlier)
Necropolis: Ballista -> held in register ECX
Stronghold: Ballista -> held in register ECX
Fortress: Ballista -> held in register ECX

With the swap between Rampart and Castle, the new Castle entry already gets assigned the value held within register EDX, so no change is needed there. Tower currently receives the contents of ECX, but I want the contents of EDX, so I need to change that:

The Tower entry:
89 0D 70 AA 6A 00 -> 89 15 70 AA 6A 00

The other Town types require the contents of the ECX register, but only two of them already do, Inferno and Stronghold. The ECX register originally held the Artifact ID for the Ammo Cart, which were available in these Towns, but after inserting the Artifact ID of the Ballista into the register ECX, these Towns immediately get the correct value according to my initial desire for these Towns. The two that remain are Necropolis and Fortress, which need to be changed as follows, like the Tower entry above:

The Necropolis entry:
89 15 80 AA 6A 00 -> 89 0D 80 AA 6A 00

The Fortress entry:
89 15 98 AA 6A 00 -> 89 0D 98 AA 6A 00

With these changes, starting up a game will now cause these Warmachines to be provided, by Town type:

Castle: First Aid Tent
Tower: First Aid Tent
Rampart: Ammo Cart
Inferno: Ballista
Necropolis: Ballista
Dungeon: Ammo Cart
Stronghold: Ballista
Fortress: Ballista
Conflux: The Grail

That's all there is to it. The resulting assembly code in the exe should now look like this (with the altered bytes highlighted with bold text, 11 altered bytes in total):

83 C8 FF
BA 06 00 00 00
B9 04 00 00 00
C7 05 68 AA 6A 00 05 00 00 00
A3 6C AA 6A 00
89 15 60 AA 6A 00
A3 64 AA 6A 00
89 15 70 AA 6A 00
A3 74 AA 6A 00
89 0D 78 AA 6A 00
A3 7C AA 6A 00
89 0D 80 AA 6A 00
A3 84 AA 6A 00
C7 05 88 AA 6A 00 05 00 00 00
A3 8C AA 6A 00
89 0D 90 AA 6A 00
A3 94 AA 6A 00
89 0D 98 AA 6A 00
A3 9C AA 6A 00
C7 05 A0 AA 6A 00 02 00 00 00
A3 A4 AA 6A 00
C3
90 90 90

or, without line breaks, as you won't see those when you HEX edit the exe file:

83 C8 FF BA 06 00 00 00 B9 04 00 00 00 C7 05 68 AA 6A 00 05 00 00 00 A3 6C AA 6A 00 89 15 60 AA 6A 00 A3 64 AA 6A 00 89 15 70 AA 6A 00 A3 74 AA 6A 00 89 0D 78 AA 6A 00 A3 7C AA 6A 00 89 0D 80 AA 6A 00 A3 84 AA 6A 00 C7 05 88 AA 6A 00 05 00 00 00 A3 8C AA 6A 00 89 0D 90 AA 6A 00 A3 94 AA 6A 00 89 0D 98 AA 6A 00 A3 9C AA 6A 00 C7 05 A0 AA 6A 00 02 00 00 00 A3 A4 AA 6A 00 C3 90 90 90

Basically, when designing your setup of Warmachines per Town type, you have to first consider which 2 Artifact ID's you want to put into your registers ECX and EDX. As it is, 6 Town types are going to derive their Warmachine from either one of these two. The remaining 3 Town types can be chosen freely. You may need to have to swap memory location pointers around though to get these three Town types into the proper entry above, just like I did with Rampart in the example. Since I wanted to assign the Ballista to 4 Town types, I couldn't do it for those Town types through a free value, but had to shift it to one of the two registers instead.

Hopefully this clarifies it a bit more .
____________
The last Reasonable Steward of Good Game Design and a Responsible Hero of HC. - Verriker

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


Famous Hero
posted September 30, 2016 07:09 PM

Great work. We must copy all to pdf tutorial. It is a lot of data.
By the way. How to add ballista missile to centaur? We have shoot animation so adding it give us new shooter like HI and II?

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

Hero of Order
Part of the furniture
posted September 30, 2016 07:36 PM
Edited by Maurice at 20:06, 30 Sep 2016.

I think that goes way beyond the easy editing detailed above. You're talking about a whole new logic for an existing unit.

Note also that the only way I could disect this information in this way was because of the pointers provided by 0xFEA. I wouldn't have been able to find the subroutine just by myself, as I never did any real disassembly of the Heroes executables.

Edit: I suspect a lot of 0xFEA's information comes from Russian or Polish forums, as Heroes 3 seems a lot more popular over there than here in Western Europe. Since my mother language is Germanic-based, I have a hard time making sense of Slavic languages; it's pretty much impossible for me to understand Russian or Polish forums - and even after Google translate, it's not easy to make sense of it .

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


Supreme Hero
Heroes is love, Heroes is life
posted September 30, 2016 10:41 PM

Thanks again Maurice.
I have been working all day today and will be working all day tomorrow, but I will probably look at editing war machines this monday. Wish me luck.  

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


Promising
Famous Hero
feanor on DF2.ru
posted September 30, 2016 11:37 PM

Baronus said:

By the way. How to add ballista missile to centaur?

0043DBB0 0F0F
+flags
+shots amount in txt
+maybe, cranim.txt

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Jump To: « Prev Thread . . . Next Thread » This thread is 11 pages long: 1 2 3 4 5 6 7 8 9 10 11 · «PREV / NEXT»
Post New Poll    Post New Topic    Post New Reply

Page compiled in 0.2484 seconds