PDA

View Full Version : Help: Script that checks NPC's alignment


Sharen Thrawn
05-13-2007, 07:48 AM
Could someone help me write a script that will check NPC's alignment? (in TSL)

stoffe
05-13-2007, 08:06 AM
Could someone help me write a script that will check NPC's alignment? (in TSL)

For use in dialogs as a conditional script to determine if a conversation branch is available, or for some other purpose? If it's for a dialog something like this might work:

// The P1 parameter should be set to one of the following numbers:
// NEUTRAL = 1
// LIGHT SIDE = 2
// DARK SIDE = 3
// The String Param should be set to the tag of the NPC to check,
// or left blank to check the dialog owner NPC.

int StartingConditional() {
string sTag = GetScriptStringParameter();
object oNPC = (sTag == "" ? OBJECT_SELF : GetObjectByTag(sTag));
return (GetAlignmentGoodEvil(oNPC) == GetScriptParameter(1));
}


Compile the script and then put the name of the resulting NCS file in one of the Conditional script fields on the dialog node you wish to check the alignment for. Set the P1 parameter value to the alignment you want to check for, where 1 = neutral/grey, 2 = lightside and 3 = darkside. Set the String Param parameter value to the tag of the NPC to check the alignment of, or leave it blank to check the NPC you are in conversation with.

Sharen Thrawn
05-13-2007, 08:18 AM
It's for conditional.

I'm n00b, tried to write this script based on influence one. Here's what i created (don't laugh ;) ): Anyway thanks for help!


// c_alignment_gt
/* Parameter Count: 2

Checks to see if an NPC's alignment > Param2

Param1 - The NPC value of the player whose Alignment is tested.
Param2 - alignment value to test against.

NPC numbers, as specified in NPC.2da

0 Atton
1 BaoDur
2 Mand
3 g0t0
4 Handmaiden
5 hk47
6 Kreia
7 Mira
8 T3m4
9 VisasMarr
10 Hanharr
11 Disciple

*/
//
// KDS 06/28/04
int StartingConditional()
{

int GetGoodEvilValue(object oNPC);
int nNPC = GetScriptParameter(1);
int nAlign = GetScriptParameter(2);

if( GetGoodEvilValue(oNPC) > nAlign) return 1;
else return 0;

}

stoffe
05-13-2007, 08:43 AM
I'm n00b, tried to write this script based on influence one. Here's what i created (don't laugh ;) ): Anyway thanks for help!


int StartingConditional()
{
int GetGoodEvilValue(object oNPC);
int nNPC = GetScriptParameter(1);
int nAlign = GetScriptParameter(2);

if( GetGoodEvilValue(oNPC) > nAlign) return 1;
else return 0;
}

There are two syntax errors in that script which would prevent it from compiling:

The line marked with red color above is missing an assignment and a name of a variable to assign the value returned from GetGoodEvilValue() to. You also have a type definition (object) in the parameter which shouldn't be there when the function is called.

Further you are using the variable oNPC which has not been declared and had any value assigned to it. The same goes for the line marked with yellow color. You'd have to read the nNPC variable value you collect, determine the tag of the specified NPC and get the object instance for the one with that tag in the area and assign that to oNPC.

With those corrected the script would check if the NPC has an alignment higher than the value specified as parameter (on a scale from 0-100).

Sharen Thrawn
05-13-2007, 09:24 AM
Tried to correct my script but failed. Do you know how this script should look like? Sorry I'm total n00b :(

Sharen Thrawn
05-15-2007, 04:02 PM
Okay, so I've been working on that code stoffe gave me for the past few days. It seems to be working if it's like this:

int StartingConditional()
{ string sTag = GetScriptStringParameter();
object oNPC = GetObjectByTag(sTag);
int nAlign = GetScriptParameter(1);

if (GetGoodEvilValue(oNPC) > nAlign) {
return TRUE;
}
return FALSE; }


If I change oNPC's value to "(sTag == "" ? OBJECT_SELF : GetObjectByTag(sTag));" , the game crashes if the conditional is putted in entry node. If putted in reply, it works. BUT!

I wanted to disable Handmaiden's whining about me doing bad things when she's evil already. That's why i needed to make a script that checks NPC's alignment and disables a dialog if NPC is too dark/white. The thing is, this script doestn't disable her dialog, but makes it play ultra-fast. And at the end I get "Influence lost: Handmaiden" :( Help!

Sorry for my english ;P :D

Pavlos
05-15-2007, 05:20 PM
I wanted to disable Handmaiden's whining about me doing bad things when she's evil already. That's why i needed to make a script that checks NPC's alignment and disables a dialog if NPC is too dark/white. The thing is, this script doestn't disable her dialog, but makes it play ultra-fast. And at the end I get "Influence lost: Handmaiden" :( Help!

Hi there.

This may help:

int StartingConditional()
{

object oNPC = GetObjectByTag(GetScriptStringParameter());

// The NPC must have below this value
int nHigh = GetScriptParameter(1);
// The NPC must have above this value
int nLow = GetScriptParameter(2);

return (GetGoodEvilValue(oNPC) > nLow && GetGoodEvilValue(oNPC) < nHigh);

}

Essentially, the script checks to see if the NPC's alignment is less than the maximum value supplied and greater than the minimum value supplied. This means those NPCs too far over either end of the alignment scale. I trust this is what you wanted?

Edit: You could, of course, simply do an influence check on the NPC and if the player has high influence then the NPC should not disagree with the player.

Edit 2: I can't see why the game would crash when making those changes to the oNPC assignment, though knowing me I have missed something glaringly obvious in all of this. Perhaps post that script and we can help you puzzle out the problem of the game crashing. I'm also unsure as to why the dialogue would play ultra-fast. Where exactly are you attaching this script?

stoffe
05-15-2007, 06:40 PM
Okay, so I've been working on that code stoffe gave me for the past few days. It seems to be working if it's like this:

Uh, was there anything wrong with the script I posted in the second post of this thread? That should work as far as I know. :confused: (Set P1 to 3 and String Param to Handmaiden)



If I change oNPC's value to "(sTag == "" ? OBJECT_SELF : GetObjectByTag(sTag));" , the game crashes if the conditional is putted in entry node. If putted in reply, it works.

That should not make any difference. The only thing that line does is assign OBJECT_SELF (i.e. the dialog owner object) to the oNPC variable is no tag has been specified, otherwise assign the object with the specified tag to the variable.


I wanted to disable Handmaiden's whining about me doing bad things when she's evil already. That's why i needed to make a script that checks NPC's alignment and disables a dialog if NPC is too dark/white.

The thing is, this script doestn't disable her dialog, but makes it play ultra-fast. And at the end I get "Influence lost: Handmaiden"

You are modifying 000react.dlg, correct? Keep in mind that if a dialog entry is blocked from being used by a conditional script the dialog will not terminate, it will just move down in the list of entries until it encounters an entry with no conditional script (or a conditional that returns true).

I.e. you must add a conditional script to the {Handmaiden} node further down as well if you want to block out both the first conversation where you can respond to her complaints, and the later oneliner barks used for subsequent offenses.

Sharen Thrawn
05-16-2007, 10:33 AM
Uh, was there anything wrong with the script I posted in the second post of this thread? That should work as far as I know. :confused: (Set P1 to 3 and String Param to Handmaiden)


Your script doesn't work if:

1. Conditional is putted in Entry node (wich is the first node of the dialog) AND the 'String Param' is left blank
2. Conditional is putted in Entry node (wich is NOT the first node of the dialog) AND the 'String Param' is left blank
3. Conditional is putted in Reply node AND the 'String Param' is left blank

If conditional is putted in Entry (first dialog's node), Entry or Reply AND String Param is set to 'Haindmaiden' it works.


That should not make any difference. The only thing that line does is assign OBJECT_SELF (i.e. the dialog owner object) to the oNPC variable is no tag has been specified, otherwise assign the object with the specified tag to the variable.

I know it should work like this, but in this specific case it doesn't if the 'String Param' is left blanked (no tag specified). Don't worry, it doesn't matter since it works perfectly if you set object tag in 'String Param' ("Handmaiedn" in this case).



You are modifying 000react.dlg, correct? Keep in mind that if a dialog entry is blocked from being used by a conditional script the dialog will not terminate, it will just move down in the list of entries until it encounters an entry with no conditional script (or a conditional that returns true).

I.e. you must add a conditional script to the {Handmaiden} node further down as well if you want to block out both the first conversation where you can respond to her complaints, and the later oneliner barks used for subsequent offenses.

Yes, i'm modifying 000react.dlg. It looks like this:
http://img504.imageshack.us/img504/3619/dowyjasnieniaey2.jpg

This is Handmaiden's reaction I want to disable with Alignment checking script. If i put my conditional (that checks alignment) for example here or here it works perfectly. Dialog will just end or a node will not show up. The problem is that this node (first node in the dialog) has already two conditionals. So as a n00b (:D) I've simply repleaced 'c_global_eq' with my conditional (a_align_gt ..... 3 ... 0 ... 0 ... 0 ....... Handmaiden). That's propably why it didn't worked. Dialog was just played ultra fast and at the end i recived Influence lost.

So the question is if it's possible to add a 3rd conditional??? :confused:

Anyway thank you all for your advices and help, and once again sorry for my english. Hope you'll understand ;P :D

stoffe
05-16-2007, 10:46 AM
Your script doesn't work if:
1. Conditional is putted in Entry node (wich is the first node of the dialog) AND the 'String Param' is left blank
2. Conditional is putted in Entry node (wich is NOT the first node of the dialog) AND the 'String Param' is left blank
3. Conditional is putted in Reply node AND the 'String Param' is left blank


This is because the 000react.dlg dialog owner is not your party member, it's an invisible placeable that initiates conversation with the player. Thus you must specify the Tag of the NPC to check the alignment of. If you want to check if they're darkside set the P1 field to 3 (2 is lightside, 1 is neutral/grey). If you leave the String Param blank in this case you are checking the alignment of the placeable, not the NPC.

The problem is that this node (first node in the dialog) has already two conditionals. So as a n00b (:D) I've simply repleaced 'c_global_eq' with my conditional (a_align_gt ..... 3 ... 0 ... 0 ... 0 ....... Handmaiden). That's propably why it didn't worked. Dialog was just played ultra fast and at the end i recived Influence lost.

So the question is if it's possible to add a 3rd conditional??? :confused:


As I said one post up this is because the entry will be skipped, but the dialog will not exit, it will just proceed farther down until it will encounter an entry the conditional script returns TRUE for. Which it will do for the {Handmaiden} node further down. This is a a oneliner bark, with a influence decrease at the end. Check the attached screenshot below. When you block out the entry with the blue arrow with your conditional script, it causes the one marked with the green arrow to fire instead, which is responsible for the influence loss.

The c_global_eq conditional you removed is there to make sure the conversation is only played once. Otherwise you'd talk about exactly the same thing every time you do something nasty with the Handmaiden present.

Dialogs only support two Action and Conditional scripts in TSL. If you need more you'll have to merge your script with one of the existing ones so it checks both things at once. You can combine it with the script that checks if the party member is present (c_npc_inprty), like:

// The P1 parameter should be set to one of the following numbers:
// NEUTRAL = 1
// LIGHT SIDE = 2
// DARK SIDE = 3
//
// The P2 parameter should be set to 1 if it should check for any
// alignment EXCEPT the one set in P1 (otherwise set to 0).
//
// The String Param should be set to the tag of the NPC to check,
// or left blank to check the dialog owner NPC.

int ST_IsInParty(object oNPC);

int StartingConditional() {
int iAlign = GetScriptParameter(1);
int iNegate = GetScriptParameter(2);
string sTag = GetScriptStringParameter();
object oNPC = (sTag == "" ? OBJECT_SELF : GetObjectByTag(sTag));

if (iNegate > 0)
return ST_IsInParty(oNPC) && (GetAlignmentGoodEvil(oNPC) != iAlign);
else
return ST_IsInParty(oNPC) && (GetAlignmentGoodEvil(oNPC) == iAlign);
}


int ST_IsInParty(object oNPC) {
float fRadius = 12.0;
string sTag = GetTag(oNPC);
int iSlot = -1;

if (sTag == "Atton") {
iSlot = NPC_ATTON;
}
else if (sTag == "Baodur") {
iSlot = NPC_BAO_DUR;
}
else if (sTag == "Mand") {
iSlot = NPC_CANDEROUS;
}
else if (sTag == "G0T0") {
iSlot = NPC_G0T0;
}
else if (sTag == "Handmaiden") {
iSlot = NPC_HANDMAIDEN;
}
else if (sTag == "HK47") {
iSlot = NPC_HK_47;
}
else if (sTag == "Kreia") {
iSlot = NPC_KREIA;
}
else if (sTag == "Mira") {
iSlot = NPC_MIRA;
}
else if (sTag == "T3M4") {
iSlot = NPC_T3_M4;
}
else if (sTag == "VisasMarr") {
iSlot = NPC_VISAS;
}
else if (sTag == "Hanharr") {
iSlot = NPC_HANHARR;
}
else if (sTag == "Disciple") {
iSlot = NPC_DISCIPLE;
}

return (IsNPCPartyMember(iSlot) && (GetDistanceBetween(GetPCSpeaker(), oNPC) <= fRadius));
}


That script will now check both if the party member is present at all in the group and close enough to talk, and then if the alignment matches. The P2 parameter can now be set to 1 to negate the alignment check. I.e. if you set P1 to 3 and P2 to 1 and String Param to Handmaiden it will allow the entry to be used if the Handmaiden is in the party and is not Darkside. If P2 is set to 1 instead it would check if the Handmaiden is in the party and is Darkside

Sharen Thrawn
05-17-2007, 12:18 PM
Thank you so much for the code stoffe! But I have another problem.

When the entry with blue arrow (on your image) fails to fire (because Handmaiden has bigger or lower Alignment than needed ) the entry with green arrow doesn't play too (well, it plays but ultra-fast, about half a second). It seems that {Handmaiden} (entry 136) entry fires and works. I know it coz if I put a a_influence_dec/inc script in that entry I get Influence lost/gain after dialog end. The problem is that after checking conditional in entry with blue arrow (it fails to fire coz of lack/excess of alignment needed) and checking conditional and scripts in entry with green arrow the dialog doesn't continue. It should has proceed to the '{Confused}I do not understand why we attacked.' entry. But it doesn't. What's wrong? :confused:

Sharen Thrawn
05-18-2007, 08:29 AM
Hmmm... As I thnik more of this, it has to be sth with c_global_eq conditional and a_global_set script. When there's no conditional that checks the alignment, everything works fine, but for some reason the game doesn't proceed to the next dialog (wich is determined by a_global_set from previous dialog) when there's aditional thing to check (alignment check in this case). Don't know if it's possible to resolve this problem, seems to be very complex

Sharen Thrawn
05-19-2007, 01:50 PM
I've managed to solve this problem. Viva la n00b! :clap2: :D I added new global variable to globalcat.2da ((Row Label) - 999; name - 000_R_Psychotic_Hand_When_Evil; type - Number) and created new Handmaiden response. Putted 000_R_Psychotic_Hand_When_Evil into String Param for c_global_eq conditional (P1 = 0) and a_global_set script (P1=0, since i've created only one new response as for now). And now everything works. If she's good, her disapproval responses fire (ones with 000_React_Psychotic_Hand string parameter). If she's evil her approval respones fire (ones with 000_React_Psychotic_Hand_When_Evil string parameter). Simple ;P

Thanks for help everyone, especially you stoffe, for your patience while expleaning simple things to a n00bie :) :gift: :heart3:

Last question. I just putted new global variable (000_React_Psychotic_Hand_When_Evil) into globalcat.2da and then saved the file into the X:/blabla/SWKotor2/Override folder. Everything works, but I'm not sure if it's the right way to edit globalcat.2da file.

tk102
05-19-2007, 02:27 PM
Congratulations, Sharen Trawn! :)

Globalcat.2da is one of simplest .2da files. What you did was just fine.

Sharen Thrawn
05-19-2007, 03:50 PM
Congratulations, Sharen Trawn! :)

Globalcat.2da is one of simplest .2da files. What you did was just fine.

Well, after few tests, it doesn't work actually. But it's not mine fault this time. I mean the whole alignment checking conditionals/scripts system works, but there's that aligmnent bug (you know, sudden NPC's alignment shifts from dark to light, light to dark etc without any reason, wich can be solved by save & load (very irritating)) wich makes even more mess to NPC's light/dark side responses XD

Unless someone fix that alignment bug, we won't be able to make a mod that changes NPC's reactions when converted to light/dark side. I hope Team Gizka will fix that bug, since as it seems they're fixing non-TSLRP related bugs also.

Sorry for my english :D Thanks for help 1 more time! :)

Pavlos
05-19-2007, 05:45 PM
Unless someone fix that alignment bug, we won't be able to make a mod that changes NPC's reactions when converted to light/dark side. I hope Team Gizka will fix that bug, since as it seems they're fixing non-TSLRP related bugs also.

Unfortunately, this is an engine bug - sorry. You could, however, simply check if the player has high influence with the NPC. Given the way the influence system works, if the player has high influence with a party member then the two have very similar alignments and thus the NPC is likely to agree with the Exile :).

Sharen Thrawn
05-19-2007, 06:35 PM
Unfortunately, this is an engine bug - sorry. You could, however, simply check if the player has high influence with the NPC. Given the way the influence system works, if the player has high influence with a party member then the two have very similar alignments and thus the NPC is likely to agree with the Exile :).

That would solve many problems since there're no influence bugs :)

But as for that alignment bug, i've been testing several things for last few hours. What I noticed (discovered) is that when your character doesn't have any bonus charisma points, those weird alignment fluctuations don't appear. Tested it several times, with different characters, on a different influence level and with different alignments. Everything was as it should have been. Of course I may be wrong, but after testing it so many times I'm pretty sure it really works.

http://img440.imageshack.us/img440/2193/charzeronx9.jpg

Is it possible to set this value (Charisma bonus points right?) to zero on constant? Maybe with some script?

RedHawke
06-14-2007, 02:29 AM
Is it possible to set the value of bonus points to Charisma to zero on constant? Or avoid getting any bonus points to charisma?
No... other than assigning no more than 10 points to charisma at character creation. And refraining from using any Charisma boosting items during the game. But note that Force powers are influenced by Charisma (at least they should be) so a low charisma will penalise you when using them.

This is a bug in the game itself and nothing that we can fix, you will either have to live with it or create a workaround as indicated above by Pavlos. Sorry.

tk102
06-14-2007, 02:36 AM
*remembers the many hours of banging my head against the keyboard trying to figure out how KSE could have caused this*

Thanks for the painful memories. :p

Well it was people using KSE to God Mod their stats to 255 or some other god awful numbers that first reported this, so yes KSE was involved! :xp: *Flees thread...* -RH

Sharen Thrawn
06-14-2007, 11:12 AM
Thanks for help guys! I will do it as Pavlos suggested. Checking at wich level of influence certain NPC's alignment shifts from dark to light should do the trick, right? Handmaiden for example becomes dark when you have 70+ influence with her.

Sharen Thrawn
06-21-2007, 08:13 AM
I need a script that will check if NPC is available in party and if it's influence is big enough. I want to combine two scripts (c_npc_inprty and c_influence_gt) but I'm not skilled enough. Tried but it didn't work :/

stoffe
06-21-2007, 08:27 AM
I need a script that will check if NPC is available in party and if it's influence is big enough. I want to combine two scripts (c_npc_inprty and c_influence_gt) but I'm not skilled enough. Tried but it didn't work :/

Set the P1 parameter in the dialog node to the party table slot number of the NPC you wish to check (defined by the NPC_ constants in nwscript.2da or line number 0-11 in npc.2da), and P2 to the influence value the player must be above witht hat NPC.


// ST: Dialog conditional script
// P1 - Party table slot of NPC to check, corresponds to NPC_ constants
// P2 - Influence value (0-100) the NPC must have above


string GetNPCTag(int nNPC);

int StartingConditional() {
int iNPC = GetScriptParameter(1);
int iInf = GetScriptParameter(2);

object oNPC = GetObjectByTag(GetNPCTag(iNPC));

return (IsNPCPartyMember(iNPC)
&& GetIsObjectValid(oNPC)
&& (GetDistanceBetween(GetPCSpeaker(), oNPC) <= 12.0)
&& (GetInfluence(iNPC) > iInf));
}



string GetNPCTag(int nNPC) {
switch( nNPC ) {
case NPC_ATTON: return "atton"; break;
case NPC_BAO_DUR: return "baodur"; break;
case NPC_CANDEROUS: return "mand"; break;
case NPC_DISCIPLE: return "disciple"; break;
case NPC_G0T0: return "g0t0"; break;
case NPC_HANDMAIDEN: return "handmaiden"; break;
case NPC_HANHARR: return "hanharr"; break;
case NPC_HK_47: return "hk47"; break;
case NPC_KREIA: return "kreia"; break;
case NPC_MIRA: return "mira"; break;
case NPC_T3_M4: return "t3m4"; break;
case NPC_VISAS: return "visasmarr"; break;
}

return "INVALID";
}

Sharen Thrawn
06-21-2007, 11:40 AM
Set the P1 parameter in the dialog node to the party table slot number of the NPC you wish to check (defined by the NPC_ constants in nwscript.2da or line number 0-11 in npc.2da), and P2 to the influence value the player must be above witht hat NPC.


Thank you so much stoffe! You're so kind to these annoying newbies like myself :D Thanks! :heart3: <hugs>

Sharen Thrawn
07-26-2007, 08:24 AM
Okay, so I've started serious works on my "Influence Enhancement Mod" (:D). So far, I've made complete list of all influence changes/opportunities for particular NPCs (props to Achilles and his complete influence guide!), and marked all the changes/additions that are need to be done in Handmaiden and Bao-Dur's dialogs. Of course I know it's not much, but I've been working on it for just a few days. Also, I've been working on new custom DS dialogs for Bao-Dur, but I realized that it was pointless. Why?

Well, English is not my first language and I'm not really good in it. I wrote new dialog options for Bao-Dur, and started making custom voice clips, but there were grammar/spelling mistakes. What's the point in spending hours on searching for specific words, with proper accent and than realize you have to change everything because of grammar mistakes? That's why I'm asking for help. I'm searching for a writer, an english speaking one (would be great if english native) who would be willing to help me writing/checking/fixing new dialog lines. I would be sure then that there're correct etc. There're not that many lines needed to be written.

As for the mod, yes, I know how time consuming creating it'll be and that there were many great budding mods that never came out. The fact that It's my first mod and my number of posts here at Holowan is definatley not impressive doesn't really help my credibility either. But I'm really determined to create this mod, since Kotor 2 is my all-time favourite game, and the influence system was my personal (and for many people too) biggest dissapointment about it apart from rushed ending and all the cut-content. I aim to create new DS responsed for LS NPCs, and vice versa + new dialog options in conversations where you were limited in either LS influence DEC/DS influence INC or DS DEC/LS INC. I want this mod to be fully TSLRP compatible, wich means my mod won't be out before RP for sure.

Since couple of months I've been learning modding, and I think I have all the knowledge needed to create this specific mod. So if anyone is willing to help me with writing new dialogs, please PM me. I can't afford anything in return and I don't aim to get money from this mod either. I just want this game to be perfect, and I believe with influence system fixed and TSLRP it will really be. :)

Masaru93
07-26-2007, 11:04 AM
Hrm. I could be your writer. English is my native lang, so you wouldn't have to worry about that. If you have a IM of some sort, you could PM me and we could start discussing details on dialogue.