diff --git a/.github/workflows/diff_protobin.yml b/.github/workflows/diff_protobin.yml new file mode 100644 index 00000000..78dee1e0 --- /dev/null +++ b/.github/workflows/diff_protobin.yml @@ -0,0 +1,92 @@ +name: Diff Protobin + +on: + pull_request_target: + paths: + - '**/*.bin' +jobs: + custom-diff: + runs-on: ubuntu-latest + if: '!github.event.pull_request.draft' + permissions: write-all + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Install ProtoC + run: sudo apt-get install -y protobuf-compiler + + - name: Fetch PR commits + run: | + git fetch origin +refs/pull/${{ github.event.pull_request.number }}/head:refs/pull/${{ github.event.pull_request.number }}/head + git fetch origin ${{ github.base_ref }} + + - name: Get Filenames + run: | + for file in $(git diff --name-only origin/${{ github.base_ref }} refs/pull/${{ github.event.pull_request.number }}/head | grep '.bin$'); do + mkdir -p $(dirname "$file") + if [ -n "$(git ls-tree "origin/${{ github.base_ref }}" -- "$file")" ]; then + git show origin/${{ github.base_ref }}:$file > $file._old + protoc --decode=guildpoint.Guildpoint xml_converter/proto/guildpoint.proto < $file._old > $file.textproto._old + else + touch $file.textproto._old + fi + + if [ -n "$(git ls-tree "refs/pull/${{ github.event.pull_request.number }}/head" -- "$file")" ]; then + git show refs/pull/${{ github.event.pull_request.number }}/head:$file > $file._new + protoc --decode=guildpoint.Guildpoint xml_converter/proto/guildpoint.proto < $file._new > $file.textproto._new + else + touch $file.textproto._new + fi + + diff -u $file.textproto._old $file.textproto._new > $file._diff || true + echo $file >> file_list.txt + done + + - name: Get PR commit hash + id: prcommithash + run: | + PR_COMMIT_HASH=$(git log --format="%H" -n 1 refs/pull/${{ github.event.pull_request.number }}/head) + echo "Latest PR Commit Hash: $PR_COMMIT_HASH" + echo "pr_commit_hash="$PR_COMMIT_HASH >> $GITHUB_OUTPUT + + - name: Post Comment + if: always() + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = require('path'); + + const issue_number = context.issue.number; + const githubToken = process.env.GITHUB_TOKEN; + + const files = fs.readFileSync('file_list.txt', 'utf8').split("\n"); + + for (let file of files) { + if (file == "") { + continue; + } + const diff_contents = fs.readFileSync(file + "._diff", 'utf8') + let comment_body = [ + "
", + "Full Diff", + "", + "```diff", + diff_contents, + "```", + "
", + ].join("\n"); + + console.log(file) + + await github.rest.pulls.createReviewComment({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: issue_number, + path: file, + body: comment_body, + commit_id: '${{ steps.prcommithash.outputs.pr_commit_hash }}', + subject_type: "file", + }); + } diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7a53084d..db88f69d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,6 @@ -# This workflow will compile the burrio_link and export the burrito binary -# the two files will be available as an artifact. +# This workflow will compile burrio_link.exe, the burrito binary, and any +# additional libraries needed to run. All these files will then be available +# as an artifact. name: CI @@ -25,16 +26,133 @@ on: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" - Build-Linux: + Build-XMLConverter-Linux: # The type of runner that the job will run on runs-on: ubuntu-20.04 # Steps represent a sequence of tasks that will be executed as part of the job steps: - - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v4 - # - name: Update Packages - # run: sudo apt-get update && sudo apt-get upgrade + # IWYU is disabled for now due to noise. It will be re-enabled at a later date + # # `clang-9` must be installed here because of a weird unlisted dependency + # # on some sort of file that clang-9 installs. Without it iwyu would + # # complain about missing files and error out. + # - name: Install include-what-you-use + # run: | + # sudo apt-get install iwyu + # sudo apt-get install clang-9 + + - name: Install protoc + run: sudo apt-get install protobuf-compiler + + - name: Install gtest + run: sudo apt-get install libgtest-dev + + - name: Install cpplint + run: | + pip3 install cpplint + + - name: Install xml_converter python Dependencies + run: | + cd xml_converter + python3 -m venv venv + source venv/bin/activate + pip install -r requirements.txt + + - name: Build xml_converter + run: | + cd xml_converter + mkdir -v -p build + cd build + cmake .. + make + + - name: Validate xml_converter + run: | + cd xml_converter + cp build/compile_commands.json ./compile_commands.json + ./presubmit.sh + + - name: Upload created file + uses: actions/upload-artifact@v3 + with: + name: xml_converter + path: xml_converter/build/xml_converter + if-no-files-found: error + + Build-BurritoLink-Linux: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install mingw + run: sudo apt-get install gcc-mingw-w64 + + - name: Build Burrito Link + run: | + mkdir burrito_link/build + cd burrito_link/build + cmake .. + make + + - name: Upload Standalone Executable Burrito Link + uses: actions/upload-artifact@v3 + with: + name: burrito_link_exe + path: burrito_link/build/burrito_link.exe + if-no-files-found: error + + - name: Upload Shared Library Burrito Link + uses: actions/upload-artifact@v3 + with: + name: burrito_link_dll + path: burrito_link/build/d3d11.dll + if-no-files-found: error + + Build-BurritoFG-Linux: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Build X11_FG + run: | + cd burrito-fg + cargo build --release + + - name: Upload created file + uses: actions/upload-artifact@v3 + with: + name: BurritoFG + path: burrito-fg/target/release/libburrito_fg.so + if-no-files-found: error + + Build-TacoParser-Linux: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Build taco_parser + run: | + cd taco_parser + cargo build --release + + - name: Upload created file + uses: actions/upload-artifact@v3 + with: + name: TacoParser + path: taco_parser/target/release/libgw2_taco_parser.so + if-no-files-found: error + + Build-BurritoUI-Linux: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v4 # - name: Cache Godot # id: cache-godot @@ -43,14 +161,15 @@ jobs: # path: ./Godot_v${GODOT_VERSION}-stable_linux_headless.64 # key: ${{ runner.os }}-godot-${GODOT_VERSION}-${CACHE_STRING} - # + - name: Download Godot # if: steps.cache-godot.outputs.cache-hit != 'true' run: | - wget -q https://downloads.tuxfamily.org/godotengine/${GODOT_VERSION}/Godot_v${GODOT_VERSION}-stable_linux_headless.64.zip + wget -q https://github.com/godotengine/godot/releases/download/${GODOT_VERSION}-stable/Godot_v${GODOT_VERSION}-stable_linux_headless.64.zip unzip Godot_v${GODOT_VERSION}-stable_linux_headless.64.zip rm Godot_v${GODOT_VERSION}-stable_linux_headless.64.zip + # - name: Cache Godot Templates # id: cache-godot-templates # uses: actions/cache@v2 @@ -64,59 +183,82 @@ jobs: run: | mkdir -v -p ~/.local/share/godot/templates/${GODOT_VERSION}.stable/ - wget -q https://downloads.tuxfamily.org/godotengine/${GODOT_VERSION}/Godot_v${GODOT_VERSION}-stable_export_templates.tpz + wget -q https://github.com/godotengine/godot/releases/download/${GODOT_VERSION}-stable/Godot_v${GODOT_VERSION}-stable_export_templates.tpz unzip Godot_v${GODOT_VERSION}-stable_export_templates.tpz mv templates/* ~/.local/share/godot/templates/${GODOT_VERSION}.stable/ ls ~/.local/share/godot/templates/${GODOT_VERSION}.stable/ + - name: Fake The GDNative Files + run: | + mkdir -p burrito-fg/target/release/ + touch burrito-fg/target/release/libburrito_fg.so + mkdir -p taco_parser/target/release/ + touch taco_parser/target/release/libgw2_taco_parser.so - - name: Install mingw - run: sudo apt-get install gcc-mingw-w64 + - name: Build Burrito + run: | + mkdir -v -p build + ./Godot_v${GODOT_VERSION}-stable_linux_headless.64 --export "Linux/X11" + chmod +x build/burrito.x86_64 + - uses: actions/upload-artifact@v3 + with: + name: Burrito_UI + path: build/burrito.x86_64 + if-no-files-found: error - # Runs a single command using the runners shell - - name: Create the Output Directory - run: mkdir output - - - name: Build X11_FG - run: | - cd burrito-fg - cargo build --release + Package-Burrito-Linux: + runs-on: ubuntu-20.04 + needs: + - Build-XMLConverter-Linux + - Build-BurritoLink-Linux + - Build-BurritoUI-Linux + - Build-BurritoFG-Linux + - Build-TacoParser-Linux + steps: + - name: Download Burrito UI + uses: actions/download-artifact@v3 + with: + name: Burrito_UI - - name: Build taco_parser - run: | - cd taco_parser - cargo build --release + - name: Download Burrito FG + uses: actions/download-artifact@v3 + with: + name: BurritoFG - - name: Build Burrito Link - run: | - mkdir output/burrito_link - mkdir burrito_link/build - cd burrito_link/build - cmake .. - make - mv burrito_link.exe ../../output/burrito_link - mv d3d11.dll ../../output/burrito_link + - name: Download TacoParser + uses: actions/download-artifact@v3 + with: + name: TacoParser + - name: Download XML Converter + uses: actions/download-artifact@v3 + with: + name: xml_converter + + - name: Download Burrito Link Exe + uses: actions/download-artifact@v3 + with: + name: burrito_link_exe + + - name: Download Burrito Link DLL + uses: actions/download-artifact@v3 + with: + name: burrito_link_dll - - name: Build Burrito - run: | - mkdir build - ./Godot_v${GODOT_VERSION}-stable_linux_headless.64 --export "Linux/X11" - chmod +x build/burrito.x86_64 - mv build/burrito.x86_64 output/ - mv build/libburrito_fg.so output/ - mv build/libgw2_taco_parser.so output/ + - name: Move Burrito Link + run: | + mkdir burrito_link/ + mv burrito_link.exe burrito_link/ + mv d3d11.dll burrito_link/ - - uses: actions/upload-artifact@v2.2.4 + - uses: actions/upload-artifact@v3 with: # Artifact name name: "Burrito_Linux" # optional, default is artifact # A file, directory or wildcard pattern that describes what to upload - path: "output/*" + path: "./*" # The desired behavior if no files are found using the provided path. if-no-files-found: error - # Duration after which artifact will expire in days. 0 means using default retention. - retention-days: 0 diff --git a/Category2D.gd b/Category2D.gd new file mode 100644 index 00000000..8f028b83 --- /dev/null +++ b/Category2D.gd @@ -0,0 +1,18 @@ +extends Node2D + +var trails2d: Array = [] +var subcategories: Array = [] + +func add_trail2d(trail2d): + self.add_child(trail2d, true) + trails2d.push_back(trail2d) + +func add_subcategory(subcategory): + self.add_child(subcategory, true) + subcategories.push_back(subcategory) + +func clear_all(): + self.trails2d = [] + self.subcategories = [] + for child in self.get_children(): + child.queue_free() diff --git a/Category2D.tscn b/Category2D.tscn new file mode 100644 index 00000000..37bc52c6 --- /dev/null +++ b/Category2D.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://Category2D.gd" type="Script" id=1] + +[node name="Category2D" type="Node2D"] +script = ExtResource( 1 ) diff --git a/Category3D.gd b/Category3D.gd new file mode 100644 index 00000000..1bf64737 --- /dev/null +++ b/Category3D.gd @@ -0,0 +1,29 @@ +extends Spatial + +var trails3d: Array = [] +var icons: Array = [] +var subcategories: Array = [] + + +func add_trail3d(trail3d): + self.add_child(trail3d, true) + trails3d.push_back(trail3d) + +func add_icon(icon): + self.add_child(icon, true) + icons.push_back(icon) + +func add_subcategory(subcategory): + self.add_child(subcategory, true) + subcategories.push_back(subcategory) + +func clear_all(): + self.trails3d = [] + self.icons = [] + self.subcategories = [] + for child in self.get_children(): + child.queue_free() + +func remove_icon(icon): + self.icons.remove(icon) + icon.queue_free() diff --git a/Category3D.tscn b/Category3D.tscn new file mode 100644 index 00000000..83bf5edb --- /dev/null +++ b/Category3D.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://Category3D.gd" type="Script" id=1] + +[node name="Category" type="Spatial"] +script = ExtResource( 1 ) diff --git a/CategoryData.gd b/CategoryData.gd new file mode 100644 index 00000000..3c4a6b04 --- /dev/null +++ b/CategoryData.gd @@ -0,0 +1,6 @@ +const Guildpoint = preload("res://guildpoint.gd") + +var category3d: Spatial +var category2d: Node2D +var guildpoint_category: Guildpoint.Category +var is_visible = false diff --git a/FileHandler.gd b/FileHandler.gd new file mode 100644 index 00000000..c74f53ce --- /dev/null +++ b/FileHandler.gd @@ -0,0 +1,65 @@ +const converter_executable_path = "./xml_converter/build/xml_converter" + +static func call_xml_converter(args: PoolStringArray): + var output: Array = [] + print(args) + var result: int = OS.execute(converter_executable_path, args, true, output, true) + print(output) + if result != OK: + print("Failed to execute the converter. Error code:", result) + else: + print("Command executed successfully.") + +static func create_directory_if_missing(path: String): + var dir = Directory.new() + if not dir.dir_exists(path): + var success = dir.make_dir(path) + if success != OK: + print("Error: Could not create data folder:", path) + +static func find_file_duplicate(directory_path: String, target_name: String, target_content: PoolByteArray, relative_path: String): + var dir = Directory.new() + if dir.open(directory_path) != OK: + return null + dir.list_dir_begin(true) + var file_name = dir.get_next() + while file_name != "": + var full_path = directory_path.plus_file(file_name) + var current_relative_path = relative_path.plus_file(file_name) + if dir.current_is_dir(): + var found_path = find_file_duplicate(full_path, target_name, target_content, current_relative_path) + if found_path != "": + dir.list_dir_end() + return found_path + if file_name == target_name: + var file = File.new() + file.open(full_path, File.READ) + var file_content = file.get_buffer(file.get_len()) + file.close() + if file_content == target_content: + dir.list_dir_end() + return current_relative_path + file_name = dir.get_next() + return null + +static func find_image_duplicates(file_path: String, destintation_dir: String): + var file_name: String = file_path.get_file() + var file_extension: String = file_name.get_extension().to_lower() + if not file_extension == "png": + print("File is not a supported image type. Please choose a png") + return "" + + var file: File = File.new() + file.open(file_path, File.READ) + var file_content = file.get_buffer(file.get_len()) + var relative_path = find_file_duplicate(destintation_dir, file_name, file_content, "") + return relative_path + + +static func copy_file(file_path: String, destination_path: String): + var dir = Directory.new() + var result = dir.copy(file_path, destination_path) + if result == OK: + print("File imported successfully.") + else: + print("Failed to import file.") diff --git a/Gizmo/PointEdit.gd b/Gizmo/PointEdit.gd index 93ddfa5c..1b9bcb3f 100644 --- a/Gizmo/PointEdit.gd +++ b/Gizmo/PointEdit.gd @@ -2,7 +2,8 @@ extends Spatial var camera: Camera signal selected(selected_object) -signal deselected(selected_object) +signal deselected() +signal updated(point_position) var last_translation var selected: bool = false @@ -27,32 +28,6 @@ func select(camera, event): $Pillar/CollisionShape.disabled = false emit_signal("selected", self) -var object_link = null -var object_2d_link = null -var object_index:int = 0 -var point_type: String - - -func link_point(point_type: String, object_link, object_2d_link = null, object_index = 0): - self.point_type = point_type - self.object_link = object_link - if point_type == "path" || point_type == "area": - self.object_2d_link = object_2d_link - self.object_index = object_index - if point_type == "icon": - pass - - -func update_point(): - if self.translation != self.last_translation: - if point_type == "path" || point_type == "area": - self.object_link.set_point_position(self.object_index, self.translation) - self.object_2d_link.points[self.object_index] = Vector2(self.translation.x, self.translation.z) - if point_type == "icon": - self.object_link.translation = self.translation - print("update") - self.last_translation = self.translation - ################################################################################ # Handle resizing the control nodes so that no matter how far away from the @@ -70,4 +45,6 @@ func _process(delta): $Plane.scale = new_scale $Pillar.scale = new_scale - update_point() + if self.translation != self.last_translation: + emit_signal("updated", self.translation) + self.last_translation = self.translation diff --git a/Icon.gd b/Icon.gd index 1d5dbaef..f4fc9209 100644 --- a/Icon.gd +++ b/Icon.gd @@ -1,9 +1,11 @@ extends Sprite3D -var texture_path +const Guildpoint = preload("res://guildpoint.gd") + +var guildpoint: Guildpoint.Icon +var category: TreeItem + func set_icon_image(texture_path: String): - self.texture_path = texture_path - var texture_file = File.new() var image = Image.new() texture_file.open(texture_path, File.READ) @@ -17,3 +19,6 @@ func set_icon_image(texture_path: String): self.texture = texture self.material_override.set_shader_param("texture_albedo", texture) + +func set_position(position: Vector3): + self.translation = position diff --git a/ImportPackDialog.gd b/ImportPackDialog.gd new file mode 100644 index 00000000..597bf7da --- /dev/null +++ b/ImportPackDialog.gd @@ -0,0 +1,25 @@ +extends FileDialog + +const FileHandler = preload("res://FileHandler.gd") +var downloaded_markers_dir: String +var unsaved_markers_dir: String +var user_data_dir: String + +func _ready(): + #TODO: Move these to global file Settings so they can be customized + self.user_data_dir = str(OS.get_user_data_dir()) + self.downloaded_markers_dir = self.user_data_dir.plus_file("packs") + self.unsaved_markers_dir = self.user_data_dir.plus_file("protobins") + FileHandler.create_directory_if_missing(self.downloaded_markers_dir) + FileHandler.create_directory_if_missing(self.unsaved_markers_dir) + +func _on_FileDialog_dir_selected(dir_path: String): + print("Selected folder:", dir_path) + var new_path: String = self.downloaded_markers_dir.plus_file(dir_path.get_file()) + FileHandler.create_directory_if_missing(new_path) + var args: PoolStringArray = [ + "--input-taco-path", dir_path, + "--output-guildpoint-path", new_path, + "--output-split-guildpoint-path", self.unsaved_markers_dir + ] + FileHandler.call_xml_converter(args) diff --git a/Route.tscn b/Route.tscn deleted file mode 100644 index 35c293f9..00000000 --- a/Route.tscn +++ /dev/null @@ -1,10 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://Route.gd" type="Script" id=1] -[ext_resource path="res://Route.tres" type="Material" id=2] - -[node name="Path" type="Spatial"] -script = ExtResource( 1 ) - -[node name="MeshInstance" type="MeshInstance" parent="."] -material_override = ExtResource( 2 ) diff --git a/Settings.gd b/Settings.gd index 663f6e2f..2af0fb9b 100644 --- a/Settings.gd +++ b/Settings.gd @@ -3,6 +3,7 @@ extends Node const CONFIG_PATH = "user://settings.json" var _config_data = {} +var local_category_data = {} var minimum_width: int = 800 var minimum_height: int = 600 @@ -25,7 +26,9 @@ func _ready(): if self._config_data == null: self._config_data = {} - + + if "local_category_data" in self._config_data: + self.local_category_data = self._config_data["local_category_data"] if "minimum_width" in self._config_data: self.minimum_width = self._config_data["minimum_width"] if "minimum_height" in self._config_data: @@ -54,8 +57,9 @@ func save(): "burrito_link_auto_launch_enabled": burrito_link_auto_launch_enabled, "burrito_link_wine_path": burrito_link_wine_path, "burrito_link_env_args": burrito_link_env_args, + "local_category_data": local_category_data } var file = File.new() file.open(CONFIG_PATH, File.WRITE) - file.store_string(JSON.print(self._config_data)) + file.store_string(JSON.print(self._config_data, " ")) diff --git a/Spatial.gd b/Spatial.gd index 321cdcc2..419248cc 100644 --- a/Spatial.gd +++ b/Spatial.gd @@ -5,7 +5,6 @@ var peers = [] var map_id:int = 0 - var map_is_open: bool var compass_is_top_right: bool @@ -13,13 +12,15 @@ var edit_panel_open: bool = false # This is the path to the texture that will be used for the next created 3d-path # object or icon object in the UI -var next_texture_path: String = "" +var next_texture_id: int = 0 -# A pointer to the path object that any new nodes should be appended to. If -# the value is null then a new path will be created the next time a path point +# A pointer to the trail object that any new nodes should be appended to. If +# the value is null then a new trail will be created the next time a trail point # will be created. -var currently_active_path = null -var currently_active_path_2d = null +var currently_active_trail3d = null +var currently_active_trail2d = null +var currently_active_guildpoint_trail = null +var currently_active_category = null var map_was_open = false @@ -36,17 +37,35 @@ var compass_width: int = 0; # A temporary setting able to be configured by the user. It is used to allow # for faster trail mesh generation. The higher the value the fewer samples are # taken for the MeshCSG leading to an overall lower number of polygons. -var path_resolution = 1 +var trail_resolution = 1 -# Variables that store opposit corners of the compass -var compass_corner1 -var compass_corner2 #x11 fg and window id var x11_fg: X11_FG var taco_parser: TacoParser var x11_window_id_burrito: int var is_transient:bool = false +# Scenes used throughout this scene +const trail3d_scene = preload("res://Trail3D.tscn") +const icon_scene = preload("res://Icon.tscn") +const category3d_scene = preload("res://Category3D.tscn") +const category2d_scene = preload("res://Category2D.tscn") +const trail2d_scene = preload("res://Trail2D.tscn") +const gizmo_scene = preload("res://Gizmo/PointEdit.tscn") + +# Scripts containing code used by this scene +const CategoryData = preload("res://CategoryData.gd") +const Guildpoint = preload("res://guildpoint.gd") +const FileHandler = preload("res://FileHandler.gd") + +# File path for the the json that contains a hash of the data files +const HASH_BY_MAP_ID_FILEPATH: String = "user://hash_by_map_id.json" + +##########Node Connections########### +onready var markers_ui := $Control/Dialogs/CategoriesDialog/MarkersUI as Tree +onready var markers_3d := $Markers3D as Spatial +onready var markers_2d := $Control/Markers2D as Node2D + # Variables that store informations about ui scaling # The ui-size as read from the link can have the values [0=small; 1=normal; 2=large; 3=larger] var ui_size: int = 1 @@ -66,6 +85,8 @@ const minimap_scale = { # Called when the node enters the scene tree for the first time. func _ready(): + self.markers_ui.set_column_expand(1, false) + self.markers_ui.set_column_min_width(1, 24) get_tree().get_root().set_transparent_background(true) x11_fg = X11_FG.new() taco_parser = TacoParser.new() @@ -80,6 +101,7 @@ func _ready(): # Postion at top left corner OS.set_window_position(Vector2(0,0)) set_minimal_mouse_block() + server.listen(4242) if (Settings.burrito_link_auto_launch_enabled): @@ -232,9 +254,8 @@ func decode_frame_packet(spb: StreamPeerBuffer): var unchecked_flag = (ui_flags & 0xFFFFFF80) != 0x00000000; if map_is_open != map_was_open: - $Paths.visible = !map_is_open - $Icons.visible = !map_is_open - reset_minimap_masks() + self.markers_3d.visible = !map_is_open + reset_minimap_masks(false) map_was_open = map_is_open if unchecked_flag: @@ -284,15 +305,15 @@ func decode_frame_packet(spb: StreamPeerBuffer): delta_position = player_map_position - Vector2(x, y); #print(map_rotation) - $Control/MiniMap.rotation = map_rotation + $Control/Markers2D.rotation = map_rotation else: - $Control/MiniMap.rotation = 0 + $Control/Markers2D.rotation = 0 var map_midpoint = map_size/2 + map_corner; - $Control/MiniMap.scale=Vector2(map_object_scaling, map_object_scaling) + $Control/Markers2D.scale=Vector2(map_object_scaling, map_object_scaling) var map_translation = map_offset - $Control/MiniMap.position = (map_translation / map_scale) + map_midpoint - player_map_position + delta_position + $Control/Markers2D.position = (map_translation / map_scale) + map_midpoint - player_map_position + delta_position var new_feet_location = Vector3(player_position.x, player_position.y, -player_position.z) $FeetLocation.translation = new_feet_location @@ -352,23 +373,22 @@ func decode_context_packet(spb: StreamPeerBuffer): if self.map_id != old_map_id: print("New Map") - - print("Saving Old Map") - self.markerdata[str(old_map_id)] = data_from_renderview() + var old_texture_path: String = "" + old_texture_path = get_texture_path(self.next_texture_id) + if old_map_id != 0 and not read_hash(old_map_id) == make_hash(self.guildpoint_data.to_bytes()): + print("Saving Old Map") + save_map_data(old_map_id) print("Loading New Map") - gen_map_markers() - - # TODO move this to reset_minimap_masks - for child in $Paths.get_children(): - child.get_node("MeshInstance").material_override.set_shader_param("map_size", Vector2(compass_width, compass_height)) - - # TODO move this to reset_minimap_masks - for icon in $Icons.get_children(): - icon.material_override.set_shader_param("map_size", Vector2(compass_width, compass_height)) + load_guildpoint_markers(self.map_id) + self.next_texture_id = get_texture_index(old_texture_path) + if self.next_texture_id == -1: + self.guildpoint_data.add_textures().set_filepath(old_texture_path) + self.next_texture_id = self.guildpoint_data.get_textures().size() - 1 reset_minimap_masks() + func decode_timeout_packet(spb: StreamPeerBuffer): if Settings.burrito_link_auto_launch_enabled: print("Link Timeout Reached, should restart link if started by burrito automatically") @@ -376,63 +396,64 @@ func decode_timeout_packet(spb: StreamPeerBuffer): launch_burrito_link() -func reset_minimap_masks(): +func reset_minimap_masks(reset_3d: bool = true): var viewport_size = get_viewport().size - compass_corner1 = Vector2(0, 0) - compass_corner2 = viewport_size + var compass_corner1 = Vector2(0, 0) + var compass_corner2 = viewport_size if !map_is_open && !compass_is_top_right: compass_corner1 = Vector2(viewport_size.x-compass_width, self.minimap_scale[self.ui_size]["offset"]) compass_corner2 = compass_corner1 + Vector2(compass_width, compass_height) elif !map_is_open && compass_is_top_right: - compass_corner1 = viewport_size - Vector2(compass_width, compass_height) - compass_corner2 = compass_corner1 + Vector2(compass_width, compass_height) - - for minimap_path in $Control/MiniMap.get_children(): - minimap_path.material.set_shader_param("minimap_corner", compass_corner1) - minimap_path.material.set_shader_param("minimap_corner2", compass_corner2) - -var markerdata = {} + compass_corner1 = viewport_size - Vector2(self.compass_width, self.compass_height) + compass_corner2 = compass_corner1 + Vector2(self.compass_width, self.compass_height) + + for category in self.markers_2d.subcategories: + reset_2D_minimap_masks(category, compass_corner1, compass_corner2) + + if reset_3d: + for category in self.markers_3d.subcategories: + reset_3D_minimap_masks(category) + +func reset_2D_minimap_masks(category2d: Node2D, compass_corner1: Vector2, compass_corner2: Vector2): + for trail2d in category2d.trails2d: + trail2d.material.set_shader_param("minimap_corner", compass_corner1) + trail2d.material.set_shader_param("minimap_corner2", compass_corner2) + for subcategory in category2d.subcategories: + reset_2D_minimap_masks(subcategory, compass_corner1, compass_corner2) + +func reset_3D_minimap_masks(category: Spatial): + for trail in category.trails3d: + trail.get_node("MeshInstance").material_override.set_shader_param("map_size", Vector2(self.compass_width, self.compass_height)) + for icon in category.icons: + icon.material_override.set_shader_param("map_size", Vector2(self.compass_width, self.compass_height)) + for subcategory in category.subcategories: + reset_3D_minimap_masks(subcategory) + + +var guildpoint_data = Guildpoint.Guildpoint.new() +# We save the marker data in this directory when the files are have been split +# by Map ID. All changes made by the editor are automatically saved in these +# files prior to export. +var unsaved_markers_dir = "user://protobin_by_map_id/" +var saved_markers_dir = "user://protobin/" var marker_file_path = "" -func load_taco_markers(marker_json_file): - self.marker_file_path = marker_json_file - - if is_xml_file(marker_json_file): - print("Loading XML file from path ", marker_json_file) - var parsed_taco_tuple = taco_parser.parse_taco_xml(marker_json_file) - var json_payload = parsed_taco_tuple[0] - var error_message = parsed_taco_tuple[1] - if error_message != "": - print("XML parsing failed with error message: ", error_message) - self.markerdata = JSON.parse(json_payload).result - else: - print("Loading Json file from path ", marker_json_file) - var file = File.new() - file.open(marker_json_file, file.READ) - var text = file.get_as_text() - self.markerdata = JSON.parse(text).result - - relative_textures_to_absolute_textures(marker_file_path.get_base_dir()) - - gen_map_markers() - -func is_xml_file(input_file): - return input_file.split(".")[-1] == "xml" - -func relative_textures_to_absolute_textures(marker_file_dir): - for map in markerdata: - for icon in markerdata[map]["icons"]: - if !icon["texture"].is_abs_path(): - icon["texture"] = marker_file_dir + "/" + icon["texture"] - #print("ABS", icon["texture"]) - for path in markerdata[map]["paths"]: - if !path["texture"].is_abs_path(): - path["texture"] = marker_file_dir + "/" + path["texture"] +func load_guildpoint_markers(map_id_to_load: int): + self.marker_file_path = self.unsaved_markers_dir + String(map_id_to_load) + ".bin" + self.guildpoint_data = Guildpoint.Guildpoint.new() + clear_map_markers() + init_category_tree() + var file = File.new() + print("Loading protobuf file from path ", self.marker_file_path) + file.open(self.marker_file_path, file.READ) + var data = file.get_buffer(file.get_len()) + self.guildpoint_data.from_bytes(data) + if !Guildpoint.PB_ERR.NO_ERRORS: + print("OK") + else: + print(Guildpoint.PB_ERR) + guildpoint_categories_to_godot_nodes() -var route_scene = load("res://Route.tscn") -var icon_scene = load("res://Icon.tscn") -var path2d_scene = load("res://Route2D.tscn") -var gizmo_scene = load("res://Gizmo/PointEdit.tscn") ##########Gizmo Stuff########### # How long the ray to search for 3D clickable object should be. @@ -505,41 +526,97 @@ func _unhandled_input(event): ################################################################################ # ################################################################################ -onready var icons = $Icons -onready var paths = $Paths -onready var minimap = $Control/MiniMap - -func gen_map_markers(): - # Clear all the rendered assets to mak way for the new ones - for path in paths.get_children(): - path.queue_free() - - for path2d in minimap.get_children(): - path2d.queue_free() - - for icon in icons.get_children(): - icon.queue_free() - - # Load the data from the markers - if str(map_id) in markerdata: - var map_markerdata = markerdata[str(map_id)] - for path in map_markerdata["paths"]: - gen_new_path(path["points"], path["texture"]) - - for icon in map_markerdata["icons"]: - var position = Vector3(icon["position"][0], icon["position"][1], icon["position"][2]) - gen_new_icon(position, icon["texture"]) - -func gen_new_path(points: Array, texture_path: String): - var points_2d: PoolVector2Array = [] - - +func clear_map_markers(): + # Clear all the rendered assets to make way for the new ones + self.markers_3d.clear_all() + self.markers_2d.clear_all() + +func init_category_tree(): + self.markers_ui.clear() + var root : TreeItem + root = self.markers_ui.create_item() + root.set_text(0, "Markers") + root.set_expand_right(0, true) + + + +func guildpoint_categories_to_godot_nodes(): + for guildpoint_category in self.guildpoint_data.get_category(): + _guildpoint_categories_to_godot_nodes(null, guildpoint_category, self.markers_3d, self.markers_2d, false) + + +func _guildpoint_categories_to_godot_nodes(item: TreeItem, guildpoint_category: Guildpoint.Category, parent_category3d: Spatial, parent_category2d: Node2D, collapsed: bool): + var godot_category3d = category3d_scene.instance() + var godot_category2d = category2d_scene.instance() + parent_category3d.add_subcategory(godot_category3d) + parent_category2d.add_subcategory(godot_category2d) + + var category_item: TreeItem = self.markers_ui.create_item(item) + var category_data = CategoryData.new() + category_data.guildpoint_category = guildpoint_category + category_data.category3d = godot_category3d + category_data.category2d = godot_category2d + + category_item.set_metadata(0, category_data) + var category_name: String = guildpoint_category.get_name() + if category_name == "": + print("Category found with no name.") + category_name = "No Name" + category_item.set_text(0, category_name) + category_item.set_cell_mode(1, TreeItem.CELL_MODE_CHECK) + # TODO 214: The format for the category name stored here is a/b/c. + # This could be changed to some UUID. + godot_category3d.name = category_name + var relative_path: String = self.markers_3d.get_path_to(godot_category3d) + category_item.set_checked(1, Settings.local_category_data.get(relative_path, {}).get("checked", false)) + category_item.set_tooltip(1, "Show/Hide") + category_item.set_editable(1, true) + category_item.set_collapsed(collapsed) + category_item.set_selectable(1, false) + + category_data.is_visible = category_item.is_checked(1) + godot_category3d.visible = category_data.is_visible + godot_category2d.visible = category_data.is_visible + + for trail in guildpoint_category.get_trail(): + gen_new_trail(trail, category_item) + + for icon in guildpoint_category.get_icon(): + gen_new_icon(icon, category_item) + + + for category_child in guildpoint_category.get_children(): + _guildpoint_categories_to_godot_nodes(category_item, category_child, godot_category3d, godot_category2d, true) + + +func apply_category_visibility_to_nodes(category_item: TreeItem): + var category_data = category_item.get_metadata(0) + var relative_path: String = self.markers_3d.get_path_to(category_data.category3d) + # TODO 214: The format for the category name stored here is a/b/c. + # This could be changed to some UUID. + Settings.local_category_data[relative_path] = { + "checked" : category_item.is_checked(1), + } + Settings.save() + + category_data.is_visible = category_item.is_checked(1) + category_data.category3d.visible = category_data.is_visible + category_data.category2d.visible = category_data.is_visible + + +func gen_new_trail(guildpoint_trail: Guildpoint.Trail, category_item: TreeItem) -> Array: # Create the texture to use from an image file # TODO: We want to be able to cache this data so that if a texture is used # by multiple objects we only need to keep ony copy of it in memory. #22. # TODO: We want to have two copies of each texture in memory one for 2D # which does not use srgb to render properly, and one for 3D which forces # srgb to render properly. Issue #23. + var texture_id: int = guildpoint_trail.get_texture_id() + if texture_id == 0: + var category_data = category_item.get_metadata(0) + print("Warning: No texture found in " , category_data.guildpoint_category.get_name()) + # TODO(330): Error Textures + var texture_path: String = self.unsaved_markers_dir + get_texture_path(texture_id) var texture_file = File.new() var image = Image.new() if !texture_file.file_exists(texture_path): @@ -552,93 +629,86 @@ func gen_new_path(points: Array, texture_path: String): texture.storage = ImageTexture.STORAGE_COMPRESS_LOSSLESS texture.create_from_image(image, 22) - - - # Create a new 3D route - var new_route = route_scene.instance() -# var new_curve = Curve3D.new() -# for point in points: -# new_curve.add_point(Vector3(point[0], point[1], -point[2])) -# points_2d.append(Vector2(point[0], -point[2])) - -# new_path.curve = new_curve - new_route.texture_path = texture_path # Save the location of the image for later - #path_3d_markers.append(new_path) - - var points_3d := PoolVector3Array() - for point in points: - points_3d.append(Vector3(point[0], point[1], -point[2])) - - new_route.create_mesh(points_3d) - new_route.set_texture(texture) - paths.add_child(new_route) - - - - - - - - for point in points: - points_2d.append(Vector2(point[0], -point[2])) - - - # Create a new 2D Path - var new_2d_path = path2d_scene.instance() - new_2d_path.points = points_2d - new_2d_path.texture = texture - minimap.add_child(new_2d_path) - - self.currently_active_path = new_route - self.currently_active_path_2d = new_2d_path - - -################################################################################ -# -################################################################################ -func gen_new_icon(position: Vector3, texture_path: String): - position.z = -position.z + var new_trail3d = trail3d_scene.instance() + new_trail3d.guildpoint = guildpoint_trail + new_trail3d.refresh_mesh() + new_trail3d.set_texture(texture) + var category_data = category_item.get_metadata(0) + category_data.category3d.add_trail3d(new_trail3d) + + + # Create a new 2D Trail + var new_trail2d = trail2d_scene.instance() + var points_2d := PoolVector2Array() + new_trail2d.texture = texture + new_trail2d.guildpoint = guildpoint_trail + new_trail2d.refresh_points() + category_data.category2d.add_trail2d(new_trail2d) + + return [new_trail3d, new_trail2d] + +func gen_new_icon(guildpoint_icon: Guildpoint.Icon, category_item: TreeItem): + var texture_id: int = guildpoint_icon.get_texture_id() + if texture_id == 0: + var category_data = category_item.get_metadata(0) + print("Warning: No texture found in " , category_data.guildpoint_category.get_name()) + # TODO(330) Error Textures + var texture_path: String = self.unsaved_markers_dir + get_texture_path(texture_id) + var position = guildpoint_icon.get_position() + if position == null: + var category_data = category_item.get_metadata(0) + print("Warning: No position found for icon ", category_data.guildpoint_category.get_name()) + return + var position_vector = Vector3(position.get_x(), position.get_y(), -position.get_z()) var new_icon = icon_scene.instance() - new_icon.translation = position + new_icon.translation = position_vector new_icon.set_icon_image(texture_path) + new_icon.guildpoint = guildpoint_icon + var category_data = category_item.get_metadata(0) + category_data.category3d.add_icon(new_icon) - #icon_markers.append(new_icon) - icons.add_child(new_icon) - -# This function take all of the currently rendered objects and converts it into -# the data format that is saved/loaded from. -func data_from_renderview(): - var icons_data = [] - var paths_data = [] - - for icon in $Icons.get_children(): - icons_data.append({ - "position": [icon.translation.x, icon.translation.y, -icon.translation.z], - "texture": icon.texture_path - }) - - for path in $Paths.get_children(): - #print(path) - var points = [] - for point in range(path.get_point_count()): - var point_position:Vector3 = path.get_point_position(point) - points.append([point_position.x, point_position.y, -point_position.z]) - paths_data.append({ - "points": points, - "texture": path.texture_path - }) - - var data_out = {"icons": icons_data, "paths": paths_data} - return data_out - -func _on_main_menu_toggle_pressed(): - $Control/Dialogs/MainMenu.show() - set_maximal_mouse_block() - -func _on_FileDialog_file_selected(path): - load_taco_markers(path) - +################################################################################ +# Section of functions for saving data to file +################################################################################ +func save_map_data(map_id: int): + var packed_bytes = self.guildpoint_data.to_bytes() + var file = File.new() + file.open(self.marker_file_path, file.WRITE) + file.store_buffer(packed_bytes) + +func make_hash(data: PoolByteArray) -> String: + var ctx = HashingContext.new() + ctx.start(HashingContext.HASH_MD5) + ctx.update(data) + var res: PoolByteArray = ctx.finish() + return res.hex_encode() + + +# Save all hashes +func save_hashes(): + var file = File.new() + var data = {} + var dir = Directory.new() + dir.open(self.unsaved_markers_dir) + dir.list_dir_begin() + var file_name = dir.get_next() + while file_name != "": + if dir.file_exists(file_name): + file.open(file_name, File.READ) + data[file_name.get_basename()] = make_hash(file.get_buffer(file.get_len())) + file_name = dir.get_next() + file.open(HASH_BY_MAP_ID_FILEPATH, File.WRITE) + file.store_string(JSON.print(data)) + +func read_hash(map_id: int) -> String: + var file = File.new() + if not file.file_exists(HASH_BY_MAP_ID_FILEPATH): + return "" + file.open(HASH_BY_MAP_ID_FILEPATH, File.READ) + return JSON.parse(file.get_as_text()).result.get(String(map_id), "") +################################################################################ +# Adjustment and gizmo functions ################################################################################ # The adjust nodes button creates handles at all the node points to allow for # editing of them via in-game interface. (Nodes can only be edited if the input @@ -652,59 +722,90 @@ func _on_AdjustNodesButton_pressed(): func gen_adjustment_nodes(): - for index in range(self.paths.get_child_count()): - var route = self.paths.get_child(index) - var path2d = self.minimap.get_child(index) - #var curve: Curve3D = path.curve - for i in range(route.get_point_count()): - var gizmo_position = route.get_point_position(i) - + if self.currently_active_category == null: + print("No category selected") + return + var guildpoint_category = self.currently_active_category.get_metadata(0).guildpoint_category + var category3d = self.currently_active_category.get_metadata(0).category3d + var category2d = self.currently_active_category.get_metadata(0).category2d + for trail_index in guildpoint_category.get_trail().size(): + var guildpoint_trail = guildpoint_category.get_trail()[trail_index] + var trail3d = category3d.trails3d[trail_index] + var trail2d = category2d.trails2d[trail_index] + for point_index in get_trail_point_count(guildpoint_trail): + var gizmo_position = get_trail_point_position(guildpoint_trail, point_index) # Simplistic cull to prevent nodes that are too far away to be # visible from being created. Additional work can be done here # if this is not enough of an optimization in the future. if (gizmo_position.distance_squared_to(self.correct_player_position) > 10000): continue - var new_gizmo = gizmo_scene.instance() new_gizmo.translation = gizmo_position - new_gizmo.link_point("path", route, path2d, i) - new_gizmo.connect("selected", self, "on_gizmo_selected") + new_gizmo.connect("selected", self, "on_trail_gizmo_selected", [guildpoint_trail, trail3d, trail2d, point_index]) new_gizmo.connect("deselected", self, "on_gizmo_deselected") + new_gizmo.connect("updated", self, "set_trail_point_position", [guildpoint_trail, trail3d, trail2d, point_index]) $Gizmos.add_child(new_gizmo) - - for index in range(self.icons.get_child_count()): - var icon = self.icons.get_child(index) + for icon_index in guildpoint_category.get_icon().size(): + var guildpoint_icon = guildpoint_category.get_icon()[icon_index] + var icon = category3d.icons[icon_index] var new_gizmo = gizmo_scene.instance() - new_gizmo.translation = icon.translation - new_gizmo.link_point("icon", icon) - new_gizmo.connect("selected", self, "on_gizmo_selected") + new_gizmo.translation = get_icon_position(guildpoint_icon) + new_gizmo.connect("selected", self, "on_icon_gizmo_selected", [guildpoint_icon, icon]) new_gizmo.connect("deselected", self, "on_gizmo_deselected") + new_gizmo.connect("updated", self, "set_icon_position", [guildpoint_icon, icon]) $Gizmos.add_child(new_gizmo) +var currently_selected_gizmo = null +var currently_selected_icon = null +var currently_selected_guildpoint_icon = null +var currently_selected_guildpoint_trail = null +var currently_selected_trail3d = null +var currently_selected_trail2d = null +var currently_selected_point_index = null + +func set_2D_position_from_3D_point(position: Vector3, trail2d: Line2D, index: int): + trail2d.set_point_position(index, Vector2(position.x, position.z)) + +func on_icon_gizmo_selected(object: Spatial, guildpoint_icon: Guildpoint.Icon, icon: Sprite3D): + self.currently_selected_gizmo = object + self.currently_selected_icon = icon + self.currently_selected_guildpoint_icon = guildpoint_icon + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/DeleteNode.disabled = false + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SnapSelectedToPlayer.disabled = false + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/XZSnapToPlayer.disabled = false + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/YSnapToPlayer.disabled = false + -var currently_selected_node = null -func on_gizmo_selected(object): - self.currently_selected_node = object +func on_trail_gizmo_selected(object: Spatial, guildpoint_trail: Guildpoint.Trail, trail3d: Spatial, trail2d: Line2D, point_index: int): + self.currently_selected_gizmo = object + self.currently_selected_guildpoint_trail = guildpoint_trail + self.currently_selected_trail3d = trail3d + self.currently_selected_trail2d = trail2d + self.currently_selected_point_index = point_index $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/DeleteNode.disabled = false - # Only enable these buttons if the object selected is a point on the path not an icon - if object.point_type == "path": - $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/NewNodeAfter.disabled = false - $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/ReversePathDirection.disabled = false - $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SetActivePath.disabled = false + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/NewTrailPointAfter.disabled = false + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/ReverseTrailDirection.disabled = false + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SetActiveTrail.disabled = false $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SnapSelectedToPlayer.disabled = false $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/XZSnapToPlayer.disabled = false $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/YSnapToPlayer.disabled = false -func on_gizmo_deselected(object): - self.currently_selected_node = null +func on_gizmo_deselected(): + self.currently_selected_gizmo = null + self.currently_selected_icon = null + self.currently_selected_guildpoint_icon = null + self.currently_selected_guildpoint_trail = null + self.currently_selected_trail3d = null + self.currently_selected_trail2d = null + self.currently_selected_point_index = null $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/DeleteNode.disabled = true - $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/NewNodeAfter.disabled = true + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/NewTrailPointAfter.disabled = true $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SnapSelectedToPlayer.disabled = true $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/XZSnapToPlayer.disabled = true $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/YSnapToPlayer.disabled = true - $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SetActivePath.disabled = true - $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/ReversePathDirection.disabled = true + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SetActiveTrail.disabled = true + $Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/ReverseTrailDirection.disabled = true func clear_adjustment_nodes(): @@ -712,6 +813,132 @@ func clear_adjustment_nodes(): $Gizmos.remove_child(child) child.queue_free() +################################################################################ +# Update Guildpoint datum +################################################################################ +func get_texture_index(path: String) -> int: + if path == "": + return 0 + for i in self.guildpoint_data.get_textures().size(): + if path == self.guildpoint_data.get_textures()[i].get_filepath(): + return i + return -1 + +func get_texture_path(texture_id: int) -> String: + if texture_id == 0: + return "" + if texture_id >= self.guildpoint_data.get_textures().size() or texture_id < 0: + toast("Invalid texture index found") + # TODO(330): This should return an error texture filepath instead of empty string + return "" + return self.guildpoint_data.get_textures()[texture_id].get_filepath() + +func set_icon_position(new_position: Vector3, guildpoint_icon: Guildpoint.Icon, icon: Sprite3D): + if icon.guildpoint != guildpoint_icon: + push_error("Desync between Guildpoint and Icon") + var position = guildpoint_icon.new_position() + position.set_x(new_position.x) + position.set_y(new_position.y) + position.set_z(new_position.z) + icon.set_position(new_position) + +func remove_icon(guildpoint_icon: Guildpoint.Icon, icon: Sprite3D): + if icon.guildpoint != guildpoint_icon: + push_error("Desync between Guildpoint and Icon") + var category: Node = icon.get_parent() + var icon_index: int = category.icons.find(icon) + category.guildpoint_category.get_icon().remove(icon_index) + category.category3d.remove_icon(icon) + +func get_icon_position(guildpoint_icon: Guildpoint.Icon): + var position: Vector3 + position[0] = guildpoint_icon.get_position().get_x() + position[1] = guildpoint_icon.get_position().get_y() + position[2] = -guildpoint_icon.get_position().get_z() + return position + +func set_trail_point_position(position: Vector3, guildpoint_trail: Guildpoint.Trail, trail3d: Spatial, trail2d: Line2D, point_index: int): + if trail3d.guildpoint != trail2d.guildpoint or trail2d.guildpoint != guildpoint_trail: + push_error("Desync between Guildpoint, Trail3D, and Trail2D") + var trail_data = guildpoint_trail.get_trail_data() + trail_data.get_points_x()[point_index] = position.x + trail_data.get_points_y()[point_index] = position.y + trail_data.get_points_z()[point_index] = -position.z + refresh_trail3d_points(trail3d) + refresh_trail2d_points(trail2d) + +func reverse_trail(guildpoint_trail: Guildpoint.Trail, trail3d: Spatial, trail2d: Line2D): + if trail3d.guildpoint != trail2d.guildpoint or trail2d.guildpoint != guildpoint_trail: + push_error("Desync between Guildpoint, Trail3D, and Trail2D") + var trail_data = guildpoint_trail.get_trail_data() + trail_data.get_points_x().invert() + trail_data.get_points_y().invert() + trail_data.get_points_z().invert() + refresh_trail3d_points(trail3d) + refresh_trail2d_points(trail2d) + +func get_trail_point_count(guildpoint_trail: Guildpoint.Trail): + var trail_data = guildpoint_trail.get_trail_data() + return trail_data.get_points_x().size() + +func get_trail_point_position(guildpoint_trail: Guildpoint.Trail, point_index: int): + var position: Vector3 + var trail_data = guildpoint_trail.get_trail_data() + position[0] = trail_data.get_points_x()[point_index] + position[1] = trail_data.get_points_y()[point_index] + position[2] = -trail_data.get_points_z()[point_index] + return position + +func add_trail_point(position: Vector3, guildpoint_trail: Guildpoint.Trail, trail3d: Spatial, trail2d: Line2D, point_index: int = -1): + if trail3d.guildpoint != trail2d.guildpoint or trail2d.guildpoint != guildpoint_trail: + push_error("Desync between Guildpoint, Trail3D, and Trail2D") + var trail_data = trail3d.guildpoint.get_trail_data() + if point_index == -1: + trail_data.get_points_x().append(position.x) + trail_data.get_points_y().append(position.y) + trail_data.get_points_z().append(position.z) + else: + trail_data.get_points_x().insert(point_index, position.x) + trail_data.get_points_y().insert(point_index, position.y) + trail_data.get_points_z().insert(point_index, -position.z) + refresh_trail3d_points(trail3d) + refresh_trail2d_points(trail2d) + +func remove_trail_point(guildpoint_trail: Guildpoint.Trail, trail3d: Spatial, trail2d: Line2D, point_index: int): + if trail3d.guildpoint != trail2d.guildpoint or trail2d.guildpoint != guildpoint_trail: + push_error("Desync between Guildpoint, Trail3D, and Trail2D") + var trail_data = trail3d.guildpoint.get_trail_data() + trail_data.get_points_x().remove(point_index) + trail_data.get_points_y().remove(point_index) + trail_data.get_points_z().remove(point_index) + refresh_trail3d_points(trail3d) + refresh_trail2d_points(trail2d) + +func new_trail_point_after(guildpoint_trail: Guildpoint.Trail, trail3d: Spatial, trail2d: Line2D, point_index: int): + var start: Vector3 = get_trail_point_position(guildpoint_trail, point_index) + var target_position: Vector3 + if get_trail_point_count(guildpoint_trail) > point_index+1: + var end: Vector3 = get_trail_point_position(guildpoint_trail, point_index+1) + target_position = ((start-end)/2) + end + else: + target_position = Vector3(self.player_position.x, self.player_position.y, -self.player_position.z) + add_trail_point(target_position, guildpoint_trail, trail3d, trail2d, point_index+1) + +func refresh_trail3d_points(trail3d: Spatial): + trail3d.refresh_mesh() + +func refresh_trail2d_points(trail2d: Line2D): + trail2d.refresh_points() + +func toast(message: String): + print(message) + +################################################################################ +# Signal Functions +################################################################################ +func _on_main_menu_toggle_pressed(): + $Control/Dialogs/MainMenu.show() + set_maximal_mouse_block() func is_any_dialog_visible(): for dialog in $Control/Dialogs.get_children(): @@ -725,22 +952,23 @@ func _on_Dialog_hide(): set_minimal_mouse_block() -func _on_LoadPath_pressed(): - var open_dialog: FileDialog = $Control/Dialogs/FileDialog - open_dialog.show() - open_dialog.set_current_dir(open_dialog.current_dir) +func _on_LoadTrail_pressed(): + if $Control/Dialogs/CategoriesDialog.is_visible(): + $Control/Dialogs/CategoriesDialog.hide() + else: + $Control/Dialogs/CategoriesDialog.show() func _on_RangesButton_pressed(): $Control/Dialogs/RangesDialog.show() -func _on_PathResolution_value_changed(value): - path_resolution = value - for path in $Paths.get_children(): - var csg:CSGPolygon = path.get_node("CSGPolygon") - csg.path_interval = path_resolution - csg.material.set_shader_param("interval", path_resolution) +func _on_TrailResolution_value_changed(value): + trail_resolution = value + for trail3d in $Trails.get_children(): + var csg:CSGPolygon = trail3d.get_node("CSGPolygon") + csg.trail_interval = trail_resolution + csg.material.set_shader_param("interval", trail_resolution) func _on_CloseEditorQuickPanel_pressed(): @@ -760,128 +988,131 @@ func _on_ChangeTexture_pressed(): set_maximal_mouse_block() ################################################################################ -# Set the file that will be used to create a new path or icon when a new path +# Set the file that will be used to create a new trail or icon when a new trail # or icon is created. ################################################################################ -func _on_TexturePathOpen_file_selected(path): - self.next_texture_path = path +func _on_TexturePathOpen_file_selected(path: String): + var next_texture_path = FileHandler.find_image_duplicates(path, self.unsaved_markers_dir) + if next_texture_path == null: + FileHandler.create_directory_if_missing(self.unsaved_markers_dir.plus_file("Data")) + next_texture_path = "Data".plus_file(path.get_file()) + var file = File.new() + if file.file_exists(self.unsaved_markers_dir.plus_file(next_texture_path)): + toast(String(["Error: A different image with the name ", path.get_file(), " has already been imported. Please rename the file and try again."])) + return + FileHandler.copy_file(path, self.unsaved_markers_dir.plus_file(next_texture_path)) + var texture_index = get_texture_index(next_texture_path) + if texture_index == -1: + self.guildpoint_data.add_textures().set_filepath(next_texture_path) + texture_index = self.guildpoint_data.get_textures().size() - 1 + self.next_texture_id = texture_index + ################################################################################ -# Null out the currently active path so that a new one is created the next time -# a path node is created. +# Null out the currently active trail so that a new one is created the next time +# a trail node is created. ################################################################################ -func _on_NewPath_pressed(): - self.currently_active_path = null +func _on_NewTrail_pressed(): + self.currently_active_trail3d = null + self.currently_active_trail2d = null + self.currently_active_guildpoint_trail = null ################################################################################ # Create a new icon and give it the texture ################################################################################ func _on_NewIcon_pressed(): - gen_new_icon(self.player_position, self.next_texture_path) - -# A new path point is created -func _on_NewPathPoint_pressed(): - if self.currently_active_path == null: - gen_new_path([self.player_position], self.next_texture_path) + var guildpoint_category: Guildpoint.Category = self.currently_active_category.get_metadata(0).guildpoint_category + var guildpoint_icon = guildpoint_category.add_icon() + var position = guildpoint_icon.new_position() + position.set_x(self.player_position.x) + position.set_y(self.player_position.y) + position.set_z(-self.player_position.z) + guildpoint_icon.set_texture_id(self.next_texture_id) + gen_new_icon(guildpoint_icon, self.currently_active_category) + +# A new trail point is created +func _on_NewTrailPoint_pressed(): + if self.currently_active_trail3d == null: + if self.currently_active_category == null: + print("No category selected") + return + var guildpoint_category: Guildpoint.Category = self.currently_active_category.get_metadata(0).guildpoint_category + var guildpoint_trail = guildpoint_category.add_trail() + var trail_data = guildpoint_trail.new_trail_data() + trail_data.add_points_x(self.player_position.x) + trail_data.add_points_y(self.player_position.y) + trail_data.add_points_z(-self.player_position.z) + guildpoint_trail.set_texture_id(self.next_texture_id) + var new_trails: Array = gen_new_trail(guildpoint_trail, self.currently_active_category) + self.currently_active_trail3d = new_trails[0] + self.currently_active_trail2d = new_trails[1] else: - var z_accurate_player_position = player_position - z_accurate_player_position.z = -z_accurate_player_position.z - self.currently_active_path.add_point(z_accurate_player_position) - self.currently_active_path_2d.add_point(Vector2(self.player_position.x, -self.player_position.z)) - - - -################################################################################ -# open the save dialog window. When a path is selected -# _on_SaveDialog_file_selected() will be called with the user specified path. -################################################################################ -func _on_SavePath_pressed(): - $Control/Dialogs/SaveDialog.show() - -################################################################################ -# Save the current markers to a file, this includes all markers in memory not -# just the markers on the current map. -################################################################################ -func _on_SaveDialog_file_selected(path): - self.markerdata[str(self.map_id)] = data_from_renderview() - var save_game = File.new() - save_game.open(path, File.WRITE) - save_game.store_string(JSON.print(self.markerdata)) - + add_trail_point(self.player_position, self.currently_active_guildpoint_trail, self.currently_active_trail3d, self.currently_active_trail2d) func _on_NodeEditorDialog_hide(): - self.currently_selected_node = null + on_gizmo_deselected() clear_adjustment_nodes() _on_Dialog_hide() func _on_DeleteNode_pressed(): - if self.currently_selected_node.point_type == "icon": - self.currently_selected_node.object_link.get_parent().remove_child(self.currently_selected_node.object_link) - self.currently_selected_node.object_link.queue_free() - elif self.currently_selected_node.point_type == "path": - var path = self.currently_selected_node.object_link - var path2d = self.currently_selected_node.object_2d_link - var index = self.currently_selected_node.object_index - - path.remove_point(index) - path2d.remove_point(index) + if self.currently_selected_guildpoint_icon != null: + remove_icon(self.currently_selected_guildpoint_icon, self.currently_selected_icon) + if self.currently_selected_guildpoint_trail != null : + remove_trail_point(self.currently_selected_guildpoint_trail, self.currently_selected_trail3d, self.currently_active_trail2d, self.currently_selected_point_index) + on_gizmo_deselected() clear_adjustment_nodes() gen_adjustment_nodes() - on_gizmo_deselected(self.currently_selected_node) - - -func _on_NewNodeAfter_pressed(): - if self.currently_selected_node.point_type == "icon": - print("Warning: Cannot add node to icon") - elif self.currently_selected_node.point_type == "path": - print("insert path node") - var path = self.currently_selected_node.object_link - var path2d = self.currently_selected_node.object_2d_link - var index = self.currently_selected_node.object_index - - var start = path.get_point_position(index) - var midpoint = self.player_position - midpoint.z = -midpoint.z - if path.get_point_count() > index+1: - var end = path.get_point_position(index+1) - midpoint = ((start-end)/2) + end - path.add_point(midpoint, index+1) - path2d.add_point(Vector2(midpoint.x, midpoint.z), index+1) - clear_adjustment_nodes() - gen_adjustment_nodes() - on_gizmo_deselected(self.currently_selected_node) +func _on_NewTrailPointAfter_pressed(): + if self.currently_selected_guildpoint_trail != null: + new_trail_point_after(self.currently_selected_guildpoint_trail, self.currently_selected_trail3d, self.currently_selected_trail2d, self.currently_selected_point_index) + on_gizmo_deselected() + clear_adjustment_nodes() + gen_adjustment_nodes() func _on_XZSnapToPlayer_pressed(): - self.currently_selected_node.translation.x = self.player_position.x - self.currently_selected_node.translation.z = -self.player_position.z + if self.currently_selected_gizmo == null: + print("Warning: No Point Selected") + return + self.currently_selected_gizmo.translation.x = self.player_position.x + self.currently_selected_gizmo.translation.z = -self.player_position.z func _on_YSnapToPlayer_pressed(): - self.currently_selected_node.translation.y = self.player_position.y + if self.currently_selected_gizmo == null: + print("Warning: No Point Selected") + return + self.currently_selected_gizmo.translation.y = self.player_position.y func _on_SnapSelectedToPlayer_pressed(): - self.currently_selected_node.translation.x = self.player_position.x - self.currently_selected_node.translation.z = -self.player_position.z - self.currently_selected_node.translation.y = self.player_position.y + if self.currently_selected_gizmo == null: + print("Warning: No Point Selected") + return + self.currently_selected_gizmo.translation.x = self.player_position.x + self.currently_selected_gizmo.translation.z = -self.player_position.z + self.currently_selected_gizmo.translation.y = self.player_position.y -func _on_SetActivePath_pressed(): - if self.currently_selected_node.point_type == "icon": - print("Warning: Cannot set icon as active path") - elif self.currently_selected_node.point_type == "path": - self.currently_active_path = self.currently_selected_node.object_link - self.currently_active_path_2d = self.currently_selected_node.object_2d_link +func _on_SetActiveTrail_pressed(): + self.currently_active_guildpoint_trail = self.currently_selected_guildpoint_trail + self.currently_active_trail3d = self.currently_selected_trail3d + self.currently_active_trail2d = self.currently_selected_trail2d -func _on_ReversePathDirection_pressed(): - self.currently_selected_node.object_link.reverse() +func _on_ReverseTrailDirection_pressed(): + if self.currently_selected_guildpoint_trail != null: + reverse_trail(self.currently_selected_guildpoint_trail, self.currently_selected_trail3d, self.currently_active_trail2d) + on_gizmo_deselected() + clear_adjustment_nodes() + gen_adjustment_nodes() func _on_ExitButton_pressed(): + if not read_hash(self.map_id) == make_hash(self.guildpoint_data.to_bytes()): + save_map_data(self.map_id) exit_burrito() @@ -890,3 +1121,43 @@ func _on_Settings_pressed(): settings_dialog.load_settings() settings_dialog.show() + +func _on_MarkersUI_cell_selected(): + var category_item = self.markers_ui.get_selected() + self.currently_active_category = category_item + self.currently_active_trail2d = null + self.currently_active_trail3d = null + self.currently_active_guildpoint_trail = null + on_gizmo_deselected() + clear_adjustment_nodes() + + +func _on_MarkersUI_item_edited(): + var category_item = self.markers_ui.get_edited() + apply_category_visibility_to_nodes(category_item) + + +func _on_ImportPath_pressed(): + $Control/Dialogs/ImportPackDialog.show() + + +func _on_ImportPackDialog_dir_selected(dir): + var user_data_dir = str(OS.get_user_data_dir()) + var args: PoolStringArray = [ + "--input-taco-path", dir, + "--input-guildpoint-path", ProjectSettings.globalize_path(self.saved_markers_dir), + "--output-guildpoint-path", ProjectSettings.globalize_path(self.saved_markers_dir), + "--output-split-guildpoint-path", ProjectSettings.globalize_path(self.unsaved_markers_dir) + ] + FileHandler.call_xml_converter(args) + save_hashes() + load_guildpoint_markers(self.map_id) + + +func _on_SaveData_pressed(): + var user_data_dir = str(OS.get_user_data_dir()) + var args: PoolStringArray = [ + "--input-guildpoint-path", ProjectSettings.globalize_path(self.unsaved_markers_dir), + "--output-guildpoint-path", ProjectSettings.globalize_path(self.saved_markers_dir), + ] + FileHandler.call_xml_converter(args) diff --git a/Spatial.tscn b/Spatial.tscn index bfe6a571..09c60b14 100644 --- a/Spatial.tscn +++ b/Spatial.tscn @@ -1,9 +1,8 @@ -[gd_scene load_steps=17 format=2] +[gd_scene load_steps=18 format=2] [ext_resource path="res://Spatial.gd" type="Script" id=1] [ext_resource path="res://shaders/range_indicators.shader" type="Shader" id=2] [ext_resource path="res://burrito.png" type="Texture" id=3] -[ext_resource path="res://Route2D.tscn" type="PackedScene" id=4] [ext_resource path="res://icon_close.png" type="Texture" id=5] [ext_resource path="res://RangeDialog.gd" type="Script" id=6] [ext_resource path="res://icon_new_icon.png" type="Texture" id=7] @@ -12,6 +11,8 @@ [ext_resource path="res://icon_new_path.png" type="Texture" id=10] [ext_resource path="res://icon_new_point.png" type="Texture" id=11] [ext_resource path="res://SettingsDialog.gd" type="Script" id=12] +[ext_resource path="res://Category3D.gd" type="Script" id=13] +[ext_resource path="res://Category2D.gd" type="Script" id=15] [sub_resource type="Shader" id=1] code = "shader_type canvas_item; @@ -50,6 +51,11 @@ shader_param/custom_7_value = 500.0 [node name="Spatial" type="Spatial"] script = ExtResource( 1 ) +[node name="Markers3D" type="Spatial" parent="."] +script = ExtResource( 13 ) + +[node name="Gizmos" type="Spatial" parent="."] + [node name="CameraMount" type="Spatial" parent="."] [node name="Camera" type="Camera" parent="CameraMount"] @@ -64,11 +70,10 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="MiniMap" type="Node2D" parent="Control"] +[node name="Markers2D" type="Node2D" parent="Control"] material = SubResource( 2 ) scale = Vector2( 2, 2 ) - -[node name="Line2D" parent="Control/MiniMap" instance=ExtResource( 4 )] +script = ExtResource( 15 ) [node name="GlobalMenuButton" type="Control" parent="Control"] margin_left = 323.0 @@ -141,19 +146,19 @@ margin_right = 116.0 margin_bottom = 35.0 text = "APoint" -[node name="NewPath" type="Button" parent="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer"] +[node name="NewTrail" type="Button" parent="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer"] margin_left = 100.0 margin_right = 146.0 margin_bottom = 40.0 rect_min_size = Vector2( 40, 0 ) -hint_tooltip = "Create New Path" +hint_tooltip = "Create New Trail" icon = ExtResource( 10 ) -[node name="NewPathPoint" type="Button" parent="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer"] +[node name="NewTrailPoint" type="Button" parent="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer"] margin_left = 150.0 margin_right = 196.0 margin_bottom = 40.0 -hint_tooltip = "Create New Point on Active Path" +hint_tooltip = "Create New Point on Active Trail" icon = ExtResource( 11 ) [node name="NewIcon" type="Button" parent="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer"] @@ -167,7 +172,7 @@ icon = ExtResource( 7 ) margin_left = 250.0 margin_right = 296.0 margin_bottom = 40.0 -hint_tooltip = "Adjust Path and Icon Positions" +hint_tooltip = "Adjust Trail and Icon Positions" icon = ExtResource( 9 ) [node name="Dialogs" type="Control" parent="Control"] @@ -177,26 +182,25 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="FileDialog" type="FileDialog" parent="Control/Dialogs"] -margin_left = 636.0 -margin_top = 174.0 -margin_right = 1307.0 -margin_bottom = 672.0 -window_title = "Open a File" -mode = 0 +[node name="ImportPackDialog" type="FileDialog" parent="Control/Dialogs"] +margin_left = 289.0 +margin_top = 36.0 +margin_right = 960.0 +margin_bottom = 534.0 +window_title = "Open a Directory" +mode = 2 access = 2 -current_dir = "." -current_file = "." -current_path = "." +current_dir = "" +current_path = "" __meta__ = { "_edit_use_anchors_": false } [node name="MainMenu" type="WindowDialog" parent="Control/Dialogs"] -margin_left = 39.0 -margin_top = 71.0 -margin_right = 252.0 -margin_bottom = 583.0 +margin_left = 55.0 +margin_top = 60.0 +margin_right = 275.0 +margin_bottom = 693.0 window_title = "Main Menu" resizable = true __meta__ = { @@ -212,52 +216,59 @@ __meta__ = { } [node name="VBoxContainer" type="VBoxContainer" parent="Control/Dialogs/MainMenu/ScrollContainer"] -margin_right = 213.0 -margin_bottom = 284.0 +margin_right = 220.0 +margin_bottom = 336.0 size_flags_horizontal = 3 -[node name="LoadPath" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] -margin_right = 213.0 +[node name="LoadTrail" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] +margin_right = 220.0 margin_bottom = 40.0 rect_min_size = Vector2( 0, 40 ) -text = "Open Markers File" +text = "Toggle Marker Visibility" -[node name="SavePath" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] +[node name="HSeparator5" type="HSeparator" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] margin_top = 44.0 -margin_right = 213.0 -margin_bottom = 84.0 -rect_min_size = Vector2( 0, 40 ) -text = "Save Markers File" +margin_right = 220.0 +margin_bottom = 48.0 +__meta__ = { +"_edit_use_anchors_": false +} -[node name="HSeparator" type="HSeparator" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] -margin_top = 88.0 -margin_right = 213.0 +[node name="ImportPath" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] +margin_top = 52.0 +margin_right = 220.0 margin_bottom = 92.0 +rect_min_size = Vector2( 0, 40 ) +text = "Import Marker Pack" -[node name="PointEditor" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] -visible = false +[node name="SaveData" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] margin_top = 96.0 -margin_right = 213.0 +margin_right = 220.0 margin_bottom = 136.0 rect_min_size = Vector2( 0, 40 ) -text = "Editor Panel" +text = "Save Markers File" + +[node name="HSeparator" type="HSeparator" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] +margin_top = 140.0 +margin_right = 220.0 +margin_bottom = 144.0 [node name="OpenEditorQuickPanel" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] -margin_top = 96.0 -margin_right = 213.0 -margin_bottom = 136.0 +margin_top = 148.0 +margin_right = 220.0 +margin_bottom = 188.0 rect_min_size = Vector2( 0, 40 ) text = "Editor Panel" [node name="HSeparator3" type="HSeparator" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] -margin_top = 140.0 -margin_right = 213.0 -margin_bottom = 144.0 +margin_top = 192.0 +margin_right = 220.0 +margin_bottom = 196.0 [node name="Ranges" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] -margin_top = 148.0 -margin_right = 213.0 -margin_bottom = 188.0 +margin_top = 200.0 +margin_right = 220.0 +margin_bottom = 240.0 rect_min_size = Vector2( 0, 40 ) text = "Range Indicators" @@ -271,21 +282,21 @@ text = "Compass" [node name="GuacamoleScript" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] visible = false -margin_top = 192.0 -margin_right = 213.0 -margin_bottom = 232.0 +margin_top = 224.0 +margin_right = 220.0 +margin_bottom = 264.0 rect_min_size = Vector2( 0, 40 ) text = "Guacamole Script Editor" [node name="HSeparator4" type="HSeparator" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] -margin_top = 192.0 -margin_right = 213.0 -margin_bottom = 196.0 +margin_top = 244.0 +margin_right = 220.0 +margin_bottom = 248.0 [node name="Settings" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] -margin_top = 200.0 -margin_right = 213.0 -margin_bottom = 240.0 +margin_top = 252.0 +margin_right = 220.0 +margin_bottom = 292.0 rect_min_size = Vector2( 0, 40 ) text = "Settings" @@ -295,25 +306,25 @@ margin_top = 219.0 margin_right = 213.0 margin_bottom = 264.0 bbcode_enabled = true -bbcode_text = "[u]Active Path[/u]: Draws a line from your character to the final node in the currently active path." -text = "Active Path: Draws a line from your character to the final node in the currently active path." +bbcode_text = "[u]Active Trail[/u]: Draws a line from your character to the final node in the currently active trail." +text = "Active Trail: Draws a line from your character to the final node in the currently active trail." fit_content_height = true scroll_active = false __meta__ = { "_edit_use_anchors_": false } -[node name="ActivePath" type="CheckButton" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] +[node name="ActiveTrail" type="CheckButton" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] visible = false -margin_top = 268.0 -margin_right = 213.0 -margin_bottom = 308.0 -text = "Active Path" +margin_top = 276.0 +margin_right = 220.0 +margin_bottom = 316.0 +text = "Active Trail" [node name="ExitButton" type="Button" parent="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer"] -margin_top = 244.0 -margin_right = 213.0 -margin_bottom = 284.0 +margin_top = 296.0 +margin_right = 220.0 +margin_bottom = 336.0 rect_min_size = Vector2( 0, 40 ) text = "Exit Burrito" @@ -476,17 +487,16 @@ __meta__ = { } [node name="TexturePathOpen" type="FileDialog" parent="Control/Dialogs"] -margin_left = 740.978 -margin_top = 139.437 -margin_right = 1343.98 -margin_bottom = 602.437 +margin_left = 327.0 +margin_top = 97.0 +margin_right = 930.0 +margin_bottom = 560.0 window_title = "Open a File" mode = 0 access = 2 filters = PoolStringArray( "*.png" ) -current_dir = "." -current_file = "." -current_path = "." +current_dir = "/" +current_path = "/" __meta__ = { "_edit_use_anchors_": false } @@ -498,10 +508,9 @@ margin_right = 883.169 margin_bottom = 624.833 window_title = "Save Path" resizable = true -access = 2 -current_dir = "." -current_file = "." -current_path = "." +access = 1 +current_dir = "user://" +current_path = "user://" __meta__ = { "_edit_use_anchors_": false } @@ -539,7 +548,7 @@ size_flags_horizontal = 3 disabled = true text = "Delete Selected" -[node name="NewNodeAfter" type="Button" parent="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer"] +[node name="NewTrailPointAfter" type="Button" parent="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer"] margin_top = 44.0 margin_right = 323.0 margin_bottom = 84.0 @@ -575,23 +584,23 @@ size_flags_horizontal = 3 disabled = true text = "Vertical Snap Selected To Player" -[node name="SetActivePath" type="Button" parent="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer"] +[node name="SetActiveTrail" type="Button" parent="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer"] margin_top = 220.0 margin_right = 323.0 margin_bottom = 260.0 rect_min_size = Vector2( 0, 40 ) size_flags_horizontal = 3 disabled = true -text = "SetActivePath" +text = "SetActiveTrail" -[node name="ReversePathDirection" type="Button" parent="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer"] +[node name="ReverseTrailDirection" type="Button" parent="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer"] margin_top = 264.0 margin_right = 323.0 margin_bottom = 304.0 rect_min_size = Vector2( 0, 40 ) size_flags_horizontal = 3 disabled = true -text = "Reverse Path Direction" +text = "Reverse Trail Direction" [node name="Set Floating Mark" type="Button" parent="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer"] visible = false @@ -601,10 +610,9 @@ margin_bottom = 348.0 rect_min_size = Vector2( 0, 40 ) size_flags_horizontal = 3 disabled = true -text = "Reverse Path Direction" +text = "Reverse Trail Direction" [node name="SettingsDialog" type="WindowDialog" parent="Control/Dialogs"] -visible = true margin_left = 592.0 margin_top = 146.0 margin_right = 981.0 @@ -764,9 +772,6 @@ visible = false margin_top = 284.0 margin_right = 112.0 margin_bottom = 284.0 -__meta__ = { -"_edit_use_anchors_": false -} [node name="LoadLutrisProfile" type="Button" parent="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer"] visible = false @@ -776,6 +781,25 @@ margin_right = 384.0 margin_bottom = 304.0 text = "Load Lutris Profile" +[node name="CategoriesDialog" type="WindowDialog" parent="Control/Dialogs"] +margin_left = 280.0 +margin_top = 105.0 +margin_right = 751.0 +margin_bottom = 486.0 +resizable = true +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="MarkersUI" type="Tree" parent="Control/Dialogs/CategoriesDialog"] +anchor_right = 1.0 +anchor_bottom = 1.0 +size_flags_vertical = 3 +columns = 2 +__meta__ = { +"_edit_use_anchors_": false +} + [node name="Border" type="Control" parent="Control"] visible = false anchor_right = 1.0 @@ -843,12 +867,10 @@ anchor_bottom = 1.0 margin_top = -6.0 color = Color( 0, 0, 0, 1 ) -[node name="Paths" type="Spatial" parent="."] +[node name="Trails" type="Spatial" parent="."] [node name="Icons" type="Spatial" parent="."] -[node name="Gizmos" type="Spatial" parent="."] - [node name="FeetLocation" type="Spatial" parent="."] [node name="DistanceIndicator" type="MeshInstance" parent="FeetLocation"] @@ -858,15 +880,16 @@ material/0 = SubResource( 4 ) [connection signal="pressed" from="Control/GlobalMenuButton/main_menu_toggle" to="." method="_on_main_menu_toggle_pressed"] [connection signal="pressed" from="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer/CloseEditorQuickPanel" to="." method="_on_CloseEditorQuickPanel_pressed"] [connection signal="pressed" from="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer/ChangeTexture" to="." method="_on_ChangeTexture_pressed"] -[connection signal="pressed" from="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer/NewPath" to="." method="_on_NewPath_pressed"] -[connection signal="pressed" from="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer/NewPathPoint" to="." method="_on_NewPathPoint_pressed"] +[connection signal="pressed" from="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer/NewTrail" to="." method="_on_NewTrail_pressed"] +[connection signal="pressed" from="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer/NewTrailPoint" to="." method="_on_NewTrailPoint_pressed"] [connection signal="pressed" from="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer/NewIcon" to="." method="_on_NewIcon_pressed"] [connection signal="pressed" from="Control/GlobalMenuButton/EditorQuckPanel/HBoxContainer/AdjustPoints" to="." method="_on_AdjustNodesButton_pressed"] -[connection signal="file_selected" from="Control/Dialogs/FileDialog" to="." method="_on_FileDialog_file_selected"] -[connection signal="hide" from="Control/Dialogs/FileDialog" to="." method="_on_Dialog_hide"] +[connection signal="dir_selected" from="Control/Dialogs/ImportPackDialog" to="." method="_on_ImportPackDialog_dir_selected"] +[connection signal="hide" from="Control/Dialogs/ImportPackDialog" to="." method="_on_Dialog_hide"] [connection signal="hide" from="Control/Dialogs/MainMenu" to="." method="_on_Dialog_hide"] -[connection signal="pressed" from="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer/LoadPath" to="." method="_on_LoadPath_pressed"] -[connection signal="pressed" from="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer/SavePath" to="." method="_on_SavePath_pressed"] +[connection signal="pressed" from="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer/LoadTrail" to="." method="_on_LoadTrail_pressed"] +[connection signal="pressed" from="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer/ImportPath" to="." method="_on_ImportPath_pressed"] +[connection signal="pressed" from="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer/SaveData" to="." method="_on_SaveData_pressed"] [connection signal="pressed" from="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer/OpenEditorQuickPanel" to="." method="_on_OpenEditorQuickPanel_pressed"] [connection signal="pressed" from="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer/Ranges" to="." method="_on_RangesButton_pressed"] [connection signal="pressed" from="Control/Dialogs/MainMenu/ScrollContainer/VBoxContainer/Settings" to="." method="_on_Settings_pressed"] @@ -888,16 +911,15 @@ material/0 = SubResource( 4 ) [connection signal="value_changed" from="Control/Dialogs/RangesDialog/GridContainer/SpinBox7" to="Control/Dialogs/RangesDialog" method="on_change"] [connection signal="file_selected" from="Control/Dialogs/TexturePathOpen" to="." method="_on_TexturePathOpen_file_selected"] [connection signal="hide" from="Control/Dialogs/TexturePathOpen" to="." method="_on_Dialog_hide"] -[connection signal="file_selected" from="Control/Dialogs/SaveDialog" to="." method="_on_SaveDialog_file_selected"] [connection signal="hide" from="Control/Dialogs/SaveDialog" to="." method="_on_Dialog_hide"] [connection signal="hide" from="Control/Dialogs/NodeEditorDialog" to="." method="_on_NodeEditorDialog_hide"] [connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/DeleteNode" to="." method="_on_DeleteNode_pressed"] -[connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/NewNodeAfter" to="." method="_on_NewNodeAfter_pressed"] +[connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/NewTrailPointAfter" to="." method="_on_NewTrailPointAfter_pressed"] [connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SnapSelectedToPlayer" to="." method="_on_SnapSelectedToPlayer_pressed"] [connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/XZSnapToPlayer" to="." method="_on_XZSnapToPlayer_pressed"] [connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/YSnapToPlayer" to="." method="_on_YSnapToPlayer_pressed"] -[connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SetActivePath" to="." method="_on_SetActivePath_pressed"] -[connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/ReversePathDirection" to="." method="_on_ReversePathDirection_pressed"] +[connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/SetActiveTrail" to="." method="_on_SetActiveTrail_pressed"] +[connection signal="pressed" from="Control/Dialogs/NodeEditorDialog/ScrollContainer/VBoxContainer/ReverseTrailDirection" to="." method="_on_ReverseTrailDirection_pressed"] [connection signal="hide" from="Control/Dialogs/SettingsDialog" to="." method="_on_NodeEditorDialog_hide"] [connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/MinimumWidth" to="Control/Dialogs/SettingsDialog" method="save_settings"] [connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/MinimumHeight" to="Control/Dialogs/SettingsDialog" method="save_settings"] @@ -907,3 +929,10 @@ material/0 = SubResource( 4 ) [connection signal="pressed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/AutoLaunchBurritoLink" to="Control/Dialogs/SettingsDialog" method="save_settings"] [connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/WinePath" to="Control/Dialogs/SettingsDialog" method="save_settings"] [connection signal="text_changed" from="Control/Dialogs/SettingsDialog/ScrollContainer/GridContainer/EnvironmentVars" to="Control/Dialogs/SettingsDialog" method="save_settings"] +[connection signal="hide" from="Control/Dialogs/CategoriesDialog" to="." method="_on_Dialog_hide"] +[connection signal="cell_selected" from="Control/Dialogs/CategoriesDialog/MarkersUI" to="." method="_on_MarkersUI_cell_selected"] +[connection signal="cell_selected" from="Control/Dialogs/CategoriesDialog/MarkersUI" to="." method="_on_MarkerPacks_cell_selected"] +[connection signal="item_edited" from="Control/Dialogs/CategoriesDialog/MarkersUI" to="." method="_on_MarkersUI_item_edited"] +[connection signal="item_edited" from="Control/Dialogs/CategoriesDialog/MarkersUI" to="." method="_on_MarkerPacks_item_edited"] +[connection signal="multi_selected" from="Control/Dialogs/CategoriesDialog/MarkersUI" to="." method="_on_Tree_multi_selected"] +[connection signal="tree_entered" from="Control/Dialogs/CategoriesDialog/MarkersUI" to="." method="_on_Tree_tree_entered"] diff --git a/Route.tres b/Trail.tres similarity index 100% rename from Route.tres rename to Trail.tres diff --git a/Trail2D.gd b/Trail2D.gd new file mode 100644 index 00000000..68bbe284 --- /dev/null +++ b/Trail2D.gd @@ -0,0 +1,11 @@ +extends Line2D + +const Guildpoint = preload("res://guildpoint.gd") +var guildpoint: Guildpoint.Trail + +func refresh_points(): + var trail_points := PoolVector2Array() + var trail_data = self.guildpoint.get_trail_data() + for index in range(0, trail_data.get_points_z().size()): + trail_points.append(Vector2(trail_data.get_points_x()[index], -trail_data.get_points_z()[index])) + self.points = trail_points diff --git a/Route2D.tscn b/Trail2D.tscn similarity index 87% rename from Route2D.tscn rename to Trail2D.tscn index 5b3da3ed..9af82593 100644 --- a/Route2D.tscn +++ b/Trail2D.tscn @@ -1,4 +1,6 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://Trail2D.gd" type="Script" id=1] [sub_resource type="Shader" id=1] code = "shader_type canvas_item; @@ -27,3 +29,4 @@ material = SubResource( 2 ) points = PoolVector2Array( 0, 0, 0, 0, 0, 0 ) default_color = Color( 1, 1, 1, 1 ) texture_mode = 1 +script = ExtResource( 1 ) diff --git a/Route.gd b/Trail3D.gd similarity index 61% rename from Route.gd rename to Trail3D.gd index 97aa155b..fa41e410 100644 --- a/Route.gd +++ b/Trail3D.gd @@ -1,26 +1,26 @@ extends Spatial -var texture_path +const Guildpoint = preload("res://guildpoint.gd") +var texture_path var color = Color(0.9, 0.1, 0.1) - -var point_list := PoolVector3Array() - -func create_mesh(point_list: PoolVector3Array): - self.point_list = point_list - refresh_mesh() +var guildpoint: Guildpoint.Trail +var category: TreeItem func refresh_mesh(): var tmpMesh = Mesh.new() var i = 0 var last_uv: float = 0.0 - for point_index in range(len(point_list)-1): - var point:Vector3 = point_list[point_index] - var next_point:Vector3 = point_list[point_index+1] + var trail_data = self.guildpoint.get_trail_data() + for point_index in range(trail_data.get_points_x().size()-1): + var point:Vector3 = Vector3(trail_data.get_points_x()[point_index], trail_data.get_points_y()[point_index], -trail_data.get_points_z()[point_index]) + var next_point:Vector3 = Vector3(trail_data.get_points_x()[point_index+1], trail_data.get_points_y()[point_index+1], -trail_data.get_points_z()[point_index+1]) + # If the line starts or ends at map coordinates (0,0,0), don't draw the line. + if point == Vector3(0,0,0) or next_point == Vector3(0,0,0): + continue var distance: float = point.distance_to(next_point) var normal: Vector3 = (next_point - point).normalized() - #print(normal) var horizontal_tangent:Vector3 = Vector3(normal.z, 0, -normal.x).normalized() normal = Vector3(0,0,0) @@ -60,35 +60,6 @@ func refresh_mesh(): $MeshInstance.mesh = tmpMesh -func update_point_vertical(index, y_value): - pass - -func reverse(): - self.point_list.invert() - refresh_mesh() - -func get_point_count(): - return len(self.point_list) - -func get_point_position(index: int): - return self.point_list[index] - -func set_point_position(index: int, position: Vector3): - self.point_list[index] = position - refresh_mesh() - -func add_point(position: Vector3, index: int = -1): - if index == -1: - self.point_list.append(position) - else: - self.point_list.insert(index, position) - refresh_mesh() - -func remove_point(index: int): - self.point_list.remove(index) - refresh_mesh() - - func set_texture(texture): $MeshInstance.material_override.set_shader_param("texture_albedo", texture) diff --git a/Trail3D.tscn b/Trail3D.tscn new file mode 100644 index 00000000..5d495687 --- /dev/null +++ b/Trail3D.tscn @@ -0,0 +1,10 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://Trail.tres" type="Material" id=1] +[ext_resource path="res://Trail3D.gd" type="Script" id=2] + +[node name="Trail3D" type="Spatial"] +script = ExtResource( 2 ) + +[node name="MeshInstance" type="MeshInstance" parent="."] +material_override = ExtResource( 1 ) diff --git a/addons/version_restrict/plugin.cfg b/addons/version_restrict/plugin.cfg new file mode 100644 index 00000000..7a2ea243 --- /dev/null +++ b/addons/version_restrict/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="VersionRestrict" +description="Restricts the Godot Engine version that can be used by the developer." +author="Orthogonal Projects" +version="1.0" +script="plugin.gd" diff --git a/addons/version_restrict/plugin.gd b/addons/version_restrict/plugin.gd new file mode 100644 index 00000000..86a93465 --- /dev/null +++ b/addons/version_restrict/plugin.gd @@ -0,0 +1,81 @@ +tool +extends EditorPlugin + +var confirm_modal: AcceptDialog +var exit_on_hide: bool = true + +var target_engine_property = "global/target_engine_version" + +################################################################################ +# _enter_tree +# +# When the plugin loads read the target_engine_version from the project config +# and compare it to the current engine version. +################################################################################ +func _enter_tree(): + var target_engine_version = ProjectSettings.get(target_engine_property) + + var engine_info = Engine.get_version_info() + var current_engine_version = "{major}.{minor}.{patch}".format({ + "major": engine_info.major, + "minor": engine_info.minor, + "patch": engine_info.patch, + }) + + # Set the target version to the current version on first run. + if target_engine_version == null: + ProjectSettings.set(target_engine_property, current_engine_version) + target_engine_version = current_engine_version + + if target_engine_version != current_engine_version: + + confirm_modal = AcceptDialog.new() + + # Remove the `X` button in the top right. We cant remove it compleetly + # without effecting the stability of the engine so it is just hidden. + confirm_modal.get_close_button().hide() + + # Rename "Ok" confirmation button to "Close Godot" + confirm_modal.get_ok().text = "Close Godot" + + get_editor_interface().get_editor_viewport().add_child(confirm_modal) + + confirm_modal.dialog_text = "You are using v"+current_engine_version+" of the Godot Engine to run this project.\n\nThis project wants you to use v"+target_engine_version+" instead.\n\nIf you beleive this is incorrect you can \n- Change the target engin version in:\n 'Project Settings' -> 'Global' -> 'Target Engine Version'\nor\n- Disable the 'Version Restrict' plugin" + + # Center the panel on the screen + confirm_modal.anchor_left = 0.5 + confirm_modal.anchor_top = 0.5 + confirm_modal.anchor_right = 0.5 + confirm_modal.anchor_bottom = 0.5 + confirm_modal.margin_left = -confirm_modal.rect_size.x/2 + confirm_modal.margin_top = -confirm_modal.rect_size.y/2 + + # Cause the program to exit when the modal is hidden + confirm_modal.connect("hide", self, "_accept_dialog_hidden") + + # TODO: Add a button to bring you to the download page for the correct version + + confirm_modal.show() + + +################################################################################ +# _accept_dialog_hidden +# +# Triggers when the accept dialog is hidden by any means. Will close the Godot +# editor unless self.exit_on_hide has been set to false somewhere. +################################################################################ +func _accept_dialog_hidden(): + if self.exit_on_hide: + get_tree().quit() + + +################################################################################ +# _exit_tree +# +# If an AcceptDialog was created when this plugin entered the tree then remove +# it. This will prevent the program from exiting when the dialog is closed. +################################################################################ +func _exit_tree(): + if confirm_modal: + self.exit_on_hide = false + confirm_modal.queue_free() diff --git a/guildpoint.gd b/guildpoint.gd new file mode 100644 index 00000000..83b08f8d --- /dev/null +++ b/guildpoint.gd @@ -0,0 +1,4219 @@ +const PROTO_VERSION = 3 + +# +# BSD 3-Clause License +# +# Copyright (c) 2018 - 2022, Oleg Malyavkin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# DEBUG_TAB redefine this " " if you need, example: const DEBUG_TAB = "\t" +const DEBUG_TAB : String = " " + +enum PB_ERR { + NO_ERRORS = 0, + VARINT_NOT_FOUND = -1, + REPEATED_COUNT_NOT_FOUND = -2, + REPEATED_COUNT_MISMATCH = -3, + LENGTHDEL_SIZE_NOT_FOUND = -4, + LENGTHDEL_SIZE_MISMATCH = -5, + PACKAGE_SIZE_MISMATCH = -6, + UNDEFINED_STATE = -7, + PARSE_INCOMPLETE = -8, + REQUIRED_FIELDS = -9 +} + +enum PB_DATA_TYPE { + INT32 = 0, + SINT32 = 1, + UINT32 = 2, + INT64 = 3, + SINT64 = 4, + UINT64 = 5, + BOOL = 6, + ENUM = 7, + FIXED32 = 8, + SFIXED32 = 9, + FLOAT = 10, + FIXED64 = 11, + SFIXED64 = 12, + DOUBLE = 13, + STRING = 14, + BYTES = 15, + MESSAGE = 16, + MAP = 17 +} + +const DEFAULT_VALUES_2 = { + PB_DATA_TYPE.INT32: null, + PB_DATA_TYPE.SINT32: null, + PB_DATA_TYPE.UINT32: null, + PB_DATA_TYPE.INT64: null, + PB_DATA_TYPE.SINT64: null, + PB_DATA_TYPE.UINT64: null, + PB_DATA_TYPE.BOOL: null, + PB_DATA_TYPE.ENUM: null, + PB_DATA_TYPE.FIXED32: null, + PB_DATA_TYPE.SFIXED32: null, + PB_DATA_TYPE.FLOAT: null, + PB_DATA_TYPE.FIXED64: null, + PB_DATA_TYPE.SFIXED64: null, + PB_DATA_TYPE.DOUBLE: null, + PB_DATA_TYPE.STRING: null, + PB_DATA_TYPE.BYTES: null, + PB_DATA_TYPE.MESSAGE: null, + PB_DATA_TYPE.MAP: null +} + +const DEFAULT_VALUES_3 = { + PB_DATA_TYPE.INT32: 0, + PB_DATA_TYPE.SINT32: 0, + PB_DATA_TYPE.UINT32: 0, + PB_DATA_TYPE.INT64: 0, + PB_DATA_TYPE.SINT64: 0, + PB_DATA_TYPE.UINT64: 0, + PB_DATA_TYPE.BOOL: false, + PB_DATA_TYPE.ENUM: 0, + PB_DATA_TYPE.FIXED32: 0, + PB_DATA_TYPE.SFIXED32: 0, + PB_DATA_TYPE.FLOAT: 0.0, + PB_DATA_TYPE.FIXED64: 0, + PB_DATA_TYPE.SFIXED64: 0, + PB_DATA_TYPE.DOUBLE: 0.0, + PB_DATA_TYPE.STRING: "", + PB_DATA_TYPE.BYTES: [], + PB_DATA_TYPE.MESSAGE: null, + PB_DATA_TYPE.MAP: [] +} + +enum PB_TYPE { + VARINT = 0, + FIX64 = 1, + LENGTHDEL = 2, + STARTGROUP = 3, + ENDGROUP = 4, + FIX32 = 5, + UNDEFINED = 8 +} + +enum PB_RULE { + OPTIONAL = 0, + REQUIRED = 1, + REPEATED = 2, + RESERVED = 3 +} + +enum PB_SERVICE_STATE { + FILLED = 0, + UNFILLED = 1 +} + +class PBField: + func _init(a_name : String, a_type : int, a_rule : int, a_tag : int, packed : bool, a_value = null): + name = a_name + type = a_type + rule = a_rule + tag = a_tag + option_packed = packed + value = a_value + + var name : String + var type : int + var rule : int + var tag : int + var option_packed : bool + var value + var is_map_field : bool = false + var option_default : bool = false + +class PBTypeTag: + var ok : bool = false + var type : int + var tag : int + var offset : int + +class PBServiceField: + var field : PBField + var func_ref = null + var state : int = PB_SERVICE_STATE.UNFILLED + +class PBPacker: + static func convert_signed(n : int) -> int: + if n < -2147483648: + return (n << 1) ^ (n >> 63) + else: + return (n << 1) ^ (n >> 31) + + static func deconvert_signed(n : int) -> int: + if n & 0x01: + return ~(n >> 1) + else: + return (n >> 1) + + static func pack_varint(value) -> PoolByteArray: + var varint : PoolByteArray = PoolByteArray() + if typeof(value) == TYPE_BOOL: + if value: + value = 1 + else: + value = 0 + for _i in range(9): + var b = value & 0x7F + value >>= 7 + if value: + varint.append(b | 0x80) + else: + varint.append(b) + break + if varint.size() == 9 && varint[8] == 0xFF: + varint.append(0x01) + return varint + + static func pack_bytes(value, count : int, data_type : int) -> PoolByteArray: + var bytes : PoolByteArray = PoolByteArray() + if data_type == PB_DATA_TYPE.FLOAT: + var spb : StreamPeerBuffer = StreamPeerBuffer.new() + spb.put_float(value) + bytes = spb.get_data_array() + elif data_type == PB_DATA_TYPE.DOUBLE: + var spb : StreamPeerBuffer = StreamPeerBuffer.new() + spb.put_double(value) + bytes = spb.get_data_array() + else: + for _i in range(count): + bytes.append(value & 0xFF) + value >>= 8 + return bytes + + static func unpack_bytes(bytes : PoolByteArray, index : int, count : int, data_type : int): + var value = 0 + if data_type == PB_DATA_TYPE.FLOAT: + var spb : StreamPeerBuffer = StreamPeerBuffer.new() + for i in range(index, count + index): + spb.put_u8(bytes[i]) + spb.seek(0) + value = spb.get_float() + elif data_type == PB_DATA_TYPE.DOUBLE: + var spb : StreamPeerBuffer = StreamPeerBuffer.new() + for i in range(index, count + index): + spb.put_u8(bytes[i]) + spb.seek(0) + value = spb.get_double() + else: + for i in range(index + count - 1, index - 1, -1): + value |= (bytes[i] & 0xFF) + if i != index: + value <<= 8 + return value + + static func unpack_varint(varint_bytes) -> int: + var value : int = 0 + for i in range(varint_bytes.size() - 1, -1, -1): + value |= varint_bytes[i] & 0x7F + if i != 0: + value <<= 7 + return value + + static func pack_type_tag(type : int, tag : int) -> PoolByteArray: + return pack_varint((tag << 3) | type) + + static func isolate_varint(bytes : PoolByteArray, index : int) -> PoolByteArray: + var result : PoolByteArray = PoolByteArray() + for i in range(index, bytes.size()): + result.append(bytes[i]) + if !(bytes[i] & 0x80): + break + return result + + static func unpack_type_tag(bytes : PoolByteArray, index : int) -> PBTypeTag: + var varint_bytes : PoolByteArray = isolate_varint(bytes, index) + var result : PBTypeTag = PBTypeTag.new() + if varint_bytes.size() != 0: + result.ok = true + result.offset = varint_bytes.size() + var unpacked : int = unpack_varint(varint_bytes) + result.type = unpacked & 0x07 + result.tag = unpacked >> 3 + return result + + static func pack_length_delimeted(type : int, tag : int, bytes : PoolByteArray) -> PoolByteArray: + var result : PoolByteArray = pack_type_tag(type, tag) + result.append_array(pack_varint(bytes.size())) + result.append_array(bytes) + return result + + static func pb_type_from_data_type(data_type : int) -> int: + if data_type == PB_DATA_TYPE.INT32 || data_type == PB_DATA_TYPE.SINT32 || data_type == PB_DATA_TYPE.UINT32 || data_type == PB_DATA_TYPE.INT64 || data_type == PB_DATA_TYPE.SINT64 || data_type == PB_DATA_TYPE.UINT64 || data_type == PB_DATA_TYPE.BOOL || data_type == PB_DATA_TYPE.ENUM: + return PB_TYPE.VARINT + elif data_type == PB_DATA_TYPE.FIXED32 || data_type == PB_DATA_TYPE.SFIXED32 || data_type == PB_DATA_TYPE.FLOAT: + return PB_TYPE.FIX32 + elif data_type == PB_DATA_TYPE.FIXED64 || data_type == PB_DATA_TYPE.SFIXED64 || data_type == PB_DATA_TYPE.DOUBLE: + return PB_TYPE.FIX64 + elif data_type == PB_DATA_TYPE.STRING || data_type == PB_DATA_TYPE.BYTES || data_type == PB_DATA_TYPE.MESSAGE || data_type == PB_DATA_TYPE.MAP: + return PB_TYPE.LENGTHDEL + else: + return PB_TYPE.UNDEFINED + + static func pack_field(field : PBField) -> PoolByteArray: + var type : int = pb_type_from_data_type(field.type) + var type_copy : int = type + if field.rule == PB_RULE.REPEATED && field.option_packed: + type = PB_TYPE.LENGTHDEL + var head : PoolByteArray = pack_type_tag(type, field.tag) + var data : PoolByteArray = PoolByteArray() + if type == PB_TYPE.VARINT: + var value + if field.rule == PB_RULE.REPEATED: + for v in field.value: + data.append_array(head) + if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: + value = convert_signed(v) + else: + value = v + data.append_array(pack_varint(value)) + return data + else: + if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: + value = convert_signed(field.value) + else: + value = field.value + data = pack_varint(value) + elif type == PB_TYPE.FIX32: + if field.rule == PB_RULE.REPEATED: + for v in field.value: + data.append_array(head) + data.append_array(pack_bytes(v, 4, field.type)) + return data + else: + data.append_array(pack_bytes(field.value, 4, field.type)) + elif type == PB_TYPE.FIX64: + if field.rule == PB_RULE.REPEATED: + for v in field.value: + data.append_array(head) + data.append_array(pack_bytes(v, 8, field.type)) + return data + else: + data.append_array(pack_bytes(field.value, 8, field.type)) + elif type == PB_TYPE.LENGTHDEL: + if field.rule == PB_RULE.REPEATED: + if type_copy == PB_TYPE.VARINT: + if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: + var signed_value : int + for v in field.value: + signed_value = convert_signed(v) + data.append_array(pack_varint(signed_value)) + else: + for v in field.value: + data.append_array(pack_varint(v)) + return pack_length_delimeted(type, field.tag, data) + elif type_copy == PB_TYPE.FIX32: + for v in field.value: + data.append_array(pack_bytes(v, 4, field.type)) + return pack_length_delimeted(type, field.tag, data) + elif type_copy == PB_TYPE.FIX64: + for v in field.value: + data.append_array(pack_bytes(v, 8, field.type)) + return pack_length_delimeted(type, field.tag, data) + elif field.type == PB_DATA_TYPE.STRING: + for v in field.value: + var obj = v.to_utf8() + data.append_array(pack_length_delimeted(type, field.tag, obj)) + return data + elif field.type == PB_DATA_TYPE.BYTES: + for v in field.value: + data.append_array(pack_length_delimeted(type, field.tag, v)) + return data + elif typeof(field.value[0]) == TYPE_OBJECT: + for v in field.value: + var obj : PoolByteArray = v.to_bytes() + data.append_array(pack_length_delimeted(type, field.tag, obj)) + return data + else: + if field.type == PB_DATA_TYPE.STRING: + var str_bytes : PoolByteArray = field.value.to_utf8() + if PROTO_VERSION == 2 || (PROTO_VERSION == 3 && str_bytes.size() > 0): + data.append_array(str_bytes) + return pack_length_delimeted(type, field.tag, data) + if field.type == PB_DATA_TYPE.BYTES: + if PROTO_VERSION == 2 || (PROTO_VERSION == 3 && field.value.size() > 0): + data.append_array(field.value) + return pack_length_delimeted(type, field.tag, data) + elif typeof(field.value) == TYPE_OBJECT: + var obj : PoolByteArray = field.value.to_bytes() + if obj.size() > 0: + data.append_array(obj) + return pack_length_delimeted(type, field.tag, data) + else: + pass + if data.size() > 0: + head.append_array(data) + return head + else: + return data + + static func unpack_field(bytes : PoolByteArray, offset : int, field : PBField, type : int, message_func_ref) -> int: + if field.rule == PB_RULE.REPEATED && type != PB_TYPE.LENGTHDEL && field.option_packed: + var count = isolate_varint(bytes, offset) + if count.size() > 0: + offset += count.size() + count = unpack_varint(count) + if type == PB_TYPE.VARINT: + var val + var counter = offset + count + while offset < counter: + val = isolate_varint(bytes, offset) + if val.size() > 0: + offset += val.size() + val = unpack_varint(val) + if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: + val = deconvert_signed(val) + elif field.type == PB_DATA_TYPE.BOOL: + if val: + val = true + else: + val = false + field.value.append(val) + else: + return PB_ERR.REPEATED_COUNT_MISMATCH + return offset + elif type == PB_TYPE.FIX32 || type == PB_TYPE.FIX64: + var type_size + if type == PB_TYPE.FIX32: + type_size = 4 + else: + type_size = 8 + var val + var counter = offset + count + while offset < counter: + if (offset + type_size) > bytes.size(): + return PB_ERR.REPEATED_COUNT_MISMATCH + val = unpack_bytes(bytes, offset, type_size, field.type) + offset += type_size + field.value.append(val) + return offset + else: + return PB_ERR.REPEATED_COUNT_NOT_FOUND + else: + if type == PB_TYPE.VARINT: + var val = isolate_varint(bytes, offset) + if val.size() > 0: + offset += val.size() + val = unpack_varint(val) + if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: + val = deconvert_signed(val) + elif field.type == PB_DATA_TYPE.BOOL: + if val: + val = true + else: + val = false + if field.rule == PB_RULE.REPEATED: + field.value.append(val) + else: + field.value = val + else: + return PB_ERR.VARINT_NOT_FOUND + return offset + elif type == PB_TYPE.FIX32 || type == PB_TYPE.FIX64: + var type_size + if type == PB_TYPE.FIX32: + type_size = 4 + else: + type_size = 8 + var val + if (offset + type_size) > bytes.size(): + return PB_ERR.REPEATED_COUNT_MISMATCH + val = unpack_bytes(bytes, offset, type_size, field.type) + offset += type_size + if field.rule == PB_RULE.REPEATED: + field.value.append(val) + else: + field.value = val + return offset + elif type == PB_TYPE.LENGTHDEL: + var inner_size = isolate_varint(bytes, offset) + if inner_size.size() > 0: + offset += inner_size.size() + inner_size = unpack_varint(inner_size) + if inner_size >= 0: + if inner_size + offset > bytes.size(): + return PB_ERR.LENGTHDEL_SIZE_MISMATCH + if message_func_ref != null: + var message = message_func_ref.call_func() + if inner_size > 0: + var sub_offset = message.from_bytes(bytes, offset, inner_size + offset) + if sub_offset > 0: + if sub_offset - offset >= inner_size: + offset = sub_offset + return offset + else: + return PB_ERR.LENGTHDEL_SIZE_MISMATCH + return sub_offset + else: + return offset + elif field.type == PB_DATA_TYPE.STRING: + var str_bytes : PoolByteArray = PoolByteArray() + for i in range(offset, inner_size + offset): + str_bytes.append(bytes[i]) + if field.rule == PB_RULE.REPEATED: + field.value.append(str_bytes.get_string_from_utf8()) + else: + field.value = str_bytes.get_string_from_utf8() + return offset + inner_size + elif field.type == PB_DATA_TYPE.BYTES: + var val_bytes : PoolByteArray = PoolByteArray() + for i in range(offset, inner_size + offset): + val_bytes.append(bytes[i]) + if field.rule == PB_RULE.REPEATED: + field.value.append(val_bytes) + else: + field.value = val_bytes + return offset + inner_size + else: + return PB_ERR.LENGTHDEL_SIZE_NOT_FOUND + else: + return PB_ERR.LENGTHDEL_SIZE_NOT_FOUND + return PB_ERR.UNDEFINED_STATE + + static func unpack_message(data, bytes : PoolByteArray, offset : int, limit : int) -> int: + while true: + var tt : PBTypeTag = unpack_type_tag(bytes, offset) + if tt.ok: + offset += tt.offset + if data.has(tt.tag): + var service : PBServiceField = data[tt.tag] + var type : int = pb_type_from_data_type(service.field.type) + if type == tt.type || (tt.type == PB_TYPE.LENGTHDEL && service.field.rule == PB_RULE.REPEATED && service.field.option_packed): + var res : int = unpack_field(bytes, offset, service.field, type, service.func_ref) + if res > 0: + service.state = PB_SERVICE_STATE.FILLED + offset = res + if offset == limit: + return offset + elif offset > limit: + return PB_ERR.PACKAGE_SIZE_MISMATCH + elif res < 0: + return res + else: + break + else: + return offset + return PB_ERR.UNDEFINED_STATE + + static func pack_message(data) -> PoolByteArray: + var DEFAULT_VALUES + if PROTO_VERSION == 2: + DEFAULT_VALUES = DEFAULT_VALUES_2 + elif PROTO_VERSION == 3: + DEFAULT_VALUES = DEFAULT_VALUES_3 + var result : PoolByteArray = PoolByteArray() + var keys : Array = data.keys() + keys.sort() + for i in keys: + if data[i].field.value != null: + if data[i].state == PB_SERVICE_STATE.UNFILLED \ + && !data[i].field.is_map_field \ + && typeof(data[i].field.value) == typeof(DEFAULT_VALUES[data[i].field.type]) \ + && data[i].field.value == DEFAULT_VALUES[data[i].field.type]: + continue + elif data[i].field.rule == PB_RULE.REPEATED && data[i].field.value.size() == 0: + continue + result.append_array(pack_field(data[i].field)) + elif data[i].field.rule == PB_RULE.REQUIRED: + print("Error: required field is not filled: Tag:", data[i].field.tag) + return PoolByteArray() + return result + + static func check_required(data) -> bool: + var keys : Array = data.keys() + for i in keys: + if data[i].field.rule == PB_RULE.REQUIRED && data[i].state == PB_SERVICE_STATE.UNFILLED: + return false + return true + + static func construct_map(key_values): + var result = {} + for kv in key_values: + result[kv.get_key()] = kv.get_value() + return result + + static func tabulate(text : String, nesting : int) -> String: + var tab : String = "" + for _i in range(nesting): + tab += DEBUG_TAB + return tab + text + + static func value_to_string(value, field : PBField, nesting : int) -> String: + var result : String = "" + var text : String + if field.type == PB_DATA_TYPE.MESSAGE: + result += "{" + nesting += 1 + text = message_to_string(value.data, nesting) + if text != "": + result += "\n" + text + nesting -= 1 + result += tabulate("}", nesting) + else: + nesting -= 1 + result += "}" + elif field.type == PB_DATA_TYPE.BYTES: + result += "<" + for i in range(value.size()): + result += String(value[i]) + if i != (value.size() - 1): + result += ", " + result += ">" + elif field.type == PB_DATA_TYPE.STRING: + result += "\"" + value + "\"" + elif field.type == PB_DATA_TYPE.ENUM: + result += "ENUM::" + String(value) + else: + result += String(value) + return result + + static func field_to_string(field : PBField, nesting : int) -> String: + var result : String = tabulate(field.name + ": ", nesting) + if field.type == PB_DATA_TYPE.MAP: + if field.value.size() > 0: + result += "(\n" + nesting += 1 + for i in range(field.value.size()): + var local_key_value = field.value[i].data[1].field + result += tabulate(value_to_string(local_key_value.value, local_key_value, nesting), nesting) + ": " + local_key_value = field.value[i].data[2].field + result += value_to_string(local_key_value.value, local_key_value, nesting) + if i != (field.value.size() - 1): + result += "," + result += "\n" + nesting -= 1 + result += tabulate(")", nesting) + else: + result += "()" + elif field.rule == PB_RULE.REPEATED: + if field.value.size() > 0: + result += "[\n" + nesting += 1 + for i in range(field.value.size()): + result += tabulate(String(i) + ": ", nesting) + result += value_to_string(field.value[i], field, nesting) + if i != (field.value.size() - 1): + result += "," + result += "\n" + nesting -= 1 + result += tabulate("]", nesting) + else: + result += "[]" + else: + result += value_to_string(field.value, field, nesting) + result += ";\n" + return result + + static func message_to_string(data, nesting : int = 0) -> String: + var DEFAULT_VALUES + if PROTO_VERSION == 2: + DEFAULT_VALUES = DEFAULT_VALUES_2 + elif PROTO_VERSION == 3: + DEFAULT_VALUES = DEFAULT_VALUES_3 + var result : String = "" + var keys : Array = data.keys() + keys.sort() + for i in keys: + if data[i].field.value != null: + if data[i].state == PB_SERVICE_STATE.UNFILLED \ + && !data[i].field.is_map_field \ + && typeof(data[i].field.value) == typeof(DEFAULT_VALUES[data[i].field.type]) \ + && data[i].field.value == DEFAULT_VALUES[data[i].field.type]: + continue + elif data[i].field.rule == PB_RULE.REPEATED && data[i].field.value.size() == 0: + continue + result += field_to_string(data[i].field, nesting) + elif data[i].field.rule == PB_RULE.REQUIRED: + result += data[i].field.name + ": " + "error" + return result + + + +############### USER DATA BEGIN ################ + + +class Guildpoint: + func _init(): + var service + + _category = PBField.new("category", PB_DATA_TYPE.MESSAGE, PB_RULE.REPEATED, 1, true, []) + service = PBServiceField.new() + service.field = _category + service.func_ref = funcref(self, "add_category") + data[_category.tag] = service + + _textures = PBField.new("textures", PB_DATA_TYPE.MESSAGE, PB_RULE.REPEATED, 2, true, []) + service = PBServiceField.new() + service.field = _textures + service.func_ref = funcref(self, "add_textures") + data[_textures.tag] = service + + var data = {} + + var _category: PBField + func get_category() -> Array: + return _category.value + func clear_category() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _category.value = [] + func add_category() -> Category: + var element = Category.new() + _category.value.append(element) + return element + + var _textures: PBField + func get_textures() -> Array: + return _textures.value + func clear_textures() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _textures.value = [] + func add_textures() -> TextureData: + var element = TextureData.new() + _textures.value.append(element) + return element + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class TextureData: + func _init(): + var service + + _filepath = PBField.new("filepath", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _filepath + data[_filepath.tag] = service + + var data = {} + + var _filepath: PBField + func get_filepath() -> String: + return _filepath.value + func clear_filepath() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _filepath.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_filepath(value : String) -> void: + _filepath.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class Category: + func _init(): + var service + + _name = PBField.new("name", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _name + data[_name.tag] = service + + _children = PBField.new("children", PB_DATA_TYPE.MESSAGE, PB_RULE.REPEATED, 2, true, []) + service = PBServiceField.new() + service.field = _children + service.func_ref = funcref(self, "add_children") + data[_children.tag] = service + + _icon = PBField.new("icon", PB_DATA_TYPE.MESSAGE, PB_RULE.REPEATED, 3, true, []) + service = PBServiceField.new() + service.field = _icon + service.func_ref = funcref(self, "add_icon") + data[_icon.tag] = service + + _trail = PBField.new("trail", PB_DATA_TYPE.MESSAGE, PB_RULE.REPEATED, 4, true, []) + service = PBServiceField.new() + service.field = _trail + service.func_ref = funcref(self, "add_trail") + data[_trail.tag] = service + + _is_separator = PBField.new("is_separator", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _is_separator + data[_is_separator.tag] = service + + _is_hidden = PBField.new("is_hidden", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 6, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _is_hidden + data[_is_hidden.tag] = service + + _tip_description = PBField.new("tip_description", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 7, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _tip_description + data[_tip_description.tag] = service + + _id = PBField.new("id", PB_DATA_TYPE.BYTES, PB_RULE.OPTIONAL, 8, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BYTES]) + service = PBServiceField.new() + service.field = _id + data[_id.tag] = service + + var data = {} + + var _name: PBField + func get_name() -> String: + return _name.value + func clear_name() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _name.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_name(value : String) -> void: + _name.value = value + + var _children: PBField + func get_children() -> Array: + return _children.value + func clear_children() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _children.value = [] + func add_children() -> Category: + var element = Category.new() + _children.value.append(element) + return element + + var _icon: PBField + func get_icon() -> Array: + return _icon.value + func clear_icon() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _icon.value = [] + func add_icon() -> Icon: + var element = Icon.new() + _icon.value.append(element) + return element + + var _trail: PBField + func get_trail() -> Array: + return _trail.value + func clear_trail() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _trail.value = [] + func add_trail() -> Trail: + var element = Trail.new() + _trail.value.append(element) + return element + + var _is_separator: PBField + func get_is_separator() -> bool: + return _is_separator.value + func clear_is_separator() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _is_separator.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_is_separator(value : bool) -> void: + _is_separator.value = value + + var _is_hidden: PBField + func get_is_hidden() -> bool: + return _is_hidden.value + func clear_is_hidden() -> void: + data[6].state = PB_SERVICE_STATE.UNFILLED + _is_hidden.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_is_hidden(value : bool) -> void: + _is_hidden.value = value + + var _tip_description: PBField + func get_tip_description() -> String: + return _tip_description.value + func clear_tip_description() -> void: + data[7].state = PB_SERVICE_STATE.UNFILLED + _tip_description.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_tip_description(value : String) -> void: + _tip_description.value = value + + var _id: PBField + func get_id() -> PoolByteArray: + return _id.value + func clear_id() -> void: + data[8].state = PB_SERVICE_STATE.UNFILLED + _id.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BYTES] + func set_id(value : PoolByteArray) -> void: + _id.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class Icon: + func _init(): + var service + + _texture_id = PBField.new("texture_id", PB_DATA_TYPE.UINT32, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.UINT32]) + service = PBServiceField.new() + service.field = _texture_id + data[_texture_id.tag] = service + + _guid = PBField.new("guid", PB_DATA_TYPE.BYTES, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BYTES]) + service = PBServiceField.new() + service.field = _guid + data[_guid.tag] = service + + _map_id = PBField.new("map_id", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 4, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _map_id + data[_map_id.tag] = service + + _distance_fade_end = PBField.new("distance_fade_end", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _distance_fade_end + data[_distance_fade_end.tag] = service + + _distance_fade_start = PBField.new("distance_fade_start", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 6, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _distance_fade_start + data[_distance_fade_start.tag] = service + + _height_offset = PBField.new("height_offset", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 7, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _height_offset + data[_height_offset.tag] = service + + _position = PBField.new("position", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 8, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _position + service.func_ref = funcref(self, "new_position") + data[_position.tag] = service + + _trigger = PBField.new("trigger", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 9, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _trigger + service.func_ref = funcref(self, "new_trigger") + data[_trigger.tag] = service + + _euler_rotation = PBField.new("euler_rotation", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 10, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _euler_rotation + service.func_ref = funcref(self, "new_euler_rotation") + data[_euler_rotation.tag] = service + + _achievement_id = PBField.new("achievement_id", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 16, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _achievement_id + data[_achievement_id.tag] = service + + _achievement_bit_index = PBField.new("achievement_bit_index", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 17, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _achievement_bit_index + data[_achievement_bit_index.tag] = service + + _disable_player_cutout = PBField.new("disable_player_cutout", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 19, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _disable_player_cutout + data[_disable_player_cutout.tag] = service + + _minimum_size_on_screen = PBField.new("minimum_size_on_screen", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 20, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _minimum_size_on_screen + data[_minimum_size_on_screen.tag] = service + + _map_display_size = PBField.new("map_display_size", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 21, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _map_display_size + data[_map_display_size.tag] = service + + _maximum_size_on_screen = PBField.new("maximum_size_on_screen", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 22, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _maximum_size_on_screen + data[_maximum_size_on_screen.tag] = service + + _constant_size_on_map = PBField.new("constant_size_on_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 23, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _constant_size_on_map + data[_constant_size_on_map.tag] = service + + _tip_description = PBField.new("tip_description", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 24, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _tip_description + data[_tip_description.tag] = service + + _tip_name = PBField.new("tip_name", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 25, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _tip_name + data[_tip_name.tag] = service + + _rgba_color = PBField.new("rgba_color", PB_DATA_TYPE.FIXED32, PB_RULE.OPTIONAL, 26, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FIXED32]) + service = PBServiceField.new() + service.field = _rgba_color + data[_rgba_color.tag] = service + + _festival_filter = PBField.new("festival_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 27, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _festival_filter + service.func_ref = funcref(self, "new_festival_filter") + data[_festival_filter.tag] = service + + _map_type_filter = PBField.new("map_type_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 28, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _map_type_filter + service.func_ref = funcref(self, "new_map_type_filter") + data[_map_type_filter.tag] = service + + _mount_filter = PBField.new("mount_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 29, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _mount_filter + service.func_ref = funcref(self, "new_mount_filter") + data[_mount_filter.tag] = service + + _profession_filter = PBField.new("profession_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 30, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _profession_filter + service.func_ref = funcref(self, "new_profession_filter") + data[_profession_filter.tag] = service + + _specialization_filter = PBField.new("specialization_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 31, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _specialization_filter + service.func_ref = funcref(self, "new_specialization_filter") + data[_specialization_filter.tag] = service + + _species_filter = PBField.new("species_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 32, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _species_filter + service.func_ref = funcref(self, "new_species_filter") + data[_species_filter.tag] = service + + _cull_chirality = PBField.new("cull_chirality", PB_DATA_TYPE.ENUM, PB_RULE.OPTIONAL, 33, true, DEFAULT_VALUES_3[PB_DATA_TYPE.ENUM]) + service = PBServiceField.new() + service.field = _cull_chirality + data[_cull_chirality.tag] = service + + _is_hidden_ingame = PBField.new("is_hidden_ingame", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 34, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _is_hidden_ingame + data[_is_hidden_ingame.tag] = service + + _is_hidden_on_map = PBField.new("is_hidden_on_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 35, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _is_hidden_on_map + data[_is_hidden_on_map.tag] = service + + _is_hidden_on_minimap = PBField.new("is_hidden_on_minimap", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 36, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _is_hidden_on_minimap + data[_is_hidden_on_minimap.tag] = service + + _tentative__scale = PBField.new("tentative__scale", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 2048, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _tentative__scale + data[_tentative__scale.tag] = service + + _bhdraft__schedule = PBField.new("bhdraft__schedule", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 2052, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _bhdraft__schedule + data[_bhdraft__schedule.tag] = service + + _bhdraft__schedule_duration = PBField.new("bhdraft__schedule_duration", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 2053, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _bhdraft__schedule_duration + data[_bhdraft__schedule_duration.tag] = service + + var data = {} + + var _texture_id: PBField + func get_texture_id() -> int: + return _texture_id.value + func clear_texture_id() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _texture_id.value = DEFAULT_VALUES_3[PB_DATA_TYPE.UINT32] + func set_texture_id(value : int) -> void: + _texture_id.value = value + + var _guid: PBField + func get_guid() -> PoolByteArray: + return _guid.value + func clear_guid() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _guid.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BYTES] + func set_guid(value : PoolByteArray) -> void: + _guid.value = value + + var _map_id: PBField + func get_map_id() -> int: + return _map_id.value + func clear_map_id() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _map_id.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_map_id(value : int) -> void: + _map_id.value = value + + var _distance_fade_end: PBField + func get_distance_fade_end() -> float: + return _distance_fade_end.value + func clear_distance_fade_end() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _distance_fade_end.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_distance_fade_end(value : float) -> void: + _distance_fade_end.value = value + + var _distance_fade_start: PBField + func get_distance_fade_start() -> float: + return _distance_fade_start.value + func clear_distance_fade_start() -> void: + data[6].state = PB_SERVICE_STATE.UNFILLED + _distance_fade_start.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_distance_fade_start(value : float) -> void: + _distance_fade_start.value = value + + var _height_offset: PBField + func get_height_offset() -> float: + return _height_offset.value + func clear_height_offset() -> void: + data[7].state = PB_SERVICE_STATE.UNFILLED + _height_offset.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_height_offset(value : float) -> void: + _height_offset.value = value + + var _position: PBField + func get_position() -> Position: + return _position.value + func clear_position() -> void: + data[8].state = PB_SERVICE_STATE.UNFILLED + _position.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_position() -> Position: + _position.value = Position.new() + return _position.value + + var _trigger: PBField + func get_trigger() -> Trigger: + return _trigger.value + func clear_trigger() -> void: + data[9].state = PB_SERVICE_STATE.UNFILLED + _trigger.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_trigger() -> Trigger: + _trigger.value = Trigger.new() + return _trigger.value + + var _euler_rotation: PBField + func get_euler_rotation() -> EulerRotation: + return _euler_rotation.value + func clear_euler_rotation() -> void: + data[10].state = PB_SERVICE_STATE.UNFILLED + _euler_rotation.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_euler_rotation() -> EulerRotation: + _euler_rotation.value = EulerRotation.new() + return _euler_rotation.value + + var _achievement_id: PBField + func get_achievement_id() -> int: + return _achievement_id.value + func clear_achievement_id() -> void: + data[16].state = PB_SERVICE_STATE.UNFILLED + _achievement_id.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_achievement_id(value : int) -> void: + _achievement_id.value = value + + var _achievement_bit_index: PBField + func get_achievement_bit_index() -> int: + return _achievement_bit_index.value + func clear_achievement_bit_index() -> void: + data[17].state = PB_SERVICE_STATE.UNFILLED + _achievement_bit_index.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_achievement_bit_index(value : int) -> void: + _achievement_bit_index.value = value + + var _disable_player_cutout: PBField + func get_disable_player_cutout() -> bool: + return _disable_player_cutout.value + func clear_disable_player_cutout() -> void: + data[19].state = PB_SERVICE_STATE.UNFILLED + _disable_player_cutout.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_disable_player_cutout(value : bool) -> void: + _disable_player_cutout.value = value + + var _minimum_size_on_screen: PBField + func get_minimum_size_on_screen() -> int: + return _minimum_size_on_screen.value + func clear_minimum_size_on_screen() -> void: + data[20].state = PB_SERVICE_STATE.UNFILLED + _minimum_size_on_screen.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_minimum_size_on_screen(value : int) -> void: + _minimum_size_on_screen.value = value + + var _map_display_size: PBField + func get_map_display_size() -> int: + return _map_display_size.value + func clear_map_display_size() -> void: + data[21].state = PB_SERVICE_STATE.UNFILLED + _map_display_size.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_map_display_size(value : int) -> void: + _map_display_size.value = value + + var _maximum_size_on_screen: PBField + func get_maximum_size_on_screen() -> int: + return _maximum_size_on_screen.value + func clear_maximum_size_on_screen() -> void: + data[22].state = PB_SERVICE_STATE.UNFILLED + _maximum_size_on_screen.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_maximum_size_on_screen(value : int) -> void: + _maximum_size_on_screen.value = value + + var _constant_size_on_map: PBField + func get_constant_size_on_map() -> bool: + return _constant_size_on_map.value + func clear_constant_size_on_map() -> void: + data[23].state = PB_SERVICE_STATE.UNFILLED + _constant_size_on_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_constant_size_on_map(value : bool) -> void: + _constant_size_on_map.value = value + + var _tip_description: PBField + func get_tip_description() -> String: + return _tip_description.value + func clear_tip_description() -> void: + data[24].state = PB_SERVICE_STATE.UNFILLED + _tip_description.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_tip_description(value : String) -> void: + _tip_description.value = value + + var _tip_name: PBField + func get_tip_name() -> String: + return _tip_name.value + func clear_tip_name() -> void: + data[25].state = PB_SERVICE_STATE.UNFILLED + _tip_name.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_tip_name(value : String) -> void: + _tip_name.value = value + + var _rgba_color: PBField + func get_rgba_color() -> int: + return _rgba_color.value + func clear_rgba_color() -> void: + data[26].state = PB_SERVICE_STATE.UNFILLED + _rgba_color.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FIXED32] + func set_rgba_color(value : int) -> void: + _rgba_color.value = value + + var _festival_filter: PBField + func get_festival_filter() -> FestivalFilter: + return _festival_filter.value + func clear_festival_filter() -> void: + data[27].state = PB_SERVICE_STATE.UNFILLED + _festival_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_festival_filter() -> FestivalFilter: + _festival_filter.value = FestivalFilter.new() + return _festival_filter.value + + var _map_type_filter: PBField + func get_map_type_filter() -> MapTypeFilter: + return _map_type_filter.value + func clear_map_type_filter() -> void: + data[28].state = PB_SERVICE_STATE.UNFILLED + _map_type_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_map_type_filter() -> MapTypeFilter: + _map_type_filter.value = MapTypeFilter.new() + return _map_type_filter.value + + var _mount_filter: PBField + func get_mount_filter() -> MountFilter: + return _mount_filter.value + func clear_mount_filter() -> void: + data[29].state = PB_SERVICE_STATE.UNFILLED + _mount_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_mount_filter() -> MountFilter: + _mount_filter.value = MountFilter.new() + return _mount_filter.value + + var _profession_filter: PBField + func get_profession_filter() -> ProfessionFilter: + return _profession_filter.value + func clear_profession_filter() -> void: + data[30].state = PB_SERVICE_STATE.UNFILLED + _profession_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_profession_filter() -> ProfessionFilter: + _profession_filter.value = ProfessionFilter.new() + return _profession_filter.value + + var _specialization_filter: PBField + func get_specialization_filter() -> SpecializationFilter: + return _specialization_filter.value + func clear_specialization_filter() -> void: + data[31].state = PB_SERVICE_STATE.UNFILLED + _specialization_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_specialization_filter() -> SpecializationFilter: + _specialization_filter.value = SpecializationFilter.new() + return _specialization_filter.value + + var _species_filter: PBField + func get_species_filter() -> SpeciesFilter: + return _species_filter.value + func clear_species_filter() -> void: + data[32].state = PB_SERVICE_STATE.UNFILLED + _species_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_species_filter() -> SpeciesFilter: + _species_filter.value = SpeciesFilter.new() + return _species_filter.value + + var _cull_chirality: PBField + func get_cull_chirality(): + return _cull_chirality.value + func clear_cull_chirality() -> void: + data[33].state = PB_SERVICE_STATE.UNFILLED + _cull_chirality.value = DEFAULT_VALUES_3[PB_DATA_TYPE.ENUM] + func set_cull_chirality(value) -> void: + _cull_chirality.value = value + + var _is_hidden_ingame: PBField + func get_is_hidden_ingame() -> bool: + return _is_hidden_ingame.value + func clear_is_hidden_ingame() -> void: + data[34].state = PB_SERVICE_STATE.UNFILLED + _is_hidden_ingame.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_is_hidden_ingame(value : bool) -> void: + _is_hidden_ingame.value = value + + var _is_hidden_on_map: PBField + func get_is_hidden_on_map() -> bool: + return _is_hidden_on_map.value + func clear_is_hidden_on_map() -> void: + data[35].state = PB_SERVICE_STATE.UNFILLED + _is_hidden_on_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_is_hidden_on_map(value : bool) -> void: + _is_hidden_on_map.value = value + + var _is_hidden_on_minimap: PBField + func get_is_hidden_on_minimap() -> bool: + return _is_hidden_on_minimap.value + func clear_is_hidden_on_minimap() -> void: + data[36].state = PB_SERVICE_STATE.UNFILLED + _is_hidden_on_minimap.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_is_hidden_on_minimap(value : bool) -> void: + _is_hidden_on_minimap.value = value + + var _tentative__scale: PBField + func get_tentative__scale() -> float: + return _tentative__scale.value + func clear_tentative__scale() -> void: + data[2048].state = PB_SERVICE_STATE.UNFILLED + _tentative__scale.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_tentative__scale(value : float) -> void: + _tentative__scale.value = value + + var _bhdraft__schedule: PBField + func get_bhdraft__schedule() -> String: + return _bhdraft__schedule.value + func clear_bhdraft__schedule() -> void: + data[2052].state = PB_SERVICE_STATE.UNFILLED + _bhdraft__schedule.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_bhdraft__schedule(value : String) -> void: + _bhdraft__schedule.value = value + + var _bhdraft__schedule_duration: PBField + func get_bhdraft__schedule_duration() -> float: + return _bhdraft__schedule_duration.value + func clear_bhdraft__schedule_duration() -> void: + data[2053].state = PB_SERVICE_STATE.UNFILLED + _bhdraft__schedule_duration.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_bhdraft__schedule_duration(value : float) -> void: + _bhdraft__schedule_duration.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class Trail: + func _init(): + var service + + _texture_id = PBField.new("texture_id", PB_DATA_TYPE.UINT32, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.UINT32]) + service = PBServiceField.new() + service.field = _texture_id + data[_texture_id.tag] = service + + _guid = PBField.new("guid", PB_DATA_TYPE.BYTES, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BYTES]) + service = PBServiceField.new() + service.field = _guid + data[_guid.tag] = service + + _map_id = PBField.new("map_id", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 4, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _map_id + data[_map_id.tag] = service + + _distance_fade_end = PBField.new("distance_fade_end", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _distance_fade_end + data[_distance_fade_end.tag] = service + + _distance_fade_start = PBField.new("distance_fade_start", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 6, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _distance_fade_start + data[_distance_fade_start.tag] = service + + _trail_data = PBField.new("trail_data", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 7, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _trail_data + service.func_ref = funcref(self, "new_trail_data") + data[_trail_data.tag] = service + + _animation_speed = PBField.new("animation_speed", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 8, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _animation_speed + data[_animation_speed.tag] = service + + _achievement_id = PBField.new("achievement_id", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 16, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _achievement_id + data[_achievement_id.tag] = service + + _achievement_bit_index = PBField.new("achievement_bit_index", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 17, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _achievement_bit_index + data[_achievement_bit_index.tag] = service + + _disable_player_cutout = PBField.new("disable_player_cutout", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 19, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _disable_player_cutout + data[_disable_player_cutout.tag] = service + + _is_wall = PBField.new("is_wall", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 20, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _is_wall + data[_is_wall.tag] = service + + _scale = PBField.new("scale", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 21, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _scale + data[_scale.tag] = service + + _rgba_color = PBField.new("rgba_color", PB_DATA_TYPE.FIXED32, PB_RULE.OPTIONAL, 22, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FIXED32]) + service = PBServiceField.new() + service.field = _rgba_color + data[_rgba_color.tag] = service + + _festival_filter = PBField.new("festival_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 23, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _festival_filter + service.func_ref = funcref(self, "new_festival_filter") + data[_festival_filter.tag] = service + + _map_type_filter = PBField.new("map_type_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 24, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _map_type_filter + service.func_ref = funcref(self, "new_map_type_filter") + data[_map_type_filter.tag] = service + + _mount_filter = PBField.new("mount_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 25, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _mount_filter + service.func_ref = funcref(self, "new_mount_filter") + data[_mount_filter.tag] = service + + _profession_filter = PBField.new("profession_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 26, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _profession_filter + service.func_ref = funcref(self, "new_profession_filter") + data[_profession_filter.tag] = service + + _specialization_filter = PBField.new("specialization_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 27, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _specialization_filter + service.func_ref = funcref(self, "new_specialization_filter") + data[_specialization_filter.tag] = service + + _species_filter = PBField.new("species_filter", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 28, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _species_filter + service.func_ref = funcref(self, "new_species_filter") + data[_species_filter.tag] = service + + _map_display_size = PBField.new("map_display_size", PB_DATA_TYPE.INT32, PB_RULE.OPTIONAL, 29, true, DEFAULT_VALUES_3[PB_DATA_TYPE.INT32]) + service = PBServiceField.new() + service.field = _map_display_size + data[_map_display_size.tag] = service + + _cull_chirality = PBField.new("cull_chirality", PB_DATA_TYPE.ENUM, PB_RULE.OPTIONAL, 30, true, DEFAULT_VALUES_3[PB_DATA_TYPE.ENUM]) + service = PBServiceField.new() + service.field = _cull_chirality + data[_cull_chirality.tag] = service + + _is_hidden_ingame = PBField.new("is_hidden_ingame", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 31, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _is_hidden_ingame + data[_is_hidden_ingame.tag] = service + + _is_hidden_on_map = PBField.new("is_hidden_on_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 32, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _is_hidden_on_map + data[_is_hidden_on_map.tag] = service + + _is_hidden_on_minimap = PBField.new("is_hidden_on_minimap", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 33, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _is_hidden_on_minimap + data[_is_hidden_on_minimap.tag] = service + + _bhdraft__schedule = PBField.new("bhdraft__schedule", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 2052, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _bhdraft__schedule + data[_bhdraft__schedule.tag] = service + + _bhdraft__schedule_duration = PBField.new("bhdraft__schedule_duration", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 2053, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _bhdraft__schedule_duration + data[_bhdraft__schedule_duration.tag] = service + + var data = {} + + var _texture_id: PBField + func get_texture_id() -> int: + return _texture_id.value + func clear_texture_id() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _texture_id.value = DEFAULT_VALUES_3[PB_DATA_TYPE.UINT32] + func set_texture_id(value : int) -> void: + _texture_id.value = value + + var _guid: PBField + func get_guid() -> PoolByteArray: + return _guid.value + func clear_guid() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _guid.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BYTES] + func set_guid(value : PoolByteArray) -> void: + _guid.value = value + + var _map_id: PBField + func get_map_id() -> int: + return _map_id.value + func clear_map_id() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _map_id.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_map_id(value : int) -> void: + _map_id.value = value + + var _distance_fade_end: PBField + func get_distance_fade_end() -> float: + return _distance_fade_end.value + func clear_distance_fade_end() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _distance_fade_end.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_distance_fade_end(value : float) -> void: + _distance_fade_end.value = value + + var _distance_fade_start: PBField + func get_distance_fade_start() -> float: + return _distance_fade_start.value + func clear_distance_fade_start() -> void: + data[6].state = PB_SERVICE_STATE.UNFILLED + _distance_fade_start.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_distance_fade_start(value : float) -> void: + _distance_fade_start.value = value + + var _trail_data: PBField + func get_trail_data() -> TrailData: + return _trail_data.value + func clear_trail_data() -> void: + data[7].state = PB_SERVICE_STATE.UNFILLED + _trail_data.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_trail_data() -> TrailData: + _trail_data.value = TrailData.new() + return _trail_data.value + + var _animation_speed: PBField + func get_animation_speed() -> float: + return _animation_speed.value + func clear_animation_speed() -> void: + data[8].state = PB_SERVICE_STATE.UNFILLED + _animation_speed.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_animation_speed(value : float) -> void: + _animation_speed.value = value + + var _achievement_id: PBField + func get_achievement_id() -> int: + return _achievement_id.value + func clear_achievement_id() -> void: + data[16].state = PB_SERVICE_STATE.UNFILLED + _achievement_id.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_achievement_id(value : int) -> void: + _achievement_id.value = value + + var _achievement_bit_index: PBField + func get_achievement_bit_index() -> int: + return _achievement_bit_index.value + func clear_achievement_bit_index() -> void: + data[17].state = PB_SERVICE_STATE.UNFILLED + _achievement_bit_index.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_achievement_bit_index(value : int) -> void: + _achievement_bit_index.value = value + + var _disable_player_cutout: PBField + func get_disable_player_cutout() -> bool: + return _disable_player_cutout.value + func clear_disable_player_cutout() -> void: + data[19].state = PB_SERVICE_STATE.UNFILLED + _disable_player_cutout.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_disable_player_cutout(value : bool) -> void: + _disable_player_cutout.value = value + + var _is_wall: PBField + func get_is_wall() -> bool: + return _is_wall.value + func clear_is_wall() -> void: + data[20].state = PB_SERVICE_STATE.UNFILLED + _is_wall.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_is_wall(value : bool) -> void: + _is_wall.value = value + + var _scale: PBField + func get_scale() -> float: + return _scale.value + func clear_scale() -> void: + data[21].state = PB_SERVICE_STATE.UNFILLED + _scale.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_scale(value : float) -> void: + _scale.value = value + + var _rgba_color: PBField + func get_rgba_color() -> int: + return _rgba_color.value + func clear_rgba_color() -> void: + data[22].state = PB_SERVICE_STATE.UNFILLED + _rgba_color.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FIXED32] + func set_rgba_color(value : int) -> void: + _rgba_color.value = value + + var _festival_filter: PBField + func get_festival_filter() -> FestivalFilter: + return _festival_filter.value + func clear_festival_filter() -> void: + data[23].state = PB_SERVICE_STATE.UNFILLED + _festival_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_festival_filter() -> FestivalFilter: + _festival_filter.value = FestivalFilter.new() + return _festival_filter.value + + var _map_type_filter: PBField + func get_map_type_filter() -> MapTypeFilter: + return _map_type_filter.value + func clear_map_type_filter() -> void: + data[24].state = PB_SERVICE_STATE.UNFILLED + _map_type_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_map_type_filter() -> MapTypeFilter: + _map_type_filter.value = MapTypeFilter.new() + return _map_type_filter.value + + var _mount_filter: PBField + func get_mount_filter() -> MountFilter: + return _mount_filter.value + func clear_mount_filter() -> void: + data[25].state = PB_SERVICE_STATE.UNFILLED + _mount_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_mount_filter() -> MountFilter: + _mount_filter.value = MountFilter.new() + return _mount_filter.value + + var _profession_filter: PBField + func get_profession_filter() -> ProfessionFilter: + return _profession_filter.value + func clear_profession_filter() -> void: + data[26].state = PB_SERVICE_STATE.UNFILLED + _profession_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_profession_filter() -> ProfessionFilter: + _profession_filter.value = ProfessionFilter.new() + return _profession_filter.value + + var _specialization_filter: PBField + func get_specialization_filter() -> SpecializationFilter: + return _specialization_filter.value + func clear_specialization_filter() -> void: + data[27].state = PB_SERVICE_STATE.UNFILLED + _specialization_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_specialization_filter() -> SpecializationFilter: + _specialization_filter.value = SpecializationFilter.new() + return _specialization_filter.value + + var _species_filter: PBField + func get_species_filter() -> SpeciesFilter: + return _species_filter.value + func clear_species_filter() -> void: + data[28].state = PB_SERVICE_STATE.UNFILLED + _species_filter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_species_filter() -> SpeciesFilter: + _species_filter.value = SpeciesFilter.new() + return _species_filter.value + + var _map_display_size: PBField + func get_map_display_size() -> int: + return _map_display_size.value + func clear_map_display_size() -> void: + data[29].state = PB_SERVICE_STATE.UNFILLED + _map_display_size.value = DEFAULT_VALUES_3[PB_DATA_TYPE.INT32] + func set_map_display_size(value : int) -> void: + _map_display_size.value = value + + var _cull_chirality: PBField + func get_cull_chirality(): + return _cull_chirality.value + func clear_cull_chirality() -> void: + data[30].state = PB_SERVICE_STATE.UNFILLED + _cull_chirality.value = DEFAULT_VALUES_3[PB_DATA_TYPE.ENUM] + func set_cull_chirality(value) -> void: + _cull_chirality.value = value + + var _is_hidden_ingame: PBField + func get_is_hidden_ingame() -> bool: + return _is_hidden_ingame.value + func clear_is_hidden_ingame() -> void: + data[31].state = PB_SERVICE_STATE.UNFILLED + _is_hidden_ingame.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_is_hidden_ingame(value : bool) -> void: + _is_hidden_ingame.value = value + + var _is_hidden_on_map: PBField + func get_is_hidden_on_map() -> bool: + return _is_hidden_on_map.value + func clear_is_hidden_on_map() -> void: + data[32].state = PB_SERVICE_STATE.UNFILLED + _is_hidden_on_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_is_hidden_on_map(value : bool) -> void: + _is_hidden_on_map.value = value + + var _is_hidden_on_minimap: PBField + func get_is_hidden_on_minimap() -> bool: + return _is_hidden_on_minimap.value + func clear_is_hidden_on_minimap() -> void: + data[33].state = PB_SERVICE_STATE.UNFILLED + _is_hidden_on_minimap.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_is_hidden_on_minimap(value : bool) -> void: + _is_hidden_on_minimap.value = value + + var _bhdraft__schedule: PBField + func get_bhdraft__schedule() -> String: + return _bhdraft__schedule.value + func clear_bhdraft__schedule() -> void: + data[2052].state = PB_SERVICE_STATE.UNFILLED + _bhdraft__schedule.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_bhdraft__schedule(value : String) -> void: + _bhdraft__schedule.value = value + + var _bhdraft__schedule_duration: PBField + func get_bhdraft__schedule_duration() -> float: + return _bhdraft__schedule_duration.value + func clear_bhdraft__schedule_duration() -> void: + data[2053].state = PB_SERVICE_STATE.UNFILLED + _bhdraft__schedule_duration.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_bhdraft__schedule_duration(value : float) -> void: + _bhdraft__schedule_duration.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class Position: + func _init(): + var service + + _x = PBField.new("x", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _x + data[_x.tag] = service + + _y = PBField.new("y", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _y + data[_y.tag] = service + + _z = PBField.new("z", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _z + data[_z.tag] = service + + var data = {} + + var _x: PBField + func get_x() -> float: + return _x.value + func clear_x() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _x.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_x(value : float) -> void: + _x.value = value + + var _y: PBField + func get_y() -> float: + return _y.value + func clear_y() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _y.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_y(value : float) -> void: + _y.value = value + + var _z: PBField + func get_z() -> float: + return _z.value + func clear_z() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _z.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_z(value : float) -> void: + _z.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class EulerRotation: + func _init(): + var service + + _x = PBField.new("x", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _x + data[_x.tag] = service + + _y = PBField.new("y", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _y + data[_y.tag] = service + + _z = PBField.new("z", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _z + data[_z.tag] = service + + var data = {} + + var _x: PBField + func get_x() -> float: + return _x.value + func clear_x() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _x.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_x(value : float) -> void: + _x.value = value + + var _y: PBField + func get_y() -> float: + return _y.value + func clear_y() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _y.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_y(value : float) -> void: + _y.value = value + + var _z: PBField + func get_z() -> float: + return _z.value + func clear_z() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _z.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_z(value : float) -> void: + _z.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class Trigger: + func _init(): + var service + + _auto_trigger = PBField.new("auto_trigger", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _auto_trigger + data[_auto_trigger.tag] = service + + _bounce_delay = PBField.new("bounce_delay", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _bounce_delay + data[_bounce_delay.tag] = service + + _bounce_duration = PBField.new("bounce_duration", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _bounce_duration + data[_bounce_duration.tag] = service + + _bounce_height = PBField.new("bounce_height", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 4, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _bounce_height + data[_bounce_height.tag] = service + + _action_copy_clipboard = PBField.new("action_copy_clipboard", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _action_copy_clipboard + data[_action_copy_clipboard.tag] = service + + _action_copy_message = PBField.new("action_copy_message", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 6, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _action_copy_message + data[_action_copy_message.tag] = service + + _has_countdown = PBField.new("has_countdown", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 7, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _has_countdown + data[_has_countdown.tag] = service + + _action_info_message = PBField.new("action_info_message", PB_DATA_TYPE.STRING, PB_RULE.OPTIONAL, 8, true, DEFAULT_VALUES_3[PB_DATA_TYPE.STRING]) + service = PBServiceField.new() + service.field = _action_info_message + data[_action_info_message.tag] = service + + _invert_display = PBField.new("invert_display", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 9, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _invert_display + data[_invert_display.tag] = service + + _reset_length = PBField.new("reset_length", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 10, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _reset_length + data[_reset_length.tag] = service + + _range = PBField.new("range", PB_DATA_TYPE.FLOAT, PB_RULE.OPTIONAL, 11, true, DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT]) + service = PBServiceField.new() + service.field = _range + data[_range.tag] = service + + _action_hide_category = PBField.new("action_hide_category", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 12, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _action_hide_category + service.func_ref = funcref(self, "new_action_hide_category") + data[_action_hide_category.tag] = service + + _action_show_category = PBField.new("action_show_category", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 13, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _action_show_category + service.func_ref = funcref(self, "new_action_show_category") + data[_action_show_category.tag] = service + + _action_toggle_category = PBField.new("action_toggle_category", PB_DATA_TYPE.MESSAGE, PB_RULE.OPTIONAL, 14, true, DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE]) + service = PBServiceField.new() + service.field = _action_toggle_category + service.func_ref = funcref(self, "new_action_toggle_category") + data[_action_toggle_category.tag] = service + + _reset_behavior = PBField.new("reset_behavior", PB_DATA_TYPE.ENUM, PB_RULE.OPTIONAL, 15, true, DEFAULT_VALUES_3[PB_DATA_TYPE.ENUM]) + service = PBServiceField.new() + service.field = _reset_behavior + data[_reset_behavior.tag] = service + + var data = {} + + var _auto_trigger: PBField + func get_auto_trigger() -> bool: + return _auto_trigger.value + func clear_auto_trigger() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _auto_trigger.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_auto_trigger(value : bool) -> void: + _auto_trigger.value = value + + var _bounce_delay: PBField + func get_bounce_delay() -> float: + return _bounce_delay.value + func clear_bounce_delay() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _bounce_delay.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_bounce_delay(value : float) -> void: + _bounce_delay.value = value + + var _bounce_duration: PBField + func get_bounce_duration() -> float: + return _bounce_duration.value + func clear_bounce_duration() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _bounce_duration.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_bounce_duration(value : float) -> void: + _bounce_duration.value = value + + var _bounce_height: PBField + func get_bounce_height() -> float: + return _bounce_height.value + func clear_bounce_height() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _bounce_height.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_bounce_height(value : float) -> void: + _bounce_height.value = value + + var _action_copy_clipboard: PBField + func get_action_copy_clipboard() -> String: + return _action_copy_clipboard.value + func clear_action_copy_clipboard() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _action_copy_clipboard.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_action_copy_clipboard(value : String) -> void: + _action_copy_clipboard.value = value + + var _action_copy_message: PBField + func get_action_copy_message() -> String: + return _action_copy_message.value + func clear_action_copy_message() -> void: + data[6].state = PB_SERVICE_STATE.UNFILLED + _action_copy_message.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_action_copy_message(value : String) -> void: + _action_copy_message.value = value + + var _has_countdown: PBField + func get_has_countdown() -> bool: + return _has_countdown.value + func clear_has_countdown() -> void: + data[7].state = PB_SERVICE_STATE.UNFILLED + _has_countdown.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_has_countdown(value : bool) -> void: + _has_countdown.value = value + + var _action_info_message: PBField + func get_action_info_message() -> String: + return _action_info_message.value + func clear_action_info_message() -> void: + data[8].state = PB_SERVICE_STATE.UNFILLED + _action_info_message.value = DEFAULT_VALUES_3[PB_DATA_TYPE.STRING] + func set_action_info_message(value : String) -> void: + _action_info_message.value = value + + var _invert_display: PBField + func get_invert_display() -> bool: + return _invert_display.value + func clear_invert_display() -> void: + data[9].state = PB_SERVICE_STATE.UNFILLED + _invert_display.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_invert_display(value : bool) -> void: + _invert_display.value = value + + var _reset_length: PBField + func get_reset_length() -> float: + return _reset_length.value + func clear_reset_length() -> void: + data[10].state = PB_SERVICE_STATE.UNFILLED + _reset_length.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_reset_length(value : float) -> void: + _reset_length.value = value + + var _range: PBField + func get_range() -> float: + return _range.value + func clear_range() -> void: + data[11].state = PB_SERVICE_STATE.UNFILLED + _range.value = DEFAULT_VALUES_3[PB_DATA_TYPE.FLOAT] + func set_range(value : float) -> void: + _range.value = value + + var _action_hide_category: PBField + func get_action_hide_category() -> Category: + return _action_hide_category.value + func clear_action_hide_category() -> void: + data[12].state = PB_SERVICE_STATE.UNFILLED + _action_hide_category.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_action_hide_category() -> Category: + _action_hide_category.value = Category.new() + return _action_hide_category.value + + var _action_show_category: PBField + func get_action_show_category() -> Category: + return _action_show_category.value + func clear_action_show_category() -> void: + data[13].state = PB_SERVICE_STATE.UNFILLED + _action_show_category.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_action_show_category() -> Category: + _action_show_category.value = Category.new() + return _action_show_category.value + + var _action_toggle_category: PBField + func get_action_toggle_category() -> Category: + return _action_toggle_category.value + func clear_action_toggle_category() -> void: + data[14].state = PB_SERVICE_STATE.UNFILLED + _action_toggle_category.value = DEFAULT_VALUES_3[PB_DATA_TYPE.MESSAGE] + func new_action_toggle_category() -> Category: + _action_toggle_category.value = Category.new() + return _action_toggle_category.value + + var _reset_behavior: PBField + func get_reset_behavior(): + return _reset_behavior.value + func clear_reset_behavior() -> void: + data[15].state = PB_SERVICE_STATE.UNFILLED + _reset_behavior.value = DEFAULT_VALUES_3[PB_DATA_TYPE.ENUM] + func set_reset_behavior(value) -> void: + _reset_behavior.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +enum CullChirality { + none = 0, + clockwise = 1, + counter_clockwise = 2 +} + +enum ResetBehavior { + always_visible = 0, + map_change = 1, + daily_reset = 2, + never = 3, + timer = 4, + map_reset = 5, + instance_change = 6, + daily_reset_per_character = 7, + weekly_reset = 8 +} + +class FestivalFilter: + func _init(): + var service + + _dragonbash = PBField.new("dragonbash", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _dragonbash + data[_dragonbash.tag] = service + + _festival_of_the_four_winds = PBField.new("festival_of_the_four_winds", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _festival_of_the_four_winds + data[_festival_of_the_four_winds.tag] = service + + _halloween = PBField.new("halloween", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _halloween + data[_halloween.tag] = service + + _lunar_new_year = PBField.new("lunar_new_year", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 4, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _lunar_new_year + data[_lunar_new_year.tag] = service + + _super_adventure_festival = PBField.new("super_adventure_festival", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _super_adventure_festival + data[_super_adventure_festival.tag] = service + + _wintersday = PBField.new("wintersday", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 6, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _wintersday + data[_wintersday.tag] = service + + _none = PBField.new("none", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 7, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _none + data[_none.tag] = service + + var data = {} + + var _dragonbash: PBField + func get_dragonbash() -> bool: + return _dragonbash.value + func clear_dragonbash() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _dragonbash.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_dragonbash(value : bool) -> void: + _dragonbash.value = value + + var _festival_of_the_four_winds: PBField + func get_festival_of_the_four_winds() -> bool: + return _festival_of_the_four_winds.value + func clear_festival_of_the_four_winds() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _festival_of_the_four_winds.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_festival_of_the_four_winds(value : bool) -> void: + _festival_of_the_four_winds.value = value + + var _halloween: PBField + func get_halloween() -> bool: + return _halloween.value + func clear_halloween() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _halloween.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_halloween(value : bool) -> void: + _halloween.value = value + + var _lunar_new_year: PBField + func get_lunar_new_year() -> bool: + return _lunar_new_year.value + func clear_lunar_new_year() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _lunar_new_year.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_lunar_new_year(value : bool) -> void: + _lunar_new_year.value = value + + var _super_adventure_festival: PBField + func get_super_adventure_festival() -> bool: + return _super_adventure_festival.value + func clear_super_adventure_festival() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _super_adventure_festival.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_super_adventure_festival(value : bool) -> void: + _super_adventure_festival.value = value + + var _wintersday: PBField + func get_wintersday() -> bool: + return _wintersday.value + func clear_wintersday() -> void: + data[6].state = PB_SERVICE_STATE.UNFILLED + _wintersday.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_wintersday(value : bool) -> void: + _wintersday.value = value + + var _none: PBField + func get_none() -> bool: + return _none.value + func clear_none() -> void: + data[7].state = PB_SERVICE_STATE.UNFILLED + _none.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_none(value : bool) -> void: + _none.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class MapTypeFilter: + func _init(): + var service + + _unknown_map = PBField.new("unknown_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _unknown_map + data[_unknown_map.tag] = service + + _redirect_map = PBField.new("redirect_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _redirect_map + data[_redirect_map.tag] = service + + _character_create_map = PBField.new("character_create_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _character_create_map + data[_character_create_map.tag] = service + + _pvp_map = PBField.new("pvp_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 4, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _pvp_map + data[_pvp_map.tag] = service + + _gvg_map = PBField.new("gvg_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _gvg_map + data[_gvg_map.tag] = service + + _instance_map = PBField.new("instance_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 6, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _instance_map + data[_instance_map.tag] = service + + _public_map = PBField.new("public_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 7, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _public_map + data[_public_map.tag] = service + + _tournament_map = PBField.new("tournament_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 8, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _tournament_map + data[_tournament_map.tag] = service + + _tutorial_map = PBField.new("tutorial_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 9, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _tutorial_map + data[_tutorial_map.tag] = service + + _user_tournament_map = PBField.new("user_tournament_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 10, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _user_tournament_map + data[_user_tournament_map.tag] = service + + _center_map = PBField.new("center_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 11, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _center_map + data[_center_map.tag] = service + + _eternal_battlegrounds_map = PBField.new("eternal_battlegrounds_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 12, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _eternal_battlegrounds_map + data[_eternal_battlegrounds_map.tag] = service + + _bluehome_map = PBField.new("bluehome_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 13, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _bluehome_map + data[_bluehome_map.tag] = service + + _blue_borderlands_map = PBField.new("blue_borderlands_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 14, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _blue_borderlands_map + data[_blue_borderlands_map.tag] = service + + _green_home_map = PBField.new("green_home_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 15, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _green_home_map + data[_green_home_map.tag] = service + + _green_borderlands_map = PBField.new("green_borderlands_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 16, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _green_borderlands_map + data[_green_borderlands_map.tag] = service + + _red_home_map = PBField.new("red_home_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 17, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _red_home_map + data[_red_home_map.tag] = service + + _red_borderlands_map = PBField.new("red_borderlands_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 18, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _red_borderlands_map + data[_red_borderlands_map.tag] = service + + _fortunes_vale_map = PBField.new("fortunes_vale_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 19, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _fortunes_vale_map + data[_fortunes_vale_map.tag] = service + + _jump_puzzle_map = PBField.new("jump_puzzle_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 20, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _jump_puzzle_map + data[_jump_puzzle_map.tag] = service + + _obsidian_sanctum_map = PBField.new("obsidian_sanctum_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 21, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _obsidian_sanctum_map + data[_obsidian_sanctum_map.tag] = service + + _edge_of_the_mists_map = PBField.new("edge_of_the_mists_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 22, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _edge_of_the_mists_map + data[_edge_of_the_mists_map.tag] = service + + _public_mini_map = PBField.new("public_mini_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 23, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _public_mini_map + data[_public_mini_map.tag] = service + + _wvw_lounge_map = PBField.new("wvw_lounge_map", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 24, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _wvw_lounge_map + data[_wvw_lounge_map.tag] = service + + var data = {} + + var _unknown_map: PBField + func get_unknown_map() -> bool: + return _unknown_map.value + func clear_unknown_map() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _unknown_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_unknown_map(value : bool) -> void: + _unknown_map.value = value + + var _redirect_map: PBField + func get_redirect_map() -> bool: + return _redirect_map.value + func clear_redirect_map() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _redirect_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_redirect_map(value : bool) -> void: + _redirect_map.value = value + + var _character_create_map: PBField + func get_character_create_map() -> bool: + return _character_create_map.value + func clear_character_create_map() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _character_create_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_character_create_map(value : bool) -> void: + _character_create_map.value = value + + var _pvp_map: PBField + func get_pvp_map() -> bool: + return _pvp_map.value + func clear_pvp_map() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _pvp_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_pvp_map(value : bool) -> void: + _pvp_map.value = value + + var _gvg_map: PBField + func get_gvg_map() -> bool: + return _gvg_map.value + func clear_gvg_map() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _gvg_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_gvg_map(value : bool) -> void: + _gvg_map.value = value + + var _instance_map: PBField + func get_instance_map() -> bool: + return _instance_map.value + func clear_instance_map() -> void: + data[6].state = PB_SERVICE_STATE.UNFILLED + _instance_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_instance_map(value : bool) -> void: + _instance_map.value = value + + var _public_map: PBField + func get_public_map() -> bool: + return _public_map.value + func clear_public_map() -> void: + data[7].state = PB_SERVICE_STATE.UNFILLED + _public_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_public_map(value : bool) -> void: + _public_map.value = value + + var _tournament_map: PBField + func get_tournament_map() -> bool: + return _tournament_map.value + func clear_tournament_map() -> void: + data[8].state = PB_SERVICE_STATE.UNFILLED + _tournament_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_tournament_map(value : bool) -> void: + _tournament_map.value = value + + var _tutorial_map: PBField + func get_tutorial_map() -> bool: + return _tutorial_map.value + func clear_tutorial_map() -> void: + data[9].state = PB_SERVICE_STATE.UNFILLED + _tutorial_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_tutorial_map(value : bool) -> void: + _tutorial_map.value = value + + var _user_tournament_map: PBField + func get_user_tournament_map() -> bool: + return _user_tournament_map.value + func clear_user_tournament_map() -> void: + data[10].state = PB_SERVICE_STATE.UNFILLED + _user_tournament_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_user_tournament_map(value : bool) -> void: + _user_tournament_map.value = value + + var _center_map: PBField + func get_center_map() -> bool: + return _center_map.value + func clear_center_map() -> void: + data[11].state = PB_SERVICE_STATE.UNFILLED + _center_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_center_map(value : bool) -> void: + _center_map.value = value + + var _eternal_battlegrounds_map: PBField + func get_eternal_battlegrounds_map() -> bool: + return _eternal_battlegrounds_map.value + func clear_eternal_battlegrounds_map() -> void: + data[12].state = PB_SERVICE_STATE.UNFILLED + _eternal_battlegrounds_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_eternal_battlegrounds_map(value : bool) -> void: + _eternal_battlegrounds_map.value = value + + var _bluehome_map: PBField + func get_bluehome_map() -> bool: + return _bluehome_map.value + func clear_bluehome_map() -> void: + data[13].state = PB_SERVICE_STATE.UNFILLED + _bluehome_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_bluehome_map(value : bool) -> void: + _bluehome_map.value = value + + var _blue_borderlands_map: PBField + func get_blue_borderlands_map() -> bool: + return _blue_borderlands_map.value + func clear_blue_borderlands_map() -> void: + data[14].state = PB_SERVICE_STATE.UNFILLED + _blue_borderlands_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_blue_borderlands_map(value : bool) -> void: + _blue_borderlands_map.value = value + + var _green_home_map: PBField + func get_green_home_map() -> bool: + return _green_home_map.value + func clear_green_home_map() -> void: + data[15].state = PB_SERVICE_STATE.UNFILLED + _green_home_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_green_home_map(value : bool) -> void: + _green_home_map.value = value + + var _green_borderlands_map: PBField + func get_green_borderlands_map() -> bool: + return _green_borderlands_map.value + func clear_green_borderlands_map() -> void: + data[16].state = PB_SERVICE_STATE.UNFILLED + _green_borderlands_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_green_borderlands_map(value : bool) -> void: + _green_borderlands_map.value = value + + var _red_home_map: PBField + func get_red_home_map() -> bool: + return _red_home_map.value + func clear_red_home_map() -> void: + data[17].state = PB_SERVICE_STATE.UNFILLED + _red_home_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_red_home_map(value : bool) -> void: + _red_home_map.value = value + + var _red_borderlands_map: PBField + func get_red_borderlands_map() -> bool: + return _red_borderlands_map.value + func clear_red_borderlands_map() -> void: + data[18].state = PB_SERVICE_STATE.UNFILLED + _red_borderlands_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_red_borderlands_map(value : bool) -> void: + _red_borderlands_map.value = value + + var _fortunes_vale_map: PBField + func get_fortunes_vale_map() -> bool: + return _fortunes_vale_map.value + func clear_fortunes_vale_map() -> void: + data[19].state = PB_SERVICE_STATE.UNFILLED + _fortunes_vale_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_fortunes_vale_map(value : bool) -> void: + _fortunes_vale_map.value = value + + var _jump_puzzle_map: PBField + func get_jump_puzzle_map() -> bool: + return _jump_puzzle_map.value + func clear_jump_puzzle_map() -> void: + data[20].state = PB_SERVICE_STATE.UNFILLED + _jump_puzzle_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_jump_puzzle_map(value : bool) -> void: + _jump_puzzle_map.value = value + + var _obsidian_sanctum_map: PBField + func get_obsidian_sanctum_map() -> bool: + return _obsidian_sanctum_map.value + func clear_obsidian_sanctum_map() -> void: + data[21].state = PB_SERVICE_STATE.UNFILLED + _obsidian_sanctum_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_obsidian_sanctum_map(value : bool) -> void: + _obsidian_sanctum_map.value = value + + var _edge_of_the_mists_map: PBField + func get_edge_of_the_mists_map() -> bool: + return _edge_of_the_mists_map.value + func clear_edge_of_the_mists_map() -> void: + data[22].state = PB_SERVICE_STATE.UNFILLED + _edge_of_the_mists_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_edge_of_the_mists_map(value : bool) -> void: + _edge_of_the_mists_map.value = value + + var _public_mini_map: PBField + func get_public_mini_map() -> bool: + return _public_mini_map.value + func clear_public_mini_map() -> void: + data[23].state = PB_SERVICE_STATE.UNFILLED + _public_mini_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_public_mini_map(value : bool) -> void: + _public_mini_map.value = value + + var _wvw_lounge_map: PBField + func get_wvw_lounge_map() -> bool: + return _wvw_lounge_map.value + func clear_wvw_lounge_map() -> void: + data[24].state = PB_SERVICE_STATE.UNFILLED + _wvw_lounge_map.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_wvw_lounge_map(value : bool) -> void: + _wvw_lounge_map.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class MountFilter: + func _init(): + var service + + _raptor = PBField.new("raptor", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _raptor + data[_raptor.tag] = service + + _springer = PBField.new("springer", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _springer + data[_springer.tag] = service + + _skimmer = PBField.new("skimmer", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _skimmer + data[_skimmer.tag] = service + + _jackal = PBField.new("jackal", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 4, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _jackal + data[_jackal.tag] = service + + _griffon = PBField.new("griffon", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _griffon + data[_griffon.tag] = service + + _roller_beetle = PBField.new("roller_beetle", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 6, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _roller_beetle + data[_roller_beetle.tag] = service + + _warclaw = PBField.new("warclaw", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 7, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warclaw + data[_warclaw.tag] = service + + _skyscale = PBField.new("skyscale", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 8, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _skyscale + data[_skyscale.tag] = service + + _skiff = PBField.new("skiff", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 9, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _skiff + data[_skiff.tag] = service + + _seige_turtle = PBField.new("seige_turtle", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 10, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _seige_turtle + data[_seige_turtle.tag] = service + + var data = {} + + var _raptor: PBField + func get_raptor() -> bool: + return _raptor.value + func clear_raptor() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _raptor.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_raptor(value : bool) -> void: + _raptor.value = value + + var _springer: PBField + func get_springer() -> bool: + return _springer.value + func clear_springer() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _springer.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_springer(value : bool) -> void: + _springer.value = value + + var _skimmer: PBField + func get_skimmer() -> bool: + return _skimmer.value + func clear_skimmer() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _skimmer.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_skimmer(value : bool) -> void: + _skimmer.value = value + + var _jackal: PBField + func get_jackal() -> bool: + return _jackal.value + func clear_jackal() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _jackal.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_jackal(value : bool) -> void: + _jackal.value = value + + var _griffon: PBField + func get_griffon() -> bool: + return _griffon.value + func clear_griffon() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _griffon.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_griffon(value : bool) -> void: + _griffon.value = value + + var _roller_beetle: PBField + func get_roller_beetle() -> bool: + return _roller_beetle.value + func clear_roller_beetle() -> void: + data[6].state = PB_SERVICE_STATE.UNFILLED + _roller_beetle.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_roller_beetle(value : bool) -> void: + _roller_beetle.value = value + + var _warclaw: PBField + func get_warclaw() -> bool: + return _warclaw.value + func clear_warclaw() -> void: + data[7].state = PB_SERVICE_STATE.UNFILLED + _warclaw.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warclaw(value : bool) -> void: + _warclaw.value = value + + var _skyscale: PBField + func get_skyscale() -> bool: + return _skyscale.value + func clear_skyscale() -> void: + data[8].state = PB_SERVICE_STATE.UNFILLED + _skyscale.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_skyscale(value : bool) -> void: + _skyscale.value = value + + var _skiff: PBField + func get_skiff() -> bool: + return _skiff.value + func clear_skiff() -> void: + data[9].state = PB_SERVICE_STATE.UNFILLED + _skiff.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_skiff(value : bool) -> void: + _skiff.value = value + + var _seige_turtle: PBField + func get_seige_turtle() -> bool: + return _seige_turtle.value + func clear_seige_turtle() -> void: + data[10].state = PB_SERVICE_STATE.UNFILLED + _seige_turtle.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_seige_turtle(value : bool) -> void: + _seige_turtle.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class ProfessionFilter: + func _init(): + var service + + _guardian = PBField.new("guardian", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _guardian + data[_guardian.tag] = service + + _warrior = PBField.new("warrior", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warrior + data[_warrior.tag] = service + + _engineer = PBField.new("engineer", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _engineer + data[_engineer.tag] = service + + _ranger = PBField.new("ranger", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 4, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _ranger + data[_ranger.tag] = service + + _thief = PBField.new("thief", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _thief + data[_thief.tag] = service + + _elementalist = PBField.new("elementalist", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 6, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _elementalist + data[_elementalist.tag] = service + + _mesmer = PBField.new("mesmer", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 7, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _mesmer + data[_mesmer.tag] = service + + _necromancer = PBField.new("necromancer", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 8, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _necromancer + data[_necromancer.tag] = service + + _revenant = PBField.new("revenant", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 9, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _revenant + data[_revenant.tag] = service + + var data = {} + + var _guardian: PBField + func get_guardian() -> bool: + return _guardian.value + func clear_guardian() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _guardian.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_guardian(value : bool) -> void: + _guardian.value = value + + var _warrior: PBField + func get_warrior() -> bool: + return _warrior.value + func clear_warrior() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _warrior.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warrior(value : bool) -> void: + _warrior.value = value + + var _engineer: PBField + func get_engineer() -> bool: + return _engineer.value + func clear_engineer() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _engineer.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_engineer(value : bool) -> void: + _engineer.value = value + + var _ranger: PBField + func get_ranger() -> bool: + return _ranger.value + func clear_ranger() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _ranger.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_ranger(value : bool) -> void: + _ranger.value = value + + var _thief: PBField + func get_thief() -> bool: + return _thief.value + func clear_thief() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _thief.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_thief(value : bool) -> void: + _thief.value = value + + var _elementalist: PBField + func get_elementalist() -> bool: + return _elementalist.value + func clear_elementalist() -> void: + data[6].state = PB_SERVICE_STATE.UNFILLED + _elementalist.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_elementalist(value : bool) -> void: + _elementalist.value = value + + var _mesmer: PBField + func get_mesmer() -> bool: + return _mesmer.value + func clear_mesmer() -> void: + data[7].state = PB_SERVICE_STATE.UNFILLED + _mesmer.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_mesmer(value : bool) -> void: + _mesmer.value = value + + var _necromancer: PBField + func get_necromancer() -> bool: + return _necromancer.value + func clear_necromancer() -> void: + data[8].state = PB_SERVICE_STATE.UNFILLED + _necromancer.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_necromancer(value : bool) -> void: + _necromancer.value = value + + var _revenant: PBField + func get_revenant() -> bool: + return _revenant.value + func clear_revenant() -> void: + data[9].state = PB_SERVICE_STATE.UNFILLED + _revenant.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_revenant(value : bool) -> void: + _revenant.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class SpecializationFilter: + func _init(): + var service + + _elementalist_tempest = PBField.new("elementalist_tempest", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _elementalist_tempest + data[_elementalist_tempest.tag] = service + + _engineer_scrapper = PBField.new("engineer_scrapper", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _engineer_scrapper + data[_engineer_scrapper.tag] = service + + _guardian_dragonhunter = PBField.new("guardian_dragonhunter", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _guardian_dragonhunter + data[_guardian_dragonhunter.tag] = service + + _mesmer_chronomancer = PBField.new("mesmer_chronomancer", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 4, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _mesmer_chronomancer + data[_mesmer_chronomancer.tag] = service + + _necromancer_reaper = PBField.new("necromancer_reaper", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _necromancer_reaper + data[_necromancer_reaper.tag] = service + + _ranger_druid = PBField.new("ranger_druid", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 6, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _ranger_druid + data[_ranger_druid.tag] = service + + _revenant_herald = PBField.new("revenant_herald", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 7, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _revenant_herald + data[_revenant_herald.tag] = service + + _thief_daredevil = PBField.new("thief_daredevil", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 8, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _thief_daredevil + data[_thief_daredevil.tag] = service + + _warrior_berserker = PBField.new("warrior_berserker", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 9, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warrior_berserker + data[_warrior_berserker.tag] = service + + _elementalist_weaver = PBField.new("elementalist_weaver", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 10, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _elementalist_weaver + data[_elementalist_weaver.tag] = service + + _engineer_holosmith = PBField.new("engineer_holosmith", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 11, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _engineer_holosmith + data[_engineer_holosmith.tag] = service + + _guardian_firebrand = PBField.new("guardian_firebrand", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 12, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _guardian_firebrand + data[_guardian_firebrand.tag] = service + + _mesmer_mirage = PBField.new("mesmer_mirage", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 13, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _mesmer_mirage + data[_mesmer_mirage.tag] = service + + _necromancer_scourge = PBField.new("necromancer_scourge", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 14, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _necromancer_scourge + data[_necromancer_scourge.tag] = service + + _ranger_soulbeast = PBField.new("ranger_soulbeast", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 15, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _ranger_soulbeast + data[_ranger_soulbeast.tag] = service + + _revenant_renegade = PBField.new("revenant_renegade", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 16, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _revenant_renegade + data[_revenant_renegade.tag] = service + + _thief_deadeye = PBField.new("thief_deadeye", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 17, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _thief_deadeye + data[_thief_deadeye.tag] = service + + _warrior_spellbreaker = PBField.new("warrior_spellbreaker", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 18, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warrior_spellbreaker + data[_warrior_spellbreaker.tag] = service + + _elementalist_catalyst = PBField.new("elementalist_catalyst", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 19, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _elementalist_catalyst + data[_elementalist_catalyst.tag] = service + + _engineer_mechanist = PBField.new("engineer_mechanist", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 20, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _engineer_mechanist + data[_engineer_mechanist.tag] = service + + _guardian_willbender = PBField.new("guardian_willbender", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 21, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _guardian_willbender + data[_guardian_willbender.tag] = service + + _mesmer_virtuoso = PBField.new("mesmer_virtuoso", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 22, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _mesmer_virtuoso + data[_mesmer_virtuoso.tag] = service + + _necromancer_harbinger = PBField.new("necromancer_harbinger", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 23, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _necromancer_harbinger + data[_necromancer_harbinger.tag] = service + + _ranger_untamed = PBField.new("ranger_untamed", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 24, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _ranger_untamed + data[_ranger_untamed.tag] = service + + _revenant_vindicator = PBField.new("revenant_vindicator", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 25, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _revenant_vindicator + data[_revenant_vindicator.tag] = service + + _thief_specter = PBField.new("thief_specter", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 26, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _thief_specter + data[_thief_specter.tag] = service + + _warrior_bladesworn = PBField.new("warrior_bladesworn", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 27, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warrior_bladesworn + data[_warrior_bladesworn.tag] = service + + _elementalist_air = PBField.new("elementalist_air", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 28, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _elementalist_air + data[_elementalist_air.tag] = service + + _elementalist_arcane = PBField.new("elementalist_arcane", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 29, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _elementalist_arcane + data[_elementalist_arcane.tag] = service + + _elementalist_earth = PBField.new("elementalist_earth", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 30, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _elementalist_earth + data[_elementalist_earth.tag] = service + + _elementalist_fire = PBField.new("elementalist_fire", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 31, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _elementalist_fire + data[_elementalist_fire.tag] = service + + _elementalist_water = PBField.new("elementalist_water", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 32, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _elementalist_water + data[_elementalist_water.tag] = service + + _engineer_alchemy = PBField.new("engineer_alchemy", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 33, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _engineer_alchemy + data[_engineer_alchemy.tag] = service + + _engineer_explosives = PBField.new("engineer_explosives", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 34, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _engineer_explosives + data[_engineer_explosives.tag] = service + + _engineer_firearms = PBField.new("engineer_firearms", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 35, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _engineer_firearms + data[_engineer_firearms.tag] = service + + _engineer_inventions = PBField.new("engineer_inventions", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 36, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _engineer_inventions + data[_engineer_inventions.tag] = service + + _engineer_tools = PBField.new("engineer_tools", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 37, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _engineer_tools + data[_engineer_tools.tag] = service + + _guardian_honor = PBField.new("guardian_honor", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 38, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _guardian_honor + data[_guardian_honor.tag] = service + + _guardian_radiance = PBField.new("guardian_radiance", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 39, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _guardian_radiance + data[_guardian_radiance.tag] = service + + _guardian_valor = PBField.new("guardian_valor", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 40, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _guardian_valor + data[_guardian_valor.tag] = service + + _guardian_virtues = PBField.new("guardian_virtues", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 41, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _guardian_virtues + data[_guardian_virtues.tag] = service + + _guardian_zeal = PBField.new("guardian_zeal", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 42, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _guardian_zeal + data[_guardian_zeal.tag] = service + + _mesmer_chaos = PBField.new("mesmer_chaos", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 43, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _mesmer_chaos + data[_mesmer_chaos.tag] = service + + _mesmer_domination = PBField.new("mesmer_domination", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 44, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _mesmer_domination + data[_mesmer_domination.tag] = service + + _mesmer_dueling = PBField.new("mesmer_dueling", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 45, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _mesmer_dueling + data[_mesmer_dueling.tag] = service + + _mesmer_illusions = PBField.new("mesmer_illusions", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 46, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _mesmer_illusions + data[_mesmer_illusions.tag] = service + + _mesmer_inspiration = PBField.new("mesmer_inspiration", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 47, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _mesmer_inspiration + data[_mesmer_inspiration.tag] = service + + _necromancer_blood_magic = PBField.new("necromancer_blood_magic", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 48, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _necromancer_blood_magic + data[_necromancer_blood_magic.tag] = service + + _necromancer_curses = PBField.new("necromancer_curses", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 49, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _necromancer_curses + data[_necromancer_curses.tag] = service + + _necromancer_death_magic = PBField.new("necromancer_death_magic", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 50, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _necromancer_death_magic + data[_necromancer_death_magic.tag] = service + + _necromancer_soul_reaping = PBField.new("necromancer_soul_reaping", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 51, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _necromancer_soul_reaping + data[_necromancer_soul_reaping.tag] = service + + _necromancer_spite = PBField.new("necromancer_spite", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 52, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _necromancer_spite + data[_necromancer_spite.tag] = service + + _ranger_beastmastery = PBField.new("ranger_beastmastery", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 53, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _ranger_beastmastery + data[_ranger_beastmastery.tag] = service + + _ranger_marksmanship = PBField.new("ranger_marksmanship", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 54, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _ranger_marksmanship + data[_ranger_marksmanship.tag] = service + + _ranger_nature_magic = PBField.new("ranger_nature_magic", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 55, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _ranger_nature_magic + data[_ranger_nature_magic.tag] = service + + _ranger_skirmishing = PBField.new("ranger_skirmishing", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 56, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _ranger_skirmishing + data[_ranger_skirmishing.tag] = service + + _ranger_wilderness_survival = PBField.new("ranger_wilderness_survival", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 57, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _ranger_wilderness_survival + data[_ranger_wilderness_survival.tag] = service + + _revenant_corruption = PBField.new("revenant_corruption", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 58, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _revenant_corruption + data[_revenant_corruption.tag] = service + + _revenant_devastation = PBField.new("revenant_devastation", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 59, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _revenant_devastation + data[_revenant_devastation.tag] = service + + _revenant_invocation = PBField.new("revenant_invocation", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 60, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _revenant_invocation + data[_revenant_invocation.tag] = service + + _revenant_retribution = PBField.new("revenant_retribution", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 61, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _revenant_retribution + data[_revenant_retribution.tag] = service + + _revenant_salvation = PBField.new("revenant_salvation", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 62, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _revenant_salvation + data[_revenant_salvation.tag] = service + + _thief_acrobatics = PBField.new("thief_acrobatics", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 63, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _thief_acrobatics + data[_thief_acrobatics.tag] = service + + _thief_critical_strikes = PBField.new("thief_critical_strikes", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 64, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _thief_critical_strikes + data[_thief_critical_strikes.tag] = service + + _thief_deadly_arts = PBField.new("thief_deadly_arts", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 65, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _thief_deadly_arts + data[_thief_deadly_arts.tag] = service + + _thief_shadow_arts = PBField.new("thief_shadow_arts", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 66, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _thief_shadow_arts + data[_thief_shadow_arts.tag] = service + + _thief_trickery = PBField.new("thief_trickery", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 67, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _thief_trickery + data[_thief_trickery.tag] = service + + _warrior_arms = PBField.new("warrior_arms", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 68, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warrior_arms + data[_warrior_arms.tag] = service + + _warrior_defense = PBField.new("warrior_defense", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 69, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warrior_defense + data[_warrior_defense.tag] = service + + _warrior_discipline = PBField.new("warrior_discipline", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 70, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warrior_discipline + data[_warrior_discipline.tag] = service + + _warrior_strength = PBField.new("warrior_strength", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 71, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warrior_strength + data[_warrior_strength.tag] = service + + _warrior_tactics = PBField.new("warrior_tactics", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 72, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _warrior_tactics + data[_warrior_tactics.tag] = service + + var data = {} + + var _elementalist_tempest: PBField + func get_elementalist_tempest() -> bool: + return _elementalist_tempest.value + func clear_elementalist_tempest() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _elementalist_tempest.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_elementalist_tempest(value : bool) -> void: + _elementalist_tempest.value = value + + var _engineer_scrapper: PBField + func get_engineer_scrapper() -> bool: + return _engineer_scrapper.value + func clear_engineer_scrapper() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _engineer_scrapper.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_engineer_scrapper(value : bool) -> void: + _engineer_scrapper.value = value + + var _guardian_dragonhunter: PBField + func get_guardian_dragonhunter() -> bool: + return _guardian_dragonhunter.value + func clear_guardian_dragonhunter() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _guardian_dragonhunter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_guardian_dragonhunter(value : bool) -> void: + _guardian_dragonhunter.value = value + + var _mesmer_chronomancer: PBField + func get_mesmer_chronomancer() -> bool: + return _mesmer_chronomancer.value + func clear_mesmer_chronomancer() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _mesmer_chronomancer.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_mesmer_chronomancer(value : bool) -> void: + _mesmer_chronomancer.value = value + + var _necromancer_reaper: PBField + func get_necromancer_reaper() -> bool: + return _necromancer_reaper.value + func clear_necromancer_reaper() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _necromancer_reaper.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_necromancer_reaper(value : bool) -> void: + _necromancer_reaper.value = value + + var _ranger_druid: PBField + func get_ranger_druid() -> bool: + return _ranger_druid.value + func clear_ranger_druid() -> void: + data[6].state = PB_SERVICE_STATE.UNFILLED + _ranger_druid.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_ranger_druid(value : bool) -> void: + _ranger_druid.value = value + + var _revenant_herald: PBField + func get_revenant_herald() -> bool: + return _revenant_herald.value + func clear_revenant_herald() -> void: + data[7].state = PB_SERVICE_STATE.UNFILLED + _revenant_herald.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_revenant_herald(value : bool) -> void: + _revenant_herald.value = value + + var _thief_daredevil: PBField + func get_thief_daredevil() -> bool: + return _thief_daredevil.value + func clear_thief_daredevil() -> void: + data[8].state = PB_SERVICE_STATE.UNFILLED + _thief_daredevil.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_thief_daredevil(value : bool) -> void: + _thief_daredevil.value = value + + var _warrior_berserker: PBField + func get_warrior_berserker() -> bool: + return _warrior_berserker.value + func clear_warrior_berserker() -> void: + data[9].state = PB_SERVICE_STATE.UNFILLED + _warrior_berserker.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warrior_berserker(value : bool) -> void: + _warrior_berserker.value = value + + var _elementalist_weaver: PBField + func get_elementalist_weaver() -> bool: + return _elementalist_weaver.value + func clear_elementalist_weaver() -> void: + data[10].state = PB_SERVICE_STATE.UNFILLED + _elementalist_weaver.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_elementalist_weaver(value : bool) -> void: + _elementalist_weaver.value = value + + var _engineer_holosmith: PBField + func get_engineer_holosmith() -> bool: + return _engineer_holosmith.value + func clear_engineer_holosmith() -> void: + data[11].state = PB_SERVICE_STATE.UNFILLED + _engineer_holosmith.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_engineer_holosmith(value : bool) -> void: + _engineer_holosmith.value = value + + var _guardian_firebrand: PBField + func get_guardian_firebrand() -> bool: + return _guardian_firebrand.value + func clear_guardian_firebrand() -> void: + data[12].state = PB_SERVICE_STATE.UNFILLED + _guardian_firebrand.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_guardian_firebrand(value : bool) -> void: + _guardian_firebrand.value = value + + var _mesmer_mirage: PBField + func get_mesmer_mirage() -> bool: + return _mesmer_mirage.value + func clear_mesmer_mirage() -> void: + data[13].state = PB_SERVICE_STATE.UNFILLED + _mesmer_mirage.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_mesmer_mirage(value : bool) -> void: + _mesmer_mirage.value = value + + var _necromancer_scourge: PBField + func get_necromancer_scourge() -> bool: + return _necromancer_scourge.value + func clear_necromancer_scourge() -> void: + data[14].state = PB_SERVICE_STATE.UNFILLED + _necromancer_scourge.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_necromancer_scourge(value : bool) -> void: + _necromancer_scourge.value = value + + var _ranger_soulbeast: PBField + func get_ranger_soulbeast() -> bool: + return _ranger_soulbeast.value + func clear_ranger_soulbeast() -> void: + data[15].state = PB_SERVICE_STATE.UNFILLED + _ranger_soulbeast.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_ranger_soulbeast(value : bool) -> void: + _ranger_soulbeast.value = value + + var _revenant_renegade: PBField + func get_revenant_renegade() -> bool: + return _revenant_renegade.value + func clear_revenant_renegade() -> void: + data[16].state = PB_SERVICE_STATE.UNFILLED + _revenant_renegade.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_revenant_renegade(value : bool) -> void: + _revenant_renegade.value = value + + var _thief_deadeye: PBField + func get_thief_deadeye() -> bool: + return _thief_deadeye.value + func clear_thief_deadeye() -> void: + data[17].state = PB_SERVICE_STATE.UNFILLED + _thief_deadeye.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_thief_deadeye(value : bool) -> void: + _thief_deadeye.value = value + + var _warrior_spellbreaker: PBField + func get_warrior_spellbreaker() -> bool: + return _warrior_spellbreaker.value + func clear_warrior_spellbreaker() -> void: + data[18].state = PB_SERVICE_STATE.UNFILLED + _warrior_spellbreaker.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warrior_spellbreaker(value : bool) -> void: + _warrior_spellbreaker.value = value + + var _elementalist_catalyst: PBField + func get_elementalist_catalyst() -> bool: + return _elementalist_catalyst.value + func clear_elementalist_catalyst() -> void: + data[19].state = PB_SERVICE_STATE.UNFILLED + _elementalist_catalyst.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_elementalist_catalyst(value : bool) -> void: + _elementalist_catalyst.value = value + + var _engineer_mechanist: PBField + func get_engineer_mechanist() -> bool: + return _engineer_mechanist.value + func clear_engineer_mechanist() -> void: + data[20].state = PB_SERVICE_STATE.UNFILLED + _engineer_mechanist.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_engineer_mechanist(value : bool) -> void: + _engineer_mechanist.value = value + + var _guardian_willbender: PBField + func get_guardian_willbender() -> bool: + return _guardian_willbender.value + func clear_guardian_willbender() -> void: + data[21].state = PB_SERVICE_STATE.UNFILLED + _guardian_willbender.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_guardian_willbender(value : bool) -> void: + _guardian_willbender.value = value + + var _mesmer_virtuoso: PBField + func get_mesmer_virtuoso() -> bool: + return _mesmer_virtuoso.value + func clear_mesmer_virtuoso() -> void: + data[22].state = PB_SERVICE_STATE.UNFILLED + _mesmer_virtuoso.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_mesmer_virtuoso(value : bool) -> void: + _mesmer_virtuoso.value = value + + var _necromancer_harbinger: PBField + func get_necromancer_harbinger() -> bool: + return _necromancer_harbinger.value + func clear_necromancer_harbinger() -> void: + data[23].state = PB_SERVICE_STATE.UNFILLED + _necromancer_harbinger.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_necromancer_harbinger(value : bool) -> void: + _necromancer_harbinger.value = value + + var _ranger_untamed: PBField + func get_ranger_untamed() -> bool: + return _ranger_untamed.value + func clear_ranger_untamed() -> void: + data[24].state = PB_SERVICE_STATE.UNFILLED + _ranger_untamed.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_ranger_untamed(value : bool) -> void: + _ranger_untamed.value = value + + var _revenant_vindicator: PBField + func get_revenant_vindicator() -> bool: + return _revenant_vindicator.value + func clear_revenant_vindicator() -> void: + data[25].state = PB_SERVICE_STATE.UNFILLED + _revenant_vindicator.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_revenant_vindicator(value : bool) -> void: + _revenant_vindicator.value = value + + var _thief_specter: PBField + func get_thief_specter() -> bool: + return _thief_specter.value + func clear_thief_specter() -> void: + data[26].state = PB_SERVICE_STATE.UNFILLED + _thief_specter.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_thief_specter(value : bool) -> void: + _thief_specter.value = value + + var _warrior_bladesworn: PBField + func get_warrior_bladesworn() -> bool: + return _warrior_bladesworn.value + func clear_warrior_bladesworn() -> void: + data[27].state = PB_SERVICE_STATE.UNFILLED + _warrior_bladesworn.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warrior_bladesworn(value : bool) -> void: + _warrior_bladesworn.value = value + + var _elementalist_air: PBField + func get_elementalist_air() -> bool: + return _elementalist_air.value + func clear_elementalist_air() -> void: + data[28].state = PB_SERVICE_STATE.UNFILLED + _elementalist_air.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_elementalist_air(value : bool) -> void: + _elementalist_air.value = value + + var _elementalist_arcane: PBField + func get_elementalist_arcane() -> bool: + return _elementalist_arcane.value + func clear_elementalist_arcane() -> void: + data[29].state = PB_SERVICE_STATE.UNFILLED + _elementalist_arcane.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_elementalist_arcane(value : bool) -> void: + _elementalist_arcane.value = value + + var _elementalist_earth: PBField + func get_elementalist_earth() -> bool: + return _elementalist_earth.value + func clear_elementalist_earth() -> void: + data[30].state = PB_SERVICE_STATE.UNFILLED + _elementalist_earth.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_elementalist_earth(value : bool) -> void: + _elementalist_earth.value = value + + var _elementalist_fire: PBField + func get_elementalist_fire() -> bool: + return _elementalist_fire.value + func clear_elementalist_fire() -> void: + data[31].state = PB_SERVICE_STATE.UNFILLED + _elementalist_fire.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_elementalist_fire(value : bool) -> void: + _elementalist_fire.value = value + + var _elementalist_water: PBField + func get_elementalist_water() -> bool: + return _elementalist_water.value + func clear_elementalist_water() -> void: + data[32].state = PB_SERVICE_STATE.UNFILLED + _elementalist_water.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_elementalist_water(value : bool) -> void: + _elementalist_water.value = value + + var _engineer_alchemy: PBField + func get_engineer_alchemy() -> bool: + return _engineer_alchemy.value + func clear_engineer_alchemy() -> void: + data[33].state = PB_SERVICE_STATE.UNFILLED + _engineer_alchemy.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_engineer_alchemy(value : bool) -> void: + _engineer_alchemy.value = value + + var _engineer_explosives: PBField + func get_engineer_explosives() -> bool: + return _engineer_explosives.value + func clear_engineer_explosives() -> void: + data[34].state = PB_SERVICE_STATE.UNFILLED + _engineer_explosives.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_engineer_explosives(value : bool) -> void: + _engineer_explosives.value = value + + var _engineer_firearms: PBField + func get_engineer_firearms() -> bool: + return _engineer_firearms.value + func clear_engineer_firearms() -> void: + data[35].state = PB_SERVICE_STATE.UNFILLED + _engineer_firearms.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_engineer_firearms(value : bool) -> void: + _engineer_firearms.value = value + + var _engineer_inventions: PBField + func get_engineer_inventions() -> bool: + return _engineer_inventions.value + func clear_engineer_inventions() -> void: + data[36].state = PB_SERVICE_STATE.UNFILLED + _engineer_inventions.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_engineer_inventions(value : bool) -> void: + _engineer_inventions.value = value + + var _engineer_tools: PBField + func get_engineer_tools() -> bool: + return _engineer_tools.value + func clear_engineer_tools() -> void: + data[37].state = PB_SERVICE_STATE.UNFILLED + _engineer_tools.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_engineer_tools(value : bool) -> void: + _engineer_tools.value = value + + var _guardian_honor: PBField + func get_guardian_honor() -> bool: + return _guardian_honor.value + func clear_guardian_honor() -> void: + data[38].state = PB_SERVICE_STATE.UNFILLED + _guardian_honor.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_guardian_honor(value : bool) -> void: + _guardian_honor.value = value + + var _guardian_radiance: PBField + func get_guardian_radiance() -> bool: + return _guardian_radiance.value + func clear_guardian_radiance() -> void: + data[39].state = PB_SERVICE_STATE.UNFILLED + _guardian_radiance.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_guardian_radiance(value : bool) -> void: + _guardian_radiance.value = value + + var _guardian_valor: PBField + func get_guardian_valor() -> bool: + return _guardian_valor.value + func clear_guardian_valor() -> void: + data[40].state = PB_SERVICE_STATE.UNFILLED + _guardian_valor.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_guardian_valor(value : bool) -> void: + _guardian_valor.value = value + + var _guardian_virtues: PBField + func get_guardian_virtues() -> bool: + return _guardian_virtues.value + func clear_guardian_virtues() -> void: + data[41].state = PB_SERVICE_STATE.UNFILLED + _guardian_virtues.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_guardian_virtues(value : bool) -> void: + _guardian_virtues.value = value + + var _guardian_zeal: PBField + func get_guardian_zeal() -> bool: + return _guardian_zeal.value + func clear_guardian_zeal() -> void: + data[42].state = PB_SERVICE_STATE.UNFILLED + _guardian_zeal.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_guardian_zeal(value : bool) -> void: + _guardian_zeal.value = value + + var _mesmer_chaos: PBField + func get_mesmer_chaos() -> bool: + return _mesmer_chaos.value + func clear_mesmer_chaos() -> void: + data[43].state = PB_SERVICE_STATE.UNFILLED + _mesmer_chaos.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_mesmer_chaos(value : bool) -> void: + _mesmer_chaos.value = value + + var _mesmer_domination: PBField + func get_mesmer_domination() -> bool: + return _mesmer_domination.value + func clear_mesmer_domination() -> void: + data[44].state = PB_SERVICE_STATE.UNFILLED + _mesmer_domination.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_mesmer_domination(value : bool) -> void: + _mesmer_domination.value = value + + var _mesmer_dueling: PBField + func get_mesmer_dueling() -> bool: + return _mesmer_dueling.value + func clear_mesmer_dueling() -> void: + data[45].state = PB_SERVICE_STATE.UNFILLED + _mesmer_dueling.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_mesmer_dueling(value : bool) -> void: + _mesmer_dueling.value = value + + var _mesmer_illusions: PBField + func get_mesmer_illusions() -> bool: + return _mesmer_illusions.value + func clear_mesmer_illusions() -> void: + data[46].state = PB_SERVICE_STATE.UNFILLED + _mesmer_illusions.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_mesmer_illusions(value : bool) -> void: + _mesmer_illusions.value = value + + var _mesmer_inspiration: PBField + func get_mesmer_inspiration() -> bool: + return _mesmer_inspiration.value + func clear_mesmer_inspiration() -> void: + data[47].state = PB_SERVICE_STATE.UNFILLED + _mesmer_inspiration.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_mesmer_inspiration(value : bool) -> void: + _mesmer_inspiration.value = value + + var _necromancer_blood_magic: PBField + func get_necromancer_blood_magic() -> bool: + return _necromancer_blood_magic.value + func clear_necromancer_blood_magic() -> void: + data[48].state = PB_SERVICE_STATE.UNFILLED + _necromancer_blood_magic.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_necromancer_blood_magic(value : bool) -> void: + _necromancer_blood_magic.value = value + + var _necromancer_curses: PBField + func get_necromancer_curses() -> bool: + return _necromancer_curses.value + func clear_necromancer_curses() -> void: + data[49].state = PB_SERVICE_STATE.UNFILLED + _necromancer_curses.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_necromancer_curses(value : bool) -> void: + _necromancer_curses.value = value + + var _necromancer_death_magic: PBField + func get_necromancer_death_magic() -> bool: + return _necromancer_death_magic.value + func clear_necromancer_death_magic() -> void: + data[50].state = PB_SERVICE_STATE.UNFILLED + _necromancer_death_magic.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_necromancer_death_magic(value : bool) -> void: + _necromancer_death_magic.value = value + + var _necromancer_soul_reaping: PBField + func get_necromancer_soul_reaping() -> bool: + return _necromancer_soul_reaping.value + func clear_necromancer_soul_reaping() -> void: + data[51].state = PB_SERVICE_STATE.UNFILLED + _necromancer_soul_reaping.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_necromancer_soul_reaping(value : bool) -> void: + _necromancer_soul_reaping.value = value + + var _necromancer_spite: PBField + func get_necromancer_spite() -> bool: + return _necromancer_spite.value + func clear_necromancer_spite() -> void: + data[52].state = PB_SERVICE_STATE.UNFILLED + _necromancer_spite.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_necromancer_spite(value : bool) -> void: + _necromancer_spite.value = value + + var _ranger_beastmastery: PBField + func get_ranger_beastmastery() -> bool: + return _ranger_beastmastery.value + func clear_ranger_beastmastery() -> void: + data[53].state = PB_SERVICE_STATE.UNFILLED + _ranger_beastmastery.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_ranger_beastmastery(value : bool) -> void: + _ranger_beastmastery.value = value + + var _ranger_marksmanship: PBField + func get_ranger_marksmanship() -> bool: + return _ranger_marksmanship.value + func clear_ranger_marksmanship() -> void: + data[54].state = PB_SERVICE_STATE.UNFILLED + _ranger_marksmanship.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_ranger_marksmanship(value : bool) -> void: + _ranger_marksmanship.value = value + + var _ranger_nature_magic: PBField + func get_ranger_nature_magic() -> bool: + return _ranger_nature_magic.value + func clear_ranger_nature_magic() -> void: + data[55].state = PB_SERVICE_STATE.UNFILLED + _ranger_nature_magic.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_ranger_nature_magic(value : bool) -> void: + _ranger_nature_magic.value = value + + var _ranger_skirmishing: PBField + func get_ranger_skirmishing() -> bool: + return _ranger_skirmishing.value + func clear_ranger_skirmishing() -> void: + data[56].state = PB_SERVICE_STATE.UNFILLED + _ranger_skirmishing.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_ranger_skirmishing(value : bool) -> void: + _ranger_skirmishing.value = value + + var _ranger_wilderness_survival: PBField + func get_ranger_wilderness_survival() -> bool: + return _ranger_wilderness_survival.value + func clear_ranger_wilderness_survival() -> void: + data[57].state = PB_SERVICE_STATE.UNFILLED + _ranger_wilderness_survival.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_ranger_wilderness_survival(value : bool) -> void: + _ranger_wilderness_survival.value = value + + var _revenant_corruption: PBField + func get_revenant_corruption() -> bool: + return _revenant_corruption.value + func clear_revenant_corruption() -> void: + data[58].state = PB_SERVICE_STATE.UNFILLED + _revenant_corruption.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_revenant_corruption(value : bool) -> void: + _revenant_corruption.value = value + + var _revenant_devastation: PBField + func get_revenant_devastation() -> bool: + return _revenant_devastation.value + func clear_revenant_devastation() -> void: + data[59].state = PB_SERVICE_STATE.UNFILLED + _revenant_devastation.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_revenant_devastation(value : bool) -> void: + _revenant_devastation.value = value + + var _revenant_invocation: PBField + func get_revenant_invocation() -> bool: + return _revenant_invocation.value + func clear_revenant_invocation() -> void: + data[60].state = PB_SERVICE_STATE.UNFILLED + _revenant_invocation.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_revenant_invocation(value : bool) -> void: + _revenant_invocation.value = value + + var _revenant_retribution: PBField + func get_revenant_retribution() -> bool: + return _revenant_retribution.value + func clear_revenant_retribution() -> void: + data[61].state = PB_SERVICE_STATE.UNFILLED + _revenant_retribution.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_revenant_retribution(value : bool) -> void: + _revenant_retribution.value = value + + var _revenant_salvation: PBField + func get_revenant_salvation() -> bool: + return _revenant_salvation.value + func clear_revenant_salvation() -> void: + data[62].state = PB_SERVICE_STATE.UNFILLED + _revenant_salvation.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_revenant_salvation(value : bool) -> void: + _revenant_salvation.value = value + + var _thief_acrobatics: PBField + func get_thief_acrobatics() -> bool: + return _thief_acrobatics.value + func clear_thief_acrobatics() -> void: + data[63].state = PB_SERVICE_STATE.UNFILLED + _thief_acrobatics.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_thief_acrobatics(value : bool) -> void: + _thief_acrobatics.value = value + + var _thief_critical_strikes: PBField + func get_thief_critical_strikes() -> bool: + return _thief_critical_strikes.value + func clear_thief_critical_strikes() -> void: + data[64].state = PB_SERVICE_STATE.UNFILLED + _thief_critical_strikes.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_thief_critical_strikes(value : bool) -> void: + _thief_critical_strikes.value = value + + var _thief_deadly_arts: PBField + func get_thief_deadly_arts() -> bool: + return _thief_deadly_arts.value + func clear_thief_deadly_arts() -> void: + data[65].state = PB_SERVICE_STATE.UNFILLED + _thief_deadly_arts.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_thief_deadly_arts(value : bool) -> void: + _thief_deadly_arts.value = value + + var _thief_shadow_arts: PBField + func get_thief_shadow_arts() -> bool: + return _thief_shadow_arts.value + func clear_thief_shadow_arts() -> void: + data[66].state = PB_SERVICE_STATE.UNFILLED + _thief_shadow_arts.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_thief_shadow_arts(value : bool) -> void: + _thief_shadow_arts.value = value + + var _thief_trickery: PBField + func get_thief_trickery() -> bool: + return _thief_trickery.value + func clear_thief_trickery() -> void: + data[67].state = PB_SERVICE_STATE.UNFILLED + _thief_trickery.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_thief_trickery(value : bool) -> void: + _thief_trickery.value = value + + var _warrior_arms: PBField + func get_warrior_arms() -> bool: + return _warrior_arms.value + func clear_warrior_arms() -> void: + data[68].state = PB_SERVICE_STATE.UNFILLED + _warrior_arms.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warrior_arms(value : bool) -> void: + _warrior_arms.value = value + + var _warrior_defense: PBField + func get_warrior_defense() -> bool: + return _warrior_defense.value + func clear_warrior_defense() -> void: + data[69].state = PB_SERVICE_STATE.UNFILLED + _warrior_defense.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warrior_defense(value : bool) -> void: + _warrior_defense.value = value + + var _warrior_discipline: PBField + func get_warrior_discipline() -> bool: + return _warrior_discipline.value + func clear_warrior_discipline() -> void: + data[70].state = PB_SERVICE_STATE.UNFILLED + _warrior_discipline.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warrior_discipline(value : bool) -> void: + _warrior_discipline.value = value + + var _warrior_strength: PBField + func get_warrior_strength() -> bool: + return _warrior_strength.value + func clear_warrior_strength() -> void: + data[71].state = PB_SERVICE_STATE.UNFILLED + _warrior_strength.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warrior_strength(value : bool) -> void: + _warrior_strength.value = value + + var _warrior_tactics: PBField + func get_warrior_tactics() -> bool: + return _warrior_tactics.value + func clear_warrior_tactics() -> void: + data[72].state = PB_SERVICE_STATE.UNFILLED + _warrior_tactics.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_warrior_tactics(value : bool) -> void: + _warrior_tactics.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class SpeciesFilter: + func _init(): + var service + + _asura = PBField.new("asura", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 1, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _asura + data[_asura.tag] = service + + _charr = PBField.new("charr", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 2, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _charr + data[_charr.tag] = service + + _human = PBField.new("human", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 3, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _human + data[_human.tag] = service + + _norn = PBField.new("norn", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 4, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _norn + data[_norn.tag] = service + + _sylvari = PBField.new("sylvari", PB_DATA_TYPE.BOOL, PB_RULE.OPTIONAL, 5, true, DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL]) + service = PBServiceField.new() + service.field = _sylvari + data[_sylvari.tag] = service + + var data = {} + + var _asura: PBField + func get_asura() -> bool: + return _asura.value + func clear_asura() -> void: + data[1].state = PB_SERVICE_STATE.UNFILLED + _asura.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_asura(value : bool) -> void: + _asura.value = value + + var _charr: PBField + func get_charr() -> bool: + return _charr.value + func clear_charr() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _charr.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_charr(value : bool) -> void: + _charr.value = value + + var _human: PBField + func get_human() -> bool: + return _human.value + func clear_human() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _human.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_human(value : bool) -> void: + _human.value = value + + var _norn: PBField + func get_norn() -> bool: + return _norn.value + func clear_norn() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _norn.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_norn(value : bool) -> void: + _norn.value = value + + var _sylvari: PBField + func get_sylvari() -> bool: + return _sylvari.value + func clear_sylvari() -> void: + data[5].state = PB_SERVICE_STATE.UNFILLED + _sylvari.value = DEFAULT_VALUES_3[PB_DATA_TYPE.BOOL] + func set_sylvari(value : bool) -> void: + _sylvari.value = value + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +class TrailData: + func _init(): + var service + + _points_x = PBField.new("points_x", PB_DATA_TYPE.FLOAT, PB_RULE.REPEATED, 2, true, []) + service = PBServiceField.new() + service.field = _points_x + data[_points_x.tag] = service + + _points_y = PBField.new("points_y", PB_DATA_TYPE.FLOAT, PB_RULE.REPEATED, 3, true, []) + service = PBServiceField.new() + service.field = _points_y + data[_points_y.tag] = service + + _points_z = PBField.new("points_z", PB_DATA_TYPE.FLOAT, PB_RULE.REPEATED, 4, true, []) + service = PBServiceField.new() + service.field = _points_z + data[_points_z.tag] = service + + var data = {} + + var _points_x: PBField + func get_points_x() -> Array: + return _points_x.value + func clear_points_x() -> void: + data[2].state = PB_SERVICE_STATE.UNFILLED + _points_x.value = [] + func add_points_x(value : float) -> void: + _points_x.value.append(value) + + var _points_y: PBField + func get_points_y() -> Array: + return _points_y.value + func clear_points_y() -> void: + data[3].state = PB_SERVICE_STATE.UNFILLED + _points_y.value = [] + func add_points_y(value : float) -> void: + _points_y.value.append(value) + + var _points_z: PBField + func get_points_z() -> Array: + return _points_z.value + func clear_points_z() -> void: + data[4].state = PB_SERVICE_STATE.UNFILLED + _points_z.value = [] + func add_points_z(value : float) -> void: + _points_z.value.append(value) + + func to_string() -> String: + return PBPacker.message_to_string(data) + + func to_bytes() -> PoolByteArray: + return PBPacker.pack_message(data) + + func from_bytes(bytes : PoolByteArray, offset : int = 0, limit : int = -1) -> int: + var cur_limit = bytes.size() + if limit != -1: + cur_limit = limit + var result = PBPacker.unpack_message(data, bytes, offset, cur_limit) + if result == cur_limit: + if PBPacker.check_required(data): + if limit == -1: + return PB_ERR.NO_ERRORS + else: + return PB_ERR.REQUIRED_FIELDS + elif limit == -1 && result > 0: + return PB_ERR.PARSE_INCOMPLETE + return result + +################ USER DATA END ################# diff --git a/project.godot b/project.godot index be568f6c..fb41ab1c 100644 --- a/project.godot +++ b/project.godot @@ -14,7 +14,7 @@ _global_script_classes=[ { "language": "NativeScript", "path": "res://tacoparser.gdns" }, { -"base": "Node", +"base": "", "class": "X11_FG", "language": "NativeScript", "path": "res://Spatial.gdns" @@ -47,10 +47,15 @@ window/vsync/use_vsync=false window/per_pixel_transparency/allowed=true window/per_pixel_transparency/enabled=true +[editor_plugins] + +enabled=PoolStringArray( "res://addons/protobuf/plugin.cfg", "res://addons/version_restrict/plugin.cfg" ) + [global] logg=true logging=true +target_engine_version="3.3.2" [rendering] diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 00000000..52a314f5 --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1 @@ +demo.trl diff --git a/scripts/simple_trail_parser.py b/scripts/simple_trail_parser.py new file mode 100644 index 00000000..a26d72f0 --- /dev/null +++ b/scripts/simple_trail_parser.py @@ -0,0 +1,15 @@ +from typing import Tuple, List +import struct + +with open("./demo.trl", 'rb') as f: + version: int = struct.unpack(" 0: + print(output) + exit_code = max(exit_code, proc.returncode) + return exit_code + + pending = [] + while invocations or pending: + # Collect completed IWYU processes and print results. + complete = [proc for proc in pending if proc.poll() is not None] + for proc in complete: + pending.remove(proc) + output = formatter(proc.get_output()) + if len(output) > 0: + print(output) + exit_code = max(exit_code, proc.returncode) + + # Schedule new processes if there's room. + capacity = jobs - len(pending) + + if max_load_average > 0: + one_min_load_average, _, _ = os.getloadavg() + load_capacity = max_load_average - one_min_load_average + if load_capacity < 0: + load_capacity = 0 + if load_capacity < capacity: + capacity = int(load_capacity) + if not capacity and not pending: + # Ensure there is at least one job running. + capacity = 1 + + pending.extend(i.start(verbose) for i in invocations[:capacity]) + invocations = invocations[capacity:] + + # Yield CPU. + time.sleep(0.0001) + return exit_code + + +def main(compilation_db_path, source_files, verbose, formatter, jobs, + max_load_average, extra_args): + """ Entry point. """ + + if not IWYU_EXECUTABLE: + print('error: include-what-you-use executable not found', + file=sys.stderr) + return 1 + + try: + if os.path.isdir(compilation_db_path): + compilation_db_path = os.path.join(compilation_db_path, + 'compile_commands.json') + + # Read compilation db from disk. + compilation_db_path = os.path.realpath(compilation_db_path) + with open(compilation_db_path, 'r') as fileobj: + compilation_db = json.load(fileobj) + except IOError as why: + print('error: failed to parse compilation database: %s' % why, + file=sys.stderr) + return 1 + + compilation_db = fixup_compilation_db(compilation_db) + compilation_db = slice_compilation_db(compilation_db, source_files) + + # Transform compilation db entries into a list of IWYU invocations. + invocations = [] + + for e in compilation_db: + # A quick hack for burrito to ignroe protobuf files. + # TODO: Maybe this can be expanded on and contributed back to iwyu + if e["file"].endswith("pb.cc"): + continue + invocations.append(Invocation.from_compile_command(e, extra_args)) + + return execute(invocations, verbose, formatter, jobs, max_load_average) + + +def _bootstrap(sys_argv): + """ Parse arguments and dispatch to main(). """ + + # This hackery is necessary to add the forwarded IWYU args to the + # usage and help strings. + def customize_usage(parser): + """ Rewrite the parser's format_usage. """ + original_format_usage = parser.format_usage + parser.format_usage = lambda: original_format_usage().rstrip() + \ + ' -- []' + os.linesep + + def customize_help(parser): + """ Rewrite the parser's format_help. """ + original_format_help = parser.format_help + + def custom_help(): + """ Customized help string, calls the adjusted format_usage. """ + helpmsg = original_format_help() + helplines = helpmsg.splitlines() + helplines[0] = parser.format_usage().rstrip() + return os.linesep.join(helplines) + os.linesep + + parser.format_help = custom_help + + # Parse arguments. + parser = argparse.ArgumentParser( + description='Include-what-you-use compilation database driver.', + epilog='Assumes include-what-you-use is available on the PATH.') + customize_usage(parser) + customize_help(parser) + + parser.add_argument('-v', '--verbose', action='store_true', + help='Print IWYU commands') + parser.add_argument('-o', '--output-format', type=str, + choices=FORMATTERS.keys(), default=DEFAULT_FORMAT, + help='Output format (default: %s)' % DEFAULT_FORMAT) + parser.add_argument('-j', '--jobs', type=int, default=1, + help='Number of concurrent subprocesses') + parser.add_argument('-l', '--load', type=float, default=0, + help='Do not start new jobs if the 1min load average is greater than the provided value') + parser.add_argument('-p', metavar='', required=True, + help='Compilation database path', dest='dbpath') + parser.add_argument('source', nargs='*', + help=('Zero or more source files (or directories) to ' + 'run IWYU on. Defaults to all in compilation ' + 'database.')) + + def partition_args(argv): + """ Split around '--' into driver args and IWYU args. """ + try: + double_dash = argv.index('--') + return argv[:double_dash], argv[double_dash+1:] + except ValueError: + return argv, [] + argv, extra_args = partition_args(sys_argv[1:]) + args = parser.parse_args(argv) + + return main(args.dbpath, args.source, args.verbose, + FORMATTERS[args.output_format], args.jobs, args.load, extra_args) + + +if __name__ == '__main__': + sys.exit(_bootstrap(sys.argv)) diff --git a/xml_converter/.clang-format b/xml_converter/.clang-format new file mode 100644 index 00000000..71dc1ff2 --- /dev/null +++ b/xml_converter/.clang-format @@ -0,0 +1,166 @@ +--- +Language: Cpp # Validate C++ +# BasedOnStyle: Google +AccessModifierOffset: -3 # With a tab indent of 4 spaces this equals a 1 space access modifier indent +AlignAfterOpenBracket: AlwaysBreak # Should be `BlockIndent` when it begins to work +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: DontAlign +AlignOperands: true +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true # V +AllowAllParametersOfDeclarationOnNextLine: true # V +AllowShortBlocksOnASingleLine: Never # V +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false # Dont binpack anything +BinPackParameters: false # Dont binpack anything +BraceWrapping: + AfterCaseLabel: false # Keep the open brace on the same line as the label + AfterClass: false # Keep the open brace on the same line as the class + AfterControlStatement: false + AfterEnum: false # V + AfterFunction: false # V + AfterNamespace: false # V + AfterObjCDeclaration: false + AfterStruct: false # V + AfterUnion: false # V + AfterExternBlock: false # V + BeforeCatch: true # V + BeforeElse: true # V + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 0 # Line break auto-formatting is very difficult. Ignoring it for now +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + - Regex: '.*' + Priority: 3 + SortPriority: 0 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 4 # Use 4 spaces for an indent +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 99999 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1 # 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Auto +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +... diff --git a/xml_converter/.gdignore b/xml_converter/.gdignore new file mode 100644 index 00000000..e69de29b diff --git a/xml_converter/.gitignore b/xml_converter/.gitignore new file mode 100644 index 00000000..7978cf59 --- /dev/null +++ b/xml_converter/.gitignore @@ -0,0 +1,14 @@ +packs/ +Makefile +CMakeFiles +CMakeCache.txt +cmake_install.cmake +compile_commands.json +.clangd/ +xml_converter +venv/ +web_docs +__pycache__/ +build/ +export_packs/ +.cache/clangd diff --git a/xml_converter/CMakeLists.txt b/xml_converter/CMakeLists.txt new file mode 100644 index 00000000..fe1a3ebc --- /dev/null +++ b/xml_converter/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required (VERSION 3.16) +project (XMLConverter) + +# Set CPP standard library to cpp17 +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + + +### Shared Infrastructure ###################################################### +set(CORE_LIB core_lib) + +# Generate Protobuf +FIND_PACKAGE(Protobuf REQUIRED) +INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) +PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER proto/guildpoint.proto) + +# Add Dependencies +file(GLOB_RECURSE SOURCES "src/*.cpp") +list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/xml_converter.cpp") + +# Create a static library for common sources +add_library(${CORE_LIB} STATIC ${SOURCES} ${PROTO_SRC}) + +# Include protobuf libraies. +target_link_libraries(${CORE_LIB} PUBLIC ${Protobuf_LIBRARIES}) + +if(MSVC) + target_compile_options(${CORE_LIB} PUBLIC /W4 /WX) +else() + target_compile_options(${CORE_LIB} PUBLIC -Wall -Wextra -Wpedantic) +endif() + + +### CLI Executable ############################################################# +# Name Output File +set(TARGET_NAME xml_converter) + +# Set output as executable. +add_executable(${TARGET_NAME} src/xml_converter.cpp) +target_link_libraries(${TARGET_NAME} ${CORE_LIB}) + + +### TESTS ###################################################################### +set(TEST_TARGET_NAME test_xml_converter) + +# Enable testing using CMake's built-in functionality to be able to run `make test` +enable_testing() + +file(GLOB_RECURSE TEST_SOURCES "tests/*.cpp") + +find_package(GTest REQUIRED) + +add_executable(${TEST_TARGET_NAME} ${TEST_SOURCES}) +target_link_libraries(${TEST_TARGET_NAME} GTest::GTest GTest::Main) +target_link_libraries(${TEST_TARGET_NAME} ${CORE_LIB}) + +gtest_discover_tests(${TEST_TARGET_NAME}) diff --git a/xml_converter/README.md b/xml_converter/README.md new file mode 100644 index 00000000..d77fa51e --- /dev/null +++ b/xml_converter/README.md @@ -0,0 +1,11 @@ +The XML Converter Module is tasked with parsing XML marker files and loading them into Burrito. + +In the future it may also preform the revers action and be able to export XML files as well. + + +Setup Clangd +------------ + +```bash +cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON +``` diff --git a/xml_converter/doc/acheivement/achievement_bit_index.md b/xml_converter/doc/acheivement/achievement_bit_index.md new file mode 100644 index 00000000..909d189f --- /dev/null +++ b/xml_converter/doc/acheivement/achievement_bit_index.md @@ -0,0 +1,46 @@ +--- +name: Achievement Bit Index +type: Int32 +applies_to: [Icon, Trail] +xml_fields: ["AchievementBit", "AchievementBitIndex"] +protobuf_field: achievement_bit_index +examples: ["0", "1", "2", "14"] +--- +A portion of the achievement that will hide this marker if it is completed. + +This value corrisponds to an `index` of a "bit" of an achivment. For example we can look at the achivement "RGB" which has the id `2655`. + +[https://api.guildwars2.com/v2/achievements?ids=2655](https://api.guildwars2.com/v2/achievements?ids=2655) + +```json +[ + { + "id": 2655, + "name": "RGB", + "description": "", + "requirement": "Obtain each pylon attunement once, and defeat the Vale Guardian.", + "locked_text": "", + "type": "Default", + "flags": ["Permanent"], + "bits": [ + {"type": "Text", "text": "Red Attunement"}, + {"type": "Text", "text": "Green Attunement"}, + {"type": "Text", "text": "Blue Attunement"} + ], + "tiers": [{"count": 3, "points": 1}] + } +] +``` +`Red Attunement` is the first one, so because we start with 0 it has the index **"0"** +`Green Attunement` is the second, so it has the index **"1"** +`Blue Attunement` is the third, so it has the index **"2"** + +If we wanted to hide this marker when "Green Attunment" had been completed we would set the Achievement Bit Index to `1` + + + +External Resources +-------------------------------------------------------------------------------- +* [https://gw2pathing.com/docs/marker-dev/attributes/achievement/](https://gw2pathing.com/docs/marker-dev/attributes/achievement/) + + diff --git a/xml_converter/doc/acheivement/achievement_id.md b/xml_converter/doc/acheivement/achievement_id.md new file mode 100644 index 00000000..5935436c --- /dev/null +++ b/xml_converter/doc/acheivement/achievement_id.md @@ -0,0 +1,15 @@ +--- +name: Achievement ID +type: Int32 +applies_to: [Icon, Trail] +xml_fields: ["AchievementId"] +protobuf_field: achievement_id +examples: + - "2655" +--- +An achivement that, if completed, will hide this marker + +Notes +===== + +https://blishhud.com/docs/markers/attributes/achievement \ No newline at end of file diff --git a/xml_converter/doc/category/category.md b/xml_converter/doc/category/category.md new file mode 100644 index 00000000..0790e495 --- /dev/null +++ b/xml_converter/doc/category/category.md @@ -0,0 +1,17 @@ +--- +name: Category +type: Custom +class: MarkerCategory +applies_to: [Icon, Trail] +xml_fields: [Type, Category] +protobuf_field: null +examples: + - "mycategory" + - "mycategory.subcategory" + - "mycategory.subcategory.subsubcategory" +--- +The category this object belongs to. + +Notes +===== +https://blishhud.com/docs/markers/attributes/type diff --git a/xml_converter/doc/disable_player_cutout/disable_player_cutout.md b/xml_converter/doc/disable_player_cutout/disable_player_cutout.md new file mode 100644 index 00000000..35fb7490 --- /dev/null +++ b/xml_converter/doc/disable_player_cutout/disable_player_cutout.md @@ -0,0 +1,22 @@ +--- +name: Disable Player Cutout +type: Boolean +applies_to: [Icon, Trail] +xml_fields: [CanFade] +protobuf_field: disable_player_cutout +custom_functions: + read.xml: + function: inverted_xml_attribute_to_bool + side_effects: [] + write.xml: + function: bool_to_inverted_xml_attribute + side_effects: [] +--- +A flag to determine if an object can be made transparent when it is possibly occluding the player. + +This value is inverted between the guildpoint format value of "Disable Player Cutout" and the TacO xml format of "Can Fade" + + +Notes +===== +https://blishhud.com/docs/markers/attributes/canfade diff --git a/xml_converter/doc/fade/distance_fade_end.md b/xml_converter/doc/fade/distance_fade_end.md new file mode 100644 index 00000000..ca4508fb --- /dev/null +++ b/xml_converter/doc/fade/distance_fade_end.md @@ -0,0 +1,17 @@ +--- +name: Distance Fade End +type: Float32 +applies_to: [Icon, Trail] +xml_fields: [FadeFar, DistanceFadeEnd] +protobuf_field: distance_fade_end +examples: + - "850" + - "600" + - "1100" +--- +Any part of the object that is farther then this value will be at 0 alpha. +Defaults to 900 + +Notes +===== +https://blishhud.com/docs/markers/attributes/fade diff --git a/xml_converter/doc/fade/distance_fade_start.md b/xml_converter/doc/fade/distance_fade_start.md new file mode 100644 index 00000000..78a1bea5 --- /dev/null +++ b/xml_converter/doc/fade/distance_fade_start.md @@ -0,0 +1,17 @@ +--- +name: Distance Fade Start +type: Float32 +applies_to: [Icon, Trail] +xml_fields: [FadeNear, DistanceFadeStart] +protobuf_field: distance_fade_start +examples: + - "650" + - "400" + - "900" +--- +Any part of the object that is farther then this value will begin to alpha fade gradually until it reaches 0 alpha at Distance Fade End. +Defaults to 700 + +Notes +===== +https://blishhud.com/docs/markers/attributes/fade diff --git a/xml_converter/doc/festival_filter/festival_filter.md b/xml_converter/doc/festival_filter/festival_filter.md new file mode 100644 index 00000000..f6ef03b4 --- /dev/null +++ b/xml_converter/doc/festival_filter/festival_filter.md @@ -0,0 +1,20 @@ +--- +name: Festival Filter +type: MultiflagValue +applies_to: [Icon, Trail] +xml_fields: [Festival] +protobuf_field: festival_filter +flags: + dragonbash: [DragonBash] + festival_of_the_four_winds: [FestivalOfTheFourWinds] + halloween: [Halloween] + lunar_new_year: [LunarNewYear] + super_adventure_festival: [SuperAdventureFestival, SuperAdventureBox] + wintersday: [Wintersday] + none: [None] +--- +One of these festivals must be occuring for these markers to apear. + +Notes +===== +https://blishhud.com/docs/markers/attributes/festival diff --git a/xml_converter/doc/is_wall/is_wall.md b/xml_converter/doc/is_wall/is_wall.md new file mode 100644 index 00000000..d94d55d6 --- /dev/null +++ b/xml_converter/doc/is_wall/is_wall.md @@ -0,0 +1,12 @@ +--- +name: Is Wall +type: Boolean +applies_to: [Trail] +xml_fields: [IsWall] +protobuf_field: is_wall +--- +Rotate the trail 90 degrees so it is vertical instead of horizontal to represent a wall. + +Notes +===== +https://blishhud.com/docs/markers/attributes/iswall \ No newline at end of file diff --git a/xml_converter/doc/map_id/map_id.md b/xml_converter/doc/map_id/map_id.md new file mode 100644 index 00000000..58b4ccda --- /dev/null +++ b/xml_converter/doc/map_id/map_id.md @@ -0,0 +1,41 @@ +--- +name: Map ID +type: Int32 +applies_to: [Icon, Trail] +xml_fields: [MapID] +protobuf_field: map_id +examples: + - "24" + - "50" + - "1509" +--- +The Map which this marker should be displayed on. + +Finding the Map ID +================== +Method 1: GameInfo Plugin +--- +The GameInfo plugin displays some useful game information on your screen about the character. One of those is the map the character is currently on + +Method 2: [Guild Wars 2 Wiki][2] infobox +--- +the InfoBox on the right hand side of map wiki pages has a field titled API followed by a number. + +For example, the [Gendarran Fields][1] wiki page has the API value of `24`. Gendarran Fields' Map ID is `24`. + +![Gendarran Fields InfoBox](./gendarran_fields_infobox.png) + + +Quirks +====== +* Map ID is also stored within the `.trl` files and may overwrite any other Map IDs set earlier in the node. + + +References +========= +* [BlishHUD MapID Marker Docs](https://blishhud.com/docs/markers/attributes/mapid) +* [TacO Marker Pack Guide](https://www.gw2taco.com/2016/01/how-to-create-your-own-marker-pack.html) + + +[1]: https://wiki.guildwars2.com/wiki/Gendarran_Fields +[2]: https://wiki.guildwars2.com \ No newline at end of file diff --git a/xml_converter/doc/map_id/map_type_filter.md b/xml_converter/doc/map_id/map_type_filter.md new file mode 100644 index 00000000..8c10c726 --- /dev/null +++ b/xml_converter/doc/map_id/map_type_filter.md @@ -0,0 +1,61 @@ +--- +name: Map Type Filter +type: MultiflagValue +applies_to: [Icon, Trail] +xml_fields: [MapType] +protobuf_field: map_type_filter +flags: + # Unknown map type + unknown_map: ["Unknown"] + # Redirect map type, e.g. when logging in while in a PvP match. + redirect_map: [redirect] + # Character create map type. + character_create_map: [charactercreate] + # PvP map type. + pvp_map: [pvp] + # GvG map type. Unused. + gvg_map: [gvg] + # Instance map type, e.g. dungeons and story content. + instance_map: [instance] + # Public map type, e.g. open world. + public_map: [public] + # Tournament map type. Probably unused. + tournament_map: [tournament] + # Tutorial map type. + tutorial_map: [tutorial] + # User tournament map type. Probably unused. + user_tournament_map: [usertournament] + # Eternal Battlegrounds (WvW) map type. + center_map: [center] + # Eternal Battlegrounds (WvW) map type. + eternal_battlegrounds_map: [eternalbattlegrounds] + # Blue Borderlands (WvW) map type. + bluehome_map: [bluehome] + # Blue Borderlands (WvW) map type. + blue_borderlands_map: [blueborderlands] + # Green Borderlands (WvW) map type. + green_home_map: [greenhome] + # Green Borderlands (WvW) map type. + green_borderlands_map: [greenborderlands] + # Red Borderlands (WvW) map type. + red_home_map: [redhome] + # Red Borderlands (WvW) map type. + red_borderlands_map: [redborderlands] + # Fortune's Vale. Unused. + fortunes_vale_map: [fortunesvale] + # Obsidian Sanctum (WvW) map type. + jump_puzzle_map: [jumppuzzle] + # Obsidian Sanctum (WvW) map type. + obsidian_sanctum_map: [obsidiansanctum] + # Edge of the Mists (WvW) map type. + edge_of_the_mists_map: [edgeofthemists] + # Mini public map type, e.g. Dry Top, the Silverwastes and Mistlock Sanctuary. + public_mini_map: [publicmini] + # WvW lounge map type, e.g. Armistice Bastion. + wvw_lounge_map: [wvwlounge] +--- +The types of maps this object should be displayed on. + +Notes +===== +https://blishhud.com/docs/markers/attributes/maptype diff --git a/xml_converter/doc/menu/display_name.md b/xml_converter/doc/menu/display_name.md new file mode 100644 index 00000000..291f2ffb --- /dev/null +++ b/xml_converter/doc/menu/display_name.md @@ -0,0 +1,25 @@ +--- +name: Display Name +type: String +applies_to: [Category] +xml_fields: [DisplayName] +protobuf_field: name +examples: + - "My Category" + - "Tribulation Mode 203" +custom_functions: + read.proto: + function: proto_display_name_to_display_name_and_name + side_effects: [Name] + write.proto: + function: display_name_and_name_to_proto_display_name + side_effects: [Name] + +--- +A human readable name of this category. + +Notes +===== +https://blishhud.com/docs/markers/attributes/displayname + + diff --git a/xml_converter/doc/menu/is_hidden.md b/xml_converter/doc/menu/is_hidden.md new file mode 100644 index 00000000..a78b08d8 --- /dev/null +++ b/xml_converter/doc/menu/is_hidden.md @@ -0,0 +1,22 @@ +--- +name: Is Hidden +type: Boolean +applies_to: [Category] +xml_fields: [DefaultToggle] +protobuf_field: is_hidden +custom_functions: + read.xml: + function: inverted_xml_attribute_to_bool + side_effects: [] + write.xml: + function: bool_to_inverted_xml_attribute + side_effects: [] +--- + +Notes +===== +If the category should be shown or hidden on or off by default. + +https://blishhud.com/docs/markers/attributes/defaulttoggle + + diff --git a/xml_converter/doc/menu/is_separator.md b/xml_converter/doc/menu/is_separator.md new file mode 100644 index 00000000..58b4d424 --- /dev/null +++ b/xml_converter/doc/menu/is_separator.md @@ -0,0 +1,14 @@ +--- +name: Is Separator +type: Boolean +applies_to: [Category] +xml_fields: [IsSeparator] +protobuf_field: is_separator +--- + +Notes +===== +Determines if this element is a seperator not a category. + +https://blishhud.com/docs/markers/attributes/isseparator + diff --git a/xml_converter/doc/menu/menu_id.md b/xml_converter/doc/menu/menu_id.md new file mode 100644 index 00000000..b097093c --- /dev/null +++ b/xml_converter/doc/menu/menu_id.md @@ -0,0 +1,20 @@ +--- +name: Menu ID +type: Custom +class: UniqueId +xml_fields: [ID, MenuID] +applies_to: [Category] +protobuf_field: id +examples: + - "KOjMBsKTXpY=" + - "LJKn7WpADjo=" + - "uJrcuLd4as8=" + - "cCxU1IXfiKQ=" +--- + +Notes +===== + +A 128bit long Unique ID. + +If the ID is not present when converting from XML, the ID is created as a hash of the category's "name" and the names of the categories parents. diff --git a/xml_converter/doc/menu/name.md b/xml_converter/doc/menu/name.md new file mode 100644 index 00000000..84de7591 --- /dev/null +++ b/xml_converter/doc/menu/name.md @@ -0,0 +1,18 @@ +--- +name: Name +type: String +applies_to: [Category] +xml_fields: [Name] +protobuf_field: null +examples: + - "mycategory" + - "tribulationmode203" +--- + +Notes +===== +A machine readable name of this category. + +https://blishhud.com/docs/markers/attributes/displayname + + diff --git a/xml_converter/doc/mount_filter/mount_filter.md b/xml_converter/doc/mount_filter/mount_filter.md new file mode 100644 index 00000000..123cc0e6 --- /dev/null +++ b/xml_converter/doc/mount_filter/mount_filter.md @@ -0,0 +1,23 @@ +--- +name: Mount Filter +type: MultiflagValue +applies_to: [Icon, Trail] +xml_fields: ["Mount"] +protobuf_field: mount_filter +flags: + raptor: ["Raptor"] + springer: ["Springer"] + skimmer: ["Skimmer"] + jackal: ["Jackal"] + griffon: ["Griffon"] + roller_beetle: ["RollerBeetle"] + warclaw: ["Warclaw"] + skyscale: ["Skyscale"] + skiff: ["Skiff"] + seige_turtle: ["SeigeTurtle"] +--- +A player must be on one of the mounts in the list to be able to see the objects. + +Notes +===== +https://blishhud.com/docs/markers/attributes/mount diff --git a/xml_converter/doc/position/height_offset.md b/xml_converter/doc/position/height_offset.md new file mode 100644 index 00000000..b0f2823f --- /dev/null +++ b/xml_converter/doc/position/height_offset.md @@ -0,0 +1,14 @@ +--- +name: Height Offset +type: Float32 +applies_to: ["Icon"] +xml_fields: ["HeightOffset", "BHHeightOffset"] +protobuf_field: height_offset +examples: + - "0" +--- +A vertical offset of the object from the recorded position. + +Notes +===== +https://blishhud.com/docs/markers/attributes/heightoffset diff --git a/xml_converter/doc/position/position.md b/xml_converter/doc/position/position.md new file mode 100644 index 00000000..ff5383a2 --- /dev/null +++ b/xml_converter/doc/position/position.md @@ -0,0 +1,34 @@ +--- +name: Position +type: CompoundValue +applies_to: ["Icon"] +xml_fields: ["Position"] +protobuf_field: position +xml_bundled_components: [] +xml_separate_components: ["X Position", "Y Position", "Z Position"] +components: +- name: X Position + type: Float32 + xml_fields: [XPos, PositionX] + protobuf_field: "x" + examples: ["166.735", "1110.4", "-433.615", "-196.412"] + +- name: Y Position + type: Float32 + xml_fields: [YPos, PositionY] + protobuf_field: "y" + examples: ["81.727", "24.5189", "-9.12564", "3.91473"] + +- name: Z Position + type: Float32 + xml_fields: [ZPos, PositionZ] + protobuf_field: "z" + examples: ["-103.464", "-135.401", "164.66", "625.115"] + +--- +An XYZ location of a point in the game world. + +Notes +===== +https://blishhud.com/docs/markers/attributes/position +https://blishhud.com/docs/markers/attributes/heightoffset diff --git a/xml_converter/doc/profession_filter/profession_filter.md b/xml_converter/doc/profession_filter/profession_filter.md new file mode 100644 index 00000000..f073cda2 --- /dev/null +++ b/xml_converter/doc/profession_filter/profession_filter.md @@ -0,0 +1,24 @@ +--- +name: Profession Filter +type: MultiflagValue +applies_to: [Icon, Trail] +xml_fields: [Profession] +protobuf_field: profession_filter +flags: + guardian: [Guardian] + warrior: [Warrior] + engineer: [Engineer] + ranger: [Ranger] + thief: [Thief] + elementalist: [Elementalist] + mesmer: [Mesmer] + necromancer: [Necromancer] + revenant: [Revenant] +--- +The player must be player a character of one of the professions in this list. + +Notes +===== +https://blishhud.com/docs/markers/attributes/profession + +PARSEABLE_VAR(profession_filter, ProfessionFilter, "Profession") diff --git a/xml_converter/doc/rendering/constant_size_on_map.md b/xml_converter/doc/rendering/constant_size_on_map.md new file mode 100644 index 00000000..b73d9932 --- /dev/null +++ b/xml_converter/doc/rendering/constant_size_on_map.md @@ -0,0 +1,21 @@ +--- +name: Constant Size On Map +type: Boolean +applies_to: [Icon] +xml_fields: [ScaleOnMapWithZoom] +protobuf_field: constant_size_on_map +custom_functions: + read.xml: + function: inverted_xml_attribute_to_bool + side_effects: [] + write.xml: + function: bool_to_inverted_xml_attribute + side_effects: [] +--- +Scale the size of the object to be the same scale as the map. + +Notes +===== + +https://blishhud.com/docs/markers/attributes/scaleonmapwithzoom + diff --git a/xml_converter/doc/rendering/cull_chirality.md b/xml_converter/doc/rendering/cull_chirality.md new file mode 100644 index 00000000..c560f3a7 --- /dev/null +++ b/xml_converter/doc/rendering/cull_chirality.md @@ -0,0 +1,19 @@ +--- +name: Cull Chirality +applies_to: [Icon, Trail] +xml_fields: [Cull] +protobuf_field: cull_chirality +type: Enum +values: + none: ["None"] + clockwise: ["Clockwise"] + counter_clockwise: ["CounterClockwise"] + +--- +Cull one of the sides of an Icon or Trail + +Notes +===== + https://blishhud.com/docs/markers/attributes/cull + + \ No newline at end of file diff --git a/xml_converter/doc/rendering/map_display_size.md b/xml_converter/doc/rendering/map_display_size.md new file mode 100644 index 00000000..5cd75677 --- /dev/null +++ b/xml_converter/doc/rendering/map_display_size.md @@ -0,0 +1,15 @@ +--- +name: Map Display Size +type: Int32 +applies_to: [Icon, Trail] +xml_fields: [MapDisplaySize] +protobuf_field: map_display_size +--- +The size, in pixels, that the marker should be shown on the minimap or fullscreen map. +When applied to a Trail, affects the width of the trail shown on the minimap or fullscreen map. + +Notes +===== +https://blishhud.com/docs/markers/attributes/mapdisplaysize + + diff --git a/xml_converter/doc/rendering/render_ingame.md b/xml_converter/doc/rendering/render_ingame.md new file mode 100644 index 00000000..3000df16 --- /dev/null +++ b/xml_converter/doc/rendering/render_ingame.md @@ -0,0 +1,22 @@ +--- +name: Render Ingame +type: Boolean +applies_to: [Icon, Trail] +xml_fields: [IngameVisibility, BHIngameVisibility] +protobuf_field: is_hidden_ingame +custom_functions: + read.xml: + function: inverted_xml_attribute_to_bool + side_effects: [] + write.xml: + function: bool_to_inverted_xml_attribute + side_effects: [] +--- + +Allows or Prevents this object from being rendered in the 3D game space. + +Notes +===== + +https://gw2pathing.com/docs/marker-dev/attributes/visibility + diff --git a/xml_converter/doc/rendering/render_on_map.md b/xml_converter/doc/rendering/render_on_map.md new file mode 100644 index 00000000..375fb135 --- /dev/null +++ b/xml_converter/doc/rendering/render_on_map.md @@ -0,0 +1,19 @@ +--- +name: Render on Map +type: Boolean +applies_to: [Icon, Trail] +xml_fields: [MapVisibility, BHMapVisibility] +protobuf_field: is_hidden_on_map +custom_functions: + read.xml: + function: inverted_xml_attribute_to_bool + side_effects: [] + write.xml: + function: bool_to_inverted_xml_attribute + side_effects: [] +--- +Allows or Prevents this object from being rendered on the world map. + +Notes +===== + diff --git a/xml_converter/doc/rendering/render_on_minimap.md b/xml_converter/doc/rendering/render_on_minimap.md new file mode 100644 index 00000000..989d89cb --- /dev/null +++ b/xml_converter/doc/rendering/render_on_minimap.md @@ -0,0 +1,19 @@ +--- +name: Render on Minimap +type: Boolean +applies_to: [Icon, Trail] +xml_fields: [MinimapVisibility, BHMinimapVisibility] +protobuf_field: is_hidden_on_minimap +custom_functions: + read.xml: + function: inverted_xml_attribute_to_bool + side_effects: [] + write.xml: + function: bool_to_inverted_xml_attribute + side_effects: [] +--- + +Allows or Prevents this object from being rendered on the minimap aka compass. + +Notes +===== diff --git a/xml_converter/doc/rotation/euler_rotation.md b/xml_converter/doc/rotation/euler_rotation.md new file mode 100644 index 00000000..cfeff7ce --- /dev/null +++ b/xml_converter/doc/rotation/euler_rotation.md @@ -0,0 +1,34 @@ +--- +name: Euler Rotation +type: CompoundValue +applies_to: ["Icon"] +xml_fields: ["Rotate"] +protobuf_field: euler_rotation +xml_bundled_components: ['X Rotation', 'Y Rotation', 'Z Rotation'] +xml_separate_components: [] +components: +- name: X Rotation + type: Float32 + xml_fields: [RotateX] + protobuf_field: "x" + examples: ["180", "90", "0", "85", "-90", "0.01"] + +- name: Y Rotation + type: Float32 + xml_fields: [RotateY] + protobuf_field: "y" + examples: ["10", "-18", "0", "-1.5", "20", "359"] + +- name: Z Rotation + type: Float32 + xml_fields: [RotateZ] + protobuf_field: "z" + examples: ["-38", "-10.55", "-0.65", "123", "53.5", "-75"] + +--- +Euler X Y Z rotation in degrees. +Can be any floating point value but will be modulo 360 when applied + +Notes +===== +https://blishhud.com/docs/markers/attributes/rotate diff --git a/xml_converter/doc/scale/icon_size.md b/xml_converter/doc/scale/icon_size.md new file mode 100644 index 00000000..7f13327e --- /dev/null +++ b/xml_converter/doc/scale/icon_size.md @@ -0,0 +1,12 @@ +--- +name: Icon Size +type: Float32 +applies_to: [Icon] +xml_fields: [IconSize] +protobuf_field: tentative__scale +--- +Multiplier on the size of an image (i.e. 1 is 100%, 2 is 200%). + +Notes +===== +https://blishhud.com/docs/markers/attributes/iconfile diff --git a/xml_converter/doc/scale/trail_scale.md b/xml_converter/doc/scale/trail_scale.md new file mode 100644 index 00000000..1a9a207e --- /dev/null +++ b/xml_converter/doc/scale/trail_scale.md @@ -0,0 +1,12 @@ +--- +name: Trail Scale +type: Float32 +applies_to: [Trail] +xml_fields: [TrailScale] +protobuf_field: scale +--- +Adjusts the width of a trail mesh as a multiplier to the default width. + +Notes +===== +https://blishhud.com/docs/markers/attributes/trailscale/ diff --git a/xml_converter/doc/schedule/schedule.md b/xml_converter/doc/schedule/schedule.md new file mode 100644 index 00000000..14d2f113 --- /dev/null +++ b/xml_converter/doc/schedule/schedule.md @@ -0,0 +1,12 @@ +--- +name: Schedule +type: String +applies_to: [Icon, Trail] +xml_fields: [Schedule] +protobuf_field: bhdraft__schedule +--- +A description of when to hide or show an object based on a realtime schedule. + +Notes +===== +https://blishhud.com/docs/markers/attributes/schedule diff --git a/xml_converter/doc/schedule/schedule_duration.md b/xml_converter/doc/schedule/schedule_duration.md new file mode 100644 index 00000000..c69b1ef5 --- /dev/null +++ b/xml_converter/doc/schedule/schedule_duration.md @@ -0,0 +1,12 @@ +--- +name: Schedule Duration +type: Float32 +applies_to: [Icon, Trail] +xml_fields: [ScheduleDuration] +protobuf_field: bhdraft__schedule_duration +--- +Combined with Schedule to determine how long after the object is shown before it is hidden again. + +Notes +===== +https://blishhud.com/docs/markers/attributes/schedule diff --git a/xml_converter/doc/size_on_screen/maximum_size_on_screen.md b/xml_converter/doc/size_on_screen/maximum_size_on_screen.md new file mode 100644 index 00000000..9f483c3e --- /dev/null +++ b/xml_converter/doc/size_on_screen/maximum_size_on_screen.md @@ -0,0 +1,11 @@ +--- +name: Maximum Size On Screen +type: Int32 +applies_to: [Icon] +xml_fields: [MaxSize] +protobuf_field: maximum_size_on_screen +--- +The largest width/height of this icon on the screen. +Notes +===== +https://blishhud.com/docs/markers/attributes/size diff --git a/xml_converter/doc/size_on_screen/minimum_size_on_screen.md b/xml_converter/doc/size_on_screen/minimum_size_on_screen.md new file mode 100644 index 00000000..3a41674c --- /dev/null +++ b/xml_converter/doc/size_on_screen/minimum_size_on_screen.md @@ -0,0 +1,12 @@ +--- +name: Minimum Size on Screen +type: Int32 +applies_to: [Icon] +xml_fields: [MinSize] +protobuf_field: minimum_size_on_screen +--- +The smallest width/height of this icon on the screen. + +Notes +===== +https://blishhud.com/docs/markers/attributes/size diff --git a/xml_converter/doc/specialization_filter/specialization_filter.md b/xml_converter/doc/specialization_filter/specialization_filter.md new file mode 100644 index 00000000..3a7a59a6 --- /dev/null +++ b/xml_converter/doc/specialization_filter/specialization_filter.md @@ -0,0 +1,91 @@ +--- +name: Specialization Filter +type: MultiflagValue +applies_to: [Icon, Trail] +xml_fields: ["Specialization"] +protobuf_field: specialization_filter +flags: + # Heart of Thorns Spec + elementalist_tempest: ["48", "Tempest"] + engineer_scrapper: ["43", "Scrapper"] + guardian_dragonhunter: ["27", "Dragonhunter"] + mesmer_chronomancer: ["40", "Chronomancer"] + necromancer_reaper: ["34", "Reaper"] + ranger_druid: ["5", "Druid"] + revenant_herald: ["52", "Herald"] + thief_daredevil: ["7", "Daredevil"] + warrior_berserker: ["18", "Berserker"] + + # Path of Fire Spec + elementalist_weaver: ["56", "Weaver"] + engineer_holosmith: ["57", "Holosmith"] + guardian_firebrand: ["62", "Firebrand"] + mesmer_mirage: ["59", "Mirage"] + necromancer_scourge: ["60", "Scourge"] + ranger_soulbeast: ["55", "Soulbeast"] + revenant_renegade: ["63", "Renegade"] + thief_deadeye: ["58", "Deadeye"] + warrior_spellbreaker: ["61", "Spellbreaker"] + + # TODO(#58): End of Dragons Spec Numbers + elementalist_catalyst: ["67", "Catalyst"] + engineer_mechanist: ["70", "Mechanist"] + guardian_willbender: ["65", "Willbender"] + mesmer_virtuoso: ["66", "Virtuoso"] + necromancer_harbinger: ["64", "Harbinger"] + ranger_untamed: ["72", "Untamed"] + revenant_vindicator: ["69", "Vindicator"] + thief_specter: ["71", "Specter"] + warrior_bladesworn: ["68", "Bladesworn"] + + # Core Spec + elementalist_air: ["41"] + elementalist_arcane: ["37"] + elementalist_earth: ["26"] + elementalist_fire: ["31"] + elementalist_water: ["17"] + engineer_alchemy: ["29"] + engineer_explosives: ["6"] + engineer_firearms: ["38"] + engineer_inventions: ["47"] + engineer_tools: ["21"] + guardian_honor: ["49"] + guardian_radiance: ["16"] + guardian_valor: ["13"] + guardian_virtues: ["46"] + guardian_zeal: ["42"] + mesmer_chaos: ["45"] + mesmer_domination: ["10"] + mesmer_dueling: ["1"] + mesmer_illusions: ["24"] + mesmer_inspiration: ["23"] + necromancer_blood_magic: ["19"] + necromancer_curses: ["39"] + necromancer_death_magic: ["2"] + necromancer_soul_reaping: ["50"] + necromancer_spite: ["53"] + ranger_beastmastery: ["32"] + ranger_marksmanship: ["8"] + ranger_nature_magic: ["25"] + ranger_skirmishing: ["30"] + ranger_wilderness_survival: ["33"] + revenant_corruption: ["14"] + revenant_devastation: ["15"] + revenant_invocation: ["3"] + revenant_retribution: ["9"] + revenant_salvation: ["12"] + thief_acrobatics: ["54"] + thief_critical_strikes: ["35"] + thief_deadly_arts: ["28"] + thief_shadow_arts: ["20"] + thief_trickery: ["44"] + warrior_arms: ["36"] + warrior_defense: ["22"] + warrior_discipline: ["51"] + warrior_strength: ["4"] + warrior_tactics: ["11"] +--- +The Specialization(s) that should be present to view this marker. + +Notes +===== \ No newline at end of file diff --git a/xml_converter/doc/species_filter/species_filter.md b/xml_converter/doc/species_filter/species_filter.md new file mode 100644 index 00000000..1881e7e1 --- /dev/null +++ b/xml_converter/doc/species_filter/species_filter.md @@ -0,0 +1,18 @@ +--- +name: Species Filter +type: MultiflagValue +applies_to: [Icon, Trail] +xml_fields: [Race, Species] +protobuf_field: species_filter + +flags: + asura: [asura] + charr: [charr] + human: [human] + norn: [norn] + sylvari: [sylvari] +--- +The player must be player a character of one of the species in this list." +Notes +===== +https://blishhud.com/docs/markers/attributes/race \ No newline at end of file diff --git a/xml_converter/doc/texture/animation_speed.md b/xml_converter/doc/texture/animation_speed.md new file mode 100644 index 00000000..36e7a055 --- /dev/null +++ b/xml_converter/doc/texture/animation_speed.md @@ -0,0 +1,15 @@ +--- +name: Animation Speed +type: Float32 +applies_to: [Trail] +xml_fields: ["AnimSpeed", "AnimationSpeed"] +protobuf_field: animation_speed +--- +The speed which the texture should be moving across the object. + +Notes +===== +https://blishhud.com/docs/markers/attributes/texture +https://blishhud.com/docs/markers/attributes/iconfile +https://blishhud.com/docs/markers/attributes/color +https://blishhud.com/docs/markers/attributes/animspeed diff --git a/xml_converter/doc/texture/color.md b/xml_converter/doc/texture/color.md new file mode 100644 index 00000000..2be02b3c --- /dev/null +++ b/xml_converter/doc/texture/color.md @@ -0,0 +1,62 @@ +--- +name: Color +type: CompoundCustomClass +class: Color +applies_to: [Icon, Trail] +xml_fields: [Color, BHColor] +protobuf_field: rgba_color +xml_bundled_components: ['Red', 'Green', 'Blue'] +xml_separate_components: ['Alpha'] +examples: + - "FFFFFF" + - "#FFFFFF" + - "#FF8800" + - "#CCCCCCFF" + - "#000000CC" + +components: +- name: Red + type: Float32 + xml_fields: [Red] + protobuf_field: null + examples: ["0", "0.25", "0.5", "0.75", "1.0"] + +- name: Green + type: Float32 + xml_fields: [Green] + protobuf_field: null + examples: ["0", "0.25", "0.5", "0.75", "1.0"] + +- name: Blue + type: Float32 + xml_fields: [Blue] + protobuf_field: null + examples: ["0", "0.25", "0.5", "0.75", "1.0"] + +- name: Alpha + type: Float32 + xml_fields: [Alpha] + protobuf_field: null + examples: ["0", "0.25", "0.5", "0.75", "1.0"] + + +--- +A multiplier color to tint the raw albedo texture of a marker of trail texture. (Unclear) Solid white will result in no change, solid black will result in a black texture. + +Note: Burrito and BlishHUD treat the alpha channel of "Color" differently. Burrito treats the 7th and 8th hex of the color as a true alpha channel, just the same as if the Alpha attribute had been used. BlishHUD treats the 7th and 8th hex as a modulator for #FFFFFF. + +A color of #00000000 will apear as transparent in Burrito, but will apear as the original texture on BlishHUD +A color of #000000 will appear as black for both Burrito and BlishHUD +A color of #FFFFFF00 will apear transparent for burrito and the original texture on BlishHUD + +Numbers are stored in an 8bit precision format so these are the floating point values that will be used if more precise values are specified: 0.000, 0.003, 0.007, 0.011, 0.015, 0.019, 0.023, 0.027, 0.031, 0.035, 0.039, 0.043, 0.047, 0.050, 0.054, 0.058, 0.062, 0.066, 0.070, 0.074, 0.078, 0.082, 0.086, 0.090, 0.094, 0.098, 0.101, 0.105, 0.109, 0.113, 0.117, 0.121, 0.125, 0.129, 0.133, 0.137, 0.141, 0.145, 0.149, 0.152, 0.156, 0.160, 0.164, 0.168, 0.172, 0.176, 0.180, 0.184, 0.188, 0.192, 0.196, 0.200, 0.203, 0.207, 0.211, 0.215, 0.219, 0.223, 0.227, 0.231, 0.235, 0.239, 0.243, 0.247, 0.250, 0.254, 0.258, 0.262, 0.266, 0.270, 0.274, 0.278, 0.282, 0.286, 0.290, 0.294, 0.298, 0.301, 0.305, 0.309, 0.313, 0.317, 0.321, 0.325, 0.329, 0.333, 0.337, 0.341, 0.345, 0.349, 0.352, 0.356, 0.360, 0.364, 0.368, 0.372, 0.376, 0.380, 0.384, 0.388, 0.392, 0.396, 0.400, 0.403, 0.407, 0.411, 0.415, 0.419, 0.423, 0.427, 0.431, 0.435, 0.439, 0.443, 0.447, 0.450, 0.454, 0.458, 0.462, 0.466, 0.470, 0.474, 0.478, 0.482, 0.486, 0.490, 0.494, 0.498, 0.501, 0.505, 0.509, 0.513, 0.517, 0.521, 0.525, 0.529, 0.533, 0.537, 0.541, 0.545, 0.549, 0.552, 0.556, 0.560, 0.564, 0.568, 0.572, 0.576, 0.580, 0.584, 0.588, 0.592, 0.596, 0.600, 0.603, 0.607, 0.611, 0.615, 0.619, 0.623, 0.627, 0.631, 0.635, 0.639, 0.643, 0.647, 0.650, 0.654, 0.658, 0.662, 0.666, 0.670, 0.674, 0.678, 0.682, 0.686, 0.690, 0.694, 0.698, 0.701, 0.705, 0.709, 0.713, 0.717, 0.721, 0.725, 0.729, 0.733, 0.737, 0.741, 0.745, 0.749, 0.752, 0.756, 0.760, 0.764, 0.768, 0.772, 0.776, 0.780, 0.784, 0.788, 0.792, 0.796, 0.800, 0.803, 0.807, 0.811, 0.815, 0.819, 0.823, 0.827, 0.831, 0.835, 0.839, 0.843, 0.847, 0.850, 0.854, 0.858, 0.862, 0.866, 0.870, 0.874, 0.878, 0.882, 0.886, 0.890, 0.894, 0.898, 0.901, 0.905, 0.909, 0.913, 0.917, 0.921, 0.925, 0.929, 0.933, 0.937, 0.941, 0.945, 0.949, 0.952, 0.956, 0.960, 0.964, 0.968, 0.972, 0.976, 0.980, 0.984, 0.988, 0.992, 0.996, 1.000 + +Values below 0 or above 1 will be clamped to 0 or 1 + +Notes +===== +https://blishhud.com/docs/markers/attributes/texture +https://blishhud.com/docs/markers/attributes/iconfile +https://blishhud.com/docs/markers/attributes/color +https://blishhud.com/docs/markers/attributes/animspeed + diff --git a/xml_converter/doc/texture/icon.md b/xml_converter/doc/texture/icon.md new file mode 100644 index 00000000..077d0c02 --- /dev/null +++ b/xml_converter/doc/texture/icon.md @@ -0,0 +1,21 @@ +--- +name: Icon +type: Custom +class: Image +applies_to: [Icon] +xml_fields: [IconFile] +uses_file_path: false +protobuf_field: texture_id +examples: + - "data/cool_icon.png" + - "data/good_direction.png" + - "data/heart_of_thorns/mastery_point.png" +--- +The path to an image which contains the texture that will be present on an icon. + +Notes +===== +https://blishhud.com/docs/markers/attributes/texture +https://blishhud.com/docs/markers/attributes/iconfile +https://blishhud.com/docs/markers/attributes/color +https://blishhud.com/docs/markers/attributes/animspeed diff --git a/xml_converter/doc/texture/texture.md b/xml_converter/doc/texture/texture.md new file mode 100644 index 00000000..07d931d4 --- /dev/null +++ b/xml_converter/doc/texture/texture.md @@ -0,0 +1,21 @@ +--- +name: Texture +type: Custom +class: Image +applies_to: [Trail] +xml_fields: [Texture] +uses_file_path: false +protobuf_field: texture_id +examples: + - "data/cool_trail.png" + - "data/bad_path.png" + - "data/heart_of_thorns/glider_only_path.png" +--- +The path to an image which contains the texture that will be present on a trail. + +Notes +===== +https://blishhud.com/docs/markers/attributes/texture +https://blishhud.com/docs/markers/attributes/iconfile +https://blishhud.com/docs/markers/attributes/color +https://blishhud.com/docs/markers/attributes/animspeed diff --git a/xml_converter/doc/tooltip/tooltip_description.md b/xml_converter/doc/tooltip/tooltip_description.md new file mode 100644 index 00000000..a783c21e --- /dev/null +++ b/xml_converter/doc/tooltip/tooltip_description.md @@ -0,0 +1,14 @@ +--- +name: Tooltip Description +type: String +applies_to: [Icon, Category] +xml_fields: [TipDescription] +protobuf_field: tip_description +--- +The full text of the tooltip. + +Notes +===== + + +https://blishhud.com/docs/markers/attributes/tip diff --git a/xml_converter/doc/tooltip/tooltip_name.md b/xml_converter/doc/tooltip/tooltip_name.md new file mode 100644 index 00000000..769b4321 --- /dev/null +++ b/xml_converter/doc/tooltip/tooltip_name.md @@ -0,0 +1,14 @@ +--- +name: Tooltip Name +type: String +applies_to: [Icon] +xml_fields: [TipName] +protobuf_field: tip_name +--- +The name of the tooltip when hovering over the minimap. + +Notes +===== + + +https://blishhud.com/docs/markers/attributes/tip diff --git a/xml_converter/doc/trail_data/byte layout.svg b/xml_converter/doc/trail_data/byte layout.svg new file mode 100644 index 00000000..a24d038a --- /dev/null +++ b/xml_converter/doc/trail_data/byte layout.svg @@ -0,0 +1,593 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + X6 + + Y6 + + Z6 + + X7 + + Y7 + + Z7 + + Version + Map ID + X1 + Y1 + Z1 + X2 + Y2 + Z2 + X3 + Y3 + Z3 + X4 + Y4 + Z4 + ... + X5 + Y5 + Z5 + + + + + + + + + + + + + + + + + + + diff --git a/xml_converter/doc/trail_data/trail_data.md b/xml_converter/doc/trail_data/trail_data.md new file mode 100644 index 00000000..a3414ce9 --- /dev/null +++ b/xml_converter/doc/trail_data/trail_data.md @@ -0,0 +1,48 @@ +--- +name: Trail Data +type: Custom +class: TrailData +xml_fields: ["TrailData"] +uses_file_path: true +protobuf_field: trail_data +applies_to: [Trail] +examples: + - "trails/my_trail.trl" + - "jumping_puzzle_path.trl" +custom_functions: + read.xml: + function: xml_attribute_to_trail_data + side_effects: [Map ID] + write.xml: + function: trail_data_to_xml_attribute + side_effects: [Map ID] +--- + +The coordinates of each point along a trail path. + +In the TacO format this attribute is a string that points to a file which contains this information packed in binary. The binary format consists of + +- 4 bytes for an integer that represents the `.trl` format version number +- 4 bytes for an integer that represents the Map ID which this trail is for +- Any number of 12 byte sets, containing 3 32 bit floats + +Example `.trl` parser +-------------------------------------------------------------------------------- + +```python +from typing import Tuple, List +import struct + +with open("./demo.trl", 'rb') as f: + version: int = struct.unpack("