Jump to content

Mod bugs/question about how Mechanics *works*


Recommended Posts

I made a mod to increase the level cap. Two versions, both at this page: https://www.nexusmods.com/pillarsofeternity2/mods/266

From testing the "getting xp past level 20" part seems to be working, but there are some issues that I was hoping I could get some help with.

 

One user said they were unable to unlock containers and doors they met the Mechanics score for in Forgotten Sanctum, and I've observed this myself as well- the combat log says "unlocked" as normal but it doesn't actually unlock. You can try unlocking it again, and it just says "unlocked" again, over and over. I've also observed that I'm not getting xp for disabling traps, specifically in Forgotten Sanctum- using below level 20 characters as well. Someone else said they were getting hugely inflated xp for traps in the starting area cave- something like 500xp when it should be 40xp.

 

I'm hoping to try and fix these issues since it's my mod causing them, but I don't know exactly what's going wrong or what goes on under the hood- if it's an engine thing it might be unfixable.

 

So I guess I have three questions, with the unspoken fourth question of "can I fix any of this?" any insight would be appreciated:

 

1: what would cause a character who is not at the level cap to not get xp for disabling a trap? Or to get more xp than they should?

 

2: what would cause a lock to not be opened by a character who meets the skill requirement but report in the combat log that it has been opened?

 

3: why would an issue with traps and locks occur specifically in the Forgotten Sanctum area?

Link to comment
Share on other sites

There is a level scaling for trap difficulty and a check for xp in the games code

 

 

public int Level
{
get
{
CharacterProgression.LevelScalingType levelScaleType = CharacterProgression.GetLevelScaleType();
if (this.m_ownerStats != null || levelScaleType == CharacterProgression.LevelScalingType.None)
{
return this.TrapLevel;
}
int num = 0;
int expectedPlayerLevel = (!GameState.Instance.CurrentMap.IsRandomEncounterMap) ? GameState.Instance.CurrentMap.ExpectedPlayerLevel : SingletonBehavior.Instance.ActiveEncounter.EncounterLevel;
if (levelScaleType != CharacterProgression.LevelScalingType.CritPath)
{
if (levelScaleType == CharacterProgression.LevelScalingType.SideContent)
{
num = GlobalGameSettingsGameData.Instance.CombatSettingsComponent.GetSideContentLevelAdjustmentBasedOnPlayerLevel(GameState.Instance.CachedPlayerLevel, expectedPlayerLevel);
}
}
else
{
num = GlobalGameSettingsGameData.Instance.CombatSettingsComponent.GetLevelAdjustmentBasedOnPlayerLevel(GameState.Instance.CachedPlayerLevel, expectedPlayerLevel);
}
int levelAdjustmentBasedOnPartySize = GlobalGameSettingsGameData.Instance.CombatSettingsComponent.GetLevelAdjustmentBasedOnPartySize(SingletonBehavior.Instance.GetNumPartyMembers(), GameState.Instance.CurrentMap.ExpectedPartySize);
if (GameState.Instance.LevelScaleUpOnly)
{
return Mathf.Clamp(this.TrapLevel, this.TrapLevel, this.TrapLevel + num + levelAdjustmentBasedOnPartySize);
}
return this.TrapLevel + num + levelAdjustmentBasedOnPartySize;
}
}

 

 

        private int GetAndIncrementTrapLockExperience(int difficulty, bool disarmTrap, bool pickLock)
        {
            if (difficulty == 0 || difficulty >= 20)
            {
                return 0;
            }
            if (this.mTrapLockXPPool[difficulty - 1] >= 10)
            {
                return 0;
            }
            float num = ExperienceTable.GameData.TrapLockXPMultiplier;
            if (num == 0f)
            {
                num = 1f;
            }
            float num2 = (float)ExperienceTable.GameData.ExperienceReference[difficulty - 1].TrapLockExperiencePool * num;
            float num3 = num2 / 10f * 5f / (float)SingletonBehavior<PartyManager>.Instance.GetNumPartyMembers();
            if (pickLock)
            {
                num3 += (float)ExperienceTable.GameData.PickLockExperienceModifier;
            }
            if (disarmTrap)
            {
                num3 += (float)ExperienceTable.GameData.DisarmTrapExperienceModifier;
            }
            int result = (int)Mathf.Round(num3);
            this.mTrapLockXPPool[difficulty - 1]++;
            return result;

 

I think the first if clause is the problem. It states if (difficulty == 0 || difficulty >= 20). For levels beyond 20, difficulty can get out of bounds and return 0.

 

I have no idea if it can be changed with gamedatabundles.

Edited by Fhav6X
Link to comment
Share on other sites

That code looks a bit janky to me, there's definitely a bug in there where it won't award XP for level 20 traps (though I didn't see any of those in a quick look through the DLC levels).

 

With the doors not unlocking, it sounds like there's some kind of exception being thrown. If it is an exception and you can acquire an output_log from after seeing the issue, it should be relatively easy to fix and I can take a look at it.

Link to comment
Share on other sites

output_log.txtThank you BMac! Code is all Greek to me, but the output log does show six instances of "IndexOutOfRangeException: Array index is out of range." which would match the five times I tried to lockpick a container and one time I disarmed a trap (output log attached)

 

May be worth noting: I have a bunch of mods active but the person who told me about this issue originally said my mod which caused the issue was the only one they had

Edited by house2fly
Link to comment
Share on other sites

I think the IndexOutOfRange is because when overriding the ExperienceReference array on the ExperienceTable object, you've left out the entries for levels 1-19.  While there is a field for "Level" in those entries, it's just for readability - the code actually ignores it entirely and uses the index of the element in the array. So with your mod installed, it thinks the experience table only supports levels 1-14 (remember that overriding an array replaces the entire array with the new one - it's not ordinarily possible to simply append more items to an existing array; you have to duplicate the whole thing, unfortunately).

 

This probably explains why you see the problem more often in the Forgotten Sanctum as it's a high-level area that has a higher concentration of traps that are greater than level 14.

 

Secondly, the Levels in the ExperienceTable don't actually correspond to character levels, but actually to the difficulty levels that are set on individual quests, traps, and encounters. So unless your mod is changing some of those, I don't think you need to override that object at all, as there are none in the game that are set to higher than level 20.

Link to comment
Share on other sites

I deleted the entire ExperienceTable object and loaded up the same area. Container now unlocks beautifully and the trap gives xp. Wonderful!

 

So just so I understand: the engine supports level progression past 20 and "MaxCharacterLevel" is just setting where that progression ends? After deleting the experiencetable my level 22 character is still 22 so it looks that way.

 

Are other aspects of levelling the same? Would a character still gain a power level every 3 levels and proficiency every however many levels with no change except to MaxCharacterLevel?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...