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


Log in to post a reply.

Support

Forums