Yep, that's also true for German.
We have some non-prepositional phrases where distinguishing between dobj and iobj can be difficult and we have verbs which have another meaning when used with a certain kind of thing.
e.g.:
>show man hat
>zeig dem Mann den Hut
or
>show hat man
>zeig den Hut dem Mann
We have the dative case here, but it's too vague to be reliable and we have too much irregular declinations in German.
In former versions of the lib I had a simple remapping which changes the dobj and iobj when necessary. But this is not ideal, because there is only one remapping per action allowed, so that the author cannot use this any more.
Now I came up with that code -- thanks to Eric Eve and his DupDobj.t extension which brought me to right point, I guess.
Code:
modify TIAction
preferredIobj = nil
replace doActionMain()
{
local lst;
local preAnnouncedDobj;
local preAnnouncedIobj;
/*
* Get the list of resolved objects for the multiple object. If
* neither has multiple objects, it doesn't matter which is
* iterated, since we'll just do the command once anyway.
*/
lst = (iobjList_.length() > 1 ? iobjList_ : dobjList_);
/*
* Set the pronoun antecedents, using the game-specific pronoun
* setter. Don't set an antecedent for a nested command.
*/
if (parentAction == nil)
{
/*
* Set both direct and indirect objects as potential
* antecedents. Rather than trying to figure out right now
* which one we might want to refer to in the future, remember
* both - we'll decide which one is the logical antecedent
* when we find a pronoun to resolve in a future command.
*/
gActor.setPronounMulti(dobjList_, iobjList_);
/*
* If one or the other object phrase was specified in the
* input as a pronoun, keep the meaning of that pronoun the
* same, overriding whatever we just did. Note that the
* order we use here doesn't matter: if a given pronoun
* appears in only one of the two lists, then the list where
* it's not set has no effect on the pronoun, hence it
* doesn't matter which comes first; if a pronoun appears in
* both lists, it will have the same value in both lists, so
* we'll just do the same thing twice, so, again, order
* doesn't matter.
*/
setPronounByInput(dobjList_);
setPronounByInput(iobjList_);
}
/*
* pre-announce the non-list object if appropriate - this will
* provide a common pre-announcement if we iterate through
* several announcements of the main list objects
*/
if (lst == dobjList_)
{
/* pre-announce the single indirect object if needed */
preAnnouncedIobj = preAnnounceActionObject(
iobjList_[1], dobjList_, IndirectObject);
/* we haven't announced the direct object yet */
preAnnouncedDobj = nil;
/* pre-calculate the multi-object announcements */
cacheMultiObjectAnnouncements(dobjList_, DirectObject);
}
else
{
/* pre-announce the single direct object if needed */
preAnnouncedDobj = preAnnounceActionObject(
dobjList_[1], iobjList_, DirectObject);
/* we haven't announced the indirect object yet */
preAnnouncedIobj = nil;
/* pre-calculate the multi-object announcements */
cacheMultiObjectAnnouncements(iobjList_, IndirectObject);
}
/* we haven't yet canceled the iteration */
iterationCanceled = nil;
/* iterate over the resolved list for the multiple object */
for (local i = 1, local len = lst.length() ;
i <= len && !iterationCanceled ; ++i)
{
local dobjInfo;
local iobjInfo;
/*
* make the current list item the direct or indirect object,
* as appropriate
*/
if (lst == dobjList_)
{
/* the direct object is the multiple object */
dobjInfo = dobjInfoCur_ = lst[i];
iobjInfo = iobjInfoCur_ = iobjList_[1];
}
else
{
/* the indirect object is the multiple object */
dobjInfo = dobjInfoCur_ = dobjList_[1];
iobjInfo = iobjInfoCur_ = lst[i];
}
// -- here goes the magic code
// -- we have now resolved objects for indirect and direct slots
if (preferredIobj != nil) {
if (dobjInfo.obj_.ofKind(preferredIobj)) {
/* change both objects */
dobjCur_ = iobjInfo.obj_;
iobjCur_ = dobjInfo.obj_;
}
else {
/* get the current dobj and iobj from the resolve info */
dobjCur_ = dobjInfo.obj_;
iobjCur_ = iobjInfo.obj_;
}
}
/*
* if the action was remapped, and we need to announce
* anything, announce the entire action
*/
if (isRemapped())
{
/*
* We were remapped. The entire phrasing of the new
* action might have changed from what the player typed,
* so it might be nonsensical to show the objects as we
* usually would, as sentence fragments that are meant
* to combine with what the player actually typed. So,
* instead of showing the usual sentence fragments, show
* the entire phrasing of the command.
*
* Only show the announcement if we have a reason to: we
* have unclear disambiguation in one of the objects, or
* one of the objects is defaulted.
*
* If we don't want to announce the remapped action,
* still consider showing a multi-object announcement,
* if we would normally need to do so.
*/
if (needRemappedAnnouncement(dobjInfo)
|| needRemappedAnnouncement(iobjInfo))
{
/* show the remapped announcement */
gTranscript.announceRemappedAction();
}
else
{
/* announce the multiple dobj if necessary */
if (!preAnnouncedDobj)
maybeAnnounceMultiObject(
dobjInfo, dobjList_.length(), DirectObject);
/* announce the multiple iobj if necessary */
if (!preAnnouncedIobj)
maybeAnnounceMultiObject(
iobjInfo, iobjList_.length(), IndirectObject);
}
}
else
{
/* announce the direct object if appropriate */
if (!preAnnouncedDobj)
announceActionObject(dobjInfo, dobjList_.length(),
DirectObject);
/* announce the indirect object if appropriate */
if (!preAnnouncedIobj)
announceActionObject(iobjInfo, iobjList_.length(),
IndirectObject);
}
/* run the execution sequence for the current direct object */
doActionOnce();
/* if we're top-level, count the iteration in the transcript */
if (parentAction == nil)
gTranscript.newIter();
}
}
;
VerbRule(ShowTo)
'zeig' dobjList singleIobj
: ShowToAction
verbPhrase = 'zu zeigen/zeigen (was) (dativ wem)'
askIobjResponseProd = singleNoun
/* this is a non-prepositional phrasing */
isPrepositionalPhrasing = nil
preferredIobj = Actor
;
Pretty much of the code is just simply copied from the doActionMain() method. Here is what this does:
It sets a new property for TIAction preferredIobj. When set to a certain kind of thing, it checks in doActionMain() from TIAction if there is a dobj which seems better in the iobj slot, and then changes both. This seems to work fine so far.
Greetings,
-- MI