-
Notifications
You must be signed in to change notification settings - Fork 1
Using The Library — No Mod Launcher
There are times when you need to make bulk edits to Pure3D files, or need to easily extract data from them. Doing this is easier outside of the mod launcher.
All the tutorials on this page assume that your script has the library loaded, as explained in Getting Started.
An example I've personally used this for, is to get the Composite Drawable
name for every character in the game.
Given that we already have DirectoryGetEntries
from the mod launcher, we can use this to iterate a directory and get all the files in that directory. I created a little helper function to do so:
-- Helper function to process a directory and get all files of a certain extension
local function ProcessDir(Path, Files, Ext)
-- Convert the extension to lowercase for case-insensitive matching
Ext = Ext:lower()
-- Begin iterating the directory
DirectoryGetEntries(Path, function(File, IsDirectory)
if IsDirectory then
-- If a directory is found, call the same function to process sub directories
ProcessDir(string.format("%s/%s", Path, File), Files, Ext)
else
-- Get the file's extension, if it has one and it equals the extension filter, add the file path to the `Files` table.
local ext = GetFileExtension(File)
if ext and ext:lower() == Ext then
Files[#Files + 1] = string.format("%s/%s", Path, File)
end
end
return true
end)
end
-- Get all P3D files in the chars folder
local files = {}
ProcessDir("C:\\SHAR\\art\\chars", files, ".p3d")
Now that we have the chars file list, we can run each file through LuaP3DLib to get access to all the chunk data in the file.
-- Iterate the chars list
for i=1,#files do
local file = files[i]
-- Create a `P3DFile` for the file
local P3DFile = P3D.P3DFile(file)
-- Get the first Composite Drawable chunk
local CompositeDrawable = P3DFile:GetChunk(P3D.Identifiers.Composite_Drawable)
-- Check if the chunk was found - `GetChunk` returns `nil` if not found
if CompositeDrawable then
-- Print the filename and the name of the Composite Drawable to console
print(file, CompositeDrawable.Name)
end
end
There are no file write functions in the mod launcher at this time, so if you want to programatically modify Pure3D files, it has to be done externally. One example of this is to remove all chunks of a type. For this tutorial, we'll use locators.
Using the function in the previous step, we can get all the Pure3D files by calling the function on the art
folder.
-- Get all P3D files in the art folder
local files = {}
ProcessDir("C:\\SHAR\\art", files, ".p3d")
Similar to the last step, we now loop each file and run it through LuaP3DLib. However, this time, we're going to modify the file.
-- Iterate the files list
for i=1,#files do
local file = files[i]
-- Create a `P3DFile` for the file
local P3DFile = P3D.P3DFile(file)
-- Create a variable to check if the file was modified. No point saving an unchanged file.
local modified = false
-- Loop all Locator chunks in the file, using `true` as the second parameter so that we loop backwards
-- Specifically when removing chunks is this necessary
for ChunkIndex, Chunk in P3DFile:GetChunksIndexed(P3D.Identifiers.Locator, true) do
-- Here you could run a check on any chunk data, in the case of a Locator you could check the Type or Name for example
P3DFile:RemoveChunk(ChunkIndex) -- `RemoveChunk` takes either an index or a chunk itself, however index is more efficient
-- We found at Locator chunk, so the file has been modified
modified = true
end
-- If the file is modified, save it with `.modified` appended to the filename
if modified then
local fileName = file:gsub("%.p3d", ".modified.p3d")
-- Open the filepath as `wb`. `w` means we're writing the file, without appending, so existing files will be overwritten. `b` means we're writing binary data, not just plain strings
local outFile = io.open(fileName, "wb")
-- Calling `tostring` on a `P3DFile` builds the Pure3D data
outFile:write(tostring(P3DFile))
-- Make sure you close your file handlers
outFile:close()
end
end