September 17th, 2015, 10:14
Posts: 10,463
Threads: 394
Joined: Aug 2015
I want to fix the problem that finding heroes fails when you clear an encounter with an army of 9.
Removing the restriction was easy but it does not split the stack of units afterwards, unlike when your town makes a unit and it has no room.
I found the subroutine responsible for splitting up your units, it's called both when you hire mercenaries or produce a unit.
So far so good, all we need now is to call it from where you find your hero (or reanimate your 10th undead or zombie, I also want to make that happen), but this is were I'm stuck.
So we have
BE546 : 9A 98 00 C0 03 call j_CheckOver9UnitsRegroup
and I want to call that from another location, 9C385 (this one is for rising undead, heroes will be another address but same concept).
So I do 9C385 : 9A 98 00 C0 03.
However, I read that far calls are being relocated when the exe loads, so I also need to add an entry to the relocation tables.
I increased the number of entries at 00006 : 79 08 to 7A 08.
Then I tried to calculate the data that goes into the entry.
9C385 is ovr123:06A5 in the disassembler.
That means the offset is 6A8, I add 3 because the 4th byte of the instruction is the segment which needs to be relocated, not the first.
For the segment address, I need to subtract the start of the code in the exe, which is 2A00, as well as the offset, 9C385-2A00-6A5=992E0, meaning the segment is 992E.
So I then move to the last byte of the relocation table and add to the empty space the address 992E:06A8, meaning I do 2222: a8 06 2E 99 in the hex editor.
And after all that, when I load it in the disassembler I get a warning that the file is invalid, so the relocation data is bad. I also tried all numbers around that just in case the segment isn't the 4th-5th byte in the call statement (I'm quite sure it is) but nothing between A5-AA works.
Why? What am I doing wrong in that calculation? Or is it some other problem?
When I tried 0000:0000 as the relocation address in other words left the table entry empty it correctly changed the beginning of the code in the exe (starting from the 1st byte not from the 0th surprisingly), but if I enter my calculated address it doesn't even load in the disassembler.
September 17th, 2015, 12:21
(This post was last modified: September 17th, 2015, 12:29 by Asfex.)
Posts: 525
Threads: 6
Joined: Dec 2010
i am not familiar with this debugger, but the new entry point in the overlay include real-time calculation.
If you want to fix 9unit problem - the best way is change summoning circle procedure. it can be done without creation the new entry point.
I try to avoid the new entry point creation always.
September 17th, 2015, 12:33
(This post was last modified: September 17th, 2015, 12:47 by Seravy.)
Posts: 10,463
Threads: 394
Joined: Aug 2015
(September 17th, 2015, 12:21)Asfex Wrote: i am not familiar with this debugger, but the new entry point in the overlay include real-time calculation.
If you want to fix 9unit problem - the best way is change summoning circle procedure. it can be done without creation the new entry point.
I try to avoid the new entry point creation always. I don't see how finding heroes and raising undead is related to summoning circles, sorry.
So the problem is that the call is being made from an overlay?
September 18th, 2015, 01:17
Posts: 488
Threads: 51
Joined: Apr 2012
(September 17th, 2015, 12:33)Seravy Wrote: I don't see how finding heroes and raising undead is related to summoning circles, sorry. Because when you use recall hero to bring a hero to your summoning circle, but the city is full, the hero is placed outside the city.
September 18th, 2015, 02:09
(This post was last modified: September 18th, 2015, 02:52 by Seravy.)
Posts: 10,463
Threads: 394
Joined: Aug 2015
(September 18th, 2015, 01:17)Tiltowait Wrote: (September 17th, 2015, 12:33)Seravy Wrote: I don't see how finding heroes and raising undead is related to summoning circles, sorry. Because when you use recall hero to bring a hero to your summoning circle, but the city is full, the hero is placed outside the city. Yes that's the effect I want to implement to finding heroes and raising zombies.
Which would require calling that subroutine responsible for placing the hero outside. Which is what I can't do, see the initial post.
Oh...now I think I start to understand.
Maybe he means to set the "Recalled" flag on the new unit, as though a Recall spell was cast on it, so it's moved back to the summoning circle automatically, where it'll be moved outside and not break the game.
I guess that could work but...the found/raised unit will appear at the circle instead of where you found it, which is definitely not what I want. Maybe if only the excess above 9 did that hmm, now that might be an interesting solution.
Edit : oh, now I see! The recall is handled in the same procedure as making the zombies, so there is a call to the regrouping procedure there, so I can use that instead of making another. How convenient, I removed the recall spells anyway so all that coding area around that call is free to use!
September 18th, 2015, 03:59
(This post was last modified: September 18th, 2015, 03:59 by Asfex.)
Posts: 525
Threads: 6
Joined: Dec 2010
its not so exactly. proc endcomat_unit_condition sets the order "recall", or "flee" or died. it is choose the way to flee too.
(at es:[bx+34h] , 100 (64h) if to summoning circle in the plane coordinate)
You must decide here, who is flee, and the place where it flee, or summon , or... and set the corresponding flags.
before the call WoRPlace_1E02, which will make the rest .
September 18th, 2015, 04:16
(This post was last modified: September 18th, 2015, 05:01 by Seravy.)
Posts: 10,463
Threads: 394
Joined: Aug 2015
(September 18th, 2015, 03:59)Asfex Wrote: its not so exactly. proc endcomat_unit_condition sets the order "recall", or "flee" or died. it is choose the way to flee too.
(at es:[bx+34h] , 100 (64h) if to summoning circle in the plane coordinate)
You must decide here, who is flee, and the place where it flee, or summon , or... and set the corresponding flags.
before the call WoRPlace_1E02, which will make the rest .
I made the undead raising go to the location of the call
ovr123:069C cmp byte ptr [bp+var_8], 9
ovr123:06A0 jl short loc_A5647
ovr123:06A2 call sub_A53ED
ovr123:06A5 nop
ovr123:06A6 nop
which is here
ovr123:042D mov ax, si
ovr123:042F mov dx, 6Eh ; 'n'
ovr123:0432 imul dx
ovr123:0434 les bx, Units_Battle
ovr123:0438 add bx, ax
ovr123:043A mov ax, es:[bx+30h]
ovr123:043E mov cl, 5
ovr123:0440 shl ax, cl
ovr123:0442 les bx, Units_Overland
ovr123:0446 add bx, ax
ovr123:0448 pop ax
ovr123:0449 mov es:[bx+2], al
ovr123:044D mov ax, si
ovr123:044F mov dx, 6Eh ; 'n'
ovr123:0452 imul dx
ovr123:0454 les bx, Units_Battle
ovr123:0458 add bx, ax
ovr123:045A mov ax, es:[bx+30h]
ovr123:045E mov cl, 5
ovr123:0460 shl ax, cl
ovr123:0462 les bx, Units_Overland
ovr123:0466 add bx, ax
ovr123:0468 mov byte ptr es:[bx+7], 1
ovr123:046D mov ax, si
ovr123:046F mov dx, 6Eh ; 'n'
ovr123:0472 imul dx
ovr123:0474 les bx, Units_Battle
ovr123:0478 add bx, ax
ovr123:047A push word ptr es:[bx+30h]
ovr123:047E call j_CheckOver9UnitsRegroup
ovr123:0483 pop cx
ovr123:0484 mov ax, si <Replaced this with retn
It executes without problems but does nothing. I get the 10th undead unit but it stays with the group.
j_CheckOver9UnitsRegroup is not pushing the units away even though it is supposed to I believe.
WoRPlace_1E02 = CheckOver9UnitsRegroup? Are we talking about the same procedure? Please use memory addresses when referring to parts in code.
Edit : tried setting es:[bx+34h] to 1 which triggers that recall code normally before making the call but it has no effect.
Edit : I tried doing dec byte ptr es:[bx+1] on the unit and it moved it one cell upward as it should, so I conclude that I'm doing it right but that procedure does not work unless some specific condition is met.
September 18th, 2015, 05:01
Posts: 525
Threads: 6
Joined: Dec 2010
"WoRPlace_1E02 = CheckOver9UnitsRegroup? Are we talking about the same procedure? Please use memory addresses when referring to parts in code."
No. WoRPlace_1E02 adress is 979a2 , it contain methods to determine if the unit may be in that place after recall . ( is it ocean, or node, or enemy units here)
Endcombat_unit_condition is in 9c1e2. this function must determine a way to flee.
September 18th, 2015, 05:15
Posts: 10,463
Threads: 394
Joined: Aug 2015
(September 18th, 2015, 05:01)Asfex Wrote: "WoRPlace_1E02 = CheckOver9UnitsRegroup? Are we talking about the same procedure? Please use memory addresses when referring to parts in code."
No. WoRPlace_1E02 adress is 979a2 , it contain methods to determine if the unit may be in that place after recall . ( is it ocean, or node, or enemy units here)
Endcombat_unit_condition is in 9c1e2. this function must determine a way to flee.
CheckOver9UnitsRegroup is also 979A2 so it is the right one then.
So what exactly do I need to set before calling it to have the unit stay with the group and push away the weakest unit in the stack like when I hire new mercenaries?
Calling it seems to have no effect, I still end up with a stack of 10+ units.
September 20th, 2015, 02:16
(This post was last modified: September 20th, 2015, 02:18 by Asfex.)
Posts: 525
Threads: 6
Joined: Dec 2010
may be,you need raise undead before call it?
Really, this work with summoning circle , but do not work for you. hence, the problem is located inside.
|