GamerRick Posted July 8, 2023 Author Share Posted July 8, 2023 (edited) Thanks! You confirmed that this is something broken in my game or maybe a corrupted save. I am really burned out on this right now. A few days ago I tested what would happen if I put all gems in a container and then saved and restarted the game. It fixed the problem for a while. The ONLY time I get the wrong soul size is for creatures that are PC Offset but have a set soul size, like the ogres in Pale Pass: level 24, soul size set to Common. I haven't figured out that one because of the bigger one. Edited July 8, 2023 by GamerRick Link to comment Share on other sites More sharing options...
RomanR Posted July 8, 2023 Share Posted July 8, 2023 Ogres in Pale Pass comes from leveled list, but their base object doesn't use PCLevelOffset (so they have static level). And yes, they're all edited to have common souls and as I tested that the soul gem will be filled with common soul after they die. Link to comment Share on other sites More sharing options...
GamerRick Posted July 8, 2023 Author Share Posted July 8, 2023 (edited) Ogres in Pale Pass comes from leveled list, but their base object doesn't use PCLevelOffset (so they have static level). And yes, they're all edited to have common souls and as I tested that the soul gem will be filled with common soul after they die.Must be OOO that changes them. It does that to a lot of actors throughout the game. I gave up on the GetInvRefs because it doesn't work better than foreach and it doesn't handle Azura's star. I also have another related script that may or may not have anything to do with the count problem. Here are my scripts: scn RFFnOnSoulTrap ;= INPUTS ref rTarget long lEffect ;=== long lSTRP ref rEffectCode ref rItem ref rItemBase short iSoulSize short iGemCount ;short iObjType short iCurrSoulLevel short iPetty short iLesser short iCommon short iGreater short iGrand short iBlack short bAzuraStar begin Function { rTarget, lEffect } if rTarget.IsActor PrintC"RFFnOnSoulTrap called on %n" rTarget endif let lSTRP := MagicEffectCodeFromChars "STRP" if lSTRP != lEffect let rEffectCode := MagicEffectFromCode lEffect PrintC "RFFnOnSoulTrap called with spell %n (%.0f)", rEffectCode, lEffect return endif if rTarget.GetIsReference player return endif if rTarget.IsActor == 0 Message "Target is not an Actor" 4 else ;set RFLightSpellQuest.rTarget to rTarget ;set RFLightSpellQuest.bShowSoulGemCount to 1 endif ;return ;========================== if rTarget.IsActor if rTarget.IsCreature == 0 set iSoulSize to 6 elseif rTarget.GetLevel >= 18 set iSoulSize to 5 elseif rTarget.GetLevel >= 13 set iSoulSize to 4 elseif rTarget.GetLevel >= 7 set iSoulSize to 3 elseif rTarget.GetLevel >= 2 set iSoulSize to 2 else set iSoulSize to 1 endif set iPetty to 0 set iLesser to 0 set iCommon to 0 set iGreater to 0 set iGrand to 0 set iBlack to 0 set bAzuraStar to 0 set rItem to 0 if RFGEMCOUNT == 1 foreach rItem <- Player if rItem.IsSoulGem let iCurrSoulLevel := rItem.GetCurrentSoulLevel let iGemCount := rItem.GetRefCount let rItemBase := rItem.GetBaseObject ;PrintC "RFFnOnSoulTrap ------ Stack Count for %n is %g, Current Soul Level = %g", rItemBase, iGemCount, iCurrSoulLevel if iCurrSoulLevel == 0 && iGemCount > 0 ; Soulgem & empty if iSoulSize == 1 if rItemBase == SoulGemEmpty1Petty ; rItem.GetSoulGemCapacity == 1 PrintC "RFFnOnSoulTrap ------ Stack Count for %n is %g, Current Soul Level = %g", rItemBase, iGemCount, iCurrSoulLevel set iPetty to iPetty + iGemCount endif elseif iSoulSize == 2 if rItemBase == SoulGemEmpty2Lesser ;rItem.GetSoulGemCapacity == 2 PrintC "RFFnOnSoulTrap ------ Stack Count for %n is %g, Current Soul Level = %g", rItemBase, iGemCount, iCurrSoulLevel set iLesser to iLesser + iGemCount endif elseif iSoulSize == 3 if rItemBase == SoulGemEmpty3Common ;rItem.GetSoulGemCapacity == 3 PrintC "RFFnOnSoulTrap ------ Stack Count for %n is %g, Current Soul Level = %g", rItemBase, iGemCount, iCurrSoulLevel set iCommon to iCommon + iGemCount endif elseif iSoulSize == 4 if rItemBase == SoulGemEmpty4Greater ;rItem.GetSoulGemCapacity == 4 PrintC "RFFnOnSoulTrap ------ Stack Count for %n is %g, Current Soul Level = %g", rItemBase, iGemCount, iCurrSoulLevel set iGreater to iGreater + iGemCount endif elseif iSoulSize == 5 if rItemBase == AzurasStar set bAzuraStar to 1 elseif rItemBase == SoulGemEmpty5Grand PrintC "RFFnOnSoulTrap ------ Stack Count for %n is %g, Current Soul Level = %g", rItemBase, iGemCount, iCurrSoulLevel set iGrand to iGrand + iGemCount endif elseif iSoulSize == 6 if rItemBase == BlackSoulGem PrintC "RFFnOnSoulTrap ------ Stack Count for %n is %g, Current Soul Level = %g", rItemBase, iGemCount, iCurrSoulLevel set iBlack to iBlack + iGemCount endif endif endif endif loop ; set rItem to 0 endif if iSoulSize == 1 Message "Target soul level is PETTY (%.0f)" iPetty, 4 ;Message "Target soul level is PETTY (%.0f)" iPetty, 4 PrintC "Target soul level is PETTY. Player has %g empty Petty soulgems" iPetty elseif iSoulSize == 2 Message "Target soul level is LESSER (%.0f)" iLesser, 4 ;Message "Target soul level is LESSER (%.0f)" iLesser, 4 PrintC "Target soul level is Lesser. Player has %g empty Lesser soulgems" iLesser elseif iSoulSize == 3 Message "Target soul level is COMMON (%.0f)" iCommon, 4 ;Message "Target soul level is COMMON (%.0f)" iCommon, 4 PrintC "Target soul level is Common. Player has %g empty Common soulgems" iCommon elseif iSoulSize == 4 Message "Target soul level is GREATER (%.0f)" iGreater, 4 ;Message "Target soul level is GREATER (%.0f)" iGreater, 4 PrintC "Target soul level is Greater. Player has %g empty Greater soulgems" iGreater elseif iSoulSize == 5 if player.GetItemCount AzurasStar > 0 if bAzuraStar == 0 Message "Target soul level is GRAND (%.0f) (Azura's Star is FULL)" iGrand, 4 ;Message "Target soul level is GRAND (%.0f) (Azura's Star is FULL)" iGrand, 4 PrintC "Target soul level is Grand. Player has %g empty Grand soulgems. Azura's Star is FULL" iGrand else Message "Target soul level is GRAND (%.0f) (AzurasStar is EMPTY)" iGrand, 4 ;Message "Target soul level is GRAND (%.0f) (AzurasStar is EMPTY)" iGrand, 4 PrintC "Target soul level is Grand. Player has %g empty Grand soulgems. Azura's Star is EMPTY" iGrand endif else Message "Target soul level is GRAND (%.0f)" iGrand, 4 ;Message "Target soul level is GRAND (%.0f)" iGrand, 4 PrintC "Target soul level is Grand. Player has %g empty Grand soulgems. Player does not have Azura's Star." iGrand endif else Message "Target soul level is BLACK (%.0f)" iBlack, 4 ;Message "Target soul level is BLACK (%.0f)" iBlack, 4 PrintC "Target soul level is Black. Player has %g empty Black soulgems." iBlack endif else ;Message "Target is not an Actor" 4 Message "Target is not an Actor" 4 endif endThis one converts user filled soulgems to their filled versions. You can also see my first failed attempt to use pluggy to write stuff to file: elseif iButton == 5 ; Soulgem Boogie set bShowMenu1 to 0 ;RFSoulGemSwapContainerRef.MoveTo player 0,0,-20 set iCount to 0 ;set strFilename to CreateString -1, "Ricks\RicksSigilStoneBoogieout.txt",1,1 ;StringToTxtFile strFilename, strFilename, 1 ;PrintC "Created String: %z" strFilename set rItem to 0 foreach rItem <- PlayerRef ;set rItem to rItemIter set rItemBase to rItem.GetBaseObject if rItem.IsSoulGem let iNumItems := rItem.GetRefCount let iSoulGemSoulSize := rItem.GetCurrentSoulLevel ; StringToTxtFile FilenameStringID StringID:long LineEnd:short ;let strHexID := GetFormIDString rItemBase ; FmtString strPluggyString, 0, "==== PROCESSING %g) %n (%z) with soul level %g.", iNumItems, rItemBase, strHexID, iSoulGemSoulSize ;let strOutputText := sv_Construct "==== PROCESSING %g) %n (%z) with soul level %g." iNumItems, rItemBase, strHexID, iSoulGemSoulSize ;set strPluggyString to -1, strOutputText, 1, 1 ;PrintC "Created String: %z" strPluggyString ;StringToTxtFile strFilename, strPluggyString, 1 ;DestroyString strPluggyString PrintC"==== PROCESSING %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;sv_Destruct strHexID, strOutputText if iNumItems > 0 && iSoulGemSoulSize > 0 PrintC"Exchanging %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;let strOutputText := sv_Construct "Exchanging %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;set strPluggyString to -1, strOutputText, 1, 1 ;StringToTxtFile strFilename strPluggyString 1 ;DestroyString strPluggyString ;sv_Destruct strOutputText if rItemBase == SoulGemEmpty1Petty RFSoulGemSwapContainerRef.AddItem SoulGem1Petty1PettySoul iNumItems rItem.RemoveMEIR PrintC"Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;let strOutputText := sv_Construct "Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;set strPluggyString to -1, strOutputText, 1, 1 ;StringToTxtFile strFilename strPluggyString 1 ;DestroyString strPluggyString ;sv_Destruct strOutputText elseif rItemBase == SoulGemEmpty2Lesser if iNumItems > PlayerRef.GetItemCount SoulGemEmpty2Lesser PrintC "RFHotkeys SoulGem Boogie - number of ref items for SoulGemEmpty2Lesser is greater than number of base items!" endif if iSoulGemSoulSize == 1 RFSoulGemSwapContainerRef.AddItem SoulGem2Lesser1PettySoul iNumItems else RFSoulGemSwapContainerRef.AddItem SoulGem2Lesser2LesserSoul iNumItems endif rItem.RemoveMEIR PrintC"Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;let strOutputText := sv_Construct "Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;set strPluggyString to -1, strOutputText, 1, 1 ;StringToTxtFile strFilename strPluggyString 1 ;DestroyString strPluggyString ;sv_Destruct strOutputText elseif rItemBase == SoulGemEmpty3Common if iNumItems > PlayerRef.GetItemCount SoulGemEmpty3Common PrintC "RFHotkeys SoulGem Boogie - number of ref items for SoulGemEmpty3Common is greater than number of base items!" endif if iSoulGemSoulSize == 1 RFSoulGemSwapContainerRef.AddItem SoulGem3Common1PettySoul iNumItems elseif iSoulGemSoulSize == 2 RFSoulGemSwapContainerRef.AddItem SoulGem3Common2LesserSoul iNumItems else PrintC" Adding common/commons to the temp swap container." RFSoulGemSwapContainerRef.AddItem SoulGem3Common3CommonSoul iNumItems endif rItem.RemoveMEIR PrintC"Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;let strOutputText := sv_Construct "Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;set strPluggyString to -1, strOutputText, 1, 1 ;StringToTxtFile strFilename strPluggyString 1 ;DestroyString strPluggyString ;sv_Destruct strOutputText elseif rItemBase == SoulGemEmpty4Greater if iNumItems > PlayerRef.GetItemCount SoulGemEmpty4Greater PrintC "RFHotkeys SoulGem Boogie - number of ref items for SoulGemEmpty4Greater is greater than number of base items!" endif if iSoulGemSoulSize == 1 RFSoulGemSwapContainerRef.AddItem SoulGem4Greater1PettySoul iNumItems elseif iSoulGemSoulSize == 2 RFSoulGemSwapContainerRef.AddItem SoulGem4Greater2LesserSoul iNumItems elseif iSoulGemSoulSize == 3 RFSoulGemSwapContainerRef.AddItem SoulGem4Greater3CommonSoul iNumItems else RFSoulGemSwapContainerRef.AddItem SoulGem4Greater4GreaterSoul iNumItems endif rItem.RemoveMEIR PrintC"Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;let strOutputText := sv_Construct "Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;set strPluggyString to -1, strOutputText, 1, 1 ;StringToTxtFile strFilename strPluggyString 1 ;DestroyString strPluggyString ;sv_Destruct strOutputText elseif rItemBase == SoulGemEmpty5Grand if iNumItems > PlayerRef.GetItemCount SoulGemEmpty5Grand PrintC "RFHotkeys SoulGem Boogie - number of ref items for SoulGemEmpty5Grand is greater than number of base items!" endif if iSoulGemSoulSize == 1 RFSoulGemSwapContainerRef.AddItem SoulGem5Grand1PettySoul iNumItems elseif iSoulGemSoulSize == 2 RFSoulGemSwapContainerRef.AddItem SoulGem5Grand2LesserSoul iNumItems elseif iSoulGemSoulSize == 3 RFSoulGemSwapContainerRef.AddItem SoulGem5Grand3CommonSoul iNumItems elseif iSoulGemSoulSize == 4 RFSoulGemSwapContainerRef.AddItem SoulGem5Grand4GreaterSoul iNumItems else RFSoulGemSwapContainerRef.AddItem SoulGem5Grand5GrandSoul iNumItems endif rItem.RemoveMEIR PrintC"Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;let strOutputText := sv_Construct "Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize ;set strPluggyString to -1, strOutputText, 1, 1 ;StringToTxtFile strFilename strPluggyString 1 ;DestroyString strPluggyString ;sv_Destruct strOutputText elseif rItemBase == BlackSoulGem if iNumItems > PlayerRef.GetItemCount BlackSoulGem PrintC "RFHotkeys SoulGem Boogie - number of ref items for BlackSoulGem is greater than number of base items!" endif if iSoulGemSoulSize == 5 RFSoulGemSwapContainerRef.AddItem BlackSoulGemFilled iNumItems rItem.RemoveMEIR PrintC"Exchanged %g) %n with soul level %g." iNumItems, rItemBase, iSoulGemSoulSize endif endif endif endif loop set rItem to 0 ;set rItem to 0 ;PrintC"============= Dump temp swap container ==========" ;foreach rItem <- RFSoulGemSwapContainerRef ;set rItemBase to rItem.GetBaseObject ;set iNumItems to rItem.GetRefCount ;PrintC"RFSoulGemSwapContainerRef - Found %g) %n)" iNumItems, rItemBase ;loop RFSoulGemSwapContainerRef.RemoveAllItems player 0 player.PlaySound3D SPLMysticismCast Message "Soulgem boogie complete." ;DestroyString strFilename elseif iButton == 6Soulgem Boogie seems to be working lately. Though in the past it would sometimes convert one soulgem I filled to two full ones. LOL! Other times I would see my entire stack of empty ones disappear and a big stack of full ones appear. However, it happens so sporadically that I can't pinpoint the cause. EDIT: My suspicion is that one (or both) of my loops are somehow corrupting the inventory stacks of soulgems in my inventory. Or xOBSE has a bug that is doing this and my scripts just happen to hit that bug in its head. I updated xOBSE at some point to 22.7 and am now at 22.9. The problem may have started with 22.7. I tried going back to OBSE 22.1, but the problem continued. I am back to 22.9 now. Edited July 8, 2023 by GamerRick Link to comment Share on other sites More sharing options...
RomanR Posted July 8, 2023 Share Posted July 8, 2023 (edited) The first seems OK, as it only checks something, it can't alter item stacks in any way. But in second one you're using AddItem command within ForEach loop, the docs explicitly say to not use such commands until it ends. Maybe you can use CreateTempRef, SetRefCount and CopyIR, but I'm not sure, as example is doing it after the end of loop too. Edited July 8, 2023 by RomanR Link to comment Share on other sites More sharing options...
GamerRick Posted July 8, 2023 Author Share Posted July 8, 2023 (edited) It's adding them to a temp container RFSoulGemSwapContainerRef. Edited July 8, 2023 by GamerRick Link to comment Share on other sites More sharing options...
RomanR Posted July 8, 2023 Share Posted July 8, 2023 Truly, you're using this container to add gems aftewards. My apologies. Link to comment Share on other sites More sharing options...
GamerRick Posted July 15, 2023 Author Share Posted July 15, 2023 (edited) The correct way to determine the soul level for creatures. Refscope is where I found this. if rTarget.IsCreature == 0 set iSoulSize to 6 elseif rTarget.IsPCLevelOffset == 0 let rTargetBase := rTarget.GetBaseObject Let iSoulSize := rTarget.GetCreatureSoulLevel PrintC"RFFnOnSoulTrap: Creature %n is NOT PCLO, Soulsize is %g", rTargetBase, iSoulSize elseif rTarget.GetLevel >= 18 set iSoulSize to 5 elseif rTarget.GetLevel >= 13 set iSoulSize to 4 elseif rTarget.GetLevel >= 7 set iSoulSize to 3 elseif rTarget.GetLevel >= 2 set iSoulSize to 2 else set iSoulSize to 1 endif Edited July 15, 2023 by GamerRick Link to comment Share on other sites More sharing options...
RomanR Posted July 15, 2023 Share Posted July 15, 2023 Yes, yours soul level part is now almost same as mine, just more tidy. Still .... this alone can't result in wrong stacks amounts. However as I saw your second script again , I have a theory about wrong timing using AddItem commands and then RemoveAllItems on a swap container. As such commands goes into queue, maybe it's better to execute RemoveAllItems next frame after AddItem command(s) fill a swap container with soul gem(s). But my experience is that only enchanted items needs such handling for equip and unequip when using OBSE, so I may be wrong. Link to comment Share on other sites More sharing options...
GamerRick Posted July 17, 2023 Author Share Posted July 17, 2023 (edited) Actually, the script (SoulGemBoogie) that converts player filled empty gems with their filled counterparts works flawlessly. It's the one that counts the gems that are still empty that is failing. So, it would seem that the empty stack in the player's inventory is the one that is getting corrupted somehow. Meanwhile I have done 2 things: 1) Change SoulGemBoogie to open the swap container, so that the player can put the non-empty empty gems into it. Upon exiting the container, the script's GameMode script will scan through the swap container, remove the stacks that can be converted, and do the AddItemNS command on the player to give them the converted ones. I did this so that there were no scripted RemoveMeIR commands being done on the player (that may or may not be cause the corruption). 2) Start a new game. It will be a while before I can cast a soultrap spell for the first time. Edited July 17, 2023 by GamerRick Link to comment Share on other sites More sharing options...
GamerRick Posted July 28, 2023 Author Share Posted July 28, 2023 It started happening again a few days ago. I have no clue what would case it. Link to comment Share on other sites More sharing options...
Recommended Posts