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 ]
HOMM1: info forum | HOMM2: info forum | HOMM3: info mods forum | HOMM4: info CTG forum | HOMM5: info mods forum | MMH6: wiki forum | MMH7: wiki forum
Heroes Community > Heroes 3.5 - WoG and Beyond > Thread: Heroes 3 Hacking Reference Guide
Thread: Heroes 3 Hacking Reference Guide This thread is 41 pages long: 1 10 20 30 ... 32 33 34 35 36 ... 40 41 · «PREV / NEXT»
AlexSpl
AlexSpl


Responsible
Supreme Hero
posted November 02, 2022 11:26 PM

Quote:
And would having the hook at 0x4E6723 change the health in advance and I ould than handle the already changed health?

No, you place your result in c->eax and by EXEC_DEFAULT the patcher executes wiped instructions, so, effectively, your result is what will be at [esi+4Ch]. Think of LoHooks with EXEC_DEFAULT as of just inserting your code before an instruction at the address of your hook. Very convenient.

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


Adventuring Hero
posted November 02, 2022 11:31 PM

Ah, ok. That's a good description of what is going on. I'll keep this in mind.

Thank you

Parascus
____________

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


Adventuring Hero
posted November 03, 2022 10:56 AM

Hi,

now I have a method beeing called several times. In my method I would need the creature and the hero that owns the unit. I tried to figure out how I get both of the hook context but I did not get consistent data. One time I thought the hero is stored in the ecx but the next time it has been called it was not a hero anymore. And could it be that the context does not include the creature data?

Any thoughts how to get them?

Kind regards

Parascus
____________

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


Responsible
Supreme Hero
posted November 03, 2022 04:00 PM
Edited by AlexSpl at 16:02, 03 Nov 2022.

Quote:
Any thoughts how to get them?

For different low hooks, sources of the game structures will be different, too. Usually, you get them from a hook's context. For example,

army* Army = (army*)c->edi;
hero* Hero = *(hero**)(c->ebp + 8);


You need to know where pointers to the structures you need are stored. High hooks make life easier, but I'm not sure you want to get acquainted with them as of yet.

And thus, to answer your question, I should at least know what addresses you are talking about.

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


Adventuring Hero
posted November 03, 2022 04:45 PM
Edited by Parascus at 17:43, 03 Nov 2022.

AlexSpl said:

For different low hooks, sources of the game structures will be different, too. Usually, you get them from a hook's context. For example,

army* Army = (army*)c->edi;
hero* Hero = *(hero**)(c->ebp + 8);




Just tried them. Army* (in my case of H3API h3::H3CombatCreature) crahes the game and Hero* (in my case h3::H3Hero) leads to an empty name.

AlexSpl said:

You need to know where pointers to the structures you need are stored. High hooks make life easier, but I'm not sure you want to get acquainted with them as of yet.



High hooks sounds like something a bloody newbee should avoid. Thanks for the warning.

AlexSpl said:

And thus, to answer your question, I should at least know what addresses you are talking about.


No doubt it would be helpful to know where I am. I know have a hook for the first aid at 0x4E6723 and returning with EXEC_DEFAULT. I try to get the creature level, the hero speciality and the hero secondary skill to decide how much of additional health points the creature gets.

Having Adelaide with Pikemen I get the Context with
  EAX: a (probably base health points of Pikemen)
  EBP: 199490 starting with "54 95 19 00 B6 41 5F 00 00 00 00 00 AC 94 19 00 00 00 00 00 C6 88 6C 06" unknown content.
  EBX: 0 (seems to be additional health points, e.g. given by an artifact. Having Vial of Lifeblood equiped it is 2.)
  ECX: 66C88C6 (This seams to be Adelaide, I see the name beginning at 66C890A but I do not see Adelaide's ID (0B)
  EDI: 66C8A8B (16 zeros followed by many FFs)
  EDX: 4C10010 (The creature name "Pikemen" but in the following next to this name there are other texts like Forgetfulness, Hypnotize, Hypnotize (again), Berserk, ...)
  ESI: 1994AC starting with "00 00 00 00 00 00 00 00 0C 55 67 00 00 55 67 00 10 00 00 00 10 10 C1 04 10 00" unknown content
  ESP: 199474 starting with "B0 D2 8D 0D 80 D2 8D 0D C0 E8 8D 0D 48 95 19 00 E1 84 63 00 FF FF FF FF C6 88" unknown content

A test with the Angels of Adelaide shows a difference with EAX (C8), prouving its the initial health. Also EDX changes, now showing the text of Angels (singular and plural) and other text info. Using Ufretin and once again Pikemen the address of ECX changes to 66Ca432 also with his name some bytes later but no other clue, what data is this and address of EDI changes also but the byte content is similar as EDI with Adelaide.

"10 00 10 00 00 00 01 10 C4 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0A 00 11 00 00 00 12 86 0A 5D 00 55 66 72 65 74 69 6E 00 00 00 00 00 00 02 00 00 00 11 FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 FF FF FF 02 02 18 06 00 00 18 06 00 00 3D 00 00 00 01 00" (The content with Ufretin at 066CA432).

Best regards

Parascus







____________

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


Responsible
Supreme Hero
posted November 03, 2022 05:54 PM

You are inside the following function:

void __thiscall SOD_add_hero_bonuses(hero *this, enum TCreatureType creatureType, TCreatureTypeTraits *creature)
{
 int primarySkill; // eax
 hero *hero; // ebx
 type_artifact *equippedArtifacts; // eax
 int v6; // ecx
 THeroSpecificAbility *v7; // edi
 int isPartOfComboArtifact; // eax
 int defense; // ecx
 int defense_2; // eax
 int damageLow_1; // ecx
 int damageHigh; // eax
 TCreatureType spec1; // ecx
 enum TCreatureType creatureType_1; // ebx
 __int32 v15; // eax
 int defense_1; // ecx
 int damageLow; // ebx
 int i_slot; // eax
 type_artifact *iArtifact; // ecx
 int speedBonus; // edi
 int combo; // eax
 int i_slot_1; // eax
 type_artifact *iArtifact_1; // ecx
 int healthBonus; // ebx
 int combo_1; // eax
 double v26; // [esp+1Ch] [ebp-Ch]

 hero = this;
 LOBYTE(primarySkill) = this->primarySkill[0];
 if ( primarySkill <= 99 )
 {
   if ( primarySkill <= 0 )
     primarySkill = 0;
   else
     primarySkill = primarySkill;
 }
 else
 {
   primarySkill = 99;
 }
 creature->attack += primarySkill;
 LOBYTE(primarySkill) = this->primarySkill[1];
 if ( primarySkill <= 99 )
 {
   if ( primarySkill <= 0 )
     primarySkill = 0;
   else
     primarySkill = primarySkill;
 }
 else
 {
   primarySkill = 99;
 }
 creature->defense += primarySkill;
 v7 = &akHeroSpecificAbilities[this->ID];
 v6 = 0;
 equippedArtifacts = hero->equippedArtifacts;
 while ( equippedArtifacts->id != VIAL_OF_DRAGON_BLOOD )
 {
   ++v6;
   ++equippedArtifacts;
   if ( v6 >= 19 )
   {
     isPartOfComboArtifact = akArtifactTraits[VIAL_OF_DRAGON_BLOOD].isPartOfComboArtifact;
     if ( isPartOfComboArtifact == -1
       || !hero::IsWieldingArtifact(hero, ComboArtSetUpPo[isPartOfComboArtifact].comboID) )
     {
       goto LABEL_18;
     }
     break;
   }
 }
 if ( (creature->flags & 0x80000000) != 0 )
 {
   defense = creature->defense;
   creature->attack += 5;
   creature->defense = defense + 5;
 }
LABEL_18:
 if ( v7->spec == 1 || v7->spec == 4 )
 {
   spec1 = v7->param1;
   creatureType_1 = creatureType;
   if ( creatureType != spec1 )
   {
     if ( spec1 == CID_BALLISTA )
       goto LABEL_39;
     v15 = !gpGame->mapKind
        && (spec1 == CID_AIR_ELEMENTAL
         || spec1 == CID_EARTH_ELEMENTAL
         || spec1 == CID_FIRE_ELEMENTAL
         || spec1 == CID_WATER_ELEMENTAL)
         ? -1
         : GetMonsterUpgrade(spec1);
     if ( creatureType != v15 )
       goto LABEL_39;
     creatureType_1 = creatureType;
   }
   if ( v7->spec == 1 )
   {
     v26 = (this->level / (creature->tier + 1)) * 0.05;
     creature->attack = (ceil(akCreatureTypeTraits[creatureType_1].attack * v26) + creature->attack);
     creature->defense = (ceil(akCreatureTypeTraits[creatureType_1].defense * v26) + creature->defense);
     if ( (creature->flags & 0x40) == 0 )
       goto LABEL_38;
   }
   else
   {
     defense_1 = creature->defense;
     creature->attack += v7->spec2;
     damageLow = creature->damageLow;
     creature->defense = v7->spec3 + defense_1;
     creature->damageLow = v7->spec4 + damageLow;
     creature->damageHigh += v7->spec4;
     if ( this->ID == HERO_XERON )
LABEL_38:
       ++creature->speed;
   }
LABEL_39:
   hero = this;
   goto LABEL_40;
 }
 if ( v7->spec == 7 && (akCreatureTypeTraits[creatureType].flags & 0x80000000) != 0 )
 {
   defense_2 = creature->defense;
   damageLow_1 = creature->damageLow;
   creature->attack += v7->spec2;
   creature->defense = v7->spec3 + defense_2;
   damageHigh = creature->damageHigh;
   creature->damageLow = v7->spec4 + damageLow_1;
   creature->damageHigh = v7->spec4 + damageHigh;
 }
LABEL_40:
 if ( (creature->flags & 0x40) == 0 )
 {
   speedBonus = 0;
   i_slot = 0;
   iArtifact = hero->equippedArtifacts;
   do
   {
     if ( iArtifact->id == NECKLACE_OF_SWIFTNESS )
       goto BREAK;
     ++i_slot;
     ++iArtifact;
   }
   while ( i_slot < 19 );
   combo = akArtifactTraits[NECKLACE_OF_SWIFTNESS].isPartOfComboArtifact;
   if ( combo != -1 && hero::IsWieldingArtifact(hero, ComboArtSetUpPo[combo].comboID) )
BREAK:
     speedBonus = 1;
   if ( hero::IsWieldingArtifact(hero, RING_OF_THE_WAYFARER) )
     ++speedBonus;
   if ( hero::IsWieldingArtifact(hero, CAPE_OF_VELOCITY) )
     speedBonus += 2;
   if ( akHeroSpecificAbilities[hero->ID].spec == 5 )
     speedBonus += 2;
   creature->speed += speedBonus;
 }
 healthBonus = 0;
 i_slot_1 = 0;
 iArtifact_1 = this->equippedArtifacts;
 do
 {
   if ( iArtifact_1->id == RING_OF_VITALITY )
     goto BREAK_1;
   ++i_slot_1;
   ++iArtifact_1;
 }
 while ( i_slot_1 < 19 );
 combo_1 = akArtifactTraits[RING_OF_VITALITY].isPartOfComboArtifact;
 if ( combo_1 != -1 && hero::IsWieldingArtifact(this, ComboArtSetUpPo[combo_1].comboID) )
BREAK_1:
   healthBonus = 1;
 if ( hero::IsWieldingArtifact(this, RING_OF_LIFE) )
   ++healthBonus;
 if ( hero::IsWieldingArtifact(this, VIAL_OF_LIFEBLOOD) )
   healthBonus += 2;
 if ( (akCreatureTypeTraits[creatureType].flags & 0x10) != 0 && hero::IsWieldingArtifact(this, ELIXIR_OF_LIFE) )
   healthBonus += akCreatureTypeTraits[creatureType].health / 4;
 creature->health += healthBonus; // Your hook is here
}


Hope, it will help. Just try to compare this listing with the assembler listing you see in IDA. I can provide immediate answers, of course, but it's always better to "rotate" things in mind by yourself.

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


Responsible
Supreme Hero
posted November 03, 2022 09:13 PM
Edited by AlexSpl at 21:20, 03 Nov 2022.

Btw, join to the testing of my superadvanced plugin (well, it's the real modern technology which uses the spell deque, lol) that makes Cure and Dispel to remove only one spell effect. FairDispelSpells. This is the level you will achieve in the end of your friendship with the patcher_x86 and Heroes API Sometimes simple things require deep knowledge.

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


Adventuring Hero
posted November 03, 2022 10:14 PM
Edited by Parascus at 22:14, 03 Nov 2022.

Hi AlexSpl,

give a man a fish and he has to eat for a day. Teach him fishing and he will have a daily meal to the end of his life. Nothing to say against this .

I have take a closer look and tried to do "some" comments on it:
      void __thiscall SOD_add_hero_bonuses(hero *this, enum TCreatureType creatureType, TCreatureTypeTraits *creature)
      {
      int primarySkill; // eax
      hero *hero; // ebx
      type_artifact *equippedArtifacts; // eax
      int v6; // ecx
      THeroSpecificAbility *v7; // edi
      int isPartOfComboArtifact; // eax
      int defense; // ecx
      int defense_2; // eax
      int damageLow_1; // ecx
      int damageHigh; // eax
      TCreatureType spec1; // ecx
      enum TCreatureType creatureType_1; // ebx
      __int32 v15; // eax
      int defense_1; // ecx
      int damageLow; // ebx
      int i_slot; // eax
      type_artifact *iArtifact; // ecx
      int speedBonus; // edi
      int combo; // eax
      int i_slot_1; // eax
      type_artifact *iArtifact_1; // ecx
      int healthBonus; // ebx
      int combo_1; // eax
      double v26; // [esp+1Ch] [ebp-Ch]
     
      hero = this;
      /*
      * Make sure, first primary skill of hero (attack) is between 0 and 99
      */

E639B: LOBYTE(primarySkill) = this->primarySkill[0];
E63A4: if ( primarySkill <= 99 )
    : {
E63AF: if ( primarySkill <= 0 )
E63B8: primarySkill = 0;
    : else
E63B3: primarySkill = primarySkill;
    : }
    : else
    : {
E63A8: primarySkill = 99;
    : }
    :
    : /*
    : * Add attack skill of hero to creatures attack
    : */
E63C0: creature->attack += primarySkill; // Here, ESI is the CombatCreature
    :
    : /*
    : * Make sure, second primary skill of hero (defense) is between 0 and 99
    : */
E63C5: LOBYTE(primarySkill) = this->primarySkill[1];
E63CB: if ( primarySkill <= 99 )
    : {
E63D6: if ( primarySkill <= 0 )
E63DF: primarySkill = 0;
    : else
E63DA: primarySkill = primarySkill;
    : }
    : else
    : {
E63CF: primarySkill = 99;
    : }
    :
    : /*
    : * Add defense skill of hero to creatures defense
    : */
E63E4: creature->defense += primarySkill;  // Here, ESI again is the CombatCreature
    :
    : /*
    : * Get the speciality of the hero
    : */
    : v7 = &akHeroSpecificAbilities[this->ID];  
: // > Id (ebx+1a) is stored in eax
: // > ecx is loaded with address of specialities - Way is the opcode mov ecx,["Heroes3 HD.exe"+279C80] but the comment is "(00678420)" (that is the first speciality)?
: // > now eax is set to the effective address of eax (hero id) + 4 times eax (hero id). Ok ...great ... ah what???
: // > edi is set to the ecx ("wrong" speciality offset address) where fivefold of the hero id is added 8 times. Ok, ok, ok ... but why?
    : v6 = 0;  // ECX set to 0
    : /*
    : * Check if the hero has the Vial Of Dragon Blood in any of the 18 slots as well as if it equipped as part of a combi artifact
    : * Remark: H3API does not know this artifact
    : */
E63FA: equippedArtifacts = hero->equippedArtifacts;
E6400: while ( equippedArtifacts->id != VIAL_OF_DRAGON_BLOOD )
    : {
E6405: ++v6;
E6406: ++equippedArtifacts;
E6409: if ( v6 >= 19 )
    : {
E640E: isPartOfComboArtifact = akArtifactTraits[VIAL_OF_DRAGON_BLOOD].isPartOfComboArtifact;
E641A: if ( isPartOfComboArtifact == -1
    : || !hero::IsWieldingArtifact(hero, ComboArtSetUpPo[isPartOfComboArtifact].comboID) )
: // > Here I asume a wild eax and ecx address calculation which leads to a call of D9460 but here I'm totally lost what it is doing
    : {
    : goto LABEL_18;
    : }
    : break;
    : }
    : }
    :
    : /*
    : * The Vial Of Dragon Blood is equipped
    : * Add 5 to attack and defense of the creature
    : */
E6437: if ( (creature->flags & 0x80000000) != 0 )
    : {
E6440: defense = creature->defense;
 -  : creature->attack += 5;
E6452: creature->defense = defense + 5;
    : }
    :
    : /*
    : * Check on Creature Speciality (static or scaling)
    : */
    : LABEL_18:
E6455: if ( v7->spec == 1 || v7->spec == 4 )
    : {
    : spec1 = v7->param1;
    : creatureType_1 = creatureType;
    : // This block I don't understand completely I think it is a special treatment of ballista and ...?
    : if ( creatureType != spec1 )
    : {  // The creature is not the specialized one
    : if ( spec1 == CID_BALLISTA )
E64B6: goto LABEL_39;
    : v15 = !gpGame->mapKind
E64E1: && (spec1 == CID_AIR_ELEMENTAL
E64E6: || spec1 == CID_EARTH_ELEMENTAL
E64EB: || spec1 == CID_FIRE_ELEMENTAL
E64F0: || spec1 == CID_WATER_ELEMENTAL)
E64F5: ? -1
E64FA: : GetMonsterUpgrade(spec1);
E6502: if ( creatureType != v15 )
    : goto LABEL_39;
    : creatureType_1 = creatureType;
    : }
E650C: if ( v7->spec == 1 )
    : {  // Adding attack and defense in dependence to the level of the hero and the creature level
    : v26 = (this->level / (creature->tier + 1)) * 0.05;
    : creature->attack = (ceil(akCreatureTypeTraits[creatureType_1].attack * v26) + creature->attack);
    : creature->defense = (ceil(akCreatureTypeTraits[creatureType_1].defense * v26) + creature->defense);
    : if ( (creature->flags & 0x40) == 0 )
    : goto LABEL_38;
    : }
    : else
    : {  // Adding attack and defense in dependence of sepciality data
E65AD: defense_1 = creature->defense;
E65B3: creature->attack += v7->spec2;
E65B9: damageLow = creature->damageLow;
E65BF: creature->defense = v7->spec3 + defense_1;
E65C8: creature->damageLow = v7->spec4 + damageLow;
    : creature->damageHigh += v7->spec4;
E65DF: if ( this->ID == HERO_XERON )
    : LABEL_38:
E65E7: ++creature->speed;
    : }
    : LABEL_39:
E65ED: hero = this; // why this? hero = this is allready set above
    : goto LABEL_40;
    : }  // Special treatment for Dragons
    : if ( v7->spec == 7 && (akCreatureTypeTraits[creatureType].flags & 0x80000000) != 0 )  // Is akCreatureTypeTraits = 0x002703B8?
    : {
    : defense_2 = creature->defense;
    : damageLow_1 = creature->damageLow;
    : creature->attack += v7->spec2;
    : creature->defense = v7->spec3 + defense_2;
    : damageHigh = creature->damageHigh;
    : creature->damageLow = v7->spec4 + damageLow_1;
    : creature->damageHigh = v7->spec4 + damageHigh;
    : }
    : LABEL_40:
    : if ( (creature->flags & 0x40) == 0 ) // Not for war machines
    : {
E65F3: speedBonus = 0;
E65F5: i_slot = 0;
E65F7: iArtifact = hero->equippedArtifacts;
    : do
    : {
E65FD: if ( iArtifact->id == NECKLACE_OF_SWIFTNESS )
E6600: goto BREAK; // is equipped directly so speed +1
E6602: ++i_slot;
E6603: ++iArtifact;
    : }
E6606: while ( i_slot < 19 );
    : combo = akArtifactTraits[NECKLACE_OF_SWIFTNESS].isPartOfComboArtifact;
E6617: if ( combo != -1 && hero::IsWieldingArtifact(hero, ComboArtSetUpPo[combo].comboID) ) // NECKLACE_OF_SWIFTNESS is equipped by combo so speed + 1
    : BREAK:
E6633: speedBonus = 1;
E663C: if ( hero::IsWieldingArtifact(hero, RING_OF_THE_WAYFARER) )
E6645: ++speedBonus; // RING_OF_THE_WAYFARER is equipped so speed + 1
E664A: if ( hero::IsWieldingArtifact(hero, CAPE_OF_VELOCITY) )
E6653: speedBonus += 2; // CAPE_OF_VELOCITY is equipped so speed + 1
E6661: if ( akHeroSpecificAbilities[hero->ID].spec == 5 )
E6667: speedBonus += 2; // Hero has Sir Mullich speciality so speed + 2
E666A: creature->speed += speedBonus;
    : }
E6670: healthBonus = 0;
E6672: i_slot_1 = 0;
E6674: iArtifact_1 = this->equippedArtifacts;
    : do
    : {
E667A: if ( iArtifact_1->id == RING_OF_VITALITY )
E667D: goto BREAK_1; // is equipped directly so health +1
E667F: ++i_slot_1;
E6680: ++iArtifact_1;
    : }
E6686: while ( i_slot_1 < 19 );
E6688: combo_1 = akArtifactTraits[RING_OF_VITALITY].isPartOfComboArtifact;
E6694: if ( combo_1 != -1 && hero::IsWieldingArtifact(this, ComboArtSetUpPo[combo_1].comboID) ) // RING_OF_VITALITY is equipped by combo so health + 1
    : BREAK_1:
E66B2: healthBonus = 1;
E66BA: if ( hero::IsWieldingArtifact(this, RING_OF_LIFE) )
E66C7: ++healthBonus; // RING_OF_LIFE is equipped so health + 1
E66C8: if ( hero::IsWieldingArtifact(this, VIAL_OF_LIFEBLOOD) )
E66D5: healthBonus += 2; // VIAL_OF_LIFEBLOOD is equipped so health + 1
E66FA: if ( (akCreatureTypeTraits[creatureType].flags & 0x10) != 0 && hero::IsWieldingArtifact(this, ELIXIR_OF_LIFE) )
    : healthBonus += akCreatureTypeTraits[creatureType].health / 4; // ELIXIR_OF_LIFE is equipped so health + 25%
E671D: creature->health += healthBonus; // Your hook is here
    : }

Following this I think the hero has to be on ebx but in the same time the health bonus is on ebx. Here I have to admit an immense lack of knowledge how I can regain the address of the hero and also the address of the creature which is on edx but also also sometimes it seems to be overwritten. Is it the only possibility to reimplement the complete function?

Regarding your FairCancelSpell, it sounds interresting. Do I understand it correctly that it removes the latest spell, e.g. if I got cursed by a dread knight and than weakend by serpent flies and at the end also slowed down by the enemy hero a dispell or cure would only remove the slow spell?

Best regards and I hope one day I can say: "I understand half of the things I have done as good as the other half is failing to work" ;-)

Parascus
____________

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


Adventuring Hero
posted November 03, 2022 11:41 PM

Hi AlexSpl,

ok, moving the Hook to 0x4E6670 (beginning of health calculation), returning to 0x4E671D, and feeling ready to reimplement this section I have access to the hero's data. But If I try to get the Create (c->esi) I don't think to have the real creature in esi because the name of it is null and also there are some other missmatches with the structure. hmmmm

Best regards

Parascus
____________

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


Adventuring Hero
posted November 04, 2022 05:14 PM

Hi AlexSpl,

I thinkI found it. The hero is sometimes in ebx and also ecx. When I use the hook, I can use ecx. Regarding the screature it is in esi but it's not the CombatCreature but the CreatureInformation.

Coding goes on

Parascus
____________

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


Responsible
Supreme Hero
posted November 04, 2022 07:20 PM

c->esi is your creature:

#pragma pack(push, 1)
struct TCreatureTypeTraits
{
 int faction;
 int tier;
 const char *shortName_p;
 const char *defName_p;
 TCreatureFlags flags;
 const char *nameSingle;
 const char *namePlural;
 int spec_p;
 int resourceCost[7];
 int fightValue;
 int AIValue;
 int Grow;
 int HGrow;
 int health;
 int speed;
 int attack;
 int defense;
 int damageLow;
 int damageHigh;
 int shots;
 int hasSpell;
 int advMapL;
 int advMapH;
};
#pragma pack(pop)


*(hero**)(c->ebp - 4) is your hero. You can get their specialty by their id (see the pointer to the array of hero specialties at 0x679C80). I think it's all you need by now.

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


Adventuring Hero
posted November 04, 2022 09:09 PM

Hi AlexSpl,

here is my hook, and its working:

int __stdcall executeFirstAidHealthBuff(LoHook* h, HookContext* c) {
   h3::H3CreatureInformation* creatureInformation = (h3::H3CreatureInformation*)(c->esi);

   int currentHealth = c->eax;

   if (creatureInformation != nullptr)
   {
       BOOLEAN isAlive = creatureInformation->alive;
       if (isAlive)
       {

           h3::H3Hero* currentHero = (h3::H3Hero*)(c->ecx);
           if (currentHero != nullptr)
           {

               BOOLEAN hasFirstAidTent = currentHero->WearsArtifact(h3::NH3Artifacts::eArtifacts::FIRST_AID_TENT);
               if (hasFirstAidTent) {

                   h3::H3HeroSpecialty* heroSpeciality = getSpecialityOfHero(currentHero);

                   if (heroSpeciality != nullptr) {

                       if (
                           heroSpeciality->type == h3::NH3Heroes::eHeroSpecialty::SKILL &&
                           heroSpeciality->bonusId == h3::NH3Skills::eSecondary::FIRST_AID
                           
                       {
                           int firstAidLevel = currentHero->secSkill[h3::NH3Skills::eSecondary::FIRST_AID];

                           currentHealth += (creatureInformation->level + 1) * (firstAidLevel + 1);
                       }
                   }
                   else
                   {
                       debugStrWin("Speciality not found");
                   }
               }
           }
       }
   }

   c->eax = currentHealth;

   return EXEC_DEFAULT;
}

Thanks for all

Parascus
____________

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


Responsible
Supreme Hero
posted November 04, 2022 10:34 PM

Nice

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


Adventuring Hero
posted November 04, 2022 11:58 PM

Hi Folks of Assembler,

I have a strange effect in the code. I'm using the debugger and have a breakpoint at 005AAD90. This breakpoint is triggered when a hero meets another. The first instruction is a jump to
  Heroes3 HD.exe+1AAD90 - E9 17920002           - jmp 025B3FAC
and executes the following:
025B3FAC - 60                    - pushad
025B3FAD - 68 C845DD05           - push 05DD45C8 { (7BE63898) }
025B3FB2 - E8 C9B08579           - call patcher_x86.dll+F080
025B3FB7 - 58                    - pop eax
025B3FB8 - 61                    - popad
025B3FB9 - 58                    - pop eax
025B3FBA - 51                    - push ecx
025B3FBB - 68 C845DD05           - push 05DD45C8 { (7BE63898) }
025B3FC0 - E8 EB50DD00           - call HD_SOD.dll+290B0
025B3FC5 - 50                    - push eax
025B3FC6 - 60                    - pushad
025B3FC7 - 68 C845DD05           - push 05DD45C8 { (7BE63898) }
025B3FCC - E8 1FAF8579           - call patcher_x86.dll+EEF0
025B3FD1 - 58                    - pop eax
025B3FD2 - 61                    - popad
025B3FD3 - C3                    - ret


but getting to the ret instruction it does not return to the next instruction but continues with the code line 005AEAEA. Has this somthing to do that this ret instruction has not value (e.g. 0008)?

P.S.: I'm on the luck images ... at this moment it shows luck level 4 - 6 at the general statistic window in the lower right, on the battle field at the hero and the creatures, the creature window. Now it's time for the exchange window, the hero statistic dialog and the explicit luck dialog. The later one is interesting because it does not show the actual level but only level 1 as to say: This is my luck icon ... you will never see any different.

Best regards

Parascus
____________

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


Responsible
Supreme Hero
posted November 05, 2022 12:03 AM

This is the code of HD mod itself. You cannot do much here because of updates.

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


Adventuring Hero
posted November 05, 2022 12:58 AM

Olala, qu'elle domage ... (what a pitty)
____________

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


Responsible
Supreme Hero
posted November 05, 2022 09:49 AM

You can always ignore this code while debugging, unless you're trying to change core things the HD mod changes.

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


Adventuring Hero
posted November 05, 2022 10:00 AM

I got an idea. Please tell me if it's a bad or an even worse one I shouldn't follow:
1. I identify the code displaying the image in the original code. (check, it's 5AB3B2 - 5AB3FC)
2. I try to implement a function doing all the stuff the original code does. (For this I'm looking for an example how an image is displayed. The code iconWidget::iconWidget(v75, 666, 45, 30, 20, 108, aImrl30_def_0, 0, 0, 0, 0, 16); does not work because i don't have a class iconWidget and I don't find the equivalence in H3API)
3. I define a Hook at the return address of the HD mod (025B3FAC) which executes my display and returns to the hooked address.

Difficulties might be:
1. Find an example routine to display an icon.
2. The address 025B3FAC might be out of scope and can't be reached by my hook.
3. Allthough the icon is displayed it could be that it flickers because it is drawn by the HD mod and afterwards by me.

Any thoughts on this?

Parascus
____________

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


Responsible
Supreme Hero
posted November 05, 2022 10:06 AM

Quote:
2. I try to implement a function doing all the stuff the original code does. (For this I'm looking for an example how an image is displayed. The code iconWidget::iconWidget(v75, 666, 45, 30, 20, 108, aImrl30_def_0, 0, 0, 0, 0, 16); does not work because i don't have a class iconWidget and I don't find the equivalence in H3API)

I'm pretty sure H3API has a constructor for iconWidget. You just have to search for it in the code.

iconWidget *__thiscall iconWidget::iconWidget(
       iconWidget *this,
       int posX,
       int posY,
       int sizeX,
       int sizeY,
       int itemId,
       char *defname,
       int cadre,
       int group,
       int mirror,
       int closeDialog,
       int flags)
{
 CSprite *Sprite; // eax

 widget::widget(this, posX, posY, sizeX, sizeY, itemId, flags);
 this->Cadre = cadre;
 LOBYTE(this->Mirror) = mirror;
 Sprite = 0;
 this->Group = group;
 this->field_40 = 2;
 this->CloseDialog = closeDialog;
 this->VMT = &iconWidget::`vftable';
 if ( defname )
   Sprite = ResourceManager::GetSprite(defname);
 this->LoadedDef = Sprite;
 return this;
}

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


Responsible
Supreme Hero
posted November 05, 2022 10:45 AM

Btw, if you need sample code that works with images/buttons look at this plugin. Source is here.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Jump To: « Prev Thread . . . Next Thread » This thread is 41 pages long: 1 10 20 30 ... 32 33 34 35 36 ... 40 41 · «PREV / NEXT»
Post New Poll    Post New Topic    Post New Reply

Page compiled in 0.1179 seconds