This is a subroutine you can use to force enemies to attack a certain target for a specified period of time, it’s particularly useful if you intend to design abilities that work like those taunts of mmorpgs rather than the (imho kinda dull and pointless) standard taunt of NWN2.
//Forces oTARGET to attack oPC for at least fDUR Seconds.
void RunTaunt(object oPC, object oTARGET, float fDUR)
{
object oTAUNT = GetLocalObject(oTARGET, "TAUNT_SOURCE");
if ((oTAUNT != oPC) && (oTAUNT != OBJECT_INVALID)) return; //Someone else is already taunting the target.
float fTAUNT = GetLocalFloat(oTARGET, "TAUNT_DUR");
if (fTAUNT >= fDUR)
{
//Taunt ends.
DeleteLocalFloat(oTARGET, "TAUNT_DUR");
DeleteLocalObject(oTARGET, "TAUNT_SOURCE");
}
else
{
if (GetCurrentAction(oTARGET) != ACTION_CASTSPELL)
{
//This is to make sure that taunt does not interrupt spellcasting.
AssignCommand(oTARGET, ClearAllActions());
AssignCommand(oTARGET, ActionAttack(oPC));
}
if (oTAUNT != oPC)
{
//This also applies a visual taunt effect. This should run only once despite the recursive call.
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectVisualEffect(VFX_DUR_TAUNT)), oTARGET, fDUR);
SetLocalObject(oTARGET, "TAUNT_SOURCE", oPC);
}
SetLocalFloat(oTARGET, "TAUNT_DUR", fTAUNT + 0.5);
DelayCommand(0.5, RunTaunt(oPC, oTARGET, fDUR));
}
}
Really nice, I’ve been wanting something like this for NWN/NWN 2. Just as a general suggestion, though, I think it might be a good idea to put in some way for the target to resist the effect. Possibly a will save, or a chance to resist proportional to Intelligence and/or Wisdom. It would just make sense for smarter/more prudent enemies to not fall for simple misdirection tactics, and it would force the player to rely on more complex tactics (such as a backup plan for smarter enemies, or just turning smarter enemies into dumber ones using a spell like Feeblemind).
This is just a function to force the target to attack the taunter, it’s up to the scripter to implement it the way he pleases.
for example, if he wants to gate it trough a will save, all he has to do is (I post in pseudo-code cause I don’t remeber the exact function right off the bat):
If (Willsave(oTARGET, nDC) == FAIL) RunTaunt(oPC, oTARGET, 6.0);
@Clangeddin I know this is over a year old, but was a this a script for just NWN2 or would it work in NWN1. I attempted to compile it and it will not. With the code Error: Unknown State in Compiler. Thanks in advance.
Which line gave that compiling error?
Anyways, I believe I have remade this for NWN1 Enhanced, so I’m gonna the new improved subroutine.
void LockOnTarget(object oPC)
{
if (GetAttackTarget() == oPC) return;
if (GetAttemptedAttackTarget() == oPC) return;
if (GetCurrentAction() == ACTION_CASTSPELL) return;
ClearAllActions();
ActionAttack(oPC);
}
//Forces oTARGET to attack oPC for at least fDUR Seconds.
//sVAR is set to "TAUNTED" on default. It's the name of the local variable used to avoid multiple taunts conflicting each other.
//nSTART is set to TRUE on default, and it's best to never touch that parameter.
void RunTaunt(object oPC, object oTARGET, float fDUR, string sVAR = "TAUNTED", int nSTART = TRUE)
{
if (fDUR <= 0.0f)
{
DeleteLocalInt(oTARGET, sVAR);
return;
}
if (GetIsDead(oPC) == TRUE)
{
DeleteLocalInt(oTARGET, sVAR);
return;
}
if (GetIsDead(oTARGET) == TRUE)
{
DeleteLocalInt(oTARGET, sVAR);
return;
}
if (nSTART == TRUE)
{
if (GetLocalInt(oTARGET, sVAR) == TRUE) return;
SetLocalInt(oTARGET, sVAR, TRUE);
}
AssignCommand(oTARGET, LockOnTarget(oPC));
DelayCommand(0.5, RunTaunt(oPC, oTARGET, fDUR - 0.5, sVAR, FALSE));
}
Remember that you will need both subroutines for this to work (using an #include file would be the easiest way)
void RunTaunt(object oPC, object oTARGET, float fDUR)
Was the error.
I can tell you what’s wrong with it, if you show me the script where you implement the subroutine.
This should definitely compile.