Jike 1 Posted November 22, 2019 I recently started doing a small mod as practice for working on other mods in the future. In the mod, I need to make a specific dialogue options result in combat between the PC and at least 2 NPCs and give the PC some Dark Side Points. I've Googled around and have been unable to find anything relating to the subject except for in Fair Strides' Script Shack. I tried what I found but I am by no means an expert in C# and am barely a beginner, and thus my code doesn't produce any results. My code is as follows: Spoiler void main() { ExecuteScript("CombatOnDialogEnd"); ExecuteScript("AjustAlignment"); } void CombatOnDialogEnd(object oNPC, int iFaction); { object oNPC = GetObjectByTag("tat20_06jawa_01", "tat20_06jawa_02"); int iFaction = STANDARD_FACTION_HOSTILE_1; ChangeToStandardFaction(oNPC, iFaction); } void AdjustAlignment(object oSubject, int nAlignment, int nShift); { object oSubject = OBJECT_SELF; int nAllignment = GetAlignmentGoodEvil(); int nShift = 15; } Any help would be appreciated. Also, apologies if there is already a forum thread on this subject, I did what research I could and couldn't find anything myself. Quote Share this post Link to post Share on other sites
DarthParametric 3,777 Posted November 22, 2019 NWScript is closer to C than C#. You have a few issues there: ExecuteScript is for, as the name suggests, executing other, external, compiled scripts. Declare your sub-functions first, before the main. Seems you have some C# influence going on there. If you want to call a sub-function declared inside the same script, you just use its name, along with any requirements. So, for example, simply CombatOnDialogEnd(oBob, STANDARD_FACTION_HOSTILE_1). You don't need to declare constants like the factions, as they are already declared in nwscript.nss and will be converted as needed by the compiler. The order of your declarations is invalid, again due to C# influence. OBJECT_SELF refers to the script owner, not the PC. Since the script will be fired from a DLG, the owner will be whoever owns the DLG, presumably the hostile NPC (you also don't declare it). That is incorrect use of GetObjectByTag - "GetObjectByTag(string sTag, int nNth=0)". Knowing in advance that the Sandpeople Enclave has multiple instances of the same Jawa UTC that you have to account for, something like this should work: void main() { object oPC = GetFirstPC(); object oJawa; string sJawa = "tat20_06jawa"; // I assume you want a DS shift here AdjustAlignment(oPC, ALIGNMENT_DARK_SIDE, 15); oJawa = GetFirstObjectInArea(); while (GetIsObjectValid(oJawa) && GetStringLeft(GetTag(oJawa), 12) == sJawa && GetStandardFaction(oJawa) != STANDARD_FACTION_HOSTILE_1) { ChangeToStandardFaction(oJawa, STANDARD_FACTION_HOSTILE_1); oJawa = GetNextObjectInArea(); } } Although you may additionally need to give them some prompting to attack the PC, depending on how your initial testing turns out. I'd suggest perusing nwscript.nss, which there will likely be a copy of in your Override if you have used KTool. You should also extract the script source (NSS) available in scripts.bif (via KTool: BIFs -> scripts.bif -> Scripts, Source). 1 1 Quote Share this post Link to post Share on other sites
Jike 1 Posted November 22, 2019 17 minutes ago, DarthParametric said: etc... Thanks for the information! I'll try it when I'm home later and get back to you with the results. Quote Share this post Link to post Share on other sites
Jike 1 Posted November 22, 2019 Unfortunately, after testing, it still doesn't work. The conversation ends and there are no DS points awarded, nor do the Jawas become hostile. I'm wondering if it might be related to the way I've designed the dialogue file. Quote Share this post Link to post Share on other sites
DarthParametric 3,777 Posted November 23, 2019 Best to attach your DLG. It's not really practical to diagnose without poking through it directly. Quote Share this post Link to post Share on other sites
Jike 1 Posted November 23, 2019 You're right! I didn't think at all, my bad haha. You'll find my dlg attached. tat20_06jawa_01.dlg Quote Share this post Link to post Share on other sites
DarthParametric 3,777 Posted November 23, 2019 The DS shift worked fine for me, but there was a problem with the script that meant the Jawa wouldn't turn hostile. This is the corrected version: void main() { object oPC = GetFirstPC(); object oJawa; string sJawa = "tat20_06jawa"; AdjustAlignment(oPC, ALIGNMENT_DARK_SIDE, 15); oJawa = GetFirstObjectInArea(); while (GetIsObjectValid(oJawa)) { if (GetStringLeft(GetTag(oJawa), 12) == sJawa && GetStandardFaction(oJawa) != STANDARD_FACTION_HOSTILE_1) { ChangeToStandardFaction(oJawa, STANDARD_FACTION_HOSTILE_1); } oJawa = GetNextObjectInArea(); } } However, the Jawa model lacks any combat or death animations (and has no supermodel), so even though they turn hostile, they just stand there and freeze in place once killed. Looking at the rig, it seems like it might be possible to point it to one of the player supermodels, or at least create a unique supermodel with a subset of required anims. I'll have a play with it. 1 1 Quote Share this post Link to post Share on other sites
Jike 1 Posted November 23, 2019 Alright, I'll test out your script in the meantime and see how it goes for me. Thanks for your time and help by the way! I really appreciate it. EDIT I replaced the old script and tested it and it all works fine. Of course the animations, much like you said, aren't there. But it's a step closer. Quote Share this post Link to post Share on other sites
DarthParametric 3,777 Posted November 23, 2019 The problem is they count as creatures, so they can't use the standard player animations as-is. They'd need a custom supermodel with all the anims renamed to the creature alternative. It would likely be extremely ropey though, since the rigs don't match at all proportions-wise. 1 Quote Share this post Link to post Share on other sites
Jike 1 Posted November 23, 2019 That makes sense. I'll have to look into that and do some learning, I don't know much about spuermodels. I'll make do with what we've achieved for now and stick with petrification. Quote Share this post Link to post Share on other sites
DarthParametric 3,777 Posted November 23, 2019 Combat animations aren't working yet, but they at least have a death animation now: K1_Jawa_Supermodel.7z 1 1 Quote Share this post Link to post Share on other sites
Jike 1 Posted November 23, 2019 I just tried out the animations and they both look and work great! I genuinely can't thank you enough for all of this. I'll need to take the time soon to learn all of this myself. Quote Share this post Link to post Share on other sites
DarthParametric 3,777 Posted November 24, 2019 I fixed the animation issue. It seems that the game didn't like it when reading directly from a modified human supermodel, but when I loaded the anims onto a scaled up Jawa rig they work fine: K1_Jawa_Supermodel_v2.7z The other issue is that none of the Jawa will actually do anything because they lack any default scripts, aside from the OnDialogue one: Adding in all those results in this: I also tweaked the script a bit. It now uses an include script, so you'll need to extract those from scripts.bif and put them in the same folder as the hostile script - k_inc_generic, k_inc_gensupport, k_inc_drop, k_inc_walkways: #include "k_inc_generic" void main() { object oPC = GetFirstPC(); object oJawaA = GetObjectByTag("tat20_06jawa_01", 0); object oJawaB = GetObjectByTag("tat20_06jawa_02", 0); object oJawaC = GetObjectByTag("tat20_06jawa_02", 1); // 10 is considered "high" in vanilla shifts, so I reduced this from 15 AdjustAlignment(oPC, ALIGNMENT_DARK_SIDE, 10); ChangeToStandardFaction(oJawaA, STANDARD_FACTION_HOSTILE_1); DelayCommand(0.5, AssignCommand(oJawaA, ClearAllActions())); DelayCommand(1.0, AssignCommand(oJawaA, GN_DetermineCombatRound())); ChangeToStandardFaction(oJawaB, STANDARD_FACTION_HOSTILE_1); DelayCommand(0.5, AssignCommand(oJawaB, ClearAllActions())); DelayCommand(1.0, AssignCommand(oJawaB, GN_DetermineCombatRound())); ChangeToStandardFaction(oJawaC, STANDARD_FACTION_HOSTILE_1); DelayCommand(0.5, AssignCommand(oJawaC, ClearAllActions())); DelayCommand(1.0, AssignCommand(oJawaC, GN_DetermineCombatRound())); } And one final tweak to the UTCs is that they lack the proper Jawa soundset. Much like the missing scripts, this was due to there never being the intention for them to end up in combat. Oh, and if you want to make UTC changes, be aware that editing them and dumping them in the Override won't work for an existing save. That will require a save before entering the module or otherwise you'll need to edit the save itself, since a module's GIT is included as part of the save, which incorporates the UTC data from any (living) NPCs. 3 1 Quote Share this post Link to post Share on other sites
Jike 1 Posted November 24, 2019 This works absolutely beautifully! I actually can't thank you enough for all your help. I never could have done any of this myself with my current skillset! All I plan on doing now is a little modification of the quest with Iziz so that the player can go back to Iziz and tell him of their actions and it's done. I should be okay for that part, but I really can't thank you enough for all you've done! Quote Share this post Link to post Share on other sites
DarthParametric 3,777 Posted November 24, 2019 Note that if you plan on releasing this, for compatibility reasons you'll want to have it use TSLPatcher and ideally set it up for module injection rather than just dump everything in the Override folder. 1 Quote Share this post Link to post Share on other sites
Jike 1 Posted November 24, 2019 Thanks for the info, I was planning on using TSLPatcher however I'm not sure I know what module injection is. Quote Share this post Link to post Share on other sites
DarthParametric 3,777 Posted November 24, 2019 Creating a MOD file that goes in the Modules folder. Read the PDF that comes with TSLPatcher for more info. 1 Quote Share this post Link to post Share on other sites
Jike 1 Posted November 24, 2019 (edited) All right, I'll give that a read now. Thanks again for your help. EDIT: After reading through the PDF that comes with TSLPatcher, I'm assuming that for creating a MOD file, I'd need to create my own one for tat_m20aa since there isn't one already existing for that module? I'm also assuming that I'd be putting the Script Source files into said MOD file so the patcher can compile them. Edited November 24, 2019 by Jike still some confusion as to creating MOD files Quote Share this post Link to post Share on other sites