Quantcast

Jump to content

» «
Photo

SA Memory handling

42 replies to this topic
Seemann
  • Seemann

    Ruhe

  • Members
  • Joined: 03 Sep 2004
  • Russia

#31

Posted 28 April 2007 - 11:31 AM

You could not pass a string parameter to the thread.

CODE
create_thread @CLV thread_name 'vchng'

This is the problem. Pass the string array index, or a label where the string's stored:

CODE
:mystring
hex
"vchng" 00
end

Bigun
  • Bigun

    wandering about

  • Members
  • Joined: 10 Jul 2004

#32

Posted 28 April 2007 - 05:34 PM

I've tried this:
CODE

:debug_var_test
thread 'VCHNG'
2@ = 2
create_thread @CLV thread_name @mystring local_num 2 set_value 40
wait 2000
054C: use_GXT_table 'POOL'
01E3: text_1number_styled 'NUM' 2@ 5000 ms 1  // ~1~
end_thread

:mystring
hex
"vchng" 00
end


But it didn't work. confused.gif
I also tried to be smartass and do this:
CODE

:debug_var_test
thread 'VCHNG'
2@ = 2
05AA: 1@s = 'vchng' // 8-byte strings
create_thread @CLV thread_name 1@s local_num 2 set_value 40
wait 2000
054C: use_GXT_table 'POOL'
01E3: text_1number_styled 'NUM' 2@ 5000 ms 1  // ~1~
end_thread


And it output weird results; depending on the value, it either crashes, or successfully modifies the thread's local var, but always to '103'. :\

Please be more detailed in the next reply since I didn't really get everything, what do you mean about array index? Use a global array with strings, and pass the index to the wanted string, maybe? Well I want to use Darkpact so I can't use globals, which is a major reason to use the CLV thread in the first place. Actually, thinking about it, I'm an idiot, I don't think Darkpact even works with Sanny... sucks.

Seemann
  • Seemann

    Ruhe

  • Members
  • Joined: 03 Sep 2004
  • Russia

#33

Posted 29 April 2007 - 03:43 AM

Yes, I mean the global array as it's the way it may work. But if you dont want to use it, there's another way:

CODE
:CLV
{
 0@ thread_name index at @Thread_Names
 1@ local var num to modify
 2@ value to set to var
}
03A4: name_thread 'CLV'
0006: 3@ = 67251

:CLV_LOOP
008B: 3@ = &0(3@,1i)
00D6: if
8039:   not  3@ == 0
004D: jump_if_false @CLV_END
// 0001: wait 0 // not necessary
0085: 4@ = 3@
0016: 4@ /= 8
000E: 4@ -= 1348395
0016: 3@ /= 4
000E: 3@ -= 2696792
00D6: if
// 05AD: &0(4@,1s) == &@Thread_Names(0@,1s)
hex
AD05           // opcode      (05AD)
0C             // data type
0000           // array name  (&0)
0400           // index name  (4@)
0102           // size&type
0C             // data type
@Thread_Names  // array name&index name (0@)
0102           // size&type
end

004D: jump_if_false @CLV_LOOP

//add to 3@ (local var num + 15)
000A: 1@ += 15
005A: 3@ += 1@
008A: &0(3@,1i) = 2@

:CLV_END
004E: end_thread

// thread names, all of 8 bytes
:Thread_Names
hex
"vchng" 00 00 00 // 8 bytes
"vchng2" 00 00   // 8 bytes
end



and example:

CODE
:TEST1
thread 'VCHNG'
2@ = 2
create_thread @CLV thread_name_index 0 local_num 2 set_value 12
wait 2000
054C: use_GXT_table 'POOL'
01E3: text_1number_styled 'NUM' 2@ 5000 ms 1  // ~1~
end_thread



But it works only if the CLV thread and Thread_Names are located at the first 64k of the main.scm (single globalvar limitation). Otherwise use CLEO.

As for DP, Y_Less posted the Sanny's version of it (with pdescobar's corrections). I guess it should work.

Seemann
  • Seemann

    Ruhe

  • Members
  • Joined: 03 Sep 2004
  • Russia

#34

Posted 02 June 2007 - 06:01 AM Edited by Seemann, 02 June 2007 - 12:23 PM.

It's a code to get the handle of nearest random ped / car / object to a variable.


Originally was written by PLPynton
but that code was buggy and never worked for me. I've fixed and improved it.

The code accepts 4 parameters for the search: XYZ coord of the point from where begin to search and radius of the searching.
If there's any ped (or car, whatever you wish) in this radius, the code stores. its handle in variable 9@.
Otherwise it returns -1. It will ignore the player or his car also.


This code is written in native line-by-line syntax so it could be used in SAMB as well (if there's someone still using it, he-he..).
Only labels and aDMA (&) should be converted (@ -> JJ, & -> $)

CODE

{
   The Interceptor
     
   by PLPynton and Seemann    

   Parameters:
   0@ - input coord X
   1@ - input coord Y
   2@ - input coord Z
   3@ - search radius

   variables 4@..20@ in use
   
   9@ = Result (returns -1 if not found)
         
}
:AIC_GETACTOR
0006: 16@ = 305868
0006: 17@ = @AIC_TESTACTORHANDLE
0006: 20@ = 1988
0002: jump @AIC_STARTSEARCH

:AIC_GETVEHICLE
0006: 16@ = 305869
0006: 17@ = @AIC_TESTVEHICLEHANDLE
0006: 18@ = -1
0006: 20@ = 2584
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @AIC_STARTSEARCH
00DF:   actor $PLAYER_ACTOR driving
004D: jump_if_false @AIC_STARTSEARCH
03C0: 18@ = actor $PLAYER_ACTOR car
0002: jump @AIC_STARTSEARCH

:AIC_GETOBJECT
0006: 16@ = 305871
0006: 17@ = @AIC_TESTOBJECTHANDLE
0006: 20@ = 412

:AIC_STARTSEARCH
0085: 4@ = 16@ // (int)
008B: 4@ = &0(4@,1i) // (int)
0085: 19@ = 4@ // (int)
000E: 19@ -= 10787160
0016: 19@ /= 4
008B: 19@ = &0(19@,1i) // (int)
000E: 4@ -= 10787168
0016: 4@ /= 4
008B: 4@ = &0(4@,1i) // (int)
0006: 9@ = -1
0085: 11@ = 4@ // (int)
0006: 10@ = 0

:AIC_SEARCHLOOPMAIN
000A: 4@ += 20
0050: gosub @AIC_READ4B
0085: 4@ = 5@ // (int)
8039:   not  4@ == 0
004D: jump_if_false @AIC_SEARCHLOOPNEXT
000A: 4@ += 48
0050: gosub @AIC_READ4B
0085: 12@ = 5@ // (int)
000A: 4@ += 4
0050: gosub @AIC_READ4B
0085: 13@ = 5@ // (int)
000A: 4@ += 4
0050: gosub @AIC_READ4B
0085: 14@ = 5@ // (int)
050A: 15@ = distance_between_XYZ 0@ 1@ 2@ and_XYZ 12@ 13@ 14@
0025:   3@ > 15@ // (float)
004D: jump_if_false @AIC_SEARCHLOOPNEXT
0085: 9@ = 10@ // (int)
0085: 4@ = 16@ // (int)
008B: 4@ = &0(4@,1i) // (int)
000A: 4@ += 4
0050: gosub @AIC_READ4B
0085: 4@ = 5@ // (int)
005A: 4@ += 9@ // (int)
0050: gosub @AIC_READ1B
0012: 9@ *= 256
005A: 9@ += 5@ // (int)
0002: jump 17@

:AIC_TESTVEHICLEHANDLE
056E:   is 9@ valid_vehicle_handle
004D: jump_if_false @AIC_NOHANDLE
00D6: if or
003B:   18@ == 9@ // (int)
0119:   car 9@ wrecked
004D: jump_if_false @AIC_NEWSEARCHRADIUS
0002: jump @AIC_NOHANDLE

:AIC_TESTACTORHANDLE
056D:   is 9@ valid_actor_handle
004D: jump_if_false @AIC_NOHANDLE
00D6: if or
003C:   $PLAYER_ACTOR == 9@ // (int)
0118:   actor 9@ dead
004D: jump_if_false @AIC_NEWSEARCHRADIUS
0002: jump @AIC_NOHANDLE

:AIC_TESTOBJECTHANDLE
//0001: wait 0
83CA:   not object 9@ exists
004D: jump_if_false @AIC_NEWSEARCHRADIUS

:AIC_NOHANDLE
0006: 9@ = -1
0002: jump @AIC_SEARCHLOOPNEXT

:AIC_NEWSEARCHRADIUS
{  
  use 0051: return to break the loop
  immediately when found at least one actor/car/object,
  does not matter if he's nearest one.
}

// v EXTRA SEARCH CRITERIA GOES HERE v

{
 21@ contains the handle of an actor/car/object
 that should be excluded from the search result
 (for example a handle found previously).
}
//803B:   21@ <> 9@
//004D: jump_if_false @AIC_NOHANDLE

   
0085: 3@ = 15@

:AIC_SEARCHLOOPNEXT
005A: 11@ += 20@ // (int)
0085: 4@ = 11@ // (int)
000A: 10@ += 1
002D:   10@ >= 19@ // (int)
004D: jump_if_false @AIC_SEARCHLOOPMAIN
0051: return

// ---------------------------------
:AIC_READ1B
0085: 6@ = 4@ // (int)
0085: 8@ = 4@ // (int)
0016: 4@ /= 4
0012: 4@ *= 4
0062: 8@ -= 4@ // (int)
0012: 8@ *= 8
000E: 4@ -= 10787168
0016: 4@ /= 4
008B: 7@ = &0(4@,1i) // (int)
0085: 4@ = 6@ // (int)
0006: 5@ = 0
0006: 6@ = 0

:AIC_READ1B_LOOP
08B9:   test 7@ bit 8@
004D: jump_if_false @AIC_READ1B_NEXTBIT
08BF: set 5@ bit 6@

:AIC_READ1B_NEXTBIT
000A: 6@ += 1
000A: 8@ += 1
0039:   6@ == 8
004D: jump_if_false @AIC_READ1B_LOOP
0051: return

:AIC_READ4B
0085: 6@ = 4@ // (int)
000E: 4@ -= 10787168
0016: 4@ /= 4
008B: 5@ = &0(4@,1i) // (int)
0085: 4@ = 6@ // (int)
0051: return




------------------------

Example:

CODE
while true
wait 100

 00A0: store_actor $PLAYER_ACTOR position_to 0@ 1@ 2@
 3@ = 15.0

 gosub @AIC_GETVEHICLE
 if
   9@ <> -1
 then
    020B: explode_car 9@ // versionA
    // 0085: 21@ = 9@ // exclude this handle from the next search, see extra search criteria in the code
 end
end


Screenshot:

A marker above random object
user posted image

X_ATP_X
  • X_ATP_X

    GTA United Scripter

  • Members
  • Joined: 17 Dec 2007

#35

Posted 29 April 2008 - 03:58 PM

QUOTE (Seemann @ Dec 6 2006, 11:57)

-------------------------------------------------

EXAMPLE 1.
Make extremely long trains, 15+ carriages!

Original (in Russian)
Screenshot
-------------------------------------------------

CODE

:LONGTRAINS
thread 'TRAINS'
  for 0@ = -382229 to -382216
    wait 0
    &0(0@,1i) = #STREAKC        
  end
                                             
  // type0 changed!

  // load models
  #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
   
  // create train with new carriages
  06D8: 1@ = create_train_at 2278.1771 -1144.8823 27.5108 type 0 direction 1

  #FREIGHT.Destroy
  #FREIFLAT.Destroy
  #STREAKC.Destroy
 
end_thread



You describe how to change train type 0. But How can I change other train Types?
Maybe I stands in The Russian version But cant Russian. Can You Explain how to Change The Other train Types?
Is it Possible To add for example only 5 Carrigages and not 15?

Seemann
  • Seemann

    Ruhe

  • Members
  • Joined: 03 Sep 2004
  • Russia

#36

Posted 03 May 2008 - 10:56 AM

Read this post to find out the addresses where the game keeps the info about train types.

If you wanna change another type, say 3, and make it 5 carriages in length, do the following:

take an address of train type (0x8D45B8). it will be the address of the locomotive. write to this address which model you want for it. next 5 dwords (4 bytes each) will be carriages models. so, write to the 0x8D45B8+4, 0x8D45B8+8, 0x8D45B8+12, 0x8D45B8+16, 0x8D45B8+20 addresses models ID for carriages. then write zero to the next address (0x8D45B8+24). so, when you create a train of type 3, the game will read these addresses until it will find zero, and you will get a train with 5 carriages.

to write to a memory address use CLEO opcode 0A8C.

CODE
0A8C: write_memory 0x8D45BC size 4 value #FREIFLAT virtual_protect 0


X_ATP_X
  • X_ATP_X

    GTA United Scripter

  • Members
  • Joined: 17 Dec 2007

#37

Posted 03 May 2008 - 01:38 PM Edited by X_ATP_X, 03 May 2008 - 02:07 PM.

QUOTE (Seemann @ May 3 2008, 10:56)
Read this post to find out the addresses where the game keeps the info about train types.

If you wanna change another type, say 3, and make it 5 carriages in length, do the following:

take an address of train type (0x8D45B8). it will be the address of the locomotive. write to this address which model you want for it. next 5 dwords (4 bytes each) will be carriages models. so, write to the 0x8D45B8+4, 0x8D45B8+8, 0x8D45B8+12, 0x8D45B8+16, 0x8D45B8+20 addresses models ID for carriages. then write zero to the next address (0x8D45B8+24). so, when you create a train of type 3, the game will read these addresses until it will find zero, and you will get a train with 5 carriages.

to write to a memory address use CLEO opcode 0A8C.

CODE
0A8C: write_memory 0x8D45BC size 4 value #FREIFLAT virtual_protect 0



Ok Thanks That works.

Seemann
  • Seemann

    Ruhe

  • Members
  • Joined: 03 Sep 2004
  • Russia

#38

Posted 04 March 2009 - 02:56 PM


-------------------------------------------------
Making cheats
the easiest way
-------------------------------------------------


Making cheats (custom keypresses) seems to be a very common problem in SA scripting. People keep asking how to make them. Even there are ways to check the keys typed (first post of this topic has one of them), they are complex and require knowledge of memory structure.

Time ago I wrote a code that allows to make the cheats easily. All you need is to store a cheat string to a variable, call the scm function and check the result (true or false).

First of all, read this post to understand how passing the strings to scm functions or threads work.

Now, the code to check a custom cheat:

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


Copy this code without any changes to your script (it does not matter is it a mission or just a script; the code is designed in the way it works for both).

You may save the provided code to an external file and include it to your script using directive $INCLUDE (or $I). For example, download the file TestCheat.inc, copy it to the directory with your script's source, add the line
CODE
{$I TestCheat.inc}

at the very end of the script and that all. When you compile, the code will be read from the external file by the compiler automatically.

So, how to use this code and check your own cheats. Very easy.

Save the cheat string (for example, the cheat will be NOCOPS) to a variable
CODE
0@s = 'nocops'

Now call the scm function TestCheat with this string as argument (the post I linked above explains the way it works).
CODE
0AB1: call_scm_func @TestCheat 2 0@ 1@

And if the function returned true it means the player typed this cheat in-game. So you need to put the function' call in a loop:

CLEO script example:
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}


^ When you typed nocops in-game the function return true, and the command clear_wanted_level will be executed.

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    

{$I TestCheat.inc}


Notes:
1. the cheat string is case-insensitive. You may write 0@s = 'nocops', 0@s = 'NoCoPs', 0@s = 'nOCOPs', it will still work.
2. The cheat could be from 1 to 16 symbols in length.

coin-god
  • coin-god

    High Roller

  • $outh $ide Hoodz
  • Joined: 18 Mar 2007

#39

Posted 04 March 2009 - 09:46 PM

Nice to see anew way, but i will stick to the old way tounge.gif

Good one icon14.gif

GamerShotgun
  • GamerShotgun

    The main protagonist.

  • Members
  • Joined: 03 Oct 2005

#40

Posted 09 September 2011 - 11:02 AM

Sorry for bumping this, but is there a way to do this in VC? smile.gif

Deji
  • Deji

    Coding like a Rockstar!

  • Members
  • Joined: 24 Dec 2007

#41

Posted 09 September 2011 - 11:58 AM

I know it's an awsum topic n'all.. but 'bumping' is heavily frowned upon wink.gif

No, because I believe VC doesn't support arrays. That's what "CLEO For VC" was created for.

GamerShotgun
  • GamerShotgun

    The main protagonist.

  • Members
  • Joined: 03 Oct 2005

#42

Posted 10 September 2011 - 10:54 PM

Well, that's cool, but I don't really know how I'm able to do cheats like this. I mean, by typing words, not just pressing combinations.

Briangangsta
  • Briangangsta

    Player Hater

  • Members
  • Joined: 02 Dec 2011

#43

Posted 06 December 2011 - 01:55 AM

hello everyone i was wondering if it is possible to make a cheat that can make the current savegame 100% finished with everything unlocked, completed and all territories taken over

thx biggrin.gif alien.gif




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users