Weird bug in conversation - I'm desperate so I'll take it up here

I have a complicated situation and since I’m getting desparate I take it up with all of you here.

Situation:

  1. PC and the party encounter an imprisoned fairy dragon that turns the PC into a chicken. A heartbeat script on the area makes sure that after being turned to a chicken the controlled main character always switches to one of the companions.
  2. The companions need to put three gems on a rock in front of the dragon for him to be pleased and turn the PC back.
  3. In order for the fairy dragon to turn the PC back you need Dispel Magic to get rid of the magic prison (some floating magical rings).

The issue:

  1. First you put the gems on the rock.
  2. Then you speak to the fairy dragon. He is pleased. If you have the Dispel Magic spell on you, or if any in the party can cast that spell, everything works perfectly.
  3. If you don’t have the spell, you can find it elsewhere in the same area.
  4. When having found the spell, you speak to the fairy dragon again and here’s where everything collapses. The dialogue checks if you have the spell, but when one of the companions tell the fairy dragon that he has the spell and will cast it, the next node (a blue one) is greyed out and the game freezes. (well, actually you can move the conversation window, it’s in NWN1 conversation style, but you can’t do much else)
    What does this greying out mean?! I have been on this for 4 hours now and I can’t understand what’s wrong. I’ve tried everything. My guess is it has something to do with you not controlling the main PC since my campaign is set to always revert to the main PC when a conversation starts, but I don’t know anymore…Nothing I do to solve this works.

So, since you don’t control the main PC I guess that has something to do with it, but with the first conversation it works.

EDIT: Scripts removed.

I have your PM too …

Have you tried this from a full cutscene conversation rather than a NWN style?

I say this, as that handles some cutscene scripts differently.

I will also take a look at the files now.

EDIT: If changing the conversation style to full cutscene does not work, then the only other thing that may be causing it to fail is the ga_cast_fake_spell_at_object script.

Therefore, as another test, remove that script and see if the conversation continues without it being there to fire. I have a different function script I use for fake spell casting.

Therefore, if that is the problem, then try using this script to fire the spell instead … NB: It has been edited from the original!

// ga_cast_spell_at_object(float fSecondsDelay, string sCaster, int nSpell, string sSpellTarget, int nMetaMagic, int bCheat, int nDomainLevel, int nProjectilePathType, int bInstantSpell)
/*
	Description:
	Has sCaster cast a spell at sSpellTarget
	
	Parameters:
		float fSecondsDelay - Delay before casting
    	string sCaster  	- The caster's tag or identifier, if blank use Dialog Owner. see "ginc_param_const" for TARGET_* constants 
	    int nSpell			- spell ID. see NWSCRIPT.nss for SPELL_* constants
	    string sSpellTarget	- The caster's tag or identifier, if blank use PC Speaker. see "ginc_param_const" for TARGET_* constants 
	    int nMetaMagic 		- Metamagic to use.  use -1 for the standard default of METAMAGIC_ANY. 0 = METAMAGIC_NONE. see NWSCRIPT.nss for METAMAGIC_* constants 
	    int bCheat 			- If this is 1, then the executor of the action doesn't have to be able to cast the spell. 
	    int nDomainLevel 	- Should define the caster level
	    int nProjectilePathType - 0 = PROJECTILE_PATH_TYPE_DEFAULT. see NWSCRIPT.nss for PROJECTILE_PATH_TYPE_* constants
	    int bInstantSpell 	- If this is 1, the spell is cast immediately.
*/
// ChazM 4/26/07

#include "ginc_param_const"

void main(float fSecondsDelay, string sCaster, int nSpell, string sSpellTarget, int nMetaMagic, int bCheat, int nDomainLevel, int nProjectilePathType, int bInstantSpell)
{
	object oCaster = GetTarget(sCaster, TARGET_OWNER);
	object oSpellTarget = GetTarget(sSpellTarget, TARGET_PC_SPEAKER);
	
	if (nMetaMagic == -1)
		nMetaMagic = METAMAGIC_ANY;
		
	// ENSURE A SPELL VFX FIRES AND CONVE CONTINUES
	int iDelay = FloatToInt(fSecondsDelay) * 1000;
	ActionPauseCutscene(iDelay);
		
	AssignCommand(oCaster, DelayCommand(fSecondsDelay, ActionCastSpellAtObject(nSpell, oSpellTarget, nMetaMagic, bCheat, nDomainLevel, nProjectilePathType, bInstantSpell)));	
}
1 Like

@andgalf it looks like all the nodes when the spell is found link to a companion named Teala. Did you try with resetting the links to the corresponding party member?

1 Like

Thank you so much for the answers my friends! I’ll take a look at what you speak about.

I can’t find the nodes you are referring to and I don’t understand what you mean here, actually. Care to elaborate? I mean, if Teala isn’t in the party it just goes on to check the next companion? I don’t get it…

I’ll try changing to NWN2 style, but first…

This ga_cast_fake_spell_at_object script is in the node AFTER the one that’s greyed out. AND this node works if the party already has the Dispel Magic, so can that really have anything to do with anything?

I have this as the “fake” version …

// ga_cast_fake_spell_at_object(float fSecondsDelay, string sCaster, int nSpell, string sSpellTarget, int nProjectilePathType)
/*
	Description:
	Has sCaster appear to cast a spell at sSpellTarget, but with no resulting effects.
	
	Parameters:
		float fSecondsDelay - Delay before casting
    	string sCaster  	- The caster's tag or identifier, if blank use Dialog Owner. see "ginc_param_const" for TARGET_* constants 
	    int nSpell			- spell ID. see NWSCRIPT.nss for SPELL_* constants
	    string sSpellTarget	- The caster's tag or identifier, if blank use PC Speaker. see "ginc_param_const" for TARGET_* constants 
	    int nProjectilePathType - 0 = PROJECTILE_PATH_TYPE_DEFAULT. see NWSCRIPT.nss for PROJECTILE_PATH_TYPE_* constants
	
*/
// ChazM 4/26/07

#include "ginc_param_const"

void main(float fSecondsDelay, string sCaster, int nSpell, string sSpellTarget, int nProjectilePathType)
{
	object oCaster = GetTarget(sCaster, TARGET_OWNER);
	object oSpellTarget = GetTarget(sSpellTarget, TARGET_PC_SPEAKER);
	
	// ENSURE A SPELL VFX FIRES AND CONVE CONTINUES
	int iDelay = FloatToInt(fSecondsDelay) * 1000;
	ActionPauseCutscene(iDelay);
	
	AssignCommand(oCaster, DelayCommand(fSecondsDelay, ActionCastFakeSpellAtObject(nSpell, oSpellTarget, nProjectilePathType)));
}

Note that it also has been edited … It is the ActionPauseDelay function that makes the difference in both scripts, from memory.

Again (like I said in my previous post), this happens in the node AFTER the greyed out one, so how can that make a difference? Plus, my script works if you already have Dispel Magic in the party.

@andgalf

Sorry, I cleaned out the scripts to go back and compare the differences you mention here.

However, as I say in my first post the “CONTINUE” option in a NWN conv can work differently to one in a Full Cutscene one. It does not always drop through automatically, and so the script on the node that follows may be causing issues preventing it from moving forward or being greyed out.

Experiment with the conversation differences/removed/changed script and see if that makes any difference or not. At least it’s a start even if I’m on the wrong track.

I tried with changing to NWN2 style conversation (but I reloaded a save game so I have to test this further) and the game just stops at the node where the companion says: “We’ll free you with Dispel Magic. One moment…”
The continue node after that has NO scripts on it, that’s why it’s so odd.

1 Like

Yes, I know … I had something similar a long while back, and iirc, the points I have here helped resolve my situation. But, of course, there may still be differences I missed on a first look.

Here’s what I mean:


double-clic on any of the “CONTINUE” node (highlighted in yellow)

and you’ll get the node below:

I’m wondering if that switch between companions could mess things up.

@4760 - Ok, I see what you mean now. I’ll try and change that…

@Lance_Botelle - I tried with removing my ga_cast_fake_spell_at_object script altogether from the node coming after the “Continue”. Unfortunately that did nothing.

@4760 - Changed it to just continue on an empty node and it made no difference…


Did the conversation no longer hang? (In either/both conv formats?)

We are trying to establish the cause for the conv hang.

It hangs even then.

I tried with creating a new dialogue for the fairy dragon. I use NWN2 style dialogue all the time now here.
The interesting part is, now after not having Dispel Magic and then picking it up, the game hangs on the first node where the fairy dragon says “…”. On that node I have a gc_global_int. If I remove that and click on the fairy dragon before the PC is turned to a chicken, that dialogue starts , and THEN it doesn’t hang. So somehow this seems to have to do with not controlling the main PC, or something…

c_ur_fairydr2.zip (30.5 KB)

1 Like

Is this empty node a link? I know that’s not the solution we’re looking for, but just to get rid of some reasons, what happens if the “We’ll free you with Dispel Magic” line has next nodes directly attached to it? Without any action/condition scripts first, then with the scripts.

@4760 - I tried that. As you can see from my screenshot I made an empty node with nothing on it, not linked to anything, and I had Nankun in the party so he’s the one, the rakshasa, that’s talking. Unfortunately that made no difference.

I’ll go for a walk now. Thank you so much, guys, for trying to help me! All this is so weird.

Interesting … What does debug say the global int is at time of the conversation check?

EDIT: I assume the PC speaker is definitely a party member here? (When checking for a party member present that can respond.) You could add a “default” last node that fires if the “party member” checks are failing to detect.

? Global ints are not determined by which PC the player is controlling.

Just testing stuff here … What happens if you check for a local variable set on the fairy dragon instead of relying on a global int? I would have thought it not to make any difference, but global ints read and write to a file, rather than just run from memory. i.e. Local ints may be slightly more reliable in this situation? To stress: I don’t think it would make any diff, but just saying.

Or, try rewriting that node, in case of some sort of conversation corruption?