More Intuitive String Matching For Objects

Liam315
I started to find it annoying in some cases where I referred to an object and a disambiguation menu was presented even though I was obviously referring to object1 and not object2.

e.g.
object 1 is a rusty key
object 2 is a piano, and one of the alternate names is "piano keys".

With the current code, Quest gives equal weighting to both so if you type "examine key" it will ask you if you mean the rusty key or the piano.

I edited the in built functions ResolveNameInternal and CompareNames so now preference is given to an object if any of its names contain a whole word that matches the input.

Below is a copy of each of the modified functions. The parameter "semifullmatches" must also be added to the CompareNames function.

ResolveNameInternal
fullmatches = NewObjectList()
partialmatches = NewObjectList()
semifullmatches = NewObjectList()
game.pov.currentcommandmultiobjectpending = false
if (objtype = "object") {
scope = ScopeVisible()
}
else if (objtype = "exit") {
scope = ScopeExits()
}
value = Trim(value)
foreach (obj, scope) {
name = LCase(GetDisplayAlias(obj))
CompareNames (name, value, obj, fullmatches, partialmatches, semifullmatches)
if (obj.alt <> null) {
foreach (altname, obj.alt) {
CompareNames (LCase(altname), value, obj, fullmatches, partialmatches, semifullmatches)
}
}
}
if (game.lastobjects <> null) {
foreach (obj, game.lastobjects) {
CompareNames (LCase(obj.article), value, obj, fullmatches, partialmatches, semifullmatches)
CompareNames (LCase(obj.gender), value, obj, fullmatches, partialmatches, semifullmatches)
}
}
if (ListCount(fullmatches) = 1) {
return (ListItem(fullmatches, 0))
}
else if (ListCount(fullmatches) = 0 and ListCount(semifullmatches) = 1) {
return (ListItem(semifullmatches, 0))
}
else if (ListCount(fullmatches) = 0 and ListCount(semifullmatches) = 0 and ListCount(partialmatches) = 1) {
return (ListItem(partialmatches, 0))
}
else if (ListCount(fullmatches) + ListCount(partialmatches) + ListCount(semifullmatches) = 0) {
return (null)
}
else {
menu = NewStringDictionary()
GenerateMenuChoices (menu, fullmatches)
GenerateMenuChoices (menu, semifullmatches)
GenerateMenuChoices (menu, 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), menu, 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), menu, true) {
if (result <> null) {
list add (game.pov.currentcommandpendingobjectlist, GetObject(result))
ResolveNextNameListItem
}
}
}
return (null)
}


CompareNames
if (name = value) {
if (not ListContains(fullmatches, obj)) {
list add (fullmatches, obj)
}
}
else {
if (StartsWith(name, value)) {
if (LengthOf(value) = (Instr(name, " ") - 1)) {
if (not ListContains(semifullmatches, obj)) {
list add (semifullmatches, obj)
}
}
else {
if ((not ListContains(partialmatches, obj)) and (not ListContains(semifullmatches, obj))) {
list add (partialmatches, obj)
}
}
}
else if (Instr(name, " " + value + " ") > 0) {
if (not ListContains(semifullmatches, obj)) {
list add (semifullmatches, obj)
}
}
else {
// check if input matches the start of any word in the name
if (Instr(name, " " + value) > 0) {
if (LengthOf(name) - Instr(name, " " + value) = LengthOf(value)) {
if (not ListContains(semifullmatches, obj)) {
list add (semifullmatches, obj)
}
}
else {
if ((not ListContains(partialmatches, obj)) and (not ListContains(semifullmatches, obj))) {
list add (partialmatches, obj)
}
}
}
}
}


If anyone finds any problems in these please let me know.

Edited to prevent certain objects from appearing twice in disambiguation menu.

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

Support

Forums