Polymorph bug? - Using ga_effect_polymorph

I just tried to use ga_effect_polymorph in a conversation, but the weird thing is, the PC polymorphs for a second but then turns back again. I first tried with Permanent and then Instant, but it’s the same result.
Is this a bug? Do I really need to do a custom script for this?

EDIT: Since I got no reply, I just created a custom script. Now everything works. I still wonder why the stock script doesn’t work though.

1 Like

Confirmed. That script is bugged. More specifically, the GetDurationType function is bugged. I’ll report my findings on the nwn2fixes thread. In the meantime, here is a corrected ga_effect_polymorph script for those that might need it:

// ga_effect_polymorph
/*
	Does a polymorph effect on the specified target.  
	Params:
		string sTarget - Uses the standard GetTarget() function, default is the PC Speaker (or OBJECT_SELF from Command Console)
		int nPolymorphSelection - row number from polymorph.2da
    	int nLocked - If 1 (TRUE), player can't cancel polymorph 
		string sDurationType - I - Instant (default), P - Permanent, or T - Temporary w/ specified duration
		float fTemporaryDuration - applies only if duration is Temporary.
*/
// ChazM 4/16/07
// travus 6/11/23 - Changed the GetDurationType method as the original was bugged.

#include "ginc_param_const"

int NewGetDurationType(string sType)
{
	sType = GetStringUpperCase(sType);
	int iType = DURATION_TYPE_INSTANT;
	
	if (FindSubString(sType, "P") == 0)
		iType = DURATION_TYPE_PERMANENT;
	
	else if (FindSubString(sType, "T") == 0)
		iType = DURATION_TYPE_TEMPORARY;
	
	return (iType);
}

string GetStandardTargetDefualt()
{
	object oPC = GetPCSpeaker();
	string sTargetDefault;
	
	if (oPC == OBJECT_INVALID)
	{   // script is not being run from a conversation with a PC speaker so assume it is from a console command.
		sTargetDefault = "$OBJECT_SELF";
	}
	
	else
	{	// script run from convo, so default to PC
		sTargetDefault = "$PC";
	}
	
	return (sTargetDefault);	
}
	
void main(string sTarget, int nPolymorphSelection, int nLocked, string sDurationType, float fTemporaryDuration)
{
	object oTarget = GetTarget(sTarget, GetStandardTargetDefualt());
//	int nDurationType = GetDurationType(sDurationType);				//
	int nDurationType = NewGetDurationType(sDurationType);			// travus change
	effect ePoly = EffectPolymorph(nPolymorphSelection, nLocked);

	ApplyEffectToObject(nDurationType, ePoly, oTarget, fTemporaryDuration);
	
	PrintString ("Applied polymorph effect to " + GetName(oTarget) + " with Duration " + IntToString(nDurationType) + " " + FloatToString(fTemporaryDuration));
}
3 Likes

@travus - Thank you for clearing that out!

1 Like