GTA2 memory addresses

Anything to do with GTA1/GTA2 modding (tools, scripts and more).
User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

GTA2 memory addresses

Post by Sektor » 02 Oct 2013, 12:28

I need to write documentation for my documentation!

All of these addresses are relative to zero, you will need to subtract the base address value to get an address that you can use use in livesplit. For gta2script and any language that uses ReadProcessMemory, you don't need to subtract the base address.

gta2.exe v11.44 base address: 0x3F0000
gta2.exe v9.6f (free classics version) base address: 0x400000

GTA2 v11.44 is required for all of the GTA2 script examples in this topic. v9.6f doesn’t have the memory writing/reading commands, the addresses should still work on v9.6f but you’ll need to write to them using an external program.

To get player 1 ped address (ped):
In gta2script, you can just do ADD_SCORE (p1,p1)

In a language that supports ReadProcessMemory:
0x5EB4FC = ptr + 0x4 = p1playerptr + 0xC4 = p1

ped+16c=pointer to the ped's current car. It will be 0 if they are on foot.

ped+1AC=camera x coordinate (coordinates are 0 to 255 multiplied by 16384)
ped+1B0=camera y coordinate
ped+1B4=camera z coordinate

ped+216h=health
ped+200h=identification number
ped=240h=occupation
ped+244h=remap

0x673E2C (6766124) = 0 if singleplayer, 1 network mode

invisibilty, electrofingers on fire and more
I haven't figured all of these out yet. It's a bitmask.
it's a dword at p1+21Ch
invis is 2000000h, something else is 4000000h
[mis]COUNTER in
COUNTER out = 33554433 // this is invis/transparency (you need to get in and out of a car to make yourself transparent on your screen but you will already be invisible on other player's screens)
//COUNTER out = 67108865 // electrofingers
SET in = (p1+540)
CHANGE_GANG_CHAR_RESPECT (in, out, 114)[/mis]

Invulnerability
p1+520 (0x208)
Set to 9999 to for untimed invulnerability (same as SET_CHAR_INVINCIBLE). Set to a lower number for a timer invulnerability.

OBJECT postion and rotation:
object + 4 = object pointer
object pointer + 0 = angle (0 to 359) * 4
object pointer + 20 = footy x coord
object pointer + 24 = footy y coord
object coords pointer + 28 = footy z coord

Pointer to information about all players
0x5EB4FC
dword[this+4] = array 0-5 of player pointers
dword[this+1Ch] = my player pointer
byte[this+23h] = number of players
byte[this+24h] = which player i spriteam
dword[this+38h] = my player pointer
byte[player+2Fh] = are all their controls disabled?
byte[player+30h] = are their enter controls disabled?
dword[player+CCh] = camera locked to player
dword[player+128h] = game camera x,y,z
dword[player+1E4h] = view camera x,y,z
dword[player+2A0h] = aux camera x,y,z
dword[player+2C4h] = player Ped pointer?
dword [ped+15Ch] = player pointer
dword [ped+168h] = sprite pointer?
dword [ped+16Ch] = car pointer
dword [ped+1ACh] = x,y,z
word [sprite pointer + 40h] = angle in degrees * 4 (angle_conversion_factor_unk_664E00)

Playercount/number of players in the game
byte [ 23h + dword [5EB4FC]]
so peek the dword at 5EB4FC, add 23h to it, then use that to peek a byte

Example code:
COUNTER static = 6206716
SET in = (static+0)
CHANGE_GANG_CHAR_RESPECT (in,out,104)
SET in = (out+35)
CHANGE_GANG_CHAR_RESPECT (in,out,101)

character/ped/player angle/x,y,z coordinates/speed
pedsprite + 57 = walk/run speed. Speed 1 to 3 walk, 4 and above run. Any faster than 12 and you will outrun the camera.
Pedsprite = peek dword [p1 + 168h] 360
anglepointer = peek dword [pedprite + 80h] 128
peek word [anglepointer]
peek word [anglepointer] + 20 = x
peek word [anglepointer] + 24 = y
peek word [anglepointer] + 28 = z

Example code:
SET in = (p1+360)
CHANGE_GANG_CHAR_RESPECT (in,out,104)
SET in = (out+128)
CHANGE_GANG_CHAR_RESPECT (in,out,104)
SET in = (out+20) //read x
CHANGE_GANG_CHAR_RESPECT (in,out,104)

vehicle coords
p1car + 88 = car pointer + 48 = car X
p1car + 88 = car pointer + 52 = car Y
p1car + 88 = car pointer + 88 = car angle
p1car + 88 = car pointer + 108 = car Z // if you want Z adjust immediately then it must increase by 8192
p1car + 88 = car pointer + 64 = car X speed
p1car + 88 = car pointer + 68 = car Y speed

camera/zoom
SET in = (p+428)
CHANGE_GANG_CHAR_RESPECT (in,out,104)
SET x = (out+0)

SET in = (p+432)
CHANGE_GANG_CHAR_RESPECT (in,out,104)
SET y = (out+0)

SET in = (p+436)
CHANGE_GANG_CHAR_RESPECT (in,out,104)
SET z = (out+0) //zoooooooooooooom

read input/keyboard
vikeplayer = peek dword [p1 + 15C] , 348

SET in = (p+348)
CHANGE_GANG_CHAR_RESPECT (in,out,104)
SET in = (out+129)
CHANGE_GANG_CHAR_RESPECT (in,out,101)
IF (out=1)
EXPLODE (p)
ENDIF

ppp = player ped pointer
SET in=(out+112) // Up numpad (only in debug mode)
SET in=(out+113) // Down numpad (only in debug mode)
SET in=(out+114) // Left numpad (only in debug mode)
SET in=(out+115) // Right numpad (only in debug mode)
SET in=(out+116) // Home numpad (only in debug mode)
SET in=(out+117) // PageUp numpad (only in debug mode)
SET in=(out+118) // PageDown (only in debug mode)
SET in=(out+119) // PageUp (only in debug mode)
SET in=(out+120) //[ppp+78h] up pressed
SET in=(out+121) //[ppp+79h] down pressed
SET in=(out+122) //[ppp+7Ah] left pressed
SET in=(out+123) //[ppp+7Bh] right pressed
SET in=(out+124) //[ppp+7Ch] shoot pressed
SET in=(out+125) //[ppp+7Dh] bool: "hop in car" is pressed
SET in=(out+126) //[ppp+7Eh] brake/jump
SET in=(out+127) //[ppp+7Fh] "prev weapon" pressed
SET in=(out+128) //[ppp+80h] "next weapon" pressed
SET in=(out+129) //[ppp+81h] bool: special is pressed
SET in=(out+130) //[ppp+82h] bool: special 2 is pressed
SET in=(out+131) //[ppp+84h] bool: special has changed state
SET in=(out+133) // special (horn/furp)
SET in=(out+134) // right shift
SET in=(out+135) // next weapon
SET in=(out+136) // prev weapon
SET in=(out+137) //[ppp+89h]bool: "hop in car" has changed state
SET in=(out+138) // brake/jump
SET in=(out+139) // up
SET in=(out+140) // down
SET in=(out+141) // fire

This byte allows instant gang to get in parked cars/stored cars/mission cars. Normally they only get in dummy traffic cars.

p1car+152 // set to 3 to allow instant gang in your car and peds in your taxi, STORE_CAR_CHARACTER_IS_IN sets p1car+152 to 2.

[mis]
CAR_DATA p1car
COUNTER in
COUNTER cargangflag=3

IF (IS_CHARACTER_IN_ANY_CAR(p1))
STORE_CAR_CHARACTER_IS_IN (p1,p1car)
GIVE_WEAPON (p1car,CAR_MACHINE_GUN)
SET in=(p1car+152)
CHANGE_GANG_CHAR_RESPECT (in,cargangflag,111) // writes the value 3 to the IN memory address, 111 just means write 1 byte
ENDIF
[/mis]

You can enable do_show_ids by changing byte at 0x5EADA1 to 1. GTA2 will save that setting to registry.

[mis]
LEVELSTART

//showpedid
COUNTER showpedid = 6204833
COUNTER one = 1
CHANGE_GANG_CHAR_RESPECT (showpedid, one, 111)
[/mis]

PLAYER_PED p1 = (117.0,133.5,255.0) 10 270 // Red
PLAYER_PED p2 = (118.0,133.5,255.0) 09 090 // Orange
PLAYER_PED p3 = (117.5,132.5,255.0) 07 180 // Yellow
PLAYER_PED p4 = (117.5,134.5,255.0) 11 000 // Green
PLAYER_PED p5 = (117.0,132.5,255.0) 13 225 // Blue
PLAYER_PED p6 = (118.0,134.5,255.0) 08 045 // Black

Armour/Armor
[mis]
LEVELSTART

COUNTER loop = 1
COUNTER player_ptr
COUNTER player_addr
COUNTER armour_ptr
COUNTER armour_addr = 10

WHILE_EXEC (loop = 1)

ALTER_WANTED_LEVEL_NO_DROP (p1,6)

SET player_ptr = (p1+348)
CHANGE_GANG_CHAR_RESPECT (player_ptr,player_addr,104)
SET armour_ptr = (player_addr+1786)
CHANGE_GANG_CHAR_RESPECT (armour_ptr,armour_addr,111)

ENDWHILE

LEVELEND
[/mis]

0x5EC470 byte (menu) start in player area 0, 1 , 2
0x5EC471 byte (menu) bonus stage
0x5EC473 byte (menu) player profile

User avatar
T.M.
Immortal
Posts: 957
Joined: 29 Jan 2010, 15:00
Location: F21B3EED

Re: GTA2 memory addresses

Post by T.M. » 02 Oct 2013, 12:40

Finally!
Sektor wrote:I just found the byte that allows instant gang to get in parked cars or stored cars. Normally they only get in dummy cars.
Does it actually allow that on purpose, or is it just a side effect? That said, these kind of hacks might end up very buggy scripts if we adjust something we dont fully understand.

User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: GTA2 memory addresses

Post by Sektor » 02 Oct 2013, 12:50

T.M. wrote:Does it actually allow that on purpose, or is it just a side effect? That said, these kind of hacks might end up very buggy scripts if we adjust something we dont fully understand.
It looks harmless, I located that byte for this purpose. It makes sense that there is a byte that stores whether a car is a parked car, dummy car or mission car. I don't know if they blocked instant gang from entering mission cars on purpose. It might have been an accident since instant gang isn't used on the official singleplayer scripts.

I'm trying to figure out what the other car bytes do.

User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: GTA2 memory addresses

Post by Sektor » 10 Dec 2013, 19:35

Uh oh, I've been attemping C/C++. Some addresses that I might use for statistics and leaderboards.

LPVOID fraglimit_addr = (void*)0x5EC4AC;
LPVOID p1kills_addr = (void*)0x5EC4BA;
LPVOID p2kills_addr = (void*)0x5EC4C4;
LPVOID p3kills_addr = (void*)0x5EC4CE;
LPVOID p4kills_addr = (void*)0x5EC4D8;
LPVOID p5kills_addr = (void*)0x5EC4E2;
LPVOID p6kills_addr = (void*)0x5EC4EC;
LPVOID p1frags_addr = (void*)0x5EC500;
LPVOID p2frags_addr = (void*)0x5EC502;
LPVOID p3frags_addr = (void*)0x5EC504;
LPVOID p4frags_addr = (void*)0x5EC506;
LPVOID p5frags_addr = (void*)0x5EC508;
LPVOID p6frags_addr = (void*)0x5EC50A;
LPVOID p1name_addr = (void*)0x5EC524;
LPVOID p2name_addr = (void*)0x5EC544;
LPVOID p3name_addr = (void*)0x5EC564;
LPVOID p4name_addr = (void*)0x5EC584;
LPVOID p5name_addr = (void*)0x5EC5A4;
LPVOID p6name_addr = (void*)0x5EC5C4;
LPVOID gmp_addr = (void*)0x5EC075;
LPVOID sty_addr = (void*)0x5EC175;
LPVOID scr_addr = (void*)0x5EC275;
LPVOID mmp_addr = (void*)0x673E30;

Krassandra
Jaywalker
Jaywalker
Posts: 8
Joined: 26 Oct 2013, 23:01
GH nick: Krassandra

Re: GTA2 memory addresses

Post by Krassandra » 11 Dec 2013, 02:20

How about timer address?

User avatar
Cuban-Pete
Immortal
Posts: 909
Joined: 29 Jan 2010, 15:03
GH nick: Cuban-Pete

Re: GTA2 memory addresses

Post by Cuban-Pete » 11 Dec 2013, 09:27

Sektor wrote:Uh oh, I've been attemping C/C++. Some addresses that I might use for statistics and leaderboards.

LPVOID fraglimit_addr = (void*)0x5EC4AC;
LPVOID p1kills_addr = (void*)0x5EC4BA;
LPVOID p2kills_addr = (void*)0x5EC4C4;
...
Nice! I tried some of them in CheatEngine and they work. p1kills_addr etc. are 2 byte type. Funny thing is that cheating is also very easy now, but the other can see that you cheated because the score does not add up.
"Mmmm, your eyes are so beautiful."

User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: GTA2 memory addresses

Post by Sektor » 11 Dec 2013, 09:42

Cuban-Pete wrote:Nice! I tried some of them in CheatEngine and they work. p1kills_addr etc. are 2 byte type. Funny thing is that cheating is also very easy now, but the other can see that you cheated because the score does not add up.
I used Cheat Engine to find these addresses. Most should be 2 bytes but I think fraglimit is 4 bytes. I read 32 bytes for the player names and filenames but they might be longer.

Changing these locally won't give you any multiplayer advantages, it will just cause desyncs.
Krassandra wrote:How about timer address?
Which timer? I'll find all the multiplayer settings.

User avatar
roarke
Mugger
Mugger
Posts: 16
Joined: 09 Dec 2013, 12:08
GH nick: Roarke
Location: Romania
Contact:

Re: GTA2 memory addresses

Post by roarke » 11 Dec 2013, 15:11

Sektor, does this work in multiplayer too ?

User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: GTA2 memory addresses

Post by Sektor » 11 Dec 2013, 16:15

roarke wrote:Sektor, does this work in multiplayer too ?
It depends what you mean by work. You can read them fine in multiplayer but for writing you would need to change the addresses on every computer playing or it would cause a desync.

None of these addresses will change what is displayed on screen during the game since those have their own addresses. You might see the changes on the final results screen but it won't match what others see.

User avatar
T.M.
Immortal
Posts: 957
Joined: 29 Jan 2010, 15:00
Location: F21B3EED

Re: GTA2 memory addresses

Post by T.M. » 11 Dec 2013, 16:15

Cuban-Pete wrote:
Sektor wrote:Uh oh, I've been attemping C/C++. Some addresses that I might use for statistics and leaderboards.

LPVOID fraglimit_addr = (void*)0x005EC4AC;
LPVOID p1kills_addr = (void*)0x005EC4BA;
LPVOID p2kills_addr = (void*)0x005EC4C4;
...
Nice! I tried some of them in CheatEngine and they work. p1kills_addr etc. are 2 byte type. Funny thing is that cheating is also very easy now, but the other can see that you cheated because the score does not add up.
Finally a convenient way for old people to play this game without learning all the chea... tricks! (or should i say "features"). Thanks Sektor! 8-)

Galactic Boy
Immortal
Posts: 333
Joined: 15 Apr 2012, 08:26

Re: GTA2 memory addresses

Post by Galactic Boy » 28 Oct 2014, 14:38

Can we script invisible bots with this script?

User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: GTA2 memory addresses

Post by Sektor » 14 Nov 2014, 13:09

Yes there is invisible code above.

robotanarchy documented a player movement input address:

0x5ecacc

// movement bits, as ORed together in GTA2 memory
// reverse engineered by robotanarchy
#define GTA2_CTRL_NOT_MOVING 0
#define GTA2_CTRL_FORWARD 1
#define GTA2_CTRL_BACKWARD 2
#define GTA2_CTRL_LEFT 4
#define GTA2_CTRL_RIGHT 8
#define GTA2_CTRL_ATTACK 16
#define GTA2_CTRL_ENTER_EXIT 32
#define GTA2_CTRL_JUMP_HANDBRAKE 64
#define GTA2_CTRL_WEAPON_PREV 128
#define GTA2_CTRL_WEAPON_NEXT 256
#define GTA2_CTRL_SPECIAL_1 512
#define GTA2_CTRL_SPECIAL_2 1024

GTA2 script example:
[mis]
COUNTER keys = 16 // fire weapon
COUNTER input = 6212300 // 0x5ecacc
CHANGE_GANG_CHAR_RESPECT ( input, keys, 112 ) // CHANGE_GANG_CHAR_RESPECT is a special command that can read/write memory[/mis]

That will make ALL players fire their weapon

User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: GTA2 memory addresses

Post by Sektor » 15 Nov 2014, 09:14

dword ptr [0x66A3B4] + word 0x44 = p1 angle/rotation

0x5DE03C = local player rotation

User avatar
Pyro
Immortal
Posts: 414
Joined: 17 Mar 2010, 04:07
GH nick: Pyro
Location: Wales, UK

Re: GTA2 memory addresses

Post by Pyro » 17 Nov 2014, 10:41

Could this (or some other memory address) also be used to allow groups following the player to get on and off trains? Currently they don't (and never have).

Speaking of trains, you know at each station the train carriages seems to spawn its own peds even if none got on the previous station? I'm guessing that can possibly be changed also... all we need now is just a load of Elvis's jumping off the train! 8-)

User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: GTA2 memory addresses

Post by Sektor » 17 Nov 2014, 13:01

I tried changing p1car+152 to 3 while on a train but my gang still couldn't get in. There must be some other check for trains.

I have the code for changing any random ped to an Elvis or any remap but you will see them change remap. There must be a way to choose their remap before they are created but I haven't looked for that memory location.

You can use CREATE_CHAR_INSIDE_CAR and ORDER_DRIVER_OUT_CAR on a train to make custom peds jump out.

User avatar
Pyro
Immortal
Posts: 414
Joined: 17 Mar 2010, 04:07
GH nick: Pyro
Location: Wales, UK

Re: GTA2 memory addresses

Post by Pyro » 17 Nov 2014, 18:21

Sektor wrote:You can use CREATE_CHAR_INSIDE_CAR and ORDER_DRIVER_OUT_CAR on a train to make custom peds jump out.
Interesting, but I thought that trains / carriages didn't have 'names', other than station names declared in map and script? Or are you using STORE_CAR_CHARACTER_IS_IN first? Maybe a code example might be useful here or in code snippits.

Looking at these makes me realise how long I've not done any GTA2 scripting for!

User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: GTA2 memory addresses

Post by Sektor » 17 Nov 2014, 22:50

Does that mean you never saw Grand Theft Loco? You can use STORE_CAR_CHARACTER_IS_IN but Jones and I figured out how to reference any random ped/vehicle. Last page of the GTA Loco topic has code.

User avatar
Pyro
Immortal
Posts: 414
Joined: 17 Mar 2010, 04:07
GH nick: Pyro
Location: Wales, UK

Re: GTA2 memory addresses

Post by Pyro » 18 Nov 2014, 11:17

Ah very nice, I think I saw it a good while ago but forgot about it.

User avatar
Pyro
Immortal
Posts: 414
Joined: 17 Mar 2010, 04:07
GH nick: Pyro
Location: Wales, UK

Re: GTA2 memory addresses

Post by Pyro » 18 Nov 2014, 12:49

I forgot to ask actually, do you think this stuff would control how 'tough' a ped is?

For example, a normal game created ped can be killed with 1 pistol shot (as can police with 1 wanted level) whereas SWAT/FBI guys are significantly tougher. I always assumed it was modified by their character type but no matter what you set it to they all seem to be the same for script-created characters. I'm guessing 'game created' peds (peds, police, SWAT, FBI etc) have their own 'toughness' somewhere?

User avatar
Sektor
Boss
Boss
Posts: 1369
Joined: 04 Mar 2008, 06:51
GH nick: Sektor
Location: GTAMP.com
Contact:

Re: GTA2 memory addresses

Post by Sektor » 19 Nov 2014, 03:25

This script sets p1 health to 200%. You could use it on any ped.
[mis]
COUNTER address
COUNTER health=200
SET address=(p1+534) //health
CHANGE_GANG_CHAR_RESPECT (address, health, 112)
[/mis]
word pedstruct + 216h = health

FBI and SWAT have more health than 100.

Post Reply