Jump to content

SubtleMods: NPC_EE - in-game customization for NPCs


Recommended Posts

17 hours ago, Iecerint said:

Maybe it has to do with Artisan's House Tweaks?

Dunno what his mod does. I’ve seen there have been some recent updates with issues, but… if you look at a .CRE file with Near Infinity, you can see a bunch of opcode 233 effects representing their proficiencies. All NPC_EE does is fill out the “parent resource” field in those op233 effects, so that they will be subject to op321 in-game. I don’t know how or why another mod could interfere with that…

Also, neither here nor there but:

18 hours ago, Iecerint said:

need to uninstall D2K and EEUITweaks temporarily

Adding UI tweaks at the end of your install order could cause problems. Wait, did we already have this conversation?

Link to comment

I uninstalled 5.9.6 and installed an older version (5.7.1) and now it works fine. So here's a bunch of response triggers in fighter proficiency assignment dialog (d5prffi) from 5.7.1:

Response trigger 0

  GlobalGT("D5_BASTARD_SWORD","LOCALS",0)
ProficiencyLT(Myself,PROFICIENCYBASTARDSWORD,1)

Response trigger 1

  GlobalGT("D5_BASTARD_SWORD","LOCALS",1)
Proficiency(Myself,PROFICIENCYBASTARDSWORD,1)
CheckStatGT(Myself,0,LEVEL)

Response trigger 2

  GlobalGT("D5_BASTARD_SWORD","LOCALS",2)
Proficiency(Myself,PROFICIENCYBASTARDSWORD,2)
CheckStatGT(Myself,2,LEVEL)

Response trigger 3

  GlobalGT("D5_BASTARD_SWORD","LOCALS",3)
Proficiency(Myself,PROFICIENCYBASTARDSWORD,3)
CheckStatGT(Myself,5,LEVEL)

Response trigger 4

  GlobalGT("D5_BASTARD_SWORD","LOCALS",4)
Proficiency(Myself,PROFICIENCYBASTARDSWORD,4)
CheckStatGT(Myself,8,LEVEL)

Now look at this mess in fighter proficiency assignment dialog from from 5.9.6:

Response trigger 0

  GlobalGT("D5_PROF_89","LOCALS",0)
ProficiencyLT(Myself,PROFICIENCYBASTARDSWORD,1)

Response trigger 1

  GlobalGT("D5_PROF_89","LOCALS",1)
Proficiency(Myself,PROFICIENCYBASTARDSWORD,1)
CheckStatGT(Myself,9,LEVEL)

Response trigger 2

  GlobalGT("D5_PROF_89","LOCALS",2)
Proficiency(Myself,PROFICIENCYBASTARDSWORD,2)
CheckStatGT(Myself,1,LEVEL)

Response trigger 3

  GlobalGT("D5_PROF_89","LOCALS",3)
Proficiency(Myself,PROFICIENCYBASTARDSWORD,3)
CheckStatGT(Myself,4,LEVEL)

Response trigger 4

  GlobalGT("D5_PROF_89","LOCALS",4)
Proficiency(Myself,PROFICIENCYBASTARDSWORD,4)
CheckStatGT(Myself,8,LEVEL)

Response trigger 5

  GlobalGT("D5_PROF_89","LOCALS",5)
Proficiency(Myself,PROFICIENCYBASTARDSWORD,5)
CheckStatGT(Myself,8,LEVEL)

It's the same for all classes and proficiencies, except druid for some reason.

Link to comment

Those CheckStatGT(Myself,x,Level) are read from values in PROFSMAX.2da. I can take a look at the code but again it works in my install, so it might be something in your game that’s different. (Does that .2da file have a different number of columns or something?)

I’ll take a look when I can.

Link to comment

Here's my profsmax.2da:

2DA V1.0
0
                    FIRST_LEVEL OTHER_LEVELS 3          6          9          
MAGE                2          5          3          4          5          
FIGHTER             2          5          3          4          5          
CLERIC              2          5          3          4          5          
THIEF               2          5          3          4          5          
BARD                2          5          3          4          5          
PALADIN             2          5          3          4          5          
FIGHTER_MAGE        2          5          3          4          5          
FIGHTER_CLERIC      2          5          3          4          5          
FIGHTER_THIEF       2          5          3          4          5          
FIGHTER_MAGE_THIEF  2          5          3          4          5          
DRUID               2          5          3          4          5          
RANGER              2          5          3          4          5          
MAGE_THIEF          2          5          3          4          5          
CLERIC_MAGE         2          5          3          4          5          
CLERIC_THIEF        2          5          3          4          5          
FIGHTER_DRUID       2          5          3          4          5          
FIGHTER_MAGE_CLERIC 2          5          3          4          5          
CLERIC_RANGER       2          5          3          4          5          
SORCERER            2          5          3          4          5          
MONK                2          5          3          4          5          
SHAMAN              2          5          3          4          5          

It's not even in override.

Link to comment

My PROFSMAX.2da shows:

                    FIRST_LEVEL OTHER_LEVELS  2          5          9        
FIGHTER             	1          7          2          3          4        

And D5CPRFFI.D shows:

IF ~GlobalGT("D5_PROF_89","LOCALS",1) Proficiency(Myself,89,1) CheckStatGT(myself,1,LEVEL)~ THEN REPLY #31126 GOTO d5cprffi_289
IF ~GlobalGT("D5_PROF_89","LOCALS",2) Proficiency(Myself,89,2) CheckStatGT(myself,4,LEVEL)~ THEN REPLY #31126 GOTO d5cprffi_389
IF ~GlobalGT("D5_PROF_89","LOCALS",3) Proficiency(Myself,89,3) CheckStatGT(myself,9,LEVEL)~ THEN REPLY #31126 GOTO d5cprffi_489
IF ~GlobalGT("D5_PROF_89","LOCALS",4) Proficiency(Myself,89,4) CheckStatGT(myself,9,LEVEL)~ THEN REPLY #31126 GOTO d5cprffi_589
IF ~GlobalGT("D5_PROF_89","LOCALS",5) Proficiency(Myself,89,5) CheckStatGT(myself,9,LEVEL)~ THEN REPLY #31126 GOTO d5cprffi_689

So almost working perfectly. Those later CheckStatGTs should be checking for '(myself,8.LEVEL)' instead of 9. Although, in this game it makes no difference since fighters get a pip at level 10 and non at level 9. Still, worth looking into.

Hm, but on an unmodded profsmax there is a problem. I'll see about fixing it.

Link to comment

Right... the PROFSMAX headers amount to "level >= this", so you need to be subtracting 1 systematically when you convert that to a LevelGT check. Except that this isn't happening for the last one, at least not consistently. And also, you never actually read the header. Since you're working with a version that has an altered header row from the base game, that's something that needs to be done.

That block in dialprof.tpa that interprets profsmax.2da is over 800 lines of highly repetitive code, and mistakes crept in. It could probably use a full reimagining. Reorganizing it all to use loops for a lot less code would make it a lot easier to debug.

Link to comment
1 hour ago, jmerry said:

Right... the PROFSMAX headers amount to "level >= this", so you need to be subtracting 1 systematically when you convert that to a LevelGT check. Except that this isn't happening for the last one, at least not consistently. And also, you never actually read the header. Since you're working with a version that has an altered header row from the base game, that's something that needs to be done.

That block in dialprof.tpa that interprets profsmax.2da is over 800 lines of highly repetitive code, and mistakes crept in. It could probably use a full reimagining. Reorganizing it all to use loops for a lot less code would make it a lot easier to debug.

Believe me, I tried to figure out how to slim down that code. My fingers were bleeding after writing it. There were... reasons... I couldn't make it simpler. I don't remember what the reasons were, but I remember being frustrated by it.

At any rate, that isn't the problem. Looking at it, I can't at all figure out why I had that '9' there in the first place... except that the '9' key is right next to the '0' key. I think it was a simple fat-finger typo, which was then copied and pasted into every other instance of the same line.

I have fixed it locally, and I'm now testing it and the other improvements I've added (another choice in the Tome, to change proficiencies without changing anything else). Version 6.0 should be inbound very soon.

@Enkidu you've already identified the dialogues with the error ("d5prfxx.dlg," one for each class - fi, th, ma, etc.) If you don't want to deal with reinstalling mods and just want to play the game, simply change those 9's to 0's. Only needs to be done in dialogues where the class can get 2 pips in the first place... given you are using the vanilla proficiency system, that means fighter, ranger, paladin, and thief (for swashbucklers). Maybe monk as well? I never remember how monks work.

Link to comment
49 minutes ago, subtledoctor said:

Believe me, I tried to figure out how to slim down that code. My fingers were bleeding after writing it. There were... reasons... I couldn't make it simpler.

Off the top of my head ... reporting the data in an array rather than individually named variables would cut things down a lot. Instead of testing for every class to see which variables to set, just report the class as one of the array keys.

In my look at the code, the "9"s seem to be for cases in which the global proficiency maximum is greater than the level 9 maximum. With your PROFSMAX in which the level 9 cap is high mastery, can you take grand mastery at some level higher than 9? Then "50" goes to cases in which the global proficiency maximum is lower and you can't reach that proficiency level at all.

Which doesn't explain why you're seeing "9" in the third line for high mastery, where it should be "8". I haven't figured out where the logic breaks. There's certainly a possibility of assignments being overwritten, but I don't see it actually happening given those inputs and that particular block of code...

Link to comment
10 minutes ago, jmerry said:

In my look at the code, the "9"s seem to be for cases in which the global proficiency maximum is greater than the level 9 maximum.

But that case should not be necessary to handle. I think, rather, that what is intended to be covered is when the level 1 limit is higher than the limit under consideration - if, say, someone changed PROFSMAX such that you could spend 3 pips at level 1, and we are defining what the lower level limit is to have 2 pips. In that case the proper value should be 0.

I changed the 9s to 0s and tested, and everything seems to work properly. So I have updated the mod to version 5.9.9 with that change, as well as a fix for a mistaken dependency on a separate mod for one resource. (There are some hard-to-pin-down issues with v6.0, that will have to wait a bit.)

Link to comment
On 3/29/2023 at 9:06 AM, subtledoctor said:

Adding UI tweaks at the end of your install order could cause problems. Wait, did we already have this conversation?

I'd thought you were saying that LeUI should go earlier, which I did notice is true for most install orders I've seen modders post, but I'd noticed that further tweaks other than LeUI are added later, because they can interfere with SCS if added before SCS. Maybe that's a dated concern.

But, simply reinstalling NPC_EE as you suggest did the trick, and D2K reinstalled automatically.

Link to comment

Does this try to autolevel NPC's to our PC's level at all? Like SCS's Improved NPC Customization is supposed to do? That's the main thing I like about the SCS component but it seems a bit borked from what I can tell/research/have experienced. 

Link to comment

No. In fact seeing the trouble people have with that mod partly informed the design of this one. 

Here, someone joins the party with X xp, then you can use the tome and go to level zero, but the xp value is never touched. You level back up to the same xp. End of story. If you want to mess around beyond that (set someone up as a dual class, or something) then you can use the SetCurrentXP() console command. 

Edited by subtledoctor
Link to comment

rip, makes sense. I will just learn to live with console GiveXP and use it during appropriate-ish moments and not every two seconds of changing party members or something. Got the mod and am reinstalling everything, thanks for making this!

EDIT:
Different question - do you have any recommendations on stat changes for the newly multiclassed NPC's(via selecting remove dual-class flag thingy options) for an EET game running with Ascension+WoP+SCS with a number of selected components including every component that overhauls the final battles in each game?
 

This is a bit subjective obvs, but you have more experience with the game than me so would love to hear your take. What would/do you personally adjust them to statwise for balance reasons and not accidentally having OP companions?

Edited by Sight
added a question :3
Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...