I need a script for a passive feat that adds temporary hit points to the character that has the feat only once (and does not stack the temporary hit points.) Also I need it so if more than one character has this feat that both characters get the right number of hit points and not the highlighted character get all of the temporary hit points while the other gest none.
I have this script thus far; #include “X0_I0_SPELLS” #include “nwn2_inc_spells”
void main()
{
object oPC = GetLastPCRested();
object oTarget = OBJECT_SELF;
int iSWhisp = GetLevelByClass(64, oTarget);
int iSWarr = GetLevelByClass(67, oTarget);
int iCaster = iSWhisp+iSWarr;
int iWis = GetAbilityModifier(ABILITY_WISDOM, oTarget);
int iBonus = (iWis)*3;
int iTempHP = (iCaster+iBonus);
If the feat is persistent and properly set up with a correct association to the spells.2da this script should be its impact spellscript, and it should work with the following:
void main()
{
object oPC = OBJECT_SELF;
if (GetHasSpellEffect(GetSpellId(), oPC) == TRUE) return;
int nSWHISP = GetLevelByClass(64, oPC);
int nSWARR = GetLevelByClass(67, oPC);
int nWIS = GetAbilityModifier(ABILITY_WISDOM, oPC);
if (nWIS < 0) nWIS = 0;
int nHP = nSWHISP + nSWARR + nWIS * 3;
effect eFX = EffectTemporaryHitpoints(nHP);
eFX = ExtraordinaryEffect(eFX);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eFX, oPC);
SendMessageToPC(oPC, "Youthful vigor active!");
}
Now that I think about it, though, I’m not sure if using temporary hit points for this is a good idea, the effect would reapply itself as soon as those temporary hit points are removed via damage (after area transition, or reload), perhaps it would be better to change them to BonusHitPoints, the effect would be roughly the same, but it would not be removed by damage.
I also found a small workaround to keep the script more similar to your original idea, with temporary hps that last for 72 hours instead of being permanent, the little “downside” is that I had to add an additional permanent effect that grants 2 (not 1 because odd numbers are gross ) max hp and reduce the amount of temporary hp by 2, it makes almost no difference in terms of gameplay, but it’s needed to avoid the double stacking without recurring to local variables and a modified rest script.
The probl i see with a Persistent feat is that it’s going to fire on more events than just the OnRested event.
(the benefit to Persistent is that it could fire in any module that uses your Spells and Feat 2das)
But since you seem okay with modifying the (module-level) OnRested script … i’d suggest removing the IsPersistent flag from the feat, and doing this in the REST_EVENTTYPE_REST_FINISHED section of your OnRested:
if (GetHasFeat(2813, oRested))
ExecuteScript("spirit_youth", oRested);
That is, there’d no longer be a spell or spellscript. The feat becomes merely an utterly passive feat. Until a character with the feat rests, that is …
the script should then remove any temporary HP, re-apply its effect, and it doesn’t need a custom ID if you go this route
ALTERNATELY, you could keep the feat as a spellability, with its spellscript, but set a variable in the OnRested script, that allows the spellscript to run its code on the rested character, then clear the variable in the spellscript … the result would be that any other event that fires your Persistent feat’s spellscript bypasses the body of its code
all the scripts posted in this topic are for a persistent feat, obviously they wont fire properly if called from OnRest, because OBJECT_SELF in that case, is the module, not the feat target.
For a OnRest event (which I wouldn’t recommend), you would need different scripts.
Ah, that’s right I didn’t see that part on the fourth post, I just looked at the original script and I saw GetLastPCrested (which, by the way, is defined and never called again?), so I assumed it was used like that on the rest script.
Still, I don’t see handling the resting type of event (if started, cancelled, finished) anywhere and I still think that handling via the OnRest event is more trouble than worth, especially if the OP has already set up a persistent feat that fired at least.
Also, the OnRest event won’t handle the feat when obtained on level up, you’d have to modify the On Level up script as well, whereas the persistent feat handles all possible types of events (except resurrection) and you just need to use a trick to avoid the double stacking.
We don’t know how he has defined oTarget there, if it’s OBJECT_SELF, then he’s running that script on the module, and we’re back to square one, it won’t fire at all.
well that’s the thing, i don’t favor mucking about with module-level events either. But it seems to me that’s got to happen if darin wants to exclude other events (ie, not OnRested events) from handling the SpiritYouth feat, whether he flags the feat as IsPersistent or not. unfortunately …
in either case, i got it to work fine here, without Active/Persistent set. I (temporarily) repurposed ChannelMuse (as not Active, not Persistent). used this for an OnRested script
// 'k_mod_player_rest'
void main()
{
switch (GetLastRestEventType())
{
case REST_EVENTTYPE_REST_STARTED:
break;
case REST_EVENTTYPE_REST_FINISHED:
{
object oRested = GetLastPCRested();
SendMessageToPC(GetFirstPC(FALSE), "checking for feat #9020");
if (GetHasFeat(9020, oRested)) //2813
{
SendMessageToPC(GetFirstPC(FALSE), ". feat found fire spirit_youth");
ExecuteScript("spirit_youth", oRested);
}
break;
}
case REST_EVENTTYPE_REST_CANCELLED:
break;
}
}
and this for the pseudo-spellscript
// 'spirit_youth'
#include "nw_i0_spells"
void main()
{
RemoveTempHitPoints();
object oTarget = OBJECT_SELF;
// int iSWhisp = GetLevelByClass(64, oTarget);
// int iSWarr = GetLevelByClass(67, oTarget);
// int iCaster = iSWhisp + iSWarr;
int iCaster = GetTotalLevels(oTarget, FALSE);
int iWis = GetAbilityModifier(ABILITY_WISDOM, oTarget);
int iBonus = iWis * 3;
int iHp = iCaster + iBonus;
effect e = EffectTemporaryHitpoints(iHp);
e = SupernaturalEffect(e);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, e, oTarget, HoursToSeconds(72));
SendMessageToPC(GetFirstPC(), "Youthful vigor active!");
}
this is the best i could do on the script. Note that as an ExtraordinaryEffect it gets removed by resting automatically. The extra hitpoints appear on the character sheet, but not on the PC’s portrait.
// 'spirit_youth'
void main()
{
object oTarget = OBJECT_SELF;
SendMessageToPC(oTarget, "Youthful vigor active!");
// int iSWhisp = GetLevelByClass(64, oTarget);
// int iSWarr = GetLevelByClass(67, oTarget);
// int iCaster = iSWhisp + iSWarr;
int iCaster = GetTotalLevels(oTarget, FALSE);
int iWis = GetAbilityModifier(ABILITY_WISDOM, oTarget);
int iBonus = iWis * 3;
int iHp = iCaster + iBonus;
effect e = EffectTemporaryHitpoints(iHp);
e = ExtraordinaryEffect(e);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, e, oTarget, HoursToSeconds(72));
}
i also tried EffectBonusHitpoints() but after 2+ rests it wants to stay at double extra HP …
I am getting double extra HP with both bonus hit points and temporary hit points. All I do is click between different character portraits and it behaves correctly for the first click on the character but doubles by the time I click on another portrait and return to the original. Bonus hit points still require the character to heal themselves up to the “bonus maximum,” so I am still confused on this one.
construct and apply EffectHeal(GetMaxHitPoints()) right after adding bonus hp and that part of it should be taken care of
ps. i should point out that buggy extra HP is a known fact about the nwn2 engine: Kaedrin went to great lengths to try a fix for it in his PrC Pack … but i don’t think it has yet been truly/reliably worked around – although, I’m not sure what the bug is exactly or if it’s applicable here …
I’d say, all in all, if you get it working reasonably to your liking yer doin ok