diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index a45979e0..d04f2251 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -24,9 +24,9 @@ on: - 'README.md' env: - GODOT_BASE_DOWNLOAD_URL: https://github.com/godotengine/godot - GODOT_VERSION: 4.5 - GODOT_VERSION_TYPE: stable + GODOT_BASE_DOWNLOAD_URL: https://github.com/godotengine/godot-builds + GODOT_VERSION: 4.6 + GODOT_VERSION_TYPE: beta2 OPENVIC_BASE_BRANCH: master concurrency: diff --git a/README.md b/README.md index a97e9fd5..8cc66a85 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Main Repo for the OpenVic Project For detailed instructions, view the Contributor Quickstart Guide [here](docs/contribution-quickstart-guide.md) ## System Requirements -* [Godot 4.5](https://github.com/godotengine/godot/releases/tag/4.5-stable) +* [Godot 4.6](https://github.com/godotengine/godot/releases/tag/4.5-stable) * [scons](https://scons.org/) > [!WARNING] @@ -31,7 +31,7 @@ See [Cloning](docs/contribution/cloning.md). ## [Godot Documentation](https://docs.godotengine.org/en/latest/) ## Build/Run Instructions -1. Install [Godot 4.5](https://github.com/godotengine/godot/releases/tag/4.5-stable) and [scons](https://scons.org/) for your system. +1. Install [Godot 4.6](https://github.com/godotengine/godot/releases/tag/4.5-stable) and [scons](https://scons.org/) for your system. 2. Run the command `git submodule update --init --recursive` to retrieve all related submodules. 3. Run `scons` in the project root, you should see a libopenvic file in `game/bin/openvic`. 4. Open with Godot 4, click import and navigate to the `game` directory. diff --git a/docs/contribution-quickstart-guide.md b/docs/contribution-quickstart-guide.md index 62119718..27004639 100644 --- a/docs/contribution-quickstart-guide.md +++ b/docs/contribution-quickstart-guide.md @@ -34,7 +34,7 @@ ![](images/installation/scons-install.png) ## 4. [Godot](https://github.com/godotengine/godot/releases/latest) -- Download Godot 4.5 The current version for the project will be on the [main README](../README.md) page. +- Download Godot 4.6 The current version for the project will be on the [main README](../README.md) page. ![](images/installation/godot-dl-page.png) diff --git a/extension/doc_tools/make_rst.py b/extension/doc_tools/make_rst.py index e8cd6e81..d8bc2680 100644 --- a/extension/doc_tools/make_rst.py +++ b/extension/doc_tools/make_rst.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 # This script makes RST files from the XML class reference for use with the online docs. +from __future__ import annotations import argparse import os @@ -8,7 +9,7 @@ import sys import xml.etree.ElementTree as ET from collections import OrderedDict -from typing import Any, Dict, List, Optional, TextIO, Tuple, Union +from typing import Any, TextIO sys.path.insert(0, root_directory := os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../")) @@ -86,11 +87,13 @@ "This method may be changed or removed in future versions.", "This operator may be changed or removed in future versions.", "This theme property may be changed or removed in future versions.", + # See also `make_rst_class()` and `editor/doc/editor_help.cpp`. "[b]Note:[/b] The returned array is [i]copied[/i] and any changes to it will not update the original property value. See [%s] for more details.", ] -strings_l10n: Dict[str, str] = {} +strings_l10n: dict[str, str] = {} +writing_translation = False -CLASS_GROUPS: Dict[str, str] = { +CLASS_GROUPS: dict[str, str] = { "global": "Globals", "node": "Nodes", "resource": "Resources", @@ -98,21 +101,21 @@ "editor": "Editor-only", "variant": "Variant types", } -CLASS_GROUPS_BASE: Dict[str, str] = { +CLASS_GROUPS_BASE: dict[str, str] = { "node": "Node", "resource": "Resource", "object": "Object", "variant": "Variant", } # Sync with editor\register_editor_types.cpp -EDITOR_CLASSES: List[str] = [ +EDITOR_CLASSES: list[str] = [ "FileSystemDock", "ScriptCreateDialog", "ScriptEditor", "ScriptEditorBase", ] # Sync with the types mentioned in https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_differences.html -CLASSES_WITH_CSHARP_DIFFERENCES: List[str] = [ +CLASSES_WITH_CSHARP_DIFFERENCES: list[str] = [ "@GlobalScope", "String", "StringName", @@ -144,7 +147,7 @@ "Variant", ] -PACKED_ARRAY_TYPES: List[str] = [ +PACKED_ARRAY_TYPES: list[str] = [ "PackedByteArray", "PackedColorArray", "PackedFloat32Array", @@ -422,7 +425,7 @@ def parse_class(self, class_root: ET.Element, filepath: str) -> None: self.current_class = "" - def parse_params(self, root: ET.Element, context: str) -> List["ParameterDef"]: + def parse_params(self, root: ET.Element, context: str) -> list[ParameterDef]: param_elements = root.findall("param") params: Any = [None] * len(param_elements) @@ -440,7 +443,7 @@ def parse_params(self, root: ET.Element, context: str) -> List["ParameterDef"]: params[index] = ParameterDef(param_name, type_name, default) - cast: List[ParameterDef] = params + cast: list[ParameterDef] = params return cast @@ -458,7 +461,7 @@ def __init__(self, raw: str, name: str, arguments: str, closing: bool) -> None: class TypeName: - def __init__(self, type_name: str, enum: Optional[str] = None, is_bitfield: bool = False) -> None: + def __init__(self, type_name: str, enum: str | None = None, is_bitfield: bool = False) -> None: self.type_name = type_name self.enum = enum self.is_bitfield = is_bitfield @@ -472,7 +475,7 @@ def to_rst(self, state: State) -> str: return make_type(self.type_name, state) @classmethod - def from_element(cls, element: ET.Element) -> "TypeName": + def from_element(cls, element: ET.Element) -> TypeName: return cls(element.attrib["type"], element.get("enum"), element.get("is_bitfield") == "true") @@ -484,8 +487,8 @@ def __init__( ) -> None: self.definition_name = definition_name self.name = name - self.deprecated: Optional[str] = None - self.experimental: Optional[str] = None + self.deprecated: str | None = None + self.experimental: str | None = None class PropertyDef(DefinitionBase): @@ -493,11 +496,11 @@ def __init__( self, name: str, type_name: TypeName, - setter: Optional[str], - getter: Optional[str], - text: Optional[str], - default_value: Optional[str], - overrides: Optional[str], + setter: str | None, + getter: str | None, + text: str | None, + default_value: str | None, + overrides: str | None, ) -> None: super().__init__("property", name) @@ -510,7 +513,7 @@ def __init__( class ParameterDef(DefinitionBase): - def __init__(self, name: str, type_name: TypeName, default_value: Optional[str]) -> None: + def __init__(self, name: str, type_name: TypeName, default_value: str | None) -> None: super().__init__("parameter", name) self.type_name = type_name @@ -518,7 +521,7 @@ def __init__(self, name: str, type_name: TypeName, default_value: Optional[str]) class SignalDef(DefinitionBase): - def __init__(self, name: str, parameters: List[ParameterDef], description: Optional[str]) -> None: + def __init__(self, name: str, parameters: list[ParameterDef], description: str | None) -> None: super().__init__("signal", name) self.parameters = parameters @@ -529,9 +532,9 @@ class AnnotationDef(DefinitionBase): def __init__( self, name: str, - parameters: List[ParameterDef], - description: Optional[str], - qualifiers: Optional[str], + parameters: list[ParameterDef], + description: str | None, + qualifiers: str | None, ) -> None: super().__init__("annotation", name) @@ -545,9 +548,9 @@ def __init__( self, name: str, return_type: TypeName, - parameters: List[ParameterDef], - description: Optional[str], - qualifiers: Optional[str], + parameters: list[ParameterDef], + description: str | None, + qualifiers: str | None, ) -> None: super().__init__("method", name) @@ -558,7 +561,7 @@ def __init__( class ConstantDef(DefinitionBase): - def __init__(self, name: str, value: str, text: Optional[str], bitfield: bool) -> None: + def __init__(self, name: str, value: str, text: str | None, bitfield: bool) -> None: super().__init__("constant", name) self.value = value @@ -577,7 +580,7 @@ def __init__(self, name: str, type_name: TypeName, bitfield: bool) -> None: class ThemeItemDef(DefinitionBase): def __init__( - self, name: str, type_name: TypeName, data_name: str, text: Optional[str], default_value: Optional[str] + self, name: str, type_name: TypeName, data_name: str, text: str | None, default_value: str | None ) -> None: super().__init__("theme property", name) @@ -597,17 +600,17 @@ def __init__(self, name: str) -> None: self.constants: OrderedDict[str, ConstantDef] = OrderedDict() self.enums: OrderedDict[str, EnumDef] = OrderedDict() self.properties: OrderedDict[str, PropertyDef] = OrderedDict() - self.constructors: OrderedDict[str, List[MethodDef]] = OrderedDict() - self.methods: OrderedDict[str, List[MethodDef]] = OrderedDict() - self.operators: OrderedDict[str, List[MethodDef]] = OrderedDict() + self.constructors: OrderedDict[str, list[MethodDef]] = OrderedDict() + self.methods: OrderedDict[str, list[MethodDef]] = OrderedDict() + self.operators: OrderedDict[str, list[MethodDef]] = OrderedDict() self.signals: OrderedDict[str, SignalDef] = OrderedDict() - self.annotations: OrderedDict[str, List[AnnotationDef]] = OrderedDict() + self.annotations: OrderedDict[str, list[AnnotationDef]] = OrderedDict() self.theme_items: OrderedDict[str, ThemeItemDef] = OrderedDict() - self.inherits: Optional[str] = None - self.brief_description: Optional[str] = None - self.description: Optional[str] = None - self.tutorials: List[Tuple[str, str]] = [] - self.keywords: Optional[str] = None + self.inherits: str | None = None + self.brief_description: str | None = None + self.description: str | None = None + self.tutorials: list[tuple[str, str]] = [] + self.keywords: str | None = None # Used to match the class with XML source for output filtering purposes. self.filepath: str = "" @@ -653,7 +656,7 @@ def update_class_group(self, state: State) -> None: # which don't necessarily need C# examples. class ScriptLanguageParityCheck: def __init__(self) -> None: - self.hit_map: OrderedDict[str, List[Tuple[DefinitionBase, str]]] = OrderedDict() + self.hit_map: OrderedDict[str, list[tuple[DefinitionBase, str]]] = OrderedDict() self.hit_count = 0 def add_hit(self, class_name: str, context: DefinitionBase, error: str, state: State) -> None: @@ -710,6 +713,8 @@ def main() -> None: # Retrieve heading translations for the given language. if not args.dry_run and args.lang != "en": + global writing_translation + writing_translation = True lang_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), "..", "translations", "{}.po".format(args.lang) ) @@ -754,8 +759,8 @@ def main() -> None: print("Checking for errors in the XML class reference...") - file_list: List[str] = [] - game_class_list: List[str] = [] + file_list: list[str] = [] + game_class_list: list[str] = [] for path in (args.path + engine_doc_paths): # Cut off trailing slashes so os.path.basename doesn't choke. @@ -782,7 +787,7 @@ def main() -> None: file_list.append(path) - classes: Dict[str, Tuple[ET.Element, str]] = {} + classes: dict[str, tuple[ET.Element, str]] = {} state = State() for cur_file in file_list: @@ -815,7 +820,7 @@ def main() -> None: print("Generating the RST class reference...") - grouped_classes: Dict[str, List[str]] = {} + grouped_classes: dict[str, list[str]] = {} for class_name, class_def in state.classes.items(): if class_name not in game_class_list: @@ -932,18 +937,18 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir: if class_def.keywords is not None and class_def.keywords != "": f.write(f".. meta::\n\t:keywords: {class_def.keywords}\n\n") - # Warn contributors not to edit this file directly. - # Also provide links to the source files for reference. + if not writing_translation: # Skip for translations to reduce diff. + # Warn contributors not to edit this file directly. + # Also provide links to the source files for reference. + git_branch = get_git_branch() + source_xml_path = os.path.relpath(class_def.filepath, root_directory).replace("\\", "/") + source_github_url = f"https://github.com/OpenVicProject/OpenVic/tree/{git_branch}/{source_xml_path}" + generator_github_url = f"https://github.com/OpenVicProject/OpenVic/tree/{git_branch}/extension/doc_tools/make_rst.py" - git_branch = get_git_branch() - source_xml_path = os.path.relpath(class_def.filepath, root_directory).replace("\\", "/") - source_github_url = f"https://github.com/OpenVicProject/OpenVic/tree/{git_branch}/{source_xml_path}" - generator_github_url = f"https://github.com/OpenVicProject/OpenVic/tree/{git_branch}/extension/doc_tools/make_rst.py" - - f.write(".. DO NOT EDIT THIS FILE!!!\n") - f.write(".. Generated automatically from OpenVic game sources.\n") - f.write(f".. Generator: {generator_github_url}.\n") - f.write(f".. XML source: {source_github_url}.\n\n") + f.write(".. DO NOT EDIT THIS FILE!!!\n") + f.write(".. Generated automatically from Godot engine sources.\n") + f.write(f".. Generator: {generator_github_url}.\n") + f.write(f".. XML source: {source_github_url}.\n\n") # Document reference id and header. f.write(f".. _class_{sanitize_class_name(class_name)}:\n\n") @@ -977,7 +982,7 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir: f.write("\n\n") # Descendants - inherited: List[str] = [] + inherited: list[str] = [] for c in state.classes.values(): if c.inherits and c.inherits.strip() == class_name: inherited.append(c.name) @@ -1038,7 +1043,7 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir: ### REFERENCE TABLES ### # Reused container for reference tables. - ml: List[Tuple[Optional[str], ...]] = [] + ml: list[tuple[str | None, ...]] = [] # Properties reference table if len(class_def.properties) > 0: @@ -1233,6 +1238,7 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir: # Annotation descriptions if len(class_def.annotations) > 0: f.write(make_separator(True)) + f.write(".. rst-class:: classref-descriptions-group\n\n") f.write(make_heading("Annotations", "-")) index = 0 @@ -1333,6 +1339,7 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir: # Add copy note to built-in properties returning `Packed*Array`. if property_def.type_name.type_name in PACKED_ARRAY_TYPES: + # See also `BASE_STRINGS` and `editor/doc/editor_help.cpp`. copy_note = f"[b]Note:[/b] The returned array is [i]copied[/i] and any changes to it will not update the original property value. See [{property_def.type_name.type_name}] for more details." f.write(f"{format_text_block(copy_note, property_def, state)}\n\n") @@ -1572,8 +1579,8 @@ def make_enum(t: str, is_bitfield: bool, state: State) -> str: def make_method_signature( - class_def: ClassDef, definition: Union[AnnotationDef, MethodDef, SignalDef], ref_type: str, state: State -) -> Tuple[str, str]: + class_def: ClassDef, definition: AnnotationDef | MethodDef | SignalDef, ref_type: str, state: State +) -> tuple[str, str]: ret_type = "" if isinstance(definition, MethodDef): @@ -1639,7 +1646,7 @@ def make_setter_signature(class_def: ClassDef, property_def: PropertyDef, state: setter = class_def.methods[property_def.setter][0] # Otherwise we fake it with the information we have available. else: - setter_params: List[ParameterDef] = [] + setter_params: list[ParameterDef] = [] setter_params.append(ParameterDef("value", property_def.type_name, None)) setter = MethodDef(property_def.setter, TypeName("void"), setter_params, None, None) @@ -1656,7 +1663,7 @@ def make_getter_signature(class_def: ClassDef, property_def: PropertyDef, state: getter = class_def.methods[property_def.getter][0] # Otherwise we fake it with the information we have available. else: - getter_params: List[ParameterDef] = [] + getter_params: list[ParameterDef] = [] getter = MethodDef(property_def.getter, property_def.type_name, getter_params, None, None) ret_type, signature = make_method_signature(class_def, getter, "", state) @@ -1755,7 +1762,7 @@ def make_link(url: str, title: str) -> str: return f"`{url} <{url}>`__" -def make_rst_index(grouped_classes: Dict[str, List[str]], dry_run: bool, output_dir: str) -> None: +def make_rst_index(grouped_classes: dict[str, list[str]], dry_run: bool, output_dir: str) -> None: with open( os.devnull if dry_run else os.path.join(output_dir, "index.rst"), "w", encoding="utf-8", newline="\n" ) as f: @@ -1820,7 +1827,7 @@ def make_rst_index(grouped_classes: Dict[str, List[str]], dry_run: bool, output_ ] -def is_in_tagset(tag_text: str, tagset: List[str]) -> bool: +def is_in_tagset(tag_text: str, tagset: list[str]) -> bool: for tag in tagset: # Complete match. if tag_text == tag: @@ -1862,7 +1869,7 @@ def get_tag_and_args(tag_text: str) -> TagState: return TagState(tag_text, tag_name, arguments, closing) -def parse_link_target(link_target: str, state: State, context_name: str) -> List[str]: +def parse_link_target(link_target: str, state: State, context_name: str) -> list[str]: if link_target.find(".") != -1: return link_target.split(".") else: @@ -2110,7 +2117,7 @@ def format_text_block( valid_param_context = isinstance(context, (MethodDef, SignalDef, AnnotationDef)) if valid_param_context: - context_params: List[ParameterDef] = context.parameters # type: ignore + context_params: list[ParameterDef] = context.parameters # type: ignore for param_def in context_params: if param_def.name == inside_code_text: print_warning( @@ -2270,7 +2277,7 @@ def format_text_block( state, ) else: - context_params: List[ParameterDef] = context.parameters # type: ignore + context_params: list[ParameterDef] = context.parameters # type: ignore found = False for param_def in context_params: if param_def.name == link_target: @@ -2435,7 +2442,7 @@ def format_text_block( return text -def preformat_text_block(text: str, state: State) -> Optional[str]: +def preformat_text_block(text: str, state: State) -> str | None: result = "" codeblock_tag = "" indent_level = 0 @@ -2485,7 +2492,7 @@ def preformat_text_block(text: str, state: State) -> Optional[str]: return result -def format_context_name(context: Union[DefinitionBase, None]) -> str: +def format_context_name(context: DefinitionBase | None) -> str: context_name: str = "unknown context" if context is not None: context_name = f'{context.definition_name} "{context.name}" description' @@ -2527,7 +2534,7 @@ def escape_rst(text: str, until_pos: int = -1) -> str: return text -def format_table(f: TextIO, data: List[Tuple[Optional[str], ...]], remove_empty_columns: bool = False) -> None: +def format_table(f: TextIO, data: list[tuple[str | None, ...]], remove_empty_columns: bool = False) -> None: if len(data) == 0: return @@ -2572,7 +2579,7 @@ def format_table(f: TextIO, data: List[Tuple[Optional[str], ...]], remove_empty_ f.write("\n") -def sanitize_class_name(dirty_name: str, is_file_name=False) -> str: +def sanitize_class_name(dirty_name: str, is_file_name: bool = False) -> str: if is_file_name: return dirty_name.lower().replace('"', "").replace("/", "--") else: @@ -2638,4 +2645,4 @@ def sanitize_operator_name(dirty_name: str, state: State) -> str: if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/extension/doc_tools/patches/make_rst.patch b/extension/doc_tools/patches/make_rst.patch index ff495bd5..2288cf25 100644 --- a/extension/doc_tools/patches/make_rst.patch +++ b/extension/doc_tools/patches/make_rst.patch @@ -1,8 +1,8 @@ diff --git a/extension/doc_tools/make_rst.py b/extension/doc_tools/make_rst.py -index f98d7b3..e8cd6e8 100644 +index 3f704bd..d8bc268 100644 --- a/extension/doc_tools/make_rst.py +++ b/extension/doc_tools/make_rst.py -@@ -12,7 +12,6 @@ from typing import Any, Dict, List, Optional, TextIO, Tuple, Union +@@ -13,7 +13,6 @@ from typing import Any, TextIO sys.path.insert(0, root_directory := os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../")) @@ -10,7 +10,7 @@ index f98d7b3..e8cd6e8 100644 from misc.utility.color import Ansi, force_stderr_color, force_stdout_color # $DOCS_URL/path/to/page.html(#fragment-tag) -@@ -673,6 +672,13 @@ class ScriptLanguageParityCheck: +@@ -676,6 +675,13 @@ class ScriptLanguageParityCheck: self.hit_map[class_name].append((context, error)) @@ -24,7 +24,7 @@ index f98d7b3..e8cd6e8 100644 # Entry point for the RST generator. def main() -> None: parser = argparse.ArgumentParser() -@@ -721,21 +727,50 @@ def main() -> None: +@@ -726,21 +732,50 @@ def main() -> None: else: print(f'No PO file at "{lang_file}" for language "{args.lang}".') @@ -55,8 +55,8 @@ index f98d7b3..e8cd6e8 100644 + print("Checking for errors in the XML class reference...") - file_list: List[str] = [] -+ game_class_list: List[str] = [] + file_list: list[str] = [] ++ game_class_list: list[str] = [] - for path in args.path: + for path in (args.path + engine_doc_paths): @@ -77,8 +77,8 @@ index f98d7b3..e8cd6e8 100644 elif os.path.isdir(path): file_list += (os.path.join(path, f) for f in os.listdir(path) if f.endswith(".xml")) -@@ -783,6 +818,8 @@ def main() -> None: - grouped_classes: Dict[str, List[str]] = {} +@@ -788,6 +823,8 @@ def main() -> None: + grouped_classes: dict[str, list[str]] = {} for class_name, class_def in state.classes.items(): + if class_name not in game_class_list: @@ -86,7 +86,7 @@ index f98d7b3..e8cd6e8 100644 if args.filter and not pattern.search(class_def.filepath): continue state.current_class = class_name -@@ -874,9 +911,6 @@ def translate(string: str) -> str: +@@ -879,9 +916,6 @@ def translate(string: str) -> str: def get_git_branch() -> str: @@ -96,22 +96,18 @@ index f98d7b3..e8cd6e8 100644 return "master" -@@ -903,11 +937,11 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir: +@@ -908,8 +942,8 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir: + # Also provide links to the source files for reference. + git_branch = get_git_branch() + source_xml_path = os.path.relpath(class_def.filepath, root_directory).replace("\\", "/") +- source_github_url = f"https://github.com/godotengine/godot/tree/{git_branch}/{source_xml_path}" +- generator_github_url = f"https://github.com/godotengine/godot/tree/{git_branch}/doc/tools/make_rst.py" ++ source_github_url = f"https://github.com/OpenVicProject/OpenVic/tree/{git_branch}/{source_xml_path}" ++ generator_github_url = f"https://github.com/OpenVicProject/OpenVic/tree/{git_branch}/extension/doc_tools/make_rst.py" - git_branch = get_git_branch() - source_xml_path = os.path.relpath(class_def.filepath, root_directory).replace("\\", "/") -- source_github_url = f"https://github.com/godotengine/godot/tree/{git_branch}/{source_xml_path}" -- generator_github_url = f"https://github.com/godotengine/godot/tree/{git_branch}/doc/tools/make_rst.py" -+ source_github_url = f"https://github.com/OpenVicProject/OpenVic/tree/{git_branch}/{source_xml_path}" -+ generator_github_url = f"https://github.com/OpenVicProject/OpenVic/tree/{git_branch}/extension/doc_tools/make_rst.py" - - f.write(".. DO NOT EDIT THIS FILE!!!\n") -- f.write(".. Generated automatically from Godot engine sources.\n") -+ f.write(".. Generated automatically from OpenVic game sources.\n") - f.write(f".. Generator: {generator_github_url}.\n") - f.write(f".. XML source: {source_github_url}.\n\n") - -@@ -1733,7 +1767,7 @@ def make_rst_index(grouped_classes: Dict[str, List[str]], dry_run: bool, output_ + f.write(".. DO NOT EDIT THIS FILE!!!\n") + f.write(".. Generated automatically from Godot engine sources.\n") +@@ -1740,7 +1774,7 @@ def make_rst_index(grouped_classes: dict[str, list[str]], dry_run: bool, output_ # Also provide links to the source files for reference. git_branch = get_git_branch() diff --git a/extension/src/openvic-extension/singletons/AssetManager.cpp b/extension/src/openvic-extension/singletons/AssetManager.cpp index 46d9c21f..92f43505 100644 --- a/extension/src/openvic-extension/singletons/AssetManager.cpp +++ b/extension/src/openvic-extension/singletons/AssetManager.cpp @@ -65,9 +65,9 @@ Ref AssetManager::_load_image(StringName const& path, bool flip_y) { Ref AssetManager::get_image(StringName const& path, BitField load_flags) { /* Check for an existing image entry indicating a previous load attempt, whether successful or not. */ - const image_asset_map_t::const_iterator it = image_assets.find(path); - if (it != image_assets.end() && it.value().image.is_valid()) { - return it.value().image; + const image_asset_map_t::Iterator it = image_assets.find(path); + if (it != image_assets.end() && it->value.image.is_valid()) { + return it->value.image; } /* No load attempt has been made yet, so we try now. */ @@ -89,9 +89,9 @@ Ref AssetManager::get_image(StringName const& path, BitField l Ref AssetManager::get_texture(StringName const& path, BitField load_flags) { /* Check for an existing texture entry indicating a previous creation attempt, whether successful or not. */ - const image_asset_map_t::const_iterator it = image_assets.find(path); - if (it != image_assets.end() && it.value().texture.is_valid()) { - return it.value().texture; + const image_asset_map_t::Iterator it = image_assets.find(path); + if (it != image_assets.end() && it->value.texture.is_valid()) { + return it->value.texture; } /* No creation attempt has yet been made, so we try now starting by finding the corresponding image. */ @@ -138,11 +138,11 @@ Ref AssetManager::make_stylebox_texture(Ref const& t } Ref AssetManager::get_font(StringName const& name) { - const font_map_t::const_iterator it = fonts.find(name); + const font_map_t::Iterator it = fonts.find(name); if (it != fonts.end()) { - ERR_FAIL_NULL_V_MSG(it->second, nullptr, Utilities::format("Failed to load font previously: %s", name)); + ERR_FAIL_NULL_V_MSG(it->value, nullptr, Utilities::format("Failed to load font previously: %s", name)); - return it->second; + return it->value; } static const String font_dir = "gfx/fonts/"; @@ -152,35 +152,35 @@ Ref AssetManager::get_font(StringName const& name) { const StringName image_path = font_dir + name + image_ext; const Ref image = get_image(image_path, LOAD_FLAG_NONE); if (image.is_null()) { - fonts.emplace(name, nullptr); + fonts.insert(name, Ref()); - ERR_FAIL_V_MSG(nullptr, Utilities::format("Failed to load font image %s for the font named %s", image_path, name)); + ERR_FAIL_V_MSG(Ref(), Utilities::format("Failed to load font image %s for the font named %s", image_path, name)); } GameSingleton* game_singleton = GameSingleton::get_singleton(); - ERR_FAIL_NULL_V(game_singleton, nullptr); + ERR_FAIL_NULL_V(game_singleton, Ref()); const String font_path = font_dir + name + font_ext; const String lookedup_font_path = convert_to( game_singleton->get_dataloader().lookup_file(convert_to(font_path)).string() ); if (lookedup_font_path.is_empty()) { - fonts.emplace(name, nullptr); + fonts.insert(name, Ref()); - ERR_FAIL_V_MSG(nullptr, Utilities::format("Failed to look up font: %s", font_path)); + ERR_FAIL_V_MSG(Ref(), Utilities::format("Failed to look up font: %s", font_path)); } const Ref font = Utilities::load_godot_font(lookedup_font_path, image); if (font.is_null()) { - fonts.emplace(name, nullptr); + fonts.insert(name, Ref()); ERR_FAIL_V_MSG( - nullptr, + Ref(), Utilities::format("Failed to load font file %s (looked up: %s) for the font named %s", font_path, lookedup_font_path, name) ); } - fonts.emplace(name, font); + fonts.insert(name, font); return font; } diff --git a/extension/src/openvic-extension/singletons/AssetManager.hpp b/extension/src/openvic-extension/singletons/AssetManager.hpp index 3728bb11..3eb50f5a 100644 --- a/extension/src/openvic-extension/singletons/AssetManager.hpp +++ b/extension/src/openvic-extension/singletons/AssetManager.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -31,8 +32,8 @@ namespace OpenVic { godot::Ref texture; }; /* deque_ordered_map to avoid the need to reallocate. */ - using image_asset_map_t = deque_ordered_map; - using font_map_t = deque_ordered_map>; + using image_asset_map_t = godot::HashMap; + using font_map_t = godot::HashMap>; image_asset_map_t image_assets; font_map_t fonts; diff --git a/extension/src/openvic-extension/singletons/CursorSingleton.cpp b/extension/src/openvic-extension/singletons/CursorSingleton.cpp index edc112bb..0e661fa9 100644 --- a/extension/src/openvic-extension/singletons/CursorSingleton.cpp +++ b/extension/src/openvic-extension/singletons/CursorSingleton.cpp @@ -61,57 +61,57 @@ TypedArray CursorSingleton::get_cursor_names() const { } TypedArray CursorSingleton::get_frames(StringName const& name, int32_t res_index) const { - const cursor_map_t::const_iterator it = cursors.find(name); + const cursor_map_t::ConstIterator it = cursors.find(name); ERR_FAIL_COND_V_MSG(it == cursors.end(), {}, Utilities::format("Cursor \"%s\" not found", name)); - std::vector> const& images = it->second.images; + std::vector> const& images = it->value.images; ERR_FAIL_INDEX_V_MSG(res_index, images.size(), {}, Utilities::format("Invalid image index for cursor \"%s\": %d", name, res_index)); return images[res_index]; } PackedVector2Array CursorSingleton::get_hotspots(StringName const& name, int32_t res_index) const { - const cursor_map_t::const_iterator it = cursors.find(name); + const cursor_map_t::ConstIterator it = cursors.find(name); ERR_FAIL_COND_V_MSG(it == cursors.end(), {}, Utilities::format("Cursor \"%s\" not found", name)); - std::vector const& hotspots = it->second.hotspots; + std::vector const& hotspots = it->value.hotspots; ERR_FAIL_INDEX_V_MSG(res_index, hotspots.size(), {}, Utilities::format("Invalid hotspot index for cursor \"%s\": %d", name, res_index)); return hotspots[res_index]; } int32_t CursorSingleton::get_animation_length(StringName const& name) const { - const cursor_map_t::const_iterator it = cursors.find(name); + const cursor_map_t::ConstIterator it = cursors.find(name); ERR_FAIL_COND_V_MSG(it == cursors.end(), {}, Utilities::format("Cursor \"%s\" not found", name)); - return it->second.animation_length; + return it->value.animation_length; } PackedVector2Array CursorSingleton::get_resolutions(StringName const& name) const { - const cursor_map_t::const_iterator it = cursors.find(name); + const cursor_map_t::ConstIterator it = cursors.find(name); ERR_FAIL_COND_V_MSG(it == cursors.end(), {}, Utilities::format("Cursor \"%s\" not found", name)); - return it->second.resolutions; + return it->value.resolutions; } PackedFloat32Array CursorSingleton::get_display_rates(StringName const& name) const { - const cursor_map_t::const_iterator it = cursors.find(name); + const cursor_map_t::ConstIterator it = cursors.find(name); ERR_FAIL_COND_V_MSG(it == cursors.end(), {}, Utilities::format("Cursor \"%s\" not found", name)); - return it->second.display_rates; + return it->value.display_rates; } PackedInt32Array CursorSingleton::get_sequence(StringName const& name) const { - const cursor_map_t::const_iterator it = cursors.find(name); + const cursor_map_t::ConstIterator it = cursors.find(name); ERR_FAIL_COND_V_MSG(it == cursors.end(), {}, Utilities::format("Cursor \"%s\" not found", name)); - return it->second.sequence; + return it->value.sequence; } void CursorSingleton::generate_resolution(StringName const& name, int32_t base_res_index, Vector2 target_res) { - cursor_map_t::iterator it = cursors.find(name); + cursor_map_t::Iterator it = cursors.find(name); ERR_FAIL_COND_MSG(it == cursors.end(), Utilities::format("Cursor \"%s\" not found", name)); - cursor_asset_t& cursor = it.value(); + cursor_asset_t& cursor = it->value; ERR_FAIL_INDEX_MSG( base_res_index, cursor.images.size(), Utilities::format("Invalid image index for cursor \"%s\": %d", name, base_res_index) @@ -556,7 +556,7 @@ bool CursorSingleton::_load_cursor_ani(StringName const& name, String const& pat } } - cursors.emplace( + cursors.insert( name, cursor_asset_t { std::move(hotspots_by_resolution), @@ -598,7 +598,7 @@ bool CursorSingleton::_load_cursor_cur(StringName const& name, String const& pat hotspots_by_resolution.push_back(hotspots); } - cursors.emplace( + cursors.insert( name, cursor_asset_t { std::move(hotspots_by_resolution), diff --git a/extension/src/openvic-extension/singletons/CursorSingleton.hpp b/extension/src/openvic-extension/singletons/CursorSingleton.hpp index 13c7b2ab..87fad7fc 100644 --- a/extension/src/openvic-extension/singletons/CursorSingleton.hpp +++ b/extension/src/openvic-extension/singletons/CursorSingleton.hpp @@ -43,7 +43,7 @@ namespace OpenVic { }; //map of "subfolder/fileName.cur/.ani" -> cursor_asset. Subfolder comes after gfx/cursor - using cursor_map_t = deque_ordered_map; + using cursor_map_t = godot::HashMap; cursor_map_t cursors; godot::TypedArray cursor_names; diff --git a/extension/src/openvic-extension/singletons/GameSingleton.cpp b/extension/src/openvic-extension/singletons/GameSingleton.cpp index 46164251..b1b76e9a 100644 --- a/extension/src/openvic-extension/singletons/GameSingleton.cpp +++ b/extension/src/openvic-extension/singletons/GameSingleton.cpp @@ -329,10 +329,10 @@ int32_t GameSingleton::get_flag_sheet_index(const country_index_t country_index, -1, Utilities::format("Invalid country index: %d", index) ); - const typename decltype(flag_type_index_map)::const_iterator it = flag_type_index_map.find(flag_type); + const typename decltype(flag_type_index_map)::ConstIterator it = flag_type_index_map.find(flag_type); ERR_FAIL_COND_V_MSG(it == flag_type_index_map.end(), -1, Utilities::format("Invalid flag type %s", flag_type)); - return flag_type_index_map.size() * index + it->second; + return flag_type_index_map.size() * index + it->value; } Rect2i GameSingleton::get_flag_sheet_rect(int32_t flag_index) const { @@ -625,7 +625,7 @@ Error GameSingleton::_load_flag_sheet() { /* Generate flag type - index lookup map */ flag_type_index_map.clear(); for (std::string_view const& type : government_type_manager.get_flag_types()) { - flag_type_index_map.emplace(convert_to(type), static_cast(flag_type_index_map.size())); + flag_type_index_map.insert(convert_to(type), static_cast(flag_type_index_map.size())); } flag_sheet_count = country_definition_manager.get_country_definition_count() * flag_type_index_map.size(); diff --git a/extension/src/openvic-extension/singletons/GameSingleton.hpp b/extension/src/openvic-extension/singletons/GameSingleton.hpp index 95ba173e..c652ade0 100644 --- a/extension/src/openvic-extension/singletons/GameSingleton.hpp +++ b/extension/src/openvic-extension/singletons/GameSingleton.hpp @@ -29,7 +29,7 @@ namespace OpenVic { godot::Vector2i flag_sheet_dims; /* The size of the flag sheet in flags, rather than pixels. */ godot::Ref flag_sheet_image; godot::Ref flag_sheet_texture; - ordered_map flag_type_index_map; + godot::HashMap flag_type_index_map; static godot::StringName const& _signal_gamestate_updated(); static godot::StringName const& _signal_mapmode_changed(); diff --git a/extension/src/openvic-extension/singletons/SoundSingleton.cpp b/extension/src/openvic-extension/singletons/SoundSingleton.cpp index 8080bc04..a9a11428 100644 --- a/extension/src/openvic-extension/singletons/SoundSingleton.cpp +++ b/extension/src/openvic-extension/singletons/SoundSingleton.cpp @@ -72,15 +72,15 @@ String SoundSingleton::to_define_file_name(String const& path, std::string_view Ref SoundSingleton::get_song(String const& path) { String name = to_define_file_name(path, music_folder); - const song_asset_map_t::const_iterator it = tracks.find(name); + const song_asset_map_t::Iterator it = tracks.find(name); if (it != tracks.end()) { // it->first = key, it->second = value - return it->second; + return it->value; } const Ref song = AudioStreamMP3::load_from_file(path); - ERR_FAIL_NULL_V_MSG(song, nullptr, Utilities::format("Failed to load music file: %s", path)); - tracks.emplace(std::move(name), song); + ERR_FAIL_NULL_V_MSG(song, Ref(), Utilities::format("Failed to load music file: %s", path)); + tracks.insert(std::move(name), song); return song; } @@ -161,29 +161,29 @@ bool SoundSingleton::load_music() { Ref SoundSingleton::get_sound(String const& path) { String name = to_define_file_name(path, sound_folder); - const sfx_asset_map_t::const_iterator it = sfx.find(name); + const sfx_asset_map_t::Iterator it = sfx.find(name); if (it != sfx.end()) { // it->first = key, it->second = value - return it->second; + return it->value; } const Ref sound = AudioStreamWAV::load_from_file(path); ERR_FAIL_NULL_V_MSG( - sound, nullptr, Utilities::format("Failed to load sound file %s", path) // named %s, path + sound, Ref(), Utilities::format("Failed to load sound file %s", path) // named %s, path ); - sfx.emplace(std::move(name), sound); + sfx.insert(std::move(name), sound); return sound; } // Get a sound by its define name Ref SoundSingleton::get_sound_stream(String const& path) { - sfx_define_map_t::iterator it = sfx_define.find(path); + sfx_define_map_t::Iterator it = sfx_define.find(path); ERR_FAIL_COND_V_MSG( - it == sfx_define.end(), nullptr, Utilities::format("Attempted to retrieve sound stream at invalid index %s.", path) + it == sfx_define.end(), Ref(), Utilities::format("Attempted to retrieve sound stream at invalid index %s.", path) ); - return it.value().audio_stream; + return it->value.audio_stream; } // get the base volume of a sound from its define name diff --git a/extension/src/openvic-extension/singletons/SoundSingleton.hpp b/extension/src/openvic-extension/singletons/SoundSingleton.hpp index 47a880f1..c340255b 100644 --- a/extension/src/openvic-extension/singletons/SoundSingleton.hpp +++ b/extension/src/openvic-extension/singletons/SoundSingleton.hpp @@ -23,11 +23,11 @@ namespace OpenVic { // cache of songs // names will be like "subfolder/songname", with "music/" base folder and the extension (.mp3) being excluded - using song_asset_map_t = deque_ordered_map>; + using song_asset_map_t = godot::HashMap>; song_asset_map_t tracks; // cache of sfx (map file name to an audio stream), only used temporarily until the sfx_define_map is built - using sfx_asset_map_t = deque_ordered_map>; + using sfx_asset_map_t = godot::HashMap>; sfx_asset_map_t sfx; // define name, stream ref, volume for sound effects so we can get these properties with a simple call in godot @@ -35,7 +35,7 @@ namespace OpenVic { godot::Ref audio_stream; std::optional volume; }; - using sfx_define_map_t = deque_ordered_map; + using sfx_define_map_t = godot::HashMap; sfx_define_map_t sfx_define; static constexpr std::string_view title_theme_name = "thecoronation_titletheme.mp3"; diff --git a/game/assets/graphics/theme/default_theme.tres b/game/assets/graphics/theme/default_theme.tres index dd8d3103..166b7d79 100644 --- a/game/assets/graphics/theme/default_theme.tres +++ b/game/assets/graphics/theme/default_theme.tres @@ -1,4 +1,4 @@ -[gd_resource type="Theme" load_steps=6 format=3 uid="uid://b48ymrsp1q8sf"] +[gd_resource type="Theme" format=3 uid="uid://b48ymrsp1q8sf"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_oe2hl"] content_margin_left = 4.0 diff --git a/game/assets/graphics/theme/main_menu.tres b/game/assets/graphics/theme/main_menu.tres index b3686fef..37c39736 100644 --- a/game/assets/graphics/theme/main_menu.tres +++ b/game/assets/graphics/theme/main_menu.tres @@ -1,4 +1,4 @@ -[gd_resource type="Theme" load_steps=36 format=3 uid="uid://qoi3oec48jp0"] +[gd_resource type="Theme" format=3 uid="uid://qoi3oec48jp0"] [ext_resource type="Script" uid="uid://d2etcw6vfl0k3" path="res://src/UI/Shared/Theme/StyleBoxCombinedTexture.gd" id="1_axke7"] [ext_resource type="Script" uid="uid://bho74dnf1rq0x" path="res://src/UI/Shared/Theme/TextureSetting.gd" id="2_7bwl2"] diff --git a/game/assets/graphics/theme/options_menu.tres b/game/assets/graphics/theme/options_menu.tres index 3f0ae1b8..dc4ea267 100644 --- a/game/assets/graphics/theme/options_menu.tres +++ b/game/assets/graphics/theme/options_menu.tres @@ -1,4 +1,4 @@ -[gd_resource type="Theme" load_steps=8 format=3 uid="uid://fbxssqcg1s0m"] +[gd_resource type="Theme" format=3 uid="uid://fbxssqcg1s0m"] [ext_resource type="Script" uid="uid://d2etcw6vfl0k3" path="res://src/UI/Shared/Theme/StyleBoxCombinedTexture.gd" id="1_6eqg5"] [ext_resource type="Script" uid="uid://bho74dnf1rq0x" path="res://src/UI/Shared/Theme/TextureSetting.gd" id="2_d0e1t"] diff --git a/game/project.godot b/game/project.godot index 3c505886..7346aee7 100644 --- a/game/project.godot +++ b/game/project.godot @@ -8,13 +8,17 @@ config_version=5 +[animation] + +compatibility/default_parent_skeleton_in_mesh_instance_3d=true + [application] config/name="OpenVic" config/description="A faithful recreation of Victoria 2: Heart of Darkness with a focus on enhancing performance, multiplayer stability, and modability for modern machines." run/main_scene="res://src/Systems/Startup/GameStart.tscn" config/use_custom_user_dir=true -config/features=PackedStringArray("4.5", "Forward Plus") +config/features=PackedStringArray("4.6", "Forward Plus") boot_splash/bg_color=Color(0, 0, 0, 0) boot_splash/show_image=false boot_splash/image="res://assets/graphics/splash_image.png" @@ -38,7 +42,7 @@ SoundManager="*res://src/Autoload/SoundManager.gd" MusicManager="*res://src/Autoload/MusicManager/MusicManager.tscn" SaveManager="*res://src/Autoload/SaveManager.gd" CursorManager="*res://src/Autoload/CursorManager.gd" -Keychain="*res://addons/keychain/Keychain.gd" +Keychain="*uid://ba4bw6vqtoail" [display] diff --git a/game/src/Systems/Startup/GameStart.tscn b/game/src/Systems/Startup/GameStart.tscn index e81a05b3..77cb5852 100644 --- a/game/src/Systems/Startup/GameStart.tscn +++ b/game/src/Systems/Startup/GameStart.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=7 format=3 uid="uid://1udsn4mggep2"] +[gd_scene format=3 uid="uid://1udsn4mggep2"] [ext_resource type="Script" uid="uid://cu1lrjpc5wbvc" path="res://src/Systems/Startup/GameStart.gd" id="1_e0cos"] [ext_resource type="PackedScene" uid="uid://3kktdpfnc0sn" path="res://src/Systems/Startup/LoadingScreen.tscn" id="2_h0oiw"] @@ -7,7 +7,7 @@ [ext_resource type="Texture2D" uid="uid://cgdnixsyh7bja" path="res://assets/graphics/splash_image.png" id="4_5b6yq"] [ext_resource type="VideoStream" uid="uid://bj077egtjnlfr" path="res://assets/graphics/splash_startup.ogv" id="5_8euyy"] -[node name="GameStartup" type="Control" node_paths=PackedStringArray("loading_screen", "vic2_dir_dialog")] +[node name="GameStartup" type="Control" unique_id=561399280 node_paths=PackedStringArray("loading_screen", "vic2_dir_dialog")] layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -18,11 +18,11 @@ script = ExtResource("1_e0cos") loading_screen = NodePath("LoadingScreen") vic2_dir_dialog = NodePath("Vic2DirDialog") -[node name="LoadingScreen" parent="." instance=ExtResource("2_h0oiw")] +[node name="LoadingScreen" parent="." unique_id=337902464 instance=ExtResource("2_h0oiw")] visible = false layout_mode = 1 -[node name="SplashContainer" type="AspectRatioContainer" parent="." node_paths=PackedStringArray("_splash_finish", "_splash_image", "_splash_video")] +[node name="SplashContainer" type="AspectRatioContainer" parent="." unique_id=1402149308 node_paths=PackedStringArray("_splash_finish", "_splash_image", "_splash_video")] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -36,23 +36,23 @@ _splash_finish = NodePath("SplashFinish") _splash_image = NodePath("SplashImage") _splash_video = NodePath("SplashVideo") -[node name="SplashFinish" type="TextureRect" parent="SplashContainer"] +[node name="SplashFinish" type="TextureRect" parent="SplashContainer" unique_id=227562310] layout_mode = 2 texture = ExtResource("3_qfv12") expand_mode = 1 -[node name="SplashImage" type="TextureRect" parent="SplashContainer"] +[node name="SplashImage" type="TextureRect" parent="SplashContainer" unique_id=2059224353] layout_mode = 2 texture = ExtResource("4_5b6yq") expand_mode = 1 -[node name="SplashVideo" type="VideoStreamPlayer" parent="SplashContainer"] +[node name="SplashVideo" type="VideoStreamPlayer" parent="SplashContainer" unique_id=1592615470] layout_mode = 2 stream = ExtResource("5_8euyy") autoplay = true expand = true -[node name="Vic2DirDialog" type="FileDialog" parent="."] +[node name="Vic2DirDialog" type="FileDialog" parent="." unique_id=1644780236] process_mode = 2 disable_3d = true title = "VIC2_DIR_DIALOG_TITLE" diff --git a/godot-cpp b/godot-cpp index e83fd090..b7242197 160000 --- a/godot-cpp +++ b/godot-cpp @@ -1 +1 @@ -Subproject commit e83fd0904c13356ed1d4c3d09f8bb9132bdc6b77 +Subproject commit b724219737883e311f4cc4da1b49a0960dd00d38