Reading from a file

Let's say you want Quest to read the information from a file in the game's folder.


I created a file named README.txt.

The contents:

Hello, Quest!

The game's code:

<!--Saved by Quest 5.7.6404.15496-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="Read from a file">
    <gameid>0872edb9-52ea-4bfb-ab02-79fead46bb02</gameid>
    <version>1.0</version>
    <firstpublished>2017</firstpublished>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <description type="script">
      msg (GetFileData("README.txt"))
    </description>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
  </object>
</asl>

The output:

image


Now, I'll change the contents of the file to this:

Hello, Quest!

<h1>THIS IS A HEADER!</h1>


image


NOTE: I don't think Quest can read a file from the hard drive that isn't in the game's folder. I am experimenting with that next, but it seems like I've read a post by Pixie saying that exact thing. (I think it concerned the Save/Load system.)


I am not sure if you can read from another directory or not, but just don't!

When you publish the game Quest will only include files in the current folder (actually, library files from elsewhere will be included).

Also, it will only include games with specific file extensions (or rather, that match specific patterns). You can modify game.publishfileextensions to include your .txt file, but by default it will not be included.


I am not sure if you can read from another directory or not, but just don't!

Boom. Sage advice.

(It didn't work anyway, kids. )


Also, it will only include games with specific file extensions (or rather, that match specific patterns). You can modify game.publishfileextensions to include your .txt file, but by default it will not be included.

Good looking out!

This is what Quest includes by default:

<publishfileextensions>*.jpg;*.jpeg;*.png;*.gif;*.js;*.wav;*.mp3;*.htm;*.html;*.svg </publishfileextensions>

NOTE:

I just renamed README.txt as README.html, and everything works just the same. (It's just reading the text. If there's HTML code, it will be displayed as coded. If not, it will display plain text.)


msg (GetFileData("README.html"))


Now, I wonder if it can read from an online file...

(It seems like the answer is no, but I'm bored. Be right back.)


Nice!!!
I assume there is a way to read the file info into a variable, like "result", then process that for needed info...
I'm thinking of a game where by completing several "missions" you get promotions for new ships (space based) and accedd for new missions...
GetFileData() should have a counter command PutFileData()...


Heck yeah, there is. (It's in Pixie's Quest, too. I'll go find it. Be right back.)


Here you go:

http://textadventures.co.uk/forum/quest/topic/np4q-x6_je_uw_aqk27zpq/creating-content-from-a-text-file-im-bringing-it-back


  <function name="LoadFile" parameters="filename">
    s = GetFileData (filename)
    current_object = null
    game.setUp = false
    foreach (line, Split(s, "\n")) {
      line = Crop(line)
      if (not line = "" and not StartsWith(line, "#")) {
        bits = Split(line, "=")
        if (StringListItem(bits, 0) = "new") {
          if (ListCount(bits) = 2) {
            create (StringListItem(bits, 1))
            current_object = GetObject(StringListItem(bits, 1))
          }
          else {
            create (StringListItem(bits, 2), StringListItem(bits, 1))
            current_object = GetObject(StringListItem(bits, 2))
          }
        }
        else if (StringListItem(bits, 0) = "find") {
          current_object = GetObject(StringListItem(bits, 1))
          if (current_object = null) {
            error ("Failed to find " + StringListItem(bits, 1) + " in the game world. Things will go badly...")
          }
        }
        else if (StringListItem(bits, 0) = "exit") {
          create exit (StringListItem(bits, 2), null, null, null, StringListItem(bits, 1))
          current_object = GetObject(StringListItem(bits, 2))
        }
        else if (StringListItem(bits, 0) = "parent") {
          newParent = StringListItem(bits, 1)
          if (newParent = "game.pov") {
            current_object.parent = game.pov.name
            game.setUp = true
            list remove (bits, "game.pov")
            list add (bits, game.pov.name)
          }
          else if (newParent = "game.pov.parent") {
            current_object.parent = game.pov.parent.name
            game.setUp = true
            list remove (bits, "game.pov.parent")
            list add (bits, game.pov.parent.name)
          }
          else if (newParent = "here") {
            current_object.parent = game.pov.parent.name
            game.setUp = true
            list remove (bits, "here")
            list add (bits, game.pov.parent.name)
          }
          else if (newParent = "player.parent") {
            current_object.parent = player.parent.name
            game.setUp = true
            list remove (bits, "player.parent")
            list add (bits, player.parent.name)
          }
          current_object.parent = GetObject(StringListItem(bits, 1))
          if (current_object.parent = null) {
            error ("Failed to find " + StringListItem(bits, 1) + " in the game world. Things will go badly...")
          }
        }
        else if (StringListItem(bits, 0) = "to") {
          current_object.to = GetObject(StringListItem(bits, 1))
          if (current_object.to = null) {
            error ("Failed to find " + StringListItem(bits, 1) + " in the game world. Things will go badly...")
          }
        }
        else {
          if (LCase(StringListItem(bits, 1)) = "false") {
            set (current_object, StringListItem(bits, 0), false)
          }
          else if (LCase(StringListItem(bits, 1)) = "true") {
            set (current_object, StringListItem(bits, 0), true)
          }
          else if (IsInt(StringListItem(bits, 1))) {
            set (current_object, StringListItem(bits, 0), ToInt(StringListItem(bits, 1)))
          }
          if (not game.setUp) {
            set (current_object, StringListItem(bits, 0), StringListItem(bits, 1))
          }
          else {
            set (current_object, StringListItem(bits, 0), game.pov)
          }
        }
      }
    }
    msg ("Done.")
  </function>
  <function name="Crop" parameters="s" type="string"><![CDATA[
    start = 1
    end = LengthOf(s)
    for (i, 1, LengthOf(s)) {
      if (Asc(Mid(s, i, 1)) < 33) {
        if (start = i) {
          start = i + 1
        }
      }
      else {
        end = i
      }
    }
    return (Mid(s, start, end - start + 1))
  ]]></function>
  <command name="px_update">
    <pattern>load #text#</pattern>
    <script>
      LoadFile (text)
    </script>
  </command>


You can load a file like this example.

find= just finds an existing object you want to change attributes on.

new= creates a new object, of course.

Everything else should be familiar.

Pixie created all this, by the way. I just added a couple of tweaks to his code.

new=kv_special_item_1
alias=black shard of &infin;
look=It's the black shard, which is the most powerful of them all!
parent=game.pov

find=kv_green_shard
parent=game.pov

new=thingy
parent=game.pov.parent

new=anotherThing
parent=player.parent

new=thing3
parent=here

GetFileData() should have a counter command PutFileData()

I can build you a version of Quest where Log doesn't print the date and time at the beginning of each entry.

You could then just use Log("whatever you want to save on a line to the .txt file") in place of PutFileData().

(I can do that. I'll damned if I can figure out how to call a function that Quest can't already call, though. I've been trying to figure out how to make it so I can call the Restart function forever!)


Log in to post a reply.

Support

Forums