» Sun Nov 18, 2012 6:12 pm
I wouldn't call it an oversight, exactly. Just a hardcoded hack.
For example, a Common gem you get that is initially filled (from a vendor or a chest, for example) will have SoulGemCommonFilled (0002E4F3) as its base type. This item is not persistent, so it stacks, and is worth 150. A Common gem that is *not* initially filled has base type SoulGemCommon (0002E4E6) and it is worth 50. When it is empty (you just picked it up) it is non-persistent and stacks, but when a soul is trapped, it is given a persistent object reference for as long as it is in your inventory, which means it no longer stacks, but it is still a SoulGemCommon and is still worth 50. This is the source of some weird behavior (try dropping a non-stacking gem and picking it up again, it resets to empty). Anyways, this persistent item reference is stored somewhere in memory. For example, if you have a handle on it you can call GetSoulSize from SKSE. When the game wants to use the gem, for example to enchant an item, it does some hardcoded jiggerypokery to examine the persistent item reference for a given gem, or to just use the non-persistent SoulGemXXXFilled variety. This is hard-coded, you won't find any script defining how this works. Similarly, trapping a soul is hard-coded magic too: scripts can't actually find empty soul gems in the player's inventory, they can only call the native TrapSoul function which examines some internal rules to find a suitable empty gem and fill it (which amounts to giving it a persistent reference with a soul size, and notably does *not* remove or add any items, or give the player a SoulGemXXXFilled item).
Basically, if you want to override this behavior, as I do, you have to resort to total hacks. My current plan is to do the following: silently move all gems of all types to a dummy hidden chest somewhere, just before the Trap Soul effect finishes. Then I repeatedly give the player increasingly powerful soul gems (petty -> lesser -> common -> greater -> black) until victim.TrapSoul() succeeds, at which point I play the TrapSoul animation and give them a SoulGemXXXFilled item. Finally I return all their old gems, except for one empty variety of the kind that succeeded. Since I can't tell how much soul that particular gem has, I might be replacing a "trapped" soul of sufficient size with a SoulGemXXXFilled item which basically means the soul trap accomplishes nothing, but this can only happen once per trapped soul, and if a player just plays with my mod all the time it will never come up.
This is super hacky, and I hate that I might overwrite trapped souls, but it accomplishes what I want to (make sure not to waste big gems on small creatures).