Companion reseting on level-up

Hi all,

I got this problem that was reported to me and then recreated in my own game. Somehow I had never noticed before I release the campaign :smiley: .

Two companions (wizard, sorcerer) reset their spells and feats on level up. For example, sorcerer reaches a level where she can pick up fireball. You pick it, and next time she levels up fireball is replaced by another spell. I can’t think of any reason that this happens so any help would be much appreciated.

If it helps, when met, they both have scripts to set their package to the desired one (necromancer for example). Perhaps that’s where the problem lies? Why would setting a package be called again on level up? Or is there a column on the packages.2da that I missed?

“Why would setting a package be called again on level up?”

Would the package get checked on level up to know what needs to be selected for the next level when levelling up?

Wouldn’t that mean that the package is checked on every class level up… regardless if it is a custom/manually selected package or a default?

I also have a cleric with a custom package but he doesn’t reset.

If it helps, here is the code that runs when the companion in question gets accepted.

//Sets the package of Jarfed to Necromancer.

void main()
{
object oJarfed = GetObjectFromRosterName(“jarfed”);

int nXP = GetFactionAverageXP(GetFirstPC());

SetLevelUpPackage(oJarfed, 33);
ResetCreatureLevelForXP(oJarfed, nXP, TRUE);

}

The other companion does not have a specified package. It would seem the game decides to reset the spellcasters(wizard, sorcerer) when they level up. Since the other companion doesn’t have a specified package, I am not sure that this is where the problem lies.

Hi,

If the PC in question is already in the party, then you do not need to keep resetting their level for XP.

If, however, this is the first time they are accepted, and you want to ensure the XP is a certain amount, then simply use SetXP instead.

Otherwise, I believe you are effectively resetting a PC as if rebuilding them from scratch each time you call this function. I had a similar problem when a player built a PC, imported them into the game, and then had the spells reset when this function was called. Bottom line, use SetXP instead if you do not want to lower levels.

I think that sounds like your issue.

Lance.

Here is something from my own module:-

int AvePCXP = GetFactionAverageXP(oPC);
int iOwnXP = GetXP(OBJECT_SELF);

if(iOwnXP < AvePCXP)
{
// FIRST TIME ADDITION ONLY
if(GIVEGOLD == 1){ResetCreatureLevelForXP(OBJECT_SELF, AvePCXP, TRUE); ForceRest(OBJECT_SELF);}

  // FUTURE REJOINS (XP ONLY - LET PLAYER LEVEL)
  else if(GetTotalLevels(OBJECT_SELF, FALSE) < GetTotalLevels(oPC, FALSE))
  {	
  	// USE AVERAGE XP TO AVOID 2DA CHECK
  	SetXP(OBJECT_SELF, AvePCXP);		
  }

}

1 Like

Hi Lance, thanks for the info. However I am not certain how it is relevant. The script I posted above only gets called once, when the companion is accepted in the party. Any other time the companion is picked to join the party, and if said companion is a lower level, setting (I think this is where it is) a campaign option to true, they will level up to match the main PC.

I guess it would be interesing to know which function is called in the background if we choose to set the campaign option for companions to be the same level as the first PC. Sorry I don’t remember how the preference is called, and I don’t want to open the campaign editor because it will mess up the party size again :slight_smile: .

Hi Andy,

No problem … hopefully we can get to the bottom of your issue for you. :slight_smile:

The problem when you call that script you write (even just the once), it will reset their spells that were on them at the time. Now, that should not be a problem if the player has only just added them, as they had no idea what spells they had originally.

However, I am curious as to what script is being fired after they have been added and are in the party, and the player then levels the PC. i.e. At that stage, the above script you say you use to “add” the companions should NOT be being called if doing so compromises what you already allocated.

And, if you (as the builder at build time) are setting the spells, and are then trying to re-level the companion after the player asks them to join for the first time (which is what it sounds like to me), then I do not think you can use this function like that as it appears to have its own agenda as to what spells to rebuild the companion with and will overwrite any you have pre-selected. That is why I was recommending using SetXP (after comparing with the player) to reset the companion XP and just let the player level the companion manually after that.

That said, it may well be that you can edit the packages.2da (and cross referenced related package - PackSPWiz8) for that companion, to ensure a particular set of spells are learned. Although, I do not know how the engine chooses which spells from that 2da just looking at it. :worried:

So, first questions I wanted to ask/clarify with you: Did you give the companion the fireball spell prior to calling the function? And is it this selection that has “gone” after running the reset function during companion add?

Cheers, Lance.

EDIT: Another quick thought: Have you tried adding a very brief delay between them? ~ 0.1 sec

EDIT 2: I also read this in the function description, “The creature to which you want to set the Level-Up package. Player OWNED creatures are not valid for this function” So, bear that in mind.

Hi Lance,

I noticed that I use the 4 recommended scripts.

ga_roster_add_object
ga_roster_selectable
ga_roster_party_add
ga_reset_level

I use the same 4 scripts on all companions, however only the 2 behave weirdly.

Further to your questions. I do set the spells for the companion in its blueprint. The idea was that, the player meets one at, let’s say, level 4. There are some preselected spells for that level. Then, when the companion gets to level 5 they reset. Note, they don’t reset on level up automatically, but only when we tell them to leave and rejoin.

The fireball spell was not given in the blueprint. It was given on a level up. Then companion left, repicked, and fireball was gone.

As for edit 2, I set the package before the joining. Like one node 1 of meeting with them.

At this moment, I am thinking that it has to do with the 4 scripts above. Perhaps I read it wrong (like 8 years ago) that they have to be used in order to add a companion. I am not certain that they are to be used on an already added to roster companion… Perhaps after the initial meet and join, one needs only the ga_roster_party_add, and then the campaign setting which syncs the levels take care of the XP functionality.

edit: It still doesn’t make sense that other spellcasters don’t reset, but hey… not the first time the toolset amazes me.

Andy, I think I found out out why the 2 companions in question are having the issue you mentioned.

In the nilee.dlg and the jarfed.dlg they each have only the one node where they can join the party and they are set to “always”. These nodes are using the following scripts as mentioned in your earlier post:

ga_roster_add_object
ga_roster_selectable
ga_roster_party_add
ga_reset_level

Because those nodes are set to “always” the ga_reset_level script will be executed every time the companion joins/rejoins the party. That script should only need to be fired once. The reset effects spells, skills, feats, and ability scores. So if you level-up the companion giving the character new spells, skill, feats, or ability scores, and then remove/rejoin later on, the changes made to the companion will be reset to the package defaults for the particular level. Thus, any earlier changes you made to the companion will be erased.

To fix this issue, set those join nodes to “once only”. Then create a second node that’s almost the same as the first, except this time set it to “always” and only use the ga_roster_party_add script. The other scripts no longer need to to be fired again as they just need to be executed once.

1 Like

I hear you! :slight_smile:

The only thing I can think is that the “package” being applied simply does not cater for fireball within it at the point/level you currently have it for the companion.

OK, here’s a thought … I just want to know if this is possible, as it’s the way mine work, and I don’t see why you do it as you do (looking for a reason why not) …

This also depends on how you are defining “companion”, as when I say “companion”, I mean a PC that the player controls completely as opposed to a “henchman”, which may tag along with the players PC and companions (in the party portraits as such), but NOT be available to possess. If you are trying to run a “companion” like a “henchman”, by trying to bypass which spells the player can add to the companion at their level up, then I am not sure you can do this due to the way the functions work. And here is my point … If the “companion” is able to be possessed (i.e. a real companion), then why not simply let the player level up the companion when it’s due? i.e. Why “reset” them at all?

And here is my other point about avoiding the “reset” function (due to the problems you describe), if the companion leaves the party for a while and rejoins … or as you say it, “ask them to leave and rejoin”, you should NOT be recalling the “reset” function when doing so. i.e. The “reset” function should only ever be called at the initial meeting/joining. Leave and rejoins, thereafter, should simply add the difference in XP to keep them up to date, and the player should/must level the rejoined companion manually … or else the “reset” will change things to the standard it wants.

Bottom line, any leaves and rejoins of the companion “after” its initial adding should only ever add the missing XP to make them the same level as the rest of the party, which the player then manually levels - but can simply use the “recommend” button to makes things go quicker. Use SetXP as per my example to manage this. :slight_smile:

Sorry about the long post, just trying to be clear in my reasoning and explanations.
Cheers, Lance.

The two companions have a different convo when you first meet them. Nilee at the academy and jarfed at the auction. So I don’t think I need the once only, as long as the 4 scripts are called in the meeting convos. Then, I leave nilee.dlg and jarfed.dlg as they are, but remove the resetting scripts

I think the reason it only happens to these two, is because every one else uses a custom script which summarizes the 4. But in this custom script I check if a companion has already been met before resetting (or not) the level.

@Lance_Botelle I think travus and you are saying the same thing. Thanks. Should be solved now. And yes, companion is a PC not a hemchman in my book :slightly_smiling_face:

1 Like

Great! :rabbit:

Just to close this subject, my custom script which sums up the 4 required scripts to add a companion for the first time looks like that.

void AddCompanionToParty(string sCompanionTag)
{
/////////////////////////////////////////////////////
// Make the companion visible on the Roster GUI
/////////////////////////////////////////////////////
SetIsRosterMemberCampaignNPC(sCompanionTag, 0);
/////////////////////////////////////////////////////
// Make the companion selectable on the Roster GUI
// FROM: ga_roster_selectable
/////////////////////////////////////////////////////
SetIsRosterMemberSelectable(sCompanionTag, 1);
/////////////////////////////////////////////////////
// Add the companion to the party
//FROM: ga_roster_party_add
/////////////////////////////////////////////////////
object oPC = GetFirstPC();
AddRosterMemberToParty(sCompanionTag, oPC);
/////////////////////////////////////////////////////
// Just in case we forgot to set this, when we add a
// companion to our party, we’ve met them.
/////////////////////////////////////////////////////
SetGlobalInt(“met_” + sCompanionTag, TRUE);
/////////////////////////////////////////////////////
// Set the companion’s XP equal to that of the PC
/////////////////////////////////////////////////////
object oCompanion = GetObjectByTag(sCompanionTag);
int nXP = GetPCAverageXP();
SetXP(oCompanion, nXP);
ForceRest(oCompanion);
}

As you see, here I called SetXP instead of resetting the level. Further investigation showed that they only companions using the reset level method are the two who had the problem. That is why all else didn’t vehave like that. Case closed.

3 Likes