AndalayBay Posted August 12, 2022 Share Posted August 12, 2022 (edited) NOTICE: shadeMe changed the way background scripts work since these scripts were written. They no longer work. Previously a background script kept running until it was terminated with return(0,1). That is no longer the case. Now background scripts terminate with a simple return statement, just like foreground scripts. I have replaced the script with the new version. First, if you aren't familiar with Coda, I suggest you check out the introduction here. This thread will provide Coda scripts for a variety of tasks. Many of these scripts will walk through an array of cells in which a particular object has been placed. My main use of this function is to ground floating trees and rocks in exterior cells. Get List of Cells for Object CODA(GetUsage) var cellUsage var baseObject var instance ; list all cells where object has been placed begin baseObject = getFormByEditorID("BMSwampRose01") cellUsage = GetCellUseList(baseObject) foreach instance <- cellUsage printC("Cell "//$instance) loop end Save this script as GetUsage.coda in Data\BGSEE\Coda. This script assumes that the specified object has been instantiated at least once. It produces a list like this: [CSE] Cell 01011EEF [CSE] Cell 01011EF1 [CSE] Cell 0100237F [CSE] Cell 01002395 [CSE] Cell 010037CB [CSE] Cell 010037CE [CSE] Cell 01011F0B [CSE] Cell 010024B3 [CSE] Cell 0103658A [CSE] Cell 010036DC [CSE] Cell 010369FB ... If you want the list of cell forms to use in another script, just remove "Cell "// from the printC statement in the script above, so it's printC($instance) instead. Now that we have a list of cells for the object we want to fix, we'll copy that list into an array in the next script. If you remove "Cell " from the print statement so you just get a list of form ID's, then you can use this regular expression to convert the list of form ID's into arAppend statements that are used in the script below: Find: ([0-9A-F]{8}) Replace: arAppend\(arCells, GetFormByFormID\(0x$1\)\) Make sure Regular Expression is checked off in the search/replace dialogue box. Grounding Floating Trees There are some commands in Coda that require the object be loaded into the Render Window. If that's the case, you'll find "The parameter reference needs to be loaded in the render window." next to the command in the Coda command documentation. Since that takes time, the script is run in the background. This script uses the FloorRef command, which is one such case. This script will also add a random rotation. If you don't need that, just remove the SetRefRotation command. The full script needed an array with 1550 elements. I will truncate the array in the code below since you'll have to replace it with the list of cells for the object you are fixing. Also shadeMe has deprecated the ArrayInsert command. Now it's arAppend which will expand the size of the array as required so we just set the size to 1 when we create the array. CODA(MoveTrees, "2.0") ; This must be run as a background script. Set polling interval to 2 seconds. var arCells var cell var objectRef var baseToComp var currHeight var newHeight var randomNum var treesMoved var waiting var doOnce var cellCounter var arRefs var arSz begin if (doOnce == 0) ; since this is a background script, make sure the init phase happens only once arCells = ArrayCreate (1) arAppend(arCells, GetFormByFormID(0x010364F3)) arAppend(arCells, GetFormByFormID(0x01011EE3)) arAppend(arCells, GetFormByFormID(0x01011EE5)) ; rest of arAppend statements as needed baseToComp = getFormByEditorID("BMEmpParasolSmall01") waiting = 0 cellCounter = 0 treesMoved = 0 doOnce = 1 endIf if (waiting == 1) ; we waited last time and the cell should now be loaded in its entirety ; so off to the next state waiting = 2 endIf arSz = ArraySize(arCells) while cellCounter < arSz cell = arCells[cellCounter] arRefs = GetCellObjects(cell) if (ArraySize(arRefs)) if (waiting == 0) ; processing the cell for the first time, let's load it up LoadRefIntoRenderWindow(arRefs[0]) ; wait for a bit until it loads printC("waiting...") waiting = 1 break() elseIf (waiting == 2) ; cell is in a usable state, do stuff now printC("fixing refs...") ; list form ID of cell in case object needs adjustment ; some wound up underwater, so I moved them manually printC("Processing cell "//$arCells[cellCounter]) forEach objectRef <- arRefs if (GetRefBaseform(objectRef) == baseToComp) ; fix height and set rotation ; these trees are actually statics so we can rotate them randomNum = RandomNumber(0, 359) SetRefRotation(objectRef, "Z", randomNum) currHeight = getRefPosition(objectRef, "Z") ; we know they're floating, so don't need this line ; if they aren't, remove the semi-colon from the next line ;setRefPosition(objectRef, "Z", currHeight + 30000) floorRef(objectRef) newHeight = getRefPosition(objectRef, "Z") printC("Ref "//$objectRef//" - Old height: "//fmtNum("%0.4f", currHeight, 0)//", New height: "//fmtNum("%0.4f", newHeight, 0)) ; this sinks the object a bit ; change 15 to whatever you need for the depth the object should be sunk into the ground setRefPosition(objectRef, "Z", newHeight - 15) markAsModified(objectRef, 1) treesMoved += 1 endif loop ; this cell is done, on to the next waiting = 0 cellCounter += 1 endif else ; nothing in this cell, continue on cellCounter += 1 endif loop if (waiting == 0) printC($treesMoved//" trees moved.") ; remove the script from the background queue return(0, 1) endIf end Save this script as MoveTrees.coda in the Data\BGSEE\Coda directory. The file name does not have to match the name in the parentheses next to the Coda keyword at the top of the script. Since this is a background script, you have to specify a polling time, which was set to 2 seconds in this case. Once you've changed this script to suit your purposes, you run it with runCodaScript movetrees 1 in the Console Window command prompt. The runCodaScript command needs the file name, not the script name after the Coda declaration at the top of the script. Since this is a background script, the background parameter is set to 1 in the run script command. Lastly, note the return command at the end of the script to remove it from the background queue. The printC commands in the script can be removed if you wish. I use them to monitor running of the script. It might be a background script, but I don't attempt to do anything else while it's running... Edited January 27, 2023 by AndalayBay Replaced code with new version Link to comment Share on other sites More sharing options...
AndalayBay Posted August 12, 2022 Author Share Posted August 12, 2022 Here are the scripts I wrote for removing the VWD flag from objects placed in interior cells. These objects should not have the VWD flag set. Many of them were statics so I have no idea why the flag was set. First, here's the script to list the cells that have objects with the flag set: CODA(ListVWDInteriors) var cell var cellEditorID var firstChars var WS var wsTemp var object var vwd ; list Items in interiors with VWD set begin forEach cell <- getDataHandlerFormList(48) cellEditorID = GetEditorID(cell) firstChars = StringSubStr(cellEditorID, 0, 2) if (StringCompare(firstChars, "BM", 1) == 0) WS = getCellWorldspace(cell) wsTemp = fmtNum("%08X", WS, 1) if (wsTemp == "00000000") ;interior cell forEach object <- GetCellObjects(cell) vwd = GetRefVWD(object) if (vwd == 1) printC(cellEditorID//" - "//$object) endif loop endif endif loop printC("All done") end We had over 220 items. Fortunately I was able to flip the flag with Coda: CODA(FixVWDInteriors) var cell var cellEditorID var firstChars var WS var wsTemp var object var vwd ; list Items in interiors with VWD set begin forEach cell <- getDataHandlerFormList(48) cellEditorID = GetEditorID(cell) firstChars = StringSubStr(cellEditorID, 0, 2) if (StringCompare(firstChars, "BM", 1) == 0) WS = getCellWorldspace(cell) wsTemp = fmtNum("%08X", WS, 1) if (wsTemp == "00000000") ;interior cell forEach object <- GetCellObjects(cell) vwd = GetRefVWD(object) if (vwd == 1) printC(cellEditorID//" - "//$object) setRefVWD(object, 0) markAsModified(object, 1) endif loop endif endif loop printC("All done") end I have also created syntax definition files (UDL files) for Legacy (Oblivion's scripting language) and Coda for Notepad++. Please let me know if you would like a copy. I copied some of shadeMe's syntax definition from the CSE. Link to comment Share on other sites More sharing options...
AndalayBay Posted August 12, 2022 Author Share Posted August 12, 2022 Need help cluttering? This potential script could load a bookshelf. You'd need a loop that changes the coordinates so the books are placed next to one another and not in the same spot each time. Coda(PlaceBooks) var book var EditorID var bookEditorID var bookName var targetCell begin forEach book <- GetDataHandlerFormList(21) EditorID = GetEditorID(book) bookEditorID = StringSubStr(EditorID, 0, 10) if StringCompare(bookEditorID, "Book1Cheap", 1) == 0 printC("editorID ="//$EditorID) bookName = GetBFCFullName(book) printC("Name ="//bookName) targetCell = getFormByEditorID("DBCStrongholdLibrary") createRef(book, -917.0, 251.0, 12.0, -90.0, 196.0, 0.0, targetCell, targetCell) endif loop end The createRef command takes a worldspace form as the last parameter, but that's ignored for interior cells, so I just repeated the interior cell form to satisfy the command parameters. Link to comment Share on other sites More sharing options...
AndalayBay Posted November 15, 2022 Author Share Posted November 15, 2022 We need to fix some regions in Argonia so I just created these scripts to help. The first script lists all objects in a specific cell. Basically you give it the form ID for the cell, whether it's interior or exterior. List Objects in Cell coda(ListObjectsInCell) var cell var arObjects var objectRef var editorID var baseObj var arDistinct var distinctStr var found begin arDistinct = arCreate (150) ; Get objects for BlackMarshes 40,13 cell = GetFormByFormID(0x01036964) arObjects = GetCellObjects(cell) if (arSize(arObjects)) foreach objectRef <- arObjects baseObj = GetRefBaseform(objectRef) editorID = getEditorID(baseObj) if (arSize(arDistinct)) found = 0 foreach distinctStr <- arDistinct ; 0 = equal if (StringCompare(editorID, distinctStr, 1) == 0) found = 1 break() endif loop if found == 0 arAppend(arDistinct, editorID) endif else arAppend(arDistinct, editorID) endif loop foreach distinctStr <- arDistinct printC("Object: "//$distinctStr) loop endif end The second script lists the landscape textures in an exterior cell. You need to load the cell in the render window for it to print the textures. List Landscape Textures in Cell coda(ListLandscapeTexturesInCell) var cell var editorID var arTextures var texture var i begin ; Get landscape textures for BlackMarshes 40,13 ; Cell must be loaded into render window first cell = GetFormByFormID(0x01036964) i = 1 while (i < 5) arTextures = GetCellLandscapeTextures(cell, i) printC("Quad = "//$i) foreach texture <- arTextures editorID = getEditorID(texture) printC("Texture: "//$editorID) loop i += 1 loop end The previous scripts can be combined into one script. Here are the results: Quote Objects in 40,13 Object: BMrockeastcoast095 Object: BMrockeastcoast045 Object: BMrockeastcoast320 Object: BMFloraMarshmerrow03 Object: BMEmpParasol01 Object: BMLL1WildernessLAKEandDEEPWATER Object: BMFloraMarshmerrow01 Object: BMFloraFirefern01 Object: BMEmpParasolSmall01 Object: BMOldFinger02 Object: BMrockeastcoast255 Object: BMrockeastcoast1190 Object: BMrockeastcoast220 Object: BMrockeastcoast830 Object: BMEmpParasolLog01 Object: MshrmFlyAmanita02 Object: MshrmFlyAmanita04 Object: BMTreeBamboo1b Object: ShrubAzaleaSU Quad = 1.000000 Texture: BMEastMudMoss Texture: BMEastSiltMoss Texture: BMEastMudMoss Texture: BMEastRockMoss Texture: BMEastSiltMossNoGrass Quad = 2.000000 Texture: BMEastMudMoss Texture: BMEastSiltMoss Texture: BMEastMudMoss Texture: BMEastRockMoss Quad = 3.000000 Texture: BMEastMudMoss Texture: TerrainHDRock02 Texture: BMEastSiltMoss Texture: BMEastMudMoss Texture: BMEastRockMoss Texture: BMEastSiltMossNoGrass Quad = 4.000000 Texture: BMEastMudMoss Texture: TerrainHDRock02 Texture: BMEastSiltMoss Texture: BMEastMudMoss Texture: BMEastRockMoss Texture: BMEastSiltMossNoGrass Now I can add those to the Generated Objects list in a region. Link to comment Share on other sites More sharing options...
AndalayBay Posted January 27, 2023 Author Share Posted January 27, 2023 The MoveTrees script in the OP has been replaced. shadeMe changed how background scripts behave in a recent version of Coda so the old script doesn't work anymore. Link to comment Share on other sites More sharing options...
AndalayBay Posted November 14, 2023 Author Share Posted November 14, 2023 Here's a new script I created earlier. It will list the elements in a levelled list. It uses one of the BFC functions. CODA(ListLLEntries) var Form var arItems var Item var EditorID begin Form = getFormByEditorID("VendorAmmo") arItems = getBFCLeveledListEntries(Form) foreach Item <- arItems EditorID = getEditorID(Item[0]) printC("Item: "//$EditorID//" Level: "//formatNumber("%.0f",Item[1],0)//" Count: "//formatNumber("%.0f",Item[2],0)) loop end Just replace VendorAmmo with the editor ID of the levelled list you want to get the details for. Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now