"FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Moderators: Nighthawk4, Dungeon Masters

Post Reply
Veomunn
Newbie
Posts: 2
Joined: Sun Apr 10, 2011 2:27 am

"FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Post by Veomunn » Sun Apr 10, 2011 2:35 am

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.

User avatar
Gorgon
CCC - Special Projects Manager
CCC - Special Projects Manager
Posts: 6250
Joined: Fri Oct 17, 2003 10:14 pm
Timezone: PDT -7
Location: Vancouver, BC, Canada

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Post by Gorgon » Sun Apr 10, 2011 3:37 am

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);
"God not only plays dice, he throws them in the corner where you can't see them."
-- Stephen William Hawking (b. 1942) --


Sprucing up ye olde NWN | Modifying nwn.ini and nwnplayer.ini | ~Rare Items Wanted~ | Stealth Modifiers

User avatar
PsiOmega
CCC
CCC
Posts: 4889
Joined: Tue Jun 08, 2004 4:55 pm
Timezone: GMT+1/+2 (DST)
Location: Sweden
Contact:

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Post by PsiOmega » Sun Apr 10, 2011 9:32 am

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);
}
Science is a candle in the dark.
Docendo discimus.

Veomunn
Newbie
Posts: 2
Joined: Sun Apr 10, 2011 2:27 am

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Post by Veomunn » Mon Apr 11, 2011 6:54 am

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.

User avatar
Gorgon
CCC - Special Projects Manager
CCC - Special Projects Manager
Posts: 6250
Joined: Fri Oct 17, 2003 10:14 pm
Timezone: PDT -7
Location: Vancouver, BC, Canada

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Post by Gorgon » Mon Apr 11, 2011 9:17 am

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.
"God not only plays dice, he throws them in the corner where you can't see them."
-- Stephen William Hawking (b. 1942) --


Sprucing up ye olde NWN | Modifying nwn.ini and nwnplayer.ini | ~Rare Items Wanted~ | Stealth Modifiers

dougnoel
Team Member; Retired with Honors
Posts: 6265
Joined: Fri May 14, 2004 4:59 pm
Location: VA (GMT -4)
Contact:

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Post by dougnoel » Tue Apr 19, 2011 12:39 am

You can also just put another definition in the include file that has the alternate return type. It can differentiate between the two.

User avatar
Gorgon
CCC - Special Projects Manager
CCC - Special Projects Manager
Posts: 6250
Joined: Fri Oct 17, 2003 10:14 pm
Timezone: PDT -7
Location: Vancouver, BC, Canada

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Post by Gorgon » Tue Apr 19, 2011 3:17 am

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*
"God not only plays dice, he throws them in the corner where you can't see them."
-- Stephen William Hawking (b. 1942) --


Sprucing up ye olde NWN | Modifying nwn.ini and nwnplayer.ini | ~Rare Items Wanted~ | Stealth Modifiers

User avatar
PlasmaJohn
Team Member; Retired with Honors; Has a Tom Selleck Stache
Posts: 8846
Joined: Fri Dec 26, 2003 10:37 pm
Timezone: US/Eastern
Location: Tyria
Contact:

Re: "FUNCTION IMPLEMENTATION AND DEFINTITION DIFFER" error

Post by PlasmaJohn » Wed Apr 20, 2011 12:06 pm

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.
Calvin: This is so cool!
Hobbes: This is so stupid.

Post Reply