GTA: Modification Area

A website for the GTA modding scene

Search
 
 

Display results as :
 


Rechercher Advanced Search

Latest topics
» Big-game starts raising Schneider's profile
Sun Mar 04, 2012 2:28 am by lavivi

» [Help] cleo created lighting
Thu Oct 14, 2010 1:03 am by findmy012

» Mission Question
Thu Oct 14, 2010 1:02 am by findmy012

» [IV] Spoiler Script
Thu Oct 14, 2010 1:02 am by findmy012

» Mission mod [help]
Sat Sep 18, 2010 5:50 pm by jayd00

» Bc7 Mod Help
Fri Aug 20, 2010 11:19 am by pengpeng

» Found a bug
Fri Dec 18, 2009 4:22 am by _CJ360_

» [IV] Novitec Rosso 599 GTB
Tue Nov 17, 2009 4:22 pm by Kotton

» Hello/Guidance Request
Mon Oct 12, 2009 6:45 am by Adler

Navigation
 Portal
 Index
 Memberlist
 Profile
 FAQ
 Search
Affiliates
image

Image

Image

Image

Image

Image

Image

Image

Image

Image

image

Image

steve-m.com

Image


----- Русский -----

Если ваш сайт содержит большую коллекцию SCM/CLEO-скриптов (больше 16), напишите на мой e-mail, и я добавлю его в список. Приветствуются скрипты, которые не встречаются на других сайтах ... Спасибо. ))))


----- English -----

If your website has a big enough collection of SCM/CLEO scripts (more than 16) notify me by e-mail
, and I will add it to the list. The unique scripts are preferable ... Thank you. ))))

Log in

I forgot my password



December 2016
MonTueWedThuFriSatSun
   1234
567891011
12131415161718
19202122232425
262728293031 

Calendar Calendar


You are not connected. Please login or register

SA Memory Example Topic

Go to page : 1, 2  Next

View previous topic View next topic Go down  Message [Page 1 of 2]

1 SA Memory Example Topic on Sat Mar 07, 2009 8:51 am

I have recently decided to create a new topic to give & collect examples of memory hacking. Cool Some of what I post here may be already know (commonly, less commonly, or may be not know), the purpose of this topic is to help individuals, and keep up to date on our example(s), if you do not understand what is written may be your scripting skills are not good with memory handling, or may be you are not skilled in memory hacking(?) However I will try to explain as clear as I can, some thing which I may post may have already been posted by me or other users on other forums, in a different language, or in the English language. Please note; that most of these are tested with the original game version(v1 U.S San Andreas), and some with the v1 German EXE version, if you find something un-working, or not working correctly make sure you check your EXE's version, (as thing very-upon in different game versions).


Any Key



Check if any key has been pressed, notably; you can check most keys with the CLEO opcode 0AB0, but some times does not work right, and you can use this opcode only if the CLEO library is installed, or you have the opcode source running from your main.scm like was explained in the project CLEO topic by Seemann.

1: Open the keys list All indexes are for version 1.0
2: Get the index of the key(s) you are going to use.
3. First column contains the index pointing to the key related memory address.
4. The keys located at the column KeyLo returns 0xFF when pressed. The keys located at the column KeyHi returns 0xFF0000 when pressed.
5. Read the mem addy using index and compare the value with the conforming constant.

Here is an example:


Code:

0@ = 304484 // Num1, Num2 index

:Test
while true
wait 0
if
  &0(0@,1i) == 0x00FF00FF // Num1+Num2
then
    1@ = 25000
    1@ *= 40  // 25k mul* 40 
    player.money($player_char) += 1@
    end
end // "while"


Cheats



In San Andreas "0x969110" is the start of an array that keeps 30 last pressed keys in SA. Accessing this address allows to create new cheats/passwords in run-time. However there is a integer value for an array index that points at this address: -229908.


Code:

0@ = -229908
008B: 1@ = &0(0@,1i)


The last four of the chars stores to 1@


So first of all making cheats through the arrays way
OK:
You can see here for scripts to test how the cheats work, now on to this:


Code:

:Cheat_03
wait 0
1@ = -229907 // address
008B: 1@ = &0(1@,1i)  // get last keypresses
0085: 2@ = 1@ // (int)
div(2@, 0x 1 00 00) // 1char 256, 2chars: 65536: 3chars: 16777216   
mul(2@, 0x 1 00 00) // same 
0062: 1@ -= 2@ // get needed number of chars (2)
if
  1@ == 0x5345
jf @Cheat_03
 1@ = -229908 // address +1          // "search"
if
  &0(1@,1i) == 0x41524348 
jf @Cheat_03
&0(1@,1i) = 0x41524300
03E5: show_text_box 'CHEAT1'  // Cheat activated


The line 1@ == 0x5345 is the first two letters of the cheat, in HEX, the line &0(1@,1i) == 0x41524348 is the next 4 letters(this cheat has 6 letters), and this line &0(1@,1i) = 0x41524300 it's the same line as above only the last digit replaced with 00.

Example script to test cheats was originally posted by me in that topic.


Code:

{$CLEO}
0000:
// Example of cheats

// Testing 4 letter cheat
// Type "hack"
:Cheat_01
0001: wait 0 ms
0006: 29@ = -0x38214
00D6: if
0038:  &0(29@,1i) == 0x4841434B
004D: jump_if_false @Cheat_02
0004: &0(29@,1i) = 0x48414300
03E5: show_text_box 'CHEAT1'  // Cheat activated
0002: jump @Cheat_01

// Testing 6 letter cheat
// Type "cheats"
:Cheat_02
0006: 30@ = -0x38213
008B: 30@ = &0(30@,1i) // (int)
0085: 31@ = 30@ // (int)
0016: 31@ /= 0x10000
0012: 31@ *= 0x10000
0062: 30@ -= 31@ // (int)
00D6: if
0039:  30@ == 0x4348
004D: jump_if_false @Cheat_03
0006: 30@ = -0x38214
00D6: if
0038:  &0(30@,1i) == 0x45415453   
004D: jump_if_false @Cheat_03
0004: &0(30@,1i) = 0x45415400
03E5: show_text_box 'CHEAT1'  // Cheat activated
0002: jump @Cheat_01

// Testing 8 letter cheat
// Type "scriptin"
:Cheat_03
0006: 28@ = -0x38213
00D6: if
0038:  &0(28@,1i) == 0x53435249 
004D: jump_if_false @Cheat_04
0006: 28@ = -0x38214
00D6: if
0038:  &0(28@,1i) == 0x5054494E       
004D: jump_if_false @Cheat_04
0004: &0(28@,1i) = 0x50544900
03E5: show_text_box 'CHEAT1'  // Cheat activated
0002: jump @Cheat_01

// Testing 10 letter cheat
// Type "Memoryhack"
:Cheat_04
0006: 20@ = -0x38212 
008B: 20@ = &0(20@,1i) // (int)
0085: 21@ = 20@ // (int)
0016: 21@ /= 0x10000
0012: 21@ *= 0x10000
0062: 20@ -= 21@ // (int) 
00D6: if
0039:  20@ == 0x4D45   
004D: jump_if_false @Cheat_05
0006: 20@ = -0x38213
00D6: if           
0038:  &0(20@,1i) == 0x4D4F5259 
004D: jump_if_false @Cheat_05
0006: 20@ = -0x38214
00D6: if
0038:  &0(20@,1i) == 0x4841434B         
004D: jump_if_false @Cheat_05
0004: &0(20@,1i) = 0x48414300
03E5: show_text_box 'CHEAT1' // Cheat activated
0002: jump @Cheat_01

// Testing 12 letter cheat
// Type "SannyBuilder"
:Cheat_05
0006: 27@ = -0x38212
00D6: if
0038:  &0(27@,1i) == 0x53414E4E       
004D: jump_if_false @Cheat_01
0006: 27@ = -0x38213
00D6: if
0038:  &0(27@,1i) == 0x59425549 
004D: jump_if_false @Cheat_01
0006: 27@ = -0x38214
00D6: if
0038:  &0(27@,1i) == 0x4C444552 
004D: jump_if_false @Cheat_01
0004: &0(27@,1i) = 0x4C444500
03E5: show_text_box 'CHEAT1'  // Cheat activated
0002: jump @Cheat_01



CLEO OpCodes way


This way uses the cheats start address "0x969110",
This time 4 letters is used up the address of course needs to move up for example; you start with "0x969110", if you used up 4 keys, after that you if you wanna use any more, then the next time you use the address it's going to be "0x969114".


Code:

:6_Letter
wait 0
0A8D: 3@ = read_memory 0x00969110 size 4 virtual_protect 0
0A8D: 4@ = read_memory 0x00969114 size 2 virtual_protect 0
if and
04A4:  3@ == 0x4D4F5259 // mory 
04A4:  4@ == 0x4D45 // me 
jf @6_Letter
03E5: show_text_box 'CHEAT1'
0A8C: write_memory 0x00969110 size 4 value 0x0 virtual_protect 0
0A8C: write_memory 0x00969114 size 2 value 0x0 virtual_protect 0


Example script to test cheats was originally posted by me in that topic.


Code:

{$CLEO}
0000:
// Example of cheats

// Testing 4 letter cheat
// Type "test"
:4_Letter   
0001: wait 0 ms                               
0A8D: 0@ = read_memory 0x00969110 size 4 virtual_protect 0
00D6: if
04A4:  0@ == 0x54455354
004D: jump_if_false @8_Letter
03E5: show_text_box 'CHEAT1'
0A8C: write_memory 0x00969110 size 4 value 0x0 virtual_protect 0
0002: jump @Restart

// Testing 8 letter cheat
// Type "SannyBui"
:8_Letter
0A8D: 1@ = read_memory 0x00969110 size 4 virtual_protect 0
0A8D: 2@ = read_memory 0x00969114 size 4 virtual_protect 0
00D6: if and
04A4:  1@ == 0x59425549 // ybui 
04A4:  2@ == 0x53414E4E  // sann
004D: jump_if_false @6_Letter
03E5: show_text_box 'CHEAT1'
0A8C: write_memory 0x00969110 size 4 value 0x0  virtual_protect 0
0A8C: write_memory 0x00969114 size 4 value 0x0  virtual_protect 0
0002: jump @Restart

// Testing 6 letter cheat
// Type "Memory"
:6_Letter
0A8D: 3@ = read_memory 0x00969110 size 4 virtual_protect 0
0A8D: 4@ = read_memory 0x00969114 size 2 virtual_protect 0
00D6: if and
04A4:  3@ == 0x4D4F5259 // mory 
04A4:  4@ == 0x4D45 // me 
004D: jump_if_false @7_Letter
03E5: show_text_box 'CHEAT1'
0A8C: write_memory 0x00969110 size 4 value 0x0  virtual_protect 0
0A8C: write_memory 0x00969114 size 2 value 0x0  virtual_protect 0
0002: jump @Restart

// Testing 7 letter cheat
// Type "hacking"
:7_Letter
0A8D: 5@ = read_memory 0x00969110 size 4 virtual_protect 0
0A8D: 6@ = read_memory 0x00969114 size 2 virtual_protect 0
0A8D: 7@ = read_memory 0x00969116 size 1 virtual_protect 0
00D6: if and
04A4:  5@ == 0x4B494E47 // king
04A4:  6@ == 0x4143 // ac
04A4:  7@ == 0x48 // h       
004D: jump_if_false @Restart
0A8C: write_memory 0x00969110 size 4 value 0x0 virtual_protect 0
0A8C: write_memory 0x00969114 size 2 value 0x0  virtual_protect 0
0A8C: write_memory 0x00969116 size 1 value 0x0  virtual_protect 0
03E5: show_text_box 'CHEAT1'

:Restart
0001: wait 2000 ms
0002: jump @4_Letter


Easiest way


This way was posted some days ago originally by Seemann on GTAForums

It uses the functions call SCM, here is the main part of the code:


Code:

:TestCheat
if
  0AA9:    is_game_version_original
then
  10@ = 0x969110 // keypresses buffer 1.0
  11@ = 0xA48960 // mission locals 1.0
else
  10@ = 0x96B790 // keypresses buffer 1.01
  11@ = 0xA4AFE0 // mission locals 1.01
end
// get 0@'s offset
0A9F: 4@ = current_thread_pointer
0A8E: 5@ = 4@ + 0xDC // mission Flag
0A8D: 5@ = read_memory 5@ size 1 virtual_protect 0
if
  5@ == 1
then
  0085: 4@ = 11@
else
  4@ += 0x3C
end
// get cheat string length
6@ = 0
while true
  0A8D: 5@ = read_memory 4@ size 1 virtual_protect 0
  if and
      5@ > 0
      6@ < 16
  then
      inc(4@)
      inc(6@)       
  else
      Break
  end
end
0085: 8@ = 10@
while 6@ > 0
  dec(4@)     
  dec(6@)
  0A8D: 5@ = read_memory 4@ size 1 virtual_protect 0 // last cheat char
  // lowercase to uppercase (a->A)
  if
      5@ > 90
  then
      5@ -= 32
  end
  0A8D: 7@ = read_memory 8@ size 1 virtual_protect 0 // last pressed key
  inc(8@) 
  if
      803B:  5@ <> 7@ // (int)
  then
      059A: return_false
      0AB2: ret 0
  end
end
0A8C: write_memory 10@ size 1 value 0 virtual_protect 0
0485: return_true
0AB2: ret 0


You then can call this code check through a script:


Code:

{$CLEO}
0000:
while true
  wait 250 ms
  0@s = 'nocops'
  if
      0AB1: call_scm_func @TestCheat 2 0@ 1@
  then
      0110: clear_player $PLAYER_CHAR wanted_level
  end
end

{$I TestCheat.inc}


The cheat string gets saved to a variable:


Code:

0@s = 'nocops'


If your cheat is longer than 7 symbols, use long strings:


Code:

{$CLEO}
0000:
while true
  wait 250 ms
  22@v = "leavemealone"
  if
      0AB1: call_scm_func @TestCheat 4 22@ 23@ 24@ 25@
  then
      0110: clear_player $PLAYER_CHAR wanted_level
  end
end


The cheat string is case-insensitive. You may write 0@s = 'nocops', 0@s = 'NoCoPs', 0@s = 'nOCOPs', it will still work.

The cheat could be from 1 to 16 symbols in length.


Hard-Coded Interface color changing



This was explained here, please refer to this

Hack weapon pickup size




Code:

032B: 5@ = create_weapon_pickup #DESERT_EAGLE group 15 ammo 99999 at 0@ 1@ 2@
0AA7: call_function 0x4552A0 num_params 1 pop 1 5@ 0@
mul(0@,0x20)
inc(0@,0x9788C4)
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
inc(0@,0x15C)
0A8C: write_memory 0@ size 4 value 12.0 virtual_protect 0


Respray




Code:

//&-ALL VEHICLES SPARRYBLE!-&
//--************************************--//
// IMPORTANT: possibility of police cars, and such vehicles allowing you to respray, them other then getting the stupid message all the time.
// 1: Open gtasa.exe with a hex editor
// 2: Find 14334978
// 3: There will be written 2 bytes: 32 C0
// 4: Replace these with the following: B0 01
// 5: Save-finish, and then test
//--************************************--//


A topic for this was published here

Timer and status text without using global variables



Last edited by gtasbigfoot on Sun Mar 22, 2009 10:41 am; edited 4 times in total

View user profile http://gtamodding.com

2 Re: SA Memory Example Topic on Sat Mar 07, 2009 8:52 am

Code:

//&-CLEO MADE TIMER-&
//--************************************--//
// CLEO TIMER
// Main reason is timers must use global vars,
// and this way is NOT good to use in CLEO script,
// so you can use this way for when writing a script in CLEO
// works with v1 San Andreas!
//--************************************--//


Code:

// here the main thing off all the code
:AddSText               
0AB1: call_scm_func @VTO 1 0@ 0@
0AB1: call_scm_func @VTO2 1 2@ 2@
0AA6: call_method 0x0044CDA0 struct 0x00BA1788 num_params 4 pop 0 ( LINE = 3@ GXT = 2@ TYPE = 1@ VARNUMBER = 0@ )
0AB2: ret 0

:RemoveST
0AB1: call_scm_func @VTO 1 0@ 0@
0AA6: call_method 0x0044CE80 struct 0x00BA1788 num_params 1 pop 0 ( VARNUMBER = 0@ )
0AB2: ret 0

:SetT
0AB1: call_scm_func @VTO 1 0@ 0@
0AB1: call_scm_func @VTO2 1 2@ 2@
0AA6: call_method 0x0044CD50 struct 0x00BA1788 num_params 3 pop 0 ( TYPE = 1@ GXT = 2@ VARNUMBER = 0@ )
0AB2: ret 0

:StopT
0AB1: call_scm_func @VTO 1 0@ 0@
0AA6: call_method 0x0044CE60 struct 0x00BA1788 num_params 1 pop 0 ( VARNUMBER = 0@ )
0AB2: ret 0

:VTO
0A9F: 1@ = current_thread_pointer
0A8E: 2@ = 1@ + 0xDC
0A8D: 2@ = read_memory 2@ size 1 virtual_protect 0
if
    2@ == 1
then
    1@ = 0x00A48960
else
    1@ += 0x3C
end
0@ *= 4
005A: 1@ += 0@
1@ -= 0xA49960
0AB2: ret 1 1@

:VTO2
if
    0@ == 0
then
    0AB2: ret 1 0
end
0A9F: 1@ = current_thread_pointer
1@ += 0x10
0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0 // baseIP
0062: 1@ -= 0@
1@ += 3
0AB2: ret 1 1@

:StatusText
0900: 'BB_19'
0000:




Code:

//--AddStatusText--//
 0AB1: call_scm_func @AddSText 4 VARNUMBER = 33 TYPE = 0 GXT = @StatusText LINE = 3

VARNUMBER = 33 - the number of local variable, a value which will be displayed (ie, 33@)

TYPE = 0 - as in the 03C4 type status: bar (1) or number (0).

GXT = @ StatusText - this is the main difference from the actual opcode. Directly to transmit a string to a function can not be (as well as a new flow, for example). Therefore, we pass the label, which is opcode 0900 to the appropriate text (GXT) (in this case 0900: 'BB_19'). You can add multiple row opcode 0900, each with their GXT and its label, and send to the function the desired tag. You can write 0 instead of tags, then only the number will be displayed without the text on the left.


Code:

//--Remove Status Text--//
 0AB1: call_scm_func @RemoveST 1 VARNUMBER = 33

This removes the status text like the opcode 0151: would do when used.

Code:

//--Set Timer--//
 0AB1: call_scm_func @SetT 3 VARNUMBER = 1 TYPE = 1 GXT = @StatusText

The parameter TYPE is the type of timer: increases(0) or decreases(1).

Code:
 
//--Stop Timer--//
 0AB1: call_scm_func @StopT 1 VARNUMBER = 1


This stops the timer like opcode 014F would do when used.


Change GXT entrys



Original


Code:

alloc($_param1, 76)
alloc($_asmproc, 77)
alloc($_param2, 78)
1@ = @_GXTNewString_1 
2@ = @_GXTNewString_2
0@ = -429863               
31@ = 1
  while 31@ < 4  // strings*2


// -------------------------------
// FIND GXT ENTRY
// -------------------------------       
      &0(0@,1i) = 0xA49960
      &0(0@,1i) += @_GetGxtStringPointer
      $_asmproc = 0x6A0050              // char* GetGxtString
      $_param1 = 0xA49958
      005E: $_param1 += 1@(31@,33i)      // char* GXTEntry     
      0572: run_asm_inject true
// -------------------------------
// CHANGE GXT STRING
// -------------------------------
      dec(31@)
      $_param1 = 0xA49964
      005E: $_param1 += 1@(31@,33i)    // char* Source, new string
      &0(0@,1i) = 0xA49960
      &0(0@,1i) += @_CopyString
      $_asmproc = 0x718660              // int CopyString
      0572: run_asm_inject true
      inc(31@,2)     
  end 
return


// ASM injectors
// ------------------------------- 
// .text:006A0050 ; char *__cdecl GetGxtString(char *GXT_Entry)
  :_GetGxtStringPointer
  hex
  FF 35 909AA400      // push dword ptr [0xA49960+$_param1*4]
  B9    40B3C100      // mov ecx, @aAmericanGxt
  FF 15 949AA400      // call dword ptr [0xA49960+$_asmproc*4]
  A3    989AA400      // mov [$_param2], eax
  C3                  // return 
  end
  // .text:00718660 ; int __cdecl CopyString(char *Destination,char *Source)
  :_CopyString
  hex
  FF 35 909AA400      // push dword ptr [0xA49960+$_param1*4]
  FF 35 989AA400      // push dword ptr [0xA49960+$_param2*4]
  FF 15 949AA400      // call dword ptr [0xA49960+$_asmproc*4]
  83 C4 08            // add esp, 8
  C3                  // return 
  end                                                         
  // Compiled Strings Pool (null-terminated)
 
:_GXTNewString_1
  0900: "Text Value"
  0900: 'Entry'
 
:_GXTNewString_2
  0900: "Text Value"
  0900: 'Entry'



Code:

// ----------------------------------------------------------------------
//          A different way using CLEO Opcodes
// ----------------------------------------------------------------------   

0A9F: 1@ = current_thread_pointer
000A: 1@ += 0x10
0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0
000E: 1@ -= @GxtLabel
000A: 1@ += 0x3
0AA8: call_function_method 0x6A0050 struct 0xC1B340 num_params 1 pop 0 1@ 0@ // GetGxtString
000A: 1@ += 0xC
0AA5: call 0x718600 num_params 2 pop 2 0@ 1@ // cpystr
0A93: end_custom_thread

:GxtLabel
0900: 'ITBEG'         

:NewName
0900: "NEW NAME"         
0000: null_terminator



Last edited by gtasbigfoot on Sat Mar 07, 2009 9:11 am; edited 2 times in total

View user profile http://gtamodding.com

3 Re: SA Memory Example Topic on Sat Mar 07, 2009 8:52 am

*reserved*

View user profile http://gtamodding.com

4 Re: SA Memory Example Topic on Sat Mar 07, 2009 9:19 am

Displaying text with games memory




Code:
 
// ----------------------------------------------------------------------
//          Ways of displaying text over the memory
// ---------------------------------------------------------------------- 

:Hexa
0A9F: 27@ = current_thread_pointer
000A: 27@ += 0x10
0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
000E: 27@ -= @Message
00D6: if 
0AA9:  is_game_version_original 
then
    0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 27@ 
else
    0AA5: call 0x5893B0 num_params 4 pop 4 0 0 0 27@
end

:Message
hex
"~g~ write_message_here" 00  // Put _ between each word as a space
end

 
// ----------------------------------------------------------------------
//          Using 0900: Object Opcode
// ---------------------------------------------------------------------- 

:0900:
0A9F: 27@ = current_thread_pointer
000A: 27@ += 0x10
0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
000E: 27@ -= @Message
27@ += 4  // Skip 0900: data
00D6: if 
0AA9:  is_game_version_original 
then
    0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 27@ 
else
    0AA5: call 0x5893B0 num_params 4 pop 4 0 0 0 27@
end

:Message
0900: "~g~ write message here"
0000: null-terminator

// ----------------------------------------------------------------------
//          Using Call Fuctions
// ---------------------------------------------------------------------- 
0AB1: call_scm_func @SubStrings 1 @Message 
0A93: end_custom_thread

:SubStrings
0A9F: 27@ = current_thread_pointer
000A: 27@ += 0x10
0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
0062: 27@ -= 0@ // (int)
27@ += 4
00D6: if 
0AA9:  is_game_version_original 
then
    0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 27@
else
    0AA5: call 0x5893B0 num_params 4 pop 4 0 0 0 27@
end
0AB2: ret 0

:Message
0900: "~g~ write message here"
0000: null-terminator
// ----------------------------------------------------------------------
//          2 Bytes + String
// ---------------------------------------------------------------------- 

0A8E: 0@ = 0xA49964 + @Message // works in main.scm
00D6: if 
0AA9:  is_game_version_original 
then
    0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 0@
else
    0AA5: call 0x5893B0 num_params 4 pop 4 0 0 0 0@
end

:Message
0900: "~g~ write message here"
0000: null-terminator


// ----------------------------------------------------------------------
//        Same way as the second, but using 0662: NOP not 0900:
// ---------------------------------------------------------------------- 

0A9F: 27@ = current_thread_pointer
000A: 27@ += 0x10
0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
000E: 27@ -= @Message
27@ += 4 
00D6: if 
0AA9:  is_game_version_original 
then
    0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 27@ 
else
    0AA5: call 0x5893B0 num_params 4 pop 4 0 0 0 27@
end

:Message
0662: NOP "AAAAAAAAA"
0000: null-terminator





Code:

 alloc($_param1, 76)
 alloc($_asmproc, 77)
 0@ = -429863         
 &0(0@,1i) = 0xA49960
 &0(0@,1i) += @_asminj
 $_asmproc = 0x588BE0
 wait 2000
 $_param1 = 0xA49964
 $_param1 += @_text1
 0572: 1             
 wait 5000
 $_param1 = 0xA49964
 $_param1 += @_text2
 0572: 1             
  wait 3000
 03E6: remove_text_box
 end_thread


 :_asminj
 hex
  FF 35 909AA400                    // push dword ptr [0xA49960+$_param1*4]
  FF 15 949AA400                    // call dword ptr [0xA49960+$_asmproc*4]
  83 C4 04                          // add esp, 4
  C3                                // return
 end
:_text1
 0900: "Welcome :)"

:_text2
0900: "Loading all requested file(s), please wait..."
0000:



Last edited by gtasbigfoot on Tue May 05, 2009 10:00 am; edited 1 time in total

View user profile http://gtamodding.com

5 Re: SA Memory Example Topic on Sat Mar 07, 2009 9:30 am

Very cool Cool And do we have anything do get rid of the motion blur when going fast in a vehicle?

View user profile

6 Re: SA Memory Example Topic on Sat Mar 07, 2009 9:43 am

Alexander wrote:Very cool Cool And do we have anything do get rid of the motion blur when going fast in a vehicle?

Yea, for sure:

Code:

0A8C: write_memory 0x8D5104 size 0x0 value 0x1 virtual_protect 0


With blur:




Without blur:

View user profile http://gtamodding.com

7 Re: SA Memory Example Topic on Sat Mar 07, 2009 9:56 am

No more map fog




Code:

for 0@ = 354164 to 354188
&0(0@,1i) = 16843009
end


Or


Code:

0006: 0@ = 354164

:MAIN_21
0004: &0(0@,1i) = 16843009
000A: 0@ += 1
0019:  0@ > 354188
jf @MAIN_21


Real minute clock




Code:

0A8C: write_memory 0xB7015C size 4 value 0xEA60 virtual_protect 0


Or


Code:

0@ = 301567
&0(0@,1i) = 60000


You can do it via array method as well.

View user profile http://gtamodding.com

8 Re: SA Memory Example Topic on Sat Mar 07, 2009 10:15 am

A very, very cool one now indeed:

Player movement file set




Code:

:Move
0@ = -429863
1@ = 304497 // index of key
while true
    wait 250
    &0(1@,1i) == 0xFF // lo
    jf continue
    &0(0@,1i) = 0xA49960
    &0(0@,1i) += @_SetNCoords
    0572: run_asm_inject true
end // while
:_SetNCoords
hex
 B8 B0 D7 5B 00 FF D0 C3
end


Put this code some where in your main.scm, after create a txt file named "playercoords.txt" in this file put the XYZ coords you want the player to walk to, then save this file in the main dir(same placed where the gtasa.exe, and the DLL files are), you may put commas or space between the X, Y, and Z, now go in the game press F3, and CJ will move to the specified co-ordinates you put in that file.

Here is another one press F4 for this one:


Code:

:Move
0@ = -429863
1@ = 304497 // index of key
while true
    wait 250
    &0(1@,1i) == 0xFF0000 // hi
    jf continue
    &0(0@,1i) = 0xA49960
    &0(0@,1i) += @_SetNCoords
    0572: run_asm_inject true
end // while
:_SetNCoords
hex
 B8 B0 D7 5B 00 FF D0 C3
end


These codes use the allow any key press method, as I described in the first post.

View user profile http://gtamodding.com

9 Re: SA Memory Example Topic on Sat Mar 07, 2009 10:48 pm

Create vehicles with the only opcode




Code:

0AA5: call 0x0043A0B6 num_params 1 pop 1 #INFERNUS


This method is used in R* car spawner they use it for there cheats, and such, like the cheat "jumpjet" which spawns a Hydra military aircraft plane for example.
There is no need to load the vehicle model, or anything do with the co-ordinates, or release or removing reference to the vehicle this all do it all for you, actually.


Freeze



Well, well here's another, this will freeze the game motion, it gets restored 5 game seconds later, perhaps, it's nice to play with:


Code:

0A8D: 1@ = read_memory 0xB610E0 size 4 virtual_protect 0
000A: 1@ += 5000
015D: set_gamespeed 0.0 // 0.3 is good

:Loop
wait 0
0A8D: 0@ = read_memory 0xB610E0 size 4 virtual_protect 0
if
001D: 0@ > 1@ // (int)
jf @Loop
015D: set_gamespeed 1.0


0xB610E0 is timer sort of it does not depend on the speed of the game.
It will also be added during the pause in the minimization



Last edited by gtasbigfoot on Sun Mar 08, 2009 5:44 am; edited 1 time in total

View user profile http://gtamodding.com

10 Re: SA Memory Example Topic on Sun Mar 08, 2009 5:23 am

Playing with Gravity




Code:

0A8D: 0@ = read_memory 0x863984 size 4 virtual_protect 1


Who like to play with gravity? Well, I like do.


This way uses the any key press method, like I described in the first post:


Code:

4@ = 304482
5@ = 304481
0A8D: 0@ = read_memory 0x863984 size 4 virtual_protect 1
0085: 2@ = 0@ // default
gosub @UDGravityStatus

while true
    wait 250               
    if
        &0(4@,1i) == 0xFF // Num -
    then
        3@ = -0.001
    else if
            &0(4@,1i) == 0xFF0000 // Num +
        then
            3@ = 0.001
        else if
                &0(5@,1i) == 0xFF0000 // Num *
            then               
                0A8C: write_memory 0x863984 size 4 value 2@ virtual_protect 1
                0085: 0@ = 2@ // default
                gosub @UDGravityStatus                             
            end
            Continue   
        end   
    end
    0A8D: 0@ = read_memory 0x863984 size 4 virtual_protect 1
    005B: 0@ += 3@ // (float)
    0A8C: write_memory 0x863984 size 4 value 0@ virtual_protect 1             
    gosub @UDGravityStatus
end // "while"

:UDGravityStatus             
0@ *= 100000.0
0092: 0@ = float 0@ to_integer
0513: show_text_box_1number 'BJ_0' number 0@
return


This uses the CLEO opcodes:


Code:


0A8D: 0@ = read_memory 0x863984 size 4 virtual_protect 1
0085: 2@ = 0@ // default
gosub @UDGravityStatus

while true
    wait 250               
    if
        0AB0:  key_pressed 0x6D // NUM -
    then
        3@ = -0.001
    else if
            0AB0:  key_pressed 0x6B // NUM +
        then
            3@ = 0.001
        else if
                0AB0:  key_pressed 0x6A // NUM *
            then               
                0A8C: write_memory 0x863984 size 4 value 2@ virtual_protect 1
                0085: 0@ = 2@ // default
                gosub @UDGravityStatus                               
            end
            Continue   
        end   
    end
    0A8D: 0@ = read_memory 0x863984 size 4 virtual_protect 1
    005B: 0@ += 3@ // (float)
    0A8C: write_memory 0x863984 size 4 value 0@ virtual_protect 1             
    gosub @UDGravityStatus
end // "while"

:UDGravityStatus             
0@ *= 100000.0
0092: 0@ = float 0@ to_integer
0513: show_text_box_1number 'BJ_0' number 0@
return


Enable your NUMPAD on your keyboard, and play around with the gravity.

View user profile http://gtamodding.com

11 Re: SA Memory Example Topic on Sun Mar 08, 2009 9:53 am

BTW, you can post how many times you want in this topic, has no limits, no such thing as double posting, or such.

Radio Station hack for all vehicles



If you want police bike to always play music, do the following:

1: Open the gtasa.exe with a hexadecimal editor(backup the original first in-case you mess up something).
2: Find 4588631 and we there.
3: There will be written 3, replace that with 0.
4: Save, close, go in the game and test.

The ambulance radio is at 4584779


To put a radio in the model of a car you want do the following:

For game version 1.0


Code:

address = 4569803 + # ID mul* 36


And for game version 1.1, this is the address, AFAIK:


Code:

address = 4580075 + # ID mul* 36


To enable the radios for all vehicles here is the code:


Code:

while true
    wait 250
    $PLAYER_CHAR.Defined
    jf continue
    if or
        00E1:  player 0 pressed_key 8
        00E1:  player 0 pressed_key 9     
    then
        0@ = 352231 
        008B: 0@ = &0(0@,1i)
        0@ > 0
        jf continue
        0@ -= 10786701
        0@ /= 4
        &0(0@,1i) = 0
        wait 2500
    end
end   


Here is a longer version, it uses a ASM injector.


Code:

    while true                               
        wait 250           
        if
            $PLAYER_CHAR.Defined
        then
            if or
                00E1:  player 0 pressed_key 8
                00E1:  player 0 pressed_key 9   
            then
                gosub @Enable
                wait 2000
            end
        end
    end 
    end_thread
        :Enable
        alloc($_asmproc, 77)
        alloc($_temp, 78)
        0@ = -429863
        &0(0@,1i) = 0xA49960
        &0(0@,1i) += @_GetActorStruct
        $_asmproc = 0x404910         
        0572: run_asm_inject true        // GetActorstruct
        $_temp -= 10785748
        $_temp /= 4
        0084: $_temp = &0($_temp,1i) // carstruct
        $_temp -= 10786701
        $_temp /= 4                                     
        &0($_temp,1i) = 0
        return
        :_GetActorStruct // $_temp = actor $PLAYER_ACTOR struct^
        hex
            FF 35 6C99A400      // push $PLAYER_ACTOR
            8B 0D 9044B700      // mov ecx, @ActorsPool
            FF 15 949AA400      // call dword ptr [0xA49960+$_asmproc*4]
            A3    989AA400      // mov [$_temp], eax
            C3                  // return
        end





Headlights



So a feature in the games engine makes it possible to obtain full control of the car headlights. Grin Smile

Through this way, you can repair vehicles headlights if they are broken.
So, how do I do this your asking(?) Well, then let us move on to it.


1: Get the players vehicle struct in the games memory:


Code:

03C0: 0@ = actor $PLAYER_ACTOR car
0A97: 1@ = car 0@ struct


For those of you, who like to get the vehicles structure using a different way(via arrays way), you can do it that way.

2: So now get the address of the desired function struct, by adding offsets to the primary address of the engine.


Code:

1@ + = 0x5A0


3: Now it is possible to make headlights. It's done by that address there:


Code:

0x006C2100


And the full code:


Code:

0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 0



The near last, 2 parameters numbers, (not the last digit(0), these ones: pop 0 1), indicates the state of the headlight, 1 means it is broken, and by 1 it indicates that it is not broken.


Last parameter figure means the number of the headlight,
(0 means the front left, 1 means the front right, 3 means the rear lights of the vehicle),

the local varible 1@ is the address of the struct, (and we got that above, remember?) Tounge 2

Varying the numbers of headlights and their state it is possible to obtain the effect of the stroboscopes (we turn off left/right front headlight on the turn) (to check necessary at night, when headlights are switch on)


Code:

while true
    wait 250
    if
        Player.Defined($PLAYER_CHAR)
    then
        if
            Actor.Driving($PLAYER_ACTOR)         
        then
            03C0: 0@ = actor $PLAYER_ACTOR car
            0A97: 1@ = car 0@ struct
            1@ += 0x5A0
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 0 // turned off the front left
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 1 // front right       
            wait 500
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 0 // front left
            0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 1 1 // turned off the front right   
            wait 500         
        end
    end
 end


Of course it is possible to check if the headlight is broken or not. This code checks such thing:


Code:

0AA8: call_function_method 0x6C2130 struct 1@ num_params 1 pop 0 1 0@


The last 2 parameters indicate the number of the headlight (1 means front right),
and the final one is the variable, into which will be the recorded result. So, value 0@ equal to 0 means that the headlight is not broken, and 1 means broken. And finally struct 1@ indicates the same address of the struct.


Code:

while true
    wait 250
    if
        Player.Defined($PLAYER_CHAR)
    then
        if
            Actor.Driving($PLAYER_ACTOR)         
        then
            03C0: 0@ = actor $PLAYER_ACTOR car
            0A97: 1@ = car 0@ struct
            1@ += 0x5A0
            0AA8: call_function_method 0x6C2130 struct 1@ num_params 1 pop 0 1 0@ // state of the headlight
            if
                0@ == 1
            then
                0AA6: call_method 0x006C2100 struct 1@ num_params 2 pop 0 0 1 // front right                         
            end           
        end
    end
 end



Last edited by gtasbigfoot on Tue Jun 30, 2009 9:16 am; edited 2 times in total

View user profile http://gtamodding.com

12 Re: SA Memory Example Topic on Sun Mar 08, 2009 9:57 am

Menu Hack



In San Andreas there is a possibility which allows you to hack the games menu.
Most main menu hacking is done by a tool of some sort, but it's also possible to hack the games menu via script. This script I'm posting here will allow you save in the games menu.




1: Create the menu "SAVEGAME"


Code:

0006: 0@ = -388622
0004: &0(0@,1i) = 0x46050001
000A: 0@ += 1
0004: &0(0@,1i) = 0x535F5445
000A: 0@ += 1
0004: &0(0@,1i) = 0xB000047
000A: 0@ += 1
0004: &0(0@,1i) = 0x10
000A: 0@ += 1
0004: &0(0@,1i) = 0x10000


2: Remove it and make it unavailable, when on a mission with the following:

Code:

0@ = -388622
&0(0@, 1i) = 0x46000001
&0(0@,1i) = 1

for 0@ = -388621 to -388617
&0(0@,1i) = 0
end // for


A script:


Code:

{$CLEO}
0000:           
wait 5500
gosub @CheckVersion

:Save_Menu
wait 0
if and
0256:  player $PLAYER_CHAR defined
//80DF:  not actor $PLAYER_ACTOR driving
0038:  $ONMISSION == 0
jf @Save_Menu3
0006: 0@ = -388622
0004: &0(0@,1i) = 0x46050001
000A: 0@ += 1
0004: &0(0@,1i) = 0x535F5445
000A: 0@ += 1
0004: &0(0@,1i) = 0xB000047
000A: 0@ += 1
0004: &0(0@,1i) = 0x10
000A: 0@ += 1
0004: &0(0@,1i) = 0x10000
jump @Save_Menu2

:Save_Menu3
0@ = -388622
&0(0@, 1i) = 0x46000001
&0(0@,1i) = 1

for 0@ = -388621 to -388617
&0(0@,1i) = 0
end // for

:Save_Menu2
jump @Save_Menu

:CheckVersion
if
  0AA9:    is_game_version_original
jf @Save_Menu4
return

:Save_Menu4
0A93: end_custom_thread


Additionally you may want to change the menu GXT "START NEW GAME", with "GAME" because now it has more options, so if you wanna change it to make it look like game options menu, use the following code to do such thing:



Code:

0@ = -386370
&0(0@,1i) = 0x4C5F4845
0@ += 1
&0(0@,1i) = 0x0B00414F


Place that after the following in the example code above:


Code:

gosub @CheckVersion
//--here--


Like this:


Code:

{$CLEO}
0000:           
wait 5500
gosub @CheckVersion
0@ = -386370
&0(0@,1i) = 0x4C5F4845
0@ += 1
&0(0@,1i) = 0x0B00414F 

:Save_Menu
wait 0
if and               
0256:  player $PLAYER_CHAR defined
//80DF:  not actor $PLAYER_ACTOR driving
0038:  $ONMISSION == 0
jf @Save_Menu3
0006: 0@ = -388622
0004: &0(0@,1i) = 0x46050001
000A: 0@ += 1
0004: &0(0@,1i) = 0x535F5445
000A: 0@ += 1
0004: &0(0@,1i) = 0xB000047
000A: 0@ += 1
0004: &0(0@,1i) = 0x10
000A: 0@ += 1
0004: &0(0@,1i) = 0x10000
jump @Save_Menu2

:Save_Menu3
0@ = -388622
&0(0@, 1i) = 0x46000001
&0(0@,1i) = 1

for 0@ = -388621 to -388617
&0(0@,1i) = 0
end // for

:Save_Menu2
jump @Save_Menu

:CheckVersion
if
  0AA9:    is_game_version_original
jf @Save_Menu4
return

:Save_Menu4
0A93: end_custom_thread


I've used the @CheckVersion as a sub-routine in both scripts, you can change that if you want it do it normally.


Attention! This works with game version 1.0

View user profile http://gtamodding.com

13 Re: SA Memory Example Topic on Tue Mar 10, 2009 1:17 am

Cool, why did you name yourself "gtasbigfoot"? I think it should be changed to "Coding-God" Don't ya think? Wink

View user profile

14 Re: SA Memory Example Topic on Tue Mar 10, 2009 1:31 am

Alexander wrote:Cool, why did you name yourself "gtasbigfoot"? I think it should be changed to "Coding-God" Don't ya think? Wink


Braggin No.

View user profile http://gtamodding.com

15 Re: SA Memory Example Topic on Thu Mar 12, 2009 2:37 am

I keep getting asked by people "How do I change train length?" and such thing, well, let me explain this today, and of course there is more then one way to do such thing.

There are 16 types of trains in SA, here is the list of them:


Code:

Train    Carriage1  Carriage2  Carriage3  Carriage4  Carriage5
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~           
0:          #FREIGHT  #FREIFLAT  #FREIFLAT  #FREIFLAT  #FREIFLAT    x
1,2,4,7,11: #STREAK  #STREAKC  #STREAKC      x        x          x
3:          #FREIGHT  #FREIFLAT  #FREIFLAT  #FREIFLAT    x          x
5:          #STREAK  #STREAKC  #STREAKC  #STREAKC      x          x
6:          #FREIGHT  #FREIFLAT  #FREIFLAT      x        x          x
8:          #TRAM    #TRAM          x          x        x          x
9,14:      #TRAM        x          x          x        x          x
10:        #FREIGHT  #FREIFLAT      x          x        x          x
12:        #FREIGHT  #FREIFLAT  #FREIFLAT  #FREIFLAT  #FREIGHT      x
13:        #FREIGHT  #FREIFLAT  #FREIFLAT  #FREIFLAT  #FREIFLAT #FREIFLAT
15:        #STREAK      x          x          x        x          x


San Andreas train type starts at 0x8D44F8 which is type 0.
These are addresses of the train types:


Code:

0x8D44F8 type 0
0x8D4538 type 1
0x8D4578 type 2
0x8D45B8 type 3
0x8D45F8 type 4
0x8D4638 type 5
0x8D4678 type 6
0x8D46B8 type 7
0x8D46F8 type 8
0x8D4738 type 9
0x8D4778 type 10
0x8D47B8 type 11
0x8D47F8 type 12
0x8D4838 type 13
0x8D4878 type 14
0x8D48B8 type 15


The game reads these numbers until it finds 0.
Using them addresses it's not so hard to change them trains, I am sure that
18(0x12) more carriages is the max limit, I do not recommend more then this, as it's over doing the EXE's limit. These memory addresses are of Data type, so because of that they can be changed directly in the game.


Code:

Each block contains:
+0 [DWord] = train model
+4 to +3C [All DWords] = carriage model



Code:

for 0@ = -382229 to -382216
  wait 0
  &0(0@,1i) = #STREAKC       
 end


In this we have added 14 more #STREAKC carriages to the train type 0(who wants to kill there self standing in front of it? Braggin),

here is a script which should help you more with this method, you can type test like a cheat to test it...


Code:

{$CLEO}
0000:

// type "test"
:Trains_01
wait 0
2@ = -229908
if
&0(2@,1i) == 0x54455354 
jf @Trains_01
&0(2@,1i) = 0x54455300
03E5: show_text_box 'CHEAT1'  // Cheat activated
0169: set_fade_color_RGB 0 0 0
fade 0 time 500

while true
if
    not fading
then
      break
    end
    wait 0
end
      // type 0 has been changed! ADDED 14 more now carriages to the train
for 0@ = -382229 to -382216
  wait 0
  &0(0@,1i) = #STREAKC       
 end

  #FREIGHT.Load
  #FREIFLAT.Load
  #STREAKC.Load

  while true
    if and
      Model.Available(#FREIGHT)
      Model.Available(#FREIFLAT)
      Model.Available(#STREAKC) 
    then
      break
    end
    wait 0
  end
 
  Actor.PutAt($PLAYER_ACTOR, 2270.1771, -1144.8823, 27.5108)
  03CB: set_rendering_origin_at 2270.1771 -1144.8823 27.5108
  04E4: unknown_refresh_game_renderer_at 2270.1771 -1144.8823
  wait 1300
  fade 1 time 1500
 
  while true
if
    fading  // if not fading then continue...
then
      break
    end
    wait 0
end
 
  06D8: 1@ = create_train_at 2278.1771 -1144.8823 27.5108 type 0 direction 1
  0395: clear_area 1 at 2270.1771 -1144.8823 27.5108 radius 1.0   
Model.Destroy(#FREIGHT)
Model.Destroy(#FREIFLAT)
Model.Destroy(#STREAKC) 
0A93: end_custom_thread





Test the script, enjoy the mad-ness. Wink
P.S. The train has 18 carriages, because I added 14, and the original train has 4 already, (do not place more carriages).

Well now, the way above may be a little bit difficult to understand, you can also change the train using the CLEO opcodes, or using the arrays method.

If you wanna do it using the CLEO opcodes do the following:

So if you wanted 15 carriages then you would do this:

Take an address of train type (listed above). (Let use use type 0 for example), it will be the address of the locomotive.
Write to this address which model you want for it. Next 15 dwords (4 bytes each) will be carriages models.
So, write to the 0x8D44F8+4, 0x8D44F8+8, 0x8D44F8+12, 0x8D44F8+16, 0x8D44F8+20, 0x8D44F8+24, 0x8D44F8+28, 0x8D44F8+32, 0x8D44F8+36, 0x8D44F8+40, 0x8D44F8+44, 0x8D44F8+48, 0x8D44F8+52, 0x8D44F8+56, 0x8D44F8+60, 0x8D44F8+64 addresses models ID for carriages.
Then write zero to the next address ( 0x8D44F8+68 ). So, when you create a train of type 0,
the game will read these addresses until it will find zero, and you will get a train with 15 carriages.

So look here is an example, this has 15:


Code:

{$CLEO}
0000:

// type "test"
:Trains_01
wait 0
0@ = -229908
if
&0(0@,1i) == 0x54455354 
jf @Trains_01
&0(0@,1i) = 0x54455300
03E5: show_text_box 'CHEAT1'  // Cheat activated
0169: set_fade_color_RGB 0 0 0
fade 0 time 500

while true
if
    not fading
then
      break
    end
    wait 0
end
     
0006: 1@ = 569
0006: 2@ = 537
0006: 3@ = 0x8D44F8
0A8C: write_memory 3@ size 4 value 2@ virtual_protect 0
3@ += 4                                           
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4
0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0
3@ += 4 
0A8C: write_memory 3@ size 4 value 0x00000000 virtual_protect 0

#FREIGHT.Load
  #FREIFLAT.Load
  #STREAKC.Load

  while true
    if and
      Model.Available(#FREIGHT)
      Model.Available(#FREIFLAT)
      Model.Available(#STREAKC)
    then
      break
    end
    wait 0
  end
 
  Actor.PutAt($PLAYER_ACTOR, 2270.1771, -1144.8823, 27.5108)
  03CB: set_rendering_origin_at 2270.1771 -1144.8823 27.5108
  04E4: unknown_refresh_game_renderer_at 2270.1771 -1144.8823
  wait 1300
  fade 1 time 1500
 
  while true
if
    fading  // if not fading then continue...
then
      break
    end
    wait 0
end
 
  06D8: 1@ = create_train_at 2278.1771 -1144.8823 27.5108 type 0 direction 1
  0395: clear_area 1 at 2270.1771 -1144.8823 27.5108 radius 1.0 
Model.Destroy(#FREIGHT)
Model.Destroy(#FREIFLAT)
Model.Destroy(#STREAKC)
0A93: end_custom_thread


Code dump EXE with a list of all types of trains:


Code:

. data: 008D44F8 TrainTypesModelPool dd 537; 0
. data: 008D44FC dd 569
. data: 008D4500 dd 569
. data: 008D4504 dd 569
. data: 008D4508 dd 569
. data: 008D450C dd 0
. data: 008D4510 dd 0
. data: 008D4514 dd 0
. data: 008D4518 dd 0
. data: 008D451C dd 0
. data: 008D4520 dd 0
. data: 008D4524 dd 0
. data: 008D4528 dd 0
. data: 008D452C dd 0
. data: 008D4530 dd 0
. data: 008D4534 dd 0
. data: 008D4538 dd 538, 1
. data: 008D453C dd 570
. data: 008D4540 dd 570
. data: 008D4544 dd 0
. data: 008D4548 dd 0
. data: 008D454C dd 0
. data: 008D4550 dd 0
. data: 008D4554 dd 0
. data: 008D4558 dd 0
. data: 008D455C dd 0
. data: 008D4560 dd 0
. data: 008D4564 dd 0
. data: 008D4568 dd 0
. data: 008D456C dd 0
. data: 008D4570 dd 0
. data: 008D4574 dd 0
. data: 008D4578 dd 538; 2
. data: 008D457C dd 570
. data: 008D4580 dd 570
. data: 008D4584 dd 0
. data: 008D4588 dd 0
. data: 008D458C dd 0
. data: 008D4590 dd 0
. data: 008D4594 dd 0
. data: 008D4598 dd 0
. data: 008D459C dd 0
. data: 008D45A0 dd 0
. data: 008D45A4 dd 0
. data: 008D45A8 dd 0
. data: 008D45AC dd 0
. data: 008D45B0 dd 0
. data: 008D45B4 dd 0
. data: 008D45B8 dd 537; 3
. data: 008D45BC dd 569
. data: 008D45C0 dd 569
. data: 008D45C4 dd 569
. data: 008D45C8 dd 0
. data: 008D45CC dd 0
. data: 008D45D0 dd 0
. data: 008D45D4 dd 0
. data: 008D45D8 dd 0
. data: 008D45DC dd 0
. data: 008D45E0 dd 0
. data: 008D45E4 dd 0
. data: 008D45E8 dd 0
. data: 008D45EC dd 0
. data: 008D45F0 dd 0
. data: 008D45F4 dd 0
. data: 008D45F8 dd 538; 4
. data: 008D45FC dd 570
. data: 008D4600 dd 570
. data: 008D4604 dd 0
. data: 008D4608 dd 0
. data: 008D460C dd 0
. data: 008D4610 dd 0
. data: 008D4614 dd 0
. data: 008D4618 dd 0
. data: 008D461C dd 0
. data: 008D4620 dd 0
. data: 008D4624 dd 0
. data: 008D4628 dd 0
. data: 008D462C dd 0
. data: 008D4630 dd 0
. data: 008D4634 dd 0
. data: 008D4638 dd 538; 5
. data: 008D463C dd 570
. data: 008D4640 dd 570
. data: 008D4644 dd 570
. data: 008D4648 dd 0
. data: 008D464C dd 0
. data: 008D4650 dd 0
. data: 008D4654 dd 0
. data: 008D4658 dd 0
. data: 008D465C dd 0
. data: 008D4660 dd 0
. data: 008D4664 dd 0
. data: 008D4668 dd 0
. data: 008D466C dd 0
. data: 008D4670 dd 0
. data: 008D4674 dd 0
. data: 008D4678 dd 537; 6
. data: 008D467C dd 569
. data: 008D4680 dd 569
. data: 008D4684 dd 0
. data: 008D4688 dd 0
. data: 008D468C dd 0
. data: 008D4690 dd 0
. data: 008D4694 dd 0
. data: 008D4698 dd 0
. data: 008D469C dd 0
. data: 008D46A0 dd 0
. data: 008D46A4 dd 0
. data: 008D46A8 dd 0
. data: 008D46AC dd 0
. data: 008D46B0 dd 0
. data: 008D46B4 dd 0
. data: 008D46B8 dd 538; 7
. data: 008D46BC dd 570
. data: 008D46C0 dd 570
. data: 008D46C4 dd 0
. data: 008D46C8 dd 0
. data: 008D46CC dd 0
. data: 008D46D0 dd 0
. data: 008D46D4 dd 0
. data: 008D46D8 dd 0
. data: 008D46DC dd 0
. data: 008D46E0 dd 0
. data: 008D46E4 dd 0
. data: 008D46E8 dd 0
. data: 008D46EC dd 0
. data: 008D46F0 dd 0
. data: 008D46F4 dd 0
. data: 008D46F8 dd 449, 8
. data: 008D46FC dd 449
. data: 008D4700 dd 0
. data: 008D4704 dd 0
. data: 008D4708 dd 0
. data: 008D470C dd 0
. data: 008D4710 dd 0
. data: 008D4714 dd 0
. data: 008D4718 dd 0
. data: 008D471C dd 0
. data: 008D4720 dd 0
. data: 008D4724 dd 0
. data: 008D4728 dd 0
. data: 008D472C dd 0
. data: 008D4730 dd 0
. data: 008D4734 dd 0
. data: 008D4738 dd 449; 9
. data: 008D473C dd 0
. data: 008D4740 dd 0
. data: 008D4744 dd 0
. data: 008D4748 dd 0
. data: 008D474C dd 0
. data: 008D4750 dd 0
. data: 008D4754 dd 0
. data: 008D4758 dd 0
. data: 008D475C dd 0
. data: 008D4760 dd 0
. data: 008D4764 dd 0
. data: 008D4768 dd 0
. data: 008D476C dd 0
. data: 008D4770 dd 0
. data: 008D4774 dd 0
. data: 008D4778 dd 537, 10
. data: 008D477C dd 569
. data: 008D4780 dd 0
. data: 008D4784 dd 0
. data: 008D4788 dd 0
. data: 008D478C dd 0
. data: 008D4790 dd 0
. data: 008D4794 dd 0
. data: 008D4798 dd 0
. data: 008D479C dd 0
. data: 008D47A0 dd 0
. data: 008D47A4 dd 0
. data: 008D47A8 dd 0
. data: 008D47AC dd 0
. data: 008D47B0 dd 0
. data: 008D47B4 dd 0
. data: 008D47B8 dd 538, 11
. data: 008D47BC dd 570
. data: 008D47C0 dd 570
. data: 008D47C4 dd 0
. data: 008D47C8 dd 0
. data: 008D47CC dd 0
. data: 008D47D0 dd 0
. data: 008D47D4 dd 0
. data: 008D47D8 dd 0
. data: 008D47DC dd 0
. data: 008D47E0 dd 0
. data: 008D47E4 dd 0
. data: 008D47E8 dd 0
. data: 008D47EC dd 0
. data: 008D47F0 dd 0
. data: 008D47F4 dd 0
. data: 008D47F8 dd 537, 12
. data: 008D47FC dd 569
. data: 008D4800 dd 569
. data: 008D4804 dd 569
. data: 008D4808 dd 537
. data: 008D480C dd 0
. data: 008D4810 dd 0
. data: 008D4814 dd 0
. data: 008D4818 dd 0
. data: 008D481C dd 0
. data: 008D4820 dd 0
. data: 008D4824 dd 0
. data: 008D4828 dd 0
. data: 008D482C dd 0
. data: 008D4830 dd 0
. data: 008D4834 dd 0
. data: 008D4838 dd 537, 13
. data: 008D483C dd 569
. data: 008D4840 dd 569
. data: 008D4844 dd 569
. data: 008D4848 dd 569
. data: 008D484C dd 569
. data: 008D4850 dd 0
. data: 008D4854 dd 0
. data: 008D4858 dd 0
. data: 008D485C dd 0
. data: 008D4860 dd 0
. data: 008D4864 dd 0
. data: 008D4868 dd 0
. data: 008D486C dd 0
. data: 008D4870 dd 0
. data: 008D4874 dd 0
. data: 008D4878 dd 449, 14
. data: 008D487C dd 0
. data: 008D4880 dd 0
. data: 008D4884 dd 0
. data: 008D4888 dd 0
. data: 008D488C dd 0
. data: 008D4890 dd 0
. data: 008D4894 dd 0
. data: 008D4898 dd 0
. data: 008D489C dd 0
. data: 008D48A0 dd 0
. data: 008D48A4 dd 0
. data: 008D48A8 dd 0
. data: 008D48AC dd 0
. data: 008D48B0 dd 0
. data: 008D48B4 dd 0
. data: 008D48B8 dd 538, 15
. data: 008D48BC dd 0
. data: 008D48C0 dd 0
. data: 008D48C4 dd 0
. data: 008D48C8 dd 0
. data: 008D48CC dd 0
. data: 008D48D0 dd 0
. data: 008D48D4 dd 0
. data: 008D48D8 dd 0
. data: 008D48DC dd 0
. data: 008D48E0 dd 0
. data: 008D48E4 dd 0
. data: 008D48E8 dd 0
. data: 008D48EC dd 0
. data: 008D48F0 dd 0
. data: 008D48F4 dd 0


If there is any question, feel free to ask them, let me remind you that the more you place carriages on the train, the more the speed of the train is restricted, I have placed examples above on testing the trains with carriages.

Note; that yes the model of the train and carriage, you need to load it then you can spawn it with this opcode for testing your long train:


Code:

06D8: 1@ = create_train_at 0.0 0.0 0.0 type 0 direction 1 

View user profile http://gtamodding.com

16 Checking SA's version via main.scm on Sun Mar 15, 2009 10:55 am

Strictly speaking, there is a difference even between the game versions, as such memory addresses are different. So here is opcode to check what version your EXE is, you may use this code to check what version of the game your using. Get the index (-429566), if the number is recorded equal to 4611680
then the game version is v1, else it is 1.01.
This is equal to the CLEO opcode 0AA9, though it can be used with or without CLEO 3 installed.


Code:

0@ = -429566 // 0xFFF97202
if
 &0(0@,1i) == 4611680 // 0x465E60
then           

 // game is version 1.0

else

 // game is version 1.01

end



Example using that:


Code:

0@ = -429566 // 0xFFF97202
if
 &0(0@,1i) == 4611680 // 0x465E60
then 
  gosub @GetMethodforv1 // <gosub to sub method> v1
else
  gosub @GetMethodforv1.1 // <gosub to sub method> v1.01
end
end_thread


:GetMethodforv1
//............................
jump @Continue

:GetMethodforv1.1
//............................

:Continue
return // -- as all gosubs return



Though, some of you may do it the following way:



Code:

if
  0AA9:    is_game_version_original
then
  gosub @GetMethodforv1 // <gosub to sub method> v1
else
  gosub @GetMethodforv1.1 // <gosub to sub method> v1.01
end
end_thread

:GetMethodforv1
//............................
jump @Continue

:GetMethodforv1.1
//............................

:Continue
return // -- as all gosubs return

View user profile http://gtamodding.com

17 Re: SA Memory Example Topic on Fri Mar 20, 2009 4:13 am

Set box color RGBA:


Code:

0@ = 73384
&0(0@,1i) = 0x7FCAFFFF


This works the same way as the codes I posted in the "Changing hard coded interface colors" topic, (7F) A (CA), B (FF), G (FF), R, the Alpha digit goes first, then Blue value, Green value, and then the Red value.(+ 17 next box).

--

I will do soon a main.scm with examples got to do Readme in English language = all in Russian language at the moment.
--

I think if you set the 00B6EC2E to 0, I think you get the same effect with game-pad, and the aiming icon as it was on PS2. Though you know you can just go to the menu and select "Joypad Mode", but some may like to do it this way, if you change it, in the menu the settings will still be set to "Keyboard and Mouse" as it goes not put it on "Joypad Mode". Player target point is at 006859A0, for peds 0060B650, the RGBA from the peds health at 0060BA80, the target icon is stored at the following:


Code:

.text:0060BFCC 064                    mov ds:dword_C4D970, esi



Code:

0A8C: write_memory 0x00B6EC2E size 4 value 0 virtual_protect 0


I got asked by some one how to disable the menu, when the player(you, not CJ) pressed ESC, set 00B5F852 to 1 to disable it.


Code:
 
0A8C: write_memory 0x00B5F852 size 4 value 1 virtual_protect 0


Note: because it's disabled, if you exit out of the game using Windows key,
when you turn the game back on, you will not be in the menu, the game is resumed right-away.

When you disabled it the HUD disappears, to not make such thing happen write to 00BA6831 = 1


Code:
 
0A8C: write_memory 0x00BA6831 size 4 value 1 virtual_protect 0

View user profile http://gtamodding.com

18 Re: SA Memory Example Topic on Sun Mar 22, 2009 3:19 am

Show the chaos:


Code:

:MAIN_PART
0001: wait 400 ms
0006: 0@ = 314639
008B: 0@ = &0(0@,1i) // (int)
000E: 0@ -= 10787168
0016: 0@ /= 4
008B: 0@ = &0(0@,1i) // (int)
0004: $77 = 0
008A: $77 = 0@ // (int)
0084: $78 = $77 // (int)
000C: $78 -= 50
00D6: if
8018:  not $78  > 0
004D: jump_if_false @MAIN_PART2
0004: $78 = 0

:MAIN_PART2
0010: $78 *= 1000
0002: jump @MAIN_PART


Address 314639 = &0(0@,1i) - 10787168(SCM start) div 4, = &0(0@,1i) status text varible set to 0, $77 = 0@ data, $78(timer) = $77(status_text) $78 - 50
$78 = 0 go to @MAIN_PART2 $78 * 1000, NOT $78 = 0, set $78 to 0 go to MAIN_PART2


Code:

04F7: status_text $77 type 0 line 1 GXT 'FES_CRI' // global_variable  // CRIMES
054C: use_GXT_table 'COPCAR'
03C3: set_timer_to $78 type 0 GXT 'COPTIME' // global_variable  // TIME LEFT


There will appear two status's on the screen, the first tells you how long you got until your wanted star disappears, the second the amount of high-ess of crime you caused.





Put this code with the other create_thread commands in the main.scm:


Code:

004F: create_thread @CRIME_O_METER



Add the following code before the mission 0 in the main.scm:


Code:

:CRIME_O_METER
04F7: status_text $77 type 0 line 1 GXT 'FES_CRI' // global_variable  // CRIMES
054C: use_GXT_table 'COPCAR'
03C3: set_timer_to $78 type 0 GXT 'COPTIME' // global_variable  // TIME LEFT
   
:MAIN_PART
0001: wait 500 ms
0006: 0@ = 314639
008B: 0@ = &0(0@,1i) // (int)
000E: 0@ -= 10787168
0016: 0@ /= 4
008B: 0@ = &0(0@,1i) // (int)
0004: $77 = 0
008A: $77 = 0@ // (int)
0084: $78 = $77 // (int)
000C: $78 -= 50
00D6: if
8018:  not $78  > 0
004D: jump_if_false @MAIN_PART2
0004: $78 = 0

:MAIN_PART2
0010: $78 *= 1000
0002: jump @MAIN_PART


Well, well, here is the cheat version if you wanna use this one type "crimes" like a cheat code:



Code:

:CRIME_O_METER
while true
wait 0
0006: 30@ = -229907
008B: 30@ = &0(30@,1i) // (int)
0085: 31@ = 30@ // (int)
0016: 31@ /= 65536
0012: 31@ *= 65536
0062: 30@ -= 31@ // (int)
if
    0039:  30@ == 0x4352 // cr
then
    0006: 30@ = -229908
    if
      0038:  &0(30@,1i) == 0x494D4553 // imes
      then
          break
        end
    end           
end  // while

0004: &0(30@,1i) = 0x494D4500
03E5: show_text_box 'CHEAT1'  // Cheat activated

04F7: status_text $77 type 0 line 1 GXT 'FES_CRI' // global_variable  // CRIMES
054C: use_GXT_table 'COPCAR'
03C3: set_timer_to $78 type 0 GXT 'COPTIME' // global_variable  // TIME LEFT
   
:MAIN_PART
wait 0
0006: 30@ = -229907
008B: 30@ = &0(30@,1i) // (int)
0085: 31@ = 30@ // (int)
0016: 31@ /= 65536
0012: 31@ *= 65536
0062: 30@ -= 31@ // (int)
if
    0039:  30@ == 0x4352 // cr
then
    0006: 30@ = -229908
    if
      0038:  &0(30@,1i) == 0x494D4553 // imes
      then
        0004: &0(30@,1i) = 0x45415400
        03E5: show_text_box 'CHEAT8'  // Cheat deactivated
        0151: remove_status_text $77
        014F: stop_timer $78
        00BE: text_clear_all
          jump @CRIME_O_METER 
    end
end


:MAIN_PART1
wait 400
0006: 0@ = 314639
008B: 0@ = &0(0@,1i) // (int)
000E: 0@ -= 10787168
0016: 0@ /= 4
008B: 0@ = &0(0@,1i) // (int)
0004: $77 = 0
008A: $77 = 0@ // (int)
0084: $78 = $77 // (int)
000C: $78 -= 50
if
  8018:  not $78  > 0
then
    0004: $78 = 0
end

:MAIN_PART2
0010: $78 *= 1000
jump @MAIN_PART



Peace, ya Wink

View user profile http://gtamodding.com

19 Re: SA Memory Example Topic on Mon Mar 23, 2009 2:09 am

Well, here is a v1.1 version of the cop viewer I posted above, needs to change 10787168 with 10797024 (0xA49960 with 0xA4BFE0) since, the SCM start for v1.1 is 10797024.


Code:

:CRIME_O_METER
04F7: status_text $77 type 0 line 1 GXT 'FES_CRI' // global_variable  // CRIMES
054C: use_GXT_table 'COPCAR'
03C3: set_timer_to $78 type 0 GXT 'COPTIME' // global_variable  // TIME LEFT
 
:MAIN_PART
0001: wait 500 ms
0006: 0@ = 314639
008B: 0@ = &0(0@,1i) // (int)
000E: 0@ -= 10797024
0016: 0@ /= 4
008B: 0@ = &0(0@,1i) // (int)
0004: $77 = 0
008A: $77 = 0@ // (int)
0084: $78 = $77 // (int)
000C: $78 -= 50
00D6: if
8018:  not $78  > 0
004D: jump_if_false @MAIN_PART2
0004: $78 = 0

:MAIN_PART2
0010: $78 *= 1000
0002: jump @MAIN_PART


If the HUD positions is modified, like for example like mine, then you may wanna adjust screen width, or height - 472505(0x735B9) is the width, 472506( 0x735BA) is the height.

Multi version works with both v1 and v1.1:


Code:

:CRIME_O_METER
0@ = -429566// check version
if
 &0(0@,1i) == 4611680 // is version 1.0
then
  1@ = 10787168 // v1
else
  1@ = 10797024 // v1.1
end

04F7: status_text $77 type 0 line 1 GXT 'FES_CRI' // global_variable  // CRIMES
054C: use_GXT_table 'COPCAR'
03C3: set_timer_to $78 type 0 GXT 'COPTIME' // global_variable  // TIME LEFT
 
:MAIN_PART
0001: wait 500 ms
0006: 0@ = 314639
008B: 0@ = &0(0@,1i) // (int)
0062: 0@ -= 1@ // SCM start
0016: 0@ /= 4
008B: 0@ = &0(0@,1i) // (int)
0004: $77 = 0
008A: $77 = 0@ // (int)
0084: $78 = $77 // (int)
000C: $78 -= 50
00D6: if
8018:  not $78  > 0
004D: jump_if_false @MAIN_PART2
0004: $78 = 0

:MAIN_PART2
0010: $78 *= 1000
0002: jump @MAIN_PART

View user profile http://gtamodding.com

20 Explantion of ASM codes on Tue Apr 07, 2009 12:07 am

How ASM codes work



More on ASM injectors, we have 2 opcodes in San Andreas (0572, and 0A3D) the first enables the taxi nitro, and the second makes the prostitutes pay you - it does not matter which is used - I mostly use the first one anyway.
But these opcodes also enable one of the games 92 flags and game begins to think that you use a cheat, though without affecting the cheats history, only implying what the cheat does. In San Andreas we have 92 cheats, 0A3D referring to the cheat #90, 0572 - cheat #91. All the cheats routines addresses are stored as simple Dword values and they can easily even be changed in game run-time. The code changes 91st cheat routine address with a value INSIDE the main.scm. Then we run this cheat and game goes to the address we set, (e.g. it goes inside the main.scm and begins work with the code as with an assembler). We use hex..end in Sanny Builder to execute ANY code we want.


We first set the 0572(I like that one best) address to the ASM inject postion(for game version 1.0):


Code:

0@ = -429863         
&0(0@,1i) = 0xA49960
&0(0@,1i) += @_Inject1


For game version v1.1:


Code:

0@ = -431117
&0(0@,1i) = 0xA4BFE0
&0(0@,1i) += @_Inject2



We can run our ASM inject with this when we are ready:


Code:

0572: run_asm_inject true


Diffrences between v1 & and v1.1:


  • The SCM base address which is necessary for the variables position in the arrays and function parameters.

  • 0572 proc address - We changed this to run the ASM code.

  • Proc - the function we call




Code:

            v1.0      v1.1
--------------------------------       
SCM        0xA49960  0xA4BFE0
0572 Addr  -429863    -431117 




Example codes



Here are some examples(game version v1):

Goes with the others(create_thread commands in main.scm):


Code:

004F: create_thread @ASM


This goes before mission 0, it adds some money to the player.


Code:

:ASM
while true
wait 250
if
    Player.Defined($PLAYER_CHAR)
then
    if
        00E1:  player 0 pressed_key 11 // -- yes
    then
          break
          end
    end
end // while

gosub @ASM_Code
end_thread


:ASM_Code
0@ = -429863
&0(0@,1i) = 0xA49960
&0(0@,1i) += @Injection
0572: run_asm_inject true
&0(0@,1i) = 0 //  restore handler
return

:Injection
hex
B8 E8030000    // mov eax, 1000
01 05 50CEB700  // add [0xB7CE50], eax
C3              // return
end



Print IPL zone:

Goes with the others(create_thread commands in main.scm):


Code:

004F: create_thread @Print


This goes before mission 0, it prints the IPL zone.


Code:

:Print
alloc($_asmproc, 76)
alloc($_param1, 77)

//----------------------------------------
// ASM inject postion
//----------------------------------------
 
 0@ = -429863         
 &0(0@,1i) = 0xA49960
 &0(0@,1i) += @_asminj
 
//----------------------------------------
// Input addresses
//---------------------------------------- 
 
 $_asmproc = 0x588BE0
 $_param1 = 0xA49A98

//----------------------------------------
// Print Zone
//----------------------------------------

 alloc($_zone, 78)
 while true
  00A0: store_actor $PLAYER_ACTOR position_to 0@ 1@ 2@
  0843: get_zone_at 0@ 1@ 2@ nameA_to s$_zone // 8-byte string
  0572: run_asm_injection true
  wait 250
 end

end_thread

 :_asminj
 hex
  FF 35 949AA400                    // push dword ptr [0xA49960+$_param1*4]
  FF 15 909AA400                    // call dword ptr [0xA49960+$_asmproc*4]
  83 C4 04                          // add esp, 4
  C3                                // return
 end


Well, here is also an example:

http://sannybuilder.com/files/cheater.rar



Some random tricks




Remove clock:


Code:

0@ = 361128
&0(0@,1i) = 0


Clear last mission name record:


Code:

0@ = 310312
&0(0@,1i) = 0


Disable Traffic:


Code:

0@ = -228223
&0(0@,1i) = 1



Disable cheat codes:

The first cheat index is -429954
the next would be -429953, and so on
set it to 0 to disable that cheat.
The ID reader can be found through testing modes.


Code:

0@ = -429954
&0(0@,1i) = 0


More motion blur stuff, you can increase it or vice versa:


Code:

0@ = -381463
&0(0@,1i) = 100


Other things to do with the motion blur where posted before:


Code:

0x8D5104 - main (1 byte).
0x8D5190 - Blur stage 1
0x8D51A0 - Blur stage 2
0x8D51B0 - Blur stage 3
0x8D51C0 - Blur stage 4
0x8D51D0 - Blur stage 5
0x8D51E0 - Blur stage 6



Replace the fog lifter with native memory writing:


Code:

for 0@ = 0x00BA3730 to 0x00BA3793 step 4
0A8C: write_memory 0@ size 4 value 1 virtual_protect 0
end



You can create a garage via a CLEO script, using the same format as the IPL uses:



Code:

{$CLEO}

0A9F: 0@ = current_thread_pointer
0@ += 0x10
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0@ -= @GRGE
0@ += 4
0AA5: call 0x5B4530 num_params 1 pop 1 0@
0A93: end_custom_thread

:GRGE
0900: "2640.78 -2049.99 12.543 2648.96 -2049.99 2640.78 -2039.55 16.206 1 1 modlast"
0000:


--

Delphi


Here is the Delphi code for the "enable all radio stations".
The code is pretty simple to understand - for "integer" 0 to 211(all the vehicles in game), then follows by the command "do" Address "0x00860B0B" + the "integer" multiply by 36. Simple uhh? If not then you problay have never used Delphi before, - but even if you have not it's still quite simple to understand.

The code:


Code:

for i := 0 to 211 do
      PByte($00860B0B + i * 36)^ := 0;


----
If anyone is also able to understand well about memory handling, maybe you would like to post something? We post whatever we feel like basically.



Last edited by gtasbigfoot on Wed Jun 10, 2009 8:58 am; edited 5 times in total

View user profile http://gtamodding.com

21 Re: SA Memory Example Topic on Fri Apr 10, 2009 11:00 am

As posted ages ago(on the first page) - a script to show text over the memory, but without using CLEO opcodes, it uses ASM injectors, so you can use it in the main.scm, without CLEO installed. Here is a multi version works with both v1, and v1.1 San Andreas:



Code:

thread 'asmtext'
alloc($_param1, 76) // $_param1 = $76
alloc($_asmproc, 77) // $_asmproc = $77
0@ = -429566 // check version
    if
      &0(0@,1i) == 4611680  // differ address
then
      0@ = -429863 // set 0572 to inject pos       
      &0(0@,1i) = 0xA49960
      &0(0@,1i) += @_asminj
     
      $_asmproc = 0x588BE0  // ASM proc(black box)
     
      wait 2000 // SCM + 4 bytes + text offset + ASM run
      $_param1 = 0xA49964
      $_param1 += @_text1
      0572: run_asm_inject true  // run ASM inject         
      wait 5000
      $_param1 = 0xA49964
      $_param1 += @_text2
      0572: run_asm_inject true           
      wait 5000
      $_param1 = 0xA49964
      $_param1 += @_text3
      0572: run_asm_inject true           
      wait 3100
      03E6: remove_text_box // clear text
else  // version v1.1
      0@ = -431117  // set 0572 to inject pos v1.1
      &0(0@,1i) =  0xA4BFE0
      &0(0@,1i) += @_asminj2
     
      $_asmproc = 0x5893B0 // ASM proc(black box) v1.1
     
      wait 2000  // SCM + 4 bytes + text offset + ASM run v1.1
      $_param1 = 0xA4BFE4
      $_param1 += @_text1
      0572: run_asm_inject true  // run ASM inject v1.1         
      wait 5000
      $_param1 = 0xA4BFE4
      $_param1 += @_text2
      0572: run_asm_inject true           
      wait 5000
      $_param1 = 0xA4BFE4
      $_param1 += @_text3
      0572: run_asm_inject true           
      wait 3100
      03E6: remove_text_box  // clear text
end
end_thread  // all showed, end thread

// ASM injectors
// v1
:_asminj
hex
 FF 35 909AA400                    // push dword ptr
 FF 15 949AA400                    // call dword ptr
 83 C4 04                          // add esp, 4
 C3                                // return
end

// v1.1
:_asminj2
hex
 FF 35 10C1A400                    // push dword ptr
 FF 15 14C1A400                    // call dword ptr
 83 C4 04                          // add esp, 4
 C3                                // return
end

 :_text1
 0900: "Testing... script loaded successful!"
 :_text2
 0900: "well, you know that it works now..."
 :_text3
 0900: "Get back to whatever your doing :)"
 0000: // so "hex" does not get displayed at end of third message



Note; in your Sanny Builder Options > Formats > Case converting, turn on the option "As is" otherwise your message will be displayed in CAPITAL(UPPERCASE) letters.

View user profile http://gtamodding.com

22 Re: SA Memory Example Topic on Mon Apr 20, 2009 12:39 am

As most memory hackers(scripter's) know you can access the memory using the SA arrays to get an access to any addresses in range of 0..FFFFFFFF, like Seemann post in his SA Memory handling topic, in my opinion the best way to access the memory is via arrays way, and also via memory access thread which was written by Seemann. With CLEO you can use opcodes 0a8c/0a8d.


1: Arrays memory read/write thread (works for the game version v1, change 0xA49960 to 0xA4BFE0 if you want it to work for game version v1.1.)

Advantages:

  • all game addresses are accessible
  • easy to use
  • nothing especial required; scm-based solution


Disadvantages:

  • some of addresses still couldn't be rewritable (because of AccessViolation Error)



Code:

// 0@ -address
// 2@ -new value
// 3@ -length (in bytes)
//--write specified number of bytes into memory
:MemoryWrite
0085: 5@ = 0@
0@ /= 4
0@ *= 4          // memory address
0062: 5@ -= 0@    // offset (0, 1, 2, 3)
:_GetInitValue      // if you specify mem offset in 5@, you're able to gosub here
gosub @MemoryRead // get initial value
3@ *= 8 // bytes -> bits
5@ *= 8
dec(3@)
for 6@ = 0 to 3@                 
  if
    08B6: test 2@ bit 6@
  then
    08BF: set 1@ bit 5@    // 1
  else
    08C5: clear 1@ bit 5@  // 0
  end
  inc(5@) // next memory bit
end
008A: &0(0@,1i) = 1@  // write new value
return

//--write 32-bit value into memory-----------

:MemoryWrite32bit
0@ -= 0xA49960
0@ /= 4
008A: &0(0@,1i) = 1@
return

//--read 32-bit value from memory-----------

:MemoryRead
0@ -= 0xA49960
0@ /= 4
008B: 1@ = &0(0@,1i)
return


Example using that code, this removes the message when Carl, is stealing a car the first time.


Code:

0@ = 0xC0BC15 // 0@ -address
2@ = 1 // 2@ -new value
3@ = 1 // 3@ -length (in bytes)
gosub @MemoryWrite
end_thread



Multi version of the script above, works for both v1 & v1.1
the code has a check to test what version your game is -- differences are: for v1 the SCM start is: 0xA49960, for v1.1 the SCM start is: 0xA4BFE0. NOTE: it's necessary to check the address for putting in if the game is the original version, then use the original address if false, then use the v1.1 address.


Code:

// TEST game version
0@ = -429566
if
  &0(0@,1i) == 4611680
then // v1

// 0@ -address
// 2@ -new value
// 3@ -length (in bytes)
//--write specified number of bytes into memory

else // v1.1

// 0@ -address
// 2@ -new value
// 3@ -length (in bytes)
//--write specified number of bytes into memory

end

:MemoryWrite
0085: 5@ = 0@
0@ /= 4
0@ *= 4          // memory address
0062: 5@ -= 0@    // offset (0, 1, 2, 3)
:_GetInitValue      // if you specify mem offset in 5@, you're able to gosub here
gosub @MemoryRead // get initial value
3@ *= 8 // bytes -> bits
5@ *= 8
dec(3@)
for 6@ = 0 to 3@                 
  if
    08B6: test 2@ bit 6@
  then
    08BF: set 1@ bit 5@    // 1
  else
    08C5: clear 1@ bit 5@  // 0
  end
  inc(5@) // next memory bit
end
008A: &0(0@,1i) = 1@  // write new value
return


//--write 32-bit value into memory-----------

:MemoryWrite32bit
0@ = -429566
if
  &0(0@,1i) == 4611680
then
  0@ -= 0xA49960
else
  0@ -= 0xA4BFE0
end
  0@ /= 4
  008A: &0(0@,1i) = 1@
return

//--read 32-bit value from memory-----------

:MemoryRead
0@ = -429566
if
  &0(0@,1i) == 4611680
then
  0@ -= 0xA49960
else
  0@ -= 0xA4BFE0
end
  0@ /= 4
  008B: 1@ = &0(0@,1i)
return


An example using that, this also removes the message when Carl, is stealing a car the first time.


Code:

0@ = -429566 // test game version
if
  &0(0@,1i) == 4611680
then // v1
    0@ = 0xC0BC15 // 0@ -address
    2@ = 1 // 2@ -new value
    3@ = 1 // 3@ -length (in bytes)
else // v1.1
    0@ = 0xC0E295 // 0@ -address
    2@ = 1 // 2@ -new value
    3@ = 1 // 3@ -length (in bytes)
end
gosub @MemoryWrite
end_thread



2: Memory Access Thread

Advantages:

  • all game addresses are accessible
  • no need for the Xieon's patch


Disadvantages:

  • if any it would be that it's not easy for new scripter's to understand



Code:

{ -----------------------------------------------------------------
  Memory Access Thread
  MultiVersion :: supports GTA SA v1 and v1.01

  to write a value with the specified length to the memory address  use
  create_thread @MemoryProofMultiWrite address for version1 X:DWord address for version1.01 X:DWord size X:BYTE value X:DWORD VirtualProtect X:BOOL

  Example:
  create_thread @MemoryProofMultiWrite address_V1 0xC0BC15 address_V2 0xC0E295 size 1 value 1
 
  to read a value with the specified length by the memory address  use
  create_thread @MemoryProofMultiRead address for version1 X:DWord address for version1.01 X:DWord size X:BYTE VirtualProtect X:BOOL
 
  The read value will be stored to the variable $MEMORY_PROOF_READ
 
  Example:
  create_thread @MemoryProofMultiRead address_V1 0x863984 address_V2 0 size 4 VirtualProtect 1

  The possible Size values: 1 (byte), 2 (word), 4 (dword)
  The VirtualProtect parameter is optional
----------------------------------------------------------------- }

:MemoryProofMultiWrite
gosub @_____gsvo01
7@ = @MemoryWrite
4@ == 1
jf @_____novp

:_____mpvp
0085: 8@ = 10@(9@,2i)
008A: &0(8@,1i) = 14@(9@,2i)
005E: &0(8@,1i) += 16@(9@,2i)
0052: gap 0 virtual_protect_at_address 0@(9@,2i) size 2@ newprotect 4 gap 0 0
0572: run_VPSV 1
gosub 7@
0052: gap 0 virtual_protect_at_address 0@(9@,2i) size 2@ newprotect -1 gap 0 0
0572: run_VPSV 1
&0(8@,1i) = 0
end_thread

:MemoryProofMultiRead
gosub @_____gsvo01
7@ = @MemoryRead
3@ == 0
jf @_____mpvp

:_____novp
gosub 7@
end_thread

:MemoryWrite
0085: 7@ = 12@(9@,2i)
008A: &0(7@,1i) = 14@(9@,2i)
005E: &0(7@,1i) += 18@(9@,2i)
0052: gap 0 target_address 0@(9@,2i) size 2@ value 3@ gap 0 0
0A3D: run_MWSS 1
&0(7@,1i) = 0
return

:MemoryRead
0085: 7@ = 12@(9@,2i)
008A: &0(7@,1i) = 14@(9@,2i)
005E: &0(7@,1i) += 20@(9@,2i)
02EC: run_MRMM 1 read_address 0@(9@,2i) size 2@
hex
3D0A008D0100000000 {store_to} 02 $MEMORY_PROOF_READ
end
&0(7@,1i) = 0
return

:_____gsvo01
8@ = -429566
&0(8@,1i) == 4611680
jf @_____gsvo012 // 1.0
//    9@  = 0
  10@ = -429863
  12@ = -429864
  14@ = 0xA49960
  16@ = @_____vpsv
  18@ = @_____mwss
  20@ = @_____mrmm
return
:_____gsvo012    // 1.01
  9@  = 1
  11@ = -431117
  13@ = -431118
  15@ = 0xA4BFE0
  17@ = @_____vpsv2
  19@ = @_____mwss2
  21@ = @_____mrmm2   
return

:_____vpsv2
hex
68 74 63 A4 00 83 3D 04 63 A4 00 FF
75 08 FF 35 74 63 A4 00 EB 06 FF 35
04 63 A4 00 FF 35 FC 62 A4 00 FF 35
F8 62 A4 00 FF 15 2C 90 85 00 C3
end

:_____vpsv
hex
68 F4 3C A4 00 83 3D 84 3C A4 00 FF
75 08 FF 35 F4 3C A4 00 EB 06 FF 35
84 3C A4 00 FF 35 80 3C A4 00 FF 35
7C 3C A4 00 FF 15 2C 80 85 00 C3
end

:_____mwss2
hex
8B 15 FC 62 A4 00 8B 05 04 63 A4 00
8B 0D 63 00 A4 00 EB 12
end

:_____mwss
hex
8B 15 7C 3C A4 00 8B 05 84 3C A4 00
8B 0D 80 3C A4 00 83 F9 01 75 03 88
02 C3 83 F9 02 75 04 66 89 02 C3 89
02 C3
end

:_____mrmm2
hex
31 C0 BA F8 62 A4 00 89 02 8B 0D 00
63 A4 00 8B 05 FC 62 A4 00 EB 15
end

:_____mrmm
hex
31 C0 BA 78 3C A4 00 89 02 8B 0D 80
3C A4 00 8B 05 7C 3C A4 00 83 F9 01
75 05 8A 00 88 02 C3 83 F9 02 75 07
66 8B 00 66 89 02 C3 8B 00 89 02 C3             
end

{ ---------end of memory access thread----------------------------- }


Parameters:


Code:

create_thread @MemoryProofMultiWrite/Read address for v1.0 (X:DWord) address for v1.01 (X:DWord) size (X:BYTE) value (X:DWORD) VirtualProtect (X:BOOL)


You could pass two addresses: one for v1, second for v1.01. The code has a check to test what game version your playing in the script.


Code:

8@ = -429566
&0(8@,1i) == 4611680
jf @_____gsvo012 // 1.0



An example of using the Memory Access Thread, this removes the message when Carl, is stealing a car the first time, address for v1 is at: 0x00C0BC15, and the v1.1 address is at: 0x00C0E295


Code:

create_thread @MemoryProofMultiWrite address_V1 0xC0BC15 address_V2 0xC0E295 size 1 value 1



3: Well, in CLEO scripts, (or if you have CLEO installed, this apply's also to the main.scm, but of course if you are going to use this example, replace opcode 0a93(0a93: end_custom_thread) in the example with 004e(004e: end_thread), because opcode 0a93 must NEVER be used in the main.scm) you can use the CLEO opcodes 0A8C to write a value to the games memory, and 0A8D to read. Here is an example:

Advantages:

  • all game addresses are accessible
  • only one line using
  • easy to use


Disadvantages:

  • CLEO must be installed



Code:

[$CLEO}
wait 5000

if
  0aa9:    is_game_version_original
then
    0a8c: write_memory 0xC0BC15 size 1 value 1 virtual_protect 0
else
    0a8c: write_memory 0xC0E295 size 1 value 1 virtual_protect 0
end
0a93: end_custom_thread


4. See this topic

Advantages:

  • the only opcode is using

    Disadvantages:
  • memory range is very limited, many useful addresses are inaccessible.


5: using the Xieon's patch, though it's not needed much anymore.

Advantages:

  • all game addresses are accessible
  • possibility to protect a memory region with VirtualProtect to rewrite it

    Disadvantages:
  • requires EXE patching

View user profile http://gtamodding.com

23 Re: SA Memory Example Topic on Fri Apr 24, 2009 11:24 am

More about changing the trains via arrays.

18 carriages is the max limit! However 16 is the highest, which is bug free-ish. Using 17th and 18th carriages it's very-bugged, because this rewrites data of the next train type. Say if I'm using 17th carriage in the second type then first carriage in the third type will be missed, AFAIR. Sometimes the game may even crash! 18 carriages in my opinion is only save to use on type 0.

-382229 is the start of the type 0, since we can add 18 carriages in total to a train, we first check if the train already comes with installed carriages(type '0' comes with '3'), if we wanted to add say another 2 carriages to that train, we would do this: for 0@ = -382229 to -382227, the number goes down by 1 each time you ADD 1 carriage to the train, (the numbers are negative), since the train
type 0 already comes with 4 installed, we may ADD another 14 carriages to it, (the total should never be more high than 18.) The following code would add 14 more carriages to the train type 0(Streak carriages):


Code:

for 0@ = -382229 to -382216
  wait 0
  &0(0@,1i) = #STREAKC
end


Offsets are negative, use there hexadecimal number if you want.

Type 0 starts at: -382234(including the actual train)
Type 1 starts at: -382220(including the actual train)
Type 2 starts at: -382202(including the actual train)
Type 3 starts at: -382186(including the actual train)
Type 4 starts at: -382170(including the actual train)
Type 6 starts at: -382138(including the actual train)

The other train type, I think is not important to change.

Syntax:


Code:

for <Type start address> to <start address (-) amount of carriages your adding> end


As already noted this method of changing the trains, use the for..end struct, you may read more about it in Sanny Builder Help or scripting function's topic.




Say if we wanted the train type 3 to have one special carriage, and the others not we can do this:



Code:

0@ = -382186 // type 3
&0(0@,1i) = #FREIGHT

for 0@ = -382185 to -382175
  wait 0
  &0(0@,1i) = #STREAKC
end

// .... create a train


There one will be a #FREIGHT model, the others #STREAKC models, (since the address starts at -382186 we do the special carriage from there, and
after this we will use -382185(for 0@ = -382185 to -382175), we could even do this the other-way-around:



Code:
 
 for 0@ = -382186 to -382176
  wait 0
  &0(0@,1i) = #STREAKC
end

0@ = -382175  // type 3
&0(0@,1i) = #FREIGHT

// .... create a train


From -382186 to -382176 all these will have the model #STREAKC, and the last carriage on the train will have the model #FREIGHT.
So, if we wanna do this then get the address(-382186), then set the model you want for the driver-seat carriage.



Code:
 
0@ = -382202
&0(0@,1i) = #FREIGHT


For an example, I've set the carriage 3 to have the model #FREIGHT. Let me remind you, that, if you wanna keep the old carriages that ALREADY comes
with the train, check first how many carriages your train originally has:


Code:
 
Type        Train    Carriage1  Carriage2  Carriage3  Carriage4  Carriage5
----------------------------------------------------------------------------           
0:          #FREIGHT  #FREIFLAT  #FREIFLAT  #FREIFLAT  #FREIFLAT    x
1,2,4,7,11: #STREAK  #STREAKC  #STREAKC      x        x          x
3:          #FREIGHT  #FREIFLAT  #FREIFLAT  #FREIFLAT    x          x
5:          #STREAK  #STREAKC  #STREAKC  #STREAKC      x          x
6:          #FREIGHT  #FREIFLAT  #FREIFLAT      x        x          x
8:          #TRAM    #TRAM          x          x        x          x
9,14:      #TRAM        x          x          x        x          x
10:        #FREIGHT  #FREIFLAT      x          x        x          x
12:        #FREIGHT  #FREIFLAT  #FREIFLAT  #FREIFLAT  #FREIGHT      x
13:        #FREIGHT  #FREIFLAT  #FREIFLAT  #FREIFLAT  #FREIFLAT #FREIFLAT
15:        #STREAK      x          x          x        x          x


So, the type 4 carriages, so without replacing these we do not use -382233, but we use -382229(-4), because the train already comes with
4 installed, and this will give us a total of 18 carriages.

At first, this may be difficult for some to understand, as it is to explain well. Take some notice of the example scripts:


Code:

:Trains_01
while true
wait 0
0@ = -229908
if
  &0(0@,1i) == 0x54455354  // 'test'
then
    break
    end
end
&0(0@,1i) = 0x54455300
03E5: show_text_box 'CHEAT1'  // Cheat activated

0169: set_fade_color_RGB 0 0 0
fade 0 time 500

while true
if
    not fading
then
      break
    end
    wait 0
end

//---- Train: #FREIGHT Carriages: #FREIFLAT  #FREIFLAT  #FREIFLAT  #FREIFLAT
// 4 carriages already installed

// add 14 more with the model "#STREAKC"
for 0@ = -382229 to -382216
  wait 0
  &0(0@,1i) = #STREAKC
end
 
 
 #FREIGHT.Load
      #FREIFLAT.Load
      #STREAKC.Load

      while true
        if and
          Model.Available(#FREIGHT)
          Model.Available(#FREIFLAT)
          Model.Available(#STREAKC)
        then
          break
        end
        wait 0
      end
   
      Actor.PutAt($PLAYER_ACTOR, 2270.1771, -1144.8823, 27.5108)
      03CB: set_rendering_origin_at 2270.1771 -1144.8823 27.5108
      04E4: unknown_refresh_game_renderer_at 2270.1771 -1144.8823
      wait 1300
      fade 1 time 1500
   
      while true
    if
        fading 
    then
          break
        end
        wait 0
    end
   
      06D8: 1@ = create_train_at 2278.1771 -1144.8823 27.5108 type 0 direction 1
      0395: clear_area 1 at 2270.1771 -1144.8823 27.5108 radius 1.0 
    Model.Destroy(#FREIGHT)
    Model.Destroy(#FREIFLAT)
    Model.Destroy(#STREAKC)
    end_thread
   




Code:

:Trains_01
while true
wait 0
0@ = -229908
if
  &0(0@,1i) == 0x54455354  // 'test'
then
    break
    end
end
&0(0@,1i) = 0x54455300
03E5: show_text_box 'CHEAT1'  // Cheat activated

0169: set_fade_color_RGB 0 0 0
fade 0 time 500

while true
if
    not fading
then
      break
    end
    wait 0
end

//---- Train: #STREAK  Carriages: #STREAKC  #STREAKC
// 2 carriages already installed

// add 13 more carriages  with the model "#STREAKC"
for 0@ = -382217 to -382204
  wait 0
  &0(0@,1i) = #STREAKC
end
 
 
 #STREAK.Load
     
      #STREAKC.Load

      while true
        if and
          Model.Available(#STREAK)
          Model.Available(#STREAKC)
        then
          break
        end
        wait 0
      end
   
      Actor.PutAt($PLAYER_ACTOR, 2270.1771, -1144.8823, 27.5108)
      03CB: set_rendering_origin_at 2270.1771 -1144.8823 27.5108
      04E4: unknown_refresh_game_renderer_at 2270.1771 -1144.8823
      wait 1300
      fade 1 time 1500
   
      while true
    if
        fading 
    then
          break
        end
        wait 0
    end
   
      06D8: 1@ = create_train_at 2278.1771 -1144.8823 27.5108 type 1 direction 1
      0395: clear_area 1 at 2270.1771 -1144.8823 27.5108 radius 1.0 
    Model.Destroy(#STREAK)
    Model.Destroy(#STREAKC)
    end_thread
     



Code:

:Trains_01
while true
wait 0
0@ = -229908
if
  &0(0@,1i) == 0x54455354  // 'test'
then
    break
    end
end
&0(0@,1i) = 0x54455300
03E5: show_text_box 'CHEAT1'  // Cheat activated

0169: set_fade_color_RGB 0 0 0
fade 0 time 500

while true
if
    not fading
then
      break
    end
    wait 0
end


0@ = -382202
&0(0@,1i) = #STREAK

//-- + 13 carriages
for 0@ = -382201 to -382188
  wait 0
  &0(0@,1i) = #STREAKC
end
 
 
 #STREAK.Load
     
      #STREAKC.Load

      while true
        if and
          Model.Available(#STREAK)
          Model.Available(#STREAKC)
        then
          break
        end
        wait 0
      end
   
      Actor.PutAt($PLAYER_ACTOR, 2270.1771, -1144.8823, 27.5108)
      03CB: set_rendering_origin_at 2270.1771 -1144.8823 27.5108
      04E4: unknown_refresh_game_renderer_at 2270.1771 -1144.8823
      wait 1300
      fade 1 time 1500
   
      while true
    if
        fading 
    then
          break
        end
        wait 0
    end
   
      06D8: 1@ = create_train_at 2278.1771 -1144.8823 27.5108 type 2 direction 1
      0395: clear_area 1 at 2270.1771 -1144.8823 27.5108 radius 1.0 
    Model.Destroy(#STREAK)
    Model.Destroy(#STREAKC)
    end_thread
     


-- Questions, are welcome! I understand it may be confusing for some... Wink

View user profile http://gtamodding.com

24 Re: SA Memory Example Topic on Sun May 03, 2009 2:27 am


These codes I am posting require knowledge of the opcode 0AB1 and
0AB2.

Get Actor Damaging Ped



An actor who is damaging a ped.


Code:

//---------------------------------------------------------

:Read_1
0A96: 1@ = actor 0@ struct
1@ += 0x764

:Read_2
0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0
if
    0@ > 0
then
    0A8D: 4@ = read_memory 0x00B74490 size 4 virtual_protect 0
    0AA8: call_function_method 0x4442D0 struct 4@ num_params 1 pop 0 0@ 1@
    if
        056D:  actor 1@ defined
    then
        0AB2: ret 1 1@
    end
end
0AB2: ret 1 -1



You can call it using the CLEO opcode 0AB1. All functions work as a condition. This means checking if 0AB1 is true or false.



Code:

0AB1: call_scm_func @Read_1 1 $PLAYER_ACTOR 1@



Car Damaging actor



Car ran over CJ


Code:

//---------------------------------------------------------

:Read_3
0A96: 1@ = actor 0@ struct
1@ += 0x764

:Read_4
0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0
if
    0@ > 0
then
    0A8D: 4@ = read_memory 0x00B74494 size 4 virtual_protect 0
    0AA8: call_function_method 0x424160 struct 4@ num_params 1 pop 0 0@ 1@
    if
        056E:  car 1@ defined
    then
        0AB2: ret 1 1@
    end
end
0AB2: ret 1 -1



Code:

0AB1: call_scm_func @Read_3 1 $PLAYER_ACTOR 1@


Ped Damaging Vehicle



A person punched the vehicle.


Code:

//---------------------------------------------------------

:Read_5
0A97: 1@ = car 0@ struct
1@ += 0x50C

:Read_6
0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0
if
    0@ > 0
then
    0A8D: 4@ = read_memory 0x00B74490 size 4 virtual_protect 0
    0AA8: call_function_method 0x4442D0 struct 4@ num_params 1 pop 0 0@ 1@
    if
        056D:  actor 1@ defined
    then
        0AB2: ret 1 1@
    end
end
0AB2: ret 1 -1



Code:

0AB1: call_scm_func @Read_5 1 0@ 1@


Get Vehicle Damaging Vehicle



A vehicle has damaged another vehicle.


Code:

//---------------------------------------------------------

:Read_7
0A97: 1@ = car 0@ struct
1@ += 0x50C

:Read_8
0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0
if
    0@ > 0
then
    0A8D: 4@ = read_memory 0x00B74494 size 4 virtual_protect 0
    0AA8: call_function_method 0x424160 struct 4@ num_params 1 pop 0 0@ 1@
    if
        056E:  car 1@ defined
    then
        0AB2: ret 1 1@
    end
end
0AB2: ret 1 -1



Code:

0AB1: call_scm_func @Read_7 1 0@ 1@



Example script



Any ped who hits Carl, will now die of a painful death. Enjoy! Wink


Code:

{$CLEO}

0000:
while true
    wait 0
    if
        Player.Defined($PLAYER_CHAR)
    then
        if
            031D:  actor $PLAYER_ACTOR hit_by_weapon 57  // 57 by any weapon
        then           
            if
                0AB1: call_scm_func @GetADP 1 $PLAYER_ACTOR 1@
            then
                  0467: clear_actor $PLAYER_ACTOR last_weapon_damage
                  0321: kill_actor 1@
                end
          end
    end
end
               
//---------------------------------------------------------

:GetADP
0A96: 1@ = actor 0@ struct
1@ += 0x764

:TestPed
0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0
if
    0@ > 0
then
    0A8D: 4@ = read_memory 0x00B74490 size 4 virtual_protect 0
    0AA8: call_function_method 0x4442D0 struct 4@ num_params 1 pop 0 0@ 1@
    if
        056D:  actor 1@ defined
    then
        0AB2: ret 1 1@
    end
end
0AB2: ret 1 -1               
               





View user profile http://gtamodding.com

25 Re: SA Memory Example Topic on Sun May 03, 2009 5:05 am


A long version, it shows how to use all the functions.


  • If CJ is damaged then who did it pays (decapitated).
  • If someone hits CJ's car (pedestrian), they get set on fire.
  • If CJ gets run over, then that car will be history (who did it).
  • If somebody hits you or vice-versa, there car and them are history.


Basically anyone who annoys CJ, must pay!


Code:

{$CLEO}

0000:
while true
    wait 0
    if
        Player.Defined($PLAYER_CHAR)
    then
      //----------------------------------
      // Get Actor Damaging Ped
      //---------------------------------- 
                // e.g. someone punches CJ
        if
            031D:  actor $PLAYER_ACTOR hit_by_weapon 57 // 57 by any weapon
        then           
            if
                0AB1: call_scm_func @Get1 1 $PLAYER_ACTOR 1@
            then
                  0467: clear_actor $PLAYER_ACTOR last_weapon_damage
                  0321: kill_actor 1@
                end
          end
             
    //----------------------------------
    // Car Damaging actor
    //----------------------------------   
               
                // e.g. CJ got ran over
  if
        031D:  actor $PLAYER_ACTOR hit_by_weapon 49 // 49 by any car
    then           
        if
            0AB1: call_scm_func @Get2 1 $PLAYER_ACTOR 1@
        then
            0467: clear_actor $PLAYER_ACTOR last_weapon_damage
            02AB: set_actor $PLAYER_ACTOR immunities BP 0 FP 1 EP 1 CP 1 MP 0

            020B: explode_car 1@ // versionA
            wait 500
            02AB: set_actor $PLAYER_ACTOR immunities BP 0 FP 0 EP 0 CP 0 MP 0

        end
    end
   
    //----------------------------------
    // Ped Damaging Vehicle
    //----------------------------------   
                      // e.g. ped punched your vehicle
    if
            Actor.Driving($PLAYER_ACTOR)
        then
            03C0: 0@ = actor $PLAYER_ACTOR car

            if
                031E:  car 0@ hit_by_weapon 57 // 57 by any weapon
            then
                if
                    0AB1: call_scm_func @Get3 1 0@ 1@
                then
                    0468: clear_car 0@ last_weapon_damage
                    0326: 31@ = create_actor 1@ fire
                    end
              end 
   
      //----------------------------------
      // Get Vehicle Damaging Vehicle
      //----------------------------------   
   
                      // e.g. CJ crashes into somebody or vice-versa
    if
                031E:  car 0@ hit_by_weapon 49  // 49 by any car
            then
                if
                    0AB1: call_scm_func @Get4 1 0@ 1@
                then
                    0468: clear_car 0@ last_weapon_damage
                 
                    02AC: set_car 0@ immunities BP 1 FP 1 EP 1 CP 1 MP 1
                    020B: explode_car 1@ // versionA
                    wait 500
                    02AC: set_car 0@ immunities BP 0 FP 0 EP 0 CP 0 MP 0
                end
          end
     
        //-- loop end
        end
    end
end


//---------------------------------------------------------

:Get1
0A96: 1@ = actor 0@ struct
1@ += 0x764

:Test1
0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0
if
    0@ > 0
then
    0A8D: 4@ = read_memory 0x00B74490 size 4 virtual_protect 0
    0AA8: call_function_method 0x4442D0 struct 4@ num_params 1 pop 0 0@ 1@
    if
        056D:  actor 1@ defined
    then
        0AB2: ret 1 1@
    end
end
0AB2: ret 1 -1

//---------------------------------------------------------

:Get2
0A96: 1@ = actor 0@ struct
1@ += 0x764

:Test2
0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0
if
    0@ > 0
then
    0A8D: 4@ = read_memory 0x00B74494 size 4 virtual_protect 0
    0AA8: call_function_method 0x424160 struct 4@ num_params 1 pop 0 0@ 1@
    if
        056E:  car 1@ defined
    then
        0AB2: ret 1 1@
    end
end
0AB2: ret 1 -1

//---------------------------------------------------------

:Get3
0A97: 1@ = car 0@ struct
1@ += 0x50C

:Test3
0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0
if
    0@ > 0
then
    0A8D: 4@ = read_memory 0x00B74490 size 4 virtual_protect 0
    0AA8: call_function_method 0x4442D0 struct 4@ num_params 1 pop 0 0@ 1@
    if
        056D:  actor 1@ defined
    then
        0AB2: ret 1 1@
    end
end
0AB2: ret 1 -1

//---------------------------------------------------------

:Get4
0A97: 1@ = car 0@ struct
1@ += 0x50C

:Test4
0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0
if
    0@ > 0
then
    0A8D: 4@ = read_memory 0x00B74494 size 4 virtual_protect 0
    0AA8: call_function_method 0x424160 struct 4@ num_params 1 pop 0 0@ 1@
    if
        056E:  car 1@ defined
    then
        0AB2: ret 1 1@
    end
end
0AB2: ret 1 -1


View user profile http://gtamodding.com

26 Re: SA Memory Example Topic Today at 7:56 pm

Sponsored content


View previous topic View next topic Back to top  Message [Page 1 of 2]

Go to page : 1, 2  Next

Permissions in this forum:
You cannot reply to topics in this forum