Download CommonLua/ArtTest.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 18.2 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/ArtTest.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/CommonLua/ArtTest.lua
-
curl -L -o ArtTest.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/ArtTest.lua
18.2 kB
| --- | |
| --- Runs a real-time thread to change the map for the "ArtTest" context. | |
| --- | |
| --- This function is likely used for debugging or testing purposes, to quickly | |
| --- switch between different map configurations in the "ArtTest" context. | |
| --- | |
| function bat() -- debug function | |
| CreateRealTimeThread(ChangeMap, "ArtTest") | |
| end | |
| --- | |
| --- Gets the lowercase version of the project name. | |
| --- | |
| --- @return string The lowercase project name. | |
| --- | |
| local project_name = string.lower(const.ProjectName) | |
| --- | |
| --- Defines paths to various asset directories and files used in the ArtTest context. | |
| --- | |
| --- @class path | |
| --- @field assets table A table containing paths to asset directories. | |
| --- @field assets.root string The root directory for assets. | |
| --- @field assets.entities string The directory for entity assets. | |
| --- @field assets.art_producer_lua string The path to the CurrentArtProducer.lua file. | |
| --- @field assets.exporter string The directory for the HGExporter. | |
| --- @field assets.entity_producers_lua string The path to the EntityProducers.lua file. | |
| --- @field max table A table containing paths to 3DS Max related files and directories. | |
| --- @field max.root string The root directory for 3DS Max scripts. | |
| --- @field max.startup string The path to the HGExporterUtility startup script. | |
| --- @field max.exporter string The directory for the HGExporter scripts. | |
| --- @field max.exporter_startup string The path to the HGExporterUtility startup script in the exporter directory. | |
| --- @field max.art_producer_ms string The path to the CurrentArtProducer.ms file in the exporter directory. | |
| --- @field max.grannyexp_ini string The path to the grannyexp.ini file in the exporter directory. | |
| --- | |
| local path = {} | |
| path.assets = {} | |
| path.assets.root = GetExecDirectory() .. "Assets/" | |
| path.assets.entities = path.assets.root .. "Bin/Common/Entities/" | |
| path.assets.art_producer_lua = path.assets.root .. "CurrentArtProducer.lua" | |
| path.assets.exporter = path.assets.root .. "HGExporter/" | |
| path.assets.entity_producers_lua = path.assets.root .. "Spec/EntityProducers.lua" | |
| path.max = {} | |
| path.max.root = "AppData/../../Local/Autodesk/3dsmax/2019 - 64bit/ENU/scripts/" | |
| path.max.startup = path.max.root .. "startup/HGExporterUtility_" .. project_name .. ".ms" | |
| path.max.exporter = path.max.root .. "HGExporter_" .. project_name .. "/" | |
| path.max.exporter_startup = path.max.exporter .. "Startup/HGExporterUtility.ms" | |
| path.max.art_producer_ms = path.max.exporter .. "CurrentArtProducer.ms" | |
| path.max.grannyexp_ini = path.max.exporter .. "grannyexp.ini" | |
| local atprint = CreatePrint({ | |
| "ArtPreview", | |
| format = "printf", | |
| }) | |
| ArtTest = { } | |
| --- | |
| --- Opens a dialog to allow the user to choose a new art producer, then sets the new producer and updates the corresponding Lua and Max Script files. | |
| --- | |
| --- @function ArtTest.OpenChangeProducerDialog | |
| function ArtTest.OpenChangeProducerDialog() | |
| local producers = table.icopy(ArtSpecConfig.EntityProducers) | |
| table.insert(producers, 1, "Any") | |
| local new_producer = WaitListChoice(terminal.desktop, producers, "Choose art producer:", 1) | |
| ArtTest.SetProducer(new_producer or "Any") | |
| CreateRealTimeThread(ChangeMap, "ArtTest") | |
| end | |
| --- | |
| --- Sets the new art producer and updates the corresponding Lua and Max Script files. | |
| --- | |
| --- @param new_producer string The new art producer to set. | |
| --- | |
| function ArtTest.SetProducer(new_producer) | |
| if not new_producer then | |
| return | |
| end | |
| atprint("Setting new art producer %s", new_producer) | |
| -- set producer | |
| rawset(_G, "g_ArtTestProducer", new_producer) | |
| AsyncCreatePath(path.assets.root) | |
| -- write to Lua file for the game | |
| local lua_content = string.format("return \"%s\"", new_producer) | |
| AsyncStringToFile(path.assets.art_producer_lua, lua_content) | |
| -- write to Max Script file for the exporter | |
| local ms_content = string.format("global g_ArtTestProducer = \"%s\"", new_producer) | |
| AsyncStringToFile(path.max.art_producer_ms, ms_content) | |
| local os_path_assets = ConvertToOSPath(path.assets.root) | |
| if string.ends_with(os_path_assets, "\\") then | |
| os_path_assets = string.sub(os_path_assets, 1, #os_path_assets - 1) | |
| end | |
| ArtTest.InstallMaxExporter() | |
| end | |
| --- | |
| --- Sets the new art producer and updates the corresponding Autodesk 3DS Max exporter configuration. | |
| --- | |
| --- This function is responsible for configuring the Autodesk 3DS Max exporter by updating the `grannyexp.ini` file with the correct assets path. It first checks if the game is run with the `-globalappdirs` command line parameter, which is required for the exporter to function properly. If the parameter is not present, it prints a warning message and returns. | |
| --- | |
| --- The function then retrieves the OS-specific path for the assets root directory and checks if it ends with a backslash. If so, it removes the trailing backslash. | |
| --- | |
| --- Next, the function checks if the `grannyexp.ini` file exists. If it does, it reads the file and updates the `assetsPath` setting with the correct assets path. If the file does not exist, it creates a new `grannyexp.ini` file with the assets path. | |
| --- | |
| --- @param new_producer string The new art producer to set. | |
| --- | |
| function ArtTest.SetProducer_3DSMax(new_producer) | |
| if not new_producer then | |
| return | |
| end | |
| local globalappdirs = string.match(GetAppCmdLine() or "", "-globalappdirs") | |
| if not globalappdirs then | |
| atprint( | |
| "Please run the game with the -globalappdirs command line parameter to install/update the Autodesk 3DS Max exporter") | |
| return | |
| end | |
| local os_path_assets = ConvertToOSPath(path.assets.root) | |
| if string.ends_with(os_path_assets, "\\") then | |
| os_path_assets = string.sub(os_path_assets, 1, #os_path_assets - 1) | |
| end | |
| if io.exists(path.max.grannyexp_ini) then -- TODO proper ini handling | |
| local err, ini = AsyncFileToString(path.max.grannyexp_ini) | |
| local first, last = string.find(ini, "assetsPath=.*\n") | |
| if first and last and first <= last then | |
| ini = string.format("%sassetsPath=%s%s", string.sub(ini, 1, first), os_path_assets, | |
| string.sub(ini, last - 1)) | |
| else | |
| ini = string.format("%s\n[Directories]\nassetsPath=%s", ini, os_path_assets) | |
| end | |
| else | |
| local ini = string.format("[Directories]\nassetsPath=%s", os_path_assets) | |
| AsyncStringToFile(path.max.grannyexp_ini, ini) | |
| end | |
| end | |
| --- | |
| --- Installs the Autodesk 3DS Max exporter by creating the necessary folder structure and copying the exporter files. | |
| --- | |
| --- This function first checks if the game is run with the `-globalappdirs` command line parameter, which is required for the exporter to function properly. If the parameter is not present, it prints a warning message and returns. | |
| --- | |
| --- The function then creates the folder structure where the exported entities will be stored, including the `Bin/`, `Bin/Common/`, and other subfolders. | |
| --- | |
| --- Next, the function copies the exporter folder structure from the `path.assets.exporter` directory to the `path.max.exporter` directory. It skips any folders or files that contain `.svn`. | |
| --- | |
| --- Finally, the function copies the exporter startup file from `path.max.exporter_startup` to `path.max.startup`, and calls `ArtTest.SetProducer_3DSMax()` with the current art producer. | |
| --- | |
| --- @return nil | |
| function ArtTest.InstallMaxExporter() | |
| local globalappdirs = string.match(GetAppCmdLine() or "", "-globalappdirs") | |
| if not globalappdirs then | |
| atprint( | |
| "Please run the game with the -globalappdirs command line parameter to install/update the Autodesk 3DS Max exporter") | |
| return | |
| end | |
| -- crate assets folder structure (where entities will be exported) | |
| local structure = {"Bin/", "Bin/Common/", "Bin/Common/Animations", "Bin/Common/Entities", "Bin/Common/Mapping", | |
| "Bin/Common/Materials", "Bin/Common/Meshes", "Bin/Common/TexturesMeta", "Bin/win32/", "Bin/win32/Textures", | |
| "Bin/win32/Fallbacks", "Bin/win32/Fallbacks/Textures"} | |
| for i, subpath in ipairs(structure) do | |
| local full_path = path.assets.root .. subpath | |
| local os_path = ConvertToOSPath(full_path) | |
| local err = AsyncCreatePath(os_path) | |
| if err then | |
| atprint("Failed creating exporter target folder structure - %s", err) | |
| return | |
| end | |
| end | |
| -- copy exporter folder structure | |
| local err, folders = AsyncListFiles(path.assets.exporter, "*", "recursive,relative,folders") | |
| if err then | |
| atprint("Failed listing Autodesk 3DS Max exporter folder structure - %s", err) | |
| return err | |
| end | |
| local os_path = ConvertToOSPath(path.max.exporter) | |
| local err = AsyncCreatePath(os_path) | |
| if err then | |
| atprint("Failed copying Autodesk 3DS Max exporter folder structure - %s", err) | |
| return err | |
| end | |
| for _, folder in ipairs(folders) do | |
| if not string.find(folder, ".svn") then | |
| local os_path = ConvertToOSPath(path.max.exporter .. folder) | |
| local err = AsyncCreatePath(os_path) | |
| if err then | |
| atprint("Failed copying Autodesk 3DS Max exporter folder structure - %s", err) | |
| return err | |
| end | |
| end | |
| end | |
| -- copy exporter files | |
| local err, files = AsyncListFiles(path.assets.exporter, "*", "recursive,relative") | |
| if err then | |
| atprint("Failed listing Autodesk 3DS Max exporter files - %s", err) | |
| return err | |
| end | |
| for _, file in ipairs(files) do | |
| if not string.find(file, ".svn") then | |
| local os_dest_path = ConvertToOSPath(path.max.exporter .. file) | |
| local err = AsyncCopyFile(path.assets.exporter .. file, os_dest_path, "raw") | |
| if err then | |
| atprint("Failed copying Autodesk 3DS Max exporter files - %s", err) | |
| return err | |
| end | |
| end | |
| end | |
| -- copy exporter startup file | |
| local err = AsyncCopyFile(path.max.exporter_startup, path.max.startup) | |
| if err then | |
| atprint("Failed copying Autodesk 3DS Max exporter startup file - %s", err) | |
| return err | |
| end | |
| ArtTest.SetProducer_3DSMax(rawget(_G, "g_ArtTestProducer")) | |
| atprint("Installed Autodesk 3DS Max exporter. Restart Autodesk 3DS Max.") | |
| end | |
| --- | |
| --- Starts the art preview mode. | |
| --- | |
| --- This function is responsible for initializing the art preview mode. It performs the following steps: | |
| --- 1. Checks if an art producer script exists and loads it. | |
| --- 2. If no art producer is found, it opens a dialog to allow the user to select an art producer. | |
| --- 3. Sets the selected art producer. | |
| --- 4. Loads external entities. | |
| --- 5. Sets up the map for the art preview. | |
| --- | |
| --- @function ArtTest.Start | |
| --- @return nil | |
| function ArtTest.Start() | |
| atprint("Starting art preview mode") | |
| if io.exists(path.assets.art_producer_lua) then | |
| local producer = dofile(path.assets.art_producer_lua) | |
| if type(producer) == "string" then | |
| rawset(_G, "g_ArtTestProducer", producer) | |
| end | |
| end | |
| local art_producer = rawget(_G, "g_ArtTestProducer") | |
| local no_art_producer = (art_producer == nil) | |
| if no_art_producer then | |
| ArtTest.OpenChangeProducerDialog() | |
| return | |
| else | |
| -- updates all files | |
| ArtTest.SetProducer(art_producer) | |
| atprint("Selected art producer %s", art_producer) | |
| end | |
| ArtTest.LoadExternalEntities() | |
| ArtTest.SetUpMap() | |
| end | |
| local mounted | |
| --- | |
| --- Loads all external entities required for the art preview mode. | |
| --- | |
| --- This function is responsible for loading all the necessary entities, meshes, animations, materials, and textures for the art preview mode. It performs the following steps: | |
| --- 1. Mounts the required folders to make the assets accessible. | |
| --- 2. Enumerates all the entity files in the `path.assets.entities` directory. | |
| --- 3. Loads each entity file using `DelayedLoadEntity`. | |
| --- 4. Opens a loading screen and forces a reload of the bin assets and DLC assets. | |
| --- 5. Waits for the bin assets to finish loading and then closes the loading screen. | |
| --- 6. Waits for any delayed entity loads to complete. | |
| --- 7. Reloads the Lua script. | |
| --- | |
| --- @function ArtTest.LoadExternalEntities | |
| --- @return nil | |
| function ArtTest.LoadExternalEntities() | |
| if not mounted then | |
| mounted = true | |
| MountFolder(path.assets.root .. "Bin/Common/Entities/Meshes/", path.assets.root .. "Bin/Common/Meshes/") | |
| MountFolder(path.assets.root .. "Bin/Common/Entities/Animations/", path.assets.root .. "Bin/Common/Animations/") | |
| MountFolder(path.assets.root .. "Bin/Common/Entities/Materials/", path.assets.root .. "Bin/Common/Materials/") | |
| MountFolder(path.assets.root .. "Bin/Common/Entities/Mapping/", path.assets.root .. "Bin/Common/Mapping/") | |
| MountFolder(path.assets.root .. "Bin/Common/Entities/Textures/", path.assets.root .. "Bin/win32/Textures/") | |
| atprint("Mounted all entity folders") | |
| end | |
| local err, all_entities = AsyncListFiles(path.assets.entities, "*.ent") | |
| if err then | |
| atprint("Failed to enumerate entities - %s", err) | |
| return | |
| end | |
| if not all_entities or #all_entities == 0 then | |
| atprint("No entities to load") | |
| return | |
| end | |
| for i, ent_file in ipairs(all_entities) do | |
| DelayedLoadEntity(false, false, ent_file) | |
| end | |
| atprint("Will load %d entities", #all_entities) | |
| LoadingScreenOpen("idArtTestLoadEntities", "ArtTestLoadEntities") | |
| local old_render_mode = GetRenderMode() | |
| WaitRenderMode("ui") | |
| ForceReloadBinAssets() | |
| DlcReloadAssets(DlcDefinitions) | |
| -- actually reload the assets | |
| LoadBinAssets(CurrentMapFolder) | |
| -- wait & unmount | |
| WaitNextFrame(2) | |
| while AreBinAssetsLoading() do | |
| Sleep(1) | |
| end | |
| WaitRenderMode(old_render_mode) | |
| LoadingScreenClose("idArtTestLoadEntities", "ArtTestLoadEntities") | |
| WaitDelayedLoadEntities() | |
| -- ReloadClassEntities() | |
| ReloadLua() | |
| atprint("Reloaded all entities") | |
| end | |
| --- Sets up the map for the ArtTest module. | |
| --- | |
| --- This function performs the following tasks: | |
| --- - Activates the cameraMax camera | |
| --- - Prints a message to the console indicating the camera has been set up | |
| --- - Calls the ArtTest.PlacePreviewObjects() function to place preview objects on the map | |
| --- - If any preview objects were placed, it moves the camera to view the first preview object | |
| function ArtTest.SetUpMap() | |
| cameraMax.Activate(1) | |
| atprint("Camera set up") | |
| local preview_objs = ArtTest.PlacePreviewObjects() | |
| if preview_objs and next(preview_objs) then | |
| ViewPos(preview_objs[1]:GetVisualPos()) | |
| atprint("Showing first preview object") | |
| end | |
| end | |
| --- Returns a list of object classes to preview in the ArtTest module. | |
| --- | |
| --- The list of object classes is determined by the current producer set in the | |
| --- `g_ArtTestProducer` global variable. If `g_ArtTestProducer` is set to "Any", | |
| --- then all object classes that have an entry in the `entity_producers_lua` file | |
| --- will be included in the list. | |
| --- | |
| --- @return table A list of object class names to preview. | |
| function ArtTest.GetObjectClassesToPreview() | |
| local current_producer = rawget(_G, "g_ArtTestProducer") or "Any" | |
| local result = {} | |
| if io.exists(path.assets.entity_producers_lua) then | |
| local entity_producers = dofile(path.assets.entity_producers_lua) | |
| for entity_id, produced_by in pairs(entity_producers) do | |
| if (current_producer == "Any" or produced_by == current_producer) and g_Classes[entity_id] then | |
| table.insert(result, entity_id) | |
| end | |
| end | |
| end | |
| return result | |
| end | |
| local spacing = 10 * guim | |
| --- Places preview objects on the map for the ArtTest module. | |
| --- | |
| --- This function places preview objects on the map for each object class that is | |
| --- eligible to be previewed in the ArtTest module. The list of eligible object | |
| --- classes is determined by the current producer set in the `g_ArtTestProducer` | |
| --- global variable. | |
| --- | |
| --- For each eligible object class, the function places one preview object for | |
| --- each valid state of the object. The preview objects are placed in a grid | |
| --- pattern, with a spacing of `spacing` units between each object. | |
| --- | |
| --- The function returns a list of all the preview objects that were placed. | |
| --- | |
| --- @param classes (optional) A list of object class names to preview. If not | |
| --- provided, the function will use the list returned by | |
| --- `ArtTest.GetObjectClassesToPreview()`. | |
| --- @return table A list of preview objects that were placed. | |
| function ArtTest.PlacePreviewObjects(classes) | |
| local current_producer = rawget(_G, "g_ArtTestProducer") or "Any" | |
| local y = 0 | |
| local result = {} | |
| local classes = classes or ArtTest.GetObjectClassesToPreview() | |
| if not classes or #classes == 0 then | |
| atprint("No preview objects to place") | |
| return | |
| end | |
| for i, classname in ipairs(classes) do | |
| local class = g_Classes[classname] | |
| local entity = class:GetEntity() | |
| local entity_bbox = GetEntityBBox(entity) | |
| local _, radius = entity_bbox:GetBSphere() | |
| local x = 0 | |
| local half_spacing = radius + spacing | |
| for i, state in pairs(EnumValidStates(entity)) do | |
| x, y = x + half_spacing, y + half_spacing | |
| local pos = point(x, y) | |
| local preview_pos = point(x, y, terrain.GetHeight(x, y)) | |
| x, y = x + half_spacing, y + half_spacing | |
| local preview_obj = PlaceObject(classname) | |
| preview_obj:SetPos(preview_pos) | |
| preview_obj:SetState(state) | |
| table.insert(result, preview_obj) | |
| local text_obj = PlaceObject("Text") | |
| text_obj:SetDepthTest(false) | |
| text_obj:SetText(entity .. "\n" .. GetStateName(state)) | |
| text_obj:SetPos(pos + point(radius, radius)) | |
| end | |
| end | |
| atprint("Placed %d preview objects", #result) | |
| return result | |
| end | |
| ---- | |
| function OnMsg.ChangeMapDone() | |
| if CurrentMap == "ArtTest" then | |
| CreateRealTimeThread(ArtTest.Start) | |
| end | |
| end | |
| if FirstLoad and config.ArtTest then | |
| CreateRealTimeThread(ChangeMap, "ArtTest") | |
| end | |