How do you go about debugging this thing? I've tried in ollydbg for a while, but I can't get back to desktop when the game hits a breakpoint, and just looking through the code when it's not running isn't enough.
Hi Haen,Haenlomal said:Hi all,
First, my apologies to Glovz for de-railing his thread. If you want, maybe we get a mod to move all relevant posts to another thread?
Scond, I'll be busy most of the day with at a friend's wedding this afternoon, so I won't be able to contribute much today. I'll say, though, that I've managed to isolate the function that returns whether or not a player has a certain trait, so with this, I should be able to isolate the raw melee bonus damage from the heavy handed bonus and from the bonus Hth damage perk. The code would look something like this:
Code:mov edx, 0x0B; // set Melee Damage attribute argument mov eax, ecx; // set pointer to critter (assuming it's stored in ecx) call 0x004aef48; // call GetCritterStat( CRITTER* eax, 0x0B) mov ebp, eax; // store result in ebp mov eax, 0x06; // Pass argument 6 (TRAIT_heavy_handed) call 0x004B3bc8; // Retrieve Player Trait cmp eax, 0x01; // does player have heavy handed trait? jne ajmp; imul eax, 0x04; sub ebp, eax; // if yes, subtract 4 from melee damage ajmp: xor edx, edx; // set Strength attribute argument mov eax, ecx; // set pointer to critter (assuming it's stored in ecx) call 0x004aef48; // call GetCritterStat( CRITTER* eax, 0x00) sub eax, 0x05; // subtract 5 from strength to get melee bonus cmp eax, 0x01; // is it less than 1? jge bjmp; mov eax, 0x01; // if yes, set it to 1 bjmp: sub ebp, eax; // subtract melee bonus to get bonus from bonus hth perk
Of course, I haven't added checks to make sure the critter is the PC, or else I think that has_trait call may crash the game. But it's a start.
Cheers,
-- The Haen.
Hi.Glovz said:Hi Nevill,
First, thank you for the input - different opinions are always welcome.
Not sure I agree with your changes, something to consider is that bonus values should almost always be added after primary calculations.
Not entirely sure of what changes will be feasible at this point until Haen considers the purposed changes and/or posts the original code.
Cheers,
Glovz
Hand 1-2
player strength 4,5,6,7,8,9,10
original
raw_damage = random(min_damage_of_weapon, max_damage_of_weapon + bonus_melee_damage)
bonus_melee_damage = max(player_strength - 5, 1) + heavy_handed_bonus + (2 * rank_of_bonus_hth_damage_perk)
raw_damage = random(1 + unarmed_attack_bonus, 2 + bonus_melee_damage + unarmed_attack_bonus).
Glovz fix
raw_damage = random(min_damage_of_weapon, max_damage_of_weapon) + bonus_melee_damage
bonus_melee_damage = max(player_strength - 5, 1 + (2 * rank_of_bonus_hth_damage_perk)) + heavy_handed_bonus
raw_damage = random(1 + unarmed_attack_bonus, 2 + unarmed_attack_bonus) + bonus_melee_damage
Nevill fix
raw_damage = random(min_damage_of_weapon, max_damage_of_weapon + bonus_melee_damage) + (2 * rank_of_bonus_hth_damage_perk)
bonus_melee_damage = max(player_strength - 5, 1) + heavy_handed_bonus
raw_damage = random(1 + unarmed_attack_bonus, 2 + bonus_melee_damage + unarmed_attack_bonus) + (2 * rank_of_bonus_hth_damage_perk).
Original
Hand, no heavy handed, no bonus HtH, no unarmed attack bonus
ST Range
4 1-3
5 1-3
6 1-3
7 1-4
8 1-5
9 1-6
10 1-7
Hand, heavy handed, no bonus HtH, no unarmed attack bonus
ST Range
4 1-7
5 1-7
6 1-7
7 1-8
8 1-9
9 1-10
10 1-11
Hand, heavy handed, one level bonus HtH, no unarmed attack bonus
ST Range
4 1-9
5 1-9
6 1-9
7 1-10
8 1-11
9 1-12
10 1-13
Hand, heavy handed, one level bonus HtH, unarmed attack bonus (2?)
ST Range
4 3-11
5 3-11
6 3-11
7 3-12
8 3-13
9 3-14
10 3-15
Glovz' Fix
Hand, no heavy handed, no bonus HtH, no unarmed attack bonus
ST Range
4 2-3
5 2-3
6 2-3
7 3-4
8 4-5
9 5-6
10 6-7
Hand, heavy handed, no bonus HtH, no unarmed attack bonus
ST Range
4 6-7
5 6-7
6 6-7
7 7-8
8 8-9
9 9-10
10 11-12
Hand, heavy handed, one level bonus HtH, no unarmed attack bonus
ST Range
4 7-7
5 7-7
6 7-7
7 7-8
8 8-9
9 9-10
10 11-12
Hand, heavy handed, one level bonus HtH, unarmed attack bonus (2?)
ST Range
4 9-9
5 9-9
6 9-9
7 9-10
8 10-11
9 11-12
10 13-14
Nevill's Fix
Hand, no heavy handed, no bonus HtH, no unarmed attack bonus
ST Range
4 1-3
5 1-3
6 1-3
7 1-4
8 1-5
9 1-6
10 1-7
Hand, heavy handed, no bonus HtH, no unarmed attack bonus
ST Range
4 1-7
5 1-7
6 1-7
7 1-8
8 1-9
9 1-10
10 1-11
Hand, heavy handed, one level bonus HtH, no unarmed attack bonus
ST Range
4 3-9
5 3-9
6 3-9
7 3-10
8 3-11
9 3-12
10 3-13
Hand, heavy handed, one level bonus HtH, unarmed attack bonus (2?)
ST Range
4 5-11
5 5-11
6 5-11
7 5-12
8 5-13
9 5-14
10 5-15
Original Formula Fixed Formula
N LA MA CA PA APA N LA MA CA PA APA
ADT 0 2 4 5 12 15 0 2 4 5 12 15
ADR 0 25 30 40 40 55 0 25 30 40 40 55
--------------------------------------------------------------------------------------------
1 1 0 0 0 0 0 2 0 0 0 0 0
2 2 0 0 0 0 0 3 1 0 0 0 0
3 3 1 0 0 0 0 4 2 0 0 0 0
4 4 2 0 0 0 0 5 3 0 0 0 0
5 5 3 1 0 0 0 6 4 1 0 0 0
6 6 3 1 1 0 0 7 5 2 0 0 0
7 7 4 2 1 0 0 8 6 3 1 0 0
8 8 5 3 2 0 0 9 7 4 2 0 0
9 9 5 4 2 0 0 10 8 5 3 0 0
10 10 6 4 3 0 0 11 9 6 4 0 0
11 11 7 5 4 0 0 12 10 7 5 0 0
12 12 8 6 4 0 0 13 11 8 6 0 0
13 13 8 6 5 1 0 14 12 9 7 0 0
14 14 9 7 5 1 0 15 13 10 8 0 0
15 15 10 8 6 2 0 16 14 11 9 0 0
--------------------------------------------------------------------------------------------
004783F8 . 7C844700 DD FALLOUT2.0047847C ; Switch table used at 00478475
004783FC . 7C844700 DD FALLOUT2.0047847C
00478400 . 83844700 DD FALLOUT2.00478483
00478404 . 83844700 DD FALLOUT2.00478483
00478408 . 8A844700 DD FALLOUT2.0047848A
0047840C . 8A844700 DD FALLOUT2.0047848A
00478410 . 7C844700 DD FALLOUT2.0047847C
00478414 . 83844700 DD FALLOUT2.00478483
00478418 . C1844700 DD FALLOUT2.004784C1 ; Switch table used at 004784B9
0047841C . CB844700 DD FALLOUT2.004784CB
00478420 . D5844700 DD FALLOUT2.004784D5
00478424 . C1844700 DD FALLOUT2.004784C1
00478428 . D5844700 DD FALLOUT2.004784D5
0047842C . E9844700 DD FALLOUT2.004784E9
00478430 . CB844700 DD FALLOUT2.004784CB
00478434 . D5844700 DD FALLOUT2.004784D5
00478438 . DF844700 DD FALLOUT2.004784DF
0047843C . D5844700 DD FALLOUT2.004784D5
00478440 . DF844700 DD FALLOUT2.004784DF
00478444 . F0844700 DD FALLOUT2.004784F0
00478448 /$ 53 PUSH EBX
00478449 |. 51 PUSH ECX
0047844A |. 56 PUSH ESI
0047844B |. 57 PUSH EDI
0047844C |. 55 PUSH EBP
0047844D |. 83EC 10 SUB ESP,10
00478450 |. 89C1 MOV ECX,EAX ; pointer to critter
00478452 |. 89D6 MOV ESI,EDX ; hit_mode (see define.h hit_modes > 7 are apparently special unarmed attacks)
00478454 |. 31D2 XOR EDX,EDX
00478456 |. 31DB XOR EBX,EBX
00478458 |. 31ED XOR EBP,EBP
0047845A |. 891424 MOV DWORD PTR SS:[ESP],EDX ; set damage max = 0
0047845D |. 895424 04 MOV DWORD PTR SS:[ESP+4],EDX ; set damage min = 0
00478461 |. 85C0 TEST EAX,EAX ; sanity check for null critter pointer
00478463 |. 0F84 FC000000 JE FALLOUT2.00478565 ; if null pointer exit function with value of 0
00478469 |. 74 21 JE SHORT FALLOUT2.0047848C ; ??? -- This is unreacheable code
0047846B |. 83FE 07 CMP ESI,7 ; is hit_mode a special unarmed attack?
0047846E |. 77 1A JA SHORT FALLOUT2.0047848A ; process unarmed attack if yes
00478470 |. 89F7 MOV EDI,ESI
00478472 |. C1E7 02 SHL EDI,2
00478475 |. 2E:FFA7 F88347>JMP DWORD PTR CS:[EDI+4783F8] ; Otherwise, detect from which slot attack was made and get item pointer to it
0047847C |> E8 3B97FFFF CALL FALLOUT2.00471BBC ; weapon in left slot, get pointer to it
00478481 |. EB 05 JMP SHORT FALLOUT2.00478488
00478483 |> E8 E896FFFF CALL FALLOUT2.00471B70 ; weapon in right slot, get pointer to it
00478488 |> 89C2 MOV EDX,EAX
0047848A |> 89D0 MOV EAX,EDX ; normal punch, kick, or special unarmed attack processing starts here
0047848C |> 89C7 MOV EDI,EAX
0047848E |. 85C0 TEST EAX,EAX ; is left/right slot empty?
00478490 |. 75 65 JNZ SHORT FALLOUT2.004784F7 ; skip ahead if yes
00478492 |. BA 01000000 MOV EDX,1 ; otherwise, no weapons used, so set min_unarmed_damage to 1
00478497 |. 89C8 MOV EAX,ECX
00478499 |. 895424 04 MOV DWORD PTR SS:[ESP+4],EDX ; store min_unarmed_damage
0047849D |. BA 0B000000 MOV EDX,0B
004784A2 |. E8 A16A0300 CALL FALLOUT2.004AEF48 ; Retrieve PC.Melee Damage Bonus
004784A7 |. 83C0 02 ADD EAX,2 ; max_unarmed_damage = bonus_melee_damage + 2
004784AA |. 83EE 08 SUB ESI,8 ; Switch (cases 8..13), also if hit_mode == 4, 5 (punch, kick), this will go back to 0047848A, but now with nonzero EDX value
004784AD |. 890424 MOV DWORD PTR SS:[ESP],EAX ; store max_unarmed_damage
004784B0 |. 83FE 0B CMP ESI,0B
004784B3 |. 0F87 9A000000 JA FALLOUT2.00478553
004784B9 |. 2E:FF24B5 1884>JMP DWORD PTR CS:[ESI*4+478418] ; processing special unarmed attack bonus
004784C1 |> BB 03000000 MOV EBX,3 ; Cases 8,B of switch 004784AA
004784C6 |. E9 88000000 JMP FALLOUT2.00478553
004784CB |> BB 05000000 MOV EBX,5 ; Cases 9,E of switch 004784AA
004784D0 |. E9 7E000000 JMP FALLOUT2.00478553
004784D5 |> BB 07000000 MOV EBX,7 ; Cases A,C,F,11 of switch 004784AA
004784DA |. E9 74000000 JMP FALLOUT2.00478553
004784DF |> BB 09000000 MOV EBX,9 ; Cases 10,12 of switch 004784AA
004784E4 |. E9 6A000000 JMP FALLOUT2.00478553
004784E9 |> BB 0A000000 MOV EBX,0A ; Case D of switch 004784AA
004784EE |. EB 63 JMP SHORT FALLOUT2.00478553
004784F0 |> BB 0C000000 MOV EBX,0C ; Case 13 of switch 004784AA
004784F5 |. EB 5C JMP SHORT FALLOUT2.00478553
004784F7 |> 89E2 MOV EDX,ESP ; normal weapon processing here
004784F9 |. 895424 0C MOV DWORD PTR SS:[ESP+C],EDX
004784FD |. 74 33 JE SHORT FALLOUT2.00478532
004784FF |. 8D5424 08 LEA EDX,DWORD PTR SS:[ESP+8]
00478503 |. 8B40 64 MOV EAX,DWORD PTR DS:[EAX+64]
00478506 |. E8 FD9B0200 CALL FALLOUT2.004A2108
0047850B |. 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4]
0047850F |. 85C0 TEST EAX,EAX
00478511 |. 74 0B JE SHORT FALLOUT2.0047851E
00478513 |. 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8]
00478517 |. 8B40 28 MOV EAX,DWORD PTR DS:[EAX+28]
0047851A |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
0047851E |> 837C24 0C 00 CMP DWORD PTR SS:[ESP+C],0
00478523 |. 74 0D JE SHORT FALLOUT2.00478532
00478525 |. 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8]
00478529 |. 8B5424 0C MOV EDX,DWORD PTR SS:[ESP+C]
0047852D |. 8B40 2C MOV EAX,DWORD PTR DS:[EAX+2C]
00478530 |. 8902 MOV DWORD PTR DS:[EDX],EAX
00478532 |> 89F2 MOV EDX,ESI
00478534 |. 89F8 MOV EAX,EDI
00478536 |. E8 45FDFFFF CALL FALLOUT2.00478280 ; Get attack_code (?)
0047853B |. 83F8 02 CMP EAX,2 ; is it a kick... (?)
0047853E |. 74 05 JE SHORT FALLOUT2.00478545
00478540 |. 83F8 01 CMP EAX,1 ; or a punch? (?) prevents melee bonus from being added to thrown weapons, I think...
00478543 |. 75 0E JNZ SHORT FALLOUT2.00478553
00478545 |> BA 0B000000 MOV EDX,0B
0047854A |. 89C8 MOV EAX,ECX
0047854C |. E8 F7690300 CALL FALLOUT2.004AEF48 ; If yes, Retrieve PC.Melee Damage Bonus
00478551 |. 89C5 MOV EBP,EAX
00478553 |> 8B1424 MOV EDX,DWORD PTR SS:[ESP] ; Default case of switch 004784AA - retrieve max damage of attack
00478556 |. 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] ; retrieve min damage of attack
0047855A |. 01EA ADD EDX,EBP ; max_damage += bonus_melee_damage
0047855C |. 01D8 ADD EAX,EBX ; min_damage += special unarmed bonus
0047855E |. 01DA ADD EDX,EBX ; max_damage += special unarmed bonus
00478560 |. E8 5BAB0200 CALL FALLOUT2.004A30C0 ; return random number between min_dam and max_dam inclusive
00478565 |> 83C4 10 ADD ESP,10
00478568 |. 5D POP EBP
00478569 |. 5F POP EDI
0047856A |. 5E POP ESI
0047856B |. 59 POP ECX
0047856C |. 5B POP EBX
0047856D \. C3 RETN
Here:Haenlomal said:What we really need is someone like crazycc or Timeslip to do this sort of stuff...
int item_w_damage(sCritter* critter, int type) {
sItem* weapon=0;
int mindmg=0, maxdmg=0;
if(!critter) return 0;
switch(type) {
case ATKTYPE_LWEP_PRIMARY: case ATKTYPE_LWEP_SECONDARY: case ATKTYPE_LWEP_RELOAD:
weapon=inven_left_hand(critter);
break;
case ATKTYPE_RWEP_PRIMARY: case ATKTYPE_RWEP_SECONDARY: case ATKTYPE_RWEP_RELOAD:
weapon=inven_right_hand(critter);
break;
}
if(weapon) {
sProto* proto;
proto_ptr(weapon->pid, &proto);
mindmg=proto->w_min_damage;
maxdmg=proto->w_max_damage;
if(item_w_subtype(weapon, type) == 1 || item_w_subtype(weapon, type)==2) {
maxdmg+=stat_level(critter, STAT_melee_damage);
}
} else {
int bonus=0;
switch(type) {
case ATKTYPE_STRONGPUNCH: bonus=3; break;
case ATKTYPE_HAMMERPUNCH: bonus=5; break;
case ATKTYPE_HAYMAKER: bonus=7; break;
case ATKTYPE_JAB: bonus=3; break;
case ATKTYPE_PALMSTRIKE: bonus=7; break;
case ATKTYPE_PIERCINGSTRIKE: bonus=10; break;
case ATKTYPE_STRONGKICK: bonus=5; break;
case ATKTYPE_SNAPKICK: bonus=7; break;
case ATKTYPE_POWERKICK: bonus=9; break;
case ATKTYPE_HIPKICK: bonus=7; break;
case ATKTYPE_HOOKKICK: bonus=9; break;
case ATKTYPE_PIERCINGKICK: bonus=12; break;
}
maxdmg=stat_level(critter, STAT_melee_damage) + 2 + bonus;
mindmg=1 + bonus;
}
return roll_random(mindmg, maxdmg);
}
Yup. (Well, mostly. In the original there's calls to item_hit_with and item_w_damage_min_max, which got inlined, so I left them inline too. It's why the code utterly pointlessly checks that the address of the stack is non-null. )Glovz said:@Timeslip
Just so I'm clear, the code you posted is the C code equivalent of the Assembly code Haen posted - correct?
Cool - though I'm not sure how to edit your code for the small changes I have made so far.Timeslip said:Yup. (Well, mostly. In the original there's calls to item_hit_with and item_w_damage_min_max, which got inlined, so I left them inline too. It's why the code utterly pointlessly checks that the address of the stack is non-null. )Glovz said:@Timeslip
Just so I'm clear, the code you posted is the C code equivalent of the Assembly code Haen posted - correct?
004783F8 . 7C844700 DD FALLOUT2.0047847C ; Switch table used at 00478475
004783FC . 7C844700 DD FALLOUT2.0047847C
00478400 . 83844700 DD FALLOUT2.00478483
00478404 . 83844700 DD FALLOUT2.00478483
00478408 . 8A844700 DD FALLOUT2.0047848A
0047840C . 8A844700 DD FALLOUT2.0047848A
00478410 . 7C844700 DD FALLOUT2.0047847C
00478414 . 83844700 DD FALLOUT2.00478483
00478418 . C1844700 DD FALLOUT2.004784C1 ; Switch table used at 004784B9
0047841C . CB844700 DD FALLOUT2.004784CB
00478420 . D5844700 DD FALLOUT2.004784D5
00478424 . C1844700 DD FALLOUT2.004784C1
00478428 . D5844700 DD FALLOUT2.004784D5
0047842C . E9844700 DD FALLOUT2.004784E9
00478430 . CB844700 DD FALLOUT2.004784CB
00478434 . D5844700 DD FALLOUT2.004784D5
00478438 . DF844700 DD FALLOUT2.004784DF
0047843C . D5844700 DD FALLOUT2.004784D5
00478440 . DF844700 DD FALLOUT2.004784DF
00478444 . F0844700 DD FALLOUT2.004784F0
00478448 /$ 53 PUSH EBX
00478449 |. 51 PUSH ECX
0047844A |. 56 PUSH ESI
0047844B |. 57 PUSH EDI
0047844C |. 55 PUSH EBP
0047844D |. 83EC 10 SUB ESP,10
00478450 |. 89C1 MOV ECX,EAX ; pointer to critter
00478452 |. 89D6 MOV ESI,EDX ; hit_mode (see define.h hit_modes > 7 are apparently special unarmed attacks)
00478454 |. 31D2 XOR EDX,EDX
00478456 |. 31DB XOR EBX,EBX
00478458 |. 31ED XOR EBP,EBP
0047845A |. 891424 MOV DWORD PTR SS:[ESP],EDX ; set damage max = 0
0047845D |. 895424 04 MOV DWORD PTR SS:[ESP+4],EDX ; set damage min = 0
00478461 |. 85C0 TEST EAX,EAX ; sanity check for null critter pointer
00478463 |. 0F84 FC000000 JE FALLOUT2.00478565 ; if null pointer exit function with value of 0
00478469 |. 74 21 JE SHORT FALLOUT2.0047848C ; ??? -- This is unreacheable code
0047846B |. 83FE 07 CMP ESI,7 ; is hit_mode a special unarmed attack?
0047846E |. 77 1A JA SHORT FALLOUT2.0047848A ; process unarmed attack if yes
00478470 |. 89F7 MOV EDI,ESI
00478472 |. C1E7 02 SHL EDI,2
00478475 |. 2E:FFA7 F88347>JMP DWORD PTR CS:[EDI+4783F8] ; Otherwise, detect from which slot attack was made and get item pointer to it
0047847C |> E8 3B97FFFF CALL FALLOUT2.00471BBC ; weapon in left slot, get pointer to it
00478481 |. EB 05 JMP SHORT FALLOUT2.00478488
00478483 |> E8 E896FFFF CALL FALLOUT2.00471B70 ; weapon in right slot, get pointer to it
00478488 |> 89C2 MOV EDX,EAX
0047848A |> 89D0 MOV EAX,EDX ; normal punch, kick, or special unarmed attack processing starts here
0047848C |> 89C7 MOV EDI,EAX
0047848E |. 85C0 TEST EAX,EAX ; is left/right slot empty?
00478490 |. 75 65 JNZ SHORT FALLOUT2.004784F7 ; skip ahead if yes
00478492 |. BA 01000000 MOV EDX,1 ; otherwise, no weapons used, so set min_unarmed_damage to 1
00478497 |. 89C8 MOV EAX,ECX
00478499 |. 895424 04 MOV DWORD PTR SS:[ESP+4],EDX ; store min_unarmed_damage
0047849D |. BA 0B000000 MOV EDX,0B
004784A2 |. E8 A16A0300 CALL FALLOUT2.004AEF48 ; Retrieve PC.Melee Damage Bonus
// Add this line here ADD DWORD PTR SS:[ESP+4],EAX ; min_unarmed_damage += bonus_melee_damage
004784A7 |. 83C0 02 ADD EAX,2 ; max_unarmed_damage = bonus_melee_damage + 2
004784AA |. 83EE 08 SUB ESI,8 ; Switch (cases 8..13), also if hit_mode == 4, 5 (punch, kick), this will go back to 0047848A, but now with nonzero EDX value
004784AD |. 890424 MOV DWORD PTR SS:[ESP],EAX ; store max_unarmed_damage
004784B0 |. 83FE 0B CMP ESI,0B
004784B3 |. 0F87 9A000000 JA FALLOUT2.00478553
004784B9 |. 2E:FF24B5 1884>JMP DWORD PTR CS:[ESI*4+478418] ; processing special unarmed attack bonus
004784C1 |> BB 03000000 MOV EBX,3 ; Cases 8,B of switch 004784AA
004784C6 |. E9 88000000 JMP FALLOUT2.00478553
004784CB |> BB 05000000 MOV EBX,5 ; Cases 9,E of switch 004784AA
004784D0 |. E9 7E000000 JMP FALLOUT2.00478553
004784D5 |> BB 07000000 MOV EBX,7 ; Cases A,C,F,11 of switch 004784AA
004784DA |. E9 74000000 JMP FALLOUT2.00478553
004784DF |> BB 09000000 MOV EBX,9 ; Cases 10,12 of switch 004784AA
004784E4 |. E9 6A000000 JMP FALLOUT2.00478553
004784E9 |> BB 0A000000 MOV EBX,0A ; Case D of switch 004784AA
004784EE |. EB 63 JMP SHORT FALLOUT2.00478553
004784F0 |> BB 0C000000 MOV EBX,0C ; Case 13 of switch 004784AA
004784F5 |. EB 5C JMP SHORT FALLOUT2.00478553
004784F7 |> 89E2 MOV EDX,ESP ; normal weapon processing here
004784F9 |. 895424 0C MOV DWORD PTR SS:[ESP+C],EDX
004784FD |. 74 33 JE SHORT FALLOUT2.00478532
004784FF |. 8D5424 08 LEA EDX,DWORD PTR SS:[ESP+8]
00478503 |. 8B40 64 MOV EAX,DWORD PTR DS:[EAX+64]
00478506 |. E8 FD9B0200 CALL FALLOUT2.004A2108
0047850B |. 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4]
0047850F |. 85C0 TEST EAX,EAX
00478511 |. 74 0B JE SHORT FALLOUT2.0047851E
00478513 |. 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8]
00478517 |. 8B40 28 MOV EAX,DWORD PTR DS:[EAX+28]
0047851A |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
0047851E |> 837C24 0C 00 CMP DWORD PTR SS:[ESP+C],0
00478523 |. 74 0D JE SHORT FALLOUT2.00478532
00478525 |. 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8]
00478529 |. 8B5424 0C MOV EDX,DWORD PTR SS:[ESP+C]
0047852D |. 8B40 2C MOV EAX,DWORD PTR DS:[EAX+2C]
00478530 |. 8902 MOV DWORD PTR DS:[EDX],EAX
00478532 |> 89F2 MOV EDX,ESI
00478534 |. 89F8 MOV EAX,EDI
00478536 |. E8 45FDFFFF CALL FALLOUT2.00478280 ; Get attack_code (?)
0047853B |. 83F8 02 CMP EAX,2 ; is it a kick... (?)
0047853E |. 74 05 JE SHORT FALLOUT2.00478545
00478540 |. 83F8 01 CMP EAX,1 ; or a punch? (?) prevents melee bonus from being added to thrown weapons, I think...
00478543 |. 75 0E JNZ SHORT FALLOUT2.00478553
00478545 |> BA 0B000000 MOV EDX,0B
0047854A |. 89C8 MOV EAX,ECX
0047854C |. E8 F7690300 CALL FALLOUT2.004AEF48 ; If yes, Retrieve PC.Melee Damage Bonus
00478551 |. 89C5 MOV EBP,EAX
00478553 |> 8B1424 MOV EDX,DWORD PTR SS:[ESP] ; Default case of switch 004784AA - retrieve max damage of attack
00478556 |. 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] ; retrieve min damage of attack
// Add this line here ADD EAX,EBP ; min_damage += bonus_melee_damage
0047855A |. 01EA ADD EDX,EBP ; max_damage += bonus_melee_damage
0047855C |. 01D8 ADD EAX,EBX ; min_damage += special unarmed bonus
0047855E |. 01DA ADD EDX,EBX ; max_damage += special unarmed bonus
00478560 |. E8 5BAB0200 CALL FALLOUT2.004A30C0 ; return random number between min_dam and max_dam inclusive
00478565 |> 83C4 10 ADD ESP,10
00478568 |. 5D POP EBP
00478569 |. 5F POP EDI
0047856A |. 5E POP ESI
0047856B |. 59 POP ECX
0047856C |. 5B POP EBX
0047856D \. C3 RETN
Thank you Timeslip for the correction.Timeslip said:The second change is fine. The first isn't; you haven't given the arguments to stat_level. It'll just crash.
In any case, there's no point calling a function twice to get the same value. Just stick a 'add [esp+4], eax' in at 0x4784A7.
tbh, given how simple and self contained that function is, if you want to change it I'd rather hookscript it than make hardcoded changes to it.
That's not another portion of the code; it's in the bit that's already posted. Or do you mean something else?Glovz said:EDIT:
There is also one other portion of code I asked Haen to post - the section that calculates the bonus melee damage. There is still one change I would like to attempt making there.
I believe I understood the code posted correctly. But please slap me if I'm wrong again.Timeslip said:That's not another portion of the code; it's in the bit that's already posted. Or do you mean something else?Glovz said:EDIT:
There is also one other portion of code I asked Haen to post - the section that calculates the bonus melee damage. There is still one change I would like to attempt making there.
bonus_melee_damage = max(player_strength - 5, 1) + heavy_handed_bonus + (2 * rank_of_bonus_hth_damage_perk)
bonus_melee_damage = max(player_strength - 5, 1 + (2 * rank_of_bonus_hth_damage_perk)) + heavy_handed_bonus
That's the stat_level function. Nothing special there; it just returns a stat of a given critter. If you want to change a critters unarmed damage stat, there are a heck of a lot easier ways of doing it than fiddling with the exe. (i.e. the set_critter_stat script function.)Glovz said:This line --- CALL FALLOUT2.004AEF48 ; Retrieve PC.Melee Damage Bonus
int stat_level(sCritter* critter, DWORD statID) {
if(statID>=STAT_real_max_stat) return 0;
if(statID==STAT_current_hp) return critter_get_hits(critter);
if(statID==STAT_current_poison) return critter_get_poison(critter);
if(statID==STAT_current_rad) return critter_get_rads(critter);
int stat=stat_get_base(critter, statID) + stat_get_bonus(critter, statID);
if(statID==STAT_ac&&GetCombatState()==1&&critter!=combat_whose_turn()) {
int apmult=1;
if(perk_level(critter, PERK_hth_evade_perk)) {
sCritter* inven=inven_right_hand(obj_dude());
if(!inven||(item_get_type(inven)!=3&&item_w_anim_code(inven)==0)) {
inven=inven_left_hand(obj_dude());
if(!inven||(item_get_type(inven)!=3&&item_w_anim_code(inven)==0)) {
apmult*=2;
}
stat+=skill_level(critter, SKILL_UNARMED_COMBAT)/12;
}
}
stat+=critter->c_CurrentAP*apmult;
}
if(statID==STAT_pe&&critter->c_InjuredLimbs&CRITTER_EYEDAMAGE) stat-=5;
if(statID==STAT_age) stat+=game_time()/0x12CC0300;
if(statID==STAT_max_ap) {
int burden=stat_level(critter, STAT_carry_amt)<item_total_weight(critter);
if(burden<0) {
stat-=1 + (-burden)/40;
}
}
if(critter==obj_dude()) {
switch(statID) {
case STAT_st:
if(perk_level(critter, PERK_gain_strength_perk)) stat++;
if(perk_level(critter, PERK_adrenaline_rush_perk)) {
if(stat_level(critter, STAT_max_hp)/2 > stat_level(critter, STAT_current_hp)) stat++;
}
break;
case STAT_pe:
if(perk_level(critter, PERK_gain_perception_perk)) stat++;
break;
case STAT_en:
if(perk_level(critter, PERK_gain_endurance_perk)) stat++;
break;
case STAT_ch:
if(perk_level(critter, PERK_gain_charisma_perk)) stat++;
if(inven_right_hand(obj_dude())->PID==0x1b1||inven_left_hand(obj_dude())->PID==0x1b1) stat++;
break;
case STAT_iq:
if(perk_level(critter, PERK_gain_intelligence_perk)) stat++;
break;
case STAT_ag:
if(perk_level(critter, PERK_gain_agility_perk)) stat++;
break;
case STAT_lu:
if(perk_level(critter, PERK_gain_luck_perk)) stat++;
break;
case STAT_rad_resist:
case STAT_poison_resist:
if(perk_level(critter, PERK_vault_city_inoculations_perk)) stat+=10;
break;
case STAT_dmg_resist:
case STAT_dmg_resist_explosion:
if(perk_level(critter, PERK_dermal_armor_perk)) stat+=5;
if(perk_level(critter, PERK_dermal_enhancement_perk)) stat+=10;
break;
case STAT_dmg_resist_laser:
case STAT_dmg_resist_fire:
case STAT_dmg_resist_plasma:
if(perk_level(critter, PERK_phoenix_armor_perk)) stat+=5;
if(perk_level(critter, PERK_phoenix_enhancement_perk)) stat+=10;
break;
case STAT_max_hp:
if(perk_level(critter, PERK_alcohol_hp_bonus1_perk)) stat+=2;
if(perk_level(critter, PERK_alcohol_hp_bonus2_perk)) stat+=4;
if(perk_level(critter, PERK_alcohol_hp_neg1_perk)) stat-=2;
if(perk_level(critter, PERK_alcohol_hp_neg2_perk)) stat-=4;
if(perk_level(critter, PERK_autodoc_hp_bonus1_perk)) stat+=2;
if(perk_level(critter, PERK_autodoc_hp_bonus2_perk)) stat+=4;
if(perk_level(critter, PERK_autodoc_hp_neg1_perk)) stat-=2;
if(perk_level(critter, PERK_autodoc_hp_neg2_perk)) stat-=4;
break;
}
}
if(stat>stat_data[statID].Maximum) stat=stat_data[statID].Maximum;
if(stat<stat_data[statID].Minimum) stat=stat_data[statID].Minimum;
return stat;
}
Glovz said:After re-evaluating the last change I wanted to make, I find it doesn't have the affect I wanted and breaks my own rule of applying bonuses only after primarily values are calculated/selected.
With that said then I think the only change necessary is the one I made earlier today.
I still want to have Haen's input.
Haen did you get a chance to evaluate the code I posted from crazycc back on page 1 of this thread? crazycc claimed it added the HtH evade perk to both unarmed and melee attacks.
raw_HtH_damage = random(min_dam + special_unarmed_bonus + 2*rank_of_HtH_dam_perk, max_dam + melee_damage + heavy_handed_bonus + special_unarmed_bonus + 2*rank_of_HtH_dam_perk)
That was more or less what I was proposing. It would be nice if you defined 'melee_damage', though, to see if its really the case.raw_HtH_damage = random(min_dam + special_unarmed_bonus + 2*rank_of_HtH_dam_perk, max_dam + melee_damage + heavy_handed_bonus + special_unarmed_bonus + 2*rank_of_HtH_dam_perk)
Nevill said:That was more or less what I was proposing. It would be nice if you defined 'melee_damage', though, to see if its really the case.
max(strength - 5, 1)
Yes, your own brain.Haenlomal said:I do have RecStudio (btw, is there anything better out there?)
melee_damage = max(player_strength - 5, 1)
raw_damage = random(min_damage_of_melee_weapon, max_damage_of_melee_weapon + melee_damage)
raw_damage = random(1, 2 + melee_damage + heavy_handed_bonus) + special_unarmed_bonus + (2*rank_of_HtH_dam_perk)