I just did a round of testing, and the deeper I went the more interesting things got. This may also speak to why GCD doesn't seem to allow your attributes to grow beyond 95, as Galsiah may have been exploiting bugs that have been fixed in OpenMW.
I started my investigation with Fortify and Drain spell effects and noticed that all the bugs seem to have been fixed. The most relevant one being that draining a fortified stat would be permanent, acting more like a Damage effect than a Drain. The only solution was to remove the Fortify effect, Restore the stat, then reapply the Fortify effect. It seems this has been fixed, meaning that modders can safely employ Fortify/Drain effects without worrying about screwing things up in this way.
But they might not even have to do that.
It seems that OpenMW doesn't follow exactly the same implementation of the Get/Mod/SetStat scripting commands that vanilla Morrowind does. This might cause some issues with existing mods (like GCD), but I think it will be an unintentional boon to those looking to make even better mods.
GetStat still works as in vanilla, giving your current stat (base + fortification/drain/damage).
ModStat nominally affects only the base stat, but is still bound to values between 0 and 100. Your current stat can never be less than 0, so if you are under a Drain or Damage effect and you ModStat below 0, it will erase the Drain/Damage effect. If you have a +30 Fortify effect, and you ModStat -200, you'll end up with 0 base and 30 current. Similarly, if you ModStat 200 while under a Damage or Drain of 30pts, you'll end up with 100 base and 70 current. In other words, Fortify effects are always preserved, Drain and Damage effects are preserved when modding up but can be lost when modding down.
We can use this to find a player's base stat. First, GetStat and save that to a variable so we can restore it later. Then ModStat 200 (or any number >100). The player's base stat should now be 100. GetStat and subtract 100. A positive value is the amount of Fortification, a negative value is the amount of Drain/Damage. Add/Subtract this from the player's original stat value to find the base stat, then restore the player's stat with SetStat to that base value.
Although my initial testing indicates that this should work, I'd like to see some more rigorous testing done. It's possible there are some unusual circumstances that might changes things that I haven't accounted for. For example, I've mostly only tested this with Agility (due to convenience on my current save), so it's possible it works differently for other attributes, or that it works differently for skills.
Now, this is all fine and dandy if you want to keep stats between 0 and 100. But what if you want to uncap attributes and skills so they can advance beyond 100? Enter SetStat.
SetStat nominally affects only the base stat, and is not limited. This means we can SetStat to values above 100 or below 0 and Fortify, Drain, and Damage effects will be preserved. Let me repeat that. Fortify, Drain, and Damage effects are always preserved. Your current stat can't be lower than 0, so if you SetStat to a negative value it will display as being at 0 in white (as if Fortified), but if you then SetStat to a positive value this faux Fortify effect is gone.
So now we have an even easier way to find base stats. Save current stat, SetStat 100, GetStat - 100, and you now have the amount of Fortification/Drain/Damage. (Might SetStat to something higher, like 500 or 1000, if you expect stats to go above 100. If they can go above 100, then they should also be able to be drained/damaged by more than 100.)
Putting this all together, we have a very easy way to find a player's base stat, and a way to set a stat to be higher than 100. The only thing missing is a way to allow the player to improve skills normally past 100. For skills, we would either need to cap off the base value below 100 so that players can still improve them normally, and boost them via Fortify effects, or implement skill improvement via scripts, which is probably a lot harder.
- Fortify/Drain bugs are fixed.
- GetStat gets your base stat + Fortify/Drain/Damage, as in vanilla.
- ModStat won't go above 100 or below 0, but preserves Fortify effects, and preserves Drain/Damage effects unless going below 0.
- SetStat only sets base stat, always preserving Fortify/Drain/Damage effects.
- CurrentStat = GetStat, SetStat 100, FortifyStat = GetStat - 100, BaseStat = CurrentStat - FortifyStat, SetStat BaseStat.