Copy and level up character - is this doable through scripting?

You’re welcome @andgalf.

You said yourself this could be game-breaking… Obviously I don’t know when this happens, but if you start at level 3 and this event takes place around level 4, maybe some wounds would not have been healed and you’ll face the same issue?
Instead of a fixed value of 40 HP, I’d rather go with a variable value of 15 or 20% of the current HP, so you’re sure she’s got at least 1 HP.

Well, you start at level 3, and the characters that joins your party are at that level from the beginning. This scene takes place at roughly 5 hours into the game. Still, you have a point. If I get a player that doesn’t do one single side quest, I guess I could have a serious problem at my hands.

If you don’t mind me asking, what would that look like script-wise if you were to set a variable of 15 % of current HP? Should you use something like the GetMaxHitPoints function perhaps, but how do you explain to the game how to take a percentage of that?

Something like this should set the character to 15% of their current HP:

void main()
	object oLoreen = GetObjectByTag("loreen");
	int nDMG = (GetCurrentHitPoints(oLoreen) / 20) * 17;

	ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oLoreen);

Thanks travus! Always there to the rescue. :smiley:

Now that function right there is something that I could never script:

I don’t actually know what /20 and *3 means in this case. I guess I’ll have to dig up kevL_s’ old script help to see if I can understand what’s happening here.

Actually change the 3 to 17. I updated the script sbove.


So, it seems these are just normal multiplication and division signs, right?
What’s the difference between GetCurrentHitPoints and GetMaxHitPoints in regards to scripting? Why do you use GetCurrentHitPoints in this case and not GetMaxHitPoints?

Yes, it’s just math.

You would probably be alright using Max HP, but I’d stick with Current HP in this scenario. Using Current HP is safer as we don’t want her to die. Using Max HP in this formula could cause more damage because of some unforeseen addition of HP from some other source. Or if she was wounded from some event prior, using Max HP in the formula would actually cause more damage to her, possibly killing her.

1 Like

Above, you damage Loreen by 15% of her current hit points (divide by 20 and multiply by 3 is the same as divide by 100 and multiply by 15).
Below, you instead keep 15% of her current hit points (as the damage amounts to 17/20 of the current hit points).

I don’t know if the integer calculation is done just before assigning the decimal value of GetCurrentHitPoints(oLoreen) / 20 * 17 or if (GetCurrentHitPoints(oLoreen) / 20) is already converted to an integer before being multiplied by 17. And I don’t know if only the integer part is kept, or rounded to the nearest integer.
So, since what we’re really looking for is to keep her alive, I’ll choose

int nDMG = (GetCurrentHitPoints(oLoreen) / 20) * 17 - 1;

that way, we’re sure she’ll have at least 1 HP.

Edit: changed +1 to -1

1 Like

The only reason is to make sure we don’t deduct too many hit points. What would happen if Loreen’s badly wounded already and has only say 6 HP left, and you make her lose 15% of her 48 (Max HP value), i.e. 7 HP?

1 Like

Ah, now I get it. She could already be wounded when we apply damage to her. Yes, I think I’ll go with your suggestion then, to be on the safe side:

But wait…how does this math work here (been too long since I did something like this in school), does the CurrentHitPoints get a +1 or the Damage in this function? (Maybe I’m just being stupid now, but it’s better to be safe than sorry, I guess)

Oops, my bad!
We calculate the damage, so it’s -1 instead of +1 we want!

So here the total damage is 85% of the current hit points, from which we deduct 1 to make sure she’ll keep at least 1 HP after the damage is applied to her.

Ah, good I spotted that then. So, like this then:

int nDMG = (GetCurrentHitPoints(oLoreen) / 20) * 17 -1;
1 Like

Yes. So even with a first-level character your script will damage her but not enough to kill her! :wink:

1 Like

Tested it ingame now with my level 1 character just to be sure…Everything works now. One thing though…She now is just “injured”. I wonder if one should go for a slightly higher value for multiplication to make her appear “badly injured” (or how it is displayed exactly ingame) like:

What do you think? Or could one even go with *19 since we made sure she has at least 1 HP?

Edit: I went with *18 and she’s still just “Injured”, but maybe I shouldn’t push my luck and just let it be at that. I don’t want new errors in this quest.

Here’s a new and improved version of reducing the character’s current HP to 15%. This will never go below 1 HP because of the way floats are converted to INTs (apparently INTs always round down). This is a hell of a lot more accurate, too.

void main()
	object oLoreen = GetObjectByTag("loreen");
	int nHP = GetCurrentHitPoints(oLoreen);
	int nDMG = FloatToInt(nHP * 0.85f);

	ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oLoreen);
1 Like

Not really related to the topic at hand to be honest but before I quit nwn2 and started focusing on my EE PW, I had the idea which would work for any PW really, having players design or plan their builds a la
the NWN2DB, then save that information to auto-level up their characters, you know because they very often make mistakes and it’s probably easier.

There’s multiple ways to achieve this, at the time I had thought of modding the chargen/levelup GUI and with scripting, but nowadays I’d think straight up editing the bics would be much easier to implement.

Editing bics is not very complicated at all, but most of visible tools are really “marketed” for nwn1, and most modders I know from nwn2 would never even think of loading OEIShared.dll on visual studio to check what’s doable, so you can probably check the set of tools called neverwinter nim by niv, I haven’t tried but I imagine they work just the same for nwn2. Though be advised the windows version doesn’t work very well, so you’re better off saving yourself the hassle and install something like WSL to run the linux version if you’re running windows.

@travus Ok, I’ll try out your improved script.