[Turn on line numbering]
arg str, @preference;
var obj, env, found, efound, sfound, match, target;
if (!str)
throw(~objnf, "No object specified.", str);
str = str.strip_article();
// Handle special cases.
if (str in ["me", "my", "myself"]) {
return this();
} else if (str[1] == "$" || str[1] == "#") {
return (> $object_lib.to_dbref(str) <);
} else if (str[1] == "~") {
str = str.subrange(2);
if (str[1] != "~")
return $user_db.match_begin(str);
} else if (str in ["it", "him", "her"]) {
return (| .match_context(str) |) || throw(~context, "I don't see " + str + " here, do you?");
}
// Start matching
found = [];
env = .environment();
// special case ordinal references
if ((match = $parse_lib.ordinal_reference(str)))
return (> env.match_nth(@match) <);
// standard matching
catch ~ambig, ~objnf {
return (> env.match_object(str) <);
} with {
// possessive matching
if ((match = $parse_lib.possessive_reference(str))) {
catch ~objnf, ~ambig, ~range {
if (match[1] == "me") {
obj = this();
} else {
target = match[1];
obj = (> env.match_object(match[1], 'possessive) <);
}
env = (| obj.contents() |) || [];
target = match[2];
if ((found = $parse_lib.ordinal_reference(match[2]))) {
return (> env.match_nth(@found) <);
} else {
// this becomes a problem, especially with exits, too broad...
return (> env.match_object(match[2], 'possessive) <);
}
} with {
if (type(obj) == 'objnum && obj.match_for_environment(match[2], 'possessive))
throw(~self, "\"" + target + "\" matches self?" + obj, [obj, @match]);
else if (error() == ~objnf)
throw(~objnf, obj.name() + " does not have " + match[2].add_indefinite() + ".");
else if (error() == ~ambig)
throw(~ambig, "\"" + target + "\" (" + str + ") can match " + traceback()[1][3].mmap('namef, 'ref).to_english("", " or ") + ".");
else
throw(~objnf, obj.name() + "'s what?");
}
} else {
if (error() == ~objnf)
throw(~objnf, "You do not see " + str.add_indefinite() + " anywhere.");
// handle ambiguous matches, start with exact match
efound = filter obj in (traceback()[1][3]) where (obj.name() == str);
if (listlen(efound) == 1)
return efound[1];
// if not exact match, check for preferencial ancestors
if (listlen(preference)) {
[preference] = preference;
found = filter obj in (traceback()[1][3]) where (obj.is(preference));
if (listlen(found) == 1)
return found[1];
}
if (efound) {
sfound = efound.mmap('namef, 'ref).to_english("", " or ");
} else {
efound = traceback()[1][3];
sfound = efound.mmap('namef, 'ref).to_english("", " or ");
}
throw(~ambig, "\"" + str + "\" can match " + sfound + ".", efound);
}
rethrow(error());
}
// $#Edited: 19 Apr 04 22:32 $brandon
["// Created 26-Mar-1995 as a part of ColdCore, see: @help Credit"]