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

Coding Snippets

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

1 Coding Snippets on Fri Apr 17, 2009 8:07 am

Thought this maybe useful for some people,

Spawn a vehicle


Code:

{$CLEO}
0A95: enable_thread_saving
014B: 1@ = init_parked_car_generator #INFERNUS color -1 -1 1 alarm 0 door_lock 0 0 10000 at 2435.302 -1671.848 12.8007 angle 90.0
014C: 1@ 101 // Set car generator 1@ cars to generate to 101 (Infinite times)
0A93: end_custom_thread


Spawn an actor


Code:

{$CLEO}

0000:

:Spawn_01
while true
wait 250
if
    Player.Defined($PLAYER_CHAR)
then 
      if
          00E1:  0 8 // BackSpace
      then
          break
        end
    end
end // while

04C4: store_coords_to 1@ 2@ 3@ from_actor $PLAYER_ACTOR with_offset 0.0 5.0 0.0
#BMYDJ.Load

:Spawn_02
while true
if
  #BMYDJ.Available
then
      break
  end
  wait 0
end

Actor.Create(4@, 23, #BMYDJ, 1@, 2@, 3@)

Actor.RemoveReferences(4@)
#BMYDJ.Destroy
wait 250
jump @Spawn_01

View user profile http://james227ukmods.synthasite.com

2 Re: Coding Snippets on Fri Apr 17, 2009 12:12 pm

Create a very long train, type 'test' like a cheat code.



Code:

{$CLEO}
0000:

: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

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)
    0a93: end_custom_thread


Discussed in the SA Memory Example Topic


Change the locals of any thread(originally posted by Seemann in Russian(codes are for main.scm)).


Code:

create_thread @TEST1
create_thread @CLV_THREAD
end_thread

// ---------------------------------------------
//  This thread shows a number after 1 sec
//  after activated. The number is stored in 10@
// ---------------------------------------------
:TEST1
thread 'TEST'
 10@ = 10000
 wait 1000
 054C: use_GXT_table 'POOL'
 01E3: text_1number_styled 'NUM' 10@ 5000 ms 1  // ~1~
end_thread

// ---------------------------------------------
//  This thread searches the one named TEST
//  and changes its local variable 10@
// ---------------------------------------------
:CLV_THREAD
thread 'CLV'
 {
  0@  =  thread address
  1@  =  temp
 }
 0@ = 0xA8B42C 
 // FIND_THREAD_LOOP
 while true
  // MEMORY READ DWORD
  0@ -= 0xA49960
  0@ /= 4
  008B: 0@ = &0(0@,1i)
  // 1@ = first active thread
  if 0@ == 0
  then
    Break // no threads, search failed
  end
  0085: 1@ = 0@    // save the pointer
  // get thread name magic address
  div(1@, 8)
  dec(1@, 1 348 395)
  {
    IMPORTANT NOTE:
    thread names are stored in lowercase registry,
    so we've to compare it in lowercase as well.
    SB option 'Case Converting' has to be set to 'As is'!
  }
  if &0(1@,1s) == 'test'
  // check if this thread's name is ""
  then   
    // well, we've found it, can do everything with it
    // 0@ contains that thread address

    // get address of 10@     
    inc(0@, 0x3c)    // thread locals pool
    inc(0@, 40)      // dword* 10 = 40
 
    // MEMORY WRITE DWORD
    0@ -= 0xA49960
    0@ /= 4
    &0(0@,1i) = 3333  // thread(test).10@ = 3333 

    Break // end the LOOP
  else
    // no, that thread has another name
    // check the next one
    wait 0
  end
  // go to while_begin
 end
 // variable changed, end_thread 
end_thread


Short version:


Code:

004F: create_thread @TEST
004F: create_thread @CLV
004E: end_thread

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

:TEST
03A4: name_thread 'TEST'
0006: 10@ = 10000 // integer values
0001: wait 1000 ms
054C: use_GXT_table 'POOL'
01E3: text_1number_styled 'NUM' 10@ 5000 ms 1  // ~1~
004E: end_thread

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

:CLV
03A4: name_thread 'CLV'
0006: 0@ = 11056172 // integer values

:CLV_21
000E: 0@ -= 10787168 // integer values
0016: 0@ /= 4 // integer values
008B: 0@ = &0(0@,1i) // integer values and handles
00D6: if
8039:  not  0@ == 0 // integer values
004D: jump_if_false @CLV_183
0085: 1@ = 0@ // integer values and handles
0016: 1@ /= 8 // integer values
000E: 1@ -= 1348395 // integer values
00D6: if
05AD:  &0(1@,1s) == 'test' // 8-byte strings
004D: jump_if_false @CLV_172
000A: 0@ += 100 // integer values
000E: 0@ -= 10787168 // integer values
0016: 0@ /= 4 // integer values
0004: &0(0@,1i) = 3333 // integer values
0002: jump @CLV_183

:CLV_172
0001: wait 0 ms
0002: jump @CLV_21

:CLV_183
004E: end_thread


Display text using ASM injectors(code is for main.scm).


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

View user profile http://gtamodding.com

3 Re: Coding Snippets on Tue Jun 02, 2009 5:24 am


About disabling cheats, I am witting it in Russian, I will do it in English later ...


А можно ли выключить определенные читы?

Открой сейв с читами в хекс-редакторе, навроде Hex Workshop, перейди на 149-й байт от начала и исправь этот байт с единицы на ноль. Теперь перейди в самый конец файла и посмотри на последние 4 байта. Это контрольная сумма сейва, используемая для контроля целостности. По сути представляет собой число, полученное алгоритмом Checksum-32 (сумма всех байтов файла). Чтобы сейв заработал после изменения, нужно уменьшить число контрольной суммы на 1. Например, у меня контрольная сумма: 4DB10101. Правильное число должно быть 4CB10101. Контрольную сумму можно посчитать и в самом Hex Workshop'e. Все, ты как будто никогда и не пользовался кодами.

Via Script



Для этого запиши 0 в адрес процедуры чита. Самый первый чит имеет индекс -429954:


Code:

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


следующий чит будет иметь индекс -429953 и т.д. ID нужного чита можно узнать тестированием через мод. Grin Smile

View user profile http://gtamodding.com

4 Re: Coding Snippets on Tue Jun 02, 2009 11:40 am



----------------------------
Русский язык
----------------------------

Код для записи случайного актера / машины / объекта в переменную.

Изначально был написан PLPynton'ом.

Код принимает 4 параметра для поиска: координаты XYZ места, откуда начинать поиск, и радиус поиска.
Если в данном радиусе есть любой прохожий, машина или объект (это особенно прикольно, можно получить управление например над фонарным столбом :-) ), код записывает в переменную 9@ его хендл (который может использоваться в других опкодах). Если никого нет - возвращается -1 (0xFFFFFFFF). Код игнорирует игрока и его машину.

При циклическом поиске, можно делать что-то вроде "искать следующего". Для этого в переменную 21@ нужно записать хендл предыдущего найденного актера / машины / объекта и при следующем поиске они будет пропущены. (для этого нужно раскомментировать участок кода в блоке AIC_NEWSEARCHRADIUS.

Работает только на версии 1.0.

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

Код легко переносится на SAMB, нужно поменять только метки и тип aDMA (& -> $).

----------------------------
English language
----------------------------

A code to get the handle of the nearest random ped / car / object to a variable.

The script was originally by PLPynton, Seemann 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, or object, whatever you want) in this radius, the code stores. its handle in variable 9@.
Otherwise it returns -1 (0xFFFFFFFF). 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 San Andreas Mission Builder also. Only labels and aDMA (&) should be converted (@ -> JJ, & -> $).

The code works for game version v1.0 only.


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@ = 20.0
       
        gosub @AIC_GETOBJECT
        if
                9@ <> -1
        then
                Marker.Disable($m2)
                Marker.CreateAboveObject($m2, 9@)
                wait 1000
                Object.Destroy(9@)
        end     
end


Вот оптимизированная версия с использованием опкодов CLEO:

(Here is a optimized version using CLEO opcodes:)


Code:

{   
    The Interceptor 1.1
     
    by PLPynton and Seemann   

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

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

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

:AIC_GETOBJECT
0006: 16@ = 305871
0006: 5@ = @AIC_TESTOBJECTHANDLE
0006: 6@ = 412

:AIC_STARTSEARCH
008B: 16@ = &0(16@,1i) // CPool*
0AB1: call_scm_func @AIC_READMEMOFFSET 2 ( 16@ + 8 )^ = 7@  // CPool.Size
0A8D: 11@ = read_memory 16@ size 4 virtual_protect 0        // CPool.pUnits
0006: 9@ = -1
0006: 10@ = 0

:AIC_SEARCHLOOPMAIN
0AB1: call_scm_func @AIC_READMEMOFFSET 2 ( 11@ + 20 )^ = 4@  // xyz*
8039:  not  4@ == 0
004D: jump_if_false @AIC_SEARCHLOOPNEXT
0AB1: call_scm_func @AIC_READMEMOFFSET 2 ( 4@ + 48 )^ = 12@  // x
0AB1: call_scm_func @AIC_READMEMOFFSET 2 ( 4@ + 52 )^ = 13@  // y
0AB1: call_scm_func @AIC_READMEMOFFSET 2 ( 4@ + 56 )^ = 14@  // z
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) // counter
0AB1: call_scm_func @AIC_READMEMOFFSET 2 ( 16@ + 4 )^ = 4@ // CPool.flags
005A: 4@ += 9@ // (int)
0A8D: 4@ = read_memory 4@ size 1 virtual_protect 0
0012: 9@ *= 256
005A: 9@ += 4@ // (int)
0002: jump 5@

:AIC_TESTVEHICLEHANDLE
056E:  is 9@ valid_vehicle_handle
004D: jump_if_false @AIC_NOHANDLE
00D6: if or
003B:  8@ == 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
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@ += 6@ // (int)
000A: 10@ += 1
002D:  10@ >= 7@ // (int)
004D: jump_if_false @AIC_SEARCHLOOPMAIN
0051: return

:AIC_READMEMOFFSET
0A8E: 0@ = 0@ + 1@ // int
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0AB2: ret 1 0@


View user profile http://gtamodding.com

5 Re: Coding Snippets on Sun Aug 02, 2009 2:18 am



Some more snippets:

1. You can write some short sentences on the screen of the game with this snippet. You should write using Latin letters - Cyrillic will not work (i.e. write "Ya" instead of "Я", and so forth).


Code:


{$CLEO} 

wait 2000
0A9F: 0@ = current_thread_pointer
0@ += 0x10
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0@ -= @Buffer     

while true
wait 100 
0AB1: call_scm_func @GetStringL 1 0x969110 1@ 
0AB1: call_scm_func @CopyStringWR 3 0x969110 0@ 1@   
0AA5: call 0x69F0B0 num_params 4 pop 4 0 0 100 0@   
end

:GetStringL
repeat
0A8D: 1@ = read_memory 0@ size 1 virtual_protect 0
000A: 0@ += 1
000A: 2@ += 1
until 1@ == 0
000A: 2@ += -1
0AB2: ret 1 2@

:CopyStringWR 
2@ -= 1
for 5@ = 2@ downto 0 do               
0A8E: 4@ = 0@ + 5@
0A8D: 3@ = read_memory 4@ size 1 virtual_protect 0
0A8C: write_memory 1@ size 1 value 3@ virtual_protect 0
000A: 1@ += 1
end
0A8C: write_memory 1@ size 1 value 0 virtual_protect 0   
0AB2: ret 0

:Buffer
hex
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
end


2. -- English (disable cheats) --

To do this write 0 to the index to disable the cheat. The first cheat index is -429954:


Code:

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


and so the next index would be -429953 etc. ID of the cheat can be found through testing.

3. Well, is another way to change the GXT entry's - the other two ways I posted before - works only in the main.scm of course.


Code:

gosub @EditGXTEntries

....

:EditGXTEntries 
  0@ = -429863
  &0(0@,1i) = 0xA49965
  &0(0@,1i) += @__hexadecimal
  02EC: run_asm_injection @__gxtentry @__newgxt
 
  :__hexadecimal
  hex
  72 05 00 51 00 8B 05 7C 3C A4 00
  05 63 99 A4 00 50 B9 40 B3 C1 00
  B8 50 00 6A 00 FF D0 8B 15 80 3C
  A4 00 81 C2 64 99 A4 00 52 50 B8
  60 86 71 00 FF D0 83 C4 08 C3 
  end
  :__newgxt
  0900: "Carl, come here, man."
  :__gxtentry 
  0900: 'yaukom2'


4. Setup swim hook:


Code:

0A8C: write_memory 0x005E82F7 size 1 value 0 virtual_protect 1



_________________
Some links for modding information:
• GTAModding Wiki
• Документация по моддингу GTA
• Sanny Builder (Русский)
• Sanny Builder Profile

View user profile http://gtamodding.com

6 Re: Coding Snippets on Sun Aug 09, 2009 7:07 am



Showing text is very easy, but you don't need to edit the GXT file or make a FXT file in order to show text. You can put the text in your self-made script instead of.

1. Pick what kind of text you want to show and get the address of it. List:


Code:

ShowTextBox = 0x588BE0
ShowTextBoxWithNumbers = 0x69DE90
ShowStyledText = 0x69F2B0
ShowStyledTextWithNumbers = 0x69E5F0
ShowTextLowPriority = 0x69F0B0
ShowTextLowPriorityWithNumbers = 0x69E360
ShowTextHighPriority = 0x69F1E0
ShowTextHighPriorityWithNumbers = 0x69E4E0


Addresses are for .exe version v1.0.

2. Read the address which is needed from the memory:


Code:

0A9F: 30@ = current_thread_pointer 
30@ += 0x10
0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0


3. Calculate the absolute address of the text in game memory,


Code:

30@ -= @MyCustomText1


4. Call one of the addresses we got before, to show our text:


Code:

0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 30@ // show text_box


5. Write the text using the hex..end structure:


Code:

hex
"My Text Here" 00
end


If you are not using the hex..end structure, but another for example opcode 0900, you need to skip 4 bytes after number 3, so it points directly to the first letter


Code:

30@ += 4


Also add 0000 to the text of the text.

Like this:


Code:

0A9F: 0@ = current_thread_pointer
0@ += 0x10
0A8D: 0@ = read_memory 0@ size 4 virtual_protect 0
0@ -= @Mytext
0@ += 4
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

0a93: end_custom_thread

0900: "My text here ..."
0000:


When using the hex..end method the skiping 4 bytes is not needed because there's none to skip (not a opcode), and also no null-terminator, but '00' is needed at the end of your text.


Code:

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

0A93: end_custom_thread

:Text
hex
"Your text here" 00
end


6. For ways of displaying text see the SA Memory Topic.

7. If you want to write in Russian you can, but same rule apply's - you need to use yelmi's RustoGXTCoder - write your sentence in Russian in the tool, then use the tool to translate it into a needed form in order for the game to display what you actually wrote (as you can't just write normally - the game does not support it).

For example:


Code:

:Text
hex
"CЈacњ—o, Kapћ!" 00
end


= Спасибо Карл!

Hexadecimal form:


Code:

hex
 43 A3 61 63 9C 97 6F 2C 5F 4B 61 70 9E 21 00
end


There are sometimes strange (de)compiling problems though, when you do Russian texts in a script file, using the show_text via script method - I don't know the reason.

8. You can use the const..end function to test them quickly:


Code:

const
ShowTextBox = 0x588BE0
ShowTextBoxWithNumbers = 0x69DE90
ShowStyledText = 0x69F2B0
ShowStyledTextWithNumbers = 0x69E5F0
ShowTextLowPriority = 0x69F0B0
ShowTextLowPriorityWithNumbers = 0x69E360
ShowTextHighPriority = 0x69F1E0
ShowTextHighPriorityWithNumbers = 0x69E4E0
end


then choose one:


Code:

0AA5: call ShowTextBox num_params 4 pop 4 0 0 0 30@


9. The texts (source) should go after the script. As it is NOT the script which reads it, but the pointer:


Code:

000E: 30@ -= @Text


For example end your test thread (like in examples above (there for CLEO)). Then put the text source(s).


10. If you don't have CLEO installed, and want to do this in the main.scm file, use a ASM injector, like the example in the second post of this topic, and change the show text_box address to a different address, as already explained.

11. Strings (if there too long) will go off screen, in order to correct this you need to start a new line. In order to do this put ~n~ before you write the new line. Spaces can be applied in the hex..end method using '_' (without the quotes).



Code:

:Text
hex
"Umm, I don't know, man ... ~n~ Where is Carl?" 00
end



= Umm, I don't know, man ...
Where is Carl?


12. So text does not get displayed in UPPER-CASE, just set the Sanny Builder -> Options -> "Case Converting" to 'As is'! Text will then appear how the user writes it.


13. Seemann implemented \s constant which is extra space within the string. So, the line "Sanny \s\s\s\ Builder" have to be displayed as


Code:

"Sanny    Builder"  // 5 spaces


in-game.

Single space between the words is also supported.

Since SB 2.98, Sanny Builder supports the single quotes within "", and the double quotes within ''
(for example: "'single'", '"double"').

14. Check the game version, using the CLEO opcode 0AA9, the addresses different in .exe versions, so use this so if the game is v1.0 use the correct address, and if false use the other address correct for that version (the code is used as a condtional opcode).


Code:

0AA9:  is_game_version_original


An example:


Code:

if
    0AA9:  is_game_version_original // is v1.0
then // true
    0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 30@ // call text_box for v1.0
else // false
    0AA5: call 0x5893B0 num_params 4 pop 4 0 0 0 30@ // call text_box for v1.01
end // end loop


This code will work and display the text_box correctly not matter what version of .exe your using (1.0 or 1.01).

15. If you want to create a custom file, when you want to display the text_box (or any type of text) just write,


Code:

0A92: create_custom_thread "Function_CallText.s" 30@


30@ is passed to the thread as the parameter, create a new file with this name (Function_CallText) put the part which shows the text in it, then end the thread. Save this file with the extension .s and put into the CLEO folder, now in the .cs/.cm file when you want to display a text just create that thread.


Code:

0A9F: 30@ = current_thread_pointer
30@ += 0x10
0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
000E: 30@ -= @Text

0A92: create_custom_thread "Function_CallText.s" 30@ 

:Text
hex
"My Text" 00
end


The .s file will just contain the text display, like this for example:


Code:

{$CLEO .s}

wait 0
if
    0AA9:  is_game_version_original
then
    0AA5: call 0x588BE0 num_params 4 pop 4 0 0 0 30@
else
    0AA5: call 0x5893B0 num_params 4 pop 4 0 0 0 30@ 
end

0A93: end_custom_thread


16. If it's just a test script or something, and you want the thread to be only executed once, you can add this opcode to the start of your script file (.cs-file):


Code:

0A95: enable_thread_saving


If you don't know about this opcode, read in Sanny Builder -> Help -> CLEO 3 opcodes.

--

Peace. Grin Smile

EDIT: Corrected some mistypes.



Last edited by gtasbigfoot on Sat Aug 15, 2009 9:57 am; edited 1 time in total


_________________
Some links for modding information:
• GTAModding Wiki
• Документация по моддингу GTA
• Sanny Builder (Русский)
• Sanny Builder Profile

View user profile http://gtamodding.com

7 Re: Coding Snippets on Wed Aug 12, 2009 10:46 am



There is a example of how to read a vehicles nitro state by script, it's easily done, get the structure of the vehicle in-game memory using CLEO opcode 0A97, add the memory offset where it's kept at (2424) and read it.


Code:

0A97: 3@ = car 1@ struct
000A: 3@ += 2424 // 0x978
0A8D: 4@ = read_memory 3@ size 1 virtual_protect 0


You should get the player's vehicle and the nitro component of the nitro (component 8, if you did not know).


Code:

03C0: 1@ = actor $PLAYER_ACTOR car
096D: get_car 1@ car_component 8 on_slot 2@


Example script, wrote quickly:


Code:

{$CLEO}
0000:

:Nitro_01
while true
wait 250
if
  Player.Defined($PLAYER_CHAR)
then
    if and
        $ONMISSION == 0
        Actor.Driving($PLAYER_ACTOR)
    then
          break
          end
    end
end


:Nitro_02
while true
wait 0
if
  Player.Defined($PLAYER_CHAR)
then
    break
    end
end
077E: get_active_interior_to 0@
    if and
        $ONMISSION == 0
        0@ == 0
        Actor.Driving($PLAYER_ACTOR)
    then
        03C0: 1@ = actor $PLAYER_ACTOR car
        096D: get_car 1@ car_component 8 on_slot 2@ // -- Nitro
    end


if
    8039:  not  2@ == 0xFFFFFFFF // -1
then
    if
        Actor.InCar($PLAYER_ACTOR, 1@)
    then
        0A97: 3@ = car 1@ struct
        000A: 3@ += 2424
        0A8D: 4@ = read_memory 3@ size 1 virtual_protect 0
        03F0: enable_text_draw 1
        045A: text_draw_1number  250.0  40.0 'NUMBER' 4@   
            end
        end
jump @Nitro_02

:Nitro_03
01C3: remove_references_to_car 1@  // Like turning a car into any random car
jump @Nitro_01


Maybe useful - if you're making some kind of racing-system or something.


_________________
Some links for modding information:
• GTAModding Wiki
• Документация по моддингу GTA
• Sanny Builder (Русский)
• Sanny Builder Profile

View user profile http://gtamodding.com

8 Re: Coding Snippets Today at 7:52 pm

Sponsored content


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

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