Allow full text response to ShowMenu - KVonGit/quest5-stuff GitHub Wiki
Normally, when a menu appears, we must either click the option or enter the number of the option.
These modified functions should also allow us to type the option's full text.
<function name="ResolveNameFromList" parameters="variable, value, objtype, scope, secondaryscope, nodisambiguating" type="object"><![CDATA[
// Modified by KV
if (not IsDefined("nodisambiguating")) {
nodisambiguating = false
}
value = Trim(LCase(value))
fullmatches = NewObjectList()
partialmatches = NewObjectList()
foreach (obj, scope) {
name = LCase(GetDisplayAlias(obj))
CompareNames (name, value, obj, fullmatches, partialmatches)
if (obj.alt <> null) {
foreach (altname, obj.alt) {
CompareNames (LCase(altname), value, obj, fullmatches, partialmatches)
}
}
}
// allow referring to objects from the previous command by gender or article
if (objtype = "object" and game.lastobjects <> null) {
foreach (obj, game.lastobjects) {
CompareNames (LCase(obj.article), value, obj, fullmatches, partialmatches)
CompareNames (LCase(obj.gender), value, obj, fullmatches, partialmatches)
}
}
// Also check the secondary scope, but only if we have not found anything yet
if (ListCount(fullmatches) = 0 and ListCount(partialmatches) = 0 and not secondaryscope = null) {
foreach (obj, secondaryscope) {
name = LCase(GetDisplayAlias(obj))
CompareNames (name, value, obj, fullmatches, partialmatches)
if (obj.alt <> null) {
foreach (altname, obj.alt) {
CompareNames (LCase(altname), value, obj, fullmatches, partialmatches)
}
}
}
}
if (ListCount(fullmatches) = 1) {
return (ListItem(fullmatches, 0))
}
else if (ListCount(fullmatches) = 0 and ListCount(partialmatches) = 1) {
return (ListItem(partialmatches, 0))
}
else if (ListCount(fullmatches) + ListCount(partialmatches) = 0) {
return (null)
}
else if (not nodisambiguating) {
// Added this line to resolve issue with new FinishTurn setup in 580
game.disambiguating = true
candidates = ListCompact(ListCombine(fullmatches, partialmatches))
if (LengthOf(variable) > 0) {
// single object command, so after showing the menu, add the object to game.pov.currentcommandresolvedelements
game.pov.currentcommandpendingvariable = variable
ShowMenu (DynamicTemplate("DisambiguateMenu", value), candidates, true) {
varname = game.pov.currentcommandpendingvariable
game.pov.currentcommandpendingvariable = null
if (result <> null) {
AddToResolvedNames (varname, GetObject(result))
}
}
}
else {
// multi-object command, so after showing the menu, add the object to the list
game.pov.currentcommandmultiobjectpending = true
ShowMenu (DynamicTemplate("DisambiguateMenu", value), candidates, true) {
if (result <> null) {
list add (game.pov.currentcommandpendingobjectlist, GetObject(result))
ResolveNextNameListItem
}
}
}
return (null)
}
return (null)
]]></function>
<function name="ResolveName" parameters="variable, value, objtype, nodisambiguating" type="object"><![CDATA[
// Modified by KV
if (not IsDefined("nodisambiguating")) {
nodisambiguating = false
}
found = false
if (game.pov.commandmetadata <> null) {
if (DictionaryContains(game.pov.commandmetadata, value)) {
result = GetObject(StringDictionaryItem(game.pov.commandmetadata, value))
if (result <> null) {
if (ListContains(ScopeVisible(), result)) {
found = true
return (result)
}
}
}
}
if (not found) {
value = LCase(value)
result = ResolveNameInternal(variable, value, objtype, nodisambiguating)
if (result <> null) {
return (result)
}
else {
// TO DO: Check this behaviour. We only want to try ignoring prefixes if we have definitely got an unresolved name.
foreach (prefix, game.parserignoreprefixes) {
if (StartsWith(value, prefix + " ")) {
result = ResolveNameInternal(variable, Mid(value, LengthOf(prefix) + 1), objtype, nodisambiguating)
}
}
if (result = null and LengthOf(variable) = 0 and not GetBoolean(game.pov, "currentcommandmultiobjectpending")) {
UnresolvedCommand (value, game.pov.currentcommandpendingvariable)
}
return (result)
}
}
]]></function>
<function name="ResolveNameInternal" parameters="variable, value, objtype, nodisambiguating" type="object">
// Modified by KV
if (not IsDefined("nodisambiguating")) {
nodisambiguating = false
}
game.pov.currentcommandmultiobjectpending = false
scope = GetScope(variable, value, objtype)
if (HasString(game.pov.currentcommandpattern, "scope")) {
secondaryscope = ScopeVisible()
}
else {
secondaryscope = null
}
return (ResolveNameFromList(variable, value, objtype, scope, secondaryscope, nodisambiguating))
</function>
<function name="HandleMenuTextResponse" parameters="input" type="boolean"><![CDATA[
// Modified by KV
handled = false
if (IsInt(input)) {
number = ToInt(input)
if (number > 0 and number <= ListCount(game.menuoptionskeys)) {
handled = true
if (not GetBoolean(game, "notranscript") and GetBoolean(game, "savetranscript")) {
JS.SaveTranscript ("<span><br/>> " + SafeXML(input) + "<br/></span>")
}
ShowMenuResponse (StringListItem(game.menuoptionskeys, number - 1))
}
}
else if (TypeOf (game.menuoptions) = "stringdictionary") {
foreach (opt, game.menuoptions) {
val = StringDictionaryItem(game.menuoptions, opt)
if (LCase(input) = LCase(val)) {
handled = true
if (not GetBoolean(game, "notranscript") and GetBoolean(game, "savetranscript")) {
JS.SaveTranscript ("<span><br/>> " + SafeXML(input) + "<br/></span>")
}
ShowMenuResponse (opt)
}
}
}
else if (GetBoolean (game, "disambiguating")) {
// Hide the current menu now, else it will never go away.
// HideOutputSection (game.menuoutputsection)
obj = ResolveName("object", input, "object", true)
if (obj <> null) {
handled = true
if (not GetBoolean(game, "notranscript") and GetBoolean(game, "savetranscript")) {
JS.SaveTranscript ("<span><br/>> " + SafeXML(input) + "<br/></span>")
}
ShowMenuResponse (obj.name)
}
else {
// If we make it here, we will see a second disambiguation menu appear, then both menus immediately disappear
game.disambiguating = false
}
}
else {
i = 0
foreach (opt, game.menuoptionskeys) {
if (LCase(input) = LCase(opt)) {
handled = true
if (not GetBoolean(game, "notranscript") and GetBoolean(game, "savetranscript")) {
JS.SaveTranscript ("<span><br/>> " + SafeXML(input) + "<br/></span>")
}
ShowMenuResponse (StringListItem(game.menuoptionskeys, i))
}
i = i + 1
}
}
return (handled)
]]></function>
Test game: https://textadventures.co.uk/games/view/ix7vvbrlpeoja2ftwtotta/hack-showmenu