Help me with a script

Post » Fri May 27, 2011 6:06 am

Hello there,
I'm new to scripting and i've got a difficulty.
Tell me how to write text to a file and then read it.
With examples please.
Thanks. :)
User avatar
Dalia
 
Posts: 3488
Joined: Mon Oct 23, 2006 12:29 pm

Post » Fri May 27, 2011 4:27 pm

What now? Exactly what is your difficulty, if there is one in particular?
I don't exactly understand your question, so I'll advise you read GhanBuriGhan's scripting for dummies.
Just a shot in the dark.
User avatar
Kayla Keizer
 
Posts: 3357
Joined: Tue Dec 12, 2006 4:31 pm

Post » Fri May 27, 2011 5:13 pm

What now? Exactly what is your difficulty, if there is one in particular?

The difficulty is that in the help (MWSE_Scripting.html) given only the functions themselves (xFileWriteString&xFileReadString?) without examples.)
User avatar
Trevi
 
Posts: 3404
Joined: Fri Apr 06, 2007 8:26 pm

Post » Fri May 27, 2011 8:49 pm

Um...Porridge, MWSE scripting is not covered in MWSFD, because it's not part of regular Morrowind scripting and requires the external MWSE (or MGE) executable to function. In fact, there's very little documentation about it currently available. Please don't be rude and refrain from commenting like that on things you don't understand.

Here, I'm very new to MWSE myself, but Melian wrote me a wonderful script over at GHF, and it demonstrates reading and writing files, so I'll post it as an example here:

begin DHM_Alchemy_Table_Mainshort stateshort buttonshort addingr  ;add ingredients or remove them?;really longslong count  ;item countlong objtype  ;object typelong l1  ;temp/junk;stringslong filename  ;not necessary, but makes it easier to change if you wantlong objid  ;object ID (for inventory items);refslong destref  ;reference for who/whatever gets the ingredients at the endlong giveref  ;reference for who/whatever has the items to startlong invref  ;inventory item referencefloat f1  ;junk varif ( GetDisabled )    if ( GetJournalIndex "HT_EddieTable" >= 100 )        enable    endifelseif ( GetJournalIndex "HT_EddieTable" < 70 )    disableendifif ( MenuMode )    returnelseif ( OnActivate )    if ( state == 0 )        MessageBox "What do you want to do?" "Open container" "Add all ingredients" "Remove all ingredients" "Cancel"        set state to 1    endifelseif ( state == 1 )    set button to GetButtonPressed    if ( button == -1 )        return    elseif ( button == 0 )  ;open normally        activate        set state to 0    elseif ( button == 1 )  ;add all        set addingr to 1        set state to 2    elseif ( button == 2 )  ;remove all        set addingr to 0        set state to 2    else                    ;cancel        set state to 0    endif    returnendifif ( state < 2 )    returnendififx ( addingr )    setx destref to xGetRef "container_ID"    setx giveref to xGetRef "player"else    setx destref to xGetRef "player"    setx giveref to xGetRef "container_ID"endifsetx filename to xStringBuild "DHMAlchemyTable"  ;sets the filename variable to this stringxFileRewind filename                             ; - change to whatever you want, but no spaces!;next bit is finding out what ingredients have to be moved;and writing it to a file, so we can move them all at once;in the next blocksetx objid count objtype l1 f1 l1 invref to giveref->xContentList 0  ;gets the first item in inventorywhilex ( objid )    set l1 to ( objtype - 1380404809 )  ;ingredient    ifx ( l1 )  ;it's not an ingredient    else        xFileWriteString filename objid        xFileWriteLong filename count    endif    ifx ( invref )        setx objid count objtype l1 f1 l1 invref to giveref->xContentList invref  ;move on to the next item    else        set objid to 0  ;exit loop    endifendwhilexFileWriteString filename "null"  ;in case there aren't any ingredients in inventory;now we read the file back and do the actual adding and removing;xStringCompare will return 0 if the strings are the same;so use this to check when we've got to the end - otherwise weird things can happen!xFileRewind filenamesetx objid to xFileReadString filenamesetx l1 count to xFileReadLong filename 1setx l1 to xStringCompare objid "null"  ;check here too, in case there weren't anywhilex ( l1 )    giveref->xRemoveItem objid count    destref->xAddItem objid count    setx objid to xFileReadString filename    setx l1 count to xFileReadLong filename 1    setx l1 to xStringCompare objid "null"endwhileset state to 0end


I'm afraid I don't have time to explain how it all works, as far as I understand it, at the moment. But if you have specific questions, I'll be back online later.

The basic functions to write a file are xFileWriteString and xFileWriteLong, XFileReadString and xFileReadLong to read them back. Apparently xFileWrite/ReadFloat has issues, so you have to use xFileWrite/ReadLong instead.

All this does, "setx filename to xStringBuild "YOURFILENAME" is name the file name for easier referencing later. "filename" is a long variable here, and can be named whatever you want, but no spaces.
User avatar
MARLON JOHNSON
 
Posts: 3377
Joined: Sun May 20, 2007 7:12 pm

Post » Fri May 27, 2011 12:15 pm

Stuporstar Thanks a lot. This is a valuable example, but I still have many questions.
For example, my file Changelog.txt lies in directory "data files". How I will need to specify a file name with the ways before him.
The best way I could understand the simple example: text "bla-bla-bla" write in the file changelog.txt and then read it. :)
P.S. What's the difference between xFileWriteString and xFileWriteLong, as well as XFileReadString and xFileReadLong?
P.P.S. And what about the function xFileWriteText?
User avatar
Sabrina garzotto
 
Posts: 3384
Joined: Fri Dec 29, 2006 4:58 pm

Post » Fri May 27, 2011 9:27 pm

Stuporstar Thanks a lot. This is a valuable example, but I still have many questions.
For example, my file Changelog.txt lies in directory "data files". How I will need to specify a file name with the ways before him.
The best way I could understand the simple example: text "bla-bla-bla" write in the file changelog.txt and then read it.
P.S. What's the difference between xFileWriteString and xFileWriteLong, as well as XFileReadString and xFileReadLong?
P.P.S. And what about the function xFileWriteText?


I haven't looked into XFileWriteText. It may be the one you're looking for, but I don't know enough to be able to tell you. Perhaps an expert will drop in and explain.

As for Strings vs. Longs, it just refers to the type of variable you are writing. You're probably familiar with longs, at least a little bit, from regular Morrowind scripting. They are large strings of numbers. A string on the other hand, is a set of characters, which is added functionality available only with script extenders. A string allows you to use things like names (such as cell names, or object IDs) and write them to a variable, which opens up whole new avenues of scripting capabilities all on its own.

You'll notice that the string variables are called longs at the beginning of the script. I don't know the inner workings of MWSE, but it uses these longs as strings or longs depending on how you use them.

One thing you'll notice in that script is the f1 junk float variable. This one is called separately from the l1 long junk variable, because apparently writing a float number (in this case it's grabbing the weight of the object, which is extraneous info so it's junked) as a long can cause instability in the script. So if you need to use floats (numbers with decimals), then call it as a float at the beginning of the script...but use xFileWriteLong to write them into a file if you're going to use the float variable.
User avatar
Mimi BC
 
Posts: 3282
Joined: Sat Oct 07, 2006 10:30 pm

Post » Fri May 27, 2011 7:55 pm

@Stuporstar Thank you for the explanation. And do you know about the paths listed in the file name?
User avatar
Alisia Lisha
 
Posts: 3480
Joined: Tue Dec 05, 2006 8:52 pm

Post » Fri May 27, 2011 3:00 pm

No, I'm afraid that's a little beyond my expertise at this point. I'm mainly explaining what I know so that I can understand it better, as I'm just learning MWSE myself. I've been using regular Morrowind scripts for years, and have done some pretty great things within their limitations, but I finally hit the wall and decided I need MWSE to do more. If you don't get an answer here, try asking over in the MWSE forums at Great House Fliggerty. That's where all the experts hide out when they're not hanging around here. ;)
User avatar
hannaH
 
Posts: 3513
Joined: Tue Aug 15, 2006 4:50 am

Post » Fri May 27, 2011 5:53 am

I'll throw this out there. I doubt it will help in this case but it may be useful: http://www.tesnexus.com/downloads/file.php?id=20927. It has a couple more examples but I don't think I did anything with File IO.

Regarding the documentation, part of the issue is that the documentation is written by programmers with C experience so a lot more knowledge is assumed.

P.S. What's the difference between xFileWriteString and xFileWriteLong, as well as XFileReadString and xFileReadLong?
P.P.S. And what about the function xFileWriteText?


This is a bit beyond basic Morrowind Scripting, but C (a systems programming language) stores strings in arrays. Think of it like a one column table with a infinite number of rows. It is then possible to make up a string by storing a character in each row. The one problem was that there was no way to tell where the end of the string was. The solution in C was to append a null character (represented as `\0` in C). Hence a string ending in `\0` is refered to as a C style string. This isn't really useful when writing anything other than binary as `\0` (ASCII code 0 btw) isn't a representable character. If you don't need it human readable It does make it easier when reading multiple strings back as you know when one ends and the other starts.

xFileWriteString writes a C style string to a file.

xFileWriteText is a bit more like messageboxes, in that you can write text with a format (So you can include formatted numerical variables). If you want to write to a human readable text file this is probably the one you want.

The important thing to note about xFileWriteShort/Long/Float is that it writes the number in binary. If you want a human readable representation of the number use xFileWriteText.

Regarding the paths, it is relative to Data Files/MWSE.
User avatar
Fiori Pra
 
Posts: 3446
Joined: Thu Mar 15, 2007 12:30 pm

Post » Fri May 27, 2011 8:03 am

I'll throw this out there. I doubt it will help in this case but it may be useful: http://www.tesnexus.com/downloads/file.php?id=20927. It has a couple more examples but I don't think I did anything with File IO.

Regarding the documentation, part of the issue is that the documentation is written by programmers with C experience so a lot more knowledge is assumed.

This is a bit beyond basic Morrowind Scripting, but C (a systems programming language) stores strings in arrays. Think of it like a one column table with a infinite number of rows. It is then possible to make up a string by storing a character in each row. The one problem was that there was no way to tell where the end of the string was. The solution in C was to append a null character (represented as `\0` in C). Hence a string ending in `\0` is refered to as a C style string. This isn't really useful when writing anything other than binary as `\0` (ASCII code 0 btw) isn't a representable character. If you don't need it human readable It does make it easier when reading multiple strings back as you know when one ends and the other starts.


So is this why "null" is written after making multiple checks in inventory and such, because in such a case we don't know how many lines are written in the array?

ifx ( run )   setx filename to xStringBuild "BOHcoords"   xFileRewind filename   setx junk pX pY pZ pA to xFileReadLong filename 4   setx pcCell to xFileReadString filename      player->xPositionCell pX pY pZ pA pcCell      set run to 0endif


In this case, we know the file has four variables, so is that why filename 4 is called, so that it stops after the four variables instead of needing to return "null"? Melian also noted that in Read/Write Longs the first variable returns as the number of variables read, so it requires the junk variable at the beginning of the line.

xFileWriteString writes a C style string to a file.

xFileWriteText is a bit more like messageboxes, in that you can write text with a format (So you can include formatted numerical variables). If you want to write to a human readable text file this is probably the one you want.

The important thing to note about xFileWriteShort/Long/Float is that it writes the number in binary. If you want a human readable representation of the number use xFileWriteText.

Regarding the paths, it is relative to Data Files/MWSE.


Can you write files outside of the script and call them later (If you're using FileReadText), or does the file have to be written by a MWSE script?

I'm just trying to learn as much as I can here. My actual programming knowledge is very basic (as in I learned basic around the age of 8, and never really went further with it).
User avatar
Milagros Osorio
 
Posts: 3426
Joined: Fri Aug 25, 2006 4:33 pm

Post » Fri May 27, 2011 10:20 am

I'll throw this out there. I doubt it will help in this case but it may be useful: http://www.tesnexus.com/downloads/file.php?id=20927. It has a couple more examples but I don't think I did anything with File IO.

Regarding the documentation, part of the issue is that the documentation is written by programmers with C experience so a lot more knowledge is assumed.

This is a bit beyond basic Morrowind Scripting, but C (a systems programming language) stores strings in arrays. Think of it like a one column table with a infinite number of rows. It is then possible to make up a string by storing a character in each row. The one problem was that there was no way to tell where the end of the string was. The solution in C was to append a null character (represented as `\0` in C). Hence a string ending in `\0` is refered to as a C style string. This isn't really useful when writing anything other than binary as `\0` (ASCII code 0 btw) isn't a representable character. If you don't need it human readable It does make it easier when reading multiple strings back as you know when one ends and the other starts.

xFileWriteString writes a C style string to a file.

xFileWriteText is a bit more like messageboxes, in that you can write text with a format (So you can include formatted numerical variables). If you want to write to a human readable text file this is probably the one you want.

The important thing to note about xFileWriteShort/Long/Float is that it writes the number in binary. If you want a human readable representation of the number use xFileWriteText.

Regarding the paths, it is relative to Data Files/MWSE.

Thanks for the info and link. I'm going to experiment. :)
@Stuporstar You'll have to wait Yacoby. ;)
User avatar
stevie critchley
 
Posts: 3404
Joined: Sat Oct 28, 2006 4:36 pm

Post » Fri May 27, 2011 9:15 pm

I hope you don't mind me posting my own questions in your thread. I'm trying to figure out all the intricacies of file writing myself. :)
User avatar
~Sylvia~
 
Posts: 3474
Joined: Thu Dec 28, 2006 5:19 am

Post » Fri May 27, 2011 6:45 pm

I hope you don't mind me posting my own questions in your thread. I'm trying to figure out all the intricacies of file writing myself. :)

You're welcome, I don't mind. :)
One last question. Where can I read more detail about the use of technology texture hook in scripts?
User avatar
Miguel
 
Posts: 3364
Joined: Sat Jul 14, 2007 9:32 am

Post » Fri May 27, 2011 10:07 am

One last question. Where can I read more detail about the use of technology texture hook in scripts?
Probably on the http://sourceforge.net/apps/mediawiki/morrgraphext/index.php?title=Main_Page or the MGE thread. If you want more information you will have to dig around in the source code or ask LizTail. I don't use DirectX so am pretty useless at answering how it works.

From what I understand you can use MGE to change a texture and optionally to apply a fragment program (DirectX calls them shaders) to it. It allows you to do much more advanced effects that you would usually be able to do with the Morrowind engine.

So is this why "null" is written after making multiple checks in inventory and such, because in such a case we don't know how many lines are written in the array?

Yes, it is used as a unique string to know when to stop reading. I don't think it is really required as xFileReadString will return 0 if it cannot read the string. I would assume "cannot read the string" includes the case when the end of the file has been reached. Having said that it may be required if the file is not truncated every time it is used.

In other words, there are probably more elegant ways to tell if the end of the file has been reached. In this case the number of inventory items could have been stored as a variable in the script.

In this case, we know the file has four variables, so is that why filename 4 is called, so that it stops after the four variables instead of needing to return "null"?

Yes, as the length of the file is known there is no need to having anything indicating the end of the file.

Melian also noted that in Read/Write Longs the first variable returns as the number of variables read, so it requires the junk variable at the beginning of the line.

Yes, although you could probably use the number of items read to indicate if you have reached the end of the file or that an error occurred reading the file.


Can you write files outside of the script and call them later (If you're using FileReadText), or does the file have to be written by a MWSE script?

Yes, you can write a file using another program and then read them using MWSE.
User avatar
Shannon Marie Jones
 
Posts: 3391
Joined: Sun Nov 12, 2006 3:19 pm

Post » Fri May 27, 2011 4:06 pm

Probably on the http://sourceforge.net/apps/mediawiki/morrgraphext/index.php?title=Main_Page or the MGE thread.

I saw it. But I do not understand the syntax examples given there.
For example, if you want to alter a texture hook so that it will never be released, and the texture hook was the bonelord splash screen, you'd use

xFileWriteText("Td%")
xFileWriteString("data files\splash\Splash_Bonelord.tga")

User avatar
m Gardner
 
Posts: 3510
Joined: Sun Jun 03, 2007 8:08 pm

Post » Fri May 27, 2011 7:16 pm

I saw it. But I do not understand the syntax examples given there.

What is given is the the C style syntax for a function call. I am fairly sure what was meant was

xFileWriteText "|MGEpipe" "Td%"xFileWriteString "|MGEpipe" "data files\splash\Splash_Bonelord.tga"

User avatar
Jeneene Hunte
 
Posts: 3478
Joined: Mon Sep 11, 2006 3:18 pm

Post » Fri May 27, 2011 7:38 am

Yes, it is used as a unique string to know when to stop reading. I don't think it is really required as xFileReadString will return 0 if it cannot read the string. I would assume "cannot read the string" includes the case when the end of the file has been reached. Having said that it may be required if the file is not truncated every time it is used.

I'm pretty sure I tested this and it doesn't return 0 for the end of the file - but I could well be wrong, I'd only just started with MWSE when I tried that. I'll test again and see.

In other words, there are probably more elegant ways to tell if the end of the file has been reached. In this case the number of inventory items could have been stored as a variable in the script.

True, you could do it that way. :)
User avatar
Stacy Hope
 
Posts: 3391
Joined: Thu Jun 22, 2006 6:23 am

Post » Fri May 27, 2011 7:50 pm

I'm pretty sure I tested this and it doesn't return 0 for the end of the file - but I could well be wrong, I'd only just started with MWSE when I tried that. I'll test again and see.

Your probably right :shrug:. It is years since I have done anything serious with MWSE Scripting.
User avatar
Sarah MacLeod
 
Posts: 3422
Joined: Tue Nov 07, 2006 1:39 am

Post » Fri May 27, 2011 6:27 am

OK, tested it: For end of file you get the string "null".
User avatar
Kari Depp
 
Posts: 3427
Joined: Wed Aug 23, 2006 3:19 pm


Return to III - Morrowind