Pull Qodot changes for Trenchbroom game config version 8
This commit is contained in:
parent
dda7f70ca8
commit
944c446e60
|
@ -1,10 +1,9 @@
|
||||||
@tool
|
@tool
|
||||||
## Defines a new game in Trenchbroom to express a set of entity definitions
|
## Defines a new game in TrenchBroom to express a set of entity definitions and editor behaviors.
|
||||||
## and editor behaviors.
|
|
||||||
class_name TrenchBroomGameConfig
|
class_name TrenchBroomGameConfig
|
||||||
extends Resource
|
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:
|
@export var export_file: bool:
|
||||||
get:
|
get:
|
||||||
return export_file
|
return export_file
|
||||||
|
@ -13,17 +12,16 @@ extends Resource
|
||||||
if Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
do_export_file()
|
do_export_file()
|
||||||
|
|
||||||
## The /games folder in either your Trenchbroom installation or your OS' user
|
## The /games folder in either your TrenchBroom installation or your OS' user data folder.
|
||||||
## data folder.
|
|
||||||
@export_global_dir var trenchbroom_games_folder : String
|
@export_global_dir var trenchbroom_games_folder : String
|
||||||
|
|
||||||
## Name of the game in Trenchbroom's game list.
|
## Name of the game in TrenchBroom's game list.
|
||||||
@export var game_name := "Qodot"
|
@export var game_name : String = "Qodot"
|
||||||
|
|
||||||
## Icon for Trenchbroom's game list.
|
## Icon for TrenchBroom's game list.
|
||||||
@export var icon : Texture2D
|
@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] = [
|
@export var map_formats: Array[Dictionary] = [
|
||||||
{ "format": "Valve", "initialmap": "initial_valve.map" },
|
{ "format": "Valve", "initialmap": "initial_valve.map" },
|
||||||
{ "format": "Standard", "initialmap": "initial_standard.map" },
|
{ "format": "Standard", "initialmap": "initial_standard.map" },
|
||||||
|
@ -31,60 +29,48 @@ extends Resource
|
||||||
{ "format": "Quake3" }
|
{ "format": "Quake3" }
|
||||||
]
|
]
|
||||||
|
|
||||||
## Array of FGD resources to include with this game.
|
## Textures matching these patterns will be hidden from TrenchBroom.
|
||||||
@export var fgd_files : Array[Resource] = [
|
@export var texture_exclusion_patterns: Array[String] = ["*_ao", "*_emission", "*_heightmap", "*_metallic", "*_normal", "*_orm", "*_roughness", "*_sss"]
|
||||||
preload("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.
|
## 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"
|
@export var entity_scale: String = "1"
|
||||||
|
|
||||||
## Scale of textures on new brushes.
|
## Scale of textures on new brushes.
|
||||||
@export var default_uv_scale : Vector2 = Vector2(1, 1)
|
@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")
|
@export_category("Editor hint tags")
|
||||||
|
|
||||||
## Container for TrenchbroomTag resources that apply to brush entities.
|
## Container for TrenchBroomTag resources that apply to brush entities.
|
||||||
@export var brush_tags : Array[Resource] = []
|
@export var brush_tags : Array[TrenchBroomTag] = []
|
||||||
|
|
||||||
## Container for TrenchbroomTag resources that apply to textures.
|
## Container for TrenchBroomTag resources that apply to textures.
|
||||||
@export var face_tags : Array[Resource] = []
|
@export var face_tags : Array[TrenchBroomTag] = []
|
||||||
|
|
||||||
## 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 = []
|
|
||||||
|
|
||||||
## Private default .cfg contents.
|
## Private default .cfg contents.
|
||||||
## See also: https://trenchbroom.github.io/manual/latest/#game_configuration_files
|
## See also: https://trenchbroom.github.io/manual/latest/#game_configuration_files
|
||||||
var _base_text: String = """{
|
const _base_text : String = """{
|
||||||
version: 3,
|
"version": 8,
|
||||||
name: "%s",
|
"name": "%s",
|
||||||
icon: "icon.png",
|
"icon": "icon.png",
|
||||||
"fileformats": [
|
"fileformats": [
|
||||||
%s
|
%s
|
||||||
],
|
],
|
||||||
"filesystem": {
|
"filesystem": {
|
||||||
"searchpath": ".",
|
"searchpath": ".",
|
||||||
"packageformat": { "extension": "pak", "format": "idpak" }
|
"packageformat": { "extension": ".zip", "format": "zip" }
|
||||||
},
|
},
|
||||||
"textures": {
|
"textures": {
|
||||||
"package": { "type": "directory", "root": "textures" },
|
"root": "textures",
|
||||||
"format": { "extensions": ["bmp", "exr", "hdr", "jpeg", "jpg", "png", "tga", "webp"], "format": "image" },
|
"extensions": [".bmp", ".exr", ".hdr", ".jpeg", ".jpg", ".png", ".tga", ".webp"],
|
||||||
"attribute": "_tb_textures"
|
"excludes": [ %s ]
|
||||||
},
|
},
|
||||||
"entities": {
|
"entities": {
|
||||||
"definitions": [ %s ],
|
"definitions": [ %s ],
|
||||||
"defaultcolor": "0.6 0.6 0.6 1.0",
|
"defaultcolor": "0.6 0.6 0.6 1.0",
|
||||||
"modelformats": [ "mdl", "md2", "md3", "bsp", "dkm" ],
|
|
||||||
"scale": %s
|
"scale": %s
|
||||||
},
|
},
|
||||||
"tags": {
|
"tags": {
|
||||||
|
@ -99,35 +85,31 @@ var _base_text: String = """{
|
||||||
"defaults": {
|
"defaults": {
|
||||||
%s
|
%s
|
||||||
},
|
},
|
||||||
"surfaceflags": [
|
"contentflags": [],
|
||||||
%s
|
"surfaceflags": []
|
||||||
],
|
|
||||||
"contentflags": [
|
|
||||||
%s
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
func _init():
|
func _init() -> void:
|
||||||
if not icon:
|
if not icon:
|
||||||
if ResourceLoader.exists("res://addons/qodot/icon.png"):
|
if ResourceLoader.exists("res://addons/qodot/icon.png"):
|
||||||
icon = ResourceLoader.load("res://addons/qodot/icon.png")
|
icon = ResourceLoader.load("res://addons/qodot/icon.png")
|
||||||
|
|
||||||
## Matches tag key enum to the String name used in .cfg
|
## Matches tag key enum to the String name used in .cfg
|
||||||
static func get_match_key(tag_match_type: int) -> String:
|
static func get_match_key(tag_match_type: int) -> String:
|
||||||
var tag_keys = {
|
match tag_match_type:
|
||||||
0: "texture",
|
TrenchBroomTag.TagMatchType.TEXTURE:
|
||||||
1: "contentflag",
|
return "texture"
|
||||||
2: "surfaceflag",
|
TrenchBroomTag.TagMatchType.CLASSNAME:
|
||||||
3: "surfaceparm",
|
return "classname"
|
||||||
4: "classname"
|
_:
|
||||||
}
|
push_error("Tag match type %s is not valid" % [tag_match_type])
|
||||||
return tag_keys[tag_match_type]
|
return "ERROR"
|
||||||
|
|
||||||
## Generates completed text for a .cfg file.
|
## Generates completed text for a .cfg file.
|
||||||
func build_class_text() -> String:
|
func build_class_text() -> String:
|
||||||
var map_formats_str := ""
|
var map_formats_str : String = ""
|
||||||
for map_format in map_formats:
|
for map_format in map_formats:
|
||||||
map_formats_str += "{ \"format\": \"" + map_format.format + "\""
|
map_formats_str += "{ \"format\": \"" + map_format.format + "\""
|
||||||
if map_format.has("initialmap"):
|
if map_format.has("initialmap"):
|
||||||
|
@ -137,33 +119,34 @@ func build_class_text() -> String:
|
||||||
else:
|
else:
|
||||||
map_formats_str += " }"
|
map_formats_str += " }"
|
||||||
|
|
||||||
var fgd_filename_str := ""
|
var texture_exclusion_patterns_str := ""
|
||||||
for fgd_filename in _fgd_filenames:
|
for tex_pattern in texture_exclusion_patterns:
|
||||||
fgd_filename_str += "\"%s\"" % fgd_filename
|
texture_exclusion_patterns_str += "\"" + tex_pattern + "\""
|
||||||
if fgd_filename != _fgd_filenames[-1]:
|
if tex_pattern != texture_exclusion_patterns[-1]:
|
||||||
fgd_filename_str += ", "
|
texture_exclusion_patterns_str += ", "
|
||||||
|
|
||||||
|
var fgd_filename_str : String = "\"" + fgd_file.fgd_name + ".fgd\""
|
||||||
|
|
||||||
var brush_tags_str = parse_tags(brush_tags)
|
var brush_tags_str = parse_tags(brush_tags)
|
||||||
var face_tags_str = parse_tags(face_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)
|
var uv_scale_str = parse_default_uv_scale(default_uv_scale)
|
||||||
return _base_text % [
|
return _base_text % [
|
||||||
game_name,
|
game_name,
|
||||||
map_formats_str,
|
map_formats_str,
|
||||||
|
texture_exclusion_patterns_str,
|
||||||
fgd_filename_str,
|
fgd_filename_str,
|
||||||
entity_scale,
|
entity_scale,
|
||||||
brush_tags_str,
|
brush_tags_str,
|
||||||
face_tags_str,
|
face_tags_str,
|
||||||
uv_scale_str,
|
uv_scale_str
|
||||||
surface_flags_str,
|
|
||||||
content_flags_str
|
|
||||||
]
|
]
|
||||||
|
|
||||||
## Converts brush, face, and attribute tags into a .cfg-usable String.
|
## Converts brush, face, and attribute tags into a .cfg-usable String.
|
||||||
func parse_tags(tags: Array) -> String:
|
func parse_tags(tags: Array) -> String:
|
||||||
var tags_str := ""
|
var tags_str := ""
|
||||||
for brush_tag in tags:
|
for brush_tag in tags:
|
||||||
|
if brush_tag.tag_match_type >= TrenchBroomTag.TagMatchType.size():
|
||||||
|
continue
|
||||||
tags_str += "{\n"
|
tags_str += "{\n"
|
||||||
tags_str += "\t\t\t\t\"name\": \"%s\",\n" % brush_tag.tag_name
|
tags_str += "\t\t\t\t\"name\": \"%s\",\n" % brush_tag.tag_name
|
||||||
var attribs_str := ""
|
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.
|
## 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
|
var folder = trenchbroom_games_folder
|
||||||
if folder.is_empty():
|
if folder.is_empty():
|
||||||
folder = QodotProjectConfig.get_setting(QodotProjectConfig.PROPERTY.TRENCHBROOM_GAMES_FOLDER)
|
folder = QodotProjectConfig.get_setting(QodotProjectConfig.PROPERTY.TRENCHBROOM_GAMES_FOLDER)
|
||||||
if folder.is_empty():
|
if folder.is_empty():
|
||||||
print("Skipping export: No TrenchBroom games folder")
|
print("Skipping export: No TrenchBroom games folder")
|
||||||
return
|
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
|
# Create config folder name by combining games folder with the game name as a directory
|
||||||
var config_folder = folder + "/" + game_name
|
var config_folder = folder + "/" + game_name
|
||||||
var config_dir := DirAccess.open(config_folder)
|
var config_dir := DirAccess.open(config_folder)
|
||||||
|
@ -221,9 +210,6 @@ func do_export_file():
|
||||||
print("Skipping export: Failed to create directory")
|
print("Skipping export: Failed to create directory")
|
||||||
return
|
return
|
||||||
config_dir = DirAccess.open(config_folder)
|
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)
|
print("Exporting TrenchBroom Game Config Folder to ", config_folder)
|
||||||
|
|
||||||
# Icon
|
# Icon
|
||||||
|
@ -236,22 +222,14 @@ func do_export_file():
|
||||||
# .cfg
|
# .cfg
|
||||||
var export_config_file: Dictionary = {}
|
var export_config_file: Dictionary = {}
|
||||||
export_config_file.game_name = game_name
|
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"
|
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)
|
var file = FileAccess.open(export_config_file.target_file, FileAccess.WRITE)
|
||||||
file.store_string(build_class_text())
|
file.store_string(build_class_text())
|
||||||
file = null # Official way to close files in GDscript 2
|
file = null # Official way to close files in GDscript 2
|
||||||
|
|
||||||
# FGDs
|
# FGD
|
||||||
for fgd_file in fgd_files:
|
var export_fgd : QodotFGDFile = fgd_file.duplicate()
|
||||||
if not fgd_file is QodotFGDFile:
|
export_fgd.target_folder = config_folder
|
||||||
print("Skipping %s: Not a valid FGD file" % [fgd_file])
|
export_fgd.do_export_file()
|
||||||
continue
|
|
||||||
var export_fgd : QodotFGDFile = fgd_file.duplicate()
|
|
||||||
export_fgd.target_folder = config_folder
|
|
||||||
export_fgd.do_export_file()
|
|
||||||
print("Export complete\n")
|
print("Export complete\n")
|
||||||
|
|
Loading…
Reference in New Issue