Hey all!
Been plugging away at a script for the better part of a day now. This is maybe my 6th script ever, maybe my second biggest. I've managed to, with additional NVSE libraries, cut some 12000 characters of code outta this, and got it down to all but two errors. These two errors though! At this point I'm completely lost as to what's wrong, because NVSE error offsets are not helpful to me in the slightest in debugging. I'm hoping someone well-versed in NVSE will save the day!
The lowdown: I'm running the 4GB launcher, using NVSE latest beta 5.0b2. Heavily used Let and different kinds of X= operators like -= and +=. I'm using Lutana's NVSE plugin and JIP's NVSE plugin. Also got GeckPU installed for working with the GECK. (because who the hell could code in this nightmare language without a damn compiler telling you when you're wrong!) (Only in this case, it's letting me compile, but failing!
The mod works like this:
There's a quest script storing some uninitialized arrays, and a scant few ints and refs. All references of these are using correct QuestID.var syntax, I believe.
You get a misc item (a 'SortPipe', one of only 3 items in added in the mod), and place it in a container. The pipe increments a global count when you add it to something (So I know for later in development how many pipes you have out there.) You can have as many as you want as far as I've worked out. If you have an item called a Pipe Blocker, you can stop the mod from recording the container it's in.
'Pipes? The hell is he on about?'
So, you activate the 'Pneumatic Sender' (Activator with OnActivate Object script - below). It starts the global variable Quest (and ends it on completion, keeping the rest of the game as lag-free as possible) initializes all the arrays. It then uses 'GetFormRefs' from Lutana to grab all references of the SortPipe and stores them in an array. (Lords know I may have completely misunderstood that function and thus my mod is entirely ineffectual because of it, but no compile errors! :/)
It then should (but doesn't seem to) grab the first pipe's container, catalogue its contents, then 'removeitemtarget' (from JIP) - removing items from your inventory based on a formlist, that very list being constructed earlier as the contents of a container. Clear the list. Loop this process for all containers you've got pipes in. Round it out by nulling all arrays to keep memory usage low, kill the Quest, end script.
Fluff-and-Lore-wise, you install a pipe and some funky electronics into a container in your home. Then after a long day of stuffing lead into Legion-And-Mutant faces alike, you dump all your hoarded looty goodness into a stolen modified Mojave Express postbox (there will be a quest for it if I get it all working), and it sends those items shooting through your location (technically all across the gameworld if it needs to) and into those containers. Intuitive, one-way autosorting, where you designate what you want to sort by already having at least one of the item in a container. Seemed super clever to me 14hrs ago, but I dunno if I'm gonna sleep tonight! These errors, man!
I can't, for the life of me, figure out two error codes that I seem to be getting, however! I also seem to not be loading JIP or PU correctly in-game, yet it seems to load fine in NVSE-run GECK... If anyone can shed light on THAT, that'd be a great start!
http://pastebin.com/XhwhYF0V
Aside from the potential problems with loading of the plugins (I'm not 100% that's the problem) I'm damn sure it's my code giving off these two Offset errors - both failures to evaluate valid results.
Here's the main code:
scn BalPackPneumaticSenderScriptbegin OnActivate StartQuest BalPackSortPipeVariableQuest int LoopCounter int ArraySize int ContainerCount int ItemCount ref rItemToAdd ref rContainer ref rPipeName array_var ar_entry ; ALIGN THE ARRAYS. BRING SAJUUK TO BEAR. let BalPackSortPipeVariableQuest.PipeLocArray1 := ar_construct array ; Pre-emptive null and rebuild of each array to prevent having to do so to start fresh. let BalPackSortPipeVariableQuest.PipeLocArray2 := ar_construct array let BalPackSortPipeVariableQuest.PipeLocArray3 := ar_construct array let BalPackSortPipeVariableQuest.PipeLocArray4 := ar_construct array let BalPackSortPipeVariableQuest.PipeLocArray5 := ar_construct array let BalPackSortPipeVariableQuest.PipeRefs := ar_construct array let ar_entry := ar_construct array let LoopCounter := -1 ; Oh so important, the precious loop counter. let BalPackSortPipeVariableQuest.PipeRefs := GetFormRefs BalPackSortPipe ; Gets all SortPipe references, stores in global array. let ArraySize:= ar_Size BalPackSortPipeVariableQuest.PipeRefs while LoopCounter < ArraySize let LoopCounter += 1 ; increment the loop! let rPipeName := BalPackSortPipeVariableQuest.PipeRefs[LoopCounter] ; grabs the first/next pipe in the above array. if rPipeName == 0 ; If rPipeName is null, this should break the loop instead of persisting any further. (NOT SURE IF THIS IS WORKING) Break endif let rContainer := rPipeName.GetContainer ; get above pipe's container if rContainer != Player ; if it's NOT the player if (rContainer.GetItemCount BalPackPipeBlocker) < 1 ; if it's NOT got a blocker inside if LoopCounter < 21 ; if the loop (and thus the pipe used) is LESS than 21 ar_append BalPackSortPipeVariableQuest.PipeLocArray1 rContainer ; add the container to the end of BalPackSortPipeVariableQuest.PipeLocArray1 elseif (LoopCounter > 20) && (LoopCounter < 41) ; ELSE, if it's between 21 and 40 inclusive ar_append BalPackSortPipeVariableQuest.PipeLocArray2 rContainer ; add the container to the end of BalPackSortPipeVariableQuest.PipeLocArray2 elseif (LoopCounter > 40) && (LoopCounter < 61) ; etc. ar_append BalPackSortPipeVariableQuest.PipeLocArray3 rContainer ; etc - BalPackSortPipeVariableQuest.PipeLocArray3 elseif (LoopCounter > 60) && (LoopCounter < 81) ; etc. ar_append BalPackSortPipeVariableQuest.PipeLocArray4 rContainer ; etc - BalPackSortPipeVariableQuest.PipeLocArray4 elseif LoopCounter > 80 ; etc. ar_append BalPackSortPipeVariableQuest.PipeLocArray5 rContainer ; etc - BalPackSortPipeVariableQuest.PipeLocArray5 endif endif ; the above array if-then statement may not be necessary if arrays can simply be appended to infinitely... endif ; if that were the case, it'd be a simple matter of removing all of the if-then array statement and all but one of the global arrays. loop ; this would make the system infinitely expandable - within limits, maybe a hardcap to prevent lag? let ArraySize := ar_Size BalPackSortPipeVariableQuest.PipeLocArray1 ; These loop blocks combine each of the 5 arrays into one large array. If this is redundant, and I could, say let LoopCounter := -1 ; just keep adding to the end of the same single array, I'm gonna feel very stupid. while LoopCounter < ArraySize let LoopCounter += 1 ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal BalPackSortPipeVariableQuest.PipeLocArray1[LoopCounter] loop let ArraySize := ar_Size BalPackSortPipeVariableQuest.PipeLocArray2 let LoopCounter := -1 while LoopCounter < ArraySize let LoopCounter += 1 ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal BalPackSortPipeVariableQuest.PipeLocArray2[LoopCounter] loop let ArraySize := ar_Size BalPackSortPipeVariableQuest.PipeLocArray3 let LoopCounter := -1 while LoopCounter < ArraySize let LoopCounter += 1 ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal BalPackSortPipeVariableQuest.PipeLocArray3[LoopCounter] loop let ArraySize := ar_Size BalPackSortPipeVariableQuest.PipeLocArray4 let LoopCounter := -1 while LoopCounter < ArraySize let LoopCounter += 1 ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal BalPackSortPipeVariableQuest.PipeLocArray4[LoopCounter] loop let ArraySize := ar_Size BalPackSortPipeVariableQuest.PipeLocArray5 let LoopCounter := -1 while LoopCounter < ArraySize let LoopCounter += 1 ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal BalPackSortPipeVariableQuest.PipeLocArray5[LoopCounter] loop ;foreach ar_entry <- BalPackSortPipeVariableQuest.PipeLocArray1 ; For each item in BalPackSortPipeVariableQuest.PipeLocArray1, add all to ar_entry as 'key' and 'value' ; ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal ar_entry["value"] ; Append to PipeLocArrayFinal each entry. ;loop ;foreach ar_entry <- BalPackSortPipeVariableQuest.PipeLocArray2 ; Rinse and repeat for each array into the final array. ; ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal ar_entry["value"] ;loop ;foreach ar_entry <- BalPackSortPipeVariableQuest.PipeLocArray3 ; DON'T KNOW IF WORKS, TAKEN OUT IN FAVOR OF ABOVE LOOPS. ; ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal ar_entry["value"] ; This was the original attempt at above array combining - don't know if it worked, but the above ;loop ; gives quite a few less errors than this. ;foreach ar_entry <- BalPackSortPipeVariableQuest.PipeLocArray4 ; ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal ar_entry["value"] ;loop ;foreach ar_entry <- BalPackSortPipeVariableQuest.PipeLocArray5 ; ar_append BalPackSortPipeVariableQuest.PipeLocArrayFinal ar_entry["value"] ;loop ;We SHOULD have a single array of up to 100 containers now. Time to catalogue their contents into individual Formlists. let ContainerCount := -1 ; Starting at Container 1 means starting the count at -1. The loop adds 1 to make it 0, which is the first entry in an array. let ArraySize := ar_Size BalPackSortPipeVariableQuest.PipeLocArrayFinal while ContainerCount < ArraySize let ContainerCount += 1 ; Increment all the things. let rContainer := BalPackSortPipeVariableQuest.PipeLocArrayFinal[ContainerCount] ; sets rContainer to the first/next container that contains a pipe. if rContainer == 0 ; if rContainer returns null, it means there's no more containers, as we've been adding incrementally. (NOT SURE IF THIS IS WORKING) Break ; if it breaks here, it's fine, because the array's empty from here on. endif let ItemCount := rContainer.GetNumItems ; For Counting Purposes - set to total items in given container. while ItemCount > 0 let ItemCount -= 1 ; Decrement - first item is 0. let rItemToAdd := rContainer.GetInventoryObject ItemCount ; Gets the first/next item in the container. (THIS TOOK ME FOREVER TO FIGURE OUT) ListAddForm BalPackSortPipeItemFormList rItemToAdd ; Adds it to the temporary Item FormList for later extraction with removeitemtarget. loop ListRemoveForm BalPackSortPipeItemFormList BalPackPipeBlocker ListRemoveForm BalPackSortPipeItemFormList BalPackSortPipe player.removeitemtarget BalPackSortPipeItemFormList rContainer ListClear BalPackSortPipeItemFormList loop let BalPackSortPipeVariableQuest.PipeLocArray1 := ar_Null let BalPackSortPipeVariableQuest.PipeLocArray2 := ar_Null let BalPackSortPipeVariableQuest.PipeLocArray3 := ar_Null let BalPackSortPipeVariableQuest.PipeLocArray4 := ar_Null let BalPackSortPipeVariableQuest.PipeLocArray5 := ar_Null let BalPackSortPipeVariableQuest.PipeRefs:= ar_Null StopQuest BalPackSortPipeVariableQuestend
Yeesh. Copy/paste it to a text doc and turn off wordwrap so the comments don't butcher its formatting. :pSo yea
I run it secondlast in my load order, short of a Weather mod - plus it's all brand new content, so there's absolutely 0% chance it's a mod conflict or other mod error. I summon a Pneumatic Sender, summon some SortPipes, add them to containers with things in them, make sure I have things of the same base object in my inventory, and then activate the Pneumatic Sender. It presents the error offsets in the log above.
I'm damn certain it's my code - I've gotten mad sloppy SOMEWHERE. Please let me know if you work out my problem, and/or any advice you can offer to a fledgling modder!
If I can give you any more info, any logs or implement any debugging output code to CREATE logs, PLEASE let me know. I'd be happy to even send you the ESP - no DLC required, just the main New Vegas ESM, no other mods (save JIP/Lutana/NVSE/4GB)