Hey guys,
I've been using the NPC Activities scripts, very useful, can't thank Deva Winblood and Qlippoth enough!
The 6.1 Documentation tells me I can turn OFF NPC activities for an NPC as follows:
Here is the basic anatomy of a script that disables NPC ACTIVITIES and then enables it when it is done doing its actions: Script is in standard text while my
comments about the script are in Orange.
void main()
{
SetLocalInt(OBJECT_SELF,â€nGNBDisabledâ€,TRUE);
This line disables NPC ACTIVITIES so, its anti-stuck behavior will
not interfere with your script. NOTE: It is important that you put
fail safes in place to turn this back to FALSE. If anything goes wrong
in your script or you fail to set this back to FALSE then this NPC
will just stand there and do nothing of interest from this point on.
Put all your own script code here
You will need to handle everything you want done here. Though some
include files to help you will be provided to help you.
SetLocalInt(OBJECT_SELF,â€nGNBDisabledâ€,FALSE);
Like I indicated it is important that this happen. In fact as a fail safe if you
know the maximum amount of time this script should take and say it is no
more than 20 seconds. You should put this line as the first line before
disabling it just as a fail safe. This is in addition to this last line. They
will not interfere with each other and this last line will cause NPC
ACTIVITIES to kick back in as quickly as possible. However, if for some
reason it never makes it to this last line then use this as your first line as a
backup.
DelayCommand(20.0,SetLocalInt(OBJECT_SELF,â€nGNBDisabledâ€,
FALSE));
This can save your script from locking up the NPC completely.
}
So, if I were to provide you of say a script called anvilpounder that could be
called using the @script this is what it might look like:
void main()
{
DelayCommand(30.0,SetLocalInt(OBJECT_SELF,â€nGNBDisabledâ€,FALSE));
SetLocalInt(OBJECT_SELF,â€nGNBDisabledâ€,TRUE);
object oAnvil=GetNearestObjectByTag(“Anvilâ€);
ActionMoveToObject(oAnvil);
ActionAttack(oAnvil,TRUE);
SetLocalInt(OBJECT_SELF,â€nGNBDisabledâ€,FALSE);
}
In this example I placed the fail safe as the first line. If within 30 seconds this script has not completed its course it will enable NPC ACTIVITIES again. So, at that point if the NPC is in fact stuck then the anti-stuck code can kick in. An example of why
this might happen is if the NPC does indeed find an Anvil but, they cannot get to it for some reason or it is taking much longer than 30 seconds. You definitely would not want your NPC to perpetually try to get to that anvil and forsake everything else.
I hope this explains it. If you were to save the above script right now as anvilpounder. You could then put @anvilpounder anywhere in your waypoint and it
will work and can be used by any NPC with no further scripting. In fact, at this point
you have made a script that a NON-SCRIPTER can use.
But every attempt to turn on nGNBDisabled in my module results in the NPC pausing briefly and then continuing on his merry NPC Activities way. I'm not even sure if the NPC actually pauses.
This is very critical to my module, as I DM it, and often need to make an NPC stop for a while to interact with the PCs.
I thought there might be something I was doing wrong, so I created an item called "nGNBDisabled", gave it Cast Spell Unique Power and a script with the same name, as follows:
//::///////////////////////////////////////////////
//:: Example Item Event Script
//:: x2_it_example
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
This is an example of how to use the
new default module events for NWN to
have all code concerning one item in
a single file.
Note that this system only works if
the following scripts are set in your
module events
OnEquip - x2_mod_def_equ
OnUnEquip - x2_mod_def_unequ
OnAcquire - x2_mod_def_aqu
OnUnAcqucire - x2_mod_def_unaqu
OnActivate - x2_mod_def_act
*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-09-10
//:: Modified By: Grimlar
//:: Modified On: March 2004
//:://////////////////////////////////////////////
#include "x2_inc_switches"
void main()
{
int nEvent = GetUserDefinedItemEventNumber(); //Which event triggered this
object oPC; //The player character using the item
object oItem; //The item being used
object oSpellOrigin; //The origin of the spell
object oSpellTarget; //The target of the spell
int iSpell; //The Spell ID number
//Set the return value for the item event script
// * X2_EXECUTE_SCRIPT_CONTINUE - continue calling script after executed script is done
// * X2_EXECUTE_SCRIPT_END - end calling script after executed script is done
int nResult = X2_EXECUTE_SCRIPT_END;
switch (nEvent)
{
case X2_ITEM_EVENT_ONHITCAST:
// * This code runs when the item has the 'OnHitCastSpell: Unique power' property
// * and it hits a target(if it is a weapon) or is being hit (if it is a piece of armor)
// * Note that this event fires for non PC creatures as well.
oItem = GetSpellCastItem(); // The item triggering this spellscript
oPC = OBJECT_SELF; // The player triggering it
oSpellOrigin = OBJECT_SELF ; // Where the spell came from
oSpellTarget = GetSpellTargetObject(); // What the spell is aimed at
//Your code goes here
break;
case X2_ITEM_EVENT_ACTIVATE:
// * This code runs when the Unique Power property of the item is used or the item
// * is activated. Note that this event fires for PCs only
{
oPC = GetItemActivator(); // The player who activated the item
oItem = GetItemActivated(); // The item that was activated
object oTarget = GetItemActivatedTarget();
int nGNBDisabled = GetLocalInt(oTarget,"nGNBDisabled");
FloatingTextStringOnCreature("nGNBDisabled is " +IntToString(GetLocalInt(oTarget,"nGNBDisabled")),oTarget, TRUE);
SendMessageToAllDMs("nGNBDisabled is " +IntToString(GetLocalInt(oTarget,"nGNBDisabled")));
if (nGNBDisabled == TRUE) SetLocalInt(oTarget,"nGNBDisabled",FALSE);
else if (nGNBDisabled == FALSE) SetLocalInt(oTarget,"nGNBDisabled",TRUE) ;
FloatingTextStringOnCreature("nGNBDisabled is " +IntToString(GetLocalInt(oTarget,"nGNBDisabled")),oTarget, TRUE);
SendMessageToAllDMs("nGNBDisabled is " +IntToString(GetLocalInt(oTarget,"nGNBDisabled")));
break;
}
case X2_ITEM_EVENT_EQUIP:
// * This code runs when the item is equipped
// * Note that this event fires for PCs only
oPC = GetPCItemLastEquippedBy(); // The player who equipped the item
oItem = GetPCItemLastEquipped(); // The item that was equipped
//Your code goes here
break;
case X2_ITEM_EVENT_UNEQUIP:
// * This code runs when the item is unequipped
// * Note that this event fires for PCs only
oPC = GetPCItemLastUnequippedBy(); // The player who unequipped the item
oItem = GetPCItemLastUnequipped(); // The item that was unequipped
//Your code goes here
break;
case X2_ITEM_EVENT_ACQUIRE:
// * This code runs when the item is acquired
// * Note that this event fires for PCs only
oPC = GetModuleItemAcquiredBy(); // The player who acquired the item
oItem = GetModuleItemAcquired(); // The item that was acquired
//Your code goes here
break;
case X2_ITEM_EVENT_UNACQUIRE:
// * This code runs when the item is unacquired
// * Note that this event fires for PCs only
oPC = GetModuleItemLostBy(); // The player who dropped the item
oItem = GetModuleItemLost(); // The item that was dropped
//Your code goes here
break;
case X2_ITEM_EVENT_SPELLCAST_AT:
//* This code runs when a PC or DM casts a spell from one of the
//* standard spellbooks on the item
oPC = OBJECT_SELF; // The player who cast the spell
oItem = GetSpellTargetObject(); // The item targeted by the spell
iSpell = GetSpellId(); // The id of the spell that was cast
// See the list of SPELL_* constants
//Your code goes here
//Change the following line from X2_EXECUTE_SCRIPT_CONTINUE to
//X2_EXECUTE_SCRIPT_END if you want to prevent the spell that was
//cast on the item from taking effect
nResult = X2_EXECUTE_SCRIPT_CONTINUE;
break;
}
//Pass the return value back to the calling script
SetExecutedScriptReturnValue(nResult);
}
As you can see, all my script does is flip the nGNBDisabled integer, and inform the DM of the change.
It works. But has no effect on my NPCs, who ignore nGNBDisabled, and keep doing their own thing.
Okay, maybe something wrong with my module, I thought.
So I opened Deva Winblood's version 6.0 demo module, and added my item and my script. Tested that. Nope, the NPCs ignore the nGNBDisabled integer, and keep doing their own thing.
Maybe the bug was fixed in a later version, I thought.
Imported the v6.1 scripts into the 6.0 demo module. Tested that. Nope, the NPCs ignore the nGNBDisabled integer, and keep doing their own thing.
Opened Quippoth's v6.2 Pathways Demo. Added my script and my item. Nope, the NPCs ignore the nGNBDisabled integer, and keep doing their own thing. ARRRRRGGGGGHHHHH...!
I've looked through the code, but haven't found a solution. The NPC Activities code does check for the nGNBDisabled integer, but some "anti-stuck" code, somewhere, is overruling it, I believe.
Has anyone else come up against this problem? How do you turn off NPC Activities for an NPC - and have it stay off?
NPC Activities: http://neverwinterva...ies-62-pathways