Conversation Abort Script

From NWN Lexicon
Jump to: navigation, search

A conversation Conversation Abort Script attached under the Current File panel of the conversation editor in the toolset, called "Aborted".


Trigger

If the conversation is exited in in a non-standard way the Conversation Abort Script plays. Generally this could be seen as "interrupting" the conversation.

The list of conditions include, but not exhaustively are:

  • The PC presses Escape - or a set of GUI panels override it (too many GUI panels at once can do this, such as opening a store with OpenStore).
    • Note that if the player is in a cutscene the cutscenes abort event will play instead, a useful way to force them to keep the conversation open (they also can't open GUI panels in conversation mode).
  • The PC or NPC enters combat
  • The PC starts a new conversation (only one can be open at a time)
  • The PC moves too far away from the NPC or vice versa (the distance seems to be around 10M or one tile). Teleporting to another area can cause this too (eg clicking an area transition)
  • The PC possesses their familiar
  • The PC leaves the game (more relevant in MP)

Note a ClearAllActions doesn't necessarily stop combat; the actions that come after might however. The state of the conversation (eg: if it is paused or not) should not be relevant to if it can be cancelled.

The reason therefore is not solely "the PC is being a dick to the NPC" or "the PC wants to escape a hard conversation choice and redo it". Make sure NPCs in conversation do not start moving around too much, and have re-entry points for important conversations you want to continue, especially if the area has potential hostile enemies the PC may have brought with them.

It should be usually combined with the Conversation End Script in cases where something must happen at the conclusion of the conversation, for instance combat with a boss who isn't currently hostile.

The reason conversations can be aborted is the MP nature of the game. Most of the OC was built around having co-op meaning players can and do interrupt conversations frequently (although PCs can't see what another PC is able to say to an NPC, but this functionality is kinda present in the game code but unavailable to use).

If you instead want to force a conversation to happen - as in a plot NPC conversation - try cutscene mode wrapped around it.


Function(s)

  • GetPCSpeaker can retrieve who is conversing with the NPC.
  • OBJECT_SELF is the NPC who is talking to the PC (if the PC is talking to themselves they will also be OBJECT_SELF).


Remarks

By default all conversations will set this event to nw_walk_wp, along side the Conversation End Script, meaning a NPC will go back to ambient animations/walking around immediately when a conversation ends.

Bosses who are meant to always attack a player generally get a version in both events where they will attack the PC who is conversing with them. This saves on putting the script in numerous Conversation Action Script events.


Example

From the OC in the conversation m4q01b26maug.dlg in Chapter 4.nwm. This will do the given actions only once. Note the On End script is not used in this particular conversation and the same script is instead used in the [Dialogue End] but it is a simple conversation.

Note the most noteworthy thing is having the local variable stating you've completed all the necessary things, meaning it won't fire twice (if somehow the conversation was re-initialised, eg; if the NPC then gave up combat and surrendered).

// * Maugrim summons in undead and attacks the player
#include "nw_i0_generic"
 
void main()
{
    if (GetLocalInt(OBJECT_SELF, "NW_L_GO_HOSTILE") == 0)
    {
 
 
/*       object oCreature = CreateObject(OBJECT_TYPE_CREATURE, "m4q1_servant", GetLocation(OBJECT_SELF));
       effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3);
       DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVis, oCreature));
       CreateObject(OBJECT_TYPE_CREATURE, "m4q1_servant", GetLocation(OBJECT_SELF));
       DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVis, oCreature));
  */
       object oCreature = GetNearestObjectByTag("M4Q1B26Servant");
       if (GetIsObjectValid(oCreature)== FALSE)
       {
       // SpeakString("failed");
       }
       ActionCastSpellAtObject(SPELL_TIME_STOP, OBJECT_SELF, METAMAGIC_QUICKEN, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
       ActionCastSpellAtObject(SPELL_RESURRECTION, oCreature, METAMAGIC_QUICKEN, TRUE);
       ActionDoCommand(AssignCommand(oCreature,SetIsDestroyable(TRUE, FALSE, TRUE)));
       ActionDoCommand(AssignCommand(oCreature, DetermineCombatRound()));
       oCreature = GetNearestObjectByTag("M4Q1B26Servant", OBJECT_SELF, 2);
       ActionCastSpellAtObject(SPELL_RESURRECTION, oCreature, METAMAGIC_QUICKEN, TRUE, 0);
       ActionDoCommand(AssignCommand(oCreature,SetIsDestroyable(TRUE, FALSE, TRUE)));
       ActionDoCommand(AssignCommand(oCreature, DetermineCombatRound()));
       ActionCastSpellAtObject(SPELL_PREMONITION, OBJECT_SELF, METAMAGIC_QUICKEN, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
       ActionCastSpellAtObject(SPELL_MASS_HASTE, OBJECT_SELF, METAMAGIC_QUICKEN, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
       ActionDoCommand(SpeakString("NW_I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK));
 
       object oPC = GetPCSpeaker();
       if (GetIsObjectValid(oPC) == FALSE)
       {
        oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC); //GetLastSpeaker();
       }
       AdjustReputation(oPC, OBJECT_SELF, -100);
       SetLocalInt(OBJECT_SELF, "NW_L_GO_HOSTILE",1);
       ActionDoCommand(SetCommandable(TRUE));
       SetLocalInt(OBJECT_SELF, "NW_L_MYRITUAL", 10);
       SetCommandable(FALSE);
       DetermineCombatRound(oPC);
 
    }
}

See Also

functions:

GetScriptParam GetPCSpeaker