Aight! Here’s the code for it on 6M62. (The code for 10.x would be almost the same, you just need to specify ParserKit instead of Parser.i6t.)
Include (-
Constant SCORE__CHOOSEOBJ = 1000;
Constant SCORE__IFGOOD = 500;
Constant SCORE__UNCONCEALED = 100;
Constant SCORE__BESTLOC = 60;
Constant SCORE__NEXTBESTLOC = 40;
Constant SCORE__NOTCOMPASS = 20;
Constant SCORE__NOTSCENERY = 10;
Constant SCORE__NOTACTOR = 5;
Constant SCORE__GNA = 1;
Constant SCORE__DIVISOR = 20;
Constant PREFER_HELD;
[ ScoreMatchL context its_owner its_score obj i j threshold met a_s l_s;
! if (indef_type & OTHER_BIT ~= 0) threshold++;
if (indef_type & MY_BIT ~= 0) threshold++;
if (indef_type & THAT_BIT ~= 0) threshold++;
if (indef_type & LIT_BIT ~= 0) threshold++;
if (indef_type & UNLIT_BIT ~= 0) threshold++;
if (indef_owner ~= nothing) threshold++;
#Ifdef DEBUG;
if (parser_trace >= 4) print " Scoring match list: indef mode ", indef_mode, " type ",
indef_type, ", satisfying ", threshold, " requirements:^";
#Endif; ! DEBUG
#ifdef PREFER_HELD;
a_s = SCORE__BESTLOC; l_s = SCORE__BESTLOC;
if (action_to_be == ##Take or ##Remove) {
a_s = SCORE__NEXTBESTLOC; l_s = SCORE__BESTLOC;
}
context = context; ! silence warning
#ifnot;
a_s = SCORE__NEXTBESTLOC; l_s = SCORE__BESTLOC;
if (context == HELD_TOKEN or MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN) {
a_s = SCORE__BESTLOC; l_s = SCORE__NEXTBESTLOC;
}
#endif; ! PREFER_HELD
for (i=0 : i<number_matched : i++) {
obj = match_list-->i; its_owner = parent(obj); its_score=0; met=0;
! if (indef_type & OTHER_BIT ~= 0
! && obj ~= itobj or himobj or herobj) met++;
if (indef_type & MY_BIT ~= 0 && its_owner == actor) met++;
if (indef_type & THAT_BIT ~= 0 && its_owner == actors_location) met++;
if (indef_type & LIT_BIT ~= 0 && obj has light) met++;
if (indef_type & UNLIT_BIT ~= 0 && obj hasnt light) met++;
if (indef_owner ~= 0 && its_owner == indef_owner) met++;
if (met < threshold) {
#Ifdef DEBUG;
if (parser_trace >= 4)
print " ", (The) match_list-->i, " (", match_list-->i, ") in ",
(the) its_owner, " is rejected (doesn't match descriptors)^";
#Endif; ! DEBUG
match_list-->i = -1;
}
else {
its_score = 0;
if (obj hasnt concealed) its_score = SCORE__UNCONCEALED;
if (its_owner == actor) its_score = its_score + a_s;
else
if (its_owner == actors_location) its_score = its_score + l_s;
else
if (its_owner ~= compass) its_score = its_score + SCORE__NOTCOMPASS;
its_score = its_score + SCORE__CHOOSEOBJ * ChooseObjects(obj, 2);
if (obj hasnt scenery) its_score = its_score + SCORE__NOTSCENERY;
if (obj ~= actor) its_score = its_score + SCORE__NOTACTOR;
! A small bonus for having the correct GNA,
! for sorting out ambiguous articles and the like.
if (indef_cases & (PowersOfTwo_TB-->(GetGNAOfObject(obj))))
its_score = its_score + SCORE__GNA;
match_scores-->i = match_scores-->i + its_score;
#Ifdef DEBUG;
if (parser_trace >= 4) print " ", (The) match_list-->i, " (", match_list-->i,
") in ", (the) its_owner, " : ", match_scores-->i, " points^";
#Endif; ! DEBUG
}
}
for (i=0 : i<number_matched : i++) {
while (match_list-->i == -1) {
if (i == number_matched-1) { number_matched--; break; }
for (j=i : j<number_matched-1 : j++) {
match_list-->j = match_list-->(j+1);
match_scores-->j = match_scores-->(j+1);
}
number_matched--;
}
}
];
-) instead of "ScoreMatchL" in "Parser.i6t".
This is a huge chunk of impenetrable I6. But there’s only one line that’s important in here:
a_s = SCORE__BESTLOC; l_s = SCORE__BESTLOC;
By default, this line sets a_s
(“actor score”, the bonus for being held by the actor) to SCORE__BESTLOC
(60 points), and l_s
(“location score”, the bonus for being in the location) to SCORE__NEXTBESTLOC
(40 points).
I’ve changed it to instead set both of them to SCORE__BESTLOC
. This means there’s no longer any difference between something being held, and being in the location, as far as the parser’s preferences go.
Now, there’s still a special exception in the parser that changes the a_s
and l_s
values if you’re taking or removing it from. I think this could also be scrapped, and handled by “does the player mean” rules. But for now I’m leaving it in, since it doesn’t do any harm.
If this proves useful, I’ll make sure it works in 10.x too and put it in an extension.