Fallout 2 memory offsets

The formula you wrote is original version of damage formula which I try to fix because for AP ammo like 1/2 -50% this formula works very bad on armoured targets (the stronger armour, the worst).

New formula I wrote in my two last post is fixed one and I want to implement it to engine and i ask Ravachol to do this.

I could not make an example here to show differencies between old (original like yours formula) and this new formula ver2 now, because I am in my job now ;)
I will do it at evening today when I return to home :)
sorry for my terrible English but I hope is unterstanding

Then the prototype files could be adjusted to work with the formula and create better game balance.

See my old versions of Ammo Mods (ver 1.xx) They are based on original damage formula and they are not perfect :/
 
I'll make a new patch when I have the time, Mulligun sent me another algo:

((((base_damage*dam_mult)/2)*cbt_diff_mod)/100-dmg_tresh/dam_div-(((((base_damage*dam_mult)/2)/cbt_diff_mod)/100-dmg_tresh/dam_div)*(ammo_dr_adj+dmg_resist)/100) )/2

(it's the same algo I already implemented except that the result is divided by 2)

Could you look at it and tell me which one is the best?

bye
 
Of course Ravachol,
I am looking at the Mulligun's formula and I do not understand why he wants to divide all result by 2???
Its not new than the formula You implemented few weeks ago!

EDIT:
In my opinion the best formula is:

(((base_damage*dam_mult)/2)*cbt_diff_mod)/100-(dmg_tresh+dmg_tresh*DRammo)/dam_div-(((((base_damage*dam_mult)/2)/cbt_diff_mod)/100-(dmg_tresh+dmg_tresh*DRammo)/dam_div)*(DRammo+DRarmor)/100

where:
DRammo - ammo DR adjust
DRarmor - damage resistance of armor
ammo_dr_adj=DRammo+DRarmor

I wrote this yesterday but I am not sure you read that post...
 
How are called shots being calculated into this?

I think it would be a nice feature if armor like leather en metal armor don't get the bonuses for there heads (or atleast suffer an penalty of the DR) because there heads are being uncoverd. I know it gives an higher critical change but I think hitting someone in the face would hurt as bad as there wearing armor or not.

Armor like power armor en combat armour will get the DR DT bonuses because they have head protection. Maybe the eyes would be the weak spot for those armors.

What do you guys think?
 
Here is comparison of different damage algorithms:

http://cubik2k.w.interia.pl/pliki/damage_algorithms.png

algo ver 2 is the algo I wrote just today and yesterday
algo ver 1 is implemented to engine by Ravachol
algo original is Fallout2 original damage algo

See at JHP/AP ammo damage results and comparisons :)

@Oracle: I think that this is good idea but does it possible to do?
 
Cubik2k said:
@Oracle: I think that this is good idea but does it possible to do?

I do not know. I think if it is possible new algos have to me made for each armor and be put back into the EXE file...

and since Ravachol is the expert in this, maybe he could give the answer.
 
Oracle said:
How are called shots being calculated into this?

I think it would be a nice feature if armor like leather en metal armor don't get the bonuses for there heads (or atleast suffer an penalty of the DR) because there heads are being uncoverd. I know it gives an higher critical change but I think hitting someone in the face would hurt as bad as there wearing armor or not.

Armor like power armor en combat armour will get the DR DT bonuses because they have head protection. Maybe the eyes would be the weak spot for those armors.

What do you guys think?

This is bad idea, there is no variable like "covers_head" in armor prototypes. And checking just prototype number of armour isn't very flexibile.
 
Hello. I found in teamX(russian forum, I don't understand it much) offset of 13-year limit...

13-летнее ограничение (Работает не всегда...)
Версия: Смещение:
Fallout2 (US v1.0) 00092E9C
Fallout2 (US v1.02d) 000938D8
Fallout2 (UK v1.01) 00093688
Fallout2 (UK v1.02e) 00093A88
Fallout2 (GR v1.0)
Fallout2 (GR v1.02d) 00093BA8
Fallout2 (FR v1.0)
Fallout2 (FR v1.02d) 00093BA8
Fallout2 (LK v1.02d) 000937A8
Mapper2 000DB9B4
( Fallout2 (315371520) 0003CC12 )
Изменить на FFFFFFFF.

But 0003CC12 isn't 315371520 (it's 0030CC12).
0003CC12 is 315360000.

If this formula is right (24 * 3600 * 365 = 31536000) it should be 10 years limit then :mad:. Or am I wrong ?

Or is it just 3 years + that hex(but why ?) ? I want to change it to something else, don't want to fill it with FFFFFFFF....
 
13-летнее ограничение (Работает не всегда...)
13-years limit (Doesn't work always...)

I'd be careful on this one. It might have some side-effects.
 
So, we (me and mario_dweller) were trying to do some real "hack" to this 13 years limit. I managed to make some research in assembler code, not really sure if it is totally OK, but here is the relevant code commented by me:

Code:
BEGTEXT:004A34CF                 mov     edx, ds:dword_51C720 ; i really guess this is age of character
BEGTEXT:004A34D5                 add     edx, eax             ; don't know what is added to it
                                                              ;  - maybe current time delta of frame ?
BEGTEXT:004A34D7                 mov     ebx, 12CC0300h       ; this REALLY looks like 3600*24*365 
                                                              ;  (year in secs), let's call it 'year'
BEGTEXT:004A34DC                 mov     ds:dword_51C720, edx ; send changed probably-age value 
                                                              ;  - this looks like age even more (and supports 
                                                              ;     my theory of 004A34D5 line)
BEGTEXT:004A34E2                 mov     eax, edx             ; move age (let's call it age ;) to eax (for div)
BEGTEXT:004A34E4                 xor     edx, edx   
BEGTEXT:004A34E6                 div     ebx                  ; factor = age (in secs) / one_year_secs
BEGTEXT:004A34E8                 xor     ecx, ecx
BEGTEXT:004A34EA                 cmp     eax, 0Dh             ; THIS is important - checks factor with 13 
                                                              ;  (0Dh is 13)
BEGTEXT:004A34ED                 jb      short loc_4A3504     ; and if factor is below 13, then jump here
                                                              ;  so we're saved from dying
BEGTEXT:004A34EF                 mov     eax, 2
BEGTEXT:004A34F4                 mov     ebx, 2
BEGTEXT:004A34F9                 call    sub_440BD0           ; we're not saved, die... there's actually endgame
                                                              ;  code in this "function", vaberoidic pseudoevidence :)
So it looks like that (now changeable) number 13 of 13-years limit (13 is everywhere, invasion! :)) is exactly on this offset: 004A34EC (single byte) -- I hope I'm right, shamed if I'm not (well, mario did check it and player died after one year he set using his hand-made patcher.. ah, now (during typing this ;) ) next check, again works :twisted:) :shock:
 
What would be interesting is if we could change this memory offsets by an ingame script.

1) So a script could run ingame and change a global variables value.

2) The patcher could read the memory address of the Global variable

3) The patcher could then copy this value into the memory address of the desired iem to patch

It could be interesting as it would then be possible change various bits ingame.
 
Code:
FFFFFFCC ; Ins/Del : create/delete structure
FFFFFFCC ; D/A/*   : create structure member (data/ascii/array)
FFFFFFCC ; N       : rename structure or structure member
FFFFFFCC ; U       : delete structure member
FFFFFFCC ; Use data definition commands to create local variables and function arguments.
FFFFFFCC ; Two special fields " r" and " s" represent return address and saved registers.
FFFFFFCC ; Frame size: 34; Saved regs: 10; Purge: 0
FFFFFFCC ;
FFFFFFCC
FFFFFFCC var_34          dd ?
FFFFFFD0 var_30          dd ?
FFFFFFD4 var_2C          dd ?
FFFFFFD8 var_28          dd ?
FFFFFFDC var_24          dd ?
FFFFFFE0 var_20          dd ?
FFFFFFE4 var_1C          dd ?
FFFFFFE8 var_18          dd ?
FFFFFFEC var_14          dd ?
FFFFFFF0 var_10          dd ?
FFFFFFF4 var_C           dd ?
FFFFFFF8 var_8           dd ?
FFFFFFFC var_4           dd ?
00000000  s              db 16 dup(?)
00000010  r              db 4 dup(?)
00000014
00000014 ; end of stack variables

can anyone tell me what these variables are holding? I have been trying to learn assembly and I have been exploring the disassembled code of the fallout2.exe - I believe they hold proto file values, they are used in the damage calculation and that according to ravachol's research, var_10 for example should be the dam_mult (damage multiplier).

If someone is able to verify that these are holding proto file values and is able to tell what each normally holds then this would help me out a great deal in understanding the damage calculation and in the long run maybe figure out a way to change it.
 
Hi, it has been some time since I've last come here.

With what you show here, there's no way to tell what these variables are holding. To find out what these vars are, you have to study the code that uses them (how is the variable initialised? where did the value a variable was initialised with come from? how is the variable used? ...) and make assumptions (there's no way to be sure only by studying dead listing in such a big program), make some tests in a debugger...
Also, don't take to the letter the names I gave to the variables, it's easier to read some code when the variables have a name you'll remember, it doesn't have to come directly and unmodified from the proto file.

I'd like to take the time to help again on this issue but I don't have the time right now.

Good luck.
 
hey ravachol,

I was just wondering and hoping you could provide some insite. I noticed the line:
cmp eax, 0Dh
appears numerous times in the code. I understand this to be a check to compare some value stored in eax to the constant of 13(0D).

Does this mean that when the code was compiled from C that there was a constant defined as equal to 13 and thus the assembly just put 0D wherever that constant was used, or does it mean the number 13 was strictly hardcoded (typed as "13") everytime it was used?

I'm asking because if it is the first possibility then changing the 13 year check might be as easy as replacing every instance of 0D in the code.
 
An instruction out of its context doesn't mean anything else than what it does (here: "compare the value in eax with 0xD").

It's probable that this value was a constant in the original code: when you write a program, you usually define constants and use them instead of their values (it's easier to maintain the code this way).

However, a constant with a value of 13 is something common (any enumeration that starts from a value below 13 and ends after 13 has at least one element with this value).

It's really naive to think you could change a constant by replacing every occurences of its value in the executable. A byte with a value of 0xD could be a lot of differents things. You have to analyze the code to find all the occurences of this constant. Use the enumerations in ida to change the value with its name in your dead listing when you know what a value represents (you have already all the constants defined in the .h that come with the mapper, it can be of some help to rename some immediate values).

About the 13 years check, it seems that Vaber and mario_dweller have found where it was checked for. I will look where it's located in the program when I have some time to have a better idea of how it works.

bye.

EDIT:
I had a look at the function spotted by Vaber and mario_dweller, here's what I can say about it:
I had already encountered the variable at 0x51C720 and named it nbticksfromstart so, yes it can be considered like the age of the character.
The death of the character is set by the "mov ebx,2" (or maybe the mov eax,2", I don't have the code under my eyes right now) which is used to set the player's state a bit later (I don't remember in details how the player's state works, I think if player's state & 1 == false then the player is dead unless it is player's state == 2).
I had encountered the fuction at 0x440BD0 since it had a name in my listing but didn't go any further (I'd make a quick guess it might be used to set the death message when you die but that's just a guess, I'm absolutly not sure of that).
This function (I've just called it advance_time) is called from the script function game_time_advance (which is very poorly implemented but that's not very important) and from a subfunction used in the worldmap loop (when you move on the map... very surprising).
Something that should be checked to be sure to have a good patch is where the nbticksfromstart variable is incremented (if it is, but it has quite a few xrefs so it's not impossible) and if there's another check somewhere else.
 
Back
Top