Issue with speak to

When you speak to anyone in the game and you have not created a response, the game will respond:
"He saies nothing."
Can the spelling of "says" get a fix?


Someone else already pointed this out. On the previous version, I pointed out that it should be "tries" rather than "trys" (which is now fixed) and "switches" instead of "switchs" (which still doesn't work).

In the last thread I suggested a change which would make these work correctly and also allow the user to add more irregular verbs if there's any I missed.

Here's a version with a little more thought in it; putting all the data into dictionaries.

<function name="Conjugate" type="string" parameters="obj, verb">
  genders = LCase(obj.gender)
  if (genders = "he" or genders = "she") {
    genders = genders + ";it"
  }
  cmd = GetObject (verb)
  foreach (gender, Split(genders)) {
    if (not cmd = null and HasString (cmd, "conjugate_"+gender)) {
      return (GetString (cmd, "conjugate_"+gender))
    }
    dict = GetAttribute (game, "conjugations_"+gender)
    if (not dict = null) {
      if (DictionaryContains (dict, verb)) {
        return (DictionaryItem (dict, verb))
      }
      foreach (ending, game.conjugations) {
        if (Left (ending, 1) = "@" and EndsWith (verb, Mid (ending, 2))) {
          return (Conjugate (obj, Left (verb, LengthOf(verb) - LengthOf(ending) + 1)) + DictionaryItem (dict, ending))
        }
        else if (Left (ending, 1) = "*" and EndsWith (verb, Mid (ending, 2))) {
          return (Left (verb, LengthOf(verb) - LengthOf(ending) + 1) + DictionaryItem (dict, ending))
        }
      }
    }
  }
  return (verb)
</function>

And then a couple of dictionaries on the game object, allowing for easy creation of fictional irregular verbs:

<attr name="conjugations_i" type="stringdictionary">
  <item><key>be</key><value>am</value></item>
</attr>

<attr name="conjugations_you" type="stringdictionary">
  <item><key>be</key><value>are</value></item>
</attr>

<attr name="conjugations_we" type="stringdictionary">
  <item><key>be</key><value>are</value></item>
</attr>

<attr name="conjugations_they" type="stringdictionary">
  <item><key>be</key><value>are</value></item>
</attr>

<attr name="conjugations_it" type="stringdictionary">
  <item><key>be</key><value>is</value></item>
  <item><key>have</key><value>has</value></item>
  <item><key>*ay</key><value>ays</value></item>
  <item><key>*oy</key><value>oys</value></item>
  <item><key>*ey</key><value>eys</value></item>
  <item><key>*y</key><value>ies</value></item>
  <item><key>*ss</key><value>sses</value></item>
  <item><key>*s</key><value>sses</value></item>
  <item><key>*sh</key><value>shes</value></item>
  <item><key>*ch</key><value>ches</value></item>
  <item><key>*o</key><value>oes</value></item>
  <item><key>*x</key><value>xes</value></item>
  <item><key>*z</key><value>zes</value></item>
  <item><key>*</key><value>s</value></item>
</attr>

With this function, the dictionaries control verb conjugation

If you want to, you could add entries like <item><key>@ with</key><value> with</value></item> so that Conjugate will work properly if given a verb with a preposition. This would make it a lot more useful to anyone who's making more advanced NPCs, because you could use it directly with most things from displayverbs.


(Here's a further thought, which might make the same Conjugate function work well enough for all languages rather than having a different one in every language library:

        else if (StartsWith (ending, "/")) {
          parts = Split (Mid (ending, 2), "/")
          pattern = "(?<fullmatch>" + ListItem (parts, 0) + ")"
          if (ListCount (parts) > 1) {
            continue = (Instr (ListItem (parts, 1), "+") > 0)
            repeat = (Instr (ListItem (parts, 1), "g") > 0)
            expr = (Instr (ListItem (parts, 1), "e") > 0)
          }
          else {
            continue = false
            repeat = false
            expr = false
          }
          if (IsRegexMatch (pattern, verb)) {
            processed = ""
            processing = verb
            while (IsRegexMatch (pattern, processing)) {
              matches = Populate (pattern, processing)
              startpos = Instr (processing, DictionaryItem (matches, fullmatch))
              endpos = startpos + LengthOf (DictionaryItem (matches, fullmatch))
              processed = processed + Left (processing, startpos - 1)
              replacement = DictionaryItem (dict, ending)
              if (expr) {
                replacement = eval (replacement, matches)
              }
              processing = replacement + Mid (processing, endpos)
              if (endpos = startpos or not repeat) {
                processed = processed + processing
                processing = ""
                pattern = "."
              }
            }
            if (continue) {
              verb = processed
            }
            else {
              return (processed)
            }
          }
        }

Allowing the dictionary keys to be regular expressions, making for arbitrarily complex rules for how to conjugate a verb.


I have uploaded a revision to Github, so this will be fixed when Quest is next updated.


Looking again at the English template (trying to make it easier to make the player "I" or "he" just by changing the player object's gender; I note that if I replace all "You" in the templates with a WriteVerb call, the most common verbs it'll be conjugating are "can" and "can't", both of which need special cases in the dictionary.

I'm looking at a little tweak to WriteVerb as well:

    <function name="WriteVerb" type="string" parameters="obj, verb">
        result = Conjugate(obj, verb)
        if (not UCase (Left (result, 1)) = LCase (Left (result, 1))) {
            result = " " + result
        }
        return (CapFirst(obj.gender) + result)
    </function>
    
    <attr name="conjugations_i" type="stringdictionary">
  <item><key>be</key><value>am</value></item>
  <item><key>'be</key><value>'m</value></item>
</attr>

<attr name="conjugations_you" type="stringdictionary">
  <item><key>be</key><value>are</value></item>
  <item><key>'be</key><value>'re</value></item>
</attr>

<attr name="conjugations_we" type="stringdictionary">
  <item><key>be</key><value>are</value></item>
  <item><key>'be</key><value>'re</value></item>
</attr>

<attr name="conjugations_they" type="stringdictionary">
  <item><key>be</key><value>are</value></item>
  <item><key>'be</key><value>'re</value></item>
</attr>

<attr name="conjugations_it" type="stringdictionary">
  <item><key>be</key><value>is</value></item>
  <item><key>have</key><value>has</value></item>
  <item><key>can</key><value>can</value></item>
  <item><key>mould</key><value>moulds</value></item>
  <item><key>*ould</key><value>ould</value></item>
  <item><key>must</key><value>must</value></item>
  <item><key>can't</key><value>can't</value></item>
  <item><key>won't</key><value>won't</value></item>
  <item><key>cannot</key><value>cannot</value></item>
  <item><key>@n't</key><value>n't</value></item>
  <item><key>'ve</key><value>'s</value></item>
  <item><key>'be</key><value>'s</value></item>
  <item><key>*ay</key><value>ays</value></item>
  <item><key>*oy</key><value>oys</value></item>
  <item><key>*ey</key><value>eys</value></item>
  <item><key>*y</key><value>ies</value></item>
  <item><key>*ss</key><value>sses</value></item>
  <item><key>*s</key><value>sses</value></item>
  <item><key>*sh</key><value>shes</value></item>
  <item><key>*ch</key><value>ches</value></item>
  <item><key>*o</key><value>oes</value></item>
  <item><key>*x</key><value>xes</value></item>
  <item><key>*z</key><value>zes</value></item>
  <item><key>*</key><value>s</value></item>
</attr>

This way, you can use WriteVerb (object, "'ve") to get "I've", "You've", or "He's" correctly; and WriteVerb (object, "'be") with an apostrophe will give "I'm", "You're", or "He's". Added a few more exceptions (like can, must, could, would, and should, and an entry for @n't to handle hasn't, doesn't, and similar.)


Hello mrangel,

Where exactly should this code show up to display this? I mean, where do we put it? How?


This has come up a few times. In general, if you are happy to work at the underlying code level you can change any of the default responses. For DefaultSpeakTo my preference is:

<dynamictemplate name="DefaultSpeakTo">"You get no response."</dynamictemplate>

Just add this line with whatever wording you prefer to your code.


@KiraSnowye
The code in my last few posts is intended to replace the WriteVerb and Conjugate functions in the file English.aslx. I posted a couple of different versions of the dictionaries as I worked on it.

I've uploaded a library including this code, which I hope you might be able to add to a game. This is basically my modifications to the English language pack, including both the verb fixes, and removing "You" from a lot of the messages so that you can make the game first person more easily.


@mrangel
So, this is only an addition to the English.aslx, and not necessarily a change of that specific file, yes? Does this entirely fix the error of the "Speak to" command in which DisplayVerbs can sync with this specific type? Or, is this more of a change in how it's executed?


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

Support

Forums