Nyrolian Posted April 10, 2021 Share Posted April 10, 2021 Hello, Baby modder here. I've been working on a script to fuse soul gem pieces together and I can't get this thing to compile for the life of me. Something that I really don't understand is that when I change the lines in the function TakeAway from (PiecesToRemove -=) to (PiecesToRemove = PiecesToRemove - 1), what used to be only six or so errors confined ONLY to that function suddenly become a bazillion errors spread throughout the whole script. Don't these mean the same thing? Is my syntax wrong? The compiler treats PiecesToRemove-= and PiecesToRemove -= as the same thing. My apologies if the post is too long or I'm breaking some kind of forum rules or something. I'm very new here and just want to figure out what I'm doing wrong. Thank you. Scriptname CustomSoulGemRefuser{This script detects how many soul gem pieces a Player has, and allows them to fuse a certain amount together to make a whole empty one of a certain size.} FormList Property SoulGemPieceList Auto;List of all accepted pieces, used to determine what menu pops up and how many options it includes SoulGem Property EmptyPetty AutoSoulGem Property EmptyLesser AutoSoulGem Property EmptyCommon Auto;Base items of unfilled soul gems, given to Player MiscItem Property SoulGemPiece001 AutoMiscItem Property SoulGemPiece002 AutoMiscItem Property SoulGemPiece003 AutoMiscItem Property SoulGemPiece004 AutoMiscItem Property SoulGemPiece005 Auto;Soul gem pieces, needed for function TakeAway (i had them there but was getting errors???) Message Property OnlyPetty AutoMessage Property PettyLesser AutoMessage Property PettyLesserCommon Auto;The three menus based on how many soul gem pieces the Player has. Options are limited to only what they can make;EG if they have four pieces, the menu will not include the option to craft a common soul gem ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Event OnActivate(ObjectReference akActionRef)Menu()EndEvent ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function Menu(Int aiButton = 0);This function determines what menu pops up based on how many soul gems the Player has and introduces the PiecesToRemove variableInt PlayerPieceCount = Game.GetPlayer().GetItemCount(SoulGemPieceList)Int PiecesToRemove = 0 If PlayerPieceCount == 3PiecesToRemove = 3aiButton = OnlyPetty.show()If aiButton == 0 ;Cancel optionElseIf aiButton == 1 ;Make petty soul gem optionTakeAway()Game.GetPlayer().AddItem(EmptyPetty)EndIf;This is the menu option if the player has only 3 pieces. They will only be able to craft a petty soul gem or exit the menu ElseIf PlayerPieceCount == 4 aiButton = PettyLesser.show()If aiButton == 0ElseIf aiButton == 1PiecesToRemove = 4TakeAway()Game.GetPlayer().AddItem(EmptyPetty)ElseIf aiButton == 2PiecesToRemove = 3TakeAway()Game.GetPlayer().AddItem(EmptyLesser);The menu option for 4 pieces. Options are to cancel, make a petty gem, or make a lesser gem ElseIf PlayerPieceCount > 4aiButton = PettyLesserCommon.show()If aiButton == 0ElseIf aiButton == 1PiecesToRemove == 3TakeAway()Game.GetPlayer().AddItem(EmptyPetty)ElseIf aiButton == 2PiecesToRemove == 4TakeAway()Game.GetPlayer().AddItem(EmptyLesser)ElseIf aiButton == 3PiecesToRemove == 5TakeAway()Game.GetPlayer().AddItem(EmptyCommon);The menu option if the player has more than 4 gems. All soul gem crafting options are offered to them ElseDebug.Notification("You don't have enough soul gem pieces to make anything")EndIf;If the Player has 2 or fewer pieces, this notification will show EndIfEndifEndFunction ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function TakeAway(Int PiecesToRemove) ;These properties point to base items of all 5 soul gem pieces individually, used for Function TakeAway Int Piece01 = Game.GetPlayer().GetItemCount(SoulGemPiece001)Int Piece02 = Game.GetPlayer().GetItemCount(SoulGemPiece002)Int Piece03 = Game.GetPlayer().GetItemCount(SoulGemPiece003)Int Piece04 = Game.GetPlayer().GetItemCount(SoulGemPiece004)Int Piece05 = Game.GetPlayer().GetItemCount(SoulGemPiece005) While PiecesToRemove > 0While Piece01 > 0Game.GetPlayer().RemoveItem(SoulGemPiece001)PiecesToRemove = PiecesToRemove - 1EndWhileWhile Piece02 > 0Game.GetPlayer().RemoveItem(SoulGemPiece002)PiecesToRemove = PiecesToRemove - 1EndWhileWhile Piece03 > 0Game.GetPlayer().RemoveItem(SoulGemPiece003)PiecesToRemove = PiecesToRemove - 1EndWhileWhile Piece04 > 0 Game.GetPlayer().RemoveItem(SoulGemPiece004)PiecesToRemove = PiecesToRemove - 1EndWhileWhile Piece05 > 0Game.GetPlayer().RemoveItem(SoulGemPiece005)PiecesToRemove = PiecesToRemove - 1EndWhileEndWhileEndFunction Link to comment Share on other sites More sharing options...
IsharaMeradin Posted April 10, 2021 Share Posted April 10, 2021 I believe it is confused by the multiple operators. Do one of the following: PiecesToRemove -= 1 PiecesToRemove = (PiecesToRemove - 1)You can speed up your script execution by replacing all those Game.GetPlayer calls with a variable referencing the player. It does not need to be a property, a local variable or even an event parameter variable will do. I would also utilize the formlist that you already have containing the soul gem pieces instead of listing them separately as properties. And because there are a lot of similar things going on, I would create a custom function to handle the work load. The following compiles and demonstrates what I've mentioned, but whether it works for your needs or not... only you can determine that Scriptname CustomSoulGemRefuser Extends ObjectReference {This script detects how many soul gem pieces a Player has, and allows them to fuse a certain amount together to make a whole empty one of a certain size.} FormList Property SoulGemPieceList Auto ;List of all accepted pieces, used to determine what menu pops up and how many options it includes SoulGem Property EmptyPetty Auto SoulGem Property EmptyLesser Auto SoulGem Property EmptyCommon Auto ;Base items of unfilled soul gems, given to Player Message Property OnlyPetty Auto Message Property PettyLesser Auto Message Property PettyLesserCommon Auto ;The three menus based on how many soul gem pieces the Player has. Options are limited to only what they can make ;EG if they have four pieces, the menu will not include the option to craft a common soul gem ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Event OnActivate(ObjectReference akActionRef) If akActionRef == Game.GetPlayer() Menu(akActionRef) EndIf EndEvent ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function Menu(ObjectReference myReader) Int PlayerPieceCount = myReader.GetItemCount(SoulGemPieceList) If PlayerPieceCount == 3 Int aiButton = OnlyPetty.show() If aiButton == 0 ElseIf aiButton == 1 HandleMenuOption(myReader,3,EmptyPetty) EndIf ElseIf PlayerPieceCount == 4 Int aiButton = PettyLesser.show() If aiButton == 0 ElseIf aiButton == 1 HandleMenuOption(myReader,4,EmptyLesser) ElseIf aiButton == 2 HandleMenuOption(myReader,3,EmptyPetty) EndIf ElseIf PlayerPieceCount > 4 Int aiButton = PettyLesserCommon.show() If aiButton == 0 ElseIf aiButton == 1 HandleMenuOption(myReader,3,EmptyPetty) ElseIf aiButton == 2 HandleMenuOption(myReader,4,EmptyLesser) ElseIf aiButton == 3 HandleMenuOption(myReader,5,EmptyCommon) Else Debug.Notification("You don't have enough soul gem pieces to make anything") EndIf Endif EndFunction Function HandleMenuOption(ObjectReference mySelector, Int PTR, Form ObjectToGive) ;take away the pieces Int index = 0 While (index < SoulGemPieceList.GetSize()) && (PTR > 0) Form Entry = SoulGemPieceList.GetAt(index) If mySelector.GetItemCount(Entry) > 0 mySelector.RemoveItem(Entry,1,true) PTR -= 1 EndIf index += 1 EndWhile ;give the empty gem mySelector.AddItem(ObjectToGive) EndFunction Link to comment Share on other sites More sharing options...
Nyrolian Posted April 11, 2021 Author Share Posted April 11, 2021 (edited) First of all, thank you very much for taking the time to look at my code and troubleshoot with me. I'm still teaching myself Papyrus, and while I still don't understand all of it, looking at the code you provided and dissecting it helped me understand what I was doing wrong. The main problem was that I didn't fully understand how parameters worked with new functions and what to put in the parentheses and how they related to each other in the different functions. Now I think I've finally got it! Also it didn't help that I wrote MiscItem property instead of the correct MiscObject property. No idea where I got the idea that it was called MiscItem. Just for posterity, this is the code I ended up going with. I tested it in-game and it works perfectly. Your suggestion for using the formlist to take away the soul gem pieces was fantastic. I didn't even realize that was an option before. Again, thank you! You really helped me get a better understanding of how this stuff works. Scriptname CustomSoulGemPieceCounter extends ObjectReference {Script detects how many soul gem pieces a player has, offers up a menu, and takes away a certain number of pieces and replaces them with a corresponding empty soul gem} FormList Property SoulGemPieces Auto Message Property OnlyPettyOption Auto Message Property PettyLesser Auto Message Property PettyLesserCommon Auto Soulgem Property EmptyPetty Auto Soulgem Property EmptyLesser Auto Soulgem Property EmptyCommon Auto Event OnActivate(ObjectReference akActionRef) Int PlayerPieces = Game.GetPlayer().GetItemCount(SoulGemPieces) If PlayerPieces > 2 Menu(PlayerPieces, akActionRef) Else Debug.Messagebox("You don't have enough soul gem pieces to make anything") EndIf EndEvent ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function Menu(int PlayerPieces, ObjectReference Player) int aiButton = 0 If PlayerPieces == 3 aiButton = OnlyPettyOption.show() If aiButton == 0 ElseIf aiButton == 1 Int PiecesToRemove = 3 TakeAway(PiecesToRemove, Player, EmptyPetty) EndIf ElseIf PlayerPieces == 4 aiButton = PettyLesser.show() If aiButton == 0 ElseIf aiButton == 1 Int PiecesToRemove = 3 TakeAway(PiecesToRemove, Player, EmptyPetty) ElseIf aiButton == 2 Int PiecesToRemove = 4 TakeAway(PiecesToRemove, Player, EmptyLesser) EndIf Else aiButton = PettyLesserCommon.show() If aiButton == 0 ElseIf aiButton == 1 Int PiecesToRemove = 3 TakeAway (PiecesToRemove, Player, EmptyPetty) ElseIf aiButton == 2 Int PiecesToRemove = 4 TakeAway(PiecesToRemove, Player, EmptyLesser) ElseIf aiButton == 3 Int PiecesToRemove = 5 TakeAway(PiecesToRemove, Player, EmptyCommon) EndIf EndIf EndFunction ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function TakeAway(int PiecesToRemove, ObjectReference Player, Form ObjectToGive) Int index = 0 While (index < SoulGemPieces.GetSize()) && (PiecesToRemove > 0) Form Entry = SoulGemPieces.GetAt(index) If Player.GetItemCount(Entry) > 0 Player.RemoveItem(Entry,1,true) PiecesToRemove -= 1 EndIf index += 1 EndWhile Player.AddItem(ObjectToGive) EndFunction Edited April 11, 2021 by Nyrolian Link to comment Share on other sites More sharing options...
AnishaDawn Posted April 11, 2021 Share Posted April 11, 2021 You can reduce that loop further for greater efficiency too. Your current loop is going in the opposite direction I think. Storing the form count as it's not expected to change, you can instead loop the other way and not have the compiler constantly query for the form count with GetSize(). ; Store the number of forms contained in the list Int index = SoulPieces.GetSize() While index > 0 && PiecesToRemove > 0 Form Entry = SoulGemPieces.GetAt(index) if player.GetItemCount(Entry) > 0 player.RemoveItem(Entry, 1, true) PiecesToRemove -= 1 endif index -= 1 EndWhile Link to comment Share on other sites More sharing options...
ReDragon2013 Posted April 11, 2021 Share Posted April 11, 2021 (edited) There is a logic error in your while loop. It doesn't matter to make it in "bottom-up" or "top-down" method. Let me explain: You have for example 3 soulgem fragments of type 3 (SoulGemPiece003).The player got the empty petty soulgem after confirming the message selection, but only one fragment has been removed from inventory by the loop, not three.Nyrolian loop: Int index = 0 While (index < SoulGemPieces.GetSize()) && (PiecesToRemove > 0) Form Entry = SoulGemPieces.GetAt(index) If Player.GetItemCount(Entry) > 0 Player.RemoveItem(Entry,1,true) PiecesToRemove -= 1 EndIf index += 1 EndWhile AnishaDawn loop: ; Store the number of forms contained in the list Int index = SoulPieces.GetSize() While index > 0 && PiecesToRemove > 0 Form Entry = SoulGemPieces.GetAt(index) if player.GetItemCount(Entry) > 0 player.RemoveItem(Entry, 1, true) PiecesToRemove -= 1 endif index -= 1 EndWhile Edited April 13, 2021 by ReDragon2013 Link to comment Share on other sites More sharing options...
ReDragon2013 Posted April 11, 2021 Share Posted April 11, 2021 (edited) first approach CustomSoulGemRefuser Scriptname CustomSoulGemRefuser extends ObjectReference {This script detects how many soul gem pieces a Player has, and allows them to fuse a certain amount together to make a whole empty one of a certain size.} ; https://forums.nexusmods.com/index.php?/topic/9876698-script-help-fusing-soul-gem-pieces/ ;The three menus based on how many soulgem pieces the Player has. Options are limited to only what they can make ;EG if they have four pieces, the menu will not include the option to craft a common soul gem Message PROPERTY OnlyPetty auto Message PROPERTY PettyLesser auto Message PROPERTY PettyLesserCommon auto ;Base items of unfilled soul gems, will be given to Player SoulGem PROPERTY EmptyPetty auto SoulGem PROPERTY EmptyLesser auto SoulGem PROPERTY EmptyCommon auto ;List of all accepted pieces (point to base items of all 5 soul gem pieces individually), used to determine, ; what menu pops up and how many options it includes FormList PROPERTY SoulGemPieceList auto ; -- EVENT -- EVENT OnActivate(ObjectReference akActionRef) IF (akActionRef == Game.GetPlayer() as ObjectReference) Menu(akActionRef) ENDIF ENDEVENT ; -- FUNCTIONs -- 3 ;----------------------------------------- FUNCTION Menu(ObjectReference akActionRef) ;----------------------------------------- ;This function determines what menu pops up based on how many soulgems the Player has. int n = akActionRef.GetItemCount(SoulGemPieceList) ; n = PlayerPieceCount int i ; i = aiButton IF (n == 3) ; 0=cancel, 1=petty; only be able to craft a petty soulgem i = OnlyPetty.show() ELSEIF (n == 4) ; 0=cancel, 1=petty, 2=lesser; make a petty or a lesser soulgem i = PettyLesser.show() ELSEIF (n > 4) ; 0,1,2, 3=common; All soulgem crafting options are offered i = PettyLesserCommon.show() ELSE Debug.Notification("You do not have enough soulgem pieces.") RETURN ; - STOP - ENDIF ;--------------------- IF (i > 0) TakeAway(i+2) ; i+2 = introduces the PiecesToRemove variable ENDIF ENDFUNCTION ;----------------------------------------------- Int FUNCTION myF_REM(Actor player, Int n, Int i) ; helper ;----------------------------------------------- form fm = SoulGemPieceList.GetAt(n) ; Form Entry = SoulGemPieceList.GetAt(index) IF (i > 0) n = player.GetItemCount(fm) WHILE (n > 0) && (i > 0) player.RemoveItem(fm) ; mySelector.RemoveItem(Entry,1,true) i = i - 1 n = n - 1 ENDWHILE ENDIF RETURN i ; give back the "piecesToRemove" counter to caller function ENDFUNCTION ;----------------------- FUNCTION TakeAway(Int i) ;----------------------- actor player = Game.GetPlayer() soulGem SG IF (i == 3) SG = EmptyPetty ELSEIF (i == 4) SG = EmptyLesser ELSEIF (i == 5) SG = EmptyCommon ENDIF ;-------------------------------- WHILE (i > 0) i = myF_REM(player, 0, i) ; SoulGemPiece001 i = myF_REM(player, 1, i) ; SoulGemPiece002 i = myF_REM(player, 2, i) ; SoulGemPiece003 i = myF_REM(player, 3, i) ; SoulGemPiece004 i = myF_REM(player, 4, i) ; SoulGemPiece005 ENDWHILE ;-------------------------------- IF ( SG ) player.AddItem(SG as Form) ENDIF ENDFUNCTION second approach CustomSoulGemRefuser Scriptname CustomSoulGemRefuser extends ObjectReference {This script detects how many soul gem pieces a Player has, and allows them to fuse a certain amount together to make a whole empty one of a certain size.} ; https://forums.nexusmods.com/index.php?/topic/9876698-script-help-fusing-soul-gem-pieces/ ;The three menus based on how many soulgem pieces the Player has. Options are limited to only what they can make ;EG if they have four pieces, the menu will not include the option to craft a common empty soulgem Message PROPERTY OnlyPetty auto Message PROPERTY PettyLesser auto Message PROPERTY PettyLesserCommon auto ;Base items of unfilled soul gems, will be given to Player SoulGem PROPERTY EmptyPetty auto SoulGem PROPERTY EmptyLesser auto SoulGem PROPERTY EmptyCommon auto ;List of all accepted pieces (point to base items of all 5 soul gem pieces individually), used to determine, FormList PROPERTY SoulGemPieceList auto ; -- EVENT -- EVENT OnActivate(ObjectReference akActionRef) IF (akActionRef == Game.GetPlayer() as ObjectReference) Menu(akActionRef) ; we are sure (at this point) akActionRef is the player, that means player has activated this object/activator ENDIF ENDEVENT ; -- FUNCTIONs -- 2 ;--------------------------------------- FUNCTION Menu(ObjectReference playerRef) ;--------------------------------------- ;This function determines what menu pops up based on how many soulgems the Player has. int n = playerRef.GetItemCount(SoulGemPieceList) ; n = PlayerPieceCount, PlayerPieces IF (n < 3) Debug.Notification("You do not have enough soulgem pieces.") RETURN ; - STOP - ENDIF ;===================== n is the amount of all soulgem pieces the player has in his inventory int i ; i = aiButton IF (n == 3) ; 0=cancel, 1=petty; only be able to craft a petty soulgem i = OnlyPetty.show() ; 3 ELSEIF (n == 4) ; 0=cancel, 1=petty, 2=lesser; make a petty or a lesser soulgem i = PettyLesser.show() ; 3,4 ELSE ;IF (n > 4) ; 0,1,2, 3=common; All soulgem crafting options are offered i = PettyLesserCommon.show() ; 3,4,5 ENDIF IF (i > 0) ; i+2 = introduces the PiecesToRemove variable i = i + 2 playerRef.AddItem( TransferItems(playerRef, i) ) ENDIF ENDFUNCTION ;------------------------------------------------------------ Form FUNCTION TransferItems(ObjectReference playerRef, Int i) ; Bottom-up method ;------------------------------------------------------------ soulGem SG IF (i == 3) SG = EmptyPetty ELSEIF (i == 4) SG = EmptyLesser ELSEIF (i == 5) SG = EmptyCommon ENDIF ;-------------------------------- int iMaxToRemove = i ; iMaxToRemove = PiecesToRemove i = 0 WHILE (iMaxToRemove > 0) && (i < SoulGemPieces.GetSize()) form fm = SoulGemPieces.GetAt(i) ; GetAt(0) is SoulGemPiece001 ; .. ; GetAt(4) is SoulGemPiece005 int n = playerRef.GetItemCount(fm) ; get players count of soulgem pieces IF (n > iMaxToRemove) n = iMaxToRemove ; reduce to max ENDIF IF (n > 0) playerRef.RemoveItem(fm, n, TRUE) iMaxToRemove = iMaxToRemove - n ; adjust remove counter ENDIF i = i + 1 ; increase formlist counter ENDWHILE ;-------------------------------- RETURN (SG as Form) ENDFUNCTION ;-------------------------------------------------------------- Form FUNCTION TransferItems_2(ObjectReference playerRef, Int i) ; Top-down method, like AnishaDawn suggested ;-------------------------------------------------------------- soulGem SG IF (i == 3) SG = EmptyPetty ELSEIF (i == 4) SG = EmptyLesser ELSEIF (i == 5) SG = EmptyCommon ENDIF ;-------------------------------- int iMaxToRemove = i ; iMaxToRemove = PiecesToRemove i = SoulGemPieces.GetSize() ; get formlist size, once here WHILE (i > 0) i = i - 1 ; decrease counter to run loop for valid formlist entry form fm = SoulGemPieces.GetAt(i) ; GetAt(4) is SoulGemPiece005 ; .. ; GetAt(0) is SoulGemPiece001 int n = playerRef.GetItemCount(fm) ; get players count of soulgem pieces IF (n > iMaxToRemove) n = iMaxToRemove ; reduce pieces counter to max ENDIF IF (n > 0) playerRef.RemoveItem(fm, n, TRUE) iMaxToRemove = iMaxToRemove - n ; adjust remove counter ENDIF IF (iMaxToRemove == 0) i = 0 ; break loop ENDIF ENDWHILE ;-------------------------------- RETURN (SG as Form) ENDFUNCTION third approach CustomSoulGemRefuser Scriptname CustomSoulGemRefuser extends ObjectReference {This script detects how many soul gem pieces a Player has, and allows them to fuse a certain amount together to make a whole empty one of a certain size.} ; https://forums.nexusmods.com/index.php?/topic/9876698-script-help-fusing-soul-gem-pieces/ ;The three menus based on how many soulgem pieces the Player has. Options are limited to only what they can make ;EG if they have four pieces, the menu will not include the option to craft a common soul gem Message PROPERTY OnlyPetty auto Message PROPERTY PettyLesser auto Message PROPERTY PettyLesserCommon auto ;Base items of unfilled soul gems, will be given to Player SoulGem PROPERTY EmptyPetty auto SoulGem PROPERTY EmptyLesser auto SoulGem PROPERTY EmptyCommon auto ;List of all accepted pieces (point to base items of all 5 soul gem pieces individually), used to determine, ; what menu pops up and how many options it includes FormList PROPERTY SoulGemPieceList auto ; -- EVENT -- EVENT OnActivate(ObjectReference akActionRef) IF (akActionRef == Game.GetPlayer() as ObjectReference) Menu(akActionRef) ENDIF ENDEVENT ; -- FUNCTIONs -- 2 ;--------------------------------------- FUNCTION Menu(ObjectReference playerRef) ;--------------------------------------- ;This function determines what menu pops up based on how many soulgems the Player has. int n = playerRef.GetItemCount(SoulGemPieceList) ; n = PlayerPieceCount IF (n < 3) Debug.Notification("You do not have enough soulgem pieces.") RETURN ; - STOP - ENDIF ;--------------------- int i ; i = aiButton IF (n == 3) ; 0=cancel, 1=petty; only be able to craft a petty soulgem i = OnlyPetty.show() ELSEIF (n == 4) ; 0=cancel, 1=petty, 2=lesser; make a petty or a lesser soulgem i = PettyLesser.show() ELSE ;IF (n > 4) ; 0,1,2, 3=common; All soulgem crafting options are offered i = PettyLesserCommon.show() ENDIF IF (i > 0) TakeAway(playerRef, i+2) ; i+2 = introduces the PiecesToRemove variable ENDIF ENDFUNCTION ;-------------------------------------------------- FUNCTION TakeAway(ObjectReference playerRef, Int i) ; random list entry at the begin (with a single loop counter and condition) ;-------------------------------------------------- soulGem SG IF (i == 3) SG = EmptyPetty ELSEIF (i == 4) SG = EmptyLesser ELSEIF (i == 5) SG = EmptyCommon ENDIF ;-------------------------------- int iMaxToRemove = i i = Utility.RandomInt(1, SoulGemPieceList.GetSize()) ; random number here WHILE (iMaxToRemove > 0) IF (i == 0) i = SoulGemPieceList.GetSize() ENDIF i = i - 1 ; update our formlist counter by -1, top-down cycle form fm = SoulGemPieceList.GetAt(i) ; valid soulgem fragment from list (i = 0..4) IF (playerRef.GetItemCount(fm) > 0) ; get amount of current soulgem fragment in players inventory playerRef.RemoveItem(fm, 1, TRUE) ; reduce players inventory for this fragment by 1 iMaxToRemove = iMaxToRemove - 1 ; decrease the item remove counter by 1 ENDIF ENDWHILE ;-------------------------------- IF ( SG ) playerRef.AddItem(SG as Form) ENDIF ENDFUNCTION Edited April 13, 2021 by ReDragon2013 Link to comment Share on other sites More sharing options...
AnishaDawn Posted April 11, 2021 Share Posted April 11, 2021 (edited) I had also noticed that error but didn't know how to approach it(I thought maybe RemoveItem(Entry, PiecesToRemove, true) would be it but..).It also doesn't make much logical sense to keep calling a native function when it's not necessary to do so but if it works, it works I guess. Edited April 11, 2021 by AnishaDawn Link to comment Share on other sites More sharing options...
dylbill Posted April 11, 2021 Share Posted April 11, 2021 Here's my take on it. Just modify the Takeaway function a bit. Function TakeAway(int PiecesToRemove, ObjectReference Player, Form ObjectToGive) Int index = 0 Int M = SoulGemPieces.GetSize() While (index < M) && (PiecesToRemove > 0) Form Entry = SoulGemPieces.GetAt(index) Int Count = Player.GetItemCount(Entry) If Count > 0 If Count > PiecesToRemove Count = PiecesToRemove Endif Player.RemoveItem(Entry,Count,true) PiecesToRemove -= Count EndIf index += 1 EndWhile Player.AddItem(ObjectToGive) EndFunction Link to comment Share on other sites More sharing options...
dylbill Posted April 11, 2021 Share Posted April 11, 2021 One more thing. If you're going to cycle top to bottom, you should subtract from the index first. This is because if let's say the list has 5 forms, getsize() will return 5, but the available entries are from 0 to 4. So the first time through the loop, Form Entry = SoulGemPieces.GetAt(index) (index = 5) would return none. Function TakeAway(int PiecesToRemove, ObjectReference Player, Form ObjectToGive) Int index = SoulGemPieces.GetSize() While (index > 0) && (PiecesToRemove > 0) index -= 1 Form Entry = SoulGemPieces.GetAt(index) Int Count = Player.GetItemCount(Entry) If Count > 0 If Count > PiecesToRemove Count = PiecesToRemove Endif Player.RemoveItem(Entry,Count,true) PiecesToRemove -= Count EndIf EndWhile Player.AddItem(ObjectToGive) EndFunction Link to comment Share on other sites More sharing options...
IsharaMeradin Posted April 11, 2021 Share Posted April 11, 2021 My thought when I suggested the while loop was that it would take one of each until the amount was reached rather than taking all of one type. And it would if the player had each, but apparently it would fail if the player had enough of one of the types but none of the others. Sorry for any confusion. Link to comment Share on other sites More sharing options...
Recommended Posts