cavbirdie Posted March 2, 2015 Share Posted March 2, 2015 (edited) I am trying to make it so when you put something in the container it will check the list of items to go to mannequins and put them into the mannequins to be equipped by the correct mannequin.If its not on that list it will check 2 other form lists of items that will activate displays (haven't gotten t that part of the scripting yet), give a message if its on the list, and return to the player if its not on any of the lists. Here is what i have ScriptName _111BW_MstrContScript extends ObjectReference Actor Property PlayerRef Auto FormList Property ItemToDisplay Auto FormList Property ItemToDisplayWpn Auto FormList Property ItemToMann Auto ObjectReference Property MannCont Auto Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) If ItemToMann.HasForm(akBaseItem) Int iIndex1 = ItemToMann.GetSize() While iIndex1 > 0 iIndex1 -= 1 If ItemToMann.GetAt(iIndex1)>=0 RemoveItem(akBaseItem, aiItemCount, false, MannCont) Debug.messagebox("Is Mannequin Item") EndIf EndWhile ElseIf ItemToDisplay.HasForm(akBaseItem) Int iIndex2 = ItemToDisplay.GetSize() While iIndex2 > 0 iIndex2 -= 1 If ItemToDisplay.GetAt(iIndex2)<0 Debug.messagebox("Is Display Item") EndIf EndWhile ElseIf ItemToDisplayWpn.HasForm(akBaseItem) Int iIndex3 = ItemToDisplayWpn.GetSize() While iIndex3 > 0 iIndex3 -= 1 If ItemToDisplayWpn.GetAt(iIndex3)<0 Debug.messagebox("Is Display Weapon") Else RemoveItem(akBaseItem, aiItemCount, false, akSourceContainer) EndIf EndWhile EndIf EndEvent_111BW_MstrContScript.psc(14,31): cannot compare a form to a int (cast missing or types unrelated)_111BW_MstrContScript.psc(23,34): cannot compare a form to a int (cast missing or types unrelated)_111BW_MstrContScript.psc(31,37): cannot compare a form to a int (cast missing or types unrelated)No output generated for _111BW_MstrContScript, compilation failed. Any Help Would Be ApreciatedBTW how do i get my code to hide? Edited March 3, 2015 by cavbirdie Link to comment Share on other sites More sharing options...
jayne2132 Posted March 3, 2015 Share Posted March 3, 2015 On 3/2/2015 at 10:21 PM, cavbirdie said: I am trying to make it so when you put something in the container it will check the list of items to go to mannequins and put them into the mannequins to be equipped by the correct mannequin.If its not on that list it will check 2 other form lists of items that will activate displays (haven't gotten t that part of the scripting yet), give a message if its on the list, and return to the player if its not on any of the lists. Here is what i have ScriptName _111BW_MstrContScript extends ObjectReference Actor Property PlayerRef Auto FormList Property ItemToDisplay Auto FormList Property ItemToDisplayWpn Auto FormList Property ItemToMann Auto ObjectReference Property MannCont Auto Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) If ItemToMann.HasForm(akBaseItem) Int iIndex1 = ItemToMann.GetSize() While iIndex1 > 0 iIndex1 -= 1 If ItemToMann.GetAt(iIndex1)>=0 RemoveItem(akBaseItem, aiItemCount, false, MannCont) Debug.messagebox("Is Mannequin Item") EndIf EndWhile ElseIf ItemToDisplay.HasForm(akBaseItem) Int iIndex2 = ItemToDisplay.GetSize() While iIndex2 > 0 iIndex2 -= 1 If ItemToDisplay.GetAt(iIndex2)<0 Debug.messagebox("Is Display Item") EndIf EndWhile ElseIf ItemToDisplayWpn.HasForm(akBaseItem) Int iIndex3 = ItemToDisplayWpn.GetSize() While iIndex3 > 0 iIndex3 -= 1 If ItemToDisplayWpn.GetAt(iIndex3)<0 Debug.messagebox("Is Display Weapon") Else RemoveItem(akBaseItem, aiItemCount, false, akSourceContainer) EndIf EndWhile EndIf EndEvent_111BW_MstrContScript.psc(14,31): cannot compare a form to a int (cast missing or types unrelated)_111BW_MstrContScript.psc(23,34): cannot compare a form to a int (cast missing or types unrelated)_111BW_MstrContScript.psc(31,37): cannot compare a form to a int (cast missing or types unrelated)No output generated for _111BW_MstrContScript, compilation failed. Any Help Would Be ApreciatedBTW how do i get my code to hide? It's hard to help without knowing the lines that are giving the errors. But I think they must be these: If ItemToMann.GetAt(iIndex1)>=0 If ItemToDisplay.GetAt(iIndex2)<0 If ItemToDisplayWpn.GetAt(iIndex3)<0 Formlists are composed of forms (in your case, I'm assuming armor and other items). Formlist.GetAt() returns the form at that index, it doesn't return an integer. I'm also not sure what your goal is with the >=0 and <0. If you're trying to confirm that a form exists at that index, you can use:If FormlistX.GetAt(iIndex) or If FormlistX.GetAt(iIndex) != noneThey're the same. Though a formlist created in the CK shouldn't have a none entry if you're filling it with base objects (which I assume you're doing). If you're trying to compare the form in the formlist to akBaseItem, you can do:If FormlistX.GetAt(iIndex) == akBaseItemYou can avoid the while loop by writing:int iIndex = FormlistX.Find(akBaseItem) If iIndex != -1 ; do what you need to do EndIfBut I'm not sure why you need to get the index of the form in the formlist since you've already confirmed that the item is in the form with FormlistX.HasForm(akBaseItem). Link to comment Share on other sites More sharing options...
cavbirdie Posted March 3, 2015 Author Share Posted March 3, 2015 (edited) Thank you Thank youThank you Ive been adding and removing code to try to make it work... and your longest solution made my code half as long... now i have to figure out if there is a way to do something like... is on formlist 1 at number 10 remove to Actor listed on formlist 2 at number 10? ive been trying to find how to do that so thats why i was trying to bas it on the iIndex Edited March 3, 2015 by cavbirdie Link to comment Share on other sites More sharing options...
jayne2132 Posted March 3, 2015 Share Posted March 3, 2015 On 3/3/2015 at 3:22 AM, cavbirdie said: Ive been adding and removing code to try to make it work. is there a way to do something like is on formlist 1 at number 10 remove to container listed on formlist 2 at number 10? ive been trying to find how to do that so thats why i was trying to bas it on the iIndex Ah that makes sense then. You can use the Find function for that.Objectreference ItemContainer int iIndex = Formlist1.Find(akBaseObject) If iIndex != -1 ItemContainer = Formlist2.GetAt(iIndex) Else ; actions if object not in formlist1 EndIfAnd a tip -- if you want to optimize for speed, arrays are faster than formlists in papyrus. You can transfer your formlists to arrays when your script starts. The drawback is that there's no Find() function for arrays, so you'd have to iterate the array (like you were doing with the formlist above in the While loop) to find the baseobject. This would still be faster than using formlists. Link to comment Share on other sites More sharing options...
sLoPpYdOtBiGhOlE Posted March 3, 2015 Share Posted March 3, 2015 Myself I'd sync it all to property arrays. Here's a crude example of what I mean.The first example is so you can see what's what to get the idea of it.The Second example is the same thing but you'd fill the properties in the CK:ScriptName _111BW_MstrContScript extends ObjectReference Actor Property PlayerRef Auto FormList Property ItemToDisplay Auto FormList Property ItemToDisplayWpn Auto FormList Property ItemToMann Auto ObjectReference Property ItemCont Auto ;Assign this to your Display Item container ObjectReference Property WpnCont Auto ;Assign this to your Display Weapon container ObjectReference Property MannCont Auto Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) ;I'm only setting these arrays like this so you can see what's in them, you would fill the array properties in CK and remove the array assignment from here. Formlist[] FL = New Formlist[3] FL[0] = ItemToDisplay FL[1] = ItemToDisplayWpn FL[2] = ItemToMann String[] Msg = New String[3] Msg[0] = "Is Display Item" Msg[1] = "Is Display Weapon" Msg[2] = "Is Mannequin Item" ObjectReference[] Cont = New ObjectReference[3] Cont[0] = ItemCont Cont[1] = WpnCont Cont[2] = MannCont Int i = 0 Int j Bool bFound = False While i < FL.Length ;Loop through each formlist j = FL[i].Find(akBaseItem) ; Check if the akBaseItem is in the formlist If j >= 0 ;We have found an item in a list, tell what type of item it is. Debug.Notification(Msg[i] + " and it's name is: " + akBaseItem.GetName() + " and it's index in the list is: " + j) ;Put the item in it's matching container Self.RemoveItem(akBaseItem, aiItemCount, false, Cont[i]) ;When we exit the loop we'll know that the item was found and moved to another container. bFound = True ;Since I assume each list does not contain items from another list, I don't need to look any further, exit the loop. i = FL.Length EndIf i += 1 EndWhile ;If this is false then no items were found in any lists, so we return the item to what ever container put it here. If !bFound Self.RemoveItem(akBaseItem, aiItemCount, false, akSourceContainer) EndIf EndEvent2nd example cleaned up:ScriptName _111BW_MstrContScript extends ObjectReference Formlist[] Property FL Auto ;In CK assign your formlists. String[] Property Msg Auto ;In CK assign you Messages, the index of the message should match the index of your formlist. ObjectReference[] Property Cont Auto ;In CK assign your containers, each container should match the same index as your Forlist and Message Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) Int i = 0 Int j Bool bFound = False While i < FL.Length j = FL[i].Find(akBaseItem) If j >= 0 Debug.Notification(Msg[i] + " and it's name is: " + akBaseItem.GetName() + " and it's index in the list is: " + j) Self.RemoveItem(akBaseItem, aiItemCount, false, Cont[i]) bFound = True i = FL.Length EndIf i += 1 EndWhile If !bFound Self.RemoveItem(akBaseItem, aiItemCount, false, akSourceContainer) EndIf EndEvent Link to comment Share on other sites More sharing options...
sLoPpYdOtBiGhOlE Posted March 3, 2015 Share Posted March 3, 2015 (edited) On 3/3/2015 at 3:46 AM, jayne2132 said: On 3/3/2015 at 3:22 AM, cavbirdie said: Ive been adding and removing code to try to make it work. is there a way to do something like is on formlist 1 at number 10 remove to container listed on formlist 2 at number 10? ive been trying to find how to do that so thats why i was trying to bas it on the iIndex Ah that makes sense then. You can use the Find function for that.Objectreference ItemContainer int iIndex = Formlist1.Find(akBaseObject) If iIndex != -1 ItemContainer = Formlist2.GetAt(iIndex) Else ; actions if object not in formlist1 EndIfAnd a tip -- if you want to optimize for speed, arrays are faster than formlists in papyrus. You can transfer your formlists to arrays when your script starts. The drawback is that there's no Find() function for arrays, so you'd have to iterate the array (like you were doing with the formlist above in the While loop) to find the baseobject. This would still be faster than using formlists. There is find function for arrays and I use it often.Arrays vs form lists really they both have pros and cons.Using them combined can break a lot of limitations that one or the other has. Array's you can not initialize an array with a int variable, which means you can't dynamically assign the size of an array on the fly at runtime.eg:int i = 49ObjectReference[] MyObjects = New ObjectReference This will not work, so if your trying to use the count of something to set the size of an array then nope.Well if you use SKSE 1.7.2 then you can actually initialize the size of an array using a variable. You can not store an array in an array, which makes formlists handy. You can not set the size of an array greater then 128eg:ObjectReference[] MyObjects = New ObjectReference[266]Will fail, yet you can actually declare an array property and fill it in CK to any size from what I tested.Once again SKSE 1.7.2 breaks that limitation. No mixed form types in arrays. Formlists don't seem to have a limit on the Size, I often have formlists with more the 15000 entries. I can stick formlists in arrays and loop through forms very easily. A formlist can contain multiple types of forms so I don't need a different formlist just because I want multiple types of items in a list. Edited March 3, 2015 by sLoPpYdOtBiGhOlE Link to comment Share on other sites More sharing options...
cavbirdie Posted March 3, 2015 Author Share Posted March 3, 2015 attempting to figure out how to do arrays... the only script i have found so far only works with arrays so it makes sense to use them (esp if the work better anyway) Link to comment Share on other sites More sharing options...
sLoPpYdOtBiGhOlE Posted March 3, 2015 Share Posted March 3, 2015 It's not a case that they work better, it's a case of what your trying to accomplish.An array can be just as slow if you have to loop through all elements while calling functions on each element or if you have multiple different types of items.It really depends on what your trying to do. Your formlists, how many items does each one contain? Does you formlist contain more then one type of item?eg: Armor and Weapons in 1 list (Shield is Armor, Sword is Weapon, so say you want to put stuff on a 3 piece plaque)An array can only be declared as 1 type, but you can cast back and forth between types as needed in some instances. Are you filling the formlists at runtime or are you filling the list in ck and they never change? Did you understand what a property array is and how to fill it in CK? (Like what I posted in my example)? Link to comment Share on other sites More sharing options...
Terra Nova Posted March 3, 2015 Share Posted March 3, 2015 (edited) On 3/3/2015 at 3:46 AM, jayne2132 said: On 3/3/2015 at 3:22 AM, cavbirdie said: Ive been adding and removing code to try to make it work. is there a way to do something like is on formlist 1 at number 10 remove to container listed on formlist 2 at number 10? ive been trying to find how to do that so thats why i was trying to bas it on the iIndex Ah that makes sense then. You can use the Find function for that.Objectreference ItemContainer int iIndex = Formlist1.Find(akBaseObject) If iIndex != -1 ItemContainer = Formlist2.GetAt(iIndex) Else ; actions if object not in formlist1 EndIfAnd a tip -- if you want to optimize for speed, arrays are faster than formlists in papyrus. You can transfer your formlists to arrays when your script starts. The drawback is that there's no Find() function for arrays, so you'd have to iterate the array (like you were doing with the formlist above in the While loop) to find the baseobject. This would still be faster than using formlists. There is a find function for arrays. myArray.Find and myArray.rFind Find starts at 0 indexrFind starts at the last index Many people don't know about it because it was implemented in I think the 1.7 patch, back when arrays were less commonly used. Formlists are slower and can have added forms be persistent. But there is no limit to how many you can have in a list(but it will get progressively slower), unlike arrays and their 128 cap(can be extended, but takes a bit of work). http://www.creationkit.com/Arrays_%28Papyrus%29 scroll down for more info on the Find function. Edited March 3, 2015 by Terra Nova Link to comment Share on other sites More sharing options...
jayne2132 Posted March 3, 2015 Share Posted March 3, 2015 Thanks Terra Nova! That's great to learn. Going to shorten my scripts quite a bit. :) Link to comment Share on other sites More sharing options...
Recommended Posts