diff --git a/addons/qodot/src/resources/game-definitions/trenchbroom_game_config.gd b/addons/qodot/src/resources/game-definitions/trenchbroom_game_config.gd index dcd2ccc..45038f7 100644 --- a/addons/qodot/src/resources/game-definitions/trenchbroom_game_config.gd +++ b/addons/qodot/src/resources/game-definitions/trenchbroom_game_config.gd @@ -1,10 +1,9 @@ @tool -## Defines a new game in Trenchbroom to express a set of entity definitions -## and editor behaviors. +## Defines a new game in TrenchBroom to express a set of entity definitions and editor behaviors. class_name TrenchBroomGameConfig extends Resource -## Button to export/update this game's folder in the Trenchbroom Games Path. +## Button to export/update this game's folder in the TrenchBroom Games Path. @export var export_file: bool: get: return export_file @@ -13,17 +12,16 @@ extends Resource if Engine.is_editor_hint(): do_export_file() -## The /games folder in either your Trenchbroom installation or your OS' user -## data folder. +## The /games folder in either your TrenchBroom installation or your OS' user data folder. @export_global_dir var trenchbroom_games_folder : String -## Name of the game in Trenchbroom's game list. -@export var game_name := "Qodot" +## Name of the game in TrenchBroom's game list. +@export var game_name : String = "Qodot" -## Icon for Trenchbroom's game list. +## Icon for TrenchBroom's game list. @export var icon : Texture2D -## Available map formats when creating a new map in Trenchbroom. The order of elements in the array is respected by Trenchbroom. The `initialmap` key value is optional. +## Available map formats when creating a new map in TrenchBroom. The order of elements in the array is respected by TrenchBroom. The `initialmap` key value is optional. @export var map_formats: Array[Dictionary] = [ { "format": "Valve", "initialmap": "initial_valve.map" }, { "format": "Standard", "initialmap": "initial_standard.map" }, @@ -31,60 +29,48 @@ extends Resource { "format": "Quake3" } ] -## Array of FGD resources to include with this game. -@export var fgd_files : Array[Resource] = [ - preload("res://addons/qodot/game_definitions/fgd/qodot_fgd.tres") -] +## Textures matching these patterns will be hidden from TrenchBroom. +@export var texture_exclusion_patterns: Array[String] = ["*_ao", "*_emission", "*_heightmap", "*_metallic", "*_normal", "*_orm", "*_roughness", "*_sss"] -## Scale expression that modifies the default display scale of entities in Trenchbroom. See the [**Trenchbroom Documentation**](https://trenchbroom.github.io/manual/latest/#game_configuration_files_entities) for more information. +## FGD resource to include with this game. If using multiple FGD resources, this should be the master FGD that contains them in the `base_fgd_files` resource array. +@export var fgd_file : QodotFGDFile = load("res://addons/qodot/game_definitions/fgd/qodot_fgd.tres") + +## Scale expression that modifies the default display scale of entities in TrenchBroom. See the [**TrenchBroom Documentation**](https://trenchbroom.github.io/manual/latest/#game_configuration_files_entities) for more information. @export var entity_scale: String = "1" ## Scale of textures on new brushes. @export var default_uv_scale : Vector2 = Vector2(1, 1) -## Arrays containing the TrenchbroomTag resource type. +## Arrays containing the TrenchBroomTag resource type. @export_category("Editor hint tags") -## Container for TrenchbroomTag resources that apply to brush entities. -@export var brush_tags : Array[Resource] = [] +## Container for TrenchBroomTag resources that apply to brush entities. +@export var brush_tags : Array[TrenchBroomTag] = [] -## Container for TrenchbroomTag resources that apply to textures. -@export var face_tags : Array[Resource] = [] - -## Arrays containing the TrenchbroomFaceAttrib resource type. Currently not parsed by Qodot. -@export_category("Quake 2 compatibility") - -## Map-wide bitflags toggleable for each face. Currently not parsed by Qodot. -@export var face_attrib_surface_flags : Array[Resource] = [] - -## Map-wide bitflags toggleable for each brush. Currently not parsed by Qodot. -@export var face_attrib_content_flags : Array[Resource] = [] - -## Private variable for storing fgd names, used in build_class_text(). -var _fgd_filenames : Array = [] +## Container for TrenchBroomTag resources that apply to textures. +@export var face_tags : Array[TrenchBroomTag] = [] ## Private default .cfg contents. ## See also: https://trenchbroom.github.io/manual/latest/#game_configuration_files -var _base_text: String = """{ - version: 3, - name: "%s", - icon: "icon.png", +const _base_text : String = """{ + "version": 8, + "name": "%s", + "icon": "icon.png", "fileformats": [ %s ], "filesystem": { "searchpath": ".", - "packageformat": { "extension": "pak", "format": "idpak" } + "packageformat": { "extension": ".zip", "format": "zip" } }, "textures": { - "package": { "type": "directory", "root": "textures" }, - "format": { "extensions": ["bmp", "exr", "hdr", "jpeg", "jpg", "png", "tga", "webp"], "format": "image" }, - "attribute": "_tb_textures" + "root": "textures", + "extensions": [".bmp", ".exr", ".hdr", ".jpeg", ".jpg", ".png", ".tga", ".webp"], + "excludes": [ %s ] }, "entities": { "definitions": [ %s ], "defaultcolor": "0.6 0.6 0.6 1.0", - "modelformats": [ "mdl", "md2", "md3", "bsp", "dkm" ], "scale": %s }, "tags": { @@ -99,35 +85,31 @@ var _base_text: String = """{ "defaults": { %s }, - "surfaceflags": [ - %s - ], - "contentflags": [ - %s - ] + "contentflags": [], + "surfaceflags": [] } } """ -func _init(): +func _init() -> void: if not icon: if ResourceLoader.exists("res://addons/qodot/icon.png"): icon = ResourceLoader.load("res://addons/qodot/icon.png") ## Matches tag key enum to the String name used in .cfg static func get_match_key(tag_match_type: int) -> String: - var tag_keys = { - 0: "texture", - 1: "contentflag", - 2: "surfaceflag", - 3: "surfaceparm", - 4: "classname" - } - return tag_keys[tag_match_type] + match tag_match_type: + TrenchBroomTag.TagMatchType.TEXTURE: + return "texture" + TrenchBroomTag.TagMatchType.CLASSNAME: + return "classname" + _: + push_error("Tag match type %s is not valid" % [tag_match_type]) + return "ERROR" ## Generates completed text for a .cfg file. func build_class_text() -> String: - var map_formats_str := "" + var map_formats_str : String = "" for map_format in map_formats: map_formats_str += "{ \"format\": \"" + map_format.format + "\"" if map_format.has("initialmap"): @@ -137,33 +119,34 @@ func build_class_text() -> String: else: map_formats_str += " }" - var fgd_filename_str := "" - for fgd_filename in _fgd_filenames: - fgd_filename_str += "\"%s\"" % fgd_filename - if fgd_filename != _fgd_filenames[-1]: - fgd_filename_str += ", " + var texture_exclusion_patterns_str := "" + for tex_pattern in texture_exclusion_patterns: + texture_exclusion_patterns_str += "\"" + tex_pattern + "\"" + if tex_pattern != texture_exclusion_patterns[-1]: + texture_exclusion_patterns_str += ", " + + var fgd_filename_str : String = "\"" + fgd_file.fgd_name + ".fgd\"" var brush_tags_str = parse_tags(brush_tags) var face_tags_str = parse_tags(face_tags) - var surface_flags_str = parse_flags(face_attrib_surface_flags) - var content_flags_str = parse_flags(face_attrib_content_flags) var uv_scale_str = parse_default_uv_scale(default_uv_scale) return _base_text % [ game_name, map_formats_str, + texture_exclusion_patterns_str, fgd_filename_str, entity_scale, brush_tags_str, face_tags_str, - uv_scale_str, - surface_flags_str, - content_flags_str + uv_scale_str ] ## Converts brush, face, and attribute tags into a .cfg-usable String. func parse_tags(tags: Array) -> String: var tags_str := "" for brush_tag in tags: + if brush_tag.tag_match_type >= TrenchBroomTag.TagMatchType.size(): + continue tags_str += "{\n" tags_str += "\t\t\t\t\"name\": \"%s\",\n" % brush_tag.tag_name var attribs_str := "" @@ -204,13 +187,19 @@ func parse_default_uv_scale(texture_scale : Vector2) -> String: }) ## Exports or updates a folder in the /games directory, with an icon, .cfg, and all accompanying FGDs. -func do_export_file(): +func do_export_file() -> void: var folder = trenchbroom_games_folder if folder.is_empty(): folder = QodotProjectConfig.get_setting(QodotProjectConfig.PROPERTY.TRENCHBROOM_GAMES_FOLDER) if folder.is_empty(): print("Skipping export: No TrenchBroom games folder") return + + # Make sure FGD file is set + if !fgd_file: + print("Skipping export: No FGD file") + return + # Create config folder name by combining games folder with the game name as a directory var config_folder = folder + "/" + game_name var config_dir := DirAccess.open(config_folder) @@ -221,9 +210,6 @@ func do_export_file(): print("Skipping export: Failed to create directory") return config_dir = DirAccess.open(config_folder) - if fgd_files.size() == 0: - print("Skipping export: No FGD files") - return print("Exporting TrenchBroom Game Config Folder to ", config_folder) # Icon @@ -236,22 +222,14 @@ func do_export_file(): # .cfg var export_config_file: Dictionary = {} export_config_file.game_name = game_name - _fgd_filenames = [] - for fgd_file in fgd_files: - _fgd_filenames.append(fgd_file.fgd_name + ".fgd") - print("Exported %s" % [fgd_file.fgd_name + ".fgd"]) export_config_file.target_file = config_folder + "/GameConfig.cfg" - print("Exporting Trenchbroom Game Config File to ", export_config_file.target_file) + print("Exporting TrenchBroom Game Config File to ", export_config_file.target_file) var file = FileAccess.open(export_config_file.target_file, FileAccess.WRITE) file.store_string(build_class_text()) file = null # Official way to close files in GDscript 2 - # FGDs - for fgd_file in fgd_files: - if not fgd_file is QodotFGDFile: - print("Skipping %s: Not a valid FGD file" % [fgd_file]) - continue - var export_fgd : QodotFGDFile = fgd_file.duplicate() - export_fgd.target_folder = config_folder - export_fgd.do_export_file() + # FGD + var export_fgd : QodotFGDFile = fgd_file.duplicate() + export_fgd.target_folder = config_folder + export_fgd.do_export_file() print("Export complete\n")