I fear I may need to send in the clones...

Odd title I know, but relevant with regards to the post. Have you ever embarked on what you may think is a simple task and end up adding and adding bits? Well I think I have 'spilled grass seed on my petunias'.

I have created a terminal of sorts, that lists various characters and areas that the player must contact and go to.

It works to the degree that it is in a loop and waits for a selection, clears and refreshes and updates as required, but here is the 'thing' that is making me a little agitated.

The list will keep changing around with all the correct data, but shuffles the important stuff. (Info. and Exit. stay at the bottom of the list, as required)

I think I may have to find a way of cloning my list on the fly?

I have posted a version of what I am trying to do, to make it a little clearer.

Thanks in advance for any help received.

-=Darchy=-

<!--Saved by Quest 5.7.6606.27193-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="computer_terminal_2">
    <gameid>3c4a6830-8fc5-4d3c-896f-737701368144</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
    <start type="script"><![CDATA[
      // game.charcount = 4
      // game.charnames = Split ("Deelo Phrax; Giles Barker;Aliya Trent;Xena Wohl")
      game.terminal_output = ""
      game.terminal_list = Split ("Info.;Exit.")
      game.terminal_list_clone = game.terminal_list
      // game.charlist = NewStringList()
      game.legend_start = "<span style='color: White; background: Red'><b>"
      game.legend_end = "</b></span><br>"
      game.terminal_header = game.legend_start + "Select:" + game.legend_end
    ]]></start>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <object name="terminal">
      <inherit name="editor_object" />
      <feature_usegive />
      <drop type="boolean">false</drop>
      <displayverbs type="stringlist">
        <value>Look at</value>
        <value>Use</value>
      </displayverbs>
      <inventoryverbs type="stringlist">
        <value>Look at</value>
        <value>Use</value>
      </inventoryverbs>
      <use type="script">
        ClearScreen
        PrintCentered (game.legend_start + "*** BARKER SECURITY TERMINAL ***" + game.legend_end)
        comp_start
      </use>
    </object>
  </object>
  <function name="comp_start"><![CDATA[
    ShowMenu (game.terminal_header, game.terminal_list, true) {
      switch (result) {
        case ("Exit.") {
          game.terminal_output = "<br>" + "Logging out of terminal." + "<br>"
          ShowRoomDescription
        }
        case ("Info.") {
          game.terminal_output = "<br>" + "Updating information available to users." + "<br>"
          list remove (game.terminal_list, "Deelo Phrax.")
          list add (game.terminal_list, "Deelo Phrax.")
          clear_terminal
        }
        case ("Deelo Phrax.") {
          game.terminal_output = "<br>Details for: Deelo Phrax: <br>Owner of \"Bar Phrax\" - A seedy nightclub on the far side of town.<br>"
          list remove (game.terminal_list, "Bar Phrax.")
          list add (game.terminal_list, "Bar Phrax.")
          clear_terminal
        }
        case ("Bar Phrax.") {
          game.terminal_output = "<br>" + "Bar Phrax can be found in the Red Zone. APPROACH WITH CAUTION!<br>"
          list remove (game.terminal_list, "Red Zone.")
          list add (game.terminal_list, "Red Zone.")
          clear_terminal
        }
        case ("Red Zone.") {
          game.terminal_output = "<br>" + "The \"Red Zone\" is a hive of depravity and criminality.<br>"
          list remove (game.terminal_list, "Red Zone.")
          list add (game.terminal_list, "Red Zone.")
          clear_terminal
        }
      }
    }
    msg (game.terminal_output)
  ]]></function>
  <function name="clear_terminal">
    ClearScreen
    // result = game.term_result
    PrintCentered (game.legend_start + "*** BARKER SECURITY TERMINAL ***" + game.legend_end)
    list remove (game.terminal_list, "Info.")
    list add (game.terminal_list, "Info.")
    list remove (game.terminal_list, "Exit.")
    list add (game.terminal_list, "Exit.")
    JS.scrollToEnd ()
    comp_start
  </function>
</asl> 

I am not sure quite what you want, but...

So you have a list, game.terminal_list, and this is a set of options the player can pick from. Besides the Exit and Info, does the order matter? One way would be to exclude Exit and Info from the list, and only add them in the ShowMenu:

    ShowMenu (game.terminal_header, game.terminal_list + "Info." + "Exit.", true) {

You might want to look at this tutorial, which is doing something similar:
https://github.com/ThePix/quest/wiki/Modelling-a-computer-system


This removes "Deelo Phrax." from its place in the list, then adds it the end of the list.

          list remove (game.terminal_list, "Deelo Phrax.")
          list add (game.terminal_list, "Deelo Phrax.")

The same thing happens with "Bar Phrax" and "Red Zone".


Then, the clear_terminal() functions removes these two from the list and adds them to the end:

    list remove (game.terminal_list, "Info.")
    list add (game.terminal_list, "Info.")
    list remove (game.terminal_list, "Exit.")
    list add (game.terminal_list, "Exit.")

I am probably missing something, but why remove something and add it right back to the list?

I'd remove (or just comment out) every instance of list remove and list add and see what happens. (Make a backup copy of the game first!)


I assumed that you're removing then re-adding items because you want to put them at the end. But then I don't know what you're asking, as it seems you've already done that.

If you want to clone a list, I'm not sure if there's a specific function to do it, but cloned_list = ListExclude(original_list, NewStringList()) is likely a fast way to do it.


Aha! Thanks Pixie.

ShowMenu (game.terminal_header, game.terminal_list + "Info." + "Exit.", true) {

Woohoo! This cuts down on a sub-function with all that list add/remove 'gubbins' to get it to show at the end thanks.

What I am attempting in theory, is something akin to a small flat file database of about 20 characters, that could be recalled at any terminal throughout the game world and also to an object (portable data device) that needs to be interfaced to a terminal that calls the same function. It is only simple information to lead the player to get items or clues.

As a part of the puzzle or person is completed or met, then the information gets removed then updated.

I shall take a look at the "Modelling-a-computer-system" page and see how it works.

Thanks again

-=Darchy=-


Hiya @KV!

list remove (game.terminal_list, "Info.")
list add (game.terminal_list, "Info.")

I forgot to delete the second set of those lol - the reason I am removing and adding is because while this is looping it will continue to add the same info over and over again when I select that item. so the list will consist of lots of the word Info. every time I click Info.

Pixie has enabled me to get rid of that 'dodgy' bit of my code.

Hiya @mrangel

You are correct in part, I think what I visualize in my head and what I can achieve in code are somewhat over zealous. The only way I can describe what I am trying to do is make one list, show the results with last added list item to be shown at the top, but when I try this, the items shuffle when I click other links in the list.

I will persevere with what I have been given so far.

Thanks guys!

-=Darchy=-


Erm... I just went back to Quest after a few hours and I think I can fix this with the use of a boolean - sorry for being a dingbat.

If it is not there (False) add it to the list, if it is there (True) don't add it to the list.

I am so sorry...

-=Darchy=-


An example game in which any selection goes to the top of the list, unless you select "Info" or "Exit":

<!--Saved by Quest 5.7.6606.27193-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="List Fun (part 2)">
    <gameid>1b422e52-9460-4420-b9cf-15df4749a5d5</gameid>
    <version>1.0</version>
    <firstpublished>2018</firstpublished>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <beforeenter type="script">
      RunMenuTest
    </beforeenter>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
  </object>
  <command name="test_menu_cmd">
    <pattern>test;menu;menu test;test menu</pattern>
    <script>
      RunMenuTest
    </script>
  </command>
  <function name="RunMenuTest"><![CDATA[
    firsttime {
      game.constant_list = Split("burger;fish;chicken;Info;Exit")
      // The next line 'clones' the original list so we can change it without altering the original.
      game.choice_list = ListExclude(game.constant_list,"")
      game.menu_script => {
        ShowMenu ("Pick one.", game.choice_list, false) {
          switch (result) {
            case ("Info") {
              msg ("The information prints.")
              invoke (game.menu_script)
            }
            case ("Exit") {
              msg ("Exiting.<br/><br/>Enter {command:MENU} to do that again.<br/>")
            }
            default {
              msg ("You picked "+result+".")
              list remove (game.choice_list, result)
              game.choice_list = result + game.choice_list
              invoke (game.menu_script)
            }
          }
        }
      }
    }
    invoke (game.menu_script)
  ]]></function>
  <function name="ResetMenu">
    game.choice_list = ListExclude(game.constant_list,"")
  </function>
</asl>

List arithmetic (from the docs)

You can use + and - on lists. These can be used to add and remove single elements from a list.

listOne = Split("one|two|three", "|")
listTwo = "zero" + listOne + "four"
msg(listTwo)
-> List: zero; one; two; three; four; 
listThree = listTwo - "two"
msg(listThree)
-> List: zero; one; three; four; 
listFour = listOne + listThree
msg(listFour)
-> List: one; two; three; zero; one; three; four; 

Also works for object lists:

objectListOne = NewObjectList()
objectListTwo = objectListOne + player
msg(objectListTwo)

And mixed lists, here in one step we add an object and a string:

list1 = NewList()
list2 = list1 + player + "player"

http://docs.textadventures.co.uk/quest/using_lists.html


Thanks K.V.

The top example is more akin to what I am aiming for.

-=Darchy=-


(filler for getting my edited post, updated/posted)
(again, filler for getting my edited post, updated/posted)


quest might have some underlying list sort it's doing, otherwise it adds new items to the end of the list, and shifts the items (after the item you remove) towards the beginning of the list if/when you remove an item that's not at the end of the list.


if you want to have your own sorted list, then you got to do it yourself, and here's two ways of doing it:

  1. sorting the list
  2. separating out the items if they're going to go at the top or bottom, displaying 3 lists or using 3 scripts

and then, you have to manually create your list (I show an example of this in the code below)

for example with #2, an example:

(if you want them as hyperlinks, let me know)

<game name="example_game">

  <attr name="start" type="script">
    do (example_object, "example_script_attribute")
  </attr>

<game>

<object name="example_object">

  <attr name="example_script_attribute" type="script">

    msg ("1. " + this.example_top_item_string_attribute)

    numbering_integer_variable = 2

    foreach (item_string_variable, this.example_stringlist_attribute) {
      msg (numbering_integer_variable + ". " + item_string_variable)
      numbering_integer_variable = numbering_integer_variable + 1
    }

    msg (numbering_integer_variable + ". " + this.example_bottom_item_string_attribute)
   
  </attr>

  <attr name="example_top_item_string_attribute" type="string">white</attr>

  <attr name="example_bottom_item_string_attribute" type="string">black</attr>

  <attr name="example_stringlist_attribute" type="stringlist">

    <value>red</value>
    <value>blue</value>
    <value>yellow</value>

  </attr>

</object>

// output/display:

1. white
2. red
3. blue
4. yellow
5. black

and it'll still work, even if we change up the list's items (or if we use a different list), for example:

<game name="example_game">

  <attr name="start" type="script">
    do (example_object, "example_script_attribute")
  </attr>

<game>

<object name="example_object">

  <attr name="example_script_attribute" type="script">

    msg ("1. " + this.example_top_item_string_attribute)

    numbering_integer_variable = 2

    foreach (item_string_variable, this.example_stringlist_attribute) {
      msg (numbering_integer_variable + ". " + item_string_variable)
      numbering_integer_variable = numbering_integer_variable + 1
    }

    msg (numbering_integer_variable + ". " + this.example_bottom_item_string_attribute)
   
  </attr>

  <attr name="example_top_item_string_attribute" type="string">white</attr>

  <attr name="example_bottom_item_string_attribute" type="string">black</attr>

  <attr name="example_stringlist_attribute" type="stringlist">

    <value>red_1</value>
    <value>purple</value>
    <value>blue</value>
    <value>green</value>
    <value>yellow</value>
    <value>orange</value>
    <value>red_2</value>

  </attr>

</object>

// output/display:

1. white
2. red_1
3. purple
4. blue
5. green
6. yellow
7. orange
8. red_2
9. black

a quick example of concatenation:

my attempt at inserting the line breaks, <br>, is probably incorrect syntax...

KV can fix it up so that it'll work, so just ask him, if it doesn't work, as he knows how to get the syntax correct for it to work
<game name="example_game">

  <attr name="start" type="script">
    do (example_object, "example_script_attribute")
  </attr>

<game>

<object name="example_object">

  <attr name="example_script_attribute" type="script">

    <![CDATA[

      concatenation_string_variable = "1. " + this.example_top_item_string_attribute

      numbering_integer_variable = 2

      foreach (item_string_variable, this.example_stringlist_attribute) {
        concatenation_string_variable = concatenation_string_variable + "<br>" + numbering_integer_variable + ". " + item_string_variable
        numbering_integer_variable = numbering_integer_variable + 1
      }

      concatenation_string_variable = concatenation_string_variable + "<br>" + numbering_integer_variable + ". " + this.example_bottom_item_string_attribute

      msg (concatenation_string_variable)
   
    ]]>

  </attr>

  <attr name="example_top_item_string_attribute" type="string">white</attr>

  <attr name="example_bottom_item_string_attribute" type="string">black</attr>

  <attr name="example_stringlist_attribute" type="stringlist">

    <value>red</value>
    <value>blue</value>
    <value>yellow</value>

  </attr>

</object>

// output/display:

1. white
2. red
3. blue
4. yellow
5. black

// without the line breaks, it'd, look-like/display/output this:

1. white2. red3. blue4. yellow5. black

(ya, I'd need to go insert a space between the items as can be seen above if this is what we wanted to do, lol)
(but, this is just to show you what concatenation is/does)

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

here, this is how the spaces get inserted:

<game name="example_game">

  <attr name="start" type="script">
    do (example_object, "example_script_attribute")
  </attr>

<game>

<object name="example_object">

  <attr name="example_script_attribute" type="script">

    <![CDATA[

      concatenation_string_variable = "(1) " + this.example_top_item_string_attribute

      numbering_integer_variable = 2

      foreach (item_string_variable, this.example_stringlist_attribute) {
        concatenation_string_variable = concatenation_string_variable + ", (" + numbering_integer_variable + ") " + item_string_variable
        numbering_integer_variable = numbering_integer_variable + 1
      }

      concatenation_string_variable = concatenation_string_variable + ", or (" + numbering_integer_variable + ") " + this.example_bottom_item_string_attribute

      msg (concatenation_string_variable)
   
    ]]>

  </attr>

  <attr name="example_top_item_string_attribute" type="string">white</attr>

  <attr name="example_bottom_item_string_attribute" type="string">black</attr>

  <attr name="example_stringlist_attribute" type="stringlist">

    <value>red</value>
    <value>blue</value>
    <value>yellow</value>

  </attr>

</object>

// display/output (actually, I'm going to edit it with parenthesis instead of dots/periods and etc, too, as it makes its display easier to read, lol):

(1) white, (2) red, (3) blue, (4) yellow, or (5) black

as for sorting, it's a bit more complex:

  1. you need scripting design to find and sort the items correctly
    and/or
  2. you need concatenation scripting to put the items together

ask, and I can help with sorting (but you'll have to provide info on what you want, as there's an infinite ways of sorting and also designs for sorting)

(for complex sorting of lots of data/content/items, then you'll want to use Data Structure design: trees, maps, dictionaries, linked lists, iterators, etc)


Cheers Hegemonkhan. I will look at this when I get time. My youngest is on half-term, so priorities get swapped.

Thanks again.

-=Darchy=-


I can't believe how daft I have been. Maybe I should consult the manual a bit more. I have found that what I want to achieve can be done by using the ConvLib library. I don't know where my head was at.

For whatever reasons, I kept imagining conversation 'organic' and conversation 'non-organic' as separate game 'entities' as opposed to game 'objects' - silly, I know.

Thank you guys for the all the input and apologies for wasting your time. I appreciate all the help I get on here, my learning curve has gone through the roof. I would not have got this far without you.

-=Darchy=-


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums