|
|
AlexSpl

   
    
Responsible
Supreme Hero
|
posted September 21, 2026 01:32 PM |
|
Edited by AlexSpl at 14:43, 21 Sep 2026.
|
Actually, the code should be as follows -
m_school = akSpellTraits[spell].m_school;
if ( (m_school & 1) != 0 )
{
v6 = 0;
equipped = this->equipped;
while ( equipped->type != ARTIFACT_ORB_OF_THE_FIRMAMENT )
{
++v6;
++equipped;
if ( v6 >= 19 )
{
m_targetCombo = akArtifactTraits[ARTIFACT_ORB_OF_THE_FIRMAMENT].m_targetCombo;
if ( m_targetCombo != COMBO_NONE && hero::IsWieldingArtifact(this, combo_artifacts[m_targetCombo].type) )
goto LABEL_25;
goto LABEL_7;
}
}
if ( this->SSLevel[SKILL_AIR_MAGIC] > 0 ) goto LABEL_25;
}
The middle part just checks if the orb is amongst the artifacts of the equipped set. We know that there are no sets which would require any of the orbs.
So, let's see if we can make our patch tiny and tidy without launching it from jmpers into so-called 'free space' 
How do we write this->SSLevel[SKILL_AIR_MAGIC] > 0 check in assembler? First of all, this is a pointer to our hero and reliably backed up and stored in the register esi, the field SSLevel of the hero class has the offset of 0xC9, and SKILL_AIR_MAGIC has ID = 0xF (15).
So we may write (0xC9 + 0xF = 0xD8) -
mov al, [esi+0D8h]; Now we have our Air Magic secondary skill mastery level in the al register
test al, al; Asking the CPU if and how al is different from 0
jle @SkipMultiplier; jle stands for <= X, and if yes, jumps to @SkipMultiplier label (address/command). In this case we asked the CPU above how al is different from 0, so this will be the comparison <= 0
Or, in the machine language, -
8A 86 D8 00 00 00
84 C0
7E xx
So, it's just 10 bytes per orb. Tiny and tidy.
Now it's up to you where you want to place this check, and the Orb of the Firmament will require Air Magic from now on.
If you feel slightly (heavily) overwhelmed, fret not and just choose Advanced Hex-Patching (Basic Hex-Patching) at your next level-up. Good Luck
|
|
phoenix4ever

 
     
Legendary Hero
Heroes is love, Heroes is life
|
posted September 21, 2026 03:52 PM |
|
|
Thanks Alex
I'm afraid I have to wait a bit to level up and hopefully be offered "Advanced Hex-Patching" in the future. 
Maybe I should just turn the orbs down to 30% or something, HotA also buffed Sorcery and I don't want damage spells to dominate everything.
|
|
purerogue3

 
   
Famous Hero
|
posted September 21, 2026 04:51 PM |
|
|
AlexSpl said: So, let's see if we can make our patch tiny and tidy without launching it from jmpers into so-called 'free space' 
yeah I don't know if it's just me, but very rarely when I see '9090' and try to use it, it crashes - don't know if it's hota/original, or 'memory' things. but if i hack off a bit from existing code that I know what it does, it works sometimes - like I tripped on an invisible wire I don't know the existance of
|
|
AlexSpl

   
    
Responsible
Supreme Hero
|
posted September 21, 2026 05:04 PM |
|
Edited by AlexSpl at 17:05, 21 Sep 2026.
|
Advanced Hex-Patching is never an easy work. Complex patches with non-trivial changes require writing hundreds or sometimes even thousands of bytes in hex, which is a tiresome and dull work, even if you write your patches in assembler first.
With the patcher_x86, all I would have to do to solve the task above is to write something like this -
_Hero_* hero = (_Hero*)c->esi;
if (hero->SSkill[SKILL_AIR_MAGIC] > 0) return EXEC_DEFAULT;
It might seem another difficult thingy to learn, but if you are really going to build a big mod, you will be stashing your byte-code until it gets the muck and the mire, and you will no longer have a will or enough time to maintain it.
|
|
purerogue3

 
   
Famous Hero
|
posted September 21, 2026 05:47 PM |
|
|
I suppose there is a sweet spot between the bottom-up or top-down approach, trading off thoroughness for timeliness.
But eventually if you want full mastery you would have to be proficient with both sides of the coin.
|
|
AlexSpl

   
    
Responsible
Supreme Hero
|
posted September 21, 2026 06:25 PM |
|
Edited by AlexSpl at 18:29, 21 Sep 2026.
|
|
There is a difference between reading and understanding a disassembled/decompiled code of a game and writing a whole mod in pure assembler/byte-code. In the first case, you still have to find addresses to put your jumps, but after that you write in a high-level language, like you would do if you have had a source code. Think of plugins like NewSpells. It would be a nightmare to write all the code required in hex, even using an assembler to produce byte-code (FASM, for example).
|
|
purerogue3

 
   
Famous Hero
|
posted September 21, 2026 06:38 PM |
|
|
I'm not saying your approach is wrong - it's probably the correct one.
I'm saying eventually high-level programmers like yourself will wander or dare I say 'challenge' themselves to the nitty-gritty.
Some people are just disposed to a certain approach because that is the way their brain works.
|
| |
|
|