Is your question, can I check if another CS-file has started through a CM-file?
Opcode 0ABA ends a custom thread. It's like that of 0459, with the only difference it's made to end CLEO-scripts.
I will answer all the things which are in this category of thread questions.
1. To check if another thread is active with specifyed name, use the CLEO opcode 0AAA.
- Code:
while true
wait 250
0AAA: 0@ = thread 'TEST' pointer
if
0@ > 0 // true if thread/mission 'TEST' is running
then
....
end
end // while true
2. To create a thread, which is not loaded until you create it through a CS/CM-file, give the file the extention ".s".
3. Threads can be ended through the end_thread opcodes. Use opcode 0ABA to end a CLEO-script with this name, and use 0459 to end a script in the main.scm file.
4. You can put mutli-threads in one CS-file by using the using create_custom_thread with parameters. Like the SCM opcode create_thread the CLEO version allows up to 34 parameters in total.
- Your CS-files name must be the same as the parameter of the create_custom_thread opcode.
- Select the threads using a check right at the top of your script, using create_custom_thread with parameters:
- Code:
0A92: create_custom_thread "TestScript.cs" 1
the 2 parameter (1) in the opcode above ^ gives the value of the local variable 0@ in the thread which get started.
Here is an example script:
- Code:
if
0@ == 0
then
0A92: create_custom_thread "TestScript.cs" 1
0A92: create_custom_thread "TestScript.cs" 2
0A92: create_custom_thread "TestScript.cs" 3
// here goes thread 1
03A4: name_thread 'Thread1'
....
end
if
0@ == 1
then
// here goes thread 2
03A4: name_thread 'Thread2'
....
end
if
0@ == 2
then
// here goes thread 3
03A4: name_thread 'Tread3'
....
end
if
0@ == 3
then
// here goes thread 4
03A4: name_thread 'Thread4'
....
end
0A93: end_custom_thread // all done!
0@ is equal to 0 at start of TestScript.cs by default.
5. Pass on parameters to other threads simply by adding them to the create_thread line. Like this:
- Code:
// create car with local var 1@
0A92: create_custom_thread "MyCustomThread.s" 1@ // the cars var passed on to the thread "MyCustomThread.s".
You can do the same in the main.scm, but use the opcode 004F.
6. In CS-files we can only use locals in range of 0@..33@
This is solved using a global variable, but that causes problems.
We have more space to the threads in advance, to save the variables to write directly to the memory.
It is difficult to operate.
However, it is very convenient to be able to increase the space to fit as much memory in the thread.
- Code:
for 0@ = 0 to 9
0093: 1@ = integer 0@ to_float
04C4: store_coords_to 5@ 6@ 7@ from_actor $PLAYER_ACTOR with_offset 0.0 1@ 0.0
0107: 2@ = create_object #KNIFECUR at 5@ 6@ 7@
gosub @get_pointer
0085: 4@ = 0@ // (int)
0012: 4@ *= 4
005A: 30@ += 4@ // (int)
0A8C: write_memory 30@ size 4 value 2@ virtual_protect 0
04C4: store_coords_to 5@ 6@ 7@ from_actor $PLAYER_ACTOR with_offset 0.0 0.0 1@
0107: 3@ = create_object #KATANA at 5@ 6@ 7@
gosub @get_pointer
0085: 4@ = 0@ // (int)
0012: 4@ *= 4
005A: 30@ += 4@ // (int)
000A: 30@ += 40
0A8C: write_memory 30@ size 4 value 3@ virtual_protect 0
end
wait 2000
for 0@ = 0 to 9
gosub @get_pointer
0085: 4@ = 0@ // (int)
0012: 4@ *= 4
005A: 30@ += 4@ // (int)
0A8D: 2@ = read_memory 30@ size 4 virtual_protect 0
if
03CA: object 2@ exists
then
0108: destroy_object 2@
end
gosub @get_pointer
0085: 4@ = 0@ // (int)
0012: 4@ *= 4
005A: 30@ += 4@ // (int)
000A: 30@ += 40
0A8D: 3@ = read_memory 30@ size 4 virtual_protect 0
if
03CA: object 3@ exists
then
0108: destroy_object 3@
end
end
:get_pointer
0A9F: 30@ = current_thread_pointer
000A: 30@ += 0x10
0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
000E: 30@ -= @pool
return
:pool
hex
//2@ - knife pool - 40byte
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
//3@ - katana pool - 40byte
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
end
1-M in front of the player is a knife and a blade at intervals of 10 units above the 1-M interval 10 a piece, extinguish all code after two seconds. Eight variables are used.
We have put a simple explanation for this case can be made with 24 variables.
Create a conversation area.
- 1. Count the number of variables you want to use.
- 2. 0 to 8 for one variable has to be written in hex..end structure
- 3. Variable used to remember the size using the
size 4 - 4. If we treat this type of counting the size of the first two types (40byte)
- Code:
:pool
hex
// 2@ - knife pool - 40byte
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
// 3@ - katana pool - 40byte
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
end
7. It's possible to pass a string to a new thread. Obviously you can't just write something like:
- Code:
create_thread @MyAnim "anim_name"
but you can do the following:
1. store the string to pass to a string variable (for example, 0@s, 0@v, s$var, v$var, etc; local variables are always preferable).
2. the string (the sequence of symbols) is now occupying 8 or 16 bytes of the variable storage. If you use a short string (@s, s$), then its length is 8 bytes; if a long string (@v, v$) - 16 bytes. Say, if you write this:
- Code:
1@s = 'THREAD1'
this does not mean that all the symbols ('T', 'H', 'R', 'E', 'A', 'D', '1') are stored in a single 1@ variable. A single variable can hold only 4 bytes of data. Each symbol takes exactly one byte, the whole 7-chars string 'THREAD1' will occupy.. guess how much?.. 7 bytes! (plus 1 byte is a null-terminator - a zero byte at the very end of a string). So, in our case the string will be stored in two variables: 1@ will contain first 4 symbols of the string (THRE) and the next variable (2@) will contain the rest (AD1). Long strings occupy up to 4 variables:
- Code:
1@v = "my_long_string" =>
1@ - my_l
2@ - ong_
3@ - stri
4@ - ng
If the string is shorter (say 2 symbols only, or even its empty one) it will still occupy 2 or 4 variables depending on its type:
- Code:
10@s = '123'
10@ - 123
11@ - nothing (just random or zero bytes)
- Code:
22@v = "gtaf"
22@ - gtaf
23@ - random/empty
24@ - random/empty
25@ - random/empty
So, one more important thing: you are normally not able to store strings in local variable 31@ and higher, as the rest of the string will be overwritten by the timers (32@/33@):
- Code:
31@ - 'string'
31@ - stri
32@ - ng -- this symbols will be lost later, as variables 32@ and 33@ due to its nature constantly change their values.
Same valid for the long strings. As you may already guess, you can not use any variables higher than 28@ for them:
- Code:
29@v = "my_long_string" =>
29@ - my_l
30@ - ong_
31@ - stri
32@ - ng --this will be lost
Global variables do not have such behaviour as there are no timers.
3. So, what about passing a string at last. You can pass the string by passing the values of the variables that contain the string content. Say you use:
- Code:
1@s = 'THREAD'
then you can pass this string as:
- Code:
create_thread @random 1@ 2@ // yahoo, the string is out
Then read the string in the "Random" thread as usually:
- Code:
:Random
03A4: name_thread 0@s //0@ is the first passed value, and s denoting its a string
With long strings:
- Code:
9@v = "THREAD"
...
create_thread @random 9@ 10@ 11@ 12@
....
:Random
03A4: name_thread 0@v
With global variables its harder to use this method as you need to know the ID the variable is compiled with. If its a DMA variable (with a numeric name), there's no problem at all:
- Code:
s$100 = 'string'
..
create_thread @random $100 $101
..
:Random
03A4: name_thread 0@s
But for the variables with custom names you should use the array trick:
- Code:
s$var = 'string'
0@ = 1 // index
create_thread @random $var $var(0@,1i)
...
:Random
03A4: name_thread 0@s
Note that you need local variables for the indexes, so it still better to use the first way (save the string to a local but not global var).
---
Note 1. This method might be applied not only to the newly created threads but also to scm functions
- Code:
1@s = 'string'
0AB1: call_scm_func @cmp 2 1@ 2@
..
:cmp
if
0@s == 'string' // compare the passed string with another one
then
...
end
0AB2: ret 0
Note 2. As this method is using string variables that may hold maximum 16 symbols, you can't pass a longer string in such a way (even if you pass it somehow, you still cant read it, as @s, @v, s$, v$ variables only work with 16 chars-max strings).
edit2 also it looks like theres a bug in the 2nd cleo you posted the one with the ped that shoots, kicks and then shoots again, if you kill the actor before he does the animation it has the player do the fight c ide animation then loops and looks up, but I can still pause it.
Yes. I did not test it for bugs - as it's not a MOD. Just an example code snippet to show you how to script it, like you asked me. It's because I did not check weather the actor is end or not, before CJ does this.
---
P.S. Do you have Microsoft Visual C++ 2008 Express Edition? If not you can download it from:
http://www.microsoft.com/rus/express/vc/
It's good to practice your programming skills, do you have knowleage in C/C++, ASM, LUA, and etc?