Creating a henchmen with Animal Companion

Hello everybody

I created a Druid henchmen, and while she does not summon her animal companion by herself, in the conversation file that I copied from some module you can ask her to do so, but then she summon a nameless naked dwarf.

What did I do wrong? In the conversation file, the action taken is called “69_hench_crtrsmn”, and it was written “HenchSummonCreature69();”. I changed to “SummonAnimalCompanion();” but nothing changed.
Her level up package is set to Default Druid.

I searched but could not find any answer. Could someone help me out?

Thank you very much.

Unless something had recently changed in EE, NWN’s NPCs aren’t really meant to summon ACs or familiars. It works though, but is quirky.

If you make your druid call this script:

void main()
{
    SummonAnimalCompanion();
}

and the druid has and can use the feat, it will always summon a unnamed badger (or a bat in case of SummonFamiliar()), which is the ResRef in row 0 from corresponding hen_*.2da table. Nothing is exposed in the toolset or in their blueprints to set the summon type.

It is trivial to set the missing name of AC summoned above (it also has the correct level), but if you want a total control over the process (i.e. choose AC type), you will have to use a workaround. I see two possibilities:

  1. Use EffectSummonCreature(), which takes care of everything (unsummon on rest, etc), but may (will) conflict with “normal” summons.
  2. Spawn AC as a henchman - no conflict, but you’ll have to do more scripting.

Hello

The problem was on the script, using only what you wrote solves the problem. It’s a pity it’s impossible to choose the animal without conflicting with summons. Thank you for enlightening me on the matter.

Thank you very much.

It is possible if you choose route #2 in my previous post.

You’ll just need to make sure you don’t duplicate the “companion”, manually decrease feat uses, show correct animation and VFX, and finally destroy the creature on rest. With all this you can pretty much replicate the vanilla AC/familiar system (except familiar possession, which makes no sense for NPCs anyway).

Small correction, but Animal Companions and Familiars persist through rests just like henchman do, so you wouldn’t have to destroy it upon resting unless the goal is to remove the “double use” the abilities have if you rest while they’re summoned. IMO it would make the most sense to add the request to unsummon them to their master’s conversation.

1 Like

You’re right. That makes it even easier (and eliminates route #1). Invoking the summon feat again just unsummons current creature, like vanilla does.

Another way to do it - more direct, although a bit unorthodox (you have to right click and then choose talk to) - is to modify nw_g_animal and nw_g_familiar to allow the PC to ask the companion to unsummon itself (no need to track who follows who). Same with regular summons, but through nw_ch_ac4 override (no convo to mod).

1 Like

The problem is that I know minimal of scripting, I don’t know how to do what you said.
Thank you for your suggestions though.

If you’re willing to learn, I can guide you through a script that will allow your NPCs to “use” their AC/fam summon feats.

I see. What do I need to do?

Thank you.

Script’s base looks like this (I’ll use AC as an example, changing it to familiars is rudimentary):

void SummonFakeAnimalCompanion(object oMaster=OBJECT_SELF)
{
    // your code here
}

void main()
{
    SummonFakeAnimalCompanion();
}

You can use this script anywhere in dialogue with your NPC.

Try this first (edit SummonFakeAnimalCompanion()):

  1. Check if oMaster (caller, your druid) has animal companion summon feat, if not - bail out (return).
  2. Create (for now) any creature and add it as oMaster's henchman.
  3. Decrement feat uses so oMaster cannot summon another creature without resting.

It’s always useful to put debug messages in the code i.e.

SendMessageToPC(GetFirstPC(), "Summoning creature");

I can understand this:

void main()
{
SummonFakeAnimalCompanion();
}

But the three steps you said are beyond me, I don’t know how to do it.

Thank you.

NWScript function names are quite self-explanatory and most of the time explained enough in the toolset (double-click on any of them for help) or in the Lexicon if you need more info.

So, when in doubt, type the words in function search inside code editor (top right corner).

This quickly resolves to what you’ll need:

  • “has animal companion summon feat” -> GetHasFeat
  • “Create (for now) any creature” -> CreateObject
  • “add it as oMaster’s henchman” -> AddHenchman
  • “Decrement feat uses” -> DecrementRemainingFeatUses

Play around those functions and see what you’ll get.

For example, beginning of SummonFakeAnimalCompanion() should look like this since there’s nothing to do without the feat.

// return if master has no feat (or already used it today)
if(!GetHasFeat(FEAT_ANIMAL_COMPANION))
{
    SendMessageToPC(GetFirstPC(), "Cannot use feat"); // debug
    return;
}

The next step is to spawn (create) some creature and check if it is valid.

Hello

I tried this, but of course it didn’t work. I don’t know how to use parenthesis and brackets.

{CreateObject Pebbles
oMaster AddHenchman
DecrementFeatUses 1}

Thank you.

Did you read Celowin’s primer on NWScript?

https://nwnlexicon.com/index.php?title=Category:Celowin

I suggest parts I, II, III, VIII and X.

It should provide basic knowledge how to read & write code.

Also double-click on every function name (like CreateObject) so you can see its invocation and description in the help box at the bottom of the script editor.

Hello

I hadn’t. I will give it a read and try again.

Thank you.

Hello

I read the tutorial and tried this:

    void main()
{
 if(!GetHasFeat(FEAT_ANIMAL_COMPANION))
   {
    SendMessageToPC(GetFirstPC(), "Cannot use feat");
    return;
   }
   object CreateObject(int OBJECT_TYPE_CREATURE, string sTemplate, location lLocation, int bUseAppearAnimation=TRUE, string sNewTag="" );

   void AddHenchman(object oMaster,object PEBBLES=OBJECT_SELF);

   void DecrementRemainingFeatUses(object oMaster, int FEAT_ANIMAL_COMPANION);
}

But there are things that I don’t know how to fill up, like sTemplate and lLocation.

Thank you.

Lexicon also contains explanation what every function in the game does and how it should be used, often with working examples. Just look them up through the search box on the left.

For example, CreateObject:

https://nwnlexicon.com/index.php?title=CreateObject

sTemplate is the ResRef of creature to spawn, for example nw_badger will cause a standard Badger to appear.

Location is where the object will appear in the game:

https://nwnlexicon.com/index.php?title=Location

Hello.

I tried this. It didn’t compile. Not sure I understand how to use the location even after reading the Lexicon. Here it is:

    void main()
    {
     if(!GetHasFeat(FEAT_ANIMAL_COMPANION))
       {
        SendMessageToPC(GetFirstPC(), "Cannot use feat");
        return;
       }
          {object CreateObject(int OBJECT_TYPE_CREATURE, string pebbles, location GetPosition(OBJECT_SELF), int bUseAppearAnimation=TRUE, string sNewTag="" );
      }
           {void AddHenchman(object oMaster,object PEBBLES=OBJECT_SELF);
           }
                 {void DecrementRemainingFeatUses(object oMaster, int FEAT_ANIMAL_COMPANION);
                 }
   }

Thank you.

Try the script from that page (I modified it a bit and removed pointless comments).

void main()
{
    // Object type to create
    int nObjectType = OBJECT_TYPE_CREATURE;
 
    // What to create - a "standard" chicken
    string sChicken = "nw_chicken";
 
    // Where to make the chicken appear
    location lTarget = GetLocation(OBJECT_SELF);
 
    // Actually create the object 
    object oChicken = CreateObject(nObjectType, sChicken, lTarget);
}

Observe how to properly call CreateObject (and the other two functions), then combine this with your current script. Make oChicken (the just-spawned NPC) a henchman of OBJECT_SELF (caller of the script).

Here is what I’ve done but it’s not working. I did just what the toolset help and the lexicon said on top of the page, but the AddHenchman is wrong. I don’t know what I did wrong. Here it is:

void main()
{
if(!GetHasFeat(FEAT_ANIMAL_COMPANION))
       {
        SendMessageToPC(GetFirstPC(), "Cannot use feat");
        return;
       }

    // Object type to create
    int nObjectType = OBJECT_TYPE_CREATURE;

    // What to create - a "standard" chicken
    string sChicken = "nw_chicken";

    // Where to make the chicken appear
    location lTarget = GetLocation(OBJECT_SELF);

    // Actually create the object
    object oChicken = CreateObject(nObjectType, sChicken, lTarget);


    object oMaster = Isiovien;

    object oHenchman = oChicken;

    void AddHenchman(oMaster, oHenchman=OBJECT_SELF);

                 {void DecrementRemainingFeatUses(object oMaster, int FEAT_ANIMAL_COMPANION);
                 }


}

Thank you