I’d be grateful for a little help on the topic of henchman if anyone has time ( and if they know anything about it so much the better )
Some of you may know, I’m working with kids in a Games Design class using NWN:EE this year and its going pretty well so far. however, since I only came across NWN in January of this year and the class is pretty decent it has been a little like the blind leading the much more capable . . .
At the moment I’m looking to introduce them to how to create a henchman in their modules.
I’ve had a look at the Module Builder’s Henchman Kit but it seems pretty elaborate and, besides, I use a Mac and it keeps crashing (!). So, at the moment I’m going with the simple approach of creating the henchman, loading the “set_xp2_henchman.ini” scripts and constructing a conversation with a Script Generator script to hire them. Works perfectly and tbh, its as much as they need.
However, I just can’t seem to figure out how to respawn the henchman in a place of my choosing. I’ve been pluttering around trying to add henchie tags to the PC death temple Waypoint, trying to alter their OnDeath script ( without having a clue what I’m doing), using a SG script to respawn but trying to change PC to the Henchman’s tag but it strikes me there has to be an easier way - or, more accurately, one that actually works, short of equipping my PC with a job lot of Rods of Resurrection.
Any help would be appreciated. I’ve done quite a bit of ferreting about here and elsewhere and can’t seem to find the answer to this.
I assume this is what you are looking for. So here’s a resurrection MWE - put it as any creature’s OnDeath handler. You can tailor it to your custom hench AI.
// raises OBJECT_SELF after death at location of object with tag "RESPAWN"
#include "nw_i0_plot"
// function made after RespawnHenchman from x0_i0_henchman
void RespawnHenchman(location lSpot, object oTarget=OBJECT_SELF)
{
// resurrect
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_PERMANENT,
EffectResurrection(), oTarget));
// heal
DelayCommand(0.2, ApplyEffectToObject(DURATION_TYPE_PERMANENT,
EffectHeal(GetMaxHitPoints(oTarget)), oTarget));
// jump
DelayCommand(0.3, AssignCommand(oTarget,
JumpToLocation(lSpot)));
// remove negative effects
DelayCommand(0.4, RemoveEffects(oTarget));
// make destroyable again (NOT REQUIRED)
DelayCommand(0.5, AssignCommand(oTarget,
SetIsDestroyable(TRUE, TRUE, TRUE)));
}
void main()
{
// make sure the object sticks around when dead
SetIsDestroyable(FALSE, TRUE, TRUE);
ActionSpeakString("I AM DEAD");
ActionWait(2.5); // dead object cannot perform this action!
ActionSpeakString("I'LL RAISE SOON");
// resurrect at target location after 5 seconds
DelayCommand(5.0, RespawnHenchman(
GetLocation(GetObjectByTag("RESPAWN")), OBJECT_SELF));
}
Some boring details:
Dead creatures cannot perform a lot of Actions. For example ActionSpeakString works, but ActionWait does not.
Dead creatures cannot JumpToLocation/Object - they need to be raised first.
There is a working set of functions in x0_i0_henchman but they aren’t generic - this code is.
I spoke a little too soon., @NWShacker. The script does resurrect the NPC but he seems to be respawning at the point where he died rather than at the Waypoint with the tag “Respawn” that I created for him.
I’m guessing I’ve done something wrong but can’t think what.
EDIT. Yup, user error. Lower / Upper case always my downfall in scripting !!!
no, i think there’s a small glitch in nwshacker’s script :
DelayCommand(0.3, JumpToLocation(lSpot));
this works fine as long as the routine is called w/o a 2nd parameter, because then oTarget resolves to OBJECT_SELF, so all of the functions work on the same object. however, if called w/an explicit 2nd argument, the other function calls target the parameterised object, but the above call still targets OBJECT_SELF – which may not be the henchman. instead of that, you may want to try sth like :
since you’ve only just revived the henchie, there should be no need to ClearAllActions() beforehand, but if you modify the routine to do other things, keep in mind that [1] JumpToLocation(lSpot)should normally add the jump in at the head of the queue while ActionJumpToLocation(lSpot) adds it to the end, and [2] you may need to clear all actions first.
Yeah, the AssignCommand was missing. Silly mistake. It worked in the scope of this script but would be wrong in a library. Which leads to the fact, that the original BioWare script has the same error - undiscovered until today (?) since only henchies were calling that subroutine.