Coding

 Reply to this postStart new topic

Files parsing

Sweet
post Jan 11 2011, 11:04 AM
Post #1


Ameteur Member

Posts: 48
Joined: 19-August 10



Hi thar, a question here.
Im making the mod, its kinda of new AI system programming.
I have text file, and some commands in it, i need to read file and if it's not empty and have more than 0 cmds, then parse file.

CODE
{$CLEO .cs}
0000: NOP

:AIINC
thread "AIINC"

:AIINC_0
wait 0
if
  0ADC: test_cheat "AI"
jf @AIINC

:AIINC_1
wait 0
if
  0AAB:  file_exists "CLEO\script.txt"
jf @AIINC_1_f
jump @AIINC_1_t

:AIINC_1_f
0ACE: show_formatted_text_box "Instructions file not found or invalid!"
wait 1000
jump @AIINC_0

:AIINC_1_t
wait 0
if
  0A9A: 0@ = openfile "CLEO\script.txt" mode "rb" // IF and SET
jf @AIINC_1_f
1@ = 1 // file opened var

:AIINC_1_t_a
04C4: store_coords_to 27@ 28@ 29@ from_actor $PLAYER_ACTOR with_offset 0.0 3.0 1.0
30@ = actor.Create(Special,#MALE01,27@,28@,29@)

///////////////////////////////////////////
// Parse file                            //
///////////////////////////////////////////

:AIINC_2
wait 0
if
0ADA: 5@ = scan_file 0@ format "kill(%d,%d)" 6@ 7@ //IF and SET
then
jf @AIINC_2_f
if
  5@ > 0
then
05E2: AS_actor 6@ kill_actor 7@
else
if
0ADA: 5@ = scan_file 0@ format "give(%d,%d)" 6@ 7@ //IF and SET
jf @AIINC_2_f
if
  5@ >
then
01B2: give_actor 6@ weapon 7@ ammo 999999
else
jump @AIINC_2_f
end
end
end_thread

:AIINC_2_f
0ACE: show_formatted_text_box "Instructions file ended!"
wait 1000
jump @AIINC_0

This code gets crash when i type "AI". It creates actor and crashes... Tried alot variants of different things, nothing helps.
My suspiction on the 0ADA opcode, i think i misunderstand it as is.
Go to the top of the page
 
+Quote Post
Deji
post Jan 11 2011, 03:54 PM
Post #2


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



SANNY
  5@ >

Where's the other param?

Anyway, I usually use SA Functions when parsing files, but CLEO 4's scan_string might be useful in this situation.


For me, this works fine:
SANNY
{$CLEO}
const
  LineBuffer = 0xB71848
end
{
  As I suggested, opening files with a hex mode makes them open in CLEO 3
  mode, which enables their handles to be passed to GTA functions without
  crashes. Here 0x72 represents 'r'. The hex of the strings are usually
  backwards ('br' instead of 'rb').
}

0A9A: 0@ = openfile "test.txt" mode 0x72
0AC8: 1@ = allocate_memory_size 24   // max command length

while true
    wait 0
    if
        0AB1:   @GetConfigLine 1 {hFile} 0@  // saves us having to read 512 bytes and check if they're commented, etc.
    then
        if
            0AD4: 2@ = scan_string LineBuffer format "kill(%d,%d)" 3@ 4@
        then
            if
                0039:   2@ == 2 // check all 2 params were found - use 0019 for a "minimum" param thing.
            then
                0AD1: show_formatted_text_highpriority "kill(%d,%d)" time 2000 3@ 4@    // print out for debugging
            end
        end
        if
            0AD4: 2@ = scan_string LineBuffer format "give(%d,%d)" 3@ 4@
        then
            if
                0039:   2@ == 2
            then
                0AD1: show_formatted_text_highpriority "give(%d,%d)" time 2000 3@ 4@
            end
        end
    end
end

:GetConfigLine
{
    0AB1:   call_scm_func @GetConfigLine 1 TEMP_1
    
    Params
      0@    - File Handle
    
    Returned
      True  - Valid config line returned
      False - Operation failed or end of file reached
}

if
    8AD6:   not end_of_file 0@ reached
then
    0A8C: write_memory 0xB71848 size 0x200 value 0 virtual_protect 0
    while 0AD7:   read_string_from_file 0@ to 0xB71848 size 0x200
        0A8D: 2@ = read_memory 0xB71848 size 1 virtual_protect 0
        if and
            8039:   not 2@ == 0xA   // \n (line empty)
            8039:   not 2@ == 0xD   // \r (line empty)
            8039:   not 2@ == 0x23  // #  (comment)
            8039:   not 2@ == 0x3B  // ;  (comment)
        then
            0006: 3@ = 1
            break
        end
    end
end
0039: 3@ == 1
0AB2: ret 0


I skipped a few steps, but it should show how it can work pretty well. The GetConfigLine SCM Func replicates a GTA Function with the same purpose, but has the ability to check whether lines are commented or empty and skip them.

You should be finished with "LineBuffer" by the time the next "wait 0" is run (or the next inexistant opcode in SA range, etc).


--------------------
Go to the top of the page
 
+Quote Post
Sweet
post Jan 11 2011, 06:01 PM
Post #3


Ameteur Member

Posts: 48
Joined: 19-August 10



Is it needeed to be finished? Im only getting crash after launch.

This post has been edited by Sweet: Jan 11 2011, 06:04 PM
Go to the top of the page
 
+Quote Post
Deji
post Jan 11 2011, 06:29 PM
Post #4


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



Hmm, just noticed this:

SANNY
:AIINC
thread "AIINC"

:AIINC_0
wait 0
if
  0ADC: test_cheat "AI"
jf @AIINC


For starters, you don't need to name your thread if you have 0000: (or any other code) before the first label... I believe CLEOs are given their filename as a default thread name anyway.

Change jf @AIINC to jf @AIINC_0.

0AAB probably isn't needed. Since attempting to open a file will return true/false depending on the file existing anyway.


Low construct looses me tongue.gif


--------------------
Go to the top of the page
 
+Quote Post
Sweet
post Jan 12 2011, 11:56 AM
Post #5


Ameteur Member

Posts: 48
Joined: 19-August 10



I'm about code that you give for example. It's not works even with changes, even don't say about my code... crazy thing tongue.gif
Go to the top of the page
 
+Quote Post
Deji
post Jan 12 2011, 02:51 PM
Post #6


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



I don't understand...


--------------------
Go to the top of the page
 
+Quote Post
Sweet
post Jan 12 2011, 05:02 PM
Post #7


Ameteur Member

Posts: 48
Joined: 19-August 10



I mean your example code you posted first, crashes anyway.
And my english is poor sad.gif
Go to the top of the page
 
+Quote Post
Deji
post Jan 12 2011, 05:39 PM
Post #8


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



Hmm.. Any error report? Works fine for me, with "test.txt" created in the main GTASA directory:
CODE
kill(1,6)


Which version of GTASA do you have? It could be the position of the line buffer that's causing problems.


--------------------
Go to the top of the page
 
+Quote Post
Sweet
post Jan 13 2011, 09:49 AM
Post #9


Ameteur Member

Posts: 48
Joined: 19-August 10



Oh wait... why
QUOTE
kill(1,6)

Why just 1 and 6? There's should be a variables of the actor (first val, 1@) who has to kill another actor (second val, 2@).
Go to the top of the page
 
+Quote Post
Deji
post Jan 13 2011, 03:19 PM
Post #10


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



Umm... if you read "2@" from a file, you will just be reading plain text, not an actor handle.

I would have assumed you planned on setting up an array of actors, using the numbers in the file as an index. Or give the actors names. 1 and 6 were just some random integers for the code to display.

You can't put actor handles in a file because they are different every time.


--------------------
Go to the top of the page
 
+Quote Post
Silent
post Jan 13 2011, 03:25 PM
Post #11


The master of cut retort

Group Icon

Posts: 239
From: Warsaw, PL
Joined: 21-July 10



@Deji

Damn you, you were faster!!!!!111111111

Oh, just noticed that you want to define variables using this? Your code won't work then, because script will try to work on actor 1 and 6, not 1@ and 6@.

Try this instead, I've combined both yours and Deji's script.

SANNY
{$CLEO}

const
    LineBuffer  = 0xB71848
end

thread "AIINC"

:AIINC
wait 0
if
  0ADC: test_cheat "AI"
jf @AIINC
if
    0A9A: 0@ = openfile "CLEO\script.txt" mode 0x72 // IF and SET
then
    04C4: store_coords_to 27@ 28@ 29@ from_actor $PLAYER_ACTOR with_offset 0.0 3.0 1.0
    009A: 30@ = create_actor_pedtype 23 model #MALE01 at 27@ 28@ 29@
    
    ///////////////////////////////////////////
    // Parse file                            //
    ///////////////////////////////////////////
    
    :AIINC_2
    wait 0
    if
        0AB1:   @GetConfigLine 1 {hFile} 0@  // saves us having to read 512 bytes and check if they're commented, etc.
    then
        if
            0AD4: 5@ = scan_string LineBuffer format "kill(%d,%d)" 6@ 7@
        then
            if
                0039:   5@ == 2
            then
                05E2: AS_actor 0@(6@,1i) kill_actor 0@(7@,1i)
            end
        end
        if
            0AD4: 5@ = scan_string LineBuffer format "give(%d,%d)" 6@ 7@
        then
            if
                0039:   5@ == 2
            then
                01B2: give_actor 0@(6@,1i) weapon 0@(7@,1i) ammo 999999
            end
        end  
        jump @AIINC_2
    end
    0ACE: show_formatted_text_box "Instructions file ended!" // As there's a jump just before 'end', it will work like a if...then...else...end construct.
    009B: destroy_actor 30@
    0A9B: closefile 0@
else
    0ACE: show_formatted_text_box "Instructions file not found or invalid!"
end
jump @AIINC

:GetConfigLine
{
    0AB1:   call_scm_func @GetConfigLine 1 TEMP_1
    
    Params
      0@    - File Handle
    
    Returned
      True  - Valid config line returned
      False - Operation failed or end of file reached
}

if
    8AD6:   not end_of_file 0@ reached
then
    0A8C: write_memory 0xB71848 size 0x200 value 0 virtual_protect 0
    while 0AD7:   read_string_from_file 0@ to 0xB71848 size 0x200
        0A8D: 2@ = read_memory 0xB71848 size 1 virtual_protect 0
        if and
            8039:   not 2@ == 0xA   // \n (line empty)
            8039:   not 2@ == 0xD   // \r (line empty)
            8039:   not 2@ == 0x23  // #  (comment)
            8039:   not 2@ == 0x3B  // ;  (comment)
        then
            0006: 3@ = 1
            break
        end
    end
end
0039: 3@ == 1
0AB2: ret 0


This post has been edited by Silent: Jan 13 2011, 03:25 PM
Go to the top of the page
 
+Quote Post
Sweet
post Jan 13 2011, 05:47 PM
Post #12


Ameteur Member

Posts: 48
Joined: 19-August 10



Well, it's not crashes, this is good smile.gif
But have not works too. But it tells that instruction file ended, even if i write something sad.gif
Go to the top of the page
 
+Quote Post
Deji
post Jan 13 2011, 06:24 PM
Post #13


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



What did you write? It will always say the file has ended after it has finished processing all the commands (which will only take a millesecond or two).


You could add a wait command like this:
SANNY
        if
            0AD4: 5@ = scan_string LineBuffer format "wait(%d)" 6@
        then
            if
                0039:   5@ == 1
            then
                0ACA: show_text_box "Waiting..."
                wait 6@
            end
        end


Shows a text box just for confirmation that the code is working.


--------------------
Go to the top of the page
 
+Quote Post
Sweet
post Jan 14 2011, 09:22 AM
Post #14


Ameteur Member

Posts: 48
Joined: 19-August 10



Well that is works. But how to get working what was above? Reading task to actor from file with some parametres?
The problem is, as far as i understand, game won't read params, insted making them just like variables.

UPD:
I've tried out what game will print if i use local var in text.
CODE
        if
            0AD4: 5@ = scan_string LineBuffer format "kill(%d)" 6@
        then
            if
                0039:   5@ == 1
            then
                0ACE: show_formatted_text_box "Task kill: %d" 6@
                wait 1500    
            end
        end

This, shows: "Task kill: 30"
Text file has: "kill(30@)"
So, i just need to add at the end of var value, @ symbol.

This post has been edited by Sweet: Jan 14 2011, 09:31 AM
Go to the top of the page
 
+Quote Post
Deji
post Jan 14 2011, 02:14 PM
Post #15


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



I fail to understand what you're trying to achieve... Anything in the text file is plain text, so you can easily add the symbol to the end of the string yourself. Reading it wouldn't make a difference. You can't use variables in a text file. Nor can a script read the text and treat it like a variable.

The best you can do is read an integer and use it as the index for an array, allowing you to access any variable indirectly.


--------------------
Go to the top of the page
 
+Quote Post
Sweet
post Jan 15 2011, 05:28 PM
Post #16


Ameteur Member

Posts: 48
Joined: 19-August 10



I've tried by myself the variant with adding symbol at the end of string, but failed. It's like needs to get offset to var, then by using 'hex ... end' construction add symbol '@' (40 in hex) and then... What then? Say me i'm wrong smile.gif
Go to the top of the page
 
+Quote Post
Deji
post Jan 15 2011, 07:25 PM
Post #17


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



I already told you.. use arrays to get the offset from the first actor variable.


--------------------
Go to the top of the page
 
+Quote Post
Reply to this postStart new topic

1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members: