Page 1 of 1

"FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Posted: Sun Apr 10, 2011 2:35 am
by Veomunn
Hello there! I'm new to scripting, and am currently on a crusade to get this script to compile. It's part of an NPC's user-defined script, and *should*, when it begins attacking a door, cause it to cease combat and initiate its conversation.

I'm probably making an obvious mistake. Here's that section of the script:

Code: Select all

int GetIsFighting()
{
    object oAttack = GetAttemptedAttackTarget();
    object oSideDoor = GetObjectByTag("Side_Ext")
    object oObjectToConverseWith = GetFirstPC();
    if(oAttack = oSideDoor)
    {
    ClearAllActions(int nClearCombatState=TRUE)
    ActionStartConversation(object oObjectToConverseWith, int bPrivateConversation=FALSE, int bPlayHello=TRUE)
    }
    else return
}
"Side_Ext" is the tag of the door to be attacked.

I'd greatly appreciate any advice.

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Posted: Sun Apr 10, 2011 3:37 am
by Gorgon
Someone may be better at explaining (and I'm a n00b as well anyways), but try this:

Code: Select all

void GetIsFighting()
{
    object oAttack = GetAttemptedAttackTarget();
    object oSideDoor = GetObjectByTag("Side_Ext");
    object oObjectToConverseWith = GetFirstPC();

    if(oAttack == oSideDoor)
    {
        ClearAllActions(TRUE);
        ActionStartConversation(oObjectToConverseWith);
    }
    else return;
}
Since you aren't returning anything from the function, it would be

Code: Select all

void GetIsFighting()
not

Code: Select all

int GetIsFighting()
int returns and integer value, while void returns nothing. Also remember to use == and not = when comparing things in

Code: Select all

if(oAttack == oSideDoor)
or else you are setting oAttack to equal oSideDoor.
The ; at the end of each line is also something to keep an eye out for.

The big ones you'd have trouble with are:

Code: Select all

    ClearAllActions(int nClearCombatState=TRUE)
    ActionStartConversation(object oObjectToConverseWith, int bPrivateConversation=FALSE, int bPlayHello=TRUE)
You only need to add the value (TRUE/FALSE or whatever), not the type or name. That is already set in the function. You also only need to add it from the point where it isn't the default, but you can't ever skip a value. While this uses the defaults for everything after the object value (hence why I left the rest out),

Code: Select all

ActionStartConversation(oObjectToConverseWith);
you couldn't actually use the values you had there without the missing

Code: Select all

string sDialogResRef=""
The whole function is:

Code: Select all

void ActionStartConversation(object oObjectToConverseWith, string sDialogResRef="", int bPrivateConversation=FALSE, int bPlayHello=TRUE)
So if you wanted to include everything anyways, it would be:

Code: Select all

ActionStartConversation(oObjectToConverseWith, "", FALSE, TRUE);

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Posted: Sun Apr 10, 2011 9:32 am
by PsiOmega
Changing the return type from int to void as Gorgon suggests will probably fix the particular error that you're getting. His other suggestions should help fix a few more errors that will come up as well.

This error happens when you've got a so-called function prototype, which tells the compiler which arguments the function takes and what type it returns, and it doesn't match the implementation. In some cases you also get this error when including a script that has a function of the same name but more often that causes a duplicate implementation error.

Example of different definition/implementations. Different return type and different arguments respectively.

Code: Select all

//These are prototypes/definitions
void ANiftyFunction();
int ANiftierFunction(int dice);

//These are implementations
int ANiftyFunction()
{
    return d6();
}

int ANiftierFunction()
{
    return d12();
}
And the same definition/implementation

Code: Select all

int ABetterFunction(int dice);

int ABetterFunction(int dice)
{
    return d6(dice);
}

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Posted: Mon Apr 11, 2011 6:54 am
by Veomunn
Thanks a bunch, guys. The script itself is fine now, and compiles on its own. :) But, here's something interesting:

When I compile the UserDefined script now, I get the same error, but a different line is hilighted: in fact, a line from another file. I kid you not: as I press ctrl+s, a tab with "x0_inc_generic" pops up, and the following line is hilighted, with the same error type as before:

Code: Select all

int GetIsFighting(object oFighting);
Later in that file, GetIsFighting seems to actually be defined. Here's the "definition" I see:

Code: Select all

int GetIsFighting(object oFighting)
{
    object oAttack = GetAttemptedAttackTarget();
    object oSpellTarget = GetAttemptedSpellTarget();

    if(GetIsObjectValid(oAttack) || GetIsObjectValid(oSpellTarget))
    {
        return TRUE;
    }
    return FALSE;
}
Now, back to the UserDefined file. Here's the section both of you helped me revise:

Code: Select all

void CheckForDisabledPartyMembers()
{
    object oMaster = GetMaster(OBJECT_SELF);
    if(oMaster != OBJECT_INVALID)
        CheckCreature(oMaster);
    int i = 1;
    object oHench = GetHenchman(oMaster, i);
    while(oHench != OBJECT_INVALID)
    {
        CheckCreature(oHench);
        i++;
        oHench = GetHenchman(oMaster, i);
    }
}
Could it be that "CheckForDisabledPartyMembers()" can only be used to determine whether or not the caller is in combat, full stop, not including the extra functions I wanted to use, causing the error? I was previously working under the assumption that "CheckForDisabledPartyMembers()" would go ahead and determine whether the NPC is in combat so I could further narrow that criteria, then give an effect if they are in combat with something in particular.

Either way, thanks again. This was the first issue I couldn't resolve with time and Google searches, so hopefully someone can see this one day and solve their problems, also.

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Posted: Mon Apr 11, 2011 9:17 am
by Gorgon
In this case it looks like you have x0_inc_generic as an include file somewhere in your script, which should look like:

Code: Select all

#include "x0_inc_generic"
and the version of GetIsFighting() there returns either TRUE (1) or FALSE (0), so that is why it is an int instead of void function. It sounds like Psi was right when he said:
In some cases you also get this error when including a script that has a function of the same name but more often that causes a duplicate implementation error.
You now have redone a function as a void with the same name, but the definition in the include file still says it is an int. If you want to use the remade function, give it a new name, and it should work fine.

I don't know how the other code fits in with this, without seeing the entire script, so hopefully that helps.

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Posted: Tue Apr 19, 2011 12:39 am
by dougnoel
You can also just put another definition in the include file that has the alternate return type. It can differentiate between the two.

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Posted: Tue Apr 19, 2011 3:17 am
by Gorgon
Changing/adding a new definition in x0_inc_generic, or editing your custom script instead, is a pretty easy choice. Don't mess with the Bioware stuff unless you have to. In the case of Avlis scripting, you'd need a very good reason to mess with stock scripts too, but this is general nwn scripting. Either way, if you can change your custom script, instead of overriding/editing a stock Bioware one, do it.

*edits to add* No, I didn't just argue against a reply from one of the people who knows far more about scripting stuff than I wish I did, honest... *hides*

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Posted: Wed Apr 20, 2011 12:06 pm
by PlasmaJohn
dougnoel wrote:You can also just put another definition in the include file that has the alternate return type. It can differentiate between the two.
Really? Most c-alikes only consider it different if the argument list is different.

Code: Select all

void foo() {
    // stuff
}

int foo() {
    // other stuff;
    return 0;
}

void main() {
    foo(); // which foo did it pick?  both are legal in this context
}
Regardless, you're much better off changing the name of your function otherwise you'll just set yourself up for some very subtle bugs in the future.