Aller au contenu

Photo

Preventing follower auto-level on recruit


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

#1
sea-

sea-
  • Members
  • 264 messages
I'm wondering if anyone knows how to prevent party followers from being auto-leveled when they are added to the party, so that they will be at level 1 and will have any extra attribute, talent, skill and spell points available for spending as the player wishes.

The current behavior scales the follower to the player's level, and any points available are spent according to the follower's AI package.

Example script here:

                object oFollower = GetObjectByTag("virgil");

                WR_SetPlotFlag(PLT_PARTY_STATUS, VIRGIL_IN_PARTY, TRUE);

                SetImmortal(oFollower, FALSE);
                SetTeamId(oFollower, -1);
                WR_SetObjectActive(oFollower, TRUE);  
                WR_SetFollowerState(oFollower, FOLLOWER_STATE_LOCKEDACTIVE); 
                SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);
                SetFollowerApprovalEnabled(oFollower, TRUE);
                SetAutoLevelUp(oFollower, 0);

                command cJump = CommandJumpToObject(GetPartyLeader());
                WR_AddCommand(oFollower, cJump);

                DoAutoSave();

I know that other mods have been released that do this, but I have not found any publicly available knowledge of how this is accomplished.

#2
MerAnne

MerAnne
  • Members
  • 1 157 messages
When creating/recruiting, do NOT have AL_DoAutoLevelUp() in your script. It worked for me to remove that line when I was testing. Not using that line (or any of the AL_Spendxxx) should cause the party member to be created without spending attribute points.

I'm not seeing some of the code that I would expect to see when recruiting a new follower so I'm not sure why/where the leveling is being set.

#3
sea-

sea-
  • Members
  • 264 messages

MerAnne wrote...


When creating/recruiting, do NOT have AL_DoAutoLevelUp() in your script. It worked for me to remove that line when I was testing. Not using that line (or any of the AL_Spendxxx) should cause the party member to be created without spending attribute points.

I'm not seeing some of the code that I would expect to see when recruiting a new follower so I'm not sure why/where the leveling is being set.

Thanks.  Could it be in WR_SetFollowerState or maybe in the party member added event in another script, like module_core or player_core?  The thing is, my follower hire script works just fine, except for the auto-leveling thing, I don't want to mess too much with something that works.

Modifié par sea-, 14 juin 2013 - 03:08 .


#4
MerAnne

MerAnne
  • Members
  • 1 157 messages
Unlikely (to FollowerState, module_core, and player_core). When do you actually create the follower? I see where you identify the existing follower:
object oFollower = GetObjectByTag("virgil");

but that doesn't create the race, class, level, etc for the follower The code in the original example looks very similar to the script that I use to add an existing follower to the PC's party. The initial creation of the follower is where (my) scripts that control leveling are located

#5
sea-

sea-
  • Members
  • 264 messages

MerAnne wrote...

Unlikely (to FollowerState, module_core, and player_core). When do you actually create the follower? I see where you identify the existing follower:
object oFollower = GetObjectByTag("virgil");

but that doesn't create the race, class, level, etc for the follower The code in the original example looks very similar to the script that I use to add an existing follower to the PC's party. The initial creation of the follower is where (my) scripts that control leveling are located

The follower is a pre-created creature that is placed in the level.

#6
MerAnne

MerAnne
  • Members
  • 1 157 messages
The 'standard' party member creation is here:
http://social.biowar...llower_tutorial
It allows you to set what the initial talents, skills, attribute points, etc are going to be for the NPC.

http://social.biowar...ining_The_Party
Shows how to create a NPC that isn't leveled up to the level that you want.

and
http://social.biowar..._in_Camp_Script

I used these tutorials when creating my NPCs and customized them for my own use.

You say "the thing is, my follower hire script works just fine, except for the auto-leveling thing, I don't want to mess too much with something that works." The only answers that I can provide involve making changes to your existing hiring script so maybe the tutorials can help you.

#7
Karma

Karma
  • Members
  • 391 messages
To be clear, do you want the follower to be at level one or do you want the follower to be at the same level as the player but with the correct number of points to spend? In my testing, if the follower is at level 1, then s/he has no points to spend. Level, from what I can tell, determines available points. So I'm guessing you mean that you want the follower to have the same level as the player but the player can decide for themselves how to distribute the points of the follower.

If I remember correctly, the function RW_CatchUpToPlayer() sets the XP of the follower to match that of the player (or at least enough to be one level behind the player). You *may* have to add that line in there. Maybe.

MerAnne suggested removing the SetAutoLevelUp() function (although it looks like you've set it not to autolevel, so in theory it shouldn't be autoleveling). Do you have a package selected in your creature file? If so, make sure that it is set to "none."

If all else fails, you could "cancel out" the autolevel by removing all skills/talents/spells (except the starting ones), setting available attribute points to 0, and re-adding the proper number of points after the autolevel is complete.

#8
Karma

Karma
  • Members
  • 391 messages
I found this in the definition of the AL_DoAutoLevelUp() function:

void AL_DoAutoLevelUp(object oChar, int bInitial = FALSE, int bChargenDefault = FALSE)
{
int nTable = _GetTableToUseForAL(oChar);

AL_SpendAttributePoints(oChar, nTable, bChargenDefault);
AL_SpendSkillPoints(oChar, nTable, bInitial);
AL_SpendSpecializationPoints(oChar, nTable);
AL_SpendTalentSpellPoints(oChar, nTable, bInitial);

// -------------------------------------------------------------------------
// Update various UIs
// -------------------------------------------------------------------------
Chargen_SetNumTactics(oChar);
SetCanLevelUp(oChar,Chargen_HasPointsToSpend(oChar));
}

Notice that bInitial is only taken into account for skill points and talent points. So setting it not to autolevel appears to only partially work. You may want to check out the script sys_autolevelup_h just to see how the autolevelup process works.

#9
MerAnne

MerAnne
  • Members
  • 1 157 messages
If I remember correctly
SetAutoLevelUp(oFollower, 0);
determines whether the NPC will continue to level up after being recruited. sea- should look into it as a possibility, but I'm not sure that it is the solution.

SetAutoLevelUp(oFollower, 0); was the code that causing the problem I was having with leveling to be done automatically after the NPC was recruited. That was using 2 rather than 0 as a parameter though. This link has more information on that particular statement: http://social.biowar...llower_tutorial

#10
sea-

sea-
  • Members
  • 264 messages
Thanks very much for your replies.

satans_karma wrote...

To be clear, do you want the follower to be at level one or do you want the follower to be at the same level as the player but with the correct number of points to spend? In my testing, if the follower is at level 1, then s/he has no points to spend. Level, from what I can tell, determines available points. So I'm guessing you mean that you want the follower to have the same level as the player but the player can decide for themselves how to distribute the points of the follower.

Yep, that's it.

satans_karma wrote...

MerAnne suggested removing the SetAutoLevelUp() function (although it looks like you've set it not to autolevel, so in theory it shouldn't be autoleveling). Do you have a package selected in your creature file? If so, make sure that it is set to "none."

They do have packages; removing the package does not work.  In fact, it just means they start wih the default Warrior class.

SetAutoLevelUp only should be changing the auto-level status of the follower, it shouldn't do any leveling itself.

Tried experimenting with solutions, including using the CatchUp function to level a newly-created follower instead of the one placed in the level.  But even then, all the points were auto-assigned.  My guess the problem has to do with WR_SetFollowerState.  I tried various combinations of parameters to pass it but none of them achieved my desired result.

Modifié par sea-, 19 juin 2013 - 03:19 .


#11
MerAnne

MerAnne
  • Members
  • 1 157 messages

sea- wrote...

satans_karma wrote...

MerAnne suggested removing the SetAutoLevelUp() function (although it looks like you've set it not to autolevel, so in theory it shouldn't be autoleveling). Do you have a package selected in your creature file? If so, make sure that it is set to "none."

They do have packages; removing the package does not work.  In fact, it just means they start wih the default Warrior class.

SetAutoLevelUp only should be changing the auto-level status of the follower, it shouldn't do any leveling itself.

Tried experimenting with solutions, including using the CatchUp function to level a newly-created follower instead of the one placed in the level.  But even then, all the points were auto-assigned.  My guess the problem has to do with WR_SetFollowerState.  I tried various combinations of parameters to pass it but none of them achieved my desired result.


Actually, I suggested removing AL_DoAutoLevelUp() or the functions that it contains.  But that is the problem  I don't see anything in the orignal example script that is calling the level up functionality that would assign the attribute, skill, and spell/talent points. 

sea- wrote...
The follower is a pre-created creature that is placed in the level.

I suspect it is in the 'pre-created' is causing the creature to level up before it is actually recruited.

#12
sea-

sea-
  • Members
  • 264 messages

MerAnne wrote...

I suspect it is in the 'pre-created' is causing the creature to level up before it is actually recruited.

I tried switching them for dynamically-created followers and it didn't help at all

Modifié par sea-, 23 juin 2013 - 11:37 .


#13
MerAnne

MerAnne
  • Members
  • 1 157 messages
http://social.biowar...unction_Include
Try that link.

I don't know what to tell you, your hiring script looks nothing like the ones that I use and I used the information that I got from the 3 links that I gave you previously. I grant that there are probably some lines of script that I don't need, but everything that I use to control leveling is not included in your script

#14
sea-

sea-
  • Members
  • 264 messages
I tried creating the follower "from scratch" as described in those tutorials but I was unable to find a way to make it work. I could get "almost there" but for some reason my followers were not showing up in the party picker despite my 2DAs all being correct as far as I could tell. I haven't used the party picker in quite a while and I'm not sure that I need to. There's no reason to have it because my followers stay in the player's party until the end of the game. That's why it's so simple.

I wonder if part of the problem is in the event that's fired when a party member is added. Maybe I need to override that for it to function correctly.

Still, I have no need for special follower hiring code, for special level up tables or anything like that.  And in fact, the same functionality could be accomplished by using a respec option.  I'm wondering if it's even possible to add that code to my mod, but given how complicated it is I doubt there is an "easy" way of doing it.

Modifié par sea-, 23 juin 2013 - 11:40 .


#15
MerAnne

MerAnne
  • Members
  • 1 157 messages
I can easily do what you originally want to do based on the tutorials. I could EASILY create them with points unassigned.

If you aren't assigning attribute, skill, and talent points, then you don't need the special level up tables, but to reach your original goal you are going to have to use some of the additional code in those tutorials. Or continue with what you have

#16
sea-

sea-
  • Members
  • 264 messages

MerAnne wrote...

I can easily do what you originally want to do based on the tutorials. I could EASILY create them with points unassigned.

If you aren't assigning attribute, skill, and talent points, then you don't need the special level up tables, but to reach your original goal you are going to have to use some of the additional code in those tutorials. Or continue with what you have

It's easy when you know how to do it.  :lol:

#17
MerAnne

MerAnne
  • Members
  • 1 157 messages
LOL. No, it was REALLY easy when it wasn't what I wanted to do! It was assigning the attribute, skill, and talent/spell points the way that I wanted them assigned that was a problem.

You had two conditions that you wanted:
1) Create NPC at 'correct' level without any of the points assigned.
2) "don't want to mess too much with something that works"

I don't know how to meet the second condition, but the 3 links that I gave you have all of the information that I used to create my own hiring scripts. No, it wasn't easy the first time, but since you don't need the level up tables it is easier.

#18
sea-

sea-
  • Members
  • 264 messages
1) As I've said, even creating the characters as new objects in the level auto-scales them, probably because WR_SetFollowerState is calling an auto-level function indirectly. I tried following the tutorials and ultimately I couldn't get them working - although this could be because of an issue with the party picker and not the follower creation itself.

2) My existing follower hiring script is not "perfect" but at the least it does not introduce any more bugs or issues. That's my concern here - I don't want to break something that already works. The only real downside of my existing follower hiring code is that there is less replayability because they can't have their skills fully specced from the start.

#19
sea-

sea-
  • Members
  • 264 messages
Here's currently what I have based on reading the follower hire code executed in player_core and the tutorials above:

case VIRGIL_JOINS:
{
object oOldFollower = GetObjectByTag("virgil");
object oFollower = CreateObject(OBJECT_TYPE_CREATURE, R"virgil.utc", GetLocation(oPC));

int nClass = CLASS_WIZARD;
int nRace = RACE_HUMAN;
int nGender = GENDER_MALE;

//update plot flag
WR_SetPlotFlag(PLT_PARTY_STATUS, VIRGIL_IN_PARTY, TRUE);

//remove old follower
SetObjectActive(oOldFollower, FALSE);
Safe_Destroy_Object(oOldFollower);

//reset character to defaults
InitFollower_Thirst(oFollower);

//init character
//Chargen_InitializeCharacter(oFollower);
Chargen_SelectRace(oFollower, nRace);
CharGen_ClearAbilityList(oFollower, 1);
Chargen_SelectCoreClass(oFollower, nClass);
Chargen_SetNumTactics(oFollower);
Chargen_EnableTacticsPresets(oFollower);

//Set player rank
SetCreatureRank(oFollower, CREATURE_RANK_PLAYER);

if(IsPartyPerceivingHostiles(oFollower) & GetCombatState(oFollower) == FALSE)
{
SetCombatState(oFollower, TRUE);
}

//remove stationary flag, allow level up
SetLocalInt(oFollower, FOLLOWER_SCALED, 1);
SetLocalInt(oFollower, AI_FLAG_STATIONARY, 0);
SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);
SetLocalInt(oFollower, AMBIENT_SYSTEM_STATE, 0);

//level scaling (DO NOT SPEND POINTS)
int nPackage = GetPackage(oFollower);
int nTargetLevel;

int nPlayerLevel = GetLevel(oPC);
if(nPlayerLevel >= 13 || nPlayerLevel == 1 )
{
nTargetLevel = nPlayerLevel;
}
else
{
nTargetLevel = nPlayerLevel + 1;
}

int nMinLevel = GetM2DAInt(TABLE_PACKAGES, "MinLevel", nPackage);

if(nMinLevel > 0 && nMinLevel > nTargetLevel)
{
nTargetLevel = nMinLevel;
}

//xp until hero level
int nXp = RW_GetXPNeededForLevel(Max(nTargetLevel, 1));
RewardXP(oFollower, nXp, TRUE, FALSE);

//add specialization
float count=1.0;
if(GetLevel(GetHero())>=7)
{
SetCreatureProperty(oFollower, 38, count); // 38 is the spec point ID
count=count+1.;
}
if(GetLevel(GetHero())>=14)
{
SetCreatureProperty(oFollower, 38, count); // 38 is the spec point ID
}

//clear any unwanted conditions on the follower
SetImmortal(oFollower, FALSE);
SetPlot(oFollower, FALSE);
SetObjectInteractive(oFollower, TRUE);
SetObjectActive(oFollower, TRUE);
SetTeamId(oFollower, -1);

//init follower settings
InitHeartbeat(oFollower, CONFIG_CONSTANT_HEARTBEAT_RATE);
SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);
SendPartyMemberHiredEvent(oFollower, FALSE);
SetFollowerApprovalEnabled(oFollower, TRUE);

//RW_CatchUpToPlayer(oFollower);

SetFollowerState(oFollower, FOLLOWER_STATE_LOCKEDACTIVE);

break;
}
}

Unfortunately this results in a follower who, while having class, race and gender selected correctly, has 1 HP, 0 mana/stamina and no available points to spend, no selected abilities or spells, etc. Although, the follower DOES receive one talent, possibly the default one when the class is selected.  Replacing the player_core "XP calculation script" with RW_CatchUpToPlayer doesn't help.

Any thoughts?

EDIT: Upon further testing I notice the following:

- The follower actually has all the "default" points to level up, same as what you get on character creation
- The follower does NOT get any racial/class benefits, so starting attributes are very low (i.e. 9 magic for a mage)

I feel like I'm quite close now, but the auto-leveling still isn't working for some reason.

EDIT 2: Success!  I had to run the extra level-up stuff after the follower is added to the party, not before.  With all that done they are receiving class/race benefits properly and also get their level-up added correctly.  Awesome.  Thanks for all the help guys!

Modifié par sea-, 24 juin 2013 - 05:08 .


#20
MerAnne

MerAnne
  • Members
  • 1 157 messages
Well done! It isn't the small change that you wanted, but if it works, that is what counts.

There are a few lines that I recognize as unneeded, but you can clean those up later if you like. Because this version works :-)

#21
sea-

sea-
  • Members
  • 264 messages

MerAnne wrote...

There are a few lines that I recognize as unneeded, but you can clean those up later if you like. Because this version works :-)

Any idea what is unnecessary?  I know that some stuff like setting the team, immortal, plot etc. may be redundant but it's "just in case" stuff.

#22
MerAnne

MerAnne
  • Members
  • 1 157 messages
I never figured out what 'heartbeat' did and have never used it. Unless you are using SendPartyMemberHiredEvent(oFollower, FALSE); for something, I have never used it. It looks like you are calculating level twice. The second time associated with the package(s) which you aren't using so don't really need.

I've never needed either of the following statements
//Set player rank
SetCreatureRank(oFollower, CREATURE_RANK_PLAYER);

if(IsPartyPerceivingHostiles(oFollower) & GetCombatState(oFollower) == FALSE)
{
SetCombatState(oFollower, TRUE);
}

But maybe you are recruiting in the (possible) middle of combat and need them.

That said, I probably have some redundancies/unneeded code in my hiring script(s), but once I got it to work, I didn't want to make any changes for fear of what I might cause to break!