Aller au contenu

Photo

Help with Henchman


  • Veuillez vous connecter pour répondre
18 réponses à ce sujet

#1
HugoLuman

HugoLuman
  • Members
  • 26 messages
Okay, so I have this henchman in my mod:

Name: Mordecai
class: Fighter
Alignment: Chaotic Evil
Appearance: Curst Swordsman
Race: Half-Elf
Gender: Male

The problem is, he won't level up. He is using all the SOU henchman scripts, which the tutorial says should work. Help?

#2
Luspr

Luspr
  • Members
  • 44 messages
How are you trying to level him up?

#3
HugoLuman

HugoLuman
  • Members
  • 26 messages
He's supposed to auto-levelup when the player levels up. Is putting "Mordecai Level x" in his comments tab important? I notice that there are several copies of the default henchmen like that

#4
HugoLuman

HugoLuman
  • Members
  • 26 messages
Ok, now he levels up, but only if you fire him and re-hire him. How do I get him to auto-level?

#5
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
Do you have a conversation attached to your henchman?

Most of the henchmen I remember level when you talk to them and ask them to level up.

I guess you could auto level them when you level your self. That would still take some extra code being added to the modules OnPCLevelUp Event.

Leveling up aof a henchman is done with the LevelUpHenchman Function

// Levels up a creature using default settings.
// If successfull it returns the level the creature now is, or 0 if it fails.
// If you want to give them a different level (ie: Give a Fighter a level of Wizard)
// you can specify that in the nclass.
// However, if you specify a class to which the creature no package specified,
// they will use the default package for that class for their levelup choices.
// (ie: no Barbarian Savage/Wizard Divination combinations)
// If you turn on bReadyAllSpells, all memorized spells will be ready to cast without resting.
// if nPackage is PACKAGE_INVALID then it will use the starting package assigned to that class or just the class package
int LevelUpHenchman( object oCreature, int nclass = class_TYPE_INVALID, int bReadyAllSpells = FALSE, int nPackage = PACKAGE_INVALID)

Your Question may get better answers if you posted it in the scripting forum. 

Modifié par Lightfoot8, 17 août 2010 - 08:07 .


#6
Fester Pot

Fester Pot
  • Members
  • 1 391 messages
Is your companion Level 1 to start? Then they will level up when they join to meet your current level.

This could be why they only level when you fire them and rejoin. I think the SOU system reverts fired companions back to level 1 so they can be properly leveled up when they rejoin the PC.

FP!

Modifié par Fester Pot, 17 août 2010 - 08:07 .


#7
HugoLuman

HugoLuman
  • Members
  • 26 messages
Yeah, he's level 1. He levels when he joins up, but firing/rehiring to level up is not something I want to do. Asking him to level up through dialogue does not work for some reason, even though I am using the correct script.

#8
420

420
  • Members
  • 190 messages

HugoLuman wrote...

Yeah, he's level 1. He levels when he joins up, but firing/rehiring to level up is not something I want to do. Asking him to level up through dialogue does not work for some reason, even though I am using the correct script.

It would help if you posted the script you are using in the conversation.

I use a Heartbeat script on my server's henchmen to check the PC's level and level up to that if they are below that level.

-420

#9
HugoLuman

HugoLuman
  • Members
  • 26 messages
Wait I got the script to work. It would be nice if the henchman leveled up automatically, bu the conversation option now works fine. I am using the x0 henchman scripts and the x2 henchman death script

#10
420

420
  • Members
  • 190 messages

HugoLuman wrote...

Wait I got the script to work. It would be nice if the henchman leveled up automatically, bu the conversation option now works fine. I am using the x0 henchman scripts and the x2 henchman death script

Here is the code I use in the henchman's OnHeartbeat script:
if(GetHitDice(OBJECT_SELF) < GetHitDice(GetMaster()))
    {
    int nHD = GetHitDice(GetMaster()) - GetHitDice(OBJECT_SELF);
    while(nHD > 0)
        {
        LevelUpHenchman(OBJECT_SELF, class_TYPE_INVALID, TRUE, PACKAGE_INVALID);
        nHD = nHD-1;
        }
    }

I also use this code in OnHeartbeat to clean up any henchman that have been removed from the party:
if(GetAssociateType(OBJECT_SELF) != ASSOCIATE_TYPE_HENCHMAN)
   {
   ExecuteScript("destroyself", OBJECT_SELF);
   }

-420

EDIT: The "destroyself" script simply sets the object to destoyable then destroys it.

Modifié par 420, 22 août 2010 - 06:51 .


#11
HugoLuman

HugoLuman
  • Members
  • 26 messages
That is good to know. I shall clean up my henchman's scripts, then.

#12
Mudeye

Mudeye
  • Members
  • 126 messages
The way I make henchmen keep leveled up is to make my own module level up script. It is called OnPlayerLevelUp. It just grabs all the PCs henchmen and levels them up. You can even make it do things like multiclassing if you like. I made a conversation option for the Henchman so you can tell them how you want them to train when they level up and then set the name of the level up package you want them to use as a local variable on the NPC. The OnPlayerLevelUp script checks for that on the Henchman and uses that as the package for leveling up.

Also, the heartbeat scripts fire every 6 seconds so if you use them too much it can cause a lot of lag.  The OnPlayerLevelUp only happens when a player actually levels up.

Modifié par Mudeye, 08 octobre 2010 - 05:49 .


#13
ffbj

ffbj
  • Members
  • 593 messages
Q. What if the PC does not have their henchman with them when they level up?

With 420's script you could add a line at the top which checks to see if the hd of the pc equals the hd of the npc henchman then return the script if that statement is true.  That may save some checks though the while loop only executes if there is a difference in levels.  Not sure if that would save cpu cycles or not. 
Though the level up idea is fine as long as the players know that it only works if the henchman is in party when the pc levels up.  I could envision other problems with this method though, such as:  You just made a level and meet someone who offers to join your party, well you can't level them to your level until you level up, so here the conversation option would be a neccessity. 

Modifié par ffbj, 08 octobre 2010 - 10:10 .


#14
Mudeye

Mudeye
  • Members
  • 126 messages
I have a script to level a new henchman when you take them on. When they become your henchman they level up. There is an on level up event for the PC where the other script is. It will level up any henchmen you already have. If you ever take a new henchman it gets leveled up automatically. The existing henchmen get leveled up whenever you do. They don't have to be near you or anything.



The issue I have with 420's script is that it runs every 6 seconds no matter what. If you make a lot of heartbeat scripts you can count on your system lagging down.

#15
Mudeye

Mudeye
  • Members
  • 126 messages
Here are  a couple of scripts for leveling up henchmen. 
I level them up to the same level as the PC.  If you want them to be 2 levels lower
OnPCLevelUp then change:    while( hlvl < mlvl && hlvl!=0 )
to be:    while( hlvl < mlvl - 2 && hlvl!=0 )
in the second script.  All henchmen must start out as level 1.
When you add them they level up to match the PC.  You can set a local string on the NPC to a class package id and that will be used for leveling the henchman instead of the default if you want.
 

void main()
{
    object pc = GetPCLevellingUp();
    int mxHench = GetMaxHenchmen();
    int i;
    object hench;
    int lvl=0;
    for( i=0; i<mxHench; i++ )
    {
        hench = GetHenchman( pc, i+1 );
         //look for a levelclass id on the henchman  if it has been set
         //it will be a package name for leveling

        int cls = GetLocalInt( oHenchman, "levelclass");
          //if it wasn't set then we just use the invalid which uses default class

        if( cls == 0 )
        {
            cls = class_TYPE_INVALID;
        }
        if( hench != OBJECT_INVALID )
        {
           lvl = LevelUpHenchman(  hench, cls  );
           //you can put tests here to make sure the henchman leveled up.
        }
    }
}

Below is the add henchman script that I used for actions taken when you take on a henchman.
It goes in the conversation as the ActionsTaken script

#include "NW_I0_GENERIC"
#include "x0_i0_assoc"
void main()
{
    object oSpeaker = GetPCSpeaker();
    object oHenchman = OBJECT_SELF;
    AddHenchman(oSpeaker, oHenchman);

              //flag to remember that this NPC was once a henchman
    string hname = GetTag( OBJECT_SELF ) + "washench"; 
    SetLocalInt( oSpeaker, hname, 1 );

          //set the desired NPC behaviors
    SetAssociateState(NW_ASC_DISTANCE_2_METERS, TRUE);
    SetAssociateState(NW_ASC_DISTANCE_4_METERS, FALSE);
    SetAssociateState(NW_ASC_DISTANCE_6_METERS, FALSE);
    SetAssociateState(NW_ASC_MODE_DEFEND_MASTER);

          //level up the henchman
    int i;
    int mlvl=0;
    int nlvl = 0;
    mlvl = GetHitDice(oSpeaker);
    nlvl = GetHitDice(oHenchman);
    int hlvl= GetHitDice(oHenchman);

          //look for a levelclass id on the henchman  if it has been set it will be a package name for leveling
    int cls = GetLocalInt( oHenchman, "levelclass");
          //if it wasn't set then we just use the invalid which goes to the default class
    if( cls == 0 )
    {
        cls = class_TYPE_INVALID;
    }
          //now level up the henchman in the specified class
    while( hlvl < mlvl && hlvl!=0 )
    {
        hlvl = LevelUpHenchman( oHenchman, cls );
    }

}

Modifié par Mudeye, 09 octobre 2010 - 05:58 .


#16
Xovian

Xovian
  • Members
  • 87 messages

HugoLuman wrote...
The problem is, he won't level up. He is using all the SOU henchman scripts, which the tutorial says should work. Help?

I know this post is a little old, but it gets asked fairly often and thought a full responce would be useful for all.
Like 420 I always run my codes in the OnHeartbeat, though originally I used
the LevelHecnhmanUpTo function as it gave a bit more control, though it
would sometimes use the Commoner package because of the usual
PACKAGE_INVALID. Really wished they had made a PACKAGE _RANDOM function,
but I have found the next best thing. I will post the  Include file Source . Followed by two scripts which I use for Henchman and then regular NPC's repectivly, in the OnHeartBeat of course. I changed the include file some, raised the level before a prestige class is taken (3rd slot), removed harper scout, and made Fighter the default class for invalid (int of -1) instead of the barbarian.

For henchman:

// Level up script for the Henchman's
    // This only works on Henchman of Level 1
    // This level up script fires only once.
int iLevel = GetLocalInt(OBJECT_SELF, "Levelup");//Int that stops the script from fireing more then once
    object oPC = GetMaster();//The Player
   
 if(GetIsObjectValid(oPC) && (iLevel==0))//Check that the player
 is a valid player and that the int is a certain number
      {
       if(GetHitDice(OBJECT_SELF) < GetHitDice(GetMaster()))//HD of henchman compared to master/player
         {
          object oObject = OBJECT_SELF;
          int nHD = GetHitDice(GetMaster()) - GetHitDice(OBJECT_SELF);//HD of master/player compared to henchman
          SetLocalInt(oObject, "nclass1Min", 1);//class minimum for primary class
          SetLocalInt(oObject, "nclass2Min", 0);//Random non-Prestige class.
         
 SetLocalInt(oObject, "nclass3Min", 0);//Random prestige class if 
available, normal class chosen if HD/Level is above 24 [u][i][b](source code is 15)[/b][/i][/u][i][/i]
          SetLocalInt(oObject, "nclass1Max", 24);// Max level of primary class
          SetLocalInt(oObject, "nclass2Max", 20);// Max level of secondary class
          SetLocalInt(oObject, "nclass3Max", 16);// Max level of prestige/normal class, provided prestige was available
          SetLocalInt(oObject, "nclass1Prob", 34);//34% probability to level in primary class
          SetLocalInt(oObject, "nclass2Prob", 33);//33% probability to level in alternate class
          SetLocalInt(oObject, "nLevelMax", nHD);//Level max is based on the character who hired them
          while(nHD > 0) // main level loop start
           {
            LevelUp(OBJECT_SELF); //Main level up function
            nHD = nHD-1; //Sets the henchman 1 level below the player, results in Error: "Too Many Instructions" if altered
            break; //Required to prevent "Error: Too Many Instructions"
           }
       }
      ForceRest(OBJECT_SELF); //Causes the Henchman to "instant rest" thus giiving all abilities/spells per day at the ready
      SetLocalInt(OBJECT_SELF, "Levelup", 1);//Stop the script from firing again
      return; //Exit the main script this is held in, namely as part of the onheartbeat so it can restart it's function checks
    }

And last but not least, that for just regular NPC's, also put on the ONHeartBeat script:

// Level up script for the NPC's
    // This only works on Henchman of Level 1
    // This level up script fires only once.
    int iLevel = GetLocalInt(OBJECT_SELF, "Levelup");//Int that stops the script from fireing more then once
    object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);//The Player
    if(GetIsObjectValid(oPC) && (iLevel==0))//Check that the player is a valid player and that the int is a certain number
      {
       if(GetHitDice(OBJECT_SELF) < GetHitDice(oPC))//HD of the NPC compared to master/player
         {
          object oObject = OBJECT_SELF;
          int nHD = GetHitDice(oPC) - GetHitDice(OBJECT_SELF);//HD of master/player compared to NPC
          SetLocalInt(oObject, "nclass1Min", 1);//class minimum for primary class
          SetLocalInt(oObject, "nclass2Min", 0);//Random non-Prestige class.
          SetLocalInt(oObject, "nclass3Min", 0);//Random prestige class if available, normal class chosen if HD/Level is above 24 [u][i][b](source code is 15)[/b][/i][/u][i][/i]
          SetLocalInt(oObject, "nclass1Max", 24);// Max level of primary class
          SetLocalInt(oObject, "nclass2Max", 20);// Max level of secondary class
          SetLocalInt(oObject, "nclass3Max", 16);// Max level of prestige/normal class, provided prestige was available
          SetLocalInt(oObject, "nclass1Prob", 34);//34% probability to level in primary class
          SetLocalInt(oObject, "nclass2Prob", 33);//33% probability to level in alternate class
          SetLocalInt(oObject, "nLevelMax", nHD);//Level max is based on the character who spawned them
          while(nHD > 0) // main level loop start
           {
            LevelUp(OBJECT_SELF); //Main level up function
            nHD = nHD-1; //Sets the henchman 1 level below the player, results in Error: "Too Many Instructions" if altered
            break; //Required to prevent "Error: Too Many Instructions"
           }
       }
      ForceRest(OBJECT_SELF); //Causes the Henchman to "instant rest" thus giiving all abilities/spells per day at the ready
      SetLocalInt(OBJECT_SELF, "Levelup", 1);//Stop the script from firing again
      return; //Exit the main script this is held in, namely as part of the onheartbeat so it can restart it's function checks
    }


Simply put this is one of the easiest ways to get randomly generated henchman
and npc's that ive run across (and modified) provided they are using a
level 1 monster. Even if the monster isnt and can't level up, it only
fires once, so you wont get any problems because it fires constantly. I
take no credit for the include file above, I simply took a page from
420's above script and made it my own for the scripts that i use for the onheartbeat .

Only bad thing, is that there is no de-level script, if you want them to reset because they have been
fired, and become available to other players, they will stay at their
max level and wont go down. They can go up however, provided the fire
script resets the local int.

Hope this helps everyone, enjoy.
 

Modifié par Xovian, 09 février 2011 - 12:28 .


#17
Omega27

Omega27
  • Members
  • 198 messages
Im sorry to barge in on this topic. I my self am having a little issue with my Henchmen.

Just about everything works fine, it also comes down to leveling up.

I have 5 henchmen each using the "multiple henchmen erf"

Using the (set_xp2_henchmen) scripts



[ResRefs]

OnBlocked=x0_ch_hen_block

OnDamaged=x0_ch_hen_damage

OnDeath=x2_hen_death

OnConversation=x0_ch_hen_conv

OnDisturbed=x0_ch_hen_distrb

OnCombatRoundEnd=x0_ch_hen_combat

OnHeartbeat=x0_ch_hen_heart

OnPhysicalAttacked=x0_ch_hen_attack

OnPerception=x0_ch_hen_percep

OnRested=x0_ch_hen_rest

OnSpawn=x0_ch_hen_spawn

OnSpellCast=x2_hen_spell

OnUserDefined=x0_ch_hen_usrdef



I want to know why? or how i can get rid of:

When they level up i end up with copies of them.

I want remove that and im not sure how

#18
Xovian

Xovian
  • Members
  • 87 messages

I want to know why? or how i can get rid of:
When they level up i end up with copies of them.
I want remove that and im not sure how


Are you using a dialog conversation for this event?

With out knowing the actual scripts used to level the henchman up (as there are so many), I'd have to see the code from "multiple henchmen erf", as I am not familiar with where you likely got that erf from.

Modifié par Xovian, 14 février 2011 - 12:48 .


#19
Omega27

Omega27
  • Members
  • 198 messages
Yes i have all hench under conversation control. and umm not to sure on how to get the multiple hench pack in copy/paste format