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

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?


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")

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)


(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)


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... :}


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.


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))


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


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.


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)


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.

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


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.


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


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


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.


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.

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>

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.

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.


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

Support

Forums