Polymorph commands? (i.e. one word, two separate commands)

thanos
26 Apr 2018, 05:28

Is there a mechanism by which we can use one word for two separate commands?

I'm translating Quest, and the problem I have is this: in Greek, we use the same word for Swich On and Open ("anoikse"), as well as Swich Off and Close ("klise"). I need "anoikse" to work as either Swich On or Open, depending on the context, that is depending on the object on which it is used.
Is it possible?


The Pixie
26 Apr 2018, 07:26

Yes, should be easy. Verbs are great for doing exactly this.

Set up a new verb, anoikse. If an object is an openable object, have the verb script do:

TryOpenClose(true, this)

If it is a switch, do this:

do(this, "turnon")

mrangel
26 Apr 2018, 10:21

I'm looking at this, and I'm thinking it might be more complex than it should be.

My first thought was to create a new command that checks for the "openable" and "switchable" types, and tries to do the right thing accordingly.

So:

<command name="anoikse">
  <pattern>anoikse #object#</pattern>
  <script>
    if (HasScript (object, "turnon")) {
      do (object, "turnon")
    }
    else {
      TryOpenClose (object, true)
    }
  </script>
</command>

<command name="klise">
  <pattern>klise #object#</pattern>
  <script>
    if (HasScript (object, "turnoff")) {
      do (object, "turnoff")
    }
    else {
      TryOpenClose (object, false)
    }
  </script>
</command>

  <template name="Open">Anoikse</template>
  <template name="Close">Klise</template>
  <template name="SwitchOn">Anoikse</template>
  <template name="SwitchOff">Klise</template>

I think this should work. The four templates at the end are added to the displayverbs list by the "openable" and "switchable" types. I wouldn't include the verbtemplates "open", "close", "turnon", or "turnoff".

This way, the "open" and "close" commands will still have their patterns set in English (so a player can type "open" if they want), but setting an item as "openable" or "switchable" in the editor will add displayverbs corresponding to the new commands.

(Does that make sense? My blood sugar is rather low this morning so I might not be thinking clearly)


mrangel
26 Apr 2018, 10:25

(Noting that I didn't test if the object is openable in that command; if the object is neither openable nor switchable, then we can rely on TryOpenClose to display the CantOpen message, which I assume would be suitable for something that can neither be opened nor switched)


thanos
26 Apr 2018, 20:41

Thanks for the input, guys.

I'm still not sure how to use it inside the language file. Commands in there use the CDATA syntax, will your example work, mrangel? Also, I'm using Greek characters, so I cannot use them for an object's name.

Can you please write the language file syntax?

Still learning this... :}


mrangel
26 Apr 2018, 22:50

As far as I understand it, you can't use Greek characters in the name, but you can in the pattern and in the templates. You'd just need to make sure that those match each other.

If Quest follows XML best practices, CDATA should be optional unless the script contains the characters &, <, or >.
If it doesn't work, then it might be necessary to change the <script> and </script> to <script><![CDATA[ and ]]></script> respectively.

I don't think there should be a problem with including commands in the language file. The language file is a library like any other, and I'm sure I've seen in some of the others that they change some functions where necessary.
I don't have the desktop version of Quest though, so can't actually test my code.


thanos
01 May 2018, 03:39

Bummer. No luck.

The Pixie, can you be a bit more detailed how to setup the verb, together with its script, in the Language file?

mrangel, your commands work when I enter them through the desktop interface, but not when I include them in the Language file. For some reason, in the latter case, is matches "anoikse #object#" LITERALLY, not e.g. "anoikse door", i.e. #object# is not assigned to the particular object.
(btw it is TryOpenClose (true, object) and not TryOpenClose (object, true))


The Pixie
01 May 2018, 06:58

If you want to do this in a language file, mrangel's way is best.

Looking at the first command, you would keep the name is Latin alphabet, but change the pattern

<command name="anoikse">
  <pattern>ανοιξε #object#</pattern>
  <script>
    if (HasScript (object, "turnon")) {
      do (object, "turnon")
    }
    else {
      TryOpenClose (object, true)
    }
  </script>
</command>

If it needs CDATA (and itshould not), then it would start:

<command name="anoikse">
  <pattern><![CDATA[ανοιξε #object#]]></pattern>
  <script>

Apologies if the Greek is wrong


thanos
01 May 2018, 07:59

So, I did that, and the output in both cases is this: (I figured the Greek characters issue, so in "Greeklish")

> anoikse door
---> UnrecognisedCommand
> anoikse #object#
(nothing)
>

So the problem is it doesn't match #object# to an actual object.


mrangel
01 May 2018, 08:52

Sorry, I wasn't paying too much attention there.

The pattern should be a regular expression: ^anoikse (?<object>.*)$
Or possibly ^(?:ανοιξε|anoikse) (?<object>.*)$ if you want to allow the player to type it either way.

(If you enter anoikse #object# in the editor, Quest will convert it to the regular expression above when you play or publish the game. I'm not sure how it determines whether a pattern needs converting or is already a regex)


thanos
01 May 2018, 13:30

Ok, seems we are getting somewhere. With the regex, the command gets matched.
The script, though, is not run. I tried this as a test

<command name="anoikse">
<pattern><![CDATA[^άνοιξε (?<object>.*)$]]></pattern>
<script>
    <![CDATA[msg ("kkkk")]]>
</script>
</command>

and it prints nothing at all.
I also tried msg ("kkk") in the script, without CDATA, still no luck.


K.V.
01 May 2018, 14:32

Hello.

You could try opening your debugger and look at the currentcommand stuff listed under the player object after entering the command to be sure Quest is matching the pattern:

image


The Pixie
01 May 2018, 14:50

I realised I had the parameters for TryOpenClose the wrong way round, but this works for me:

<command name="anoikse">
  <pattern>ανοιξε #object#</pattern>
  <script>
    if (HasScript (object, "turnon")) {
      do (object, "turnon")
    }
    else {
      TryOpenClose (object, true)
    }
  </script>
</command>

Then:

> ανοιξε box
It is already open.


thanos
01 May 2018, 15:12

K.V. thanks for the info, I will be using the debugger. Yes, it matches the command.

The Pixie: It works if I enter a command through the interface, but it doesn't work when I try to incorporate it in the language file. I tried inserting the above in the English language file, no luck.

Apparently there is an issue with how the


thanos
01 May 2018, 15:32

Apparently there is an issue with how the < script> part is handled through the Language file???


The Pixie
01 May 2018, 16:39

I cannot check right now, but changing the third line to this might work:

  <script type="script">

Somewhere there is code telling Quest some default types for certain attrributes, and it might be because language files are loaded before that.


mrangel
01 May 2018, 16:50

I don't think it should be different in a language file, as the language file is just a library.

(I could be wrong; I don't have Windows, so I'm trying to follow how it works by going through the code in my head)

How about if you use the implicit script form?

<command name="anoikse" pattern="^(?:άνοιξε|anoikse) (?<object>.*)$">
  <![CDATA[
    if (HasScript (object, "turnon")) {
      do (object, "turnon")
    }
    else {
      TryOpenClose (true, object)
    }
  ]]>
</command>

Does that work any better?


K.V.
01 May 2018, 17:45

I'm no good with languages other than American English, but...

I tried inserting the above in the English language file, no luck.

Is English.aslx where that should be added to test it in Greek?


This is what works for me:

  <command name="anoikse">
    <pattern type="string"><![CDATA[^(άνοιξε|anoikse) (?<object>.*)$]]></pattern>
    <script>
      if (HasScript (object, "turnon")) {
        do (object, "turnon")
      }
      else {
        TryOpenClose (true, object)
      }
    </script>
  </command>

thanos
01 May 2018, 17:50

Yes, Pixie, that's it! < script type="script">, paradoxically, did it!

Here is the code:

<command name="anoikse">
  <pattern><![CDATA[^anoikse (?<object>.*)$]]></pattern>
  <script type="script">
    if (HasScript (object, "turnon")) {
      do (object, "turnon")
    }
    else {
       TryOpenClose (true, object)
    }
</script>
</command>

So the output now, is a sweety:

You are in a room.
You can see a box and a diakoptis.

> anoikse box
You open it.

> anoikse diakoptis
You switch it on.

Thank you all, guys!


K.V.
01 May 2018, 17:54

It didn't understand until I set the pattern's type to string:

<pattern type="string"><![CDATA[^(άνοιξε|anoikse) (?<object>.*)$]]></pattern>

...and (extra paradoxically) I don't need to declare the type of the script. It's just <script>, and it works for me (with everything set to English).


anoikse

You are in a room.
You can see a box and a lamp.

> anoikse box
You open it.

> anoikse lamp
You switch it on.