commit 3322aa989769ec3af0909b7d4f03a6ec5f60f68e Author: Nekojimi Date: Wed Apr 16 22:56:14 2025 +0100 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4709183 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Godot 4+ specific ignores +.godot/ diff --git a/CitizenManager.gd b/CitizenManager.gd new file mode 100644 index 0000000..12572e3 --- /dev/null +++ b/CitizenManager.gd @@ -0,0 +1,113 @@ +extends Node +class_name CitizenManager + +@export var task_assignment_rate: float = 100 + +var task_assignment_budget: float = 0 + +#signal task_queue_updated(task_queue: Array[Task]) + +var task_queue: Array[Task] = [] + +const FLOAT64_MAX: float = 2.0**1023 * (2 - 2.0**-52) + +func _process(delta: float) -> void: + task_assignment_budget += task_assignment_rate * delta + if task_assignment_budget >= task_assignment_rate: + task_assignment_budget = task_assignment_rate + + var idle_workers: Array[Citizen] = [] + for worker in get_tree().get_nodes_in_group("Citizens"): + if worker.is_idle(): + idle_workers.append(worker) + + #idle_workers.shuffle() + + while !idle_workers.is_empty() and !task_queue.is_empty() and task_assignment_budget > 0: + var task: Task = task_queue.pop_front() + task_assignment_budget -= 1 + if task.is_ready(): + # TODO: this currently assigns to the first worker found + var worker: Citizen = idle_workers.pop_front() + worker.assign_task(task) + else: + add_task(task) + +func remove_task(task: Task): + var idx: int = task_queue.find(task) + if idx >= 0: + task_queue.remove_at(idx) + +func add_task(task: Task): + var idx: int = task_queue.bsearch_custom(task, sort_tasks, false) + task_queue.insert(idx, task) + +func sort_tasks(a: Task,b: Task) -> bool: + return a.priority > b.priority + +const TASK_PRIORITY_ANYTIME = 0 +const TASK_PRIORITY_BY_WAVE_START = 10 +const TASK_PRIORITY_ASAP = 20 + +class Task: + var priority: int = TASK_PRIORITY_ANYTIME + func get_task_name() -> String: + return "Task" + func is_ready() -> bool: + return true + func get_location() -> Vector2: + return Vector2() + func execute(worker: Citizen) -> bool: + return false + func interrupt(worker: Citizen) -> void: + pass + func cancel(worker: Citizen) -> void: + pass + +class BuildTask extends Task: + var building: Building + func _init() -> void: + priority = 1 + func get_task_name() -> String: + return "Build " + building.name + func is_ready() -> bool: + return super() and building.can_build() + func get_location() -> Vector2: + return building.global_position + func execute(worker: Citizen) -> bool: + var ok: bool = true + ok = await worker.go_to_destination(building.position) + if !ok: + return false + building.build() + return true + +class FetchItemTask extends Task: + var building: Building + var item: Item + func get_task_name() -> String: + return "Transfer " + item.name + " to " + building.name + func execute(worker: Citizen) -> bool: + # find the item from nearby buildings + # TODO: also look for items on the floor? + var storage_building: Machine = null + var closest: float = FLOAT64_MAX + + for machine in worker.get_tree().get_nodes_in_group("Buildings"): + if machine is Machine: + if machine.stored_items.has(item): + var distance_sqr: float = machine.position.distance_squared_to(worker.position) + if distance_sqr < closest: + storage_building = machine + closest = distance_sqr + + if storage_building == null: return false + # go to the storage + if !await worker.go_to_destination(storage_building.global_position): return false + # pick up the item + if !await worker.pickup_item_from_building(item, storage_building): return false + # carry the item to the construction site + if !await worker.go_to_destination(building.global_position): return false + # store the item in the construction site + if !await worker.store_item_in_contruction_site(building): return false + return true diff --git a/CitizenManager.gd.uid b/CitizenManager.gd.uid new file mode 100644 index 0000000..3e91876 --- /dev/null +++ b/CitizenManager.gd.uid @@ -0,0 +1 @@ +uid://dxo54c0g6uo6v diff --git a/Stackable Towers.xcf b/Stackable Towers.xcf new file mode 100644 index 0000000..f19d2c4 Binary files /dev/null and b/Stackable Towers.xcf differ diff --git a/addons/debug_draw_3d/LICENSE b/addons/debug_draw_3d/LICENSE new file mode 100644 index 0000000..617a15b --- /dev/null +++ b/addons/debug_draw_3d/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 DmitriySalnikov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, andor sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/addons/debug_draw_3d/README.md b/addons/debug_draw_3d/README.md new file mode 100644 index 0000000..fe91a13 --- /dev/null +++ b/addons/debug_draw_3d/README.md @@ -0,0 +1,158 @@ +![icon](/images/icon_3d_128.png) + +# Debug drawing utility for Godot + +This is an add-on for debug drawing in 3D and for some 2D overlays, which is written in `C++` and can be used with `GDScript` or `C#`. + +Based on my previous addon, which was developed [only for C#](https://github.com/DmitriySalnikov/godot_debug_draw_cs), and which was inspired by [Zylann's GDScript addon](https://github.com/Zylann/godot_debug_draw) + +## [Documentation](https://dd3d.dmitriysalnikov.ru/docs/) + +## [Godot 3 version](https://github.com/DmitriySalnikov/godot_debug_draw_3d/tree/godot_3) + +## Support me + +Your support adds motivation to develop my public projects. + +Boosty + +USDT-TRC20 + +USDT-TRC20 TEw934PrsffHsAn5M63SoHYRuZo984EF6v + +## Features + +3D: + +* Arrow +* Billboard opaque square +* Box +* Camera Frustum +* Cylinder +* Gizmo +* Grid +* Line +* Line Path +* Line with Arrow +* Plane +* Points +* Position 3D (3 crossing axes) +* Sphere + +2D: + +* **[Work in progress]** + +Overlay: + +* Text (with grouping and coloring) +* FPS Graph +* Custom Graphs + +Precompiled for: + +* Windows +* Linux (built on Ubuntu 22.04) +* macOS (10.15+) +* Android (5.0+) +* iOS +* Web (Firefox is supported by Godot 4.3+) + +This addon supports working with several World3D and different Viewports. +There is also a no depth test mode and other settings that can be changed for each instance. + +This library supports double-precision builds, for more information, [see the documentation](https://dd3d.dmitriysalnikov.ru/docs/?page=md_docs_2DoublePrecision.html). + +## [Interactive Web Demo](https://dd3d.dmitriysalnikov.ru/demo/) + +[![screenshot_web](/images/screenshot_web.png)](https://dd3d.dmitriysalnikov.ru/demo/) + +## Download + +To download, use the [Godot Asset Library](https://godotengine.org/asset-library/asset/1766) or use one of the stable versions from the [GitHub Releases](https://github.com/DmitriySalnikov/godot_debug_draw_3d/releases) page. + +For versions prior to `1.4.5`, just download one of the `source codes` in the assets. For newer versions, download `debug-draw-3d_[version].zip`. + +### Installation + +* Close editor +* Copy `addons/debug_draw_3d` to your `addons` folder, create it if the folder doesn't exist +* Launch editor + +## Examples + +More examples can be found in the `examples_dd3d/` folder. + +Simple test: + +```gdscript +func _process(delta: float) -> void: + var _time = Time.get_ticks_msec() / 1000.0 + var box_pos = Vector3(0, sin(_time * 4), 0) + var line_begin = Vector3(-1, sin(_time * 4), 0) + var line_end = Vector3(1, cos(_time * 4), 0) + + DebugDraw3D.draw_box(box_pos, Quaternion.IDENTITY, Vector3(1, 2, 1), Color(0, 1, 0)) + DebugDraw3D.draw_line(line_begin, line_end, Color(1, 1, 0)) + DebugDraw2D.set_text("Time", _time) + DebugDraw2D.set_text("Frames drawn", Engine.get_frames_drawn()) + DebugDraw2D.set_text("FPS", Engine.get_frames_per_second()) + DebugDraw2D.set_text("delta", delta) +``` + +![screenshot_1](/images/screenshot_1.png) + +An example of using scoped configs: + +```gdscript +@tool +extends Node3D + +func _ready(): + # Set the base scoped_config. + # Each frame will be reset to these scoped values. + DebugDraw3D.scoped_config().set_thickness(0.1).set_center_brightness(0.6) + +func _process(delta): + # Draw using the base scoped config. + DebugDraw3D.draw_box(Vector3.ZERO, Quaternion.IDENTITY, Vector3.ONE * 2, Color.CORNFLOWER_BLUE) + if true: + # Create a scoped config that will exist until exiting this if. + var _s = DebugDraw3D.new_scoped_config().set_thickness(0).set_center_brightness(0.1) + # Draw with a thickness of 0 + DebugDraw3D.draw_box(Vector3.ZERO, Quaternion.IDENTITY, Vector3.ONE, Color.RED) + # If necessary, the values inside this scope can be changed + # even before each call to draw_*. + _s.set_thickness(0.05) + DebugDraw3D.draw_box(Vector3(1,0,1), Quaternion.IDENTITY, Vector3.ONE * 1, Color.BLUE_VIOLET) +``` + +![screenshot_5](/images/screenshot_5.png) + +> [!TIP] +> +> If you want to use a non-standard Viewport for rendering a 3d scene, then do not forget to specify it in the scoped config! + +## API + +This project has a separate [documentation](https://dd3d.dmitriysalnikov.ru/docs/) page. + +Also, a list of all functions is available in the documentation inside the editor (see `DebugDraw3D` and `DebugDraw2D`). + +![screenshot_4](/images/screenshot_4.png) + +## Known issues and limitations + +The text in the keys and values of a text group cannot contain multi-line strings. + +The entire text overlay can only be placed in one corner. + +[Frustum of Camera3D does not take into account the window size from ProjectSettings](https://github.com/godotengine/godot/issues/70362). + +## More screenshots + +`DebugDrawDemoScene.tscn` in editor +![screenshot_2](/images/screenshot_2.png) + +`DebugDrawDemoScene.tscn` in play mode +![screenshot_3](/images/screenshot_3.png) diff --git a/addons/debug_draw_3d/debug_draw_3d.gdextension b/addons/debug_draw_3d/debug_draw_3d.gdextension new file mode 100644 index 0000000..cead527 --- /dev/null +++ b/addons/debug_draw_3d/debug_draw_3d.gdextension @@ -0,0 +1,153 @@ +[configuration] + +entry_symbol = "debug_draw_3d_library_init" +compatibility_minimum = "4.2.2" +reloadable = false + +[dependencies] + +; example.x86_64 = { "relative or absolute path to the dependency" : "the path relative to the exported project", } +; ------------------------------------- +; debug + +macos = { } +windows.x86_64 = { } +linux.x86_64 = { } + +; by default godot is using threads +web.wasm32.nothreads = {} +web.wasm32 = {} + +android.arm32 = { } +android.arm64 = { } +android.x86_32 = { } +android.x86_64 = { } + +ios = {} + +; ------------------------------------- +; release no debug draw + +macos.template_release = { } +windows.template_release.x86_64 = { } +linux.template_release.x86_64 = { } + +web.template_release.wasm32.nothreads = { } +web.template_release.wasm32 = { } + +android.template_release.arm32 = { } +android.template_release.arm64 = { } +android.template_release.x86_32 = { } +android.template_release.x86_64 = { } + +ios.template_release = {} + +; ------------------------------------- +; release forced debug draw + +macos.template_release.forced_dd3d = { } +windows.template_release.x86_64.forced_dd3d = { } +linux.template_release.x86_64.forced_dd3d = { } + +web.template_release.wasm32.nothreads.forced_dd3d = { } +web.template_release.wasm32.forced_dd3d = { } + +ios.template_release.forced_dd3d = {} + +[libraries] + +; ------------------------------------- +; debug + +macos = "libs/libdd3d.macos.editor.universal.framework" +windows.x86_64 = "libs/libdd3d.windows.editor.x86_64.dll" +linux.x86_64 = "libs/libdd3d.linux.editor.x86_64.so" + +web.wasm32.nothreads = "libs/libdd3d.web.template_debug.wasm32.wasm" +web.wasm32 = "libs/libdd3d.web.template_debug.wasm32.threads.wasm" + +android.arm32 = "libs/libdd3d.android.template_debug.arm32.so" +android.arm64 = "libs/libdd3d.android.template_debug.arm64.so" +android.x86_32 = "libs/libdd3d.android.template_debug.x86_32.so" +android.x86_64 = "libs/libdd3d.android.template_debug.x86_64.so" + +ios = "libs/libdd3d.ios.template_debug.universal.dylib" + +; ------------------------------------- +; release no debug draw + +macos.template_release = "libs/libdd3d.macos.template_release.universal.framework" +windows.template_release.x86_64 = "libs/libdd3d.windows.template_release.x86_64.dll" +linux.template_release.x86_64 = "libs/libdd3d.linux.template_release.x86_64.so" + +web.template_release.wasm32.nothreads = "libs/libdd3d.web.template_release.wasm32.wasm" +web.template_release.wasm32 = "libs/libdd3d.web.template_release.wasm32.threads.wasm" + +android.template_release.arm32 = "libs/libdd3d.android.template_release.arm32.so" +android.template_release.arm64 = "libs/libdd3d.android.template_release.arm64.so" +android.template_release.x86_32 = "libs/libdd3d.android.template_release.x86_32.so" +android.template_release.x86_64 = "libs/libdd3d.android.template_release.x86_64.so" + +ios.template_release = "libs/libdd3d.ios.template_release.universal.dylib" + +; ------------------------------------- +; release forced debug draw + +macos.template_release.forced_dd3d = "libs/libdd3d.macos.template_release.universal.enabled.framework" +windows.template_release.x86_64.forced_dd3d = "libs/libdd3d.windows.template_release.x86_64.enabled.dll" +linux.template_release.x86_64.forced_dd3d = "libs/libdd3d.linux.template_release.x86_64.enabled.so" + +web.template_release.wasm32.nothreads.forced_dd3d = "libs/libdd3d.web.template_release.wasm32.enabled.wasm" +web.template_release.wasm32.forced_dd3d = "libs/libdd3d.web.template_release.wasm32.threads.enabled.wasm" + +ios.template_release.forced_dd3d = "libs/libdd3d.ios.template_release.universal.enabled.dylib" + +; ------------------------------------- +; DOUBLE PRECISION +; ------------------------------------- + +; ------------------------------------- +; debug + +macos.double = "libs/libdd3d.macos.editor.universal.double.framework" +windows.x86_64.double = "libs/libdd3d.windows.editor.x86_64.double.dll" +linux.x86_64.double = "libs/libdd3d.linux.editor.x86_64.double.so" + +web.wasm32.nothreads.double = "libs/libdd3d.web.template_debug.wasm32.double.wasm" +web.wasm32.double = "libs/libdd3d.web.template_debug.wasm32.threads.double.wasm" + +android.arm32.double = "libs/libdd3d.android.template_debug.arm32.double.so" +android.arm64.double = "libs/libdd3d.android.template_debug.arm64.double.so" +android.x86_32.double = "libs/libdd3d.android.template_debug.x86_32.double.so" +android.x86_64.double = "libs/libdd3d.android.template_debug.x86_64.double.so" + +ios.double = "libs/libdd3d.ios.template_debug.universal.dylib" + +; ------------------------------------- +; release no debug draw + +macos.template_release.double = "libs/libdd3d.macos.template_release.universal.double.framework" +windows.template_release.x86_64.double = "libs/libdd3d.windows.template_release.x86_64.double.dll" +linux.template_release.x86_64.double = "libs/libdd3d.linux.template_release.x86_64.double.so" + +web.template_release.wasm32.nothreads.double = "libs/libdd3d.web.template_release.wasm32.double.wasm" +web.template_release.wasm32.double = "libs/libdd3d.web.template_release.wasm32.threads.double.wasm" + +android.template_release.arm32.double = "libs/libdd3d.android.template_release.arm32.double.so" +android.template_release.arm64.double = "libs/libdd3d.android.template_release.arm64.double.so" +android.template_release.x86_32.double = "libs/libdd3d.android.template_release.x86_32.double.so" +android.template_release.x86_64.double = "libs/libdd3d.android.template_release.x86_64.double.so" + +ios.template_release.double = "libs/libdd3d.ios.template_release.universal.double.dylib" + +; ------------------------------------- +; release forced debug draw + +macos.template_release.forced_dd3d.double = "libs/libdd3d.macos.template_release.universal.enabled.double.framework" +windows.template_release.x86_64.forced_dd3d.double = "libs/libdd3d.windows.template_release.x86_64.enabled.double.dll" +linux.template_release.x86_64.forced_dd3d.double = "libs/libdd3d.linux.template_release.x86_64.enabled.double.so" + +web.template_release.wasm32.nothreads.forced_dd3d.double = "libs/libdd3d.web.template_release.wasm32.enabled.double.wasm" +web.template_release.wasm32.forced_dd3d.double = "libs/libdd3d.web.template_release.wasm32.threads.enabled.double.wasm" + +ios.template_release.forced_dd3d.double = "libs/libdd3d.ios.template_release.universal.enabled.double.dylib" diff --git a/addons/debug_draw_3d/debug_draw_3d.gdextension.uid b/addons/debug_draw_3d/debug_draw_3d.gdextension.uid new file mode 100644 index 0000000..15da0d3 --- /dev/null +++ b/addons/debug_draw_3d/debug_draw_3d.gdextension.uid @@ -0,0 +1 @@ +uid://svqaxfp5kyrl diff --git a/addons/debug_draw_3d/libs/.gdignore b/addons/debug_draw_3d/libs/.gdignore new file mode 100644 index 0000000..e69de29 diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm32.so b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm32.so new file mode 100644 index 0000000..388f178 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm32.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm64.so b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm64.so new file mode 100644 index 0000000..1166b25 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.arm64.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_32.so b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_32.so new file mode 100644 index 0000000..4f87efd Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_32.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_64.so b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_64.so new file mode 100644 index 0000000..7228e89 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_debug.x86_64.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm32.so b/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm32.so new file mode 100644 index 0000000..6270ce3 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm32.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm64.so b/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm64.so new file mode 100644 index 0000000..a66e7b2 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_release.arm64.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_32.so b/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_32.so new file mode 100644 index 0000000..528a3d1 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_32.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_64.so b/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_64.so new file mode 100644 index 0000000..2f25e64 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.android.template_release.x86_64.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.ios.template_debug.universal.dylib b/addons/debug_draw_3d/libs/libdd3d.ios.template_debug.universal.dylib new file mode 100644 index 0000000..2e3e052 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.ios.template_debug.universal.dylib differ diff --git a/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.dylib b/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.dylib new file mode 100644 index 0000000..cf8fb54 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.dylib differ diff --git a/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.enabled.dylib b/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.enabled.dylib new file mode 100644 index 0000000..a24b083 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.ios.template_release.universal.enabled.dylib differ diff --git a/addons/debug_draw_3d/libs/libdd3d.linux.editor.x86_64.so b/addons/debug_draw_3d/libs/libdd3d.linux.editor.x86_64.so new file mode 100644 index 0000000..756cb15 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.linux.editor.x86_64.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.enabled.so b/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.enabled.so new file mode 100644 index 0000000..457ef8c Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.enabled.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.so b/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.so new file mode 100644 index 0000000..776475e Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.linux.template_release.x86_64.so differ diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/Resources/Info.plist b/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/Resources/Info.plist new file mode 100644 index 0000000..ab50767 --- /dev/null +++ b/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/Resources/Info.plist @@ -0,0 +1,33 @@ + + + + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleDevelopmentRegion + en + CFBundleExecutable + libdd3d.macos.editor.universal.dylib + CFBundleName + Debug Draw 3D + CFBundleDisplayName + Debug Draw 3D + CFBundleIdentifier + ru.dmitriysalnikov.dd3d + NSHumanReadableCopyright + Copyright (c) Dmitriy Salnikov. + CFBundleVersion + 1.5.0 + CFBundleShortVersionString + 1.5.0 + CFBundlePackageType + FMWK + CSResourcesFileMapped + + DTPlatformName + macosx + LSMinimumSystemVersion + 10.14 + + + \ No newline at end of file diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/libdd3d.macos.editor.universal.dylib b/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/libdd3d.macos.editor.universal.dylib new file mode 100644 index 0000000..f7e3f44 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.macos.editor.universal.framework/libdd3d.macos.editor.universal.dylib differ diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/Resources/Info.plist b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/Resources/Info.plist new file mode 100644 index 0000000..be48360 --- /dev/null +++ b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/Resources/Info.plist @@ -0,0 +1,33 @@ + + + + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleDevelopmentRegion + en + CFBundleExecutable + libdd3d.macos.template_release.universal.enabled.dylib + CFBundleName + Debug Draw 3D + CFBundleDisplayName + Debug Draw 3D + CFBundleIdentifier + ru.dmitriysalnikov.dd3d + NSHumanReadableCopyright + Copyright (c) Dmitriy Salnikov. + CFBundleVersion + 1.5.0 + CFBundleShortVersionString + 1.5.0 + CFBundlePackageType + FMWK + CSResourcesFileMapped + + DTPlatformName + macosx + LSMinimumSystemVersion + 10.14 + + + \ No newline at end of file diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/libdd3d.macos.template_release.universal.enabled.dylib b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/libdd3d.macos.template_release.universal.enabled.dylib new file mode 100644 index 0000000..92958df Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.enabled.framework/libdd3d.macos.template_release.universal.enabled.dylib differ diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/Resources/Info.plist b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/Resources/Info.plist new file mode 100644 index 0000000..02284de --- /dev/null +++ b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/Resources/Info.plist @@ -0,0 +1,33 @@ + + + + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleDevelopmentRegion + en + CFBundleExecutable + libdd3d.macos.template_release.universal.dylib + CFBundleName + Debug Draw 3D + CFBundleDisplayName + Debug Draw 3D + CFBundleIdentifier + ru.dmitriysalnikov.dd3d + NSHumanReadableCopyright + Copyright (c) Dmitriy Salnikov. + CFBundleVersion + 1.5.0 + CFBundleShortVersionString + 1.5.0 + CFBundlePackageType + FMWK + CSResourcesFileMapped + + DTPlatformName + macosx + LSMinimumSystemVersion + 10.14 + + + \ No newline at end of file diff --git a/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/libdd3d.macos.template_release.universal.dylib b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/libdd3d.macos.template_release.universal.dylib new file mode 100644 index 0000000..9f6e7fa Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.macos.template_release.universal.framework/libdd3d.macos.template_release.universal.dylib differ diff --git a/addons/debug_draw_3d/libs/libdd3d.web.template_debug.wasm32.threads.wasm b/addons/debug_draw_3d/libs/libdd3d.web.template_debug.wasm32.threads.wasm new file mode 100644 index 0000000..d141395 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.web.template_debug.wasm32.threads.wasm differ diff --git a/addons/debug_draw_3d/libs/libdd3d.web.template_debug.wasm32.wasm b/addons/debug_draw_3d/libs/libdd3d.web.template_debug.wasm32.wasm new file mode 100644 index 0000000..71c53e5 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.web.template_debug.wasm32.wasm differ diff --git a/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.enabled.wasm b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.enabled.wasm new file mode 100644 index 0000000..6c796d7 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.enabled.wasm differ diff --git a/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.threads.enabled.wasm b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.threads.enabled.wasm new file mode 100644 index 0000000..7611a50 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.threads.enabled.wasm differ diff --git a/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.threads.wasm b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.threads.wasm new file mode 100644 index 0000000..3fe340a Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.threads.wasm differ diff --git a/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.wasm b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.wasm new file mode 100644 index 0000000..dbc9d49 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.web.template_release.wasm32.wasm differ diff --git a/addons/debug_draw_3d/libs/libdd3d.windows.editor.x86_64.dll b/addons/debug_draw_3d/libs/libdd3d.windows.editor.x86_64.dll new file mode 100644 index 0000000..70df5e3 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.windows.editor.x86_64.dll differ diff --git a/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.dll b/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.dll new file mode 100644 index 0000000..544e405 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.dll differ diff --git a/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.enabled.dll b/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.enabled.dll new file mode 100644 index 0000000..018c573 Binary files /dev/null and b/addons/debug_draw_3d/libs/libdd3d.windows.template_release.x86_64.enabled.dll differ diff --git a/assets/enemy.png b/assets/enemy.png new file mode 100644 index 0000000..17677d1 Binary files /dev/null and b/assets/enemy.png differ diff --git a/assets/enemy.png.import b/assets/enemy.png.import new file mode 100644 index 0000000..cea5c27 --- /dev/null +++ b/assets/enemy.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b8x6okhfoufpx" +path="res://.godot/imported/enemy.png-63f114c7bb3f2105c232c34f647cbc2d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/enemy.png" +dest_files=["res://.godot/imported/enemy.png-63f114c7bb3f2105c232c34f647cbc2d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/enemy.xcf b/assets/enemy.xcf new file mode 100644 index 0000000..1d9a83e Binary files /dev/null and b/assets/enemy.xcf differ diff --git a/assets/factory.png b/assets/factory.png new file mode 100644 index 0000000..f78ba06 Binary files /dev/null and b/assets/factory.png differ diff --git a/assets/factory.png.import b/assets/factory.png.import new file mode 100644 index 0000000..ef8d98e --- /dev/null +++ b/assets/factory.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cr8sqiuh5at1x" +path="res://.godot/imported/factory.png-9772b16d8f6036fa0ccbd2dbecae07d2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/factory.png" +dest_files=["res://.godot/imported/factory.png-9772b16d8f6036fa0ccbd2dbecae07d2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/bulldoze.png b/assets/icons/bulldoze.png new file mode 100644 index 0000000..318bbe2 Binary files /dev/null and b/assets/icons/bulldoze.png differ diff --git a/assets/icons/conveyor.png b/assets/icons/conveyor.png new file mode 100644 index 0000000..5af7436 Binary files /dev/null and b/assets/icons/conveyor.png differ diff --git a/assets/icons/conveyor.png.import b/assets/icons/conveyor.png.import new file mode 100644 index 0000000..c279ef8 --- /dev/null +++ b/assets/icons/conveyor.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b48vbil24uyma" +path="res://.godot/imported/conveyor.png-4aca5d7210c98a50167ebcf929e85157.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/conveyor.png" +dest_files=["res://.godot/imported/conveyor.png-4aca5d7210c98a50167ebcf929e85157.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/conveyor2.png b/assets/icons/conveyor2.png new file mode 100644 index 0000000..a55ff7d Binary files /dev/null and b/assets/icons/conveyor2.png differ diff --git a/assets/icons/conveyor2.png.import b/assets/icons/conveyor2.png.import new file mode 100644 index 0000000..0994eb1 --- /dev/null +++ b/assets/icons/conveyor2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cfu3m8pss1ph8" +path="res://.godot/imported/conveyor2.png-e3ffe0c04b803dd9c613abeac70e5dc4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/conveyor2.png" +dest_files=["res://.godot/imported/conveyor2.png-e3ffe0c04b803dd9c613abeac70e5dc4.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/miner.png b/assets/icons/miner.png new file mode 100644 index 0000000..353c6a2 Binary files /dev/null and b/assets/icons/miner.png differ diff --git a/assets/icons/miner.png.import b/assets/icons/miner.png.import new file mode 100644 index 0000000..a60c7bc --- /dev/null +++ b/assets/icons/miner.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c41pea1l3e5b8" +path="res://.godot/imported/miner.png-fb3990a11afbb20de06a2481fd097cbf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/miner.png" +dest_files=["res://.godot/imported/miner.png-fb3990a11afbb20de06a2481fd097cbf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/processor.png b/assets/icons/processor.png new file mode 100644 index 0000000..9dac71e Binary files /dev/null and b/assets/icons/processor.png differ diff --git a/assets/icons/processor.png.import b/assets/icons/processor.png.import new file mode 100644 index 0000000..cac9e33 --- /dev/null +++ b/assets/icons/processor.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dh2iqb21845yr" +path="res://.godot/imported/processor.png-62c9e1b1824010e53894d7397407a327.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/processor.png" +dest_files=["res://.godot/imported/processor.png-62c9e1b1824010e53894d7397407a327.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/storage.png b/assets/icons/storage.png new file mode 100644 index 0000000..e43a84e Binary files /dev/null and b/assets/icons/storage.png differ diff --git a/assets/icons/storage.png.import b/assets/icons/storage.png.import new file mode 100644 index 0000000..70d4e11 --- /dev/null +++ b/assets/icons/storage.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cgbwagn11sku6" +path="res://.godot/imported/storage.png-bf52b5b6ba53cb8d070d24c569a22219.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/storage.png" +dest_files=["res://.godot/imported/storage.png-bf52b5b6ba53cb8d070d24c569a22219.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/turret.png b/assets/icons/turret.png new file mode 100644 index 0000000..40a4416 Binary files /dev/null and b/assets/icons/turret.png differ diff --git a/assets/icons/turret.png.import b/assets/icons/turret.png.import new file mode 100644 index 0000000..e463223 --- /dev/null +++ b/assets/icons/turret.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c1mmxh7v77d8j" +path="res://.godot/imported/turret.png-0e83a9583a58ffe3fe3094af11f3f990.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/turret.png" +dest_files=["res://.godot/imported/turret.png-0e83a9583a58ffe3fe3094af11f3f990.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/icons/watchtower.png b/assets/icons/watchtower.png new file mode 100644 index 0000000..d8c6ccd Binary files /dev/null and b/assets/icons/watchtower.png differ diff --git a/assets/icons/watchtower.png.import b/assets/icons/watchtower.png.import new file mode 100644 index 0000000..692f115 --- /dev/null +++ b/assets/icons/watchtower.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://kp4ghn1277as" +path="res://.godot/imported/watchtower.png-78beb9a6c81c48cefc40fc529892056e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/watchtower.png" +dest_files=["res://.godot/imported/watchtower.png-78beb9a6c81c48cefc40fc529892056e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/lilguy.png b/assets/lilguy.png new file mode 100644 index 0000000..2bf95b9 Binary files /dev/null and b/assets/lilguy.png differ diff --git a/assets/lilguy.png.import b/assets/lilguy.png.import new file mode 100644 index 0000000..e4c3314 --- /dev/null +++ b/assets/lilguy.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://8rd4sbar25mm" +path="res://.godot/imported/lilguy.png-51b8c6e36093bdd961b3dfc357dd7dc1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/lilguy.png" +dest_files=["res://.godot/imported/lilguy.png-51b8c6e36093bdd961b3dfc357dd7dc1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/lilguy.xcf b/assets/lilguy.xcf new file mode 100644 index 0000000..a28af8c Binary files /dev/null and b/assets/lilguy.xcf differ diff --git a/assets/lilguy_arms.png b/assets/lilguy_arms.png new file mode 100644 index 0000000..0fd4a1c Binary files /dev/null and b/assets/lilguy_arms.png differ diff --git a/assets/lilguy_arms.png.import b/assets/lilguy_arms.png.import new file mode 100644 index 0000000..12322cd --- /dev/null +++ b/assets/lilguy_arms.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dh4vl2saw2ykx" +path="res://.godot/imported/lilguy_arms.png-470abb82ebf96beff978f16f6ec9d492.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/lilguy_arms.png" +dest_files=["res://.godot/imported/lilguy_arms.png-470abb82ebf96beff978f16f6ec9d492.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/lilguy_away.png b/assets/lilguy_away.png new file mode 100644 index 0000000..499d164 Binary files /dev/null and b/assets/lilguy_away.png differ diff --git a/assets/lilguy_away.png.import b/assets/lilguy_away.png.import new file mode 100644 index 0000000..a4276d8 --- /dev/null +++ b/assets/lilguy_away.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bwktu2pl8g8hv" +path="res://.godot/imported/lilguy_away.png-a0c33d6f2e2ffd4ba5e453ea8822145e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/lilguy_away.png" +dest_files=["res://.godot/imported/lilguy_away.png-a0c33d6f2e2ffd4ba5e453ea8822145e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/lilguy_towards.png b/assets/lilguy_towards.png new file mode 100644 index 0000000..5feec47 Binary files /dev/null and b/assets/lilguy_towards.png differ diff --git a/assets/lilguy_towards.png.import b/assets/lilguy_towards.png.import new file mode 100644 index 0000000..5d7542c --- /dev/null +++ b/assets/lilguy_towards.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bhnybt0fglwg4" +path="res://.godot/imported/lilguy_towards.png-b871f57090fbe82ab8dd8be36de5a07d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/lilguy_towards.png" +dest_files=["res://.godot/imported/lilguy_towards.png-b871f57090fbe82ab8dd8be36de5a07d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/miner.png b/assets/miner.png new file mode 100644 index 0000000..f3856a9 Binary files /dev/null and b/assets/miner.png differ diff --git a/assets/miner.png.import b/assets/miner.png.import new file mode 100644 index 0000000..08504be --- /dev/null +++ b/assets/miner.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://uk1jbajptxhc" +path="res://.godot/imported/miner.png-43e17d2f73ad36509ba8eaa10c614d5d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/miner.png" +dest_files=["res://.godot/imported/miner.png-43e17d2f73ad36509ba8eaa10c614d5d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/resources.png b/assets/resources.png new file mode 100644 index 0000000..6fbfe9d Binary files /dev/null and b/assets/resources.png differ diff --git a/assets/resources.png.import b/assets/resources.png.import new file mode 100644 index 0000000..0fa65a7 --- /dev/null +++ b/assets/resources.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b63im173j48xu" +path="res://.godot/imported/resources.png-e20d020b8fdf4f2f2e000c7cdc9364d2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/resources.png" +dest_files=["res://.godot/imported/resources.png-e20d020b8fdf4f2f2e000c7cdc9364d2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/splat.png b/assets/splat.png new file mode 100644 index 0000000..a575168 Binary files /dev/null and b/assets/splat.png differ diff --git a/assets/splat.png.import b/assets/splat.png.import new file mode 100644 index 0000000..9192672 --- /dev/null +++ b/assets/splat.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://xkum0axedc4a" +path="res://.godot/imported/splat.png-e34996eb33a9915030e3b715801840eb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/splat.png" +dest_files=["res://.godot/imported/splat.png-e34996eb33a9915030e3b715801840eb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/storage.png b/assets/storage.png new file mode 100644 index 0000000..259db77 Binary files /dev/null and b/assets/storage.png differ diff --git a/assets/storage.png.import b/assets/storage.png.import new file mode 100644 index 0000000..b613bfe --- /dev/null +++ b/assets/storage.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cv0h0l631pr7p" +path="res://.godot/imported/storage.png-2117570ae7865fe22d823222d213cbbd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/storage.png" +dest_files=["res://.godot/imported/storage.png-2117570ae7865fe22d823222d213cbbd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/storage.xcf b/assets/storage.xcf new file mode 100644 index 0000000..ece0886 Binary files /dev/null and b/assets/storage.xcf differ diff --git a/assets/tiles.png b/assets/tiles.png new file mode 100644 index 0000000..7cd1843 Binary files /dev/null and b/assets/tiles.png differ diff --git a/assets/tiles.png.import b/assets/tiles.png.import new file mode 100644 index 0000000..cbcf5fb --- /dev/null +++ b/assets/tiles.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dadllqpm2l3fi" +path="res://.godot/imported/tiles.png-0d11a4bcdfb48056f67a66da241684a1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/tiles.png" +dest_files=["res://.godot/imported/tiles.png-0d11a4bcdfb48056f67a66da241684a1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/tiles.xcf b/assets/tiles.xcf new file mode 100644 index 0000000..898f02f Binary files /dev/null and b/assets/tiles.xcf differ diff --git a/assets/turret.png b/assets/turret.png new file mode 100644 index 0000000..4655b3b Binary files /dev/null and b/assets/turret.png differ diff --git a/assets/turret.png.import b/assets/turret.png.import new file mode 100644 index 0000000..f70dfcc --- /dev/null +++ b/assets/turret.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ba7x80lx3rjsw" +path="res://.godot/imported/turret.png-608c0b2b2f2422ecd6efb28e1ad86de5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/turret.png" +dest_files=["res://.godot/imported/turret.png-608c0b2b2f2422ecd6efb28e1ad86de5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/watchtower.png b/assets/watchtower.png new file mode 100644 index 0000000..3dddf06 Binary files /dev/null and b/assets/watchtower.png differ diff --git a/assets/watchtower.png.import b/assets/watchtower.png.import new file mode 100644 index 0000000..b9c6e5e --- /dev/null +++ b/assets/watchtower.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d22ptkg3yrygu" +path="res://.godot/imported/watchtower.png-013d302290ae0862e961d32785a0c1e7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/watchtower.png" +dest_files=["res://.godot/imported/watchtower.png-013d302290ae0862e961d32785a0c1e7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/default_bus_layout.tres b/default_bus_layout.tres new file mode 100644 index 0000000..62a76ca --- /dev/null +++ b/default_bus_layout.tres @@ -0,0 +1,3 @@ +[gd_resource type="AudioBusLayout" format=3 uid="uid://cqg1rj8bwyb5t"] + +[resource] diff --git a/examples_dd3d/DebugDrawDemoScene.gd b/examples_dd3d/DebugDrawDemoScene.gd new file mode 100644 index 0000000..a9e7171 --- /dev/null +++ b/examples_dd3d/DebugDrawDemoScene.gd @@ -0,0 +1,581 @@ +@tool +extends Node3D + +@export var custom_font : Font +@export var custom_3d_font : Font +@export var zylann_example := false +@export var update_in_physics := false +@export var test_text := true +@export var more_test_cases := true +@export var draw_3d_text := true +@export var draw_array_of_boxes := false +@export var draw_text_with_boxes := false +@export var draw_1m_boxes := false +@export_range(0, 5, 0.001) var debug_thickness := 0.1 +@export_range(0, 1, 0.001) var debug_center_brightness := 0.8 +@export_range(0, 1) var camera_frustum_scale := 0.9 + +@export_group("Text groups", "text_groups") +@export var text_groups_show_examples := true +@export var text_groups_show_hints := true +@export var text_groups_show_stats := false +@export var text_groups_show_stats_2d := false +@export var text_groups_position := DebugDraw2DConfig.POSITION_LEFT_TOP +@export var text_groups_offset := Vector2i(8, 8) +@export var text_groups_padding := Vector2i(3, 1) +@export_range(1, 100) var text_groups_default_font_size := 15 +@export_range(1, 100) var text_groups_title_font_size := 20 +@export_range(1, 100) var text_groups_text_font_size := 17 + +@export_group("Tests", "tests") +@export var tests_use_threads := false +var test_thread : Thread = null +var test_thread_closing := false + +var button_presses := {} +var frame_rendered := false +var physics_tick_processed := false + +var timer_1 := 0.0 +var timer_cubes := 0.0 +var timer_3 := 0.0 +var timer_text := 0.0 + + +func _process(delta) -> void: + #print("Label3Ds count: %d" % get_child(0).get_child_count() if Engine.is_editor_hint() else get_tree().root.get_child(0).get_child_count()) + + $OtherWorld.mesh.material.set_shader_parameter("albedo_texture", $OtherWorld/SubViewport.get_texture()) + + physics_tick_processed = false + if not update_in_physics: + main_update(delta) + _update_timers(delta) + + _call_from_thread() + + +## Since physics frames may not be called every frame or may be called multiple times in one frame, +## there is an additional check to ensure that a new frame has been drawn before updating the data. +func _physics_process(delta: float) -> void: + if not physics_tick_processed: + physics_tick_processed = true + if update_in_physics: + main_update(delta) + _update_timers(delta) + + # Physics specific: + if not zylann_example: + DebugDraw3D.draw_line($"Lines/8".global_position, $Lines/Target.global_position, Color.YELLOW) + + if more_test_cases: + _draw_rays_casts() + + ## Additional drawing in the Viewport + if true: + var _w1 = DebugDraw3D.new_scoped_config().set_viewport(%OtherWorldBox.get_viewport()).set_thickness(0.01).set_center_brightness(1).set_no_depth_test(true) + DebugDraw3D.draw_box_xf(Transform3D(Basis() + .scaled(Vector3.ONE*0.3) + .rotated(Vector3(0,0,1), PI/4) + .rotated(Vector3(0,1,0), wrapf(Time.get_ticks_msec() / -1500.0, 0, TAU) - PI/4), %OtherWorldBox.global_transform.origin), + Color.BROWN, true, 0.4) + + +func main_update(delta: float) -> void: + DebugDraw3D.scoped_config().set_thickness(debug_thickness).set_center_brightness(debug_center_brightness) + + _update_keys_just_press() + + if _is_key_just_pressed(KEY_F1): + zylann_example = !zylann_example + + # Zylann's example :D + if zylann_example: + var _time = Time.get_ticks_msec() / 1000.0 + var box_pos = Vector3(0, sin(_time * 4), 0) + var line_begin = Vector3(-1, sin(_time * 4), 0) + var line_end = Vector3(1, cos(_time * 4), 0) + + DebugDraw3D.draw_box(box_pos, Quaternion.IDENTITY, Vector3(1, 2, 1), Color(0, 1, 0)) + DebugDraw3D.draw_line(line_begin, line_end, Color(1, 1, 0)) + DebugDraw2D.set_text("Time", _time) + DebugDraw2D.set_text("Frames drawn", Engine.get_frames_drawn()) + DebugDraw2D.set_text("FPS", Engine.get_frames_per_second()) + DebugDraw2D.set_text("delta", delta) + + $HitTest.visible = false + $LagTest.visible = false + $PlaneOrigin.visible = false + $OtherWorld.visible = false + %ZDepthTestCube.visible = false + return + + $HitTest.visible = true + $LagTest.visible = true + $PlaneOrigin.visible = true + $OtherWorld.visible = true + %ZDepthTestCube.visible = true + + # Testing the rendering layers by showing the image from the second camera inside the 2D panel + DebugDraw3D.config.geometry_render_layers = 1 if not Input.is_key_pressed(KEY_ALT) else 0b10010 + $Panel.visible = Input.is_key_pressed(KEY_ALT) + DebugDraw2D.custom_canvas = %CustomCanvas if Input.is_key_pressed(KEY_ALT) else null + + # More property toggles + DebugDraw3D.config.freeze_3d_render = Input.is_key_pressed(KEY_DOWN) + DebugDraw3D.config.visible_instance_bounds = Input.is_key_pressed(KEY_RIGHT) + + # Regenerate meshes + if Input.is_action_just_pressed("ui_end"): + DebugDraw3D.regenerate_geometry_meshes() + + # Some property toggles + if _is_key_just_pressed(KEY_LEFT): + DebugDraw3D.config.use_frustum_culling = !DebugDraw3D.config.use_frustum_culling + if _is_key_just_pressed(KEY_UP): + DebugDraw3D.config.force_use_camera_from_scene = !DebugDraw3D.config.force_use_camera_from_scene + if _is_key_just_pressed(KEY_CTRL): + if not Engine.is_editor_hint(): + get_viewport().msaa_3d = Viewport.MSAA_DISABLED if get_viewport().msaa_3d == Viewport.MSAA_4X else Viewport.MSAA_4X + + if not Engine.is_editor_hint(): + if _is_key_just_pressed(KEY_1): + DebugDraw3D.debug_enabled = !DebugDraw3D.debug_enabled + if _is_key_just_pressed(KEY_2): + DebugDraw2D.debug_enabled = !DebugDraw2D.debug_enabled + if _is_key_just_pressed(KEY_3): + DebugDrawManager.debug_enabled = !DebugDrawManager.debug_enabled + + + DebugDraw3D.config.frustum_length_scale = camera_frustum_scale + + # Zones with black borders + for z in $Zones.get_children(): + DebugDraw3D.draw_box_xf(z.global_transform, Color.BLACK) + + # Spheres + _draw_zone_title(%SpheresBox, "Spheres") + + DebugDraw3D.draw_sphere_xf($Spheres/SphereTransform.global_transform, Color.CRIMSON) + if true: + var _shd = DebugDraw3D.new_scoped_config().set_hd_sphere(true) + DebugDraw3D.draw_sphere_xf($Spheres/SphereHDTransform.global_transform, Color.ORANGE_RED) + + ## Delayed spheres + if timer_1 < 0: + DebugDraw3D.draw_sphere($Spheres/SpherePosition.global_position, 2.0, Color.BLUE_VIOLET, 2.0) + var _shd = DebugDraw3D.new_scoped_config().set_hd_sphere(true) + DebugDraw3D.draw_sphere($Spheres/SpherePosition.global_position + Vector3.FORWARD * 4, 2.0, Color.CORNFLOWER_BLUE, 2.0) + timer_1 = 2 + + # Cylinders + _draw_zone_title(%CylindersBox, "Cylinders") + + DebugDraw3D.draw_cylinder($Cylinders/Cylinder1.global_transform, Color.CRIMSON) + DebugDraw3D.draw_cylinder(Transform3D(Basis.IDENTITY.scaled(Vector3(1,2,1)), $Cylinders/Cylinder2.global_position), Color.RED) + DebugDraw3D.draw_cylinder_ab($"Cylinders/Cylinder3/1".global_position, $"Cylinders/Cylinder3/2".global_position, 0.7) + + # Boxes + _draw_zone_title(%BoxesBox, "Boxes") + + DebugDraw3D.draw_box_xf($Boxes/Box1.global_transform, Color.MEDIUM_PURPLE) + DebugDraw3D.draw_box($Boxes/Box2.global_position, Quaternion.from_euler(Vector3(0, deg_to_rad(45), deg_to_rad(45))), Vector3.ONE, Color.REBECCA_PURPLE) + DebugDraw3D.draw_box_xf(Transform3D(Basis(Vector3.UP, PI * 0.25).scaled(Vector3.ONE * 2), $Boxes/Box3.global_position), Color.ROSY_BROWN) + + DebugDraw3D.draw_aabb(AABB($Boxes/AABB_fixed.global_position, Vector3(2, 1, 2)), Color.AQUA) + DebugDraw3D.draw_aabb_ab($Boxes/AABB/a.global_position, $Boxes/AABB/b.global_position, Color.DEEP_PINK) + + # Boxes AB + DebugDraw3D.draw_arrow($Boxes/BoxAB.global_position, $Boxes/BoxAB/o/up.global_position, Color.GOLD, 0.1, true) + DebugDraw3D.draw_box_ab($Boxes/BoxAB/a.global_position, $Boxes/BoxAB/b.global_position, $Boxes/BoxAB/o/up.global_position - $Boxes/BoxAB.global_position, Color.PERU) + + DebugDraw3D.draw_arrow($Boxes/BoxABEdge.global_position, $Boxes/BoxABEdge/o/up.global_position, Color.DARK_RED, 0.1, true) + DebugDraw3D.draw_box_ab($Boxes/BoxABEdge/a.global_position, $Boxes/BoxABEdge/b.global_position, $Boxes/BoxABEdge/o/up.global_position - $Boxes/BoxABEdge.global_position, Color.DARK_OLIVE_GREEN, false) + + # Lines + _draw_zone_title(%LinesBox, "Lines") + + var target = $Lines/Target + DebugDraw3D.draw_square(target.global_position, 0.5, Color.RED) + + DebugDraw3D.draw_line($"Lines/1".global_position, target.global_position, Color.FUCHSIA) + DebugDraw3D.draw_ray($"Lines/3".global_position, (target.global_position - $"Lines/3".global_position).normalized(), 3.0, Color.CRIMSON) + + if timer_3 < 0: + DebugDraw3D.draw_line($"Lines/6".global_position, target.global_position, Color.FUCHSIA, 2.0) + timer_3 = 2 + + # Test UP vector + DebugDraw3D.draw_line($"Lines/7".global_position, target.global_position, Color.RED) + + # Lines with Arrow + DebugDraw3D.draw_arrow($"Lines/2".global_position, target.global_position, Color.BLUE, 0.5, true) + DebugDraw3D.draw_arrow_ray($"Lines/4".global_position, (target.global_position - $"Lines/4".global_position).normalized(), 8.0, Color.LAVENDER, 0.5, true) + + DebugDraw3D.draw_line_hit_offset($"Lines/5".global_position, target.global_position, true, abs(sin(Time.get_ticks_msec() / 1000.0)), 0.25, Color.AQUA) + + # Paths + _draw_zone_title(%PathsBox, "Paths") + + ## preparing data + var points: PackedVector3Array = [] + var points_below: PackedVector3Array = [] + var points_below2: PackedVector3Array = [] + var points_below3: PackedVector3Array = [] + var points_below4: PackedVector3Array = [] + var lines_above: PackedVector3Array = [] + + for c in $LinePath.get_children(): + if not c is Node3D: + break + points.append(c.global_position) + points_below.append(c.global_position + Vector3.DOWN) + points_below2.append(c.global_position + Vector3.DOWN * 2) + points_below3.append(c.global_position + Vector3.DOWN * 3) + points_below4.append(c.global_position + Vector3.DOWN * 4) + + for x in points.size()-1: + lines_above.append(points[x] + Vector3.UP) + lines_above.append(points[x+1] + Vector3.UP) + + ## drawing lines + DebugDraw3D.draw_lines(lines_above) + DebugDraw3D.draw_line_path(points, Color.BEIGE) + DebugDraw3D.draw_points(points_below, DebugDraw3D.POINT_TYPE_SQUARE, 0.2, Color.DARK_GREEN) + DebugDraw3D.draw_point_path(points_below2, DebugDraw3D.POINT_TYPE_SQUARE, 0.25, Color.BLUE, Color.TOMATO) + DebugDraw3D.draw_arrow_path(points_below3, Color.GOLD, 0.5) + if true: + var _sl = DebugDraw3D.new_scoped_config().set_thickness(0.05) + DebugDraw3D.draw_point_path(points_below4, DebugDraw3D.POINT_TYPE_SPHERE, 0.25, Color.MEDIUM_SEA_GREEN, Color.MEDIUM_VIOLET_RED) + + # Misc + _draw_zone_title(%MiscBox, "Misc") + + if Engine.is_editor_hint(): + #for i in 1000: + var _a11 = DebugDraw3D.new_scoped_config().set_thickness(0) + DebugDraw3D.draw_camera_frustum($Camera, Color.DARK_ORANGE) + + if true: + var _s123 = DebugDraw3D.new_scoped_config().set_center_brightness(0.1) + DebugDraw3D.draw_arrowhead($Misc/Arrow.global_transform, Color.YELLOW_GREEN) + + DebugDraw3D.draw_square($Misc/Billboard.global_position, 0.5, Color.GREEN) + + DebugDraw3D.draw_position($Misc/Position.global_transform, Color.BROWN) + + DebugDraw3D.draw_gizmo($Misc/GizmoTransform.global_transform, DebugDraw3D.empty_color, true) + DebugDraw3D.draw_gizmo($Misc/GizmoOneColor.global_transform, Color.BROWN, true) + if true: + var _s123 = DebugDraw3D.new_scoped_config().set_center_brightness(0.5).set_no_depth_test(true) + DebugDraw3D.draw_gizmo($Misc/GizmoNormal.global_transform.orthonormalized(), DebugDraw3D.empty_color, false) + + # Grids + _draw_zone_title_pos($Grids/GridCentered.global_position + Vector3(0, 1.5, 0), "Grids", 96, 36) + + var tg : Transform3D = $Grids/Grid.global_transform + var tn : Vector3 = $Grids/Grid/Subdivision.transform.origin + DebugDraw3D.draw_grid(tg.origin, tg.basis.x, tg.basis.z, Vector2i(int(tn.x*10), int(tn.z*10)), Color.LIGHT_CORAL, false) + + var tn1 = $Grids/GridCentered/Subdivision.transform.origin + DebugDraw3D.draw_grid_xf($Grids/GridCentered.global_transform, Vector2i(tn1.x*10, tn1.z*10)) + + if true: + var _s32 = DebugDraw3D.new_scoped_config().set_thickness(0.05) + DebugDraw3D.draw_box_xf($PostProcess.global_transform, Color.SEA_GREEN) + + # 2D + DebugDraw2D.config.text_default_size = text_groups_default_font_size + DebugDraw2D.config.text_block_offset = text_groups_offset + DebugDraw2D.config.text_block_position = text_groups_position + DebugDraw2D.config.text_padding = text_groups_padding + + DebugDraw2D.config.text_custom_font = custom_font + + if test_text: + _text_tests() + + # Lag Test + var lag_test_pos = $LagTest/RESET.get_animation("RESET").track_get_key_value(0,0) + _draw_zone_title_pos(lag_test_pos, "Lag test") + + $LagTest.position = lag_test_pos + Vector3(sin(Time.get_ticks_msec() / 100.0) * 2.5, 0, 0) + DebugDraw3D.draw_box($LagTest.global_position, Quaternion.IDENTITY, Vector3.ONE * 2.01, Color.CHOCOLATE, true) + + if more_test_cases: + for ray in $HitTest/RayEmitter.get_children(): + ray.set_physics_process_internal(true) + + _more_tests() + else: + for ray in $HitTest/RayEmitter.get_children(): + ray.set_physics_process_internal(false) + + _draw_other_world() + + if draw_array_of_boxes: + _draw_array_of_boxes() + + +func _text_tests(): + DebugDraw2D.set_text("FPS", "%.2f" % Engine.get_frames_per_second(), 0, Color.GOLD) + + if text_groups_show_examples: + if timer_text < 0: + DebugDraw2D.set_text("Some delayed text", "for 2.5s", -1, Color.BLACK, 2.5) # it's supposed to show text for 2.5 seconds + timer_text = 5 + + DebugDraw2D.begin_text_group("-- First Group --", 2, Color.LIME_GREEN, true, text_groups_title_font_size, text_groups_text_font_size) + DebugDraw2D.set_text("Simple text") + DebugDraw2D.set_text("Text", "Value", 0, Color.AQUAMARINE) + DebugDraw2D.set_text("Text out of order", null, -1, Color.SILVER) + DebugDraw2D.begin_text_group("-- Second Group --", 1, Color.BEIGE) + DebugDraw2D.set_text("Rendered frames", Engine.get_frames_drawn()) + DebugDraw2D.end_text_group() + + if text_groups_show_stats or text_groups_show_stats_2d: + DebugDraw2D.begin_text_group("-- Stats --", 3, Color.WHEAT) + + var render_stats := DebugDraw3D.get_render_stats() + if render_stats && text_groups_show_stats: + DebugDraw2D.set_text("Total", render_stats.total_geometry) + DebugDraw2D.set_text("Instances", render_stats.instances + render_stats.instances_physics, 1) + DebugDraw2D.set_text("Lines", render_stats.lines + render_stats.lines_physics, 2) + DebugDraw2D.set_text("Total Visible", render_stats.total_visible, 3) + DebugDraw2D.set_text("Visible Instances", render_stats.visible_instances, 4) + DebugDraw2D.set_text("Visible Lines", render_stats.visible_lines, 5) + + DebugDraw2D.set_text("---", null, 12) + + DebugDraw2D.set_text("Culling time", "%.2f ms" % (render_stats.total_time_culling_usec / 1000.0), 13) + DebugDraw2D.set_text("Filling instances buffer", "%.2f ms" % (render_stats.time_filling_buffers_instances_usec / 1000.0), 14) + DebugDraw2D.set_text("Filling lines buffer", "%.2f ms" % (render_stats.time_filling_buffers_lines_usec / 1000.0), 15) + DebugDraw2D.set_text("Filling time", "%.2f ms" % (render_stats.total_time_filling_buffers_usec / 1000.0), 16) + DebugDraw2D.set_text("Total time", "%.2f ms" % (render_stats.total_time_spent_usec / 1000.0), 17) + + DebugDraw2D.set_text("----", null, 32) + + DebugDraw2D.set_text("Total Label3D", render_stats.nodes_label3d_exists_total, 33) + DebugDraw2D.set_text("Visible Label3D", render_stats.nodes_label3d_visible + render_stats.nodes_label3d_visible_physics, 34) + + DebugDraw2D.set_text("-----", null, 48) + + DebugDraw2D.set_text("Created scoped configs", "%d" % render_stats.created_scoped_configs, 49) + + if text_groups_show_stats && text_groups_show_stats_2d: + DebugDraw2D.set_text("------", null, 64) + + var render_stats_2d := DebugDraw2D.get_render_stats() + if render_stats_2d && text_groups_show_stats_2d: + DebugDraw2D.set_text("Text groups", render_stats_2d.overlay_text_groups, 96) + DebugDraw2D.set_text("Text lines", render_stats_2d.overlay_text_lines, 97) + + DebugDraw2D.end_text_group() + + if text_groups_show_hints: + DebugDraw2D.begin_text_group("controls", 1024, Color.WHITE, false) + if not Engine.is_editor_hint(): + DebugDraw2D.set_text("WASD QE, LMB", "To move", 0) + DebugDraw2D.set_text("Alt: change render layers", DebugDraw3D.config.geometry_render_layers, 1) + if not OS.has_feature("web"): + DebugDraw2D.set_text("Ctrl: toggle anti-aliasing", "MSAA 4x" if get_viewport().msaa_3d == Viewport.MSAA_4X else "Disabled", 2) + DebugDraw2D.set_text("Down: freeze render", DebugDraw3D.config.freeze_3d_render, 3) + if Engine.is_editor_hint(): + DebugDraw2D.set_text("Up: use scene camera", DebugDraw3D.config.force_use_camera_from_scene, 4) + DebugDraw2D.set_text("1,2,3: toggle debug", "%s, %s 😐, %s 😏" % [DebugDraw3D.debug_enabled, DebugDraw2D.debug_enabled, DebugDrawManager.debug_enabled], 5) + DebugDraw2D.set_text("Left: toggle frustum culling", DebugDraw3D.config.use_frustum_culling, 6) + DebugDraw2D.set_text("Right: draw bounds for culling", DebugDraw3D.config.visible_instance_bounds, 7) + DebugDraw2D.end_text_group() + + +func _draw_zone_title(node: Node3D, title: String): + if draw_3d_text: + var _s1 = DebugDraw3D.new_scoped_config().set_text_outline_size(72) + DebugDraw3D.draw_text(node.global_position + node.global_basis.y * 0.85, title, 128) + + +func _draw_zone_title_pos(pos: Vector3, title: String, font_size: int = 128, outline: int = 72): + if draw_3d_text: + var _s1 = DebugDraw3D.new_scoped_config().set_text_outline_size(outline) + DebugDraw3D.draw_text(pos, title, font_size) + + +func _draw_other_world(): + var _w1 = DebugDraw3D.new_scoped_config().set_viewport(%OtherWorldBox.get_viewport()) + DebugDraw3D.draw_box_xf(%OtherWorldBox.global_transform.rotated_local(Vector3(1,1,-1).normalized(), wrapf(Time.get_ticks_msec() / 1000.0, 0, TAU)), Color.SANDY_BROWN) + DebugDraw3D.draw_box_xf(%OtherWorldBox.global_transform.rotated_local(Vector3(-1,1,-1).normalized(), wrapf(Time.get_ticks_msec() / -1000.0, 0, TAU) - PI/4), Color.SANDY_BROWN) + + if draw_3d_text: + var angle = wrapf(Time.get_ticks_msec() / 1000.0, 0, TAU) + if true: + var _w2 = DebugDraw3D.new_scoped_config().set_text_font(custom_3d_font) + DebugDraw3D.draw_text(%OtherWorldBox.global_position + Vector3(cos(angle), -0.25, sin(angle)), "Hello world!", 32, Color.CRIMSON, 0) + + if true: + var _w3 = DebugDraw3D.new_scoped_config().set_no_depth_test(true).set_text_outline_color(Color.INDIAN_RED).set_text_outline_size(6) + DebugDraw3D.draw_text(%OtherWorldBox.global_position + Vector3(cos(angle), +0.25, sin(-angle)), "World without depth", 20, Color.PINK, 0) + + +func _draw_rays_casts(): + # Line hits render + _draw_zone_title_pos(%HitTestSphere.global_position, "Line hits", 96, 36) + + for ray in $HitTest/RayEmitter.get_children(): + if ray is RayCast3D: + ray.force_raycast_update() + DebugDraw3D.draw_line_hit(ray.global_position, ray.to_global(ray.target_position), ray.get_collision_point(), ray.is_colliding(), 0.3) + + +func _more_tests(): + # Delayed line render + if true: + var _a12 = DebugDraw3D.new_scoped_config().set_thickness(0.035) + DebugDraw3D.draw_line($LagTest.global_position + Vector3.UP, $LagTest.global_position + Vector3(0,3,sin(Time.get_ticks_msec() / 50.0)), DebugDraw3D.empty_color, 0.35) + + if draw_3d_text: + DebugDraw3D.draw_text($LagTest.global_position + Vector3(0,3,sin(Time.get_ticks_msec() / 50.0)), "%.1f" % sin(Time.get_ticks_msec() / 50.0), 16, DebugDraw3D.empty_color, 0.35) + + # Draw plane + if true: + var _s11 = DebugDraw3D.new_scoped_config().set_thickness(0.02).set_plane_size(10) + + var pl_node: Node3D = $PlaneOrigin + var xf: Transform3D = pl_node.global_transform + var normal: = xf.basis.y.normalized() + var plane = Plane(normal, xf.origin.dot(normal)) + + var vp: Viewport = get_viewport() + if Engine.is_editor_hint() and Engine.get_singleton(&"EditorInterface").get_editor_viewport_3d(0): + vp = Engine.get_singleton(&"EditorInterface").get_editor_viewport_3d(0) + + var cam = vp.get_camera_3d() + if cam: + var dir = vp.get_camera_3d().project_ray_normal(vp.get_mouse_position()) + var intersect = plane.intersects_ray(cam.global_position, dir) + + DebugDraw3D.draw_plane(plane, Color.CORAL * Color(1,1,1, 0.4), pl_node.global_position) + if intersect and intersect.distance_to(pl_node.global_position) < _s11.get_plane_size() * 0.5: + # Need to test different colors on both sides of the plane + var col = Color.FIREBRICK if plane.is_point_over(cam.global_position) else Color.AQUAMARINE + DebugDraw3D.draw_sphere(intersect, 0.3, col) + + +func _draw_array_of_boxes(): + # Lots of boxes to check performance.. + var x_size := 50 + var y_size := 50 + var z_size := 3 + var mul := 1 + var cubes_max_time := 1.25 + var show_text := draw_text_with_boxes + var cfg = DebugDraw3D.new_scoped_config() + + if draw_1m_boxes: + x_size = 100 + y_size = 100 + z_size = 100 + mul = 4 + cubes_max_time = 60 + show_text = false + + var size := Vector3.ONE + var half_size := size * 0.5 + + if timer_cubes < 0: + var _start_time = Time.get_ticks_usec() + for x in x_size: + for y in y_size: + for z in z_size: + cfg.set_thickness(randf_range(0, 0.1)) + var pos := Vector3(x * mul, (-4-z) * mul, y * mul) + global_position + DebugDraw3D.draw_box(pos, Quaternion.IDENTITY, size, DebugDraw3D.empty_color, false, cubes_max_time) + + if show_text and z == 0: + DebugDraw3D.draw_text(pos + half_size, str(pos), 32, DebugDraw3D.empty_color, cubes_max_time) + #print("Draw Cubes: %.3fms" % ((Time.get_ticks_usec() - _start_time) / 1000.0)) + timer_cubes = cubes_max_time + + +func _ready() -> void: + _update_keys_just_press() + + await get_tree().process_frame + + # this check is required for inherited scenes, because an instance of this + # script is created first, and then overridden by another + if not is_inside_tree(): + return + + DebugDraw2D.config.text_background_color = Color(0.3, 0.3, 0.3, 0.8) + + +func _is_key_just_pressed(key): + if (button_presses[key] == 1): + button_presses[key] = 2 + return true + return false + + +func _update_keys_just_press(): + var set_key = func (k: Key): + if Input.is_key_pressed(k) and button_presses.has(k): + if button_presses[k] == 0: + return 1 + else: + return button_presses[k] + else: + return 0 + button_presses[KEY_LEFT] = set_key.call(KEY_LEFT) + button_presses[KEY_UP] = set_key.call(KEY_UP) + button_presses[KEY_CTRL] = set_key.call(KEY_CTRL) + button_presses[KEY_F1] = set_key.call(KEY_F1) + button_presses[KEY_1] = set_key.call(KEY_1) + button_presses[KEY_2] = set_key.call(KEY_2) + button_presses[KEY_3] = set_key.call(KEY_3) + + +func _update_timers(delta : float): + timer_1 -= delta + timer_cubes -= delta + timer_3 -= delta + timer_text -= delta + + +func _notification(what: int) -> void: + if what == NOTIFICATION_EDITOR_PRE_SAVE or what == NOTIFICATION_EXIT_TREE: + _thread_stop() + + +func _call_from_thread(): + if tests_use_threads and (not test_thread or not test_thread.is_alive()): + test_thread_closing = false + test_thread = Thread.new() + test_thread.start(_thread_body) + elif not tests_use_threads and (test_thread and test_thread.is_alive()): + _thread_stop() + + +func _thread_stop(): + if test_thread and test_thread.is_alive(): + tests_use_threads = false + test_thread_closing = true + test_thread.wait_to_finish() + + +func _thread_body(): + print("Thread started!") + while not test_thread_closing: + DebugDraw3D.draw_box(Vector3(0,-1,0), Quaternion.IDENTITY, Vector3.ONE, Color.BROWN, true, 0.016) + + var boxes = 10 + for y in boxes: + var offset := sin(TAU/boxes * y + wrapf(Time.get_ticks_msec() / 100.0, 0, TAU)) + var pos := Vector3(offset, y, 0) + DebugDraw3D.draw_box(pos, Quaternion.IDENTITY, Vector3.ONE, Color.GREEN_YELLOW, true, 0.016) + DebugDraw3D.draw_text(pos, str(y), 64, Color.WHITE , 0.016) + + if y == 0: + DebugDraw2D.set_text("thread. sin", offset) + + OS.delay_msec(16) + print("Thread finished!") diff --git a/examples_dd3d/DebugDrawDemoScene.gd.uid b/examples_dd3d/DebugDrawDemoScene.gd.uid new file mode 100644 index 0000000..39b5273 --- /dev/null +++ b/examples_dd3d/DebugDrawDemoScene.gd.uid @@ -0,0 +1 @@ +uid://ba2ie81p2x3x7 diff --git a/examples_dd3d/DebugDrawDemoScene.tscn b/examples_dd3d/DebugDrawDemoScene.tscn new file mode 100644 index 0000000..f7ccb1b --- /dev/null +++ b/examples_dd3d/DebugDrawDemoScene.tscn @@ -0,0 +1,979 @@ +[gd_scene load_steps=41 format=3 uid="uid://c3sccy6x0ht5j"] + +[ext_resource type="Script" uid="uid://ba2ie81p2x3x7" path="res://examples_dd3d/DebugDrawDemoScene.gd" id="1"] +[ext_resource type="FontFile" uid="uid://erdgllynwqkw" path="res://examples_dd3d/Roboto-Bold.ttf" id="2_aedbq"] +[ext_resource type="Script" uid="uid://b5mdrjubj0lg5" path="res://examples_dd3d/demo_camera_movement.gd" id="3_3m1mp"] +[ext_resource type="FontFile" uid="uid://7am1h57ldd6" path="res://examples_dd3d/PixelatedElegance.ttf" id="3_tkhi8"] +[ext_resource type="Script" uid="uid://bebbekatkxaoe" path="res://examples_dd3d/demo_music_visualizer.gd" id="4_eq2lt"] +[ext_resource type="Script" uid="uid://83dhsep7l725" path="res://examples_dd3d/demo_settings_panel.gd" id="5_31v5h"] +[ext_resource type="Script" uid="uid://hvx3t70syvkm" path="res://examples_dd3d/demo_web_docs_version_select.gd" id="6_07f7q"] + +[sub_resource type="Animation" id="Animation_ucqh5"] +resource_name = "RESET" +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("..:tests_use_threads") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_cq37i"] +_data = { +&"RESET": SubResource("Animation_ucqh5") +} + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_87638"] +sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) +ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) + +[sub_resource type="Sky" id="Sky_4jfme"] +sky_material = SubResource("ProceduralSkyMaterial_87638") + +[sub_resource type="Environment" id="Environment_38m85"] +sky = SubResource("Sky_4jfme") +tonemap_mode = 2 +fog_light_energy = 0.41 +fog_density = 0.0757 +fog_height = 0.5 +fog_height_density = 4.6102 + +[sub_resource type="Animation" id="9"] +resource_name = "New Anim" +length = 1.5 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Spatial2:transform") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.7), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 1, 1), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0.31558, 1)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Spatial5:transform") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1, 1), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1.5801, 1)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Spatial4:transform") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.443643, 0, 1.53767), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.443643, -0.791383, 1.53767)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Spatial7:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0.4, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(1.33, -0.119, -0.025), Vector3(1.32989, -0.583818, -0.025198)] +} + +[sub_resource type="Animation" id="10"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Spatial2:transform") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 1, 1)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Spatial5:transform") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1, 1)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Spatial4:transform") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.443643, 0, 1.53767)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Spatial7:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(1.32989, -0.583818, -0.025198)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_nj4nv"] +_data = { +&"New Anim": SubResource("9"), +&"RESET": SubResource("10") +} + +[sub_resource type="Shader" id="Shader_621vv"] +code = "shader_type spatial; +render_mode unshaded; + +uniform sampler2D albedo_texture : source_color; + +void fragment() { + ALBEDO = texture(albedo_texture,UV).rgb; +} +" + +[sub_resource type="ViewportTexture" id="ViewportTexture_wsp8h"] +viewport_path = NodePath("OtherWorld/SubViewport") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_ho0aq"] +render_priority = 0 +shader = SubResource("Shader_621vv") +shader_parameter/albedo_texture = SubResource("ViewportTexture_wsp8h") + +[sub_resource type="PlaneMesh" id="PlaneMesh_c6mie"] +material = SubResource("ShaderMaterial_ho0aq") +size = Vector2(4, 4) + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_tigpa"] +radius = 0.395 +height = 1.825 + +[sub_resource type="BoxMesh" id="BoxMesh_b14rm"] + +[sub_resource type="SphereShape3D" id="4"] +radius = 1.0 + +[sub_resource type="StandardMaterial3D" id="5"] +transparency = 1 +albedo_color = Color(0.54902, 0.54902, 0.729412, 0.403922) +emission_enabled = true +emission = Color(0.752941, 0.741176, 0.862745, 1) + +[sub_resource type="Animation" id="6"] +resource_name = "New Anim" +length = 3.0 +loop_mode = 1 +tracks/0/type = "rotation_3d" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("RayEmitter") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = PackedFloat32Array(0, 1, 0, 0, 0, 1, 1.3, 1, 1.31237e-06, -9.55543e-07, -2.2333e-06, 1, 2.3, 1, -0.158418, 0.0315871, 0.980558, -0.111409) +tracks/1/type = "position_3d" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("RayEmitter") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = PackedFloat32Array(0, 1, -1.03574, 2.47907, -0.819963, 0.5, 1, 0.914907, 1.78507, -0.103575, 1.3, 1, 0.00863326, 2.47907, -0.595551, 2.3, 1, 1.00051, 1.4046, 1.02585) + +[sub_resource type="Animation" id="7"] +length = 0.001 +tracks/0/type = "position_3d" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("RayEmitter") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = PackedFloat32Array(0, 1, -1.03574, 2.47907, -0.819963) +tracks/1/type = "rotation_3d" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("RayEmitter") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = PackedFloat32Array(0, 1, 0, 0, 0, 1) + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_vh8ml"] +_data = { +&"New Anim": SubResource("6"), +&"RESET": SubResource("7") +} + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_rbfyn"] +transparency = 1 +cull_mode = 2 +shading_mode = 0 +albedo_color = Color(0.215686, 0.215686, 0.215686, 0.764706) + +[sub_resource type="QuadMesh" id="QuadMesh_1t0id"] +material = SubResource("StandardMaterial3D_rbfyn") +orientation = 1 + +[sub_resource type="StandardMaterial3D" id="1"] +shading_mode = 0 +albedo_color = Color(0.533333, 0.105882, 0.105882, 1) + +[sub_resource type="Animation" id="8"] +resource_name = "RESET" +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(7, -2, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_a7f1a"] +_data = { +&"RESET": SubResource("8") +} + +[sub_resource type="Shader" id="Shader_3cmiq"] +code = "shader_type spatial; +render_mode unshaded; + +uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest; + +void fragment() { + vec4 col = texture(screen_texture, SCREEN_UV); + ALBEDO = col.brg; + ALPHA = col.a; +} +" + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_t3isk"] +render_priority = 0 +shader = SubResource("Shader_3cmiq") + +[sub_resource type="BoxMesh" id="BoxMesh_0xv07"] +material = SubResource("ShaderMaterial_t3isk") + +[sub_resource type="Gradient" id="Gradient_tup4c"] +offsets = PackedFloat32Array(0.00471698, 0.316038, 0.646226, 1) +colors = PackedColorArray(0, 0.0156863, 1, 1, 0.0988327, 1, 0.122977, 1, 1, 0.111986, 0.118936, 1, 0, 0.0156863, 1, 1) + +[sub_resource type="Animation" id="Animation_n750a"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../MusicPlayer:stream") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [null] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_0ity1"] +_data = { +&"RESET": SubResource("Animation_n750a") +} + +[sub_resource type="Theme" id="3"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_oj5gf"] +content_margin_top = 5.0 +content_margin_bottom = 7.0 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_boyhr"] +content_margin_left = 5.0 +content_margin_top = 5.0 +content_margin_right = 5.0 +content_margin_bottom = 5.0 +bg_color = Color(0.0705882, 0.0705882, 0.0705882, 0.784314) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[node name="DebugDrawDemoScene" type="Node3D"] +process_priority = 1 +script = ExtResource("1") +custom_font = ExtResource("2_aedbq") +custom_3d_font = ExtResource("3_tkhi8") +text_groups_position = 2 + +[node name="RESET" type="AnimationPlayer" parent="."] +root_node = NodePath("../OtherWorld") +libraries = { +&"": SubResource("AnimationLibrary_cq37i") +} + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) +visible = false +directional_shadow_max_distance = 200.0 + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_38m85") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.953191, 0.30237, 0, -0.30237, 0.953191, -6.988, 10.986, 29.2059) +cull_mask = 1 +current = true +fov = 53.0 +far = 100.0 +script = ExtResource("3_3m1mp") + +[node name="Panel" type="PanelContainer" parent="."] +visible = false +custom_minimum_size = Vector2(300, 300) +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_top = -300.0 +offset_right = 300.0 +grow_vertical = 0 + +[node name="ViewportContainer" type="SubViewportContainer" parent="Panel"] +layout_mode = 2 + +[node name="Viewport" type="SubViewport" parent="Panel/ViewportContainer"] +handle_input_locally = false +size = Vector2i(300, 300) +render_target_update_mode = 0 + +[node name="CameraLayer2_5" type="Camera3D" parent="Panel/ViewportContainer/Viewport"] +transform = Transform3D(1, 0, 0, 0, 0.34202, 0.939693, 0, -0.939693, 0.34202, -3.988, 39.474, 14.053) +cull_mask = 2 +current = true +fov = 38.8 +near = 2.63 +far = 52.5 + +[node name="Zones" type="Node3D" parent="."] + +[node name="SpheresBox" type="Node3D" parent="Zones"] +unique_name_in_owner = true +transform = Transform3D(8.3761, 0, 0, 0, 4.89771, 0, 0, 0, 9.36556, -11.1864, 0.645876, -7.86506) + +[node name="CylindersBox" type="Node3D" parent="Zones"] +unique_name_in_owner = true +transform = Transform3D(9.78549, 0, 0, 0, 4.20302, 0, 0, 0, 5.62455, -23.6827, -0.015712, -6.19233) + +[node name="BoxesBox" type="Node3D" parent="Zones"] +unique_name_in_owner = true +transform = Transform3D(10.0513, 0, 0, 0, 5.99877, 0, 0, 0, 12.1174, -16.0257, -0.206735, 6.27643) + +[node name="LinesBox" type="Node3D" parent="Zones"] +unique_name_in_owner = true +transform = Transform3D(10.7186, 0, 0, 0, 3.9777, 0, 0, 0, 7.05487, 10.6302, 1.91174, -7.11416) + +[node name="PathsBox" type="Node3D" parent="Zones"] +unique_name_in_owner = true +transform = Transform3D(5.95153, 0, 0, 0, 7.71864, 0, 0, 0, 6.31617, 0.184938, 1.12881, -7.18731) + +[node name="MiscBox" type="Node3D" parent="Zones"] +unique_name_in_owner = true +transform = Transform3D(4.38886, 0, 0, 0, 2.72083, 0, 0, 0, 7.17107, -5.69728, -0.206735, 4.4244) + +[node name="LinesAnim" type="AnimationPlayer" parent="."] +root_node = NodePath("../LinePath") +libraries = { +&"": SubResource("AnimationLibrary_nj4nv") +} +autoplay = "New Anim" + +[node name="LinePath" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.0543, -8) + +[node name="Spatial" type="Node3D" parent="LinePath"] + +[node name="Spatial2" type="Node3D" parent="LinePath"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 1, 1) + +[node name="Spatial3" type="Node3D" parent="LinePath"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.462435, 0, 3) + +[node name="Spatial4" type="Node3D" parent="LinePath"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.443643, 0, 1.53767) + +[node name="Spatial5" type="Node3D" parent="LinePath"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1, 1) + +[node name="Spatial6" type="Node3D" parent="LinePath"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, -1) + +[node name="Spatial7" type="Node3D" parent="LinePath"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.32989, -0.583818, -0.025198) + +[node name="Cylinders" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -23.5266, 4.76837e-07, -5.82213) + +[node name="Cylinder1" type="Node3D" parent="Cylinders"] +transform = Transform3D(1.20775, 0.591481, -3.4521e-07, 0.554162, -1.12986, 0.858242, 0.208031, -0.424147, -2.28622, -3.03832, 0, -0.377882) + +[node name="Cylinder2" type="Node3D" parent="Cylinders"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.234978, -0.4237, 0.332998) + +[node name="Cylinder3" type="Node3D" parent="Cylinders"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.35527, -0.655492, -0.352802) + +[node name="1" type="Node3D" parent="Cylinders/Cylinder3"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.419773, -2.38419e-07, -1.40591) + +[node name="2" type="Node3D" parent="Cylinders/Cylinder3"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.01018, 0.486778, 1.32635) + +[node name="Spheres" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.1201, 0.166728, -7.893) + +[node name="SphereTransform" type="Node3D" parent="Spheres"] +transform = Transform3D(3.018, 0, 0, 0, 0.945452, -3.30182, 0, 1.04515, 2.98686, -2.14465, 4.76837e-07, 2.11952) + +[node name="SphereHDTransform" type="Node3D" parent="Spheres"] +transform = Transform3D(1.26984, 1.16629, -2.42095, 0.098772, 0.80937, 4.21576, -2.65493, 0.587941, -1.00109, -2.13175, 4.76837e-07, -2.62531) + +[node name="SpherePosition" type="Node3D" parent="Spheres"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.76745, 0.458486, 1.95921) + +[node name="Boxes" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.2493, 0, 6.42043) + +[node name="Box1" type="Node3D" parent="Boxes"] +transform = Transform3D(2.90583, -0.000527017, -5.34615, 0.00469241, 3.92788, 0.0141019, 0.556318, -0.0303774, 1.91619, -0.961557, 0, -3.78672) +rotation_edit_mode = 2 + +[node name="Box2" type="Node3D" parent="Boxes"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.531922, -1.34723, 1.44924) + +[node name="Box3" type="Node3D" parent="Boxes"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.34837, -1.08298, 4.36414) + +[node name="AABB_fixed" type="Node3D" parent="Boxes"] +transform = Transform3D(0.834492, 0, -0.551019, 0, 1, 0, 0.55102, 0, 0.834493, -3.71325, -1.03995, 0.470324) + +[node name="AABB" type="Node3D" parent="Boxes"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.99963, -0.869998, 0.205034) + +[node name="a" type="Node3D" parent="Boxes/AABB"] +transform = Transform3D(0.864099, 0.258702, 0.431747, -1.49012e-08, 0.857796, -0.51399, -0.503322, 0.444139, 0.741221, 1.48526, -1.45318, 1.96619) + +[node name="b" type="Node3D" parent="Boxes/AABB"] +transform = Transform3D(0.864099, 0.258702, 0.431747, -1.49012e-08, 0.857796, -0.51399, -0.503322, 0.444139, 0.741221, -1.24128, 1.47773, -2.13102) + +[node name="BoxAB" type="Node3D" parent="Boxes"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.66169, -2.2624, 4.04042) + +[node name="a" type="Node3D" parent="Boxes/BoxAB"] +transform = Transform3D(0.864099, 0.258702, 0.431747, -1.49012e-08, 0.857796, -0.51399, -0.503322, 0.444139, 0.741221, 0.556136, -0.666145, 0.951601) + +[node name="b" type="Node3D" parent="Boxes/BoxAB"] +transform = Transform3D(0.864099, 0.258702, 0.431747, -1.49012e-08, 0.857796, -0.51399, -0.503322, 0.444139, 0.741221, -0.548804, 0.715255, -0.942184) + +[node name="o" type="Node3D" parent="Boxes/BoxAB"] +transform = Transform3D(0.826805, 0.360538, 0.431748, -0.102949, 0.851596, -0.51399, -0.552988, 0.380522, 0.741221, 0, 0, 0) +metadata/_edit_group_ = true + +[node name="up" type="Node3D" parent="Boxes/BoxAB/o"] +transform = Transform3D(1, -1.49012e-08, 0, -1.04308e-07, 1, 0, 0, 0, 1, 0, 0.553809, -0.331842) + +[node name="BoxABEdge" type="Node3D" parent="Boxes"] +transform = Transform3D(0.965926, -0.0669873, -0.25, 0, 0.965926, -0.258819, 0.258819, 0.25, 0.933013, 0.348115, -1.30239, 4.88007) + +[node name="a" type="Node3D" parent="Boxes/BoxABEdge"] +transform = Transform3D(0.241143, 0.650584, 0.720132, -0.123077, 0.756539, -0.642262, -0.962654, 0.066246, 0.262507, 0.384618, -0.635015, 0.0956135) + +[node name="b" type="Node3D" parent="Boxes/BoxABEdge"] +transform = Transform3D(0.241143, 0.650584, 0.720133, -0.123077, 0.756539, -0.642261, -0.962654, 0.0662459, 0.262507, -0.287622, 0.997905, -0.144578) + +[node name="o" type="Node3D" parent="Boxes/BoxABEdge"] +transform = Transform3D(1, 1.49012e-08, 2.98023e-08, 7.45058e-09, 1, -1.49012e-08, -1.49012e-08, -1.49012e-08, 1, 0, 0, 0) +metadata/_edit_group_ = true + +[node name="up" type="Node3D" parent="Boxes/BoxABEdge/o"] +transform = Transform3D(1, -7.45058e-09, 0, -7.45058e-09, 1, 0, 2.98023e-08, -1.49012e-08, 1, -9.53674e-07, 0.6, 0) + +[node name="OtherWorld" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.53219, -2.5, 5.30229) +mesh = SubResource("PlaneMesh_c6mie") +skeleton = NodePath("") + +[node name="RESET" type="AnimationPlayer" parent="OtherWorld"] +libraries = { +&"": SubResource("AnimationLibrary_cq37i") +} + +[node name="SubViewport" type="SubViewport" parent="OtherWorld"] +own_world_3d = true +handle_input_locally = false +render_target_update_mode = 4 + +[node name="SubViewportContainer" type="SubViewportContainer" parent="OtherWorld/SubViewport"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +stretch = true + +[node name="SubViewport" type="SubViewport" parent="OtherWorld/SubViewport/SubViewportContainer"] +handle_input_locally = false +render_target_update_mode = 4 + +[node name="Camera3D" type="Camera3D" parent="OtherWorld/SubViewport/SubViewportContainer/SubViewport"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.57063, 0.6, 7.25557) +current = true +far = 5.0 + +[node name="MeshInstance3D" type="MeshInstance3D" parent="OtherWorld/SubViewport/SubViewportContainer/SubViewport"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.57063, 0.6, 5.72253) +mesh = SubResource("CapsuleMesh_tigpa") +skeleton = NodePath("../../..") + +[node name="OtherWorldBox" type="Node3D" parent="OtherWorld/SubViewport/SubViewportContainer/SubViewport"] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.57063, 0.6, 5.72253) + +[node name="Misc" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.68259, 0, 4.46741) + +[node name="Billboard" type="Node3D" parent="Misc"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.403353, -0.331599, 2.22542) + +[node name="Arrow" type="Node3D" parent="Misc"] +transform = Transform3D(0.802141, -0.286294, -0.524028, -0.539546, 0.0285125, -0.841473, 0.25585, 0.957718, -0.131597, -0.475607, -0.670307, 2.30581) + +[node name="Position" type="Node3D" parent="Misc"] +transform = Transform3D(1.51514, 0.589536, 1.00858, -1.34875, 0.662262, 1.133, 0, -0.462445, 2.90833, 0.853743, 0.0843356, -1.73676) + +[node name="GizmoNormal" type="Node3D" parent="Misc"] +transform = Transform3D(0.965926, 0, -0.258819, 0, 1, 0, 0.258819, 0, 0.965926, 0.890203, -0.306246, 0.356159) + +[node name="ZDepthTestCube" type="MeshInstance3D" parent="Misc/GizmoNormal"] +unique_name_in_owner = true +transform = Transform3D(0.591801, 0, 4.47035e-08, 0, 0.591801, 0, -4.47035e-08, 0, 0.591801, 0, 0, 0) +mesh = SubResource("BoxMesh_b14rm") + +[node name="GizmoTransform" type="Node3D" parent="Misc"] +transform = Transform3D(0.879881, 0.248446, -0.405072, -0.346604, 0.918688, -0.189411, 0.325077, 0.307059, 0.894449, -0.838587, -0.458, -0.176491) + +[node name="GizmoOneColor" type="Node3D" parent="Misc"] +transform = Transform3D(0.385568, 0.0415614, 0.921743, 0.082879, 0.993386, -0.0794599, -0.91895, 0.107031, 0.379573, -0.838587, -0.139425, -1.93055) + +[node name="HitTest" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.724359, -1.03227, 7.85404) + +[node name="StaticBody" type="StaticBody3D" parent="HitTest"] + +[node name="CollisionShape" type="CollisionShape3D" parent="HitTest/StaticBody"] +shape = SubResource("4") + +[node name="HitTestSphere" type="CSGSphere3D" parent="HitTest/StaticBody"] +unique_name_in_owner = true +radius = 1.0 +radial_segments = 16 +rings = 10 +material = SubResource("5") + +[node name="RayEmitter" type="Node3D" parent="HitTest"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.03574, 2.47907, -0.819963) + +[node name="RayCast" type="RayCast3D" parent="HitTest/RayEmitter"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.732104, 0, -0.814761) +enabled = false +target_position = Vector3(0, -3.464, 0) + +[node name="RayCast2" type="RayCast3D" parent="HitTest/RayEmitter"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.684873, 0, -0.791145) +enabled = false +target_position = Vector3(0, -3.464, 0) + +[node name="RayCast3" type="RayCast3D" parent="HitTest/RayEmitter"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.708488, 0, 0.543175) +enabled = false +target_position = Vector3(0, -3.464, 0) + +[node name="RayCast4" type="RayCast3D" parent="HitTest/RayEmitter"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.708489, 0, 0.566791) +enabled = false +target_position = Vector3(0, -3.464, 0) + +[node name="RayCast5" type="RayCast3D" parent="HitTest/RayEmitter"] +transform = Transform3D(0.974217, -0.225614, 0, 0.225614, 0.974217, 0, 0, 0, 1, -0.447564, 0, -0.259778) +enabled = false +target_position = Vector3(0, -3.464, 0) + +[node name="RayCast6" type="RayCast3D" parent="HitTest/RayEmitter"] +transform = Transform3D(0.935992, 0.352021, 0, -0.352021, 0.935992, 0, 0, 0, 1, 0.35227, -0.245904, -0.25849) +enabled = false +target_position = Vector3(0, -3.464, 0) + +[node name="RayEmitterAnimationPlayer" type="AnimationPlayer" parent="HitTest"] +unique_name_in_owner = true +libraries = { +&"": SubResource("AnimationLibrary_vh8ml") +} +autoplay = "New Anim" + +[node name="Grids" type="Node3D" parent="."] +transform = Transform3D(0.707106, 0, -0.707108, 0, 1, 0, 0.707108, 0, 0.707106, 0.730597, -2.5, 2.76274) + +[node name="GridCentered" type="Node3D" parent="Grids"] +transform = Transform3D(1.74492, 0.723785, -1.74493, -1.24976, -7.72562e-08, -1.24975, -1.74493, 0.723783, 1.74493, 1.74919, -0.0010004, 1.75466) +rotation_edit_mode = 2 + +[node name="Subdivision" type="Node3D" parent="Grids/GridCentered"] +transform = Transform3D(1, -6.03961e-14, -2.68221e-07, 3.55271e-13, 1, 1.42109e-14, -1.19209e-07, 1.1724e-13, 1, -0.2, 4.76837e-07, 0.4) + +[node name="Grid" type="Node3D" parent="Grids"] +transform = Transform3D(5, 0, 4.76837e-07, 0, 1, 0, -4.76837e-07, 0, 5, 0, 0, 0) + +[node name="Subdivision" type="Node3D" parent="Grids/Grid"] +transform = Transform3D(1, 0, -2.98023e-08, 0, 0.999999, 1.90735e-05, 0, 4.65661e-10, 0.999999, 1, 0, 1) + +[node name="PlaneOrigin" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 11.0482, 7.33669, -13.1715) +mesh = SubResource("QuadMesh_1t0id") + +[node name="Lines" type="Node3D" parent="."] +transform = Transform3D(1.51514, 0.589536, 1.00858, -1.34875, 0.662262, 1.133, 0, -0.462445, 2.90833, 10.2488, -0.331599, -10.3326) + +[node name="1" type="Node3D" parent="Lines"] +transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 9.40939e-07, 1, 0, -2.76085e-08, -1.49012e-08, 1, -1.46213, -4.03317, 0.61692) + +[node name="2" type="Node3D" parent="Lines"] +transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 9.40939e-07, 1, 0, -2.76085e-08, -1.49012e-08, 1, -1.01875, -1.79584, -0.163045) + +[node name="3" type="Node3D" parent="Lines"] +transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 6.87561e-07, 1, 0, -2.87275e-08, -1.49012e-08, 1, -0.1559, -0.407045, 0.0523388) + +[node name="4" type="Node3D" parent="Lines"] +transform = Transform3D(1, 6.61592e-09, 2.23038e-08, 4.9239e-07, 1, 0, -3.40677e-08, -1.49012e-08, 1, 1.18591, 1.8987, 0.301906) + +[node name="5" type="Node3D" parent="Lines"] +transform = Transform3D(-0.998871, -0.0207882, -0.0355643, 0.0855375, -0.5714, -2.68836, 0.0136011, -0.249864, 0.572532, 1.43126, 0.26242, 1.92347) + +[node name="6" type="Node3D" parent="Lines"] +transform = Transform3D(-0.998872, -0.0207882, -0.0355643, 0.085537, -0.5714, -2.68836, 0.0136012, -0.249864, 0.572533, 1.43441, 1.50606, 1.20028) + +[node name="7" type="Node3D" parent="Lines"] +transform = Transform3D(-0.998873, -0.0207882, -0.0355641, 0.0855357, -0.5714, -2.68836, 0.0136014, -0.249864, 0.572533, 0.0511096, -1.3236, 1.06745) + +[node name="8" type="Node3D" parent="Lines"] +transform = Transform3D(-0.998873, -0.0207882, -0.0355641, 0.0855353, -0.5714, -2.68836, 0.0136016, -0.249864, 0.572533, -1.01372, -3.80486, 1.25019) + +[node name="Target" type="Node3D" parent="Lines"] +transform = Transform3D(1, -2.7352e-06, 2.60722e-07, 4.10378e-06, 1, 0, -4.28605e-07, -1.49012e-08, 1, -0.69134, 0.176475, 1.30597) + +[node name="LagTest" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, -2, 0) +size = Vector3(2, 2, 2) +material = SubResource("1") + +[node name="RESET" type="AnimationPlayer" parent="LagTest"] +libraries = { +&"": SubResource("AnimationLibrary_a7f1a") +} + +[node name="PostProcess" type="MeshInstance3D" parent="."] +transform = Transform3D(-2.18557e-07, 0, 1.5, 0, 5, 0, -5, 0, -6.55671e-08, 16, 0, 0) +mesh = SubResource("BoxMesh_0xv07") +skeleton = NodePath("../Lines") + +[node name="MusicVisualizer" type="VBoxContainer" parent="."] +offset_left = 10.0 +offset_top = 10.0 +offset_right = 50.0 +offset_bottom = 50.0 +script = ExtResource("4_eq2lt") +colors = SubResource("Gradient_tup4c") + +[node name="OpenFile" type="Button" parent="MusicVisualizer"] +layout_mode = 2 +size_flags_horizontal = 0 +text = "Open music" + +[node name="RESET" type="AnimationPlayer" parent="MusicVisualizer"] +root_node = NodePath("../OpenFile") +libraries = { +&"": SubResource("AnimationLibrary_0ity1") +} + +[node name="MusicPlayer" type="AudioStreamPlayer" parent="MusicVisualizer"] +unique_name_in_owner = true +autoplay = true + +[node name="VBox" type="VBoxContainer" parent="MusicVisualizer"] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="MusicVisualizer/VBox"] +layout_mode = 2 + +[node name="VolumeSlider" type="HSlider" parent="MusicVisualizer/VBox/HBoxContainer"] +unique_name_in_owner = true +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 +max_value = 1.0 +step = 0.01 +value = 1.0 + +[node name="MuteMaster" type="CheckBox" parent="MusicVisualizer/VBox/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Mute" + +[node name="AudioVisualizer" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(0.2, 0, 0, 0, 5, 0, 0, 0, 0.2, -5.31036, -1.422, 14.14) + +[node name="CustomCanvas" type="Control" parent="."] +unique_name_in_owner = true +layout_mode = 3 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -545.0 +offset_top = 46.0 +offset_right = -37.0 +offset_bottom = 638.0 +grow_horizontal = 0 +mouse_filter = 2 +metadata/_edit_lock_ = true + +[node name="Settings" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme = SubResource("3") +script = ExtResource("5_31v5h") +switch_to_scene = "res://examples_dd3d/DebugDrawDemoSceneCS.tscn" +metadata/_edit_lock_ = true + +[node name="HBox" type="HBoxContainer" parent="Settings"] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -497.0 +offset_top = -372.0 +offset_right = -10.0006 +offset_bottom = -10.0 +grow_horizontal = 0 +grow_vertical = 0 + +[node name="VBoxContainer" type="VBoxContainer" parent="Settings/HBox"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 8 + +[node name="VersionBlock" type="HBoxContainer" parent="Settings/HBox/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +script = ExtResource("6_07f7q") + +[node name="Label" type="Label" parent="Settings/HBox/VBoxContainer/VersionBlock"] +layout_mode = 2 +size_flags_horizontal = 10 +theme_override_font_sizes/font_size = 13 +text = "Demo version:" + +[node name="OptionButton" type="OptionButton" parent="Settings/HBox/VBoxContainer/VersionBlock"] +layout_mode = 2 +size_flags_horizontal = 8 +theme_override_font_sizes/font_size = 13 +item_count = 1 +popup/item_0/text = "1.0.0" +popup/item_0/id = 0 + +[node name="Label" type="Label" parent="Settings/HBox/VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 8 +theme_override_styles/normal = SubResource("StyleBoxEmpty_oj5gf") +text = "GDScript example" +horizontal_alignment = 2 +metadata/_edit_use_anchors_ = true + +[node name="VBox" type="VBoxContainer" parent="Settings/HBox"] +layout_mode = 2 +alignment = 2 + +[node name="HideShowPanelButton" type="Button" parent="Settings/HBox/VBox"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_font_sizes/font_size = 13 +text = "Hide panel" + +[node name="SettingsPanel" type="PanelContainer" parent="Settings/HBox/VBox"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 8 +theme_override_styles/panel = SubResource("StyleBoxFlat_boyhr") + +[node name="VBox" type="VBoxContainer" parent="Settings/HBox/VBox/SettingsPanel"] +layout_mode = 2 +size_flags_horizontal = 3 +alignment = 2 + +[node name="Label" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.792157, 0.792157, 0.792157, 1) +text = "Common:" + +[node name="HBox3" type="HBoxContainer" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox3"] +layout_mode = 2 +text = "Thickness " + +[node name="ThicknessSlider" type="HSlider" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox3"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 +max_value = 0.5 +step = 0.001 +value = 0.05 + +[node name="HBox5" type="HBoxContainer" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox5"] +layout_mode = 2 +text = "Frustum Scale" + +[node name="FrustumScaleSlider" type="HSlider" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox5"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 +max_value = 1.0 +step = 0.001 +value = 0.5 + +[node name="UpdateInPhysics" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +unique_name_in_owner = true +layout_mode = 2 +text = "Update in physics (15 Ticks) *" + +[node name="Label4" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.792157, 0.792157, 0.792157, 1) +text = "Text:" + +[node name="ShowText" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +unique_name_in_owner = true +layout_mode = 2 +text = "Show text" + +[node name="ShowExamples" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +unique_name_in_owner = true +layout_mode = 2 +text = "Examples" + +[node name="ShowStats" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +unique_name_in_owner = true +layout_mode = 2 +text = "Debug stats" + +[node name="ShowHints" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +unique_name_in_owner = true +layout_mode = 2 +text = "Hints" + +[node name="Draw3DText" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +unique_name_in_owner = true +layout_mode = 2 +text = "3D Text" + +[node name="Label3" type="Label" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.792157, 0.792157, 0.792157, 1) +text = "Boxes:" + +[node name="HBox4" type="HBoxContainer" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +layout_mode = 2 + +[node name="DrawBoxes" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox4"] +unique_name_in_owner = true +layout_mode = 2 +text = "Draw an array of boxes" + +[node name="Draw1MBoxes" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox/HBox4"] +unique_name_in_owner = true +layout_mode = 2 +tooltip_text = "Draw 1 Million boxes, otherwise 7500pcs." +text = "1M" + +[node name="DrawBoxesAddText" type="CheckBox" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +unique_name_in_owner = true +layout_mode = 2 +text = "Add text to boxes" + +[node name="SwitchLang" type="Button" parent="Settings/HBox/VBox/SettingsPanel/VBox"] +unique_name_in_owner = true +layout_mode = 2 +text = "Switch to C#" + +[connection signal="pressed" from="MusicVisualizer/OpenFile" to="MusicVisualizer" method="_pressed"] +[connection signal="value_changed" from="MusicVisualizer/VBox/HBoxContainer/VolumeSlider" to="MusicVisualizer" method="_on_volume_slider_value_changed"] +[connection signal="toggled" from="MusicVisualizer/VBox/HBoxContainer/MuteMaster" to="MusicVisualizer" method="_on_mute_master_toggled"] +[connection signal="pressed" from="Settings/HBox/VBox/HideShowPanelButton" to="Settings" method="_on_hide_show_panel_pressed"] +[connection signal="value_changed" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox3/ThicknessSlider" to="Settings" method="_on_thickness_slider_value_changed"] +[connection signal="value_changed" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox5/FrustumScaleSlider" to="Settings" method="_on_frustum_scale_slider_value_changed"] +[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/UpdateInPhysics" to="Settings" method="_on_update_in_physics_toggled"] +[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/ShowText" to="Settings" method="_on_show_text_toggled"] +[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/ShowExamples" to="Settings" method="_on_show_examples_toggled"] +[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/ShowStats" to="Settings" method="_on_show_stats_toggled"] +[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/ShowHints" to="Settings" method="_on_show_hints_toggled"] +[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/Draw3DText" to="Settings" method="_on_draw_3d_text_toggled"] +[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox4/DrawBoxes" to="Settings" method="_on_draw_boxes_toggled"] +[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/HBox4/Draw1MBoxes" to="Settings" method="_on_draw_1m_boxes_toggled"] +[connection signal="toggled" from="Settings/HBox/VBox/SettingsPanel/VBox/DrawBoxesAddText" to="Settings" method="_on_add_text_to_boxes_toggled"] +[connection signal="pressed" from="Settings/HBox/VBox/SettingsPanel/VBox/SwitchLang" to="Settings" method="_on_Button_pressed"] diff --git a/examples_dd3d/DebugDrawDemoSceneCS.cs b/examples_dd3d/DebugDrawDemoSceneCS.cs new file mode 100644 index 0000000..af5115f --- /dev/null +++ b/examples_dd3d/DebugDrawDemoSceneCS.cs @@ -0,0 +1,797 @@ + +using Godot; +using System; +using System.Collections.Generic; + +[Tool] +public partial class DebugDrawDemoSceneCS : Node3D +{ + Random random = new Random(); + + [Export] Font custom_font; + [Export] Font custom_3d_font; + [Export] bool zylann_example = false; + [Export] bool update_in_physics = false; + [Export] bool test_text = true; + [Export] bool more_test_cases = true; + [Export] bool draw_3d_text = true; + [Export] bool draw_array_of_boxes = false; + [Export] bool draw_text_with_boxes = false; + [Export] bool draw_1m_boxes = false; + [Export(PropertyHint.Range, "0, 5, 0.001")] float debug_thickness = 0.1f; + [Export(PropertyHint.Range, "0, 1")] float camera_frustum_scale = 0.9f; + + [ExportGroup("Text groups", "text_groups")] + [Export] bool text_groups_show_examples = true; + [Export] bool text_groups_show_hints = true; + [Export] bool text_groups_show_stats = true; + [Export] bool text_groups_show_stats_2d = true; + [Export] DebugDraw2DConfig.BlockPosition text_groups_position = DebugDraw2DConfig.BlockPosition.LeftTop; + [Export] Vector2I text_groups_offset = new Vector2I(8, 8); + [Export] Vector2I text_groups_padding = new Vector2I(3, 1); + [Export(PropertyHint.Range, "1, 100")] int text_groups_default_font_size = 15; + [Export(PropertyHint.Range, "1, 100")] int text_groups_title_font_size = 20; + [Export(PropertyHint.Range, "1, 100")] int text_groups_text_font_size = 17; + + Dictionary button_presses = new Dictionary() { + { Key.Left, 0 }, + { Key.Up, 0 }, + { Key.Ctrl, 0 }, + { Key.F1, 0 }, + { Key.Key1, 0 }, + { Key.Key2, 0 }, + { Key.Key3, 0 }, + }; + + double timer_1 = 0.0; + double timer_cubes = 0.0; + double timer_3 = 0.0; + double timer_text = 0.0; + + public override async void _Ready() + { + _get_nodes(); + _update_keys_just_press(); + + await new SignalAwaiter(GetTree(), "process_frame", this); + + // this check is required for inherited scenes, because an instance of this + // script is created first, and then overridden by another + if (!IsInsideTree()) + return; + + DebugDraw2D.Config.TextBackgroundColor = new Color(0.3f, 0.3f, 0.3f, 0.8f); + } + + bool _is_key_just_pressed(Key key) + { + if (button_presses[key] == 1) + { + button_presses[key] = 2; + return true; + } + return false; + } + + void _update_timers(double delta) + { + timer_1 -= delta; + timer_cubes -= delta; + timer_3 -= delta; + timer_text -= delta; + } + + void _update_keys_just_press() + { + var set = (Key k) => Input.IsKeyPressed(k) ? (button_presses[k] == 0 ? 1 : button_presses[k]) : 0; + button_presses[Key.Left] = set(Key.Left); + button_presses[Key.Up] = set(Key.Up); + button_presses[Key.Ctrl] = set(Key.Ctrl); + button_presses[Key.F1] = set(Key.F1); + button_presses[Key.Key1] = set(Key.Key1); + button_presses[Key.Key2] = set(Key.Key2); + button_presses[Key.Key3] = set(Key.Key3); + } + + bool phys_frame_called = false; + public override void _Process(double delta) + { + ((ShaderMaterial)((PrimitiveMesh)dOtherWorld.Mesh).Material).SetShaderParameter("albedo_texture", dOtherWorldViewport.GetTexture()); + + phys_frame_called = false; + if (!update_in_physics) + { + MainUpdate(delta); + _update_timers(delta); + } + } + + public override void _PhysicsProcess(double delta) + { + if (!phys_frame_called) + { + phys_frame_called = true; + if (update_in_physics) + { + MainUpdate(delta); + _update_timers(delta); + } + } + + // Physics specific: + if (!zylann_example) + { + DebugDraw3D.DrawLine(dLines_8.GlobalPosition, dLines_Target.GlobalPosition, Colors.Yellow); + if (more_test_cases) + { + _draw_rays_casts(); + } + + // Additional drawing in the Viewport + using (var _w1 = DebugDraw3D.NewScopedConfig().SetViewport(dOtherWorldBox.GetViewport()).SetThickness(0.01f).SetCenterBrightness(1).SetNoDepthTest(true)) + { + DebugDraw3D.DrawBoxXf(new Transform3D(Basis.Identity + .Scaled(Vector3.One * 0.3f) + .Rotated(new Vector3(0, 0, 1), Mathf.Pi / 4) + .Rotated(new Vector3(0, 1, 0), Mathf.Wrap(Time.GetTicksMsec() / -1500.0f, 0, Mathf.Tau) - Mathf.Pi / 4), dOtherWorldBox.GlobalPosition), + Colors.Brown, true, 0.4f); + } + } + } + + void MainUpdate(double delta) + { + DebugDraw3D.ScopedConfig().SetThickness(debug_thickness); + + _update_keys_just_press(); + + if (_is_key_just_pressed(Key.F1)) + zylann_example = !zylann_example; + + // Zylann's example :D + if (zylann_example) + { + var _time = Time.GetTicksMsec() / 1000.0f; + var box_pos = new Vector3(0, Mathf.Sin(_time * 4f), 0); + var line_begin = new Vector3(-1, Mathf.Sin(_time * 4f), 0); + var line_end = new Vector3(1, Mathf.Cos(_time * 4f), 0); + DebugDraw3D.DrawBox(box_pos, Quaternion.Identity, new Vector3(1, 2, 1), new Color(0, 1, 0)); + DebugDraw3D.DrawLine(line_begin, line_end, new Color(1, 1, 0)); + DebugDraw2D.SetText("Time", _time); + DebugDraw2D.SetText("Frames drawn", Engine.GetFramesDrawn()); + DebugDraw2D.SetText("FPS", Engine.GetFramesPerSecond()); + DebugDraw2D.SetText("delta", delta); + + dHitTest.Visible = false; + dLagTest.Visible = false; + dPlaneOrigin.Visible = false; + pZDepthTestCube.Visible = false; + dOtherWorld.Visible = false; + return; + } + + dHitTest.Visible = true; + dLagTest.Visible = true; + dPlaneOrigin.Visible = true; + pZDepthTestCube.Visible = true; + dOtherWorld.Visible = true; + + // Testing the rendering layers by showing the image from the second camera inside the 2D panel + DebugDraw3D.Config.GeometryRenderLayers = !Input.IsKeyPressed(Key.Alt) ? 1 : 0b10010; + dPanel.Visible = Input.IsKeyPressed(Key.Alt); + DebugDraw2D.CustomCanvas = Input.IsKeyPressed(Key.Alt) ? dCustomCanvas : null; + + // More property toggles + DebugDraw3D.Config.Freeze3dRender = Input.IsKeyPressed(Key.Down); + DebugDraw3D.Config.VisibleInstanceBounds = Input.IsKeyPressed(Key.Right); + + // Regenerate meshes + if (Input.IsActionJustPressed("ui_end")) + DebugDraw3D.RegenerateGeometryMeshes(); + + // Some property toggles + if (_is_key_just_pressed(Key.Left)) + DebugDraw3D.Config.UseFrustumCulling = !DebugDraw3D.Config.UseFrustumCulling; + + if (_is_key_just_pressed(Key.Up)) + DebugDraw3D.Config.ForceUseCameraFromScene = !DebugDraw3D.Config.ForceUseCameraFromScene; + + if (_is_key_just_pressed(Key.Ctrl)) + if (!Engine.IsEditorHint()) + GetViewport().Msaa3D = GetViewport().Msaa3D == Viewport.Msaa.Msaa4X ? Viewport.Msaa.Disabled : Viewport.Msaa.Msaa4X; + + if (!Engine.IsEditorHint()) + { + if (_is_key_just_pressed(Key.Key1)) + DebugDraw3D.DebugEnabled = !DebugDraw3D.DebugEnabled; + if (_is_key_just_pressed(Key.Key2)) + DebugDraw2D.DebugEnabled = !DebugDraw2D.DebugEnabled; + if (_is_key_just_pressed(Key.Key3)) + DebugDrawManager.DebugEnabled = !DebugDrawManager.DebugEnabled; + } + + + DebugDraw3D.Config.FrustumLengthScale = camera_frustum_scale; + + // Zones with black borders + foreach (var node in dZones.GetChildren()) + { + if (node is Node3D z) + { + DebugDraw3D.DrawBoxXf(z.GlobalTransform, Colors.Black); + } + } + + // Spheres + _draw_zone_title(pSpheresBox, "Spheres"); + + DebugDraw3D.DrawSphereXf(dSphereTransform.GlobalTransform, Colors.Crimson); + using (var _s1 = DebugDraw3D.NewScopedConfig().SetHdSphere(true)) + DebugDraw3D.DrawSphereXf(dSphereHDTransform.GlobalTransform, Colors.OrangeRed); + + /// Delayed spheres + if (timer_1 <= 0) + { + DebugDraw3D.DrawSphere(dSpherePosition.GlobalPosition, 2.0f, Colors.BlueViolet, 2.0f); + using (var _s1 = DebugDraw3D.NewScopedConfig().SetHdSphere(true)) + DebugDraw3D.DrawSphere(dSpherePosition.GlobalPosition + Vector3.Forward * 4, 2.0f, Colors.CornflowerBlue, 2.0f); + timer_1 = 2; + } + + timer_1 -= delta; + + // Cylinders + _draw_zone_title(pCylindersBox, "Cylinders"); + + DebugDraw3D.DrawCylinder(dCylinder1.GlobalTransform, Colors.Crimson); + DebugDraw3D.DrawCylinder(new Transform3D(Basis.Identity.Scaled(new Vector3(1, 2, 1)), dCylinder2.GlobalPosition), Colors.Red); + DebugDraw3D.DrawCylinderAb(dCylinder3a.GlobalPosition, dCylinder3b.GlobalPosition, 0.7f); + + // Boxes + _draw_zone_title(pBoxesBox, "Boxes"); + + DebugDraw3D.DrawBoxXf(dBox1.GlobalTransform, Colors.MediumPurple); + DebugDraw3D.DrawBox(dBox2.GlobalPosition, Quaternion.FromEuler(new Vector3(0, Mathf.DegToRad(45), Mathf.DegToRad(45))), Vector3.One, Colors.RebeccaPurple); + DebugDraw3D.DrawBoxXf(new Transform3D(new Basis(Vector3.Up, Mathf.Pi * 0.25f).Scaled(Vector3.One * 2), dBox3.GlobalPosition), Colors.RosyBrown); + + DebugDraw3D.DrawAabb(new Aabb(dAABB_fixed.GlobalPosition, new Vector3(2, 1, 2)), Colors.Aqua); + DebugDraw3D.DrawAabbAb(dAABB.GetChild(0).GlobalPosition, dAABB.GetChild(1).GlobalPosition, Colors.DeepPink); + + // Boxes AB + + DebugDraw3D.DrawArrow(dBoxAB.GlobalPosition, dBoxABup.GlobalPosition, Colors.Gold, 0.1f, true); + DebugDraw3D.DrawBoxAb(dBoxABa.GlobalPosition, dBoxABb.GlobalPosition, dBoxABup.GlobalPosition - dBoxAB.GlobalPosition, Colors.Peru); + + DebugDraw3D.DrawArrow(dBoxABEdge.GlobalPosition, dBoxABEdgeup.GlobalPosition, Colors.DarkRed, 0.1f, true); + DebugDraw3D.DrawBoxAb(dBoxABEdgea.GlobalPosition, dBoxABEdgeb.GlobalPosition, dBoxABEdgeup.GlobalPosition - dBoxABEdge.GlobalPosition, Colors.DarkOliveGreen, false); + + // Lines + _draw_zone_title(pLinesBox, "Lines"); + + DebugDraw3D.DrawSquare(dLines_Target.GlobalPosition, 0.5f, Colors.Red); + + DebugDraw3D.DrawLine(dLines_1.GlobalPosition, dLines_Target.GlobalPosition, Colors.Fuchsia); + DebugDraw3D.DrawRay(dLines_3.GlobalPosition, (dLines_Target.GlobalPosition - dLines_3.GlobalPosition).Normalized(), 3.0f, Colors.Crimson); + + + if (timer_3 <= 0) + { + DebugDraw3D.DrawLine(dLines_6.GlobalPosition, dLines_Target.GlobalPosition, Colors.Fuchsia, 2.0f); + timer_3 = 2; + } + + timer_3 -= delta; + + // Test UP vector + DebugDraw3D.DrawLine(dLines_7.GlobalPosition, dLines_Target.GlobalPosition, Colors.Red); + + // Lines with Arrow + DebugDraw3D.DrawArrow(dLines_2.GlobalPosition, dLines_Target.GlobalPosition, Colors.Blue, 0.5f, true); + DebugDraw3D.DrawArrowRay(dLines_4.GlobalPosition, (dLines_Target.GlobalPosition - dLines_4.GlobalPosition).Normalized(), 8.0f, Colors.Lavender, 0.5f, true); + + DebugDraw3D.DrawLineHitOffset(dLines_5.GlobalPosition, dLines_Target.GlobalPosition, true, Mathf.Abs(Mathf.Sin(Time.GetTicksMsec() / 1000.0f)), 0.25f, Colors.Aqua); + + // Paths + _draw_zone_title(pPathsBox, "Paths"); + + /// preparing data + List points = new List(); + List points_below = new List(); + List points_below2 = new List(); + List points_below3 = new List(); + List points_below4 = new List(); + List lines_above = new List(); + + foreach (var node in dLinePath.GetChildren()) + { + if (node is Node3D c) + { + points.Add(c.GlobalPosition); + points_below.Add(c.GlobalPosition + Vector3.Down); + points_below2.Add(c.GlobalPosition + Vector3.Down * 2); + points_below3.Add(c.GlobalPosition + Vector3.Down * 3); + points_below4.Add(c.GlobalPosition + Vector3.Down * 4); + } + } + + for (int x = 0; x < points.Count - 1; x++) + { + lines_above.Add(points[x] + Vector3.Up); + lines_above.Add(points[x + 1] + Vector3.Up); + } + + /// drawing lines + DebugDraw3D.DrawLines(lines_above.ToArray()); + DebugDraw3D.DrawLinePath(points.ToArray(), Colors.Beige); + DebugDraw3D.DrawPoints(points_below.ToArray(), DebugDraw3D.PointType.TypeSquare, 0.2f, Colors.DarkGreen); + DebugDraw3D.DrawPointPath(points_below2.ToArray(), DebugDraw3D.PointType.TypeSquare, 0.25f, Colors.Blue, Colors.Tomato); + DebugDraw3D.DrawArrowPath(points_below3.ToArray(), Colors.Gold, 0.5f); + using (var _sl = DebugDraw3D.NewScopedConfig().SetThickness(0.05f)) + DebugDraw3D.DrawPointPath(points_below4.ToArray(), DebugDraw3D.PointType.TypeSphere, 0.25f, Colors.MediumSeaGreen, Colors.MediumVioletRed); + + // Misc + _draw_zone_title(pMiscBox, "Misc"); + + if (Engine.IsEditorHint()) + { + using var s = DebugDraw3D.NewScopedConfig().SetThickness(0); + DebugDraw3D.DrawCameraFrustum(dCamera, Colors.DarkOrange); + } + + using (var s = DebugDraw3D.NewScopedConfig().SetCenterBrightness(0.1f)) + { + DebugDraw3D.DrawArrowhead(dMisc_Arrow.GlobalTransform, Colors.YellowGreen); + } + + DebugDraw3D.DrawSquare(dMisc_Billboard.GlobalPosition, 0.5f, Colors.Green); + + DebugDraw3D.DrawPosition(dMisc_Position.GlobalTransform, Colors.Brown); + + DebugDraw3D.DrawGizmo(dMisc_GizmoTransform.GlobalTransform, null, true); + DebugDraw3D.DrawGizmo(dMisc_GizmoOneColor.GlobalTransform, Colors.Brown, true); + using (var s = DebugDraw3D.NewScopedConfig().SetCenterBrightness(0.5f).SetNoDepthTest(true)) + { + DebugDraw3D.DrawGizmo(dMisc_GizmoNormal.GlobalTransform.Orthonormalized(), null, false); + } + + // Grids + _draw_zone_title_pos(dGrids_GridCentered.GlobalPosition + new Vector3(0, 1.5f, 0), "Grids", 96, 36); + + Transform3D tg = dGrids_Grid.GlobalTransform; + Vector3 tn = dGrids_Grid_Subdivision.Transform.Origin; + DebugDraw3D.DrawGrid(tg.Origin, tg.Basis.X, tg.Basis.Z, new Vector2I((int)tn.X * 10, (int)tn.Z * 10), Colors.LightCoral, false); + + var tn1 = dGrids_GridCentered_Subdivision.Transform.Origin; + DebugDraw3D.DrawGridXf(dGrids_GridCentered.GlobalTransform, new Vector2I((int)(tn1.X * 10), (int)(tn1.Z * 10))); + + using (var s = DebugDraw3D.NewScopedConfig().SetThickness(0.05f)) + { + DebugDraw3D.DrawBoxXf(dPostProcess.GlobalTransform, Colors.SeaGreen); + } + + // 2D + DebugDraw2D.Config.TextDefaultSize = text_groups_default_font_size; + DebugDraw2D.Config.TextBlockOffset = text_groups_offset; + DebugDraw2D.Config.TextBlockPosition = text_groups_position; + DebugDraw2D.Config.TextPadding = text_groups_padding; + + DebugDraw2D.Config.TextCustomFont = custom_font; + + + if (test_text) + { + _text_tests(); + } + + // Lag Test + var lag_test_pos = (Vector3)dLagTest_RESET.GetAnimation("RESET").TrackGetKeyValue(0, 0); + _draw_zone_title_pos(lag_test_pos, "Lag test"); + + dLagTest.Position = lag_test_pos + new Vector3(Mathf.Sin(Time.GetTicksMsec() / 100.0f) * 2.5f, 0, 0); + DebugDraw3D.DrawBox(dLagTest.GlobalPosition, Quaternion.Identity, Vector3.One * 2.01f, Colors.Chocolate, true); + + if (more_test_cases) + { + foreach (var node in dHitTest_RayEmitter.GetChildren()) + { + if (node is RayCast3D ray) + ray.SetPhysicsProcessInternal(true); + } + + _more_tests(); + } + else + { + foreach (var node in dHitTest_RayEmitter.GetChildren()) + { + if (node is RayCast3D ray) + ray.SetPhysicsProcessInternal(false); + } + } + + _draw_other_world(); + + if (draw_array_of_boxes) + { + _draw_array_of_boxes(); + } + + } + + void _text_tests() + { + DebugDraw2D.SetText("FPS", $"{Engine.GetFramesPerSecond():F2}", 0, Colors.Gold); + + if (text_groups_show_examples) + { + if (timer_text < 0) + { + DebugDraw2D.SetText("Some delayed text", "for 2.5s", -1, Colors.Black, 2.5f); // it's supposed to show text for 2.5 seconds + timer_text += 5; + } + + DebugDraw2D.BeginTextGroup("-- First Group --", 2, Colors.LimeGreen, true, text_groups_title_font_size, text_groups_text_font_size); + DebugDraw2D.SetText("Simple text"); + DebugDraw2D.SetText("Text", "Value", 0, Colors.Aquamarine); + DebugDraw2D.SetText("Text out of order", null, -1, Colors.Silver); + DebugDraw2D.BeginTextGroup("-- Second Group --", 1, Colors.Beige); + DebugDraw2D.SetText("Rendered frames", Engine.GetFramesDrawn()); + DebugDraw2D.EndTextGroup(); + } + + if (text_groups_show_stats) + { + DebugDraw2D.BeginTextGroup("-- Stats --", 3, Colors.Wheat); + var render_stats = DebugDraw3D.GetRenderStats(); + + if (render_stats != null && text_groups_show_stats) + { + DebugDraw2D.SetText("Total", render_stats.TotalGeometry); + DebugDraw2D.SetText("Instances", render_stats.Instances, 1); + DebugDraw2D.SetText("Lines", render_stats.Lines, 2); + DebugDraw2D.SetText("Total Visible", render_stats.TotalVisible, 3); + DebugDraw2D.SetText("Visible Instances", render_stats.VisibleInstances, 4); + DebugDraw2D.SetText("Visible Lines", render_stats.VisibleLines, 5); + + DebugDraw2D.SetText("---", "", 12); + + DebugDraw2D.SetText("Culling time", $"{(render_stats.TotalTimeCullingUsec / 1000.0):F2} ms", 13); + DebugDraw2D.SetText("Filling instances buffer", $"{(render_stats.TimeFillingBuffersInstancesUsec / 1000.0):F2} ms", 14); + DebugDraw2D.SetText("Filling lines buffer", $"{(render_stats.TimeFillingBuffersLinesUsec / 1000.0):F2} ms", 15); + DebugDraw2D.SetText("Filling time", $"{(render_stats.TotalTimeFillingBuffersUsec / 1000.0):F2} ms", 16); + DebugDraw2D.SetText("Total time", $"{(render_stats.TotalTimeSpentUsec / 1000.0):F2} ms", 17); + + DebugDraw2D.SetText("----", null, 32); + + DebugDraw2D.SetText("Total Label3D", render_stats.NodesLabel3dExistsTotal, 33); + DebugDraw2D.SetText("Visible Label3D", render_stats.NodesLabel3dVisible + render_stats.NodesLabel3dVisiblePhysics, 34); + + DebugDraw2D.SetText("-----", null, 48); + + DebugDraw2D.SetText("Created scoped configs", $"{render_stats.CreatedScopedConfigs}", 49); + } + + if (text_groups_show_stats && text_groups_show_stats_2d) + { + DebugDraw2D.SetText("------", null, 64); + } + + var render_stats_2d = DebugDraw2D.GetRenderStats(); + if (render_stats_2d != null && text_groups_show_stats_2d) + { + DebugDraw2D.SetText("Text groups", render_stats_2d.OverlayTextGroups, 96); + DebugDraw2D.SetText("Text lines", render_stats_2d.OverlayTextLines, 97); + } + DebugDraw2D.EndTextGroup(); + } + + if (text_groups_show_hints) + { + DebugDraw2D.BeginTextGroup("controls", 1024, Colors.White, false); + if (!Engine.IsEditorHint()) + { + DebugDraw2D.SetText("WASD QE, LMB", "To move", 0); + } + DebugDraw2D.SetText("Alt: change render layers", DebugDraw3D.Config.GeometryRenderLayers, 1); + if (!OS.HasFeature("web")) + { + DebugDraw2D.SetText("Ctrl: toggle anti-aliasing", GetViewport().Msaa3D == Viewport.Msaa.Msaa4X ? "MSAA 4x" : "Disabled", 2); + } + DebugDraw2D.SetText("Down: freeze render", DebugDraw3D.Config.Freeze3dRender, 3); + if (Engine.IsEditorHint()) + { + DebugDraw2D.SetText("Up: use scene camera", DebugDraw3D.Config.ForceUseCameraFromScene, 4); + } + DebugDraw2D.SetText("1,2,3: toggle debug", $"{DebugDraw3D.DebugEnabled}, {DebugDraw2D.DebugEnabled} 😐, {DebugDrawManager.DebugEnabled} 😏", 5); + DebugDraw2D.SetText("Left: toggle frustum culling", DebugDraw3D.Config.UseFrustumCulling, 6); + DebugDraw2D.SetText("Right: draw bounds for culling", DebugDraw3D.Config.VisibleInstanceBounds, 7); + } + } + + void _draw_zone_title(Node3D node, string title) + { + if (draw_3d_text) + { + using var _s1 = DebugDraw3D.NewScopedConfig().SetTextOutlineSize(72); + DebugDraw3D.DrawText(node.GlobalPosition + node.GlobalBasis.Y * 0.85f, title, 128); + } + } + + void _draw_zone_title_pos(Vector3 pos, string title, int font_size = 128, int outline = 72) + { + if (draw_3d_text) + { + using var _s1 = DebugDraw3D.NewScopedConfig().SetTextOutlineSize(outline); + DebugDraw3D.DrawText(pos, title, font_size); + } + } + + void _draw_other_world() + { + using var s = DebugDraw3D.NewScopedConfig().SetViewport(dOtherWorldBox.GetViewport()); + DebugDraw3D.DrawBoxXf(dOtherWorldBox.GlobalTransform.RotatedLocal(new Vector3(1, 1, -1).Normalized(), Mathf.Wrap(Time.GetTicksMsec() / 1000.0f, 0f, Mathf.Tau)), Colors.SandyBrown); + DebugDraw3D.DrawBoxXf(dOtherWorldBox.GlobalTransform.RotatedLocal(new Vector3(-1, 1, -1).Normalized(), Mathf.Wrap(Time.GetTicksMsec() / 1000.0f, 0f, Mathf.Tau) - Mathf.Pi / 4), Colors.SandyBrown); + + if (draw_3d_text) + { + var angle = Mathf.Wrap(Time.GetTicksMsec() / 1000.0f, 0, Mathf.Tau); + using (var _w2 = DebugDraw3D.NewScopedConfig().SetTextFont(custom_3d_font)) + { + DebugDraw3D.DrawText(dOtherWorldBox.GlobalPosition + new Vector3(Mathf.Cos(angle), -0.25f, Mathf.Sin(angle)), "Hello world!", 32, Colors.Crimson, 0); + } + + using (var _w3 = DebugDraw3D.NewScopedConfig().SetNoDepthTest(true).SetTextOutlineColor(Colors.IndianRed).SetTextOutlineSize(6)) + { + DebugDraw3D.DrawText(dOtherWorldBox.GlobalPosition + new Vector3(Mathf.Cos(angle), +0.25f, Mathf.Sin(-angle)), "World without depth", 20, Colors.Pink, 0); + } + } + } + + void _draw_rays_casts() + { + // Line hits render + _draw_zone_title_pos(pHitTestSphere.GlobalPosition, "Line hits", 96, 36); + + foreach (var node in dHitTest_RayEmitter.GetChildren()) + { + if (node is RayCast3D ray) + { + ray.ForceRaycastUpdate(); + DebugDraw3D.DrawLineHit(ray.GlobalPosition, ray.ToGlobal(ray.TargetPosition), ray.GetCollisionPoint(), ray.IsColliding(), 0.3f); + } + } + } + + void _more_tests() + { + // Delayed line render + using (var s = DebugDraw3D.NewScopedConfig().SetThickness(0.035f)) + { + DebugDraw3D.DrawLine(dLagTest.GlobalPosition + Vector3.Up, dLagTest.GlobalPosition + new Vector3(0, 3, Mathf.Sin(Time.GetTicksMsec() / 50.0f)), null, 0.35f); + + if (draw_3d_text) + { + DebugDraw3D.DrawText(dLagTest.GlobalPosition + new Vector3(0, 3, Mathf.Sin(Time.GetTicksMsec() / 50.0f)), $"{Mathf.Sin(Time.GetTicksMsec() / 50.0f):F1}", 16, null, 0.35f); + } + } + + // Draw plane + using (var _s11 = DebugDraw3D.NewScopedConfig().SetThickness(0.02f).SetPlaneSize(10)) + { + var pl_node = GetNode("PlaneOrigin"); + var xf = pl_node.GlobalTransform; + var normal = xf.Basis.Y.Normalized(); + var plane = new Plane(normal, xf.Origin.Dot(normal)); + + var vp = GetViewport(); + if (Engine.IsEditorHint() && (Viewport)Engine.GetSingleton("EditorInterface").Call("get_editor_viewport_3d", 0) != null) + { + vp = (Viewport)Engine.GetSingleton("EditorInterface").Call("get_editor_viewport_3d", 0); + } + + var cam = vp.GetCamera3D(); + if (cam != null) + { + var dir = vp.GetCamera3D().ProjectRayNormal(vp.GetMousePosition()); + Vector3? intersect = plane.IntersectsRay(cam.GlobalPosition, dir); + + DebugDraw3D.DrawPlane(plane, Colors.Coral * new Color(1, 1, 1, 0.4f), pl_node.GlobalPosition); + if (intersect.HasValue && intersect.Value.DistanceTo(pl_node.GlobalPosition) < _s11.GetPlaneSize() * 0.5f) + { + // Need to test different colors on both sides of the plane + var col = plane.IsPointOver(cam.GlobalPosition) ? Colors.Firebrick : Colors.Aquamarine; + DebugDraw3D.DrawSphere(intersect.Value, 0.3f, col); + } + } + } + } + + void _draw_array_of_boxes() + { + // Lots of boxes to check performance.. + var x_size = 50; + var y_size = 50; + var z_size = 3; + var mul = 1.0f; + var cubes_max_time = 1.25f; + var show_text = draw_text_with_boxes; + using var cfg = DebugDraw3D.NewScopedConfig(); + + if (draw_1m_boxes) + { + x_size = 100; + y_size = 100; + z_size = 100; + mul = 4.0f; + cubes_max_time = 60f; + draw_text_with_boxes = false; + } + + var size = Vector3.One; + var half_size = size * 0.5f; + + if (timer_cubes <= 0) + { + var start_time = Time.GetTicksUsec(); + for (int x = 0; x < x_size; x++) + { + for (int y = 0; y < y_size; y++) + { + for (int z = 0; z < z_size; z++) + { + cfg.SetThickness(Random.Shared.NextSingle() * 0.1f); + var pos = new Vector3(x * mul, (-4 - z) * mul, y * mul) + GlobalPosition; + DebugDraw3D.DrawBox(pos, Quaternion.Identity, size, null, false, cubes_max_time); + + if (show_text && z == 0) + { + DebugDraw3D.DrawText(pos + half_size, pos.ToString(), 32, null, cubes_max_time); + } + } + } + } + //GD.Print($"Draw Cubes: {((Time.GetTicksUsec() - start_time) / 1000.0):F3}ms"); + timer_cubes = cubes_max_time; + } + } + + Node3D dHitTest; + CsgBox3D dLagTest; + PanelContainer dPanel; + Node3D dZones; + Node3D dSpherePosition; + Node3D dSphereTransform; + Node3D dSphereHDTransform; + Node3D dAABB; + Node3D dAABB_fixed; + Node3D dBox1; + Node3D dBox2; + Node3D dBox3; + Node3D dBoxAB; + Node3D dBoxABa; + Node3D dBoxABb; + Node3D dBoxABup; + Node3D dBoxABEdge; + Node3D dBoxABEdgea; + Node3D dBoxABEdgeb; + Node3D dBoxABEdgeup; + Node3D dLines_1; + Node3D dLines_2; + Node3D dLines_3; + Node3D dLines_4; + Node3D dLines_5; + Node3D dLines_6; + Node3D dLines_7; + Node3D dLines_8; + Node3D dLines_Target; + Node3D dLinePath; + Node3D dCylinder1; + Node3D dCylinder2; + Node3D dCylinder3a; + Node3D dCylinder3b; + + Node3D pSpheresBox; + Node3D pCylindersBox; + Node3D pBoxesBox; + Node3D pLinesBox; + Node3D pPathsBox; + Node3D pMiscBox; + + MeshInstance3D dPlaneOrigin; + MeshInstance3D pZDepthTestCube; + + MeshInstance3D dOtherWorld; + SubViewport dOtherWorldViewport; + Node3D dOtherWorldBox; + + Control dCustomCanvas; + Node3D dMisc_Arrow; + Camera3D dCamera; + Node3D dMisc_Billboard; + Node3D dMisc_Position; + Node3D dMisc_GizmoTransform; + Node3D dMisc_GizmoNormal; + Node3D dMisc_GizmoOneColor; + + Node3D dGrids_Grid; + Node3D dGrids_Grid_Subdivision; + Node3D dGrids_GridCentered_Subdivision; + Node3D dGrids_GridCentered; + + MeshInstance3D dPostProcess; + AnimationPlayer dLagTest_RESET; + Node3D dHitTest_RayEmitter; + Node3D pHitTestSphere; + + void _get_nodes() + { + dHitTest = GetNode("HitTest"); + dLagTest = GetNode("LagTest"); + dPanel = GetNode("Panel"); + dZones = GetNode("Zones"); + dSpherePosition = GetNode("Spheres/SpherePosition"); + dSphereTransform = GetNode("Spheres/SphereTransform"); + dSphereHDTransform = GetNode("Spheres/SphereHDTransform"); + dAABB = GetNode("Boxes/AABB"); + dAABB_fixed = GetNode("Boxes/AABB_fixed"); + dBox1 = GetNode("Boxes/Box1"); + dBox2 = GetNode("Boxes/Box2"); + dBox3 = GetNode("Boxes/Box3"); + dBoxAB = GetNode("Boxes/BoxAB"); + dBoxABa = GetNode("Boxes/BoxAB/a"); + dBoxABb = GetNode("Boxes/BoxAB/b"); + dBoxABup = GetNode("Boxes/BoxAB/o/up"); + dBoxABEdge = GetNode("Boxes/BoxABEdge"); + dBoxABEdgea = GetNode("Boxes/BoxABEdge/a"); + dBoxABEdgeb = GetNode("Boxes/BoxABEdge/b"); + dBoxABEdgeup = GetNode("Boxes/BoxABEdge/o/up"); + dLines_1 = GetNode("Lines/1"); + dLines_2 = GetNode("Lines/2"); + dLines_3 = GetNode("Lines/3"); + dLines_4 = GetNode("Lines/4"); + dLines_5 = GetNode("Lines/5"); + dLines_6 = GetNode("Lines/6"); + dLines_7 = GetNode("Lines/7"); + dLines_8 = GetNode("Lines/8"); + dLines_Target = GetNode("Lines/Target"); + dLinePath = GetNode("LinePath"); + dCylinder1 = GetNode("Cylinders/Cylinder1"); + dCylinder2 = GetNode("Cylinders/Cylinder2"); + dCylinder3a = GetNode("Cylinders/Cylinder3/1"); + dCylinder3b = GetNode("Cylinders/Cylinder3/2"); + + pSpheresBox = GetNode("%SpheresBox"); + pCylindersBox = GetNode("%CylindersBox"); + pBoxesBox = GetNode("%BoxesBox"); + pLinesBox = GetNode("%LinesBox"); + pPathsBox = GetNode("%PathsBox"); + pMiscBox = GetNode("%MiscBox"); + + dPlaneOrigin = GetNode("PlaneOrigin"); + pZDepthTestCube = GetNode("%ZDepthTestCube"); + + dOtherWorld = GetNode("OtherWorld"); + dOtherWorldViewport = GetNode("OtherWorld/SubViewport"); + dOtherWorldBox = GetNode("OtherWorld/SubViewport/SubViewportContainer/SubViewport/OtherWorldBox"); + + dCustomCanvas = GetNode("CustomCanvas"); + dMisc_Arrow = GetNode("Misc/Arrow"); + dCamera = GetNode("Camera"); + dMisc_Billboard = GetNode("Misc/Billboard"); + dMisc_Position = GetNode("Misc/Position"); + dMisc_GizmoTransform = GetNode("Misc/GizmoTransform"); + dMisc_GizmoNormal = GetNode("Misc/GizmoNormal"); + dMisc_GizmoOneColor = GetNode("Misc/GizmoOneColor"); + + dGrids_Grid = GetNode("Grids/Grid"); + dGrids_Grid_Subdivision = GetNode("Grids/Grid/Subdivision"); + dGrids_GridCentered_Subdivision = GetNode("Grids/GridCentered/Subdivision"); + dGrids_GridCentered = GetNode("Grids/GridCentered"); + + dPostProcess = GetNode("PostProcess"); + + dLagTest_RESET = GetNode("LagTest/RESET"); + dHitTest_RayEmitter = GetNode("HitTest/RayEmitter"); + pHitTestSphere = GetNode("%HitTestSphere"); + } +} diff --git a/examples_dd3d/DebugDrawDemoSceneCS.cs.uid b/examples_dd3d/DebugDrawDemoSceneCS.cs.uid new file mode 100644 index 0000000..8576e05 --- /dev/null +++ b/examples_dd3d/DebugDrawDemoSceneCS.cs.uid @@ -0,0 +1 @@ +uid://dnf8ejsrnlvxb diff --git a/examples_dd3d/DebugDrawDemoSceneCS.tscn b/examples_dd3d/DebugDrawDemoSceneCS.tscn new file mode 100644 index 0000000..2e7b26f --- /dev/null +++ b/examples_dd3d/DebugDrawDemoSceneCS.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=3 format=3 uid="uid://sxtw8fme7g63"] + +[ext_resource type="PackedScene" uid="uid://c3sccy6x0ht5j" path="res://examples_dd3d/DebugDrawDemoScene.tscn" id="2"] +[ext_resource type="Script" path="res://examples_dd3d/DebugDrawDemoSceneCS.cs" id="2_ipqea"] + +[node name="DebugDrawDemoSceneCS" instance=ExtResource("2")] +script = ExtResource("2_ipqea") + +[node name="Settings" parent="." index="23"] +switch_to_scene = "res://examples_dd3d/DebugDrawDemoScene.tscn" + +[node name="Label" parent="Settings/HBox/VBoxContainer" index="1"] +text = "C# example" + +[node name="SwitchLang" parent="Settings/HBox/VBox/SettingsPanel/VBox" index="12"] +text = "Switch to GDScript" diff --git a/examples_dd3d/PixelatedElegance.ttf b/examples_dd3d/PixelatedElegance.ttf new file mode 100644 index 0000000..ce55ead Binary files /dev/null and b/examples_dd3d/PixelatedElegance.ttf differ diff --git a/examples_dd3d/PixelatedElegance.ttf.import b/examples_dd3d/PixelatedElegance.ttf.import new file mode 100644 index 0000000..16ce9d6 --- /dev/null +++ b/examples_dd3d/PixelatedElegance.ttf.import @@ -0,0 +1,35 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://7am1h57ldd6" +path="res://.godot/imported/PixelatedElegance.ttf-aac00801d681e5d2b42b23257b2692a7.fontdata" + +[deps] + +source_file="res://examples_dd3d/PixelatedElegance.ttf" +dest_files=["res://.godot/imported/PixelatedElegance.ttf-aac00801d681e5d2b42b23257b2692a7.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/examples_dd3d/Roboto-Bold.ttf b/examples_dd3d/Roboto-Bold.ttf new file mode 100644 index 0000000..d3f01ad Binary files /dev/null and b/examples_dd3d/Roboto-Bold.ttf differ diff --git a/examples_dd3d/Roboto-Bold.ttf.import b/examples_dd3d/Roboto-Bold.ttf.import new file mode 100644 index 0000000..f9fca34 --- /dev/null +++ b/examples_dd3d/Roboto-Bold.ttf.import @@ -0,0 +1,39 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://erdgllynwqkw" +path="res://.godot/imported/Roboto-Bold.ttf-3674de3d9ad3ee757cd4b4a89f1e126d.fontdata" + +[deps] + +source_file="res://examples_dd3d/Roboto-Bold.ttf" +dest_files=["res://.godot/imported/Roboto-Bold.ttf-3674de3d9ad3ee757cd4b4a89f1e126d.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[{ +"chars": [], +"glyphs": [], +"name": "New Configuration" +}] +language_support={} +script_support={} +opentype_features={} diff --git a/examples_dd3d/VisualizerAudioBus.tres b/examples_dd3d/VisualizerAudioBus.tres new file mode 100644 index 0000000..4c7b662 --- /dev/null +++ b/examples_dd3d/VisualizerAudioBus.tres @@ -0,0 +1,17 @@ +[gd_resource type="AudioBusLayout" load_steps=2 format=3 uid="uid://7sy4h4ibftrk"] + +[sub_resource type="AudioEffectSpectrumAnalyzer" id="AudioEffectSpectrumAnalyzer_odciy"] +resource_name = "SpectrumAnalyzer" +fft_size = 3 + +[resource] +bus/0/mute = true +bus/0/volume_db = -20.0 +bus/1/name = &"MusicAnalyzer" +bus/1/solo = false +bus/1/mute = false +bus/1/bypass_fx = false +bus/1/volume_db = 0.0 +bus/1/send = &"Master" +bus/1/effect/0/effect = SubResource("AudioEffectSpectrumAnalyzer_odciy") +bus/1/effect/0/enabled = true diff --git a/examples_dd3d/addon_icon.gd b/examples_dd3d/addon_icon.gd new file mode 100644 index 0000000..4283024 --- /dev/null +++ b/examples_dd3d/addon_icon.gd @@ -0,0 +1,11 @@ +@tool +extends Node3D + +func _process(delta: float) -> void: + var a = DebugDraw3D.new_scoped_config().set_thickness(0.015) + DebugDraw3D.draw_box_xf($box.global_transform, Color.GREEN) + DebugDraw3D.draw_gizmo($gizmo.global_transform) + DebugDraw3D.draw_grid_xf($gizmo/grid.global_transform, Vector2i(2,2), DebugDraw3D.empty_color, false) + DebugDraw3D.draw_sphere_xf($sphere.global_transform, Color.RED) + DebugDraw3D.draw_cylinder($cylinder.global_transform, Color.BLUE) + DebugDraw3D.draw_line_hit_offset($"line/1".global_transform.origin, $"line/2".global_transform.origin, true, 0.3, 0.1) diff --git a/examples_dd3d/addon_icon.gd.uid b/examples_dd3d/addon_icon.gd.uid new file mode 100644 index 0000000..c3fca43 --- /dev/null +++ b/examples_dd3d/addon_icon.gd.uid @@ -0,0 +1 @@ +uid://b2lj85riqyno0 diff --git a/examples_dd3d/addon_icon.tscn b/examples_dd3d/addon_icon.tscn new file mode 100644 index 0000000..b577312 --- /dev/null +++ b/examples_dd3d/addon_icon.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=3 format=3 uid="uid://1lhiwf8tgleh"] + +[ext_resource type="Script" path="res://examples_dd3d/addon_icon.gd" id="1_bq18y"] + +[sub_resource type="Environment" id="1"] +background_mode = 1 + +[node name="icon" type="Node3D"] +script = ExtResource("1_bq18y") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 5.39732) +environment = SubResource("1") +current = true + +[node name="box" type="Node3D" parent="."] +transform = Transform3D(0.316305, 0.0204714, -0.293415, -0.239575, 0.267896, -0.239575, 0.170631, 0.338191, 0.207538, -0.410294, 0.312541, 0.243199) + +[node name="gizmo" type="Node3D" parent="."] +transform = Transform3D(0.707107, 0, -0.707107, -0.294265, 0.909294, -0.294265, 0.642968, 0.416154, 0.642968, 0, 0, 0) + +[node name="grid" type="Node3D" parent="gizmo"] +transform = Transform3D(1, -2.98023e-08, 1.19209e-07, 0, 1, 0, 1.19209e-07, -2.98023e-08, 1, -0.0263093, -0.0170284, -0.0263093) + +[node name="sphere" type="Node3D" parent="."] +transform = Transform3D(0.401341, 0.207831, -0.437109, -0.449118, 0.371584, -0.235691, 0.180418, 0.46267, 0.385639, 0.466197, 0.322665, 0.200436) + +[node name="cylinder" type="Node3D" parent="."] +transform = Transform3D(0.155034, 0.231693, -0.112783, -0.160003, 0.264761, -0.0839674, 0.0232275, 0.277352, 0.174372, -0.0566943, -0.290515, 0.905274) + +[node name="line" type="Node3D" parent="."] + +[node name="1" type="Node3D" parent="line"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.568458, -0.615948, 0.653444) + +[node name="2" type="Node3D" parent="line"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0051975, 0.373791, 0.0974927) diff --git a/examples_dd3d/demo_camera_movement.gd b/examples_dd3d/demo_camera_movement.gd new file mode 100644 index 0000000..51f758d --- /dev/null +++ b/examples_dd3d/demo_camera_movement.gd @@ -0,0 +1,60 @@ +extends Camera3D + +@export var mouse_sensitivity := 0.25 +@export var camera_speed := 10.0 +@export var camera_speed_fast := 30.0 + +var btn_clicked := false +const hPI := PI/2 +var rot_x := 0.0 +var rot_y := 0.0 + + +func _ready(): + reset_input_rotation() + + +func _unhandled_input(event) -> void: + if event is InputEventMouseButton: + btn_clicked = event.pressed + + +func reset_input_rotation(): + rot_x = rotation.y + rot_y = rotation.x + + +func _input(event) -> void: + if btn_clicked: + if event is InputEventMouseMotion: + if event.button_mask == MOUSE_BUTTON_LEFT: + rot_x += -deg_to_rad(event.relative.x * mouse_sensitivity) + rot_y += -deg_to_rad(event.relative.y * mouse_sensitivity) + rot_y = clamp(rot_y, -hPI, hPI) + + transform.basis = Basis() + rotate_object_local(Vector3.UP, rot_x) + rotate_object_local(Vector3.RIGHT, rot_y) + + +func get_axis(neg : Array[Key], pos : Array[Key]) -> float: + var pressed = func (arr: Array[Key]): + var p: float = 0 + for k in arr: + if Input.is_physical_key_pressed(k): + p = 1 + break + return p + + return pressed.call(pos) - pressed.call(neg) + + +func _process(delta) -> void: + var motion := Vector2(get_axis([KEY_S], [KEY_W]), get_axis([KEY_A], [KEY_D])) + var lift := get_axis([KEY_Q, KEY_CTRL], [KEY_E, KEY_SPACE]) + var speed := camera_speed_fast if Input.is_physical_key_pressed(KEY_SHIFT) else camera_speed + motion = motion.limit_length() + + var b := global_transform.basis + var v := (-b.z * motion.x) + (b.x * motion.y) + (b.y * lift) + global_position += v.limit_length() * speed * delta diff --git a/examples_dd3d/demo_camera_movement.gd.uid b/examples_dd3d/demo_camera_movement.gd.uid new file mode 100644 index 0000000..03651ca --- /dev/null +++ b/examples_dd3d/demo_camera_movement.gd.uid @@ -0,0 +1 @@ +uid://b5mdrjubj0lg5 diff --git a/examples_dd3d/demo_music_visualizer.gd b/examples_dd3d/demo_music_visualizer.gd new file mode 100644 index 0000000..73e9867 --- /dev/null +++ b/examples_dd3d/demo_music_visualizer.gd @@ -0,0 +1,175 @@ +@tool +extends VBoxContainer + +@export_range(1, 128) var bars_count := 32 +var transform: Transform3D: + get: + return %AudioVisualizer.global_transform +@export_exp_easing("inout") var motion_smoothing := 0.025 +@export_range(0, 0.5) var bar_thickness := 0.065 +@export_range(0, 10) var bars_separation := 0.325 +@export_exp_easing("inout") var color_offset_speed := 0.4 +@export var colors: Gradient = null + +var MusicAnalyzerBus := &"MusicAnalyzer" +var MasterBus := &"Master" +var MAX_HZ := 16000.0 +var MIN_HZ := 20.0 +var MIN_DB := 60.0 +var spectrum: AudioEffectSpectrumAnalyzerInstance = null + +var smoothed_energy: Array[float] = [] +var color_offset := 0.0 + +var _on_data_loaded_callback = null + + +func _ready(): + var bus = AudioServer.get_bus_index(MusicAnalyzerBus) + if bus == -1: + print("'MusicVisualizer' audio bus not found.\nSet 'VisualizerAudioBus.tres' as the default bus to use the audio visualizer.") + + spectrum = AudioServer.get_bus_effect_instance(bus, 0) + %MuteMaster.button_pressed = AudioServer.is_bus_mute(AudioServer.get_bus_index(MasterBus)) + %VolumeSlider.value = db_to_linear(AudioServer.get_bus_volume_db(AudioServer.get_bus_index(MasterBus))) + + if OS.has_feature('web'): + motion_smoothing = motion_smoothing * 1.5 + + _on_data_loaded_callback = JavaScriptBridge.create_callback(_on_data_loaded) + # Retrieve the 'gd_callbacks' object + var gdcallbacks: JavaScriptObject = JavaScriptBridge.get_interface("gd_callbacks") + # Assign the callbacks + gdcallbacks.dataLoaded = _on_data_loaded_callback + + +func _process(_delta): + if %MusicPlayer.playing: + draw_spectrum() + + +func _pressed(): + var open_file = func(filepath: String): + print("Opening '%s'" % filepath) + var file = FileAccess.open(filepath, FileAccess.READ) + var data = file.get_buffer(file.get_length()) + open_stream(filepath.get_extension(), data) + + if DisplayServer.has_feature(DisplayServer.FEATURE_NATIVE_DIALOG): + DisplayServer.file_dialog_show("Select audio file", "", "", true, DisplayServer.FILE_DIALOG_MODE_OPEN_FILE, ["*.mp3"], + func (status: bool, selected: PackedStringArray, _fileter: int): + if status and selected.size(): + open_file.call(selected[0]) + ) + elif OS.has_feature('web'): + JavaScriptBridge.eval("loadData()") + else: + var fd := FileDialog.new() + add_child(fd) + + fd.title = "Select audio file" + fd.access = FileDialog.ACCESS_FILESYSTEM + fd.file_mode = FileDialog.FILE_MODE_OPEN_FILE + fd.current_dir = OS.get_system_dir(OS.SYSTEM_DIR_DOWNLOADS) + fd.add_filter("*.mp3") + fd.popup_centered_ratio(0.8) + + fd.file_selected.connect(func(path: String): + open_file.call(path) + ) + + fd.visibility_changed.connect(func(): + if not fd.visible: + fd.queue_free() + ) + + +func _on_data_loaded(data: Array) -> void: + # Make sure there is something + if (data.size() == 0): + return + + var file_name: String = data[0] + print("Opening '%s'" % file_name) + + var arr: PackedByteArray = JavaScriptBridge.eval("gd_callbacks.dataLoadedResult;") + open_stream(file_name.get_extension(), arr) + + +func open_stream(file_ext: String, data: PackedByteArray): + var stream: AudioStream = null + if file_ext == "mp3": + stream = AudioStreamMP3.new() + stream.data = data + + if not stream.data: + print("Failed to load MP3!") + return + + if not stream: + print("Failed to load music!") + return + + %MusicPlayer.stream = stream + %MusicPlayer.bus = MusicAnalyzerBus + %MusicPlayer.play() + + # Debugging frequencies + for ih in range(1, bars_count + 1): + var _hz: float = log_freq(ih / float(bars_count), MIN_HZ, MAX_HZ) + #print("%.0f hz %.2f" % [_hz, ih / float(bars_count)]) + + +func draw_spectrum(): + var _s1 = DebugDraw3D.scoped_config().set_thickness(bar_thickness).set_center_brightness(0.9) + var prev_hz = MIN_HZ + smoothed_energy.resize(bars_count) + + var xf := transform + var y := xf.basis.y + var h := y.length() + var x := xf.basis.x + var z := xf.basis.z + var origin := xf.origin - (x * bars_count + (x * bars_separation) * (bars_count - 1)) * 0.5 + var sum := 0.0 + + for ih in range(1, bars_count + 1): + var i := ih - 1 + var hz: float = log_freq(ih / float(bars_count), MIN_HZ, MAX_HZ) + var magnitude: float = spectrum.get_magnitude_for_frequency_range(prev_hz, hz, AudioEffectSpectrumAnalyzerInstance.MAGNITUDE_AVERAGE).length() + var energy: float = clampf((MIN_DB + linear_to_db(magnitude)) / MIN_DB, 0, 1) + var e: float = lerp(smoothed_energy[i], energy, clampf(get_process_delta_time() / motion_smoothing if motion_smoothing else 1.0, 0, 1)) + smoothed_energy[i] = e + var height: float = e * h + sum += e + + var s := x * bars_separation + + var a := origin + x * i + s * i + (z * 0.5) + var b := origin + x * (i + 1) + s * i + (z * -0.5) + xf.basis.y.normalized() * clampf(height, 0.001, h) + var c := Color.HOT_PINK + if colors: + c = colors.sample(wrapf(float(ih) / bars_count + color_offset, 0, 1)) + c.s = clamp(c.s - smoothed_energy[i] * 0.3, 0, 1.0) + + DebugDraw3D.draw_box_ab(a, b, y, c) + + prev_hz = hz + + color_offset = wrapf(color_offset + sum / smoothed_energy.size() * clampf(get_process_delta_time() / color_offset_speed if color_offset_speed else 1.0, 0, 1), 0, 1) + + +func log10(val: float) -> float: + return log(val) / 2.302585 + + +func log_freq(pos: float, min_hz: float, max_hz: float) -> float: + return pow(10, log10(min_hz) + (log10(max_hz) - log10(min_hz)) * pos) + + +func _on_volume_slider_value_changed(value): + AudioServer.set_bus_volume_db(AudioServer.get_bus_index(MasterBus), linear_to_db(value)) + + +func _on_mute_master_toggled(toggled_on): + AudioServer.set_bus_mute(AudioServer.get_bus_index(MasterBus), toggled_on) diff --git a/examples_dd3d/demo_music_visualizer.gd.uid b/examples_dd3d/demo_music_visualizer.gd.uid new file mode 100644 index 0000000..7463855 --- /dev/null +++ b/examples_dd3d/demo_music_visualizer.gd.uid @@ -0,0 +1 @@ +uid://bebbekatkxaoe diff --git a/examples_dd3d/demo_settings_panel.gd b/examples_dd3d/demo_settings_panel.gd new file mode 100644 index 0000000..4896b47 --- /dev/null +++ b/examples_dd3d/demo_settings_panel.gd @@ -0,0 +1,103 @@ +@tool +extends Control + +@export var switch_to_scene = "" +var is_ready := false + +func _ready(): + if Engine.is_editor_hint(): + return + + if ProjectSettings.has_setting("application/config/no_csharp_support"): + %SwitchLang.visible = false + + %SwitchLang.disabled = true + + %ThicknessSlider.value = get_parent().debug_thickness + %FrustumScaleSlider.value = get_parent().camera_frustum_scale + %UpdateInPhysics.text = "Update in physics (%d Ticks) *" % ProjectSettings.get_setting("physics/common/physics_ticks_per_second") + %UpdateInPhysics.button_pressed = get_parent().update_in_physics + + %ShowText.button_pressed = get_parent().test_text + %ShowExamples.button_pressed = get_parent().text_groups_show_examples + %ShowStats.button_pressed = get_parent().text_groups_show_stats + %ShowHints.button_pressed = get_parent().text_groups_show_hints + %Draw3DText.button_pressed = get_parent().draw_3d_text + + %DrawBoxes.button_pressed = get_parent().draw_array_of_boxes + %Draw1MBoxes.button_pressed = get_parent().draw_1m_boxes + %DrawBoxesAddText.button_pressed = get_parent().draw_text_with_boxes + + if get_tree(): + await get_tree().create_timer(0.2).timeout + + %SwitchLang.disabled = false + is_ready = true + + +func _on_Button_pressed() -> void: + get_tree().call_deferred("change_scene_to_file", switch_to_scene) + + +func _on_hide_show_panel_pressed(): + if %SettingsPanel.visible: + %SettingsPanel.hide() + %HideShowPanelButton.text = "Show panel" + else: + %SettingsPanel.show() + %HideShowPanelButton.text = "Hide panel" + + +func _on_thickness_slider_value_changed(value): + if not is_ready: return + + get_parent().debug_thickness = value + + +func _on_frustum_scale_slider_value_changed(value): + if not is_ready: return + + get_parent().camera_frustum_scale = value + + +func _on_update_in_physics_toggled(toggled_on): + get_parent().update_in_physics = toggled_on + + +func _on_show_text_toggled(toggled_on: bool) -> void: + get_parent().test_text = toggled_on + + +func _on_show_examples_toggled(toggled_on: bool) -> void: + get_parent().text_groups_show_examples = toggled_on + + +func _on_show_stats_toggled(toggled_on): + get_parent().text_groups_show_stats = toggled_on + + +func _on_show_hints_toggled(toggled_on: bool) -> void: + get_parent().text_groups_show_hints = toggled_on + + +func _on_draw_3d_text_toggled(toggled_on: bool) -> void: + get_parent().draw_3d_text = toggled_on + + +func _on_draw_boxes_toggled(toggled_on): + get_parent().draw_array_of_boxes = toggled_on + + DebugDraw3D.clear_all() + get_parent().timer_cubes = 0 + + +func _on_draw_1m_boxes_toggled(toggled_on): + get_parent().draw_1m_boxes = toggled_on + + if get_parent().draw_array_of_boxes: + DebugDraw3D.clear_all() + get_parent().timer_cubes = 0 + + +func _on_add_text_to_boxes_toggled(toggled_on: bool) -> void: + get_parent().draw_text_with_boxes = toggled_on diff --git a/examples_dd3d/demo_settings_panel.gd.uid b/examples_dd3d/demo_settings_panel.gd.uid new file mode 100644 index 0000000..3b41e62 --- /dev/null +++ b/examples_dd3d/demo_settings_panel.gd.uid @@ -0,0 +1 @@ +uid://83dhsep7l725 diff --git a/examples_dd3d/demo_web_docs_version_select.gd b/examples_dd3d/demo_web_docs_version_select.gd new file mode 100644 index 0000000..c63bc49 --- /dev/null +++ b/examples_dd3d/demo_web_docs_version_select.gd @@ -0,0 +1,42 @@ +extends HBoxContainer + +var _on_versions_loaded_callback = null +@onready var btn: OptionButton = $OptionButton + +func _enter_tree(): + hide() + + +func _ready(): + if OS.has_feature('web'): + _on_versions_loaded_callback = JavaScriptBridge.create_callback(_on_versions_loaded) + var versions_callbacks: JavaScriptObject = JavaScriptBridge.get_interface("versions_callbacks") + versions_callbacks.loaded = _on_versions_loaded_callback + + JavaScriptBridge.eval("loadVersions()") + + +func _on_versions_loaded(args: Array) -> void: + if (args.size() == 0): + return + + var current_version: String = args[0] + + var versions_str: String = JavaScriptBridge.eval("versions_callbacks.versions;") + var version_urls_str: String = JavaScriptBridge.eval("versions_callbacks.version_urls;") + var versions: PackedStringArray = versions_str.split(";", false) + var version_urls: PackedStringArray = version_urls_str.split(";", false) + + if versions: + show() + btn.clear() + btn.item_selected.connect(func(idx): + # move to another version + JavaScriptBridge.eval("window.location.href = \"%s\"" % version_urls[idx]) + ) + + for i in range(versions.size()): + btn.add_item(versions[i], i) + + if versions[i] == current_version: + btn.select(i) diff --git a/examples_dd3d/demo_web_docs_version_select.gd.uid b/examples_dd3d/demo_web_docs_version_select.gd.uid new file mode 100644 index 0000000..a058966 --- /dev/null +++ b/examples_dd3d/demo_web_docs_version_select.gd.uid @@ -0,0 +1 @@ +uid://hvx3t70syvkm diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..1a10d58 --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..58e2c8e --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cntc3q04j3j2h" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/item_list.gd b/item_list.gd new file mode 100644 index 0000000..24dc35c --- /dev/null +++ b/item_list.gd @@ -0,0 +1,9 @@ +extends ItemList + +func _process(delta: float) -> void: + while item_count > $"../../CitizenManager".task_queue.size(): + remove_item(0) + while item_count < $"../../CitizenManager".task_queue.size(): + add_item("") + for i in range($"../../CitizenManager".task_queue.size()): + set_item_text(i, $"../../CitizenManager".task_queue[i].get_task_name()) diff --git a/item_list.gd.uid b/item_list.gd.uid new file mode 100644 index 0000000..9429448 --- /dev/null +++ b/item_list.gd.uid @@ -0,0 +1 @@ +uid://dhm0h03mw4rbo diff --git a/items/bullet.res b/items/bullet.res new file mode 100644 index 0000000..ab03f00 Binary files /dev/null and b/items/bullet.res differ diff --git a/items/copper.res b/items/copper.res new file mode 100644 index 0000000..f189362 Binary files /dev/null and b/items/copper.res differ diff --git a/objects/Storage.tscn b/objects/Storage.tscn new file mode 100644 index 0000000..2027f86 --- /dev/null +++ b/objects/Storage.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=7 format=3 uid="uid://0vvjqh8xyqg8"] + +[ext_resource type="Script" uid="uid://b1g3m8gfjrkef" path="res://scripts/storage.gd" id="1_upgem"] +[ext_resource type="Texture2D" uid="uid://cv0h0l631pr7p" path="res://assets/storage.png" id="2_fn4fu"] +[ext_resource type="Script" uid="uid://bha4kv6d0iba0" path="res://scripts/Item.gd" id="2_ujb2c"] +[ext_resource type="Script" uid="uid://inyhfjkw5h2u" path="res://scripts/PathfindObstacle.gd" id="3_dadgq"] +[ext_resource type="Resource" uid="uid://cgxall2fn3bsn" path="res://items/copper.res" id="3_mq7b5"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_upgem"] +radius = 32.0 + +[node name="Storage" type="StaticBody2D" groups=["Buildings"]] +input_pickable = true +script = ExtResource("1_upgem") +source_limit = 3 +sink_limit = 3 +storage_limit = 250 +build_materials_required = Dictionary[ExtResource("2_ujb2c"), int]({ +ExtResource("3_mq7b5"): 3 +}) + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("2_fn4fu") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_upgem") + +[node name="PathfindObstacle" type="Node2D" parent="."] +script = ExtResource("3_dadgq") +added_weight = 99.0 +metadata/_custom_type_script = "uid://inyhfjkw5h2u" diff --git a/objects/building.tscn b/objects/building.tscn new file mode 100644 index 0000000..5c0a77e --- /dev/null +++ b/objects/building.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=4 format=3 uid="uid://bkfr2sxxhhjcn"] + +[ext_resource type="Script" uid="uid://dqq6rfbnf5xo" path="res://scripts/Building.gd" id="1_gfisn"] +[ext_resource type="Script" uid="uid://inyhfjkw5h2u" path="res://scripts/PathfindObstacle.gd" id="2_515t0"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_i7id8"] +radius = 32.0 + +[node name="Building" type="StaticBody2D" groups=["Buildings"]] +collision_layer = 4 +collision_mask = 7 +script = ExtResource("1_gfisn") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_i7id8") + +[node name="PathfindObstacle" type="Node2D" parent="."] +script = ExtResource("2_515t0") +added_weight = 99.0 +metadata/_custom_type_script = "uid://inyhfjkw5h2u" + +[node name="Sprite2D" type="Sprite2D" parent="."] diff --git a/objects/bullet.tscn b/objects/bullet.tscn new file mode 100644 index 0000000..e6b19fd --- /dev/null +++ b/objects/bullet.tscn @@ -0,0 +1,32 @@ +[gd_scene load_steps=5 format=3 uid="uid://dx2wpxj51mnju"] + +[ext_resource type="Texture2D" uid="uid://b63im173j48xu" path="res://assets/resources.png" id="1_1hbe6"] +[ext_resource type="Script" uid="uid://c5sb5760mlui6" path="res://scripts/Projectile.gd" id="1_3ndsa"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_17rhs"] +atlas = ExtResource("1_1hbe6") +region = Rect2(64, 0, 64, 64) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_8j1ou"] +size = Vector2(12, 23) + +[node name="Bullet" type="RigidBody2D"] +collision_layer = 8 +collision_mask = 3 +contact_monitor = true +max_contacts_reported = 3 +script = ExtResource("1_3ndsa") +cancel_speed = 200.0 +lethal_speed = 250.0 + +[node name="Sprite2D" type="Sprite2D" parent="."] +rotation = 1.5708 +scale = Vector2(0.5, 0.5) +texture = SubResource("AtlasTexture_17rhs") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2(-1.5, 0) +rotation = 1.5708 +shape = SubResource("RectangleShape2D_8j1ou") + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/objects/citizen.tscn b/objects/citizen.tscn new file mode 100644 index 0000000..792b30c --- /dev/null +++ b/objects/citizen.tscn @@ -0,0 +1,52 @@ +[gd_scene load_steps=7 format=3 uid="uid://cs5hyqq024i3h"] + +[ext_resource type="Script" uid="uid://b80nc18ya55my" path="res://scripts/Citizen.gd" id="1_2umkp"] +[ext_resource type="Texture2D" uid="uid://8rd4sbar25mm" path="res://assets/lilguy.png" id="2_3lb75"] +[ext_resource type="Texture2D" uid="uid://dh4vl2saw2ykx" path="res://assets/lilguy_arms.png" id="3_s56hq"] +[ext_resource type="PackedScene" uid="uid://bul5wdylupx54" path="res://objects/parts/detection_area.tscn" id="4_3lb75"] + +[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_2umkp"] +friction = 0.0 +bounce = 0.3 + +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_i6j5g"] +radius = 16.0 +height = 32.0 + +[node name="Citizen" type="RigidBody2D" groups=["Citizens"]] +collision_layer = 16 +collision_mask = 7 +physics_material_override = SubResource("PhysicsMaterial_2umkp") +lock_rotation = true +linear_damp = 0.5 +script = ExtResource("1_2umkp") +movement_force = 250.0 +max_speed = 100.0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CapsuleShape2D_i6j5g") + +[node name="Body" type="Sprite2D" parent="."] +texture_filter = 1 +texture = ExtResource("2_3lb75") +hframes = 2 + +[node name="Arms" type="Sprite2D" parent="."] +texture_filter = 1 +texture = ExtResource("3_s56hq") + +[node name="Label" type="Label" parent="."] +visible = false +offset_left = -23.0 +offset_top = -28.0 +offset_right = 144.0 +offset_bottom = 73.0 +scale = Vector2(0.28002, 0.48002) +text = "DOES THIS LOOK LIKE + + +THE FACE OF MERCY" + +[node name="DetectionArea" parent="." instance=ExtResource("4_3lb75")] +requires_line_of_sight = true +active_state = 2 diff --git a/objects/conveyor.tscn b/objects/conveyor.tscn new file mode 100644 index 0000000..70f8fb6 --- /dev/null +++ b/objects/conveyor.tscn @@ -0,0 +1,26 @@ +[gd_scene load_steps=4 format=3 uid="uid://bewbv5s2iesac"] + +[ext_resource type="Script" uid="uid://dkv4h3rp0ml1t" path="res://scripts/Conveyor.gd" id="1_tsxf6"] +[ext_resource type="Script" uid="uid://bre6c0lytr0ow" path="res://scripts/ResourceMover.gd" id="2_poikd"] + +[sub_resource type="SegmentShape2D" id="SegmentShape2D_tsxf6"] +b = Vector2(11, 12) + +[node name="Conveyor" type="Area2D"] +script = ExtResource("1_tsxf6") +source_limit = 1 +sink_limit = 1 +storage_limit = 9999 + +[node name="Line" type="Line2D" parent="."] +points = PackedVector2Array(0, 0, 10, 10) +default_color = Color(0.201527, 0.201527, 0.201527, 1) +begin_cap_mode = 2 +end_cap_mode = 2 +script = ExtResource("2_poikd") +speed = 50.0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("SegmentShape2D_tsxf6") + +[connection signal="node_at_end" from="Line" to="." method="_on_line_node_at_end"] diff --git a/objects/enemy.tscn b/objects/enemy.tscn new file mode 100644 index 0000000..ab263c9 --- /dev/null +++ b/objects/enemy.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=7 format=3 uid="uid://ci2qx1cctt27p"] + +[ext_resource type="Script" uid="uid://vxnx03ef25s8" path="res://scripts/Enemy.gd" id="1_7jlpp"] +[ext_resource type="Texture2D" uid="uid://b8x6okhfoufpx" path="res://assets/enemy.png" id="2_41oev"] + +[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_7jlpp"] +friction = 0.0 +bounce = 0.3 + +[sub_resource type="CircleShape2D" id="CircleShape2D_223my"] +radius = 28.0 + +[sub_resource type="Gradient" id="Gradient_7jlpp"] +colors = PackedColorArray(1, 0, 0, 1, 1, 1, 0, 1) + +[sub_resource type="Gradient" id="Gradient_41oev"] +colors = PackedColorArray(0.265048, 8.43251e-05, 0.922038, 1, 0.676137, 0.000581419, 0.724855, 1) + +[node name="Enemy" type="RigidBody2D" groups=["Enemy"]] +collision_layer = 2 +collision_mask = 15 +physics_material_override = SubResource("PhysicsMaterial_7jlpp") +lock_rotation = true +linear_damp = 1.0 +script = ExtResource("1_7jlpp") +movement_force = 250.0 +max_speed = 100.0 +path_give_up_theshold = 128.0 +stuck_speed = 50.0 + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("2_41oev") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_223my") + +[node name="PathDebugLine" type="Line2D" parent="."] +visible = false +default_color = Color(1, 0, 0, 1) +gradient = SubResource("Gradient_7jlpp") +joint_mode = 2 +begin_cap_mode = 2 +end_cap_mode = 2 + +[node name="ForceDebugLine" type="Line2D" parent="."] +visible = false +points = PackedVector2Array(0, 0, 0, 200) +default_color = Color(0.27964, 0.000166725, 0.903432, 1) +gradient = SubResource("Gradient_41oev") +begin_cap_mode = 2 +end_cap_mode = 2 diff --git a/objects/miner.tscn b/objects/miner.tscn new file mode 100644 index 0000000..c399b28 --- /dev/null +++ b/objects/miner.tscn @@ -0,0 +1,32 @@ +[gd_scene load_steps=4 format=3 uid="uid://c4ra55vavvnge"] + +[ext_resource type="Script" uid="uid://cdor1505oo2oj" path="res://scripts/Miner.gd" id="1_bqtd2"] +[ext_resource type="Script" uid="uid://inyhfjkw5h2u" path="res://scripts/PathfindObstacle.gd" id="2_aoohl"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_bqtd2"] +radius = 32.0 + +[node name="Miner" type="StaticBody2D" groups=["Buildings"]] +collision_layer = 4 +collision_mask = 7 +input_pickable = true +script = ExtResource("1_bqtd2") +production_period = 0.25 +sink_limit = 3 + +[node name="Polygon2D" type="Polygon2D" parent="."] +color = Color(1, 0, 0, 1) +antialiased = true +invert_border = 1.0 +polygon = PackedVector2Array(-35, -25, 33, -25, 0, 42) + +[node name="Sprite2D" type="Sprite2D" parent="."] +visible = false + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_bqtd2") + +[node name="PathfindObstacle" type="Node2D" parent="."] +script = ExtResource("2_aoohl") +added_weight = 99.0 +metadata/_custom_type_script = "uid://inyhfjkw5h2u" diff --git a/objects/parts/detection_area.tscn b/objects/parts/detection_area.tscn new file mode 100644 index 0000000..081cae0 --- /dev/null +++ b/objects/parts/detection_area.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=5 format=3 uid="uid://bul5wdylupx54"] + +[ext_resource type="Script" uid="uid://dkqr1sxxunr2w" path="res://scripts/DetectionArea.gd" id="1_txslw"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_g682f"] +radius = 500.0 + +[sub_resource type="Gradient" id="Gradient_augeu"] +offsets = PackedFloat32Array(0.745547, 1) +colors = PackedColorArray(1, 1, 1, 1, 0, 0, 0, 1) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_f5emh"] +gradient = SubResource("Gradient_augeu") +width = 1000 +height = 1000 +fill = 1 +fill_from = Vector2(0.495726, 0.517094) +fill_to = Vector2(1, 0.508547) + +[node name="DetectionArea" type="Area2D"] +collision_layer = 2 +collision_mask = 2 +script = ExtResource("1_txslw") +radius = 200.0 +requires_line_of_sight = null +active_state = null + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_g682f") + +[node name="PointLight2D" type="PointLight2D" parent="."] +energy = 0.3 +shadow_enabled = true +texture = SubResource("GradientTexture2D_f5emh") + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/objects/processor.tscn b/objects/processor.tscn new file mode 100644 index 0000000..2838903 --- /dev/null +++ b/objects/processor.tscn @@ -0,0 +1,45 @@ +[gd_scene load_steps=8 format=3 uid="uid://bvpfnmtbexv0w"] + +[ext_resource type="Script" uid="uid://bsc4h24tql7nr" path="res://scripts/Processor.gd" id="1_8fiim"] +[ext_resource type="Script" uid="uid://bha4kv6d0iba0" path="res://scripts/Item.gd" id="2_vu1qv"] +[ext_resource type="Resource" uid="uid://cgxall2fn3bsn" path="res://items/copper.res" id="3_r717d"] +[ext_resource type="Texture2D" uid="uid://cr8sqiuh5at1x" path="res://assets/factory.png" id="3_vu1qv"] +[ext_resource type="Resource" uid="uid://dtem6pgfrxmm7" path="res://items/bullet.res" id="4_rcuv8"] +[ext_resource type="Script" uid="uid://inyhfjkw5h2u" path="res://scripts/PathfindObstacle.gd" id="6_r717d"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_r717d"] +radius = 32.0 + +[node name="Processor" type="StaticBody2D" groups=["Buildings"]] +collision_layer = 4 +collision_mask = 7 +input_pickable = true +script = ExtResource("1_8fiim") +ingredient_items = Dictionary[ExtResource("2_vu1qv"), int]({ +ExtResource("3_r717d"): 2 +}) +production_time = 0.5 +produced_item = ExtResource("4_rcuv8") +source_limit = 1 +sink_limit = 1 +build_materials_required = Dictionary[ExtResource("2_vu1qv"), int]({ +ExtResource("3_r717d"): 5 +}) + +[node name="Sprite2D" type="Sprite2D" parent="."] +visible = false +texture = ExtResource("3_vu1qv") + +[node name="Polygon2D" type="Polygon2D" parent="."] +color = Color(0, 1, 0, 1) +polygon = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_r717d") + +[node name="Consumer" type="Node" parent="."] + +[node name="PathfindObstacle" type="Node2D" parent="."] +script = ExtResource("6_r717d") +added_weight = 99.0 +metadata/_custom_type_script = "uid://inyhfjkw5h2u" diff --git a/objects/resource.tscn b/objects/resource.tscn new file mode 100644 index 0000000..9e596d2 --- /dev/null +++ b/objects/resource.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=4 format=3 uid="uid://dy4bso58ba8wj"] + +[ext_resource type="Script" uid="uid://ccu24smgm1u4" path="res://scripts/ItemNode.gd" id="1_bk1pl"] +[ext_resource type="Texture2D" uid="uid://b63im173j48xu" path="res://assets/resources.png" id="2_yvlix"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_73fnb"] +atlas = ExtResource("2_yvlix") +region = Rect2(0, 0, 64, 64) + +[node name="ItemNode" type="Node2D"] +script = ExtResource("1_bk1pl") + +[node name="Sprite2D" type="Sprite2D" parent="."] +scale = Vector2(0.5, 0.5) +texture = SubResource("AtlasTexture_73fnb") diff --git a/objects/splat.tscn b/objects/splat.tscn new file mode 100644 index 0000000..99e95f3 --- /dev/null +++ b/objects/splat.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=4 format=3 uid="uid://bh2tyagbwe13k"] + +[ext_resource type="Texture2D" uid="uid://xkum0axedc4a" path="res://assets/splat.png" id="1_titfq"] +[ext_resource type="Script" uid="uid://3ush0k3p0d8i" path="res://scripts/splat.gd" id="2_ioscy"] +[ext_resource type="Script" uid="uid://inyhfjkw5h2u" path="res://scripts/PathfindObstacle.gd" id="3_8gi7h"] + +[node name="Splat" type="Sprite2D"] +texture = ExtResource("1_titfq") +script = ExtResource("2_ioscy") + +[node name="PathfindObstacle" type="Node2D" parent="."] +script = ExtResource("3_8gi7h") +radius = 64.0 +added_weight = 0.1 +metadata/_custom_type_script = "uid://inyhfjkw5h2u" diff --git a/objects/turret.tscn b/objects/turret.tscn new file mode 100644 index 0000000..315778d --- /dev/null +++ b/objects/turret.tscn @@ -0,0 +1,48 @@ +[gd_scene load_steps=10 format=3 uid="uid://buveekbt35pk2"] + +[ext_resource type="Script" uid="uid://dqwkwjkvo374n" path="res://scripts/Turret.gd" id="1_50gud"] +[ext_resource type="PackedScene" uid="uid://dx2wpxj51mnju" path="res://objects/bullet.tscn" id="2_4h670"] +[ext_resource type="Resource" uid="uid://dtem6pgfrxmm7" path="res://items/bullet.res" id="3_s8ob3"] +[ext_resource type="Texture2D" uid="uid://ba7x80lx3rjsw" path="res://assets/turret.png" id="4_3q0ie"] +[ext_resource type="Script" uid="uid://bha4kv6d0iba0" path="res://scripts/Item.gd" id="4_ppeal"] +[ext_resource type="Script" uid="uid://inyhfjkw5h2u" path="res://scripts/PathfindObstacle.gd" id="5_4h670"] +[ext_resource type="Resource" uid="uid://cgxall2fn3bsn" path="res://items/copper.res" id="5_bn0qb"] +[ext_resource type="PackedScene" uid="uid://bul5wdylupx54" path="res://objects/parts/detection_area.tscn" id="8_ppeal"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_ppeal"] +radius = 32.0 + +[node name="Turret" type="StaticBody2D"] +collision_layer = 4 +collision_mask = 7 +input_pickable = true +script = ExtResource("1_50gud") +bullet_scene = ExtResource("2_4h670") +bullet_item = ExtResource("3_s8ob3") +fire_period = 0.1 +detection_poll_time = 0.1 +source_limit = 3 +build_materials_required = Dictionary[ExtResource("4_ppeal"), int]({ +ExtResource("5_bn0qb"): 8 +}) + +[node name="Sprite2D" type="Sprite2D" parent="."] +visible = false +texture = ExtResource("4_3q0ie") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_ppeal") + +[node name="Polygon2D" type="Polygon2D" parent="."] +color = Color(0, 0, 1, 1) +polygon = PackedVector2Array(-32, 0, -28, -16, -16, -28, 0, -32, 16, -28, 28, -16, 32, 0, 28, 16, 16, 28, 0, 32, -16, 28, -28, 16) + +[node name="PathfindObstacle" type="Node2D" parent="."] +script = ExtResource("5_4h670") +added_weight = 99.0 +metadata/_custom_type_script = "uid://inyhfjkw5h2u" + +[node name="DetectionArea" parent="." instance=ExtResource("8_ppeal")] +radius = 500.0 +requires_line_of_sight = true +active_state = null diff --git a/objects/watchtower.tscn b/objects/watchtower.tscn new file mode 100644 index 0000000..9bff51e --- /dev/null +++ b/objects/watchtower.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=7 format=3 uid="uid://x0r04ycx527j"] + +[ext_resource type="PackedScene" uid="uid://bkfr2sxxhhjcn" path="res://objects/building.tscn" id="1_q065r"] +[ext_resource type="Script" uid="uid://ck2p0rdh6q5vw" path="res://scripts/watchtower.gd" id="2_f5emh"] +[ext_resource type="Script" uid="uid://bha4kv6d0iba0" path="res://scripts/Item.gd" id="2_g682f"] +[ext_resource type="Texture2D" uid="uid://d22ptkg3yrygu" path="res://assets/watchtower.png" id="2_tvdeu"] +[ext_resource type="Resource" uid="uid://cgxall2fn3bsn" path="res://items/copper.res" id="3_augeu"] +[ext_resource type="PackedScene" uid="uid://bul5wdylupx54" path="res://objects/parts/detection_area.tscn" id="5_augeu"] + +[node name="Machine" instance=ExtResource("1_q065r")] +script = ExtResource("2_f5emh") +build_materials_required = Dictionary[ExtResource("2_g682f"), int]({ +ExtResource("3_augeu"): 3 +}) + +[node name="Sprite2D" parent="." index="2"] +texture = ExtResource("2_tvdeu") + +[node name="DetectionArea" parent="." index="3" instance=ExtResource("5_augeu")] +radius = 1500.0 +requires_line_of_sight = true +active_state = null diff --git a/path_follow_2d.gd b/path_follow_2d.gd new file mode 100644 index 0000000..4380d45 --- /dev/null +++ b/path_follow_2d.gd @@ -0,0 +1,4 @@ +extends PathFollow2D + +func _process(delta: float) -> void: + progress += delta * 100 diff --git a/path_follow_2d.gd.uid b/path_follow_2d.gd.uid new file mode 100644 index 0000000..755a98e --- /dev/null +++ b/path_follow_2d.gd.uid @@ -0,0 +1 @@ +uid://cecu23c6t1xig diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..80cee13 --- /dev/null +++ b/project.godot @@ -0,0 +1,78 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="TowerGameProto" +run/main_scene="uid://u5y7hylu4uva" +config/features=PackedStringArray("4.4") +config/icon="res://icon.svg" + +[debug] + +gdscript/warnings/untyped_declaration=1 +gdscript/warnings/inferred_declaration=1 +gdscript/warnings/unsafe_property_access=1 +gdscript/warnings/unsafe_method_access=1 +gdscript/warnings/unsafe_call_argument=1 + +[file_customization] + +folder_colors={ +"res://scripts/": "yellow" +} + +[global_group] + +Enemy="" +Buildings="" +Spawners="" +Citizens="" + +[input] + +camera_up={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +camera_down={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} +camera_left={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +camera_right={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} + +[layer_names] + +2d_physics/layer_1="Terrain" +2d_physics/layer_2="Enemies" +2d_physics/layer_3="Buildings" +2d_physics/layer_4="Projectiles" +2d_physics/layer_5="Citizens" +2d_physics/layer_32="Input" + +[physics] + +2d/default_gravity=0.0 + +[rendering] + +textures/canvas_textures/default_texture_filter=0 +textures/default_filters/use_nearest_mipmap_filter=true diff --git a/scene.tscn b/scene.tscn new file mode 100644 index 0000000..8e6c724 --- /dev/null +++ b/scene.tscn @@ -0,0 +1,290 @@ +[gd_scene load_steps=33 format=4 uid="uid://u5y7hylu4uva"] + +[ext_resource type="Texture2D" uid="uid://dadllqpm2l3fi" path="res://assets/tiles.png" id="1_m7jmp"] +[ext_resource type="Script" uid="uid://tndb4f3lkc7g" path="res://scripts/GameManager.gd" id="1_xpof7"] +[ext_resource type="Script" uid="uid://dentfojljr2f0" path="res://scripts/World.gd" id="3_8hm71"] +[ext_resource type="PackedScene" uid="uid://c4ra55vavvnge" path="res://objects/miner.tscn" id="5_8j1ou"] +[ext_resource type="PackedScene" uid="uid://bvpfnmtbexv0w" path="res://objects/processor.tscn" id="6_gu47o"] +[ext_resource type="PackedScene" uid="uid://buveekbt35pk2" path="res://objects/turret.tscn" id="7_8hm71"] +[ext_resource type="Resource" uid="uid://cgxall2fn3bsn" path="res://items/copper.res" id="7_73fnb"] +[ext_resource type="PackedScene" uid="uid://bh2tyagbwe13k" path="res://objects/splat.tscn" id="10_i6j5g"] +[ext_resource type="Script" uid="uid://dxo54c0g6uo6v" path="res://CitizenManager.gd" id="12_i6j5g"] +[ext_resource type="PackedScene" uid="uid://cs5hyqq024i3h" path="res://objects/citizen.tscn" id="13_1q4c1"] +[ext_resource type="PackedScene" uid="uid://bewbv5s2iesac" path="res://objects/conveyor.tscn" id="13_17rhs"] +[ext_resource type="Texture2D" uid="uid://c41pea1l3e5b8" path="res://assets/icons/miner.png" id="14_223my"] +[ext_resource type="PackedScene" uid="uid://ci2qx1cctt27p" path="res://objects/enemy.tscn" id="14_gu47o"] +[ext_resource type="Texture2D" uid="uid://dh2iqb21845yr" path="res://assets/icons/processor.png" id="16_8j1ou"] +[ext_resource type="Script" uid="uid://2rysy0w0dk7c" path="res://scripts/Spawner.gd" id="16_17rhs"] +[ext_resource type="PackedScene" uid="uid://dx2wpxj51mnju" path="res://objects/bullet.tscn" id="16_223my"] +[ext_resource type="Texture2D" uid="uid://c1mmxh7v77d8j" path="res://assets/icons/turret.png" id="17_8j1ou"] +[ext_resource type="Script" uid="uid://bxhqx5445f6r3" path="res://scripts/Camera.gd" id="18_8j1ou"] +[ext_resource type="Texture2D" uid="uid://cgbwagn11sku6" path="res://assets/icons/storage.png" id="18_302uq"] +[ext_resource type="Texture2D" uid="uid://cfu3m8pss1ph8" path="res://assets/icons/conveyor2.png" id="18_o3hm7"] +[ext_resource type="PackedScene" uid="uid://0vvjqh8xyqg8" path="res://objects/Storage.tscn" id="18_xpof7"] +[ext_resource type="Script" uid="uid://c8bkwna465q5i" path="res://scripts/BuildButton.gd" id="19_o3hm7"] +[ext_resource type="Script" uid="uid://de84jpof8rcc3" path="res://scripts/spawners_active_button.gd" id="23_aobyt"] +[ext_resource type="PackedScene" uid="uid://x0r04ycx527j" path="res://objects/watchtower.tscn" id="23_g6g5t"] +[ext_resource type="Script" uid="uid://dhm0h03mw4rbo" path="res://item_list.gd" id="23_i6j5g"] +[ext_resource type="Texture2D" uid="uid://kp4ghn1277as" path="res://assets/icons/watchtower.png" id="23_iss77"] + +[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_8hm71"] + +[sub_resource type="OccluderPolygon2D" id="OccluderPolygon2D_fy5k1"] +polygon = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_xlvrw"] +texture = ExtResource("1_m7jmp") +texture_region_size = Vector2i(64, 64) +0:0/0 = 0 +0:0/0/custom_data_1 = 1.0 +1:0/0 = 0 +1:0/0/occlusion_layer_0/polygon_0/polygon = SubResource("OccluderPolygon2D_fy5k1") +1:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-31.9208, -31.9495, 32.0355, -31.9495, 32.0355, 32.0068, -32.0355, 31.9495) +2:0/0 = 0 +2:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-31.9208, -31.9495, 32.0355, -31.9495, 32.0355, 32.0068, -32.0355, 31.9495) +3:0/0 = 0 +4:0/0 = 0 +5:0/0 = 0 +6:0/0 = 0 +7:0/0 = 0 +0:1/0 = 0 +0:1/0/custom_data_0 = ExtResource("7_73fnb") +0:1/0/custom_data_1 = 0.8 +1:1/0 = 0 +2:1/0 = 0 +3:1/0 = 0 +4:1/0 = 0 +5:1/0 = 0 +6:1/0 = 0 +7:1/0 = 0 +0:2/0 = 0 +1:2/0 = 0 +2:2/0 = 0 +3:2/0 = 0 +4:2/0 = 0 +5:2/0 = 0 +6:2/0 = 0 +7:2/0 = 0 +0:3/0 = 0 +1:3/0 = 0 +2:3/0 = 0 +3:3/0 = 0 +4:3/0 = 0 +5:3/0 = 0 +6:3/0 = 0 +7:3/0 = 0 + +[sub_resource type="TileSet" id="TileSet_73fnb"] +tile_size = Vector2i(64, 64) +occlusion_layer_0/light_mask = 1 +physics_layer_0/collision_layer = 1 +physics_layer_0/physics_material = SubResource("PhysicsMaterial_8hm71") +custom_data_layer_0/name = "Ore" +custom_data_layer_0/type = 24 +custom_data_layer_1/name = "Movement Speed" +custom_data_layer_1/type = 3 +sources/0 = SubResource("TileSetAtlasSource_xlvrw") + +[sub_resource type="Gradient" id="Gradient_5c1cw"] +colors = PackedColorArray(1, 1, 1, 1, 0, 0, 0, 1) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_akxrc"] +gradient = SubResource("Gradient_5c1cw") +width = 420 +height = 420 +fill = 1 +fill_from = Vector2(0.5, 0.5) +fill_to = Vector2(1, 0.5) + +[node name="Scene" type="Node2D"] +script = ExtResource("1_xpof7") + +[node name="CitizenManager" type="Node" parent="."] +script = ExtResource("12_i6j5g") + +[node name="TileMap" type="TileMapLayer" parent="."] +z_index = -10 +use_parent_material = true +tile_map_data = PackedByteArray("AAACAAAAAAABAAAAAAADAAAAAAABAAAAAAABAAEAAAABAAAAAAAAAAIAAAABAAAAAAAAAAMAAAABAAAAAAAAAAQAAAABAAAAAAAAAAUAAAABAAAAAAAAAAYAAAABAAAAAAAAAAcAAAABAAAAAAAAAAgAAAABAAAAAAAAAAkAAAABAAAAAAABAAIAAAABAAAAAAABAAMAAAABAAAAAAABAAQAAAABAAAAAAABAAUAAAAAAAEAAAABAAYAAAAAAAAAAAABAAcAAAAAAAAAAAABAAgAAAAAAAAAAAABAAkAAAAAAAAAAAACAAEAAAABAAAAAAACAAIAAAABAAAAAAACAAMAAAABAAAAAAACAAQAAAAAAAEAAAACAAUAAAAAAAEAAAACAAYAAAAAAAAAAAACAAcAAAAAAAAAAAACAAgAAAAAAAAAAAACAAkAAAAAAAAAAAADAAEAAAABAAAAAAADAAIAAAABAAAAAAADAAMAAAAAAAEAAAADAAQAAAAAAAEAAAADAAUAAAAAAAEAAAADAAYAAAAAAAAAAAADAAcAAAAAAAAAAAADAAgAAAAAAAAAAAADAAkAAAAAAAAAAAAEAAAAAAABAAAAAAAEAAEAAAABAAAAAAAEAAMAAAAAAAEAAAAEAAQAAAAAAAAAAAAEAAUAAAAAAAAAAAAEAAYAAAAAAAAAAAAEAAcAAAAAAAAAAAAEAAgAAAAAAAAAAAAEAAkAAAAAAAAAAAAFAAAAAAABAAAAAAAFAAEAAAABAAAAAAAFAAIAAAAAAAEAAAAFAAMAAAAAAAAAAAAFAAQAAAAAAAAAAAAFAAUAAAAAAAAAAAAFAAYAAAAAAAAAAAAFAAcAAAAAAAAAAAAFAAgAAAAAAAAAAAAFAAkAAAAAAAAAAAAGAAAAAAABAAAAAAAGAAEAAAABAAAAAAAGAAIAAAAAAAEAAAAGAAMAAAAAAAAAAAAGAAQAAAAAAAAAAAAGAAUAAAAAAAAAAAAGAAYAAAAAAAAAAAAGAAcAAAAAAAAAAAAGAAgAAAAAAAAAAAAGAAkAAAAAAAAAAAAHAAAAAAABAAAAAAAHAAEAAAAAAAAAAAAHAAIAAAAAAAAAAAAHAAMAAAAAAAAAAAAHAAQAAAAAAAAAAAAHAAUAAAAAAAAAAAAHAAYAAAAAAAAAAAAHAAcAAAAAAAAAAAAHAAgAAAAAAAAAAAAHAAkAAAAAAAAAAAAIAAAAAAABAAAAAAAIAAEAAAAAAAAAAAAIAAIAAAAAAAAAAAAIAAMAAAAAAAAAAAAIAAQAAAAAAAAAAAAIAAUAAAAAAAAAAAAIAAYAAAAAAAAAAAAIAAcAAAAAAAAAAAAIAAgAAAAAAAAAAAAIAAkAAAAAAAAAAAAJAAAAAAABAAAAAAAJAAEAAAAAAAAAAAAJAAIAAAAAAAAAAAAJAAMAAAAAAAAAAAAJAAQAAAAAAAAAAAAJAAUAAAAAAAAAAAAJAAYAAAAAAAAAAAAJAAcAAAAAAAAAAAAJAAgAAAAAAAAAAAAJAAkAAAAAAAAAAAAKAAAAAAABAAAAAAAKAAEAAAAAAAAAAAAKAAIAAAAAAAAAAAAKAAMAAAAAAAAAAAAKAAQAAAAAAAAAAAAKAAUAAAAAAAAAAAAKAAYAAAAAAAAAAAAKAAcAAAAAAAAAAAAKAAgAAAAAAAAAAAAKAAkAAAAAAAAAAAALAAAAAAABAAAAAAALAAEAAAAAAAAAAAALAAIAAAABAAAAAAALAAMAAAABAAAAAAALAAQAAAAAAAAAAAALAAUAAAAAAAAAAAALAAYAAAAAAAAAAAALAAcAAAAAAAAAAAALAAgAAAAAAAAAAAALAAkAAAAAAAAAAAAMAAAAAAABAAAAAAAMAAEAAAAAAAAAAAAMAAIAAAABAAAAAAAMAAMAAAABAAAAAAAMAAQAAAABAAAAAAAMAAUAAAAAAAAAAAAMAAYAAAAAAAAAAAAMAAcAAAAAAAAAAAAMAAgAAAAAAAAAAAAMAAkAAAAAAAAAAAANAAAAAAABAAAAAAANAAEAAAAAAAAAAAANAAIAAAAAAAAAAAANAAMAAAABAAAAAAANAAQAAAABAAAAAAANAAUAAAAAAAAAAAANAAYAAAABAAAAAAANAAcAAAAAAAAAAAANAAgAAAAAAAAAAAANAAkAAAAAAAAAAAAOAAAAAAABAAAAAAAOAAEAAAAAAAAAAAAOAAIAAAAAAAAAAAAOAAMAAAABAAAAAAAOAAQAAAAAAAEAAAAOAAUAAAABAAAAAAAOAAYAAAAAAAAAAAAOAAcAAAAAAAAAAAAOAAgAAAAAAAAAAAAOAAkAAAABAAAAAAAPAAAAAAABAAAAAAAPAAEAAAAAAAAAAAAPAAIAAAAAAAAAAAAPAAMAAAABAAAAAAAPAAQAAAAAAAEAAAAPAAUAAAABAAAAAAAPAAYAAAAAAAAAAAAPAAcAAAAAAAAAAAAPAAgAAAAAAAAAAAAPAAkAAAABAAAAAAAQAAAAAAABAAAAAAAQAAEAAAAAAAAAAAAQAAIAAAAAAAAAAAAQAAMAAAABAAAAAAAQAAQAAAAAAAEAAAAQAAUAAAABAAAAAAAQAAYAAAAAAAAAAAAQAAcAAAAAAAAAAAAQAAgAAAAAAAAAAAAQAAkAAAAAAAAAAAARAAAAAAABAAAAAAARAAEAAAAAAAAAAAARAAIAAAAAAAAAAAARAAMAAAAAAAAAAAARAAQAAAABAAAAAAARAAUAAAAAAAAAAAARAAYAAAAAAAAAAAARAAcAAAAAAAAAAAARAAgAAAAAAAAAAAARAAkAAAAAAAAAAAAAAAoAAAABAAAAAAAAAAsAAAABAAAAAAAAAAwAAAABAAAAAAAAAA0AAAABAAAAAAAAAA4AAAABAAAAAAAAAA8AAAABAAAAAAAAABAAAAABAAAAAAAAABEAAAABAAAAAAAAABIAAAABAAAAAAAAABMAAAABAAAAAAAAABQAAAABAAAAAAAAABUAAAABAAAAAAAAABYAAAABAAAAAAAAABcAAAABAAAAAAAAABgAAAABAAAAAAAAABkAAAABAAAAAAAAABoAAAABAAAAAAABAAoAAAAAAAAAAAABAAsAAAAAAAAAAAABAAwAAAAAAAAAAAABAA0AAAAAAAAAAAABAA4AAAAAAAAAAAABAA8AAAAAAAAAAAABABAAAAAAAAAAAAABABEAAAAAAAAAAAABABIAAAAAAAAAAAABABMAAAABAAAAAAABABQAAAABAAAAAAABABUAAAABAAAAAAABABYAAAABAAAAAAABABcAAAABAAAAAAABABgAAAABAAAAAAABABkAAAABAAAAAAABABoAAAABAAAAAAACAAoAAAAAAAAAAAACAAsAAAAAAAAAAAACAAwAAAAAAAAAAAACAA0AAAAAAAAAAAACAA4AAAAAAAAAAAACAA8AAAAAAAAAAAACABAAAAAAAAAAAAACABEAAAAAAAAAAAACABIAAAAAAAAAAAACABMAAAAAAAAAAAACABQAAAAAAAAAAAACABUAAAAAAAAAAAACABYAAAAAAAEAAAACABcAAAAAAAEAAAACABgAAAAAAAAAAAACABkAAAABAAAAAAACABoAAAABAAAAAAADAAoAAAAAAAAAAAADAAsAAAAAAAAAAAADAAwAAAAAAAAAAAADAA0AAAAAAAAAAAADAA4AAAAAAAAAAAADAA8AAAAAAAAAAAADABAAAAAAAAAAAAADABEAAAAAAAAAAAADABIAAAAAAAAAAAADABMAAAAAAAAAAAADABQAAAAAAAAAAAADABUAAAAAAAAAAAADABYAAAAAAAAAAAADABcAAAAAAAAAAAADABgAAAAAAAAAAAADABkAAAAAAAAAAAADABoAAAAAAAAAAAAEAAoAAAAAAAAAAAAEAAsAAAABAAAAAAAEAAwAAAABAAAAAAAEAA0AAAABAAAAAAAEAA4AAAAAAAAAAAAEAA8AAAAAAAAAAAAEABAAAAABAAAAAAAEABEAAAABAAAAAAAEABIAAAABAAAAAAAEABMAAAABAAAAAAAEABQAAAABAAAAAAAEABUAAAABAAAAAAAEABYAAAAAAAAAAAAEABcAAAAAAAAAAAAEABgAAAAAAAAAAAAEABkAAAAAAAAAAAAEABoAAAAAAAAAAAAFAAoAAAABAAAAAAAFAAsAAAABAAAAAAAFAAwAAAAAAAEAAAAFAA0AAAAAAAAAAAAFAA4AAAAAAAAAAAAFAA8AAAABAAAAAAAFABAAAAABAAAAAAAFABEAAAABAAAAAAAFABIAAAABAAAAAAAFABMAAAABAAAAAAAFABQAAAABAAAAAAAFABUAAAAAAAAAAAAFABYAAAAAAAAAAAAFABcAAAAAAAAAAAAFABgAAAAAAAAAAAAFABkAAAAAAAAAAAAFABoAAAAAAAAAAAAGAAoAAAABAAAAAAAGAAsAAAAAAAEAAAAGAAwAAAAAAAAAAAAGAA0AAAAAAAAAAAAGAA4AAAAAAAAAAAAGAA8AAAAAAAAAAAAGABAAAAAAAAEAAAAGABEAAAABAAAAAAAGABIAAAABAAAAAAAGABMAAAAAAAAAAAAGABQAAAAAAAAAAAAGABUAAAAAAAAAAAAGABYAAAAAAAAAAAAGABcAAAAAAAAAAAAGABgAAAAAAAAAAAAGABkAAAAAAAAAAAAGABoAAAAAAAAAAAAHAAoAAAABAAAAAAAHAAsAAAAAAAAAAAAHAAwAAAAAAAAAAAAHAA0AAAAAAAAAAAAHAA4AAAAAAAAAAAAHAA8AAAAAAAAAAAAHABAAAAAAAAAAAAAHABEAAAAAAAAAAAAHABIAAAAAAAAAAAAHABMAAAAAAAAAAAAHABQAAAAAAAAAAAAHABUAAAAAAAAAAAAHABYAAAAAAAAAAAAHABcAAAAAAAAAAAAHABgAAAAAAAAAAAAHABkAAAAAAAAAAAAHABoAAAAAAAAAAAAIAAoAAAABAAAAAAAIAAsAAAABAAAAAAAIAAwAAAAAAAAAAAAIAA0AAAAAAAAAAAAIAA4AAAAAAAAAAAAIAA8AAAAAAAAAAAAIABAAAAAAAAAAAAAIABEAAAAAAAAAAAAIABIAAAAAAAAAAAAIABMAAAAAAAAAAAAIABQAAAAAAAAAAAAIABUAAAAAAAAAAAAIABYAAAAAAAAAAAAIABcAAAAAAAAAAAAIABgAAAAAAAAAAAAIABkAAAAAAAAAAAAIABoAAAAAAAAAAAAJAAoAAAAAAAAAAAAJAAsAAAABAAAAAAAJAAwAAAAAAAAAAAAJAA0AAAAAAAAAAAAJAA4AAAAAAAAAAAAJAA8AAAAAAAAAAAAJABAAAAABAAAAAAAJABEAAAABAAAAAAAJABIAAAABAAAAAAAJABMAAAABAAAAAAAJABQAAAABAAAAAAAJABUAAAABAAAAAAAJABYAAAABAAAAAAAJABcAAAAAAAAAAAAJABgAAAAAAAAAAAAJABkAAAAAAAAAAAAJABoAAAAAAAAAAAAKAAoAAAAAAAAAAAAKAAsAAAAAAAAAAAAKAAwAAAAAAAAAAAAKAA0AAAAAAAAAAAAKAA4AAAAAAAAAAAAKAA8AAAAAAAAAAAAKABAAAAABAAAAAAAKABEAAAABAAAAAAAKABIAAAABAAAAAAAKABMAAAAAAAAAAAAKABQAAAAAAAAAAAAKABUAAAABAAAAAAAKABYAAAABAAAAAAAKABcAAAAAAAAAAAAKABgAAAAAAAAAAAAKABkAAAAAAAAAAAAKABoAAAAAAAAAAAALAAoAAAAAAAAAAAALAAsAAAAAAAAAAAALAAwAAAAAAAAAAAALAA0AAAAAAAAAAAALAA4AAAAAAAAAAAALAA8AAAAAAAAAAAALABAAAAABAAAAAAALABEAAAABAAAAAAALABIAAAABAAAAAAALABMAAAAAAAAAAAALABQAAAAAAAAAAAALABUAAAABAAAAAAALABYAAAABAAAAAAALABcAAAAAAAAAAAALABgAAAAAAAAAAAALABkAAAAAAAAAAAALABoAAAAAAAAAAAAMAAoAAAAAAAAAAAAMAAsAAAABAAAAAAAMAAwAAAABAAAAAAAMAA0AAAABAAAAAAAMAA4AAAAAAAAAAAAMAA8AAAAAAAAAAAAMABAAAAAAAAAAAAAMABEAAAAAAAAAAAAMABIAAAAAAAAAAAAMABMAAAAAAAAAAAAMABQAAAAAAAAAAAAMABUAAAAAAAAAAAAMABYAAAABAAAAAAAMABcAAAAAAAAAAAAMABgAAAAAAAAAAAAMABkAAAAAAAAAAAAMABoAAAABAAAAAAANAAoAAAAAAAAAAAANAAsAAAAAAAAAAAANAAwAAAABAAAAAAANAA0AAAABAAAAAAANAA4AAAAAAAAAAAANAA8AAAAAAAAAAAANABAAAAAAAAAAAAANABEAAAAAAAAAAAANABIAAAAAAAAAAAANABMAAAAAAAAAAAANABQAAAAAAAAAAAANABUAAAAAAAAAAAANABYAAAAAAAAAAAANABcAAAAAAAAAAAANABgAAAAAAAAAAAANABkAAAAAAAAAAAANABoAAAABAAAAAAAOAAoAAAAAAAAAAAAOAAsAAAAAAAAAAAAOAAwAAAABAAAAAAAOAA0AAAAAAAEAAAAOAA4AAAAAAAAAAAAOAA8AAAAAAAAAAAAOABAAAAAAAAAAAAAOABEAAAAAAAAAAAAOABIAAAAAAAAAAAAOABMAAAAAAAAAAAAOABQAAAAAAAAAAAAOABUAAAAAAAAAAAAOABYAAAAAAAAAAAAOABcAAAAAAAAAAAAOABgAAAAAAAAAAAAOABkAAAAAAAAAAAAOABoAAAABAAAAAAAPAAoAAAAAAAAAAAAPAAsAAAABAAAAAAAPAAwAAAAAAAEAAAAPAA0AAAAAAAEAAAAPAA4AAAABAAAAAAAPAA8AAAABAAAAAAAPABAAAAABAAAAAAAPABEAAAABAAAAAAAPABIAAAAAAAAAAAAPABMAAAAAAAAAAAAPABQAAAAAAAAAAAAPABUAAAAAAAAAAAAPABYAAAAAAAAAAAAPABcAAAAAAAAAAAAPABgAAAAAAAAAAAAPABkAAAAAAAAAAAAPABoAAAAAAAAAAAAQAAoAAAABAAAAAAAQAAsAAAABAAAAAAAQAAwAAAABAAAAAAAQAA0AAAABAAAAAAAQAA4AAAABAAAAAAAQAA8AAAABAAAAAAAQABAAAAABAAAAAAAQABEAAAABAAAAAAAQABIAAAAAAAAAAAAQABMAAAAAAAAAAAAQABQAAAAAAAAAAAAQABUAAAAAAAAAAAAQABYAAAAAAAAAAAAQABcAAAAAAAAAAAAQABgAAAAAAAAAAAAQABkAAAAAAAAAAAAQABoAAAAAAAEAAAARAAoAAAAAAAAAAAARAAsAAAABAAAAAAARAAwAAAABAAAAAAARAA0AAAABAAAAAAARAA4AAAABAAAAAAARAA8AAAABAAAAAAARABAAAAABAAAAAAARABEAAAAAAAAAAAARABIAAAAAAAAAAAARABMAAAAAAAAAAAARABQAAAABAAAAAAARABUAAAABAAAAAAARABYAAAABAAAAAAARABcAAAAAAAAAAAARABgAAAAAAAAAAAARABkAAAAAAAAAAAARABoAAAAAAAEAAAASAAAAAAABAAAAAAASAAEAAAABAAAAAAASAAIAAAAAAAAAAAASAAMAAAAAAAAAAAASAAQAAAAAAAAAAAASAAUAAAAAAAAAAAASAAYAAAAAAAAAAAASAAcAAAAAAAAAAAASAAgAAAAAAAAAAAASAAkAAAAAAAAAAAASAAoAAAAAAAAAAAASAAsAAAAAAAAAAAASAAwAAAAAAAAAAAASAA0AAAABAAAAAAASAA4AAAABAAAAAAASAA8AAAABAAAAAAASABAAAAAAAAAAAAASABEAAAAAAAAAAAASABIAAAAAAAAAAAASABMAAAABAAAAAAASABQAAAABAAAAAAASABUAAAAAAAAAAAASABYAAAAAAAAAAAASABcAAAAAAAAAAAASABgAAAAAAAAAAAASABkAAAAAAAAAAAASABoAAAAAAAAAAAATAAAAAAABAAAAAAATAAEAAAABAAAAAAATAAIAAAAAAAAAAAATAAMAAAAAAAAAAAATAAQAAAAAAAAAAAATAAUAAAAAAAAAAAATAAYAAAAAAAAAAAATAAcAAAAAAAAAAAATAAgAAAABAAAAAAATAAkAAAABAAAAAAATAAoAAAABAAAAAAATAAsAAAABAAAAAAATAAwAAAAAAAAAAAATAA0AAAABAAAAAAATAA4AAAABAAAAAAATAA8AAAABAAAAAAATABAAAAAAAAAAAAATABEAAAAAAAAAAAATABIAAAAAAAAAAAATABMAAAABAAAAAAATABQAAAAAAAAAAAATABUAAAAAAAAAAAATABYAAAAAAAAAAAATABcAAAAAAAAAAAATABgAAAAAAAAAAAATABkAAAAAAAAAAAATABoAAAAAAAAAAAAUAAAAAAABAAAAAAAUAAEAAAABAAAAAAAUAAIAAAAAAAAAAAAUAAMAAAAAAAAAAAAUAAQAAAABAAAAAAAUAAUAAAABAAAAAAAUAAYAAAAAAAAAAAAUAAcAAAAAAAAAAAAUAAgAAAABAAAAAAAUAAkAAAABAAAAAAAUAAoAAAABAAAAAAAUAAsAAAABAAAAAAAUAAwAAAAAAAAAAAAUAA0AAAAAAAAAAAAUAA4AAAAAAAAAAAAUAA8AAAABAAAAAAAUABAAAAAAAAAAAAAUABEAAAAAAAAAAAAUABIAAAAAAAAAAAAUABMAAAAAAAAAAAAUABQAAAAAAAAAAAAUABUAAAAAAAAAAAAUABYAAAAAAAAAAAAUABcAAAAAAAAAAAAUABgAAAAAAAAAAAAUABkAAAAAAAAAAAAUABoAAAAAAAAAAAAVAAAAAAABAAAAAAAVAAEAAAAAAAAAAAAVAAIAAAAAAAAAAAAVAAMAAAAAAAAAAAAVAAQAAAABAAAAAAAVAAUAAAABAAAAAAAVAAYAAAAAAAAAAAAVAAcAAAAAAAAAAAAVAAgAAAAAAAAAAAAVAAkAAAAAAAAAAAAVAAoAAAAAAAAAAAAVAAsAAAAAAAAAAAAVAAwAAAAAAAAAAAAVAA0AAAAAAAAAAAAVAA4AAAAAAAAAAAAVAA8AAAAAAAAAAAAVABAAAAAAAAAAAAAVABEAAAAAAAAAAAAVABIAAAAAAAAAAAAVABMAAAAAAAAAAAAVABQAAAAAAAAAAAAVABUAAAAAAAAAAAAVABYAAAAAAAAAAAAVABcAAAAAAAAAAAAVABgAAAAAAAAAAAAVABkAAAAAAAAAAAAVABoAAAAAAAAAAAAWAAAAAAABAAAAAAAWAAEAAAAAAAAAAAAWAAIAAAAAAAAAAAAWAAMAAAAAAAAAAAAWAAQAAAABAAAAAAAWAAUAAAABAAAAAAAWAAYAAAAAAAAAAAAWAAcAAAAAAAAAAAAWAAgAAAAAAAAAAAAWAAkAAAAAAAAAAAAWAAoAAAAAAAAAAAAWAAsAAAAAAAAAAAAWAAwAAAAAAAAAAAAWAA0AAAAAAAAAAAAWAA4AAAAAAAAAAAAWAA8AAAAAAAAAAAAWABAAAAAAAAAAAAAWABEAAAAAAAAAAAAWABIAAAAAAAAAAAAWABMAAAAAAAAAAAAWABQAAAAAAAAAAAAWABUAAAAAAAAAAAAWABYAAAAAAAAAAAAWABcAAAAAAAAAAAAWABgAAAAAAAAAAAAWABkAAAAAAAAAAAAWABoAAAAAAAAAAAAXAAAAAAABAAAAAAAXAAEAAAAAAAAAAAAXAAIAAAAAAAAAAAAXAAMAAAAAAAAAAAAXAAQAAAABAAAAAAAXAAUAAAABAAAAAAAXAAYAAAABAAAAAAAXAAcAAAAAAAAAAAAXAAgAAAAAAAAAAAAXAAkAAAAAAAAAAAAXAAoAAAAAAAAAAAAXAAsAAAAAAAAAAAAXAAwAAAAAAAAAAAAXAA0AAAABAAAAAAAXAA4AAAABAAAAAAAXAA8AAAABAAAAAAAXABAAAAABAAAAAAAXABEAAAABAAAAAAAXABIAAAAAAAAAAAAXABMAAAAAAAAAAAAXABQAAAAAAAAAAAAXABUAAAAAAAAAAAAXABYAAAAAAAAAAAAXABcAAAAAAAAAAAAXABgAAAAAAAAAAAAXABkAAAAAAAAAAAAXABoAAAAAAAAAAAAYAAAAAAABAAAAAAAYAAEAAAAAAAAAAAAYAAIAAAAAAAAAAAAYAAMAAAAAAAAAAAAYAAQAAAABAAAAAAAYAAUAAAABAAAAAAAYAAYAAAABAAAAAAAYAAcAAAAAAAAAAAAYAAgAAAAAAAAAAAAYAAkAAAAAAAAAAAAYAAoAAAAAAAAAAAAYAAsAAAABAAAAAAAYAAwAAAAAAAEAAAAYAA0AAAAAAAEAAAAYAA4AAAABAAAAAAAYAA8AAAABAAAAAAAYABAAAAABAAAAAAAYABEAAAABAAAAAAAYABIAAAAAAAAAAAAYABMAAAAAAAAAAAAYABQAAAAAAAAAAAAYABUAAAAAAAAAAAAYABYAAAAAAAAAAAAYABcAAAAAAAAAAAAYABgAAAAAAAAAAAAYABkAAAAAAAAAAAAYABoAAAAAAAAAAAAZAAAAAAABAAAAAAAZAAEAAAAAAAAAAAAZAAIAAAAAAAAAAAAZAAMAAAAAAAAAAAAZAAQAAAAAAAAAAAAZAAUAAAAAAAAAAAAZAAYAAAAAAAAAAAAZAAcAAAAAAAAAAAAZAAgAAAAAAAAAAAAZAAkAAAAAAAAAAAAZAAoAAAAAAAAAAAAZAAsAAAABAAAAAAAZAAwAAAABAAAAAAAZAA0AAAAAAAEAAAAZAA4AAAAAAAAAAAAZAA8AAAAAAAAAAAAZABAAAAAAAAAAAAAZABEAAAAAAAAAAAAZABIAAAAAAAAAAAAZABMAAAAAAAAAAAAZABQAAAAAAAAAAAAZABUAAAAAAAAAAAAZABYAAAAAAAAAAAAZABcAAAAAAAAAAAAZABgAAAAAAAAAAAAZABkAAAAAAAAAAAAZABoAAAAAAAAAAAAaAAAAAAAAAAAAAAAaAAEAAAAAAAAAAAAaAAIAAAAAAAAAAAAaAAMAAAAAAAAAAAAaAAQAAAAAAAAAAAAaAAUAAAAAAAAAAAAaAAYAAAAAAAAAAAAaAAcAAAAAAAAAAAAaAAgAAAAAAAAAAAAaAAkAAAAAAAAAAAAaAAoAAAAAAAAAAAAaAAsAAAAAAAAAAAAaAAwAAAAAAAAAAAAaAA0AAAAAAAAAAAAaAA4AAAAAAAAAAAAaAA8AAAAAAAAAAAAaABAAAAAAAAAAAAAaABEAAAAAAAAAAAAaABIAAAAAAAAAAAAaABMAAAAAAAAAAAAaABQAAAAAAAAAAAAaABUAAAAAAAAAAAAaABYAAAAAAAAAAAAaABcAAAAAAAAAAAAaABgAAAAAAAAAAAAaABkAAAAAAAAAAAAaABoAAAAAAAAAAAAbAAAAAAAAAAAAAAAbAAEAAAAAAAAAAAAbAAIAAAAAAAAAAAAbAAMAAAAAAAAAAAAbAAQAAAAAAAAAAAAbAAUAAAAAAAAAAAAbAAYAAAAAAAAAAAAbAAcAAAAAAAAAAAAbAAgAAAAAAAAAAAAbAAkAAAAAAAAAAAAbAAoAAAAAAAAAAAAbAAsAAAAAAAAAAAAbAAwAAAAAAAAAAAAbAA0AAAAAAAAAAAAbAA4AAAAAAAAAAAAbAA8AAAAAAAAAAAAbABAAAAAAAAAAAAAbABEAAAABAAAAAAAbABIAAAABAAAAAAAbABMAAAABAAAAAAAbABQAAAAAAAAAAAAbABUAAAAAAAAAAAAbABYAAAAAAAAAAAAbABcAAAAAAAAAAAAbABgAAAAAAAAAAAAbABkAAAAAAAAAAAAbABoAAAAAAAAAAAAAAAEAAAABAAAAAAABAAAAAAABAAAAAAAAAAAAAAABAAAAAAAEAAIAAAAAAAEAAAAAABsAAAABAAAAAAAAABwAAAABAAAAAAAAAB0AAAABAAAAAAAAAB4AAAABAAAAAAAAAB8AAAABAAAAAAAAACAAAAABAAAAAAAAACEAAAABAAAAAAAAACIAAAABAAAAAAAAACMAAAAAAAAAAAAAACQAAAAAAAAAAAAAACUAAAAAAAAAAAAAACYAAAAAAAAAAAAAACcAAAAAAAAAAAAAACgAAAAAAAAAAAAAACkAAAAAAAAAAAAAACoAAAABAAAAAAAAACsAAAABAAAAAAAAACwAAAABAAAAAAAAAC0AAAABAAAAAAABABsAAAABAAAAAAABABwAAAABAAAAAAABAB0AAAABAAAAAAABAB4AAAABAAAAAAABAB8AAAABAAAAAAABACAAAAABAAAAAAABACEAAAABAAAAAAABACIAAAAAAAAAAAABACMAAAAAAAAAAAABACQAAAAAAAAAAAABACUAAAAAAAAAAAABACYAAAAAAAAAAAABACcAAAAAAAAAAAABACgAAAAAAAAAAAABACkAAAAAAAAAAAABACoAAAAAAAAAAAABACsAAAABAAAAAAABACwAAAABAAAAAAABAC0AAAABAAAAAAACABsAAAAAAAAAAAACABwAAAAAAAAAAAACAB0AAAAAAAAAAAACAB4AAAABAAAAAAACAB8AAAABAAAAAAACACAAAAAAAAAAAAACACEAAAAAAAAAAAACACIAAAAAAAAAAAACACMAAAAAAAAAAAACACQAAAAAAAAAAAACACUAAAAAAAAAAAACACYAAAAAAAAAAAACACcAAAAAAAAAAAACACgAAAAAAAAAAAACACkAAAAAAAAAAAACACoAAAAAAAAAAAACACsAAAAAAAAAAAACACwAAAAAAAAAAAACAC0AAAABAAAAAAADABsAAAAAAAAAAAADABwAAAAAAAAAAAADAB0AAAAAAAAAAAADAB4AAAAAAAAAAAADAB8AAAAAAAAAAAADACAAAAAAAAAAAAADACEAAAAAAAAAAAADACIAAAAAAAAAAAADACMAAAAAAAAAAAADACQAAAAAAAAAAAADACUAAAAAAAAAAAADACYAAAAAAAAAAAADACcAAAAAAAAAAAADACgAAAAAAAAAAAADACkAAAAAAAAAAAADACoAAAAAAAAAAAADACsAAAAAAAAAAAADACwAAAAAAAAAAAADAC0AAAAAAAAAAAAEABsAAAAAAAAAAAAEABwAAAAAAAAAAAAEAB0AAAAAAAAAAAAEAB4AAAAAAAAAAAAEAB8AAAAAAAAAAAAEACAAAAAAAAAAAAAEACEAAAAAAAAAAAAEACIAAAAAAAAAAAAEACMAAAAAAAAAAAAEACQAAAAAAAAAAAAEACUAAAAAAAAAAAAEACYAAAAAAAAAAAAEACcAAAAAAAAAAAAEACgAAAAAAAAAAAAEACkAAAAAAAAAAAAEACoAAAAAAAAAAAAEACsAAAAAAAAAAAAEACwAAAAAAAAAAAAEAC0AAAAAAAAAAAAFABsAAAAAAAAAAAAFABwAAAABAAAAAAAFAB0AAAABAAAAAAAFAB4AAAABAAAAAAAFAB8AAAABAAAAAAAFACAAAAAAAAAAAAAFACEAAAAAAAAAAAAFACIAAAAAAAAAAAAFACMAAAAAAAAAAAAFACQAAAABAAAAAAAFACUAAAABAAAAAAAFACYAAAABAAAAAAAFACcAAAAAAAAAAAAFACgAAAAAAAAAAAAFACkAAAAAAAAAAAAFACoAAAAAAAAAAAAFACsAAAAAAAAAAAAFACwAAAAAAAAAAAAFAC0AAAAAAAAAAAAGABsAAAAAAAAAAAAGABwAAAABAAAAAAAGAB0AAAABAAAAAAAGAB4AAAABAAAAAAAGAB8AAAABAAAAAAAGACAAAAAAAAEAAAAGACEAAAAAAAAAAAAGACIAAAAAAAAAAAAGACMAAAAAAAAAAAAGACQAAAABAAAAAAAGACUAAAABAAAAAAAGACYAAAABAAAAAAAGACcAAAAAAAAAAAAGACgAAAAAAAAAAAAGACkAAAAAAAAAAAAGACoAAAAAAAAAAAAGACsAAAAAAAAAAAAGACwAAAAAAAAAAAAGAC0AAAAAAAAAAAAHABsAAAAAAAAAAAAHABwAAAABAAAAAAAHAB0AAAABAAAAAAAHAB4AAAABAAAAAAAHAB8AAAABAAAAAAAHACAAAAAAAAEAAAAHACEAAAAAAAAAAAAHACIAAAAAAAAAAAAHACMAAAAAAAAAAAAHACQAAAABAAAAAAAHACUAAAABAAAAAAAHACYAAAAAAAAAAAAHACcAAAAAAAAAAAAHACgAAAAAAAAAAAAHACkAAAAAAAAAAAAHACoAAAAAAAAAAAAHACsAAAABAAAAAAAHACwAAAABAAAAAAAHAC0AAAAAAAAAAAAIABsAAAAAAAAAAAAIABwAAAABAAAAAAAIAB0AAAABAAAAAAAIAB4AAAAAAAAAAAAIAB8AAAAAAAAAAAAIACAAAAAAAAAAAAAIACEAAAAAAAAAAAAIACIAAAAAAAAAAAAIACMAAAAAAAAAAAAIACQAAAAAAAAAAAAIACUAAAAAAAAAAAAIACYAAAAAAAAAAAAIACcAAAAAAAAAAAAIACgAAAAAAAAAAAAIACkAAAAAAAAAAAAIACoAAAABAAAAAAAIACsAAAABAAAAAAAIACwAAAABAAAAAAAIAC0AAAABAAAAAAAJABsAAAAAAAAAAAAJABwAAAAAAAAAAAAJAB0AAAAAAAAAAAAJAB4AAAAAAAAAAAAJAB8AAAAAAAAAAAAJACAAAAAAAAAAAAAJACEAAAAAAAAAAAAJACIAAAAAAAAAAAAJACMAAAAAAAAAAAAJACQAAAAAAAAAAAAJACUAAAAAAAAAAAAJACYAAAAAAAAAAAAJACcAAAAAAAAAAAAJACgAAAAAAAAAAAAJACkAAAAAAAAAAAAJACoAAAAAAAAAAAAJACsAAAABAAAAAAAJACwAAAABAAAAAAAJAC0AAAABAAAAAAAKABsAAAAAAAAAAAAKABwAAAAAAAAAAAAKAB0AAAAAAAAAAAAKAB4AAAAAAAAAAAAKAB8AAAAAAAAAAAAKACAAAAAAAAAAAAAKACEAAAAAAAAAAAAKACIAAAAAAAAAAAAKACMAAAAAAAAAAAAKACQAAAAAAAAAAAAKACUAAAAAAAAAAAAKACYAAAAAAAAAAAAKACcAAAAAAAAAAAAKACgAAAAAAAAAAAAKACkAAAAAAAAAAAAKACoAAAAAAAAAAAAKACsAAAABAAAAAAAKACwAAAABAAAAAAAKAC0AAAABAAAAAAALABsAAAAAAAAAAAALABwAAAAAAAAAAAALAB0AAAAAAAAAAAALAB4AAAAAAAAAAAALAB8AAAAAAAAAAAALACAAAAAAAAAAAAALACEAAAAAAAAAAAALACIAAAAAAAAAAAALACMAAAAAAAAAAAALACQAAAAAAAAAAAALACUAAAAAAAAAAAALACYAAAAAAAAAAAALACcAAAAAAAAAAAALACgAAAAAAAAAAAALACkAAAAAAAAAAAALACoAAAAAAAAAAAALACsAAAAAAAAAAAALACwAAAAAAAAAAAALAC0AAAAAAAAAAAAMABsAAAABAAAAAAAMABwAAAABAAAAAAAMAB0AAAABAAAAAAAMAB4AAAABAAAAAAAMAB8AAAAAAAAAAAAMACAAAAAAAAAAAAAMACEAAAAAAAAAAAAMACIAAAAAAAAAAAAMACMAAAAAAAAAAAAMACQAAAAAAAAAAAAMACUAAAAAAAAAAAAMACYAAAABAAAAAAAMACcAAAABAAAAAAAMACgAAAAAAAAAAAAMACkAAAAAAAAAAAAMACoAAAAAAAAAAAAMACsAAAAAAAAAAAAMACwAAAAAAAAAAAAMAC0AAAAAAAAAAAANABsAAAABAAAAAAANABwAAAABAAAAAAANAB0AAAABAAAAAAANAB4AAAABAAAAAAANAB8AAAABAAAAAAANACAAAAAAAAAAAAANACEAAAAAAAAAAAANACIAAAAAAAAAAAANACMAAAAAAAAAAAANACQAAAAAAAAAAAANACUAAAAAAAAAAAANACYAAAAAAAAAAAANACcAAAABAAAAAAANACgAAAABAAAAAAANACkAAAAAAAAAAAANACoAAAAAAAAAAAANACsAAAAAAAAAAAANACwAAAAAAAAAAAANAC0AAAAAAAAAAAAOABsAAAABAAAAAAAOABwAAAABAAAAAAAOAB0AAAABAAAAAAAOAB4AAAABAAAAAAAOAB8AAAABAAAAAAAOACAAAAAAAAAAAAAOACEAAAAAAAAAAAAOACIAAAAAAAAAAAAOACMAAAAAAAAAAAAOACQAAAABAAAAAAAOACUAAAAAAAAAAAAOACYAAAAAAAAAAAAOACcAAAAAAAAAAAAOACgAAAABAAAAAAAOACkAAAAAAAAAAAAOACoAAAAAAAAAAAAOACsAAAAAAAAAAAAOACwAAAAAAAAAAAAOAC0AAAAAAAAAAAAPABsAAAABAAAAAAAPABwAAAABAAAAAAAPAB0AAAABAAAAAAAPAB4AAAABAAAAAAAPAB8AAAABAAAAAAAPACAAAAAAAAAAAAAPACEAAAAAAAAAAAAPACIAAAAAAAAAAAAPACMAAAAAAAAAAAAPACQAAAAAAAAAAAAPACUAAAAAAAAAAAAPACYAAAAAAAAAAAAPACcAAAABAAAAAAAPACgAAAAAAAAAAAAPACkAAAAAAAAAAAAPACoAAAAAAAAAAAAPACsAAAAAAAAAAAAPACwAAAAAAAAAAAAPAC0AAAAAAAAAAAAQABsAAAABAAAAAAAQABwAAAABAAAAAAAQAB0AAAABAAAAAAAQAB4AAAABAAAAAAAQAB8AAAABAAAAAAAQACAAAAAAAAAAAAAQACEAAAAAAAAAAAAQACIAAAAAAAAAAAAQACMAAAAAAAAAAAAQACQAAAAAAAAAAAAQACUAAAAAAAAAAAAQACYAAAAAAAAAAAAQACcAAAAAAAAAAAAQACgAAAABAAAAAAAQACkAAAAAAAAAAAAQACoAAAAAAAAAAAAQACsAAAAAAAAAAAAQACwAAAABAAAAAAAQAC0AAAABAAAAAAARABsAAAAAAAEAAAARABwAAAAAAAEAAAARAB0AAAABAAAAAAARAB4AAAABAAAAAAARAB8AAAABAAAAAAARACAAAAAAAAAAAAARACEAAAAAAAAAAAARACIAAAAAAAAAAAARACMAAAAAAAAAAAARACQAAAABAAAAAAARACUAAAAAAAAAAAARACYAAAAAAAAAAAARACcAAAABAAAAAAARACgAAAABAAAAAAARACkAAAAAAAAAAAARACoAAAAAAAAAAAARACsAAAAAAAAAAAARACwAAAABAAAAAAARAC0AAAABAAAAAAASABsAAAAAAAAAAAASABwAAAAAAAAAAAASAB0AAAAAAAAAAAASAB4AAAAAAAAAAAASAB8AAAAAAAAAAAASACAAAAAAAAAAAAASACEAAAAAAAAAAAASACIAAAAAAAAAAAASACMAAAAAAAAAAAASACQAAAAAAAAAAAASACUAAAAAAAAAAAASACYAAAABAAAAAAASACcAAAABAAAAAAASACgAAAAAAAAAAAASACkAAAAAAAAAAAASACoAAAAAAAAAAAASACsAAAAAAAAAAAASACwAAAABAAAAAAASAC0AAAABAAAAAAATABsAAAAAAAAAAAATABwAAAAAAAAAAAATAB0AAAAAAAAAAAATAB4AAAAAAAAAAAATAB8AAAAAAAAAAAATACAAAAAAAAAAAAATACEAAAAAAAAAAAATACIAAAAAAAAAAAATACMAAAAAAAAAAAATACQAAAAAAAAAAAATACUAAAAAAAAAAAATACYAAAAAAAAAAAATACcAAAAAAAAAAAATACgAAAAAAAAAAAATACkAAAAAAAAAAAATACoAAAAAAAAAAAATACsAAAAAAAAAAAATACwAAAAAAAAAAAATAC0AAAAAAAAAAAAUABsAAAAAAAAAAAAUABwAAAAAAAAAAAAUAB0AAAAAAAAAAAAUAB4AAAAAAAAAAAAUAB8AAAAAAAAAAAAUACAAAAAAAAAAAAAUACEAAAAAAAAAAAAUACIAAAAAAAAAAAAUACMAAAAAAAAAAAAUACQAAAAAAAAAAAAUACUAAAAAAAAAAAAUACYAAAAAAAAAAAAUACcAAAAAAAAAAAAUACgAAAAAAAAAAAAUACkAAAAAAAAAAAAUACoAAAAAAAAAAAAUACsAAAAAAAAAAAAUACwAAAAAAAAAAAAUAC0AAAAAAAAAAAAVABsAAAAAAAAAAAAVABwAAAAAAAAAAAAVAB0AAAAAAAAAAAAVAB4AAAAAAAAAAAAVAB8AAAAAAAAAAAAVACAAAAAAAAAAAAAVACEAAAAAAAAAAAAVACIAAAAAAAAAAAAVACMAAAAAAAAAAAAVACQAAAAAAAAAAAAVACUAAAAAAAAAAAAVACYAAAAAAAAAAAAVACcAAAAAAAAAAAAVACgAAAAAAAAAAAAVACkAAAAAAAAAAAAVACoAAAAAAAAAAAAVACsAAAAAAAAAAAAVACwAAAAAAAAAAAAVAC0AAAAAAAAAAAAWABsAAAAAAAAAAAAWABwAAAAAAAAAAAAWAB0AAAAAAAAAAAAWAB4AAAAAAAAAAAAWAB8AAAAAAAAAAAAWACAAAAABAAAAAAAWACEAAAABAAAAAAAWACIAAAAAAAAAAAAWACMAAAAAAAAAAAAWACQAAAAAAAAAAAAWACUAAAAAAAAAAAAWACYAAAAAAAAAAAAWACcAAAAAAAAAAAAWACgAAAAAAAAAAAAWACkAAAAAAAAAAAAWACoAAAAAAAAAAAAWACsAAAAAAAAAAAAWACwAAAAAAAAAAAAWAC0AAAAAAAAAAAAXABsAAAAAAAAAAAAXABwAAAAAAAAAAAAXAB0AAAAAAAAAAAAXAB4AAAAAAAAAAAAXAB8AAAAAAAAAAAAXACAAAAABAAAAAAAXACEAAAABAAAAAAAXACIAAAABAAAAAAAXACMAAAAAAAAAAAAXACQAAAABAAAAAAAXACUAAAABAAAAAAAXACYAAAABAAAAAAAXACcAAAAAAAAAAAAXACgAAAAAAAAAAAAXACkAAAAAAAAAAAAXACoAAAAAAAAAAAAXACsAAAABAAAAAAAXACwAAAABAAAAAAAXAC0AAAABAAAAAAAYABsAAAAAAAAAAAAYABwAAAAAAAAAAAAYAB0AAAAAAAAAAAAYAB4AAAAAAAAAAAAYAB8AAAAAAAAAAAAYACAAAAABAAAAAAAYACEAAAABAAAAAAAYACIAAAABAAAAAAAYACMAAAABAAAAAAAYACQAAAABAAAAAAAYACUAAAABAAAAAAAYACYAAAABAAAAAAAYACcAAAAAAAAAAAAYACgAAAAAAAAAAAAYACkAAAAAAAAAAAAYACoAAAAAAAAAAAAYACsAAAABAAAAAAAYACwAAAABAAAAAAAYAC0AAAABAAAAAAAZABsAAAAAAAAAAAAZABwAAAAAAAAAAAAZAB0AAAAAAAAAAAAZAB4AAAAAAAAAAAAZAB8AAAAAAAAAAAAZACAAAAABAAAAAAAZACEAAAABAAAAAAAZACIAAAABAAAAAAAZACMAAAABAAAAAAAZACQAAAABAAAAAAAZACUAAAABAAAAAAAZACYAAAAAAAAAAAAZACcAAAAAAAAAAAAZACgAAAAAAAAAAAAZACkAAAAAAAAAAAAZACoAAAABAAAAAAAZACsAAAABAAAAAAAZACwAAAABAAAAAAAZAC0AAAABAAAAAAAaABsAAAAAAAAAAAAaABwAAAAAAAAAAAAaAB0AAAAAAAAAAAAaAB4AAAAAAAAAAAAaAB8AAAAAAAEAAAAaACAAAAABAAAAAAAaACEAAAABAAAAAAAaACIAAAABAAAAAAAaACMAAAAAAAAAAAAaACQAAAAAAAAAAAAaACUAAAAAAAAAAAAaACYAAAAAAAAAAAAaACcAAAAAAAAAAAAaACgAAAAAAAAAAAAaACkAAAAAAAAAAAAaACoAAAABAAAAAAAaACsAAAABAAAAAAAaACwAAAABAAAAAAAaAC0AAAAAAAEAAAAbABsAAAAAAAAAAAAbABwAAAAAAAAAAAAbAB0AAAAAAAAAAAAbAB4AAAAAAAAAAAAbAB8AAAAAAAEAAAAbACAAAAAAAAEAAAAbACEAAAABAAAAAAAbACIAAAAAAAAAAAAbACMAAAAAAAAAAAAbACQAAAAAAAAAAAAbACUAAAAAAAAAAAAbACYAAAAAAAAAAAAbACcAAAAAAAAAAAAbACgAAAAAAAAAAAAbACkAAAABAAAAAAAbACoAAAABAAAAAAAbACsAAAABAAAAAAAbACwAAAABAAAAAAAbAC0AAAAAAAEAAAAcABsAAAAAAAAAAAAcABwAAAAAAAAAAAAcAB0AAAAAAAAAAAAcAB4AAAAAAAAAAAAcAB8AAAAAAAAAAAAcACAAAAAAAAAAAAAcACEAAAAAAAAAAAAcACIAAAAAAAAAAAAcACMAAAAAAAAAAAAcACQAAAAAAAAAAAAcACUAAAAAAAAAAAAcACYAAAAAAAAAAAAcACcAAAAAAAAAAAAcACgAAAAAAAAAAAAcACkAAAABAAAAAAAcACoAAAABAAAAAAAcACsAAAABAAAAAAAcACwAAAABAAAAAAAcAC0AAAAAAAEAAAAdABsAAAAAAAAAAAAdABwAAAAAAAAAAAAdAB0AAAAAAAAAAAAdAB4AAAAAAAAAAAAdAB8AAAAAAAAAAAAdACAAAAAAAAAAAAAdACEAAAAAAAAAAAAdACIAAAAAAAAAAAAdACMAAAAAAAAAAAAdACQAAAAAAAAAAAAdACUAAAAAAAAAAAAdACYAAAAAAAAAAAAdACcAAAAAAAAAAAAdACgAAAAAAAAAAAAdACkAAAABAAAAAAAdACoAAAABAAAAAAAdACsAAAABAAAAAAAdACwAAAABAAAAAAAdAC0AAAABAAAAAAAeABsAAAAAAAAAAAAeABwAAAAAAAAAAAAeAB0AAAAAAAAAAAAeAB4AAAAAAAAAAAAeAB8AAAAAAAAAAAAeACAAAAAAAAAAAAAeACEAAAAAAAAAAAAeACIAAAAAAAAAAAAeACMAAAAAAAAAAAAeACQAAAAAAAAAAAAeACUAAAAAAAAAAAAeACYAAAAAAAAAAAAeACcAAAAAAAAAAAAeACgAAAAAAAAAAAAeACkAAAAAAAAAAAAeACoAAAABAAAAAAAeACsAAAABAAAAAAAeACwAAAABAAAAAAAeAC0AAAABAAAAAAAfABsAAAAAAAAAAAAfABwAAAAAAAAAAAAfAB0AAAAAAAAAAAAfAB4AAAAAAAAAAAAfAB8AAAABAAAAAAAfACAAAAABAAAAAAAfACEAAAABAAAAAAAfACIAAAABAAAAAAAfACMAAAABAAAAAAAfACQAAAABAAAAAAAfACUAAAAAAAAAAAAfACYAAAAAAAAAAAAfACcAAAAAAAAAAAAfACgAAAAAAAAAAAAfACkAAAAAAAAAAAAfACoAAAAAAAAAAAAfACsAAAABAAAAAAAfACwAAAABAAAAAAAfAC0AAAABAAAAAAAgABsAAAAAAAAAAAAgABwAAAAAAAAAAAAgAB0AAAAAAAAAAAAgAB4AAAAAAAAAAAAgAB8AAAABAAAAAAAgACAAAAABAAAAAAAgACEAAAABAAAAAAAgACIAAAABAAAAAAAgACMAAAABAAAAAAAgACQAAAABAAAAAAAgACUAAAAAAAAAAAAgACYAAAAAAAAAAAAgACcAAAAAAAAAAAAgACgAAAAAAAAAAAAgACkAAAAAAAAAAAAgACoAAAAAAAAAAAAgACsAAAABAAAAAAAgACwAAAABAAAAAAAgAC0AAAABAAAAAAAhABsAAAAAAAAAAAAhABwAAAAAAAAAAAAhAB0AAAAAAAAAAAAhAB4AAAAAAAAAAAAhAB8AAAAAAAAAAAAhACAAAAAAAAAAAAAhACEAAAAAAAAAAAAhACIAAAAAAAAAAAAhACMAAAAAAAAAAAAhACQAAAAAAAAAAAAhACUAAAAAAAAAAAAhACYAAAAAAAAAAAAhACcAAAAAAAAAAAAhACgAAAAAAAAAAAAhACkAAAAAAAAAAAAhACoAAAAAAAAAAAAhACsAAAAAAAAAAAAhACwAAAABAAAAAAAhAC0AAAABAAAAAAAiABsAAAAAAAAAAAAiABwAAAAAAAAAAAAiAB0AAAAAAAAAAAAiAB4AAAAAAAAAAAAiAB8AAAAAAAAAAAAiACAAAAAAAAAAAAAiACEAAAAAAAAAAAAiACIAAAAAAAAAAAAiACMAAAAAAAAAAAAiACQAAAAAAAAAAAAiACUAAAAAAAAAAAAiACYAAAAAAAAAAAAiACcAAAAAAAAAAAAiACgAAAAAAAAAAAAiACkAAAAAAAAAAAAiACoAAAAAAAAAAAAiACsAAAAAAAAAAAAiACwAAAAAAAAAAAAiAC0AAAABAAAAAAAjABsAAAAAAAAAAAAjABwAAAAAAAAAAAAjAB0AAAAAAAAAAAAjAB4AAAAAAAAAAAAjAB8AAAABAAAAAAAjACAAAAAAAAAAAAAjACEAAAAAAAAAAAAjACIAAAAAAAAAAAAjACMAAAAAAAAAAAAjACQAAAAAAAAAAAAjACUAAAAAAAAAAAAjACYAAAAAAAAAAAAjACcAAAAAAAAAAAAjACgAAAAAAAAAAAAjACkAAAAAAAAAAAAjACoAAAAAAAAAAAAjACsAAAAAAAAAAAAjACwAAAAAAAAAAAAjAC0AAAAAAAAAAAAkABsAAAAAAAAAAAAkABwAAAAAAAAAAAAkAB0AAAAAAAAAAAAkAB4AAAABAAAAAAAkAB8AAAABAAAAAAAkACAAAAAAAAAAAAAkACEAAAAAAAAAAAAkACIAAAAAAAAAAAAkACMAAAAAAAAAAAAkACQAAAAAAAAAAAAkACUAAAAAAAAAAAAkACYAAAAAAAAAAAAkACcAAAAAAAAAAAAkACgAAAAAAAAAAAAkACkAAAAAAAAAAAAkACoAAAAAAAAAAAAkACsAAAAAAAAAAAAkACwAAAAAAAAAAAAkAC0AAAAAAAAAAAAlABsAAAAAAAAAAAAlABwAAAAAAAAAAAAlAB0AAAAAAAAAAAAlAB4AAAABAAAAAAAlAB8AAAABAAAAAAAlACAAAAAAAAAAAAAlACEAAAAAAAAAAAAlACIAAAAAAAAAAAAlACMAAAAAAAAAAAAlACQAAAAAAAAAAAAlACUAAAAAAAAAAAAlACYAAAAAAAAAAAAlACcAAAAAAAAAAAAlACgAAAAAAAAAAAAlACkAAAAAAAAAAAAlACoAAAAAAAAAAAAlACsAAAAAAAAAAAAlACwAAAAAAAAAAAAlAC0AAAAAAAAAAAAmABsAAAAAAAAAAAAmABwAAAAAAAAAAAAmAB0AAAAAAAAAAAAmAB4AAAABAAAAAAAmAB8AAAABAAAAAAAmACAAAAAAAAAAAAAmACEAAAAAAAAAAAAmACIAAAAAAAAAAAAmACMAAAAAAAAAAAAmACQAAAAAAAAAAAAmACUAAAAAAAAAAAAmACYAAAAAAAAAAAAmACcAAAAAAAAAAAAmACgAAAAAAAAAAAAmACkAAAAAAAAAAAAmACoAAAAAAAAAAAAmACsAAAAAAAAAAAAmACwAAAAAAAAAAAAmAC0AAAAAAAAAAAAnABsAAAAAAAAAAAAnABwAAAAAAAAAAAAnAB0AAAAAAAAAAAAnAB4AAAAAAAAAAAAnAB8AAAABAAAAAAAnACAAAAAAAAAAAAAnACEAAAAAAAAAAAAnACIAAAAAAAAAAAAnACMAAAAAAAAAAAAnACQAAAAAAAAAAAAnACUAAAAAAAAAAAAnACYAAAABAAAAAAAnACcAAAABAAAAAAAnACgAAAABAAAAAAAnACkAAAABAAAAAAAnACoAAAABAAAAAAAnACsAAAAAAAAAAAAnACwAAAAAAAAAAAAnAC0AAAAAAAAAAAAoABsAAAAAAAAAAAAoABwAAAAAAAAAAAAoAB0AAAAAAAAAAAAoAB4AAAAAAAAAAAAoAB8AAAAAAAAAAAAoACAAAAAAAAAAAAAoACEAAAAAAAAAAAAoACIAAAAAAAAAAAAoACMAAAAAAAAAAAAoACQAAAAAAAAAAAAoACUAAAABAAAAAAAoACYAAAABAAAAAAAoACcAAAABAAAAAAAoACgAAAABAAAAAAAoACkAAAABAAAAAAAoACoAAAABAAAAAAAoACsAAAABAAAAAAAoACwAAAAAAAAAAAAoAC0AAAAAAAAAAAApABsAAAAAAAAAAAApABwAAAAAAAAAAAApAB0AAAAAAAAAAAApAB4AAAAAAAAAAAApAB8AAAAAAAAAAAApACAAAAAAAAAAAAApACEAAAAAAAAAAAApACIAAAAAAAAAAAApACMAAAAAAAAAAAApACQAAAABAAAAAAApACUAAAABAAAAAAApACYAAAABAAAAAAApACcAAAABAAAAAAApACgAAAABAAAAAAApACkAAAABAAAAAAApACoAAAABAAAAAAApACsAAAABAAAAAAApACwAAAABAAAAAAApAC0AAAAAAAAAAAAqABsAAAAAAAAAAAAqABwAAAAAAAAAAAAqAB0AAAAAAAAAAAAqAB4AAAAAAAAAAAAqAB8AAAAAAAAAAAAqACAAAAAAAAAAAAAqACEAAAAAAAAAAAAqACIAAAAAAAAAAAAqACMAAAAAAAAAAAAqACQAAAABAAAAAAAqACUAAAABAAAAAAAqACYAAAABAAAAAAAqACcAAAAAAAEAAAAqACgAAAAAAAEAAAAqACkAAAAAAAEAAAAqACoAAAABAAAAAAAqACsAAAABAAAAAAAqACwAAAABAAAAAAAqAC0AAAABAAAAAAArABsAAAAAAAAAAAArABwAAAAAAAAAAAArAB0AAAAAAAAAAAArAB4AAAAAAAAAAAArAB8AAAAAAAAAAAArACAAAAAAAAAAAAArACEAAAAAAAAAAAArACIAAAAAAAAAAAArACMAAAAAAAAAAAArACQAAAABAAAAAAArACUAAAABAAAAAAArACYAAAAAAAEAAAArACcAAAAAAAEAAAArACgAAAAAAAEAAAArACkAAAAAAAAAAAArACoAAAAAAAAAAAArACsAAAABAAAAAAArACwAAAABAAAAAAArAC0AAAABAAAAAAAsABsAAAAAAAAAAAAsABwAAAAAAAAAAAAsAB0AAAAAAAAAAAAsAB4AAAAAAAAAAAAsAB8AAAAAAAAAAAAsACAAAAAAAAAAAAAsACEAAAAAAAAAAAAsACIAAAAAAAAAAAAsACMAAAAAAAAAAAAsACQAAAAAAAAAAAAsACUAAAAAAAAAAAAsACYAAAAAAAAAAAAsACcAAAAAAAAAAAAsACgAAAAAAAAAAAAsACkAAAAAAAAAAAAsACoAAAAAAAAAAAAsACsAAAAAAAAAAAAsACwAAAABAAAAAAAsAC0AAAAAAAAAAAAtABsAAAAAAAAAAAAtABwAAAAAAAAAAAAtAB0AAAAAAAAAAAAtAB4AAAAAAAAAAAAtAB8AAAAAAAAAAAAtACAAAAAAAAAAAAAtACEAAAAAAAAAAAAtACIAAAAAAAAAAAAtACMAAAAAAAAAAAAtACQAAAAAAAAAAAAtACUAAAAAAAAAAAAtACYAAAAAAAAAAAAtACcAAAAAAAAAAAAtACgAAAAAAAAAAAAtACkAAAAAAAAAAAAtACoAAAAAAAAAAAAtACsAAAAAAAAAAAAtACwAAAAAAAAAAAAtAC0AAAAAAAAAAAAuABsAAAAAAAAAAAAuABwAAAAAAAAAAAAuAB0AAAAAAAAAAAAuAB4AAAAAAAAAAAAuAB8AAAAAAAAAAAAuACAAAAAAAAAAAAAuACEAAAAAAAAAAAAuACIAAAAAAAAAAAAuACMAAAAAAAAAAAAuACQAAAAAAAAAAAAuACUAAAAAAAAAAAAuACYAAAAAAAAAAAAuACcAAAAAAAAAAAAuACgAAAAAAAAAAAAuACkAAAAAAAAAAAAuACoAAAAAAAAAAAAuACsAAAAAAAAAAAAuACwAAAAAAAAAAAAuAC0AAAAAAAAAAAAvABsAAAAAAAAAAAAvABwAAAAAAAAAAAAvAB0AAAAAAAAAAAAvAB4AAAAAAAAAAAAvAB8AAAAAAAAAAAAvACAAAAAAAAAAAAAvACEAAAAAAAAAAAAvACIAAAAAAAAAAAAvACMAAAAAAAAAAAAvACQAAAAAAAAAAAAvACUAAAAAAAAAAAAvACYAAAAAAAAAAAAvACcAAAAAAAAAAAAvACgAAAAAAAAAAAAvACkAAAAAAAAAAAAvACoAAAAAAAAAAAAvACsAAAAAAAAAAAAvACwAAAAAAAAAAAAvAC0AAAAAAAAAAAAwABsAAAAAAAAAAAAwABwAAAAAAAAAAAAwAB0AAAAAAAAAAAAwAB4AAAAAAAAAAAAwAB8AAAAAAAAAAAAwACAAAAAAAAAAAAAwACEAAAAAAAAAAAAwACIAAAAAAAAAAAAwACMAAAAAAAAAAAAwACQAAAAAAAAAAAAwACUAAAAAAAAAAAAwACYAAAAAAAAAAAAwACcAAAAAAAAAAAAwACgAAAAAAAAAAAAwACkAAAAAAAAAAAAwACoAAAAAAAAAAAAwACsAAAAAAAAAAAAwACwAAAAAAAAAAAAwAC0AAAAAAAAAAAAxABsAAAAAAAAAAAAxABwAAAAAAAAAAAAxAB0AAAABAAAAAAAxAB4AAAABAAAAAAAxAB8AAAABAAAAAAAxACAAAAAAAAAAAAAxACEAAAAAAAAAAAAxACIAAAAAAAAAAAAxACMAAAAAAAAAAAAxACQAAAAAAAAAAAAxACUAAAAAAAAAAAAxACYAAAAAAAAAAAAxACcAAAAAAAAAAAAxACgAAAABAAAAAAAxACkAAAABAAAAAAAxACoAAAAAAAAAAAAxACsAAAAAAAAAAAAxACwAAAAAAAAAAAAxAC0AAAAAAAAAAAAyABsAAAAAAAAAAAAyABwAAAAAAAAAAAAyAB0AAAABAAAAAAAyAB4AAAABAAAAAAAyAB8AAAABAAAAAAAyACAAAAABAAAAAAAyACEAAAABAAAAAAAyACIAAAAAAAAAAAAyACMAAAAAAAEAAAAyACQAAAAAAAEAAAAyACUAAAABAAAAAAAyACYAAAABAAAAAAAyACcAAAABAAAAAAAyACgAAAABAAAAAAAyACkAAAABAAAAAAAyACoAAAABAAAAAAAyACsAAAABAAAAAAAyACwAAAABAAAAAAAyAC0AAAABAAAAAAAzABsAAAAAAAAAAAAzABwAAAAAAAAAAAAzAB0AAAABAAAAAAAzAB4AAAABAAAAAAAzAB8AAAABAAAAAAAzACAAAAABAAAAAAAzACEAAAABAAAAAAAzACIAAAABAAAAAAAzACMAAAABAAAAAAAzACQAAAABAAAAAAAzACUAAAABAAAAAAAzACYAAAABAAAAAAAzACcAAAABAAAAAAAzACgAAAABAAAAAAAzACkAAAABAAAAAAAzACoAAAABAAAAAAAzACsAAAABAAAAAAAzACwAAAABAAAAAAAzAC0AAAABAAAAAAA0ABsAAAABAAAAAAA0ABwAAAABAAAAAAA0AB0AAAABAAAAAAA0AB4AAAABAAAAAAA0AB8AAAABAAAAAAA0ACAAAAABAAAAAAA0ACEAAAABAAAAAAA0ACIAAAABAAAAAAA0ACMAAAABAAAAAAA0ACQAAAABAAAAAAA0ACUAAAABAAAAAAA0ACYAAAABAAAAAAA0ACcAAAABAAAAAAA0ACgAAAABAAAAAAA0ACkAAAABAAAAAAA0ACoAAAABAAAAAAA0ACsAAAABAAAAAAA0ACwAAAABAAAAAAA0AC0AAAABAAAAAAAcAAAAAAAAAAAAAAAcAAEAAAAAAAAAAAAcAAIAAAAAAAAAAAAcAAMAAAAAAAAAAAAcAAQAAAAAAAAAAAAcAAUAAAAAAAAAAAAcAAYAAAAAAAAAAAAcAAcAAAAAAAAAAAAcAAgAAAAAAAAAAAAcAAkAAAAAAAAAAAAcAAoAAAAAAAAAAAAcAAsAAAAAAAAAAAAcAAwAAAAAAAAAAAAcAA0AAAAAAAAAAAAcAA4AAAAAAAAAAAAcAA8AAAAAAAAAAAAcABAAAAAAAAAAAAAcABEAAAABAAAAAAAcABIAAAABAAAAAAAcABMAAAABAAAAAAAcABQAAAAAAAEAAAAcABUAAAAAAAAAAAAcABYAAAAAAAAAAAAcABcAAAAAAAAAAAAcABgAAAAAAAAAAAAcABkAAAAAAAAAAAAcABoAAAAAAAAAAAAdAAAAAAAAAAAAAAAdAAEAAAAAAAAAAAAdAAIAAAAAAAAAAAAdAAMAAAAAAAAAAAAdAAQAAAAAAAAAAAAdAAUAAAAAAAAAAAAdAAYAAAAAAAAAAAAdAAcAAAAAAAAAAAAdAAgAAAAAAAAAAAAdAAkAAAAAAAAAAAAdAAoAAAAAAAAAAAAdAAsAAAAAAAAAAAAdAAwAAAAAAAAAAAAdAA0AAAAAAAAAAAAdAA4AAAAAAAAAAAAdAA8AAAAAAAAAAAAdABAAAAABAAAAAAAdABEAAAABAAAAAAAdABIAAAABAAAAAAAdABMAAAABAAAAAAAdABQAAAAAAAEAAAAdABUAAAAAAAEAAAAdABYAAAAAAAAAAAAdABcAAAAAAAAAAAAdABgAAAAAAAAAAAAdABkAAAAAAAAAAAAdABoAAAAAAAAAAAAeAAAAAAAAAAAAAAAeAAEAAAAAAAAAAAAeAAIAAAAAAAAAAAAeAAMAAAAAAAAAAAAeAAQAAAAAAAAAAAAeAAUAAAAAAAAAAAAeAAYAAAAAAAAAAAAeAAcAAAAAAAAAAAAeAAgAAAAAAAAAAAAeAAkAAAAAAAAAAAAeAAoAAAAAAAAAAAAeAAsAAAAAAAAAAAAeAAwAAAAAAAAAAAAeAA0AAAAAAAAAAAAeAA4AAAAAAAAAAAAeAA8AAAAAAAAAAAAeABAAAAABAAAAAAAeABEAAAABAAAAAAAeABIAAAABAAAAAAAeABMAAAABAAAAAAAeABQAAAABAAAAAAAeABUAAAAAAAEAAAAeABYAAAABAAAAAAAeABcAAAABAAAAAAAeABgAAAAAAAAAAAAeABkAAAAAAAAAAAAeABoAAAAAAAAAAAAfAAAAAAAAAAAAAAAfAAEAAAAAAAAAAAAfAAIAAAAAAAAAAAAfAAMAAAAAAAAAAAAfAAQAAAAAAAAAAAAfAAUAAAAAAAAAAAAfAAYAAAAAAAAAAAAfAAcAAAAAAAAAAAAfAAgAAAABAAAAAAAfAAkAAAABAAAAAAAfAAoAAAAAAAAAAAAfAAsAAAAAAAAAAAAfAAwAAAAAAAAAAAAfAA0AAAAAAAAAAAAfAA4AAAAAAAAAAAAfAA8AAAAAAAAAAAAfABAAAAAAAAAAAAAfABEAAAABAAAAAAAfABIAAAABAAAAAAAfABMAAAABAAAAAAAfABQAAAABAAAAAAAfABUAAAABAAAAAAAfABYAAAABAAAAAAAfABcAAAABAAAAAAAfABgAAAABAAAAAAAfABkAAAABAAAAAAAfABoAAAAAAAAAAAAgAAAAAAABAAAAAAAgAAEAAAAAAAAAAAAgAAIAAAAAAAAAAAAgAAMAAAAAAAAAAAAgAAQAAAAAAAAAAAAgAAUAAAAAAAAAAAAgAAYAAAAAAAAAAAAgAAcAAAABAAAAAAAgAAgAAAABAAAAAAAgAAkAAAABAAAAAAAgAAoAAAAAAAAAAAAgAAsAAAAAAAAAAAAgAAwAAAAAAAAAAAAgAA0AAAAAAAAAAAAgAA4AAAAAAAAAAAAgAA8AAAAAAAAAAAAgABAAAAAAAAAAAAAgABEAAAABAAAAAAAgABIAAAABAAAAAAAgABMAAAABAAAAAAAgABQAAAABAAAAAAAgABUAAAABAAAAAAAgABYAAAABAAAAAAAgABcAAAABAAAAAAAgABgAAAABAAAAAAAgABkAAAABAAAAAAAgABoAAAAAAAAAAAAhAAAAAAABAAAAAAAhAAEAAAAAAAAAAAAhAAIAAAAAAAAAAAAhAAMAAAAAAAAAAAAhAAQAAAAAAAAAAAAhAAUAAAAAAAAAAAAhAAYAAAAAAAAAAAAhAAcAAAABAAAAAAAhAAgAAAABAAAAAAAhAAkAAAABAAAAAAAhAAoAAAAAAAAAAAAhAAsAAAAAAAAAAAAhAAwAAAAAAAAAAAAhAA0AAAAAAAAAAAAhAA4AAAAAAAAAAAAhAA8AAAAAAAAAAAAhABAAAAAAAAAAAAAhABEAAAABAAAAAAAhABIAAAABAAAAAAAhABMAAAABAAAAAAAhABQAAAABAAAAAAAhABUAAAABAAAAAAAhABYAAAABAAAAAAAhABcAAAABAAAAAAAhABgAAAABAAAAAAAhABkAAAABAAAAAAAhABoAAAAAAAAAAAAiAAAAAAABAAAAAAAiAAEAAAABAAAAAAAiAAIAAAAAAAAAAAAiAAMAAAAAAAAAAAAiAAQAAAAAAAAAAAAiAAUAAAAAAAAAAAAiAAYAAAAAAAAAAAAiAAcAAAAAAAAAAAAiAAgAAAAAAAAAAAAiAAkAAAAAAAAAAAAiAAoAAAAAAAAAAAAiAAsAAAAAAAAAAAAiAAwAAAAAAAAAAAAiAA0AAAAAAAAAAAAiAA4AAAAAAAAAAAAiAA8AAAAAAAAAAAAiABAAAAAAAAAAAAAiABEAAAABAAAAAAAiABIAAAABAAAAAAAiABMAAAABAAAAAAAiABQAAAABAAAAAAAiABUAAAABAAAAAAAiABYAAAABAAAAAAAiABcAAAABAAAAAAAiABgAAAABAAAAAAAiABkAAAAAAAAAAAAiABoAAAAAAAAAAAAjAAAAAAABAAAAAAAjAAEAAAABAAAAAAAjAAIAAAABAAAAAAAjAAMAAAAAAAAAAAAjAAQAAAAAAAAAAAAjAAUAAAAAAAAAAAAjAAYAAAAAAAAAAAAjAAcAAAAAAAAAAAAjAAgAAAAAAAAAAAAjAAkAAAAAAAAAAAAjAAoAAAAAAAAAAAAjAAsAAAAAAAAAAAAjAAwAAAAAAAAAAAAjAA0AAAAAAAAAAAAjAA4AAAAAAAAAAAAjAA8AAAAAAAAAAAAjABAAAAAAAAAAAAAjABEAAAABAAAAAAAjABIAAAABAAAAAAAjABMAAAABAAAAAAAjABQAAAABAAAAAAAjABUAAAAAAAAAAAAjABYAAAABAAAAAAAjABcAAAABAAAAAAAjABgAAAABAAAAAAAjABkAAAAAAAAAAAAjABoAAAAAAAAAAAAkAAAAAAABAAAAAAAkAAEAAAABAAAAAAAkAAIAAAABAAAAAAAkAAMAAAAAAAAAAAAkAAQAAAAAAAAAAAAkAAUAAAABAAAAAAAkAAYAAAAAAAAAAAAkAAcAAAAAAAAAAAAkAAgAAAAAAAAAAAAkAAkAAAAAAAAAAAAkAAoAAAAAAAAAAAAkAAsAAAAAAAAAAAAkAAwAAAAAAAAAAAAkAA0AAAAAAAAAAAAkAA4AAAAAAAAAAAAkAA8AAAAAAAAAAAAkABAAAAABAAAAAAAkABEAAAABAAAAAAAkABIAAAABAAAAAAAkABMAAAABAAAAAAAkABQAAAABAAAAAAAkABUAAAAAAAAAAAAkABYAAAAAAAAAAAAkABcAAAAAAAAAAAAkABgAAAAAAAAAAAAkABkAAAAAAAAAAAAkABoAAAAAAAAAAAAlAAAAAAABAAAAAAAlAAEAAAABAAAAAAAlAAIAAAABAAAAAAAlAAMAAAAAAAAAAAAlAAQAAAABAAAAAAAlAAUAAAABAAAAAAAlAAYAAAAAAAAAAAAlAAcAAAAAAAAAAAAlAAgAAAAAAAAAAAAlAAkAAAAAAAAAAAAlAAoAAAAAAAAAAAAlAAsAAAAAAAAAAAAlAAwAAAAAAAAAAAAlAA0AAAAAAAAAAAAlAA4AAAAAAAAAAAAlAA8AAAABAAAAAAAlABAAAAABAAAAAAAlABEAAAABAAAAAAAlABIAAAABAAAAAAAlABMAAAABAAAAAAAlABQAAAAAAAAAAAAlABUAAAAAAAAAAAAlABYAAAAAAAAAAAAlABcAAAAAAAAAAAAlABgAAAAAAAAAAAAlABkAAAAAAAAAAAAlABoAAAAAAAAAAAAmAAAAAAABAAAAAAAmAAEAAAABAAAAAAAmAAIAAAABAAAAAAAmAAMAAAABAAAAAAAmAAQAAAABAAAAAAAmAAUAAAABAAAAAAAmAAYAAAAAAAAAAAAmAAcAAAAAAAAAAAAmAAgAAAAAAAAAAAAmAAkAAAAAAAAAAAAmAAoAAAAAAAAAAAAmAAsAAAAAAAAAAAAmAAwAAAAAAAAAAAAmAA0AAAABAAAAAAAmAA4AAAABAAAAAAAmAA8AAAABAAAAAAAmABAAAAABAAAAAAAmABEAAAABAAAAAAAmABIAAAABAAAAAAAmABMAAAAAAAAAAAAmABQAAAAAAAAAAAAmABUAAAAAAAAAAAAmABYAAAAAAAAAAAAmABcAAAAAAAAAAAAmABgAAAAAAAAAAAAmABkAAAAAAAAAAAAmABoAAAAAAAAAAAAnAAAAAAABAAAAAAAnAAEAAAABAAAAAAAnAAIAAAABAAAAAAAnAAMAAAABAAAAAAAnAAQAAAABAAAAAAAnAAUAAAABAAAAAAAnAAYAAAAAAAAAAAAnAAcAAAAAAAAAAAAnAAgAAAAAAAAAAAAnAAkAAAAAAAAAAAAnAAoAAAAAAAAAAAAnAAsAAAAAAAAAAAAnAAwAAAABAAAAAAAnAA0AAAABAAAAAAAnAA4AAAABAAAAAAAnAA8AAAABAAAAAAAnABAAAAABAAAAAAAnABEAAAABAAAAAAAnABIAAAABAAAAAAAnABMAAAAAAAAAAAAnABQAAAAAAAAAAAAnABUAAAAAAAAAAAAnABYAAAAAAAAAAAAnABcAAAAAAAAAAAAnABgAAAAAAAAAAAAnABkAAAAAAAAAAAAnABoAAAAAAAAAAAAoAAAAAAABAAAAAAAoAAEAAAABAAAAAAAoAAIAAAABAAAAAAAoAAMAAAABAAAAAAAoAAQAAAABAAAAAAAoAAUAAAABAAAAAAAoAAYAAAAAAAAAAAAoAAcAAAAAAAAAAAAoAAgAAAAAAAAAAAAoAAkAAAAAAAAAAAAoAAoAAAAAAAAAAAAoAAsAAAABAAAAAAAoAAwAAAABAAAAAAAoAA0AAAABAAAAAAAoAA4AAAABAAAAAAAoAA8AAAABAAAAAAAoABAAAAABAAAAAAAoABEAAAABAAAAAAAoABIAAAABAAAAAAAoABMAAAAAAAAAAAAoABQAAAAAAAAAAAAoABUAAAAAAAAAAAAoABYAAAAAAAAAAAAoABcAAAAAAAAAAAAoABgAAAAAAAAAAAAoABkAAAAAAAAAAAAoABoAAAAAAAAAAAApAAAAAAABAAAAAAApAAEAAAABAAAAAAApAAIAAAABAAAAAAApAAMAAAABAAAAAAApAAQAAAABAAAAAAApAAUAAAAAAAAAAAApAAYAAAAAAAAAAAApAAcAAAAAAAAAAAApAAgAAAAAAAAAAAApAAkAAAAAAAAAAAApAAoAAAABAAAAAAApAAsAAAABAAAAAAApAAwAAAABAAAAAAApAA0AAAABAAAAAAApAA4AAAABAAAAAAApAA8AAAABAAAAAAApABAAAAABAAAAAAApABEAAAABAAAAAAApABIAAAAAAAAAAAApABMAAAAAAAAAAAApABQAAAAAAAAAAAApABUAAAABAAAAAAApABYAAAABAAAAAAApABcAAAAAAAAAAAApABgAAAAAAAAAAAApABkAAAAAAAAAAAApABoAAAAAAAAAAAAqAAAAAAABAAAAAAAqAAEAAAABAAAAAAAqAAIAAAABAAAAAAAqAAMAAAABAAAAAAAqAAQAAAABAAAAAAAqAAUAAAAAAAAAAAAqAAYAAAAAAAAAAAAqAAcAAAAAAAAAAAAqAAgAAAAAAAAAAAAqAAkAAAAAAAAAAAAqAAoAAAABAAAAAAAqAAsAAAABAAAAAAAqAAwAAAABAAAAAAAqAA0AAAABAAAAAAAqAA4AAAABAAAAAAAqAA8AAAABAAAAAAAqABAAAAABAAAAAAAqABEAAAAAAAAAAAAqABIAAAAAAAAAAAAqABMAAAAAAAAAAAAqABQAAAAAAAAAAAAqABUAAAABAAAAAAAqABYAAAABAAAAAAAqABcAAAABAAAAAAAqABgAAAAAAAAAAAAqABkAAAAAAAAAAAAqABoAAAAAAAAAAAArAAAAAAABAAAAAAArAAEAAAABAAAAAAArAAIAAAABAAAAAAArAAMAAAABAAAAAAArAAQAAAAAAAAAAAArAAUAAAAAAAAAAAArAAYAAAAAAAAAAAArAAcAAAAAAAAAAAArAAgAAAAAAAAAAAArAAkAAAAAAAAAAAArAAoAAAABAAAAAAArAAsAAAAAAAEAAAArAAwAAAABAAAAAAArAA0AAAABAAAAAAArAA4AAAABAAAAAAArAA8AAAABAAAAAAArABAAAAAAAAAAAAArABEAAAAAAAAAAAArABIAAAAAAAAAAAArABMAAAAAAAAAAAArABQAAAAAAAAAAAArABUAAAABAAAAAAArABYAAAABAAAAAAArABcAAAABAAAAAAArABgAAAAAAAAAAAArABkAAAAAAAAAAAArABoAAAAAAAAAAAAsAAAAAAABAAAAAAAsAAEAAAABAAAAAAAsAAIAAAABAAAAAAAsAAMAAAABAAAAAAAsAAQAAAAAAAAAAAAsAAUAAAAAAAAAAAAsAAYAAAAAAAEAAAAsAAcAAAAAAAEAAAAsAAgAAAAAAAAAAAAsAAkAAAAAAAAAAAAsAAoAAAAAAAAAAAAsAAsAAAABAAAAAAAsAAwAAAABAAAAAAAsAA0AAAABAAAAAAAsAA4AAAABAAAAAAAsAA8AAAAAAAAAAAAsABAAAAAAAAAAAAAsABEAAAAAAAAAAAAsABIAAAAAAAAAAAAsABMAAAAAAAAAAAAsABQAAAABAAAAAAAsABUAAAABAAAAAAAsABYAAAABAAAAAAAsABcAAAABAAAAAAAsABgAAAAAAAAAAAAsABkAAAAAAAAAAAAsABoAAAAAAAAAAAAtAAAAAAABAAAAAAAtAAEAAAABAAAAAAAtAAIAAAABAAAAAAAtAAMAAAAAAAAAAAAtAAQAAAAAAAAAAAAtAAUAAAAAAAEAAAAtAAYAAAAAAAEAAAAtAAcAAAAAAAAAAAAtAAgAAAAAAAAAAAAtAAkAAAAAAAAAAAAtAAoAAAAAAAAAAAAtAAsAAAAAAAAAAAAtAAwAAAAAAAAAAAAtAA0AAAAAAAAAAAAtAA4AAAAAAAAAAAAtAA8AAAAAAAAAAAAtABAAAAAAAAAAAAAtABEAAAAAAAAAAAAtABIAAAAAAAAAAAAtABMAAAAAAAAAAAAtABQAAAABAAAAAAAtABUAAAABAAAAAAAtABYAAAABAAAAAAAtABcAAAAAAAAAAAAtABgAAAAAAAAAAAAtABkAAAAAAAAAAAAtABoAAAAAAAAAAAAuAAAAAAABAAAAAAAuAAEAAAABAAAAAAAuAAIAAAAAAAAAAAAuAAMAAAAAAAAAAAAuAAQAAAAAAAEAAAAuAAUAAAAAAAEAAAAuAAYAAAAAAAAAAAAuAAcAAAAAAAAAAAAuAAgAAAAAAAEAAAAuAAkAAAAAAAAAAAAuAAoAAAAAAAAAAAAuAAsAAAAAAAAAAAAuAAwAAAAAAAAAAAAuAA0AAAAAAAAAAAAuAA4AAAAAAAAAAAAuAA8AAAAAAAAAAAAuABAAAAAAAAAAAAAuABEAAAAAAAAAAAAuABIAAAAAAAAAAAAuABMAAAAAAAAAAAAuABQAAAAAAAAAAAAuABUAAAAAAAAAAAAuABYAAAAAAAAAAAAuABcAAAAAAAAAAAAuABgAAAAAAAAAAAAuABkAAAAAAAAAAAAuABoAAAAAAAAAAAAvAAAAAAABAAAAAAAvAAEAAAAAAAAAAAAvAAIAAAAAAAAAAAAvAAMAAAAAAAAAAAAvAAQAAAAAAAAAAAAvAAUAAAAAAAAAAAAvAAYAAAAAAAAAAAAvAAcAAAAAAAAAAAAvAAgAAAAAAAEAAAAvAAkAAAAAAAAAAAAvAAoAAAAAAAAAAAAvAAsAAAAAAAAAAAAvAAwAAAAAAAAAAAAvAA0AAAAAAAAAAAAvAA4AAAAAAAAAAAAvAA8AAAAAAAAAAAAvABAAAAAAAAAAAAAvABEAAAAAAAAAAAAvABIAAAAAAAAAAAAvABMAAAAAAAAAAAAvABQAAAAAAAAAAAAvABUAAAAAAAAAAAAvABYAAAAAAAAAAAAvABcAAAAAAAAAAAAvABgAAAAAAAAAAAAvABkAAAAAAAAAAAAvABoAAAAAAAAAAAAwAAAAAAABAAAAAAAwAAEAAAAAAAAAAAAwAAIAAAAAAAAAAAAwAAMAAAAAAAAAAAAwAAQAAAAAAAAAAAAwAAUAAAAAAAAAAAAwAAYAAAAAAAAAAAAwAAcAAAAAAAEAAAAwAAgAAAAAAAAAAAAwAAkAAAAAAAAAAAAwAAoAAAAAAAAAAAAwAAsAAAAAAAAAAAAwAAwAAAAAAAAAAAAwAA0AAAAAAAAAAAAwAA4AAAABAAAAAAAwAA8AAAABAAAAAAAwABAAAAAAAAAAAAAwABEAAAAAAAAAAAAwABIAAAAAAAAAAAAwABMAAAAAAAAAAAAwABQAAAAAAAAAAAAwABUAAAAAAAAAAAAwABYAAAAAAAAAAAAwABcAAAAAAAAAAAAwABgAAAAAAAAAAAAwABkAAAAAAAAAAAAwABoAAAAAAAAAAAAxAAAAAAABAAAAAAAxAAEAAAAAAAAAAAAxAAIAAAAAAAAAAAAxAAMAAAAAAAAAAAAxAAQAAAAAAAAAAAAxAAUAAAAAAAAAAAAxAAYAAAAAAAAAAAAxAAcAAAAAAAEAAAAxAAgAAAAAAAAAAAAxAAkAAAAAAAAAAAAxAAoAAAAAAAAAAAAxAAsAAAAAAAAAAAAxAAwAAAAAAAAAAAAxAA0AAAABAAAAAAAxAA4AAAABAAAAAAAxAA8AAAABAAAAAAAxABAAAAABAAAAAAAxABEAAAAAAAAAAAAxABIAAAAAAAAAAAAxABMAAAAAAAAAAAAxABQAAAAAAAAAAAAxABUAAAAAAAAAAAAxABYAAAAAAAAAAAAxABcAAAAAAAAAAAAxABgAAAAAAAAAAAAxABkAAAAAAAAAAAAxABoAAAAAAAAAAAAyAAAAAAAAAAAAAAAyAAEAAAAAAAAAAAAyAAIAAAAAAAAAAAAyAAMAAAAAAAAAAAAyAAQAAAAAAAAAAAAyAAUAAAAAAAAAAAAyAAYAAAAAAAAAAAAyAAcAAAAAAAEAAAAyAAgAAAAAAAAAAAAyAAkAAAAAAAAAAAAyAAoAAAAAAAAAAAAyAAsAAAAAAAAAAAAyAAwAAAABAAAAAAAyAA0AAAABAAAAAAAyAA4AAAABAAAAAAAyAA8AAAABAAAAAAAyABAAAAABAAAAAAAyABEAAAAAAAAAAAAyABIAAAAAAAAAAAAyABMAAAAAAAAAAAAyABQAAAAAAAAAAAAyABUAAAAAAAAAAAAyABYAAAAAAAAAAAAyABcAAAAAAAAAAAAyABgAAAAAAAAAAAAyABkAAAAAAAAAAAAyABoAAAAAAAAAAAAzAAAAAAAAAAAAAAAzAAEAAAAAAAAAAAAzAAIAAAAAAAAAAAAzAAMAAAAAAAAAAAAzAAQAAAAAAAAAAAAzAAUAAAAAAAAAAAAzAAYAAAAAAAAAAAAzAAcAAAAAAAAAAAAzAAgAAAABAAAAAAAzAAkAAAABAAAAAAAzAAoAAAABAAAAAAAzAAsAAAABAAAAAAAzAAwAAAABAAAAAAAzAA0AAAABAAAAAAAzAA4AAAABAAAAAAAzAA8AAAABAAAAAAAzABAAAAABAAAAAAAzABEAAAAAAAAAAAAzABIAAAAAAAAAAAAzABMAAAAAAAAAAAAzABQAAAAAAAAAAAAzABUAAAAAAAAAAAAzABYAAAAAAAAAAAAzABcAAAAAAAAAAAAzABgAAAAAAAAAAAAzABkAAAAAAAAAAAAzABoAAAAAAAAAAAA0AAAAAAAAAAAAAAA0AAEAAAAAAAAAAAA0AAIAAAAAAAAAAAA0AAMAAAAAAAAAAAA0AAQAAAABAAAAAAA0AAUAAAABAAAAAAA0AAYAAAABAAAAAAA0AAcAAAABAAAAAAA0AAgAAAABAAAAAAA0AAkAAAABAAAAAAA0AAoAAAABAAAAAAA0AAsAAAABAAAAAAA0AAwAAAABAAAAAAA0AA0AAAABAAAAAAA0AA4AAAABAAAAAAA0AA8AAAABAAAAAAA0ABAAAAABAAAAAAA0ABEAAAABAAAAAAA0ABIAAAABAAAAAAA0ABMAAAAAAAAAAAA0ABQAAAAAAAAAAAA0ABUAAAAAAAAAAAA0ABYAAAAAAAAAAAA0ABcAAAAAAAAAAAA0ABgAAAAAAAAAAAA0ABkAAAABAAAAAAA0ABoAAAABAAAAAAAAAC4AAAABAAAAAAAAAC8AAAABAAAAAAAAADAAAAABAAAAAAAAADEAAAABAAAAAAAAADIAAAABAAAAAAABAC4AAAABAAAAAAABAC8AAAABAAAAAAABADAAAAABAAAAAAABADEAAAABAAAAAAABADIAAAABAAAAAAACAC4AAAABAAAAAAACAC8AAAABAAAAAAACADAAAAABAAAAAAACADEAAAABAAAAAAACADIAAAABAAAAAAADAC4AAAAAAAAAAAADAC8AAAAAAAEAAAADADAAAAAAAAEAAAADADEAAAABAAAAAAADADIAAAABAAAAAAAEAC4AAAAAAAAAAAAEAC8AAAAAAAEAAAAEADAAAAABAAAAAAAEADEAAAABAAAAAAAEADIAAAABAAAAAAAFAC4AAAAAAAAAAAAFAC8AAAAAAAEAAAAFADAAAAABAAAAAAAFADEAAAABAAAAAAAFADIAAAABAAAAAAAGAC4AAAAAAAAAAAAGAC8AAAAAAAEAAAAGADAAAAAAAAEAAAAGADEAAAABAAAAAAAGADIAAAABAAAAAAAHAC4AAAAAAAAAAAAHAC8AAAAAAAEAAAAHADAAAAAAAAEAAAAHADEAAAABAAAAAAAHADIAAAABAAAAAAAIAC4AAAABAAAAAAAIAC8AAAABAAAAAAAIADAAAAABAAAAAAAIADEAAAABAAAAAAAIADIAAAABAAAAAAAJAC4AAAABAAAAAAAJAC8AAAABAAAAAAAJADAAAAABAAAAAAAJADEAAAABAAAAAAAJADIAAAABAAAAAAAKAC4AAAAAAAAAAAAKAC8AAAABAAAAAAAKADAAAAABAAAAAAAKADEAAAABAAAAAAAKADIAAAABAAAAAAALAC4AAAAAAAAAAAALAC8AAAAAAAAAAAALADAAAAABAAAAAAALADEAAAABAAAAAAALADIAAAABAAAAAAAMAC4AAAAAAAAAAAAMAC8AAAAAAAAAAAAMADAAAAAAAAAAAAAMADEAAAAAAAAAAAAMADIAAAABAAAAAAANAC4AAAAAAAAAAAANAC8AAAAAAAAAAAANADAAAAAAAAAAAAANADEAAAAAAAAAAAANADIAAAAAAAAAAAAOAC4AAAAAAAAAAAAOAC8AAAAAAAAAAAAOADAAAAAAAAAAAAAOADEAAAAAAAAAAAAOADIAAAAAAAAAAAAPAC4AAAAAAAAAAAAPAC8AAAAAAAAAAAAPADAAAAAAAAAAAAAPADEAAAAAAAAAAAAPADIAAAABAAAAAAAQAC4AAAABAAAAAAAQAC8AAAAAAAAAAAAQADAAAAAAAAAAAAAQADEAAAAAAAAAAAAQADIAAAABAAAAAAARAC4AAAABAAAAAAARAC8AAAAAAAAAAAARADAAAAAAAAAAAAARADEAAAAAAAAAAAARADIAAAABAAAAAAASAC4AAAAAAAAAAAASAC8AAAAAAAAAAAASADAAAAAAAAAAAAASADEAAAAAAAAAAAASADIAAAABAAAAAAATAC4AAAAAAAAAAAATAC8AAAAAAAAAAAATADAAAAAAAAAAAAATADEAAAAAAAAAAAATADIAAAABAAAAAAAUAC4AAAAAAAAAAAAUAC8AAAAAAAAAAAAUADAAAAAAAAAAAAAUADEAAAAAAAAAAAAUADIAAAABAAAAAAAVAC4AAAAAAAAAAAAVAC8AAAAAAAAAAAAVADAAAAAAAAAAAAAVADEAAAAAAAAAAAAVADIAAAABAAAAAAAWAC4AAAAAAAAAAAAWAC8AAAAAAAAAAAAWADAAAAAAAAAAAAAWADEAAAAAAAAAAAAWADIAAAABAAAAAAAXAC4AAAABAAAAAAAXAC8AAAABAAAAAAAXADAAAAAAAAAAAAAXADEAAAAAAAAAAAAXADIAAAABAAAAAAAYAC4AAAABAAAAAAAYAC8AAAABAAAAAAAYADAAAAAAAAAAAAAYADEAAAABAAAAAAAYADIAAAABAAAAAAAZAC4AAAABAAAAAAAZAC8AAAAAAAAAAAAZADAAAAAAAAAAAAAZADEAAAABAAAAAAAZADIAAAABAAAAAAAaAC4AAAAAAAAAAAAaAC8AAAAAAAAAAAAaADAAAAABAAAAAAAaADEAAAABAAAAAAAaADIAAAABAAAAAAAbAC4AAAABAAAAAAAbAC8AAAABAAAAAAAbADAAAAABAAAAAAAbADEAAAABAAAAAAAbADIAAAABAAAAAAAcAC4AAAAAAAAAAAAcAC8AAAABAAAAAAAcADAAAAABAAAAAAAcADEAAAABAAAAAAAcADIAAAABAAAAAAAdAC4AAAAAAAAAAAAdAC8AAAAAAAAAAAAdADAAAAABAAAAAAAdADEAAAABAAAAAAAdADIAAAABAAAAAAAeAC4AAAABAAAAAAAeAC8AAAAAAAAAAAAeADAAAAAAAAAAAAAeADEAAAABAAAAAAAeADIAAAABAAAAAAAfAC4AAAABAAAAAAAfAC8AAAABAAAAAAAfADAAAAAAAAAAAAAfADEAAAABAAAAAAAfADIAAAABAAAAAAAgAC4AAAABAAAAAAAgAC8AAAABAAAAAAAgADAAAAAAAAAAAAAgADEAAAABAAAAAAAgADIAAAABAAAAAAAhAC4AAAABAAAAAAAhAC8AAAABAAAAAAAhADAAAAAAAAAAAAAhADEAAAABAAAAAAAhADIAAAABAAAAAAAiAC4AAAABAAAAAAAiAC8AAAABAAAAAAAiADAAAAAAAAAAAAAiADEAAAABAAAAAAAiADIAAAABAAAAAAAjAC4AAAAAAAAAAAAjAC8AAAAAAAAAAAAjADAAAAAAAAAAAAAjADEAAAABAAAAAAAjADIAAAABAAAAAAAkAC4AAAAAAAAAAAAkAC8AAAAAAAAAAAAkADAAAAABAAAAAAAkADEAAAABAAAAAAAkADIAAAABAAAAAAAlAC4AAAAAAAAAAAAlAC8AAAAAAAAAAAAlADAAAAAAAAAAAAAlADEAAAAAAAAAAAAlADIAAAABAAAAAAAmAC4AAAAAAAAAAAAmAC8AAAAAAAAAAAAmADAAAAAAAAAAAAAmADEAAAAAAAAAAAAnAC4AAAAAAAAAAAAnAC8AAAAAAAAAAAAnADAAAAAAAAAAAAAnADEAAAAAAAAAAAAoAC4AAAAAAAAAAAAoAC8AAAAAAAAAAAAoADAAAAAAAAAAAAAoADEAAAAAAAAAAAApAC4AAAAAAAAAAAApAC8AAAAAAAAAAAApADAAAAAAAAAAAAApADEAAAAAAAAAAAAqAC4AAAAAAAAAAAAqAC8AAAAAAAAAAAAqADAAAAAAAAAAAAAqADEAAAAAAAAAAAArAC4AAAAAAAAAAAArAC8AAAAAAAAAAAArADAAAAAAAAAAAAArADEAAAAAAAAAAAAsAC4AAAAAAAAAAAAsAC8AAAAAAAAAAAAsADAAAAAAAAAAAAAsADEAAAAAAAAAAAAtAC4AAAAAAAAAAAAtAC8AAAAAAAAAAAAtADAAAAAAAAAAAAAtADEAAAAAAAAAAAAtADIAAAABAAAAAAAuAC4AAAAAAAAAAAAuAC8AAAAAAAAAAAAuADAAAAAAAAAAAAAuADEAAAABAAAAAAAuADIAAAABAAAAAAAvAC4AAAAAAAAAAAAvAC8AAAAAAAAAAAAvADAAAAABAAAAAAAvADEAAAABAAAAAAAvADIAAAABAAAAAAAwAC4AAAAAAAAAAAAwAC8AAAAAAAAAAAAwADAAAAABAAAAAAAwADEAAAABAAAAAAAwADIAAAABAAAAAAAxAC4AAAAAAAAAAAAxAC8AAAAAAAAAAAAxADAAAAABAAAAAAAxADEAAAABAAAAAAAxADIAAAABAAAAAAAyAC4AAAABAAAAAAAyAC8AAAABAAAAAAAyADAAAAABAAAAAAAyADEAAAABAAAAAAAyADIAAAABAAAAAAAzAC4AAAABAAAAAAAzAC8AAAABAAAAAAAzADAAAAABAAAAAAAzADEAAAABAAAAAAAzADIAAAABAAAAAAA0AC4AAAABAAAAAAA0AC8AAAABAAAAAAA0ADAAAAABAAAAAAA0ADEAAAABAAAAAAA0ADIAAAABAAAAAAAmADIAAAAAAAAAAAAnADIAAAAAAAAAAAAoADIAAAAAAAAAAAApADIAAAAAAAAAAAAqADIAAAAAAAAAAAArADIAAAAAAAAAAAAsADIAAAAAAAAAAAA=") +tile_set = SubResource("TileSet_73fnb") +script = ExtResource("3_8hm71") + +[node name="Spawner" type="Node2D" parent="TileMap" groups=["Spawners"]] +position = Vector2(1845, 10) +script = ExtResource("16_17rhs") +spawned_entity = ExtResource("14_gu47o") + +[node name="Spawner2" type="Node2D" parent="TileMap" groups=["Spawners"]] +position = Vector2(30, 2467) +script = ExtResource("16_17rhs") +spawned_entity = ExtResource("14_gu47o") + +[node name="Spawner3" type="Node2D" parent="TileMap" groups=["Spawners"]] +position = Vector2(3359, 32) +script = ExtResource("16_17rhs") +spawned_entity = ExtResource("14_gu47o") + +[node name="Spawner4" type="Node2D" parent="TileMap" groups=["Spawners"]] +position = Vector2(3365, 1379) +script = ExtResource("16_17rhs") +spawned_entity = ExtResource("14_gu47o") + +[node name="Spawner5" type="Node2D" parent="TileMap" groups=["Spawners"]] +position = Vector2(2630, 3230) +script = ExtResource("16_17rhs") +spawned_entity = ExtResource("14_gu47o") + +[node name="Spawner6" type="Node2D" parent="TileMap" groups=["Spawners"]] +position = Vector2(905, 3238) +script = ExtResource("16_17rhs") +spawned_entity = ExtResource("14_gu47o") + +[node name="PointLight2D" type="PointLight2D" parent="TileMap"] +visible = false +position = Vector2(474, 477) +shadow_enabled = true +shadow_filter = 1 +texture = SubResource("GradientTexture2D_akxrc") + +[node name="Bullet" parent="TileMap" instance=ExtResource("16_223my")] +position = Vector2(617, 287) + +[node name="Citizen" parent="TileMap" instance=ExtResource("13_1q4c1")] +position = Vector2(1479, 1475) + +[node name="Citizen2" parent="TileMap" instance=ExtResource("13_1q4c1")] +position = Vector2(1512, 1458) + +[node name="Citizen3" parent="TileMap" instance=ExtResource("13_1q4c1")] +position = Vector2(1443, 1463) + +[node name="Citizen4" parent="TileMap" instance=ExtResource("13_1q4c1")] +position = Vector2(1473, 1427) + +[node name="Citizen5" parent="TileMap" instance=ExtResource("13_1q4c1")] +position = Vector2(1521, 1409) + +[node name="Splat" parent="TileMap" instance=ExtResource("10_i6j5g")] +z_index = -1 +z_as_relative = false +position = Vector2(1780, 1355) + +[node name="Camera2D" type="Camera2D" parent="."] +position = Vector2(1628, 1565) +script = ExtResource("18_8j1ou") + +[node name="Control" type="CanvasLayer" parent="."] + +[node name="VBoxContainer" type="VBoxContainer" parent="Control"] +offset_left = 10.0 +offset_top = 10.0 +offset_right = 94.0 +offset_bottom = 308.0 + +[node name="MinerBuildButton" type="Button" parent="Control/VBoxContainer"] +layout_mode = 2 +text = "Miner" +icon = ExtResource("14_223my") +icon_alignment = 1 +vertical_icon_alignment = 0 +script = ExtResource("19_o3hm7") +build_scene = ExtResource("5_8j1ou") + +[node name="ProcessorBuildButton" type="Button" parent="Control/VBoxContainer"] +layout_mode = 2 +text = "Processor" +icon = ExtResource("16_8j1ou") +icon_alignment = 1 +vertical_icon_alignment = 0 +script = ExtResource("19_o3hm7") +build_scene = ExtResource("6_gu47o") + +[node name="TurretBuildButton" type="Button" parent="Control/VBoxContainer"] +layout_mode = 2 +text = "Turret" +icon = ExtResource("17_8j1ou") +icon_alignment = 1 +vertical_icon_alignment = 0 +script = ExtResource("19_o3hm7") +build_scene = ExtResource("7_8hm71") + +[node name="StorageBuildButton" type="Button" parent="Control/VBoxContainer"] +layout_mode = 2 +text = "Storage +" +icon = ExtResource("18_302uq") +icon_alignment = 1 +vertical_icon_alignment = 0 +script = ExtResource("19_o3hm7") +build_scene = ExtResource("18_xpof7") + +[node name="ConveyorBuildButton" type="Button" parent="Control/VBoxContainer"] +layout_mode = 2 +text = "Conveyor" +icon = ExtResource("18_o3hm7") +icon_alignment = 1 +vertical_icon_alignment = 0 +script = ExtResource("19_o3hm7") +build_scene = ExtResource("13_17rhs") + +[node name="WatchtowerBuildButton" type="Button" parent="Control/VBoxContainer"] +layout_mode = 2 +text = "Watchtower" +icon = ExtResource("23_iss77") +icon_alignment = 1 +vertical_icon_alignment = 0 +script = ExtResource("19_o3hm7") +build_scene = ExtResource("23_g6g5t") + +[node name="VBoxContainer2" type="VBoxContainer" parent="Control"] +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -40.0 +offset_bottom = 40.0 +grow_horizontal = 0 +size_flags_horizontal = 8 +size_flags_vertical = 0 + +[node name="SpawnersActiveButton" type="CheckButton" parent="Control/VBoxContainer2"] +layout_mode = 2 +text = "Enemy Spawns" +script = ExtResource("23_aobyt") + +[node name="ItemList" type="ItemList" parent="Control"] +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -40.0 +offset_top = -40.0 +grow_horizontal = 0 +grow_vertical = 0 +size_flags_horizontal = 6 +size_flags_vertical = 6 +auto_width = true +auto_height = true +text_overrun_behavior = 2 +item_count = 2 +item_0/text = "Build Turret" +item_1/text = "Transfer Cloudy to Bed" +script = ExtResource("23_i6j5g") + +[connection signal="task_available" from="TileMap/Citizen" to="CitizenManager" method="add_task"] +[connection signal="task_available" from="TileMap/Citizen2" to="CitizenManager" method="add_task"] +[connection signal="task_available" from="TileMap/Citizen3" to="CitizenManager" method="add_task"] +[connection signal="task_available" from="TileMap/Citizen4" to="CitizenManager" method="add_task"] +[connection signal="task_available" from="TileMap/Citizen5" to="CitizenManager" method="add_task"] +[connection signal="build_requested" from="Control/VBoxContainer/MinerBuildButton" to="." method="build_object"] +[connection signal="pressed" from="Control/VBoxContainer/MinerBuildButton" to="Control/VBoxContainer/MinerBuildButton" method="_on_pressed"] +[connection signal="build_requested" from="Control/VBoxContainer/ProcessorBuildButton" to="." method="build_object"] +[connection signal="pressed" from="Control/VBoxContainer/ProcessorBuildButton" to="Control/VBoxContainer/ProcessorBuildButton" method="_on_pressed"] +[connection signal="build_requested" from="Control/VBoxContainer/TurretBuildButton" to="." method="build_object"] +[connection signal="pressed" from="Control/VBoxContainer/TurretBuildButton" to="Control/VBoxContainer/TurretBuildButton" method="_on_pressed"] +[connection signal="build_requested" from="Control/VBoxContainer/StorageBuildButton" to="." method="build_object"] +[connection signal="pressed" from="Control/VBoxContainer/StorageBuildButton" to="Control/VBoxContainer/StorageBuildButton" method="_on_pressed"] +[connection signal="build_requested" from="Control/VBoxContainer/ConveyorBuildButton" to="." method="build_two_point_object"] +[connection signal="pressed" from="Control/VBoxContainer/ConveyorBuildButton" to="Control/VBoxContainer/ConveyorBuildButton" method="_on_pressed"] +[connection signal="build_requested" from="Control/VBoxContainer/WatchtowerBuildButton" to="." method="build_object"] +[connection signal="pressed" from="Control/VBoxContainer/WatchtowerBuildButton" to="Control/VBoxContainer/WatchtowerBuildButton" method="_on_pressed"] diff --git a/scripts/BuildButton.gd b/scripts/BuildButton.gd new file mode 100644 index 0000000..b850c41 --- /dev/null +++ b/scripts/BuildButton.gd @@ -0,0 +1,8 @@ +extends Button + +signal build_requested(scene: PackedScene) + +@export var build_scene: PackedScene + +func _on_pressed() -> void: + build_requested.emit(build_scene) diff --git a/scripts/BuildButton.gd.uid b/scripts/BuildButton.gd.uid new file mode 100644 index 0000000..97efeec --- /dev/null +++ b/scripts/BuildButton.gd.uid @@ -0,0 +1 @@ +uid://c8bkwna465q5i diff --git a/scripts/Building.gd b/scripts/Building.gd new file mode 100644 index 0000000..bd5f311 --- /dev/null +++ b/scripts/Building.gd @@ -0,0 +1,74 @@ +extends CollisionObject2D +class_name Building + +enum BuildState { UNPLACED, BUILDING, FUNCTIONAL, DESTROYED } + +signal selected(building: Building) +signal task_available(task: CitizenManager.Task) + +signal placed() +signal built() +signal destroyed() + +@export var build_materials_required: Dictionary[Item, int] +@export var build_time: float = 10.0 + +var build_materials: Dictionary[Item, int] +@export var build_state: BuildState = BuildState.UNPLACED + +var old_collision_layers: int = 0 + +func start_placement() -> void: + set_collidable(false) + #$CollisionShape2D.disabled = true + +func place() -> void: + build_state = BuildState.BUILDING + modulate = Color(1,1,1,0.25) + + if !build_materials_required.is_empty(): + for item in build_materials_required.keys(): + for i in range(build_materials_required[item]): + var task: CitizenManager.FetchItemTask = CitizenManager.FetchItemTask.new() + task.building = self + task.item = item + task_available.emit(task) + else: + var build_task: CitizenManager.BuildTask = CitizenManager.BuildTask.new() + build_task.building = self + task_available.emit(build_task) + +func add_build_material(item_node: ItemNode) -> void: + var item: Item = item_node.item_type + item_node.queue_free() + build_materials.set(item, build_materials.get(item,0) + 1) + + if can_build(): + var build_task: CitizenManager.BuildTask = CitizenManager.BuildTask.new() + build_task.building = self + task_available.emit(build_task) + +func can_build() -> bool: + for item in build_materials_required.keys(): + if build_materials.get(item, 0) < build_materials_required[item]: + return false + return true + +func build() -> void: + build_state = BuildState.FUNCTIONAL + modulate = Color(1,1,1,1) + + set_collidable(true) + +func set_collidable(enabled: bool) -> void: + if enabled: + collision_layer = old_collision_layers + else: + old_collision_layers = collision_layer + collision_layer = 0x8000_0000 # layer 32 + + for child in find_children("*", "PathfindObstacle"): + child.enabled = enabled + +func is_functional() -> bool: + return build_state == BuildState.FUNCTIONAL diff --git a/scripts/Building.gd.uid b/scripts/Building.gd.uid new file mode 100644 index 0000000..dbd3c9d --- /dev/null +++ b/scripts/Building.gd.uid @@ -0,0 +1 @@ +uid://dqq6rfbnf5xo diff --git a/scripts/Camera.gd b/scripts/Camera.gd new file mode 100644 index 0000000..7b536c0 --- /dev/null +++ b/scripts/Camera.gd @@ -0,0 +1,10 @@ +extends Camera2D + +@export var camera_speed: float = 250.0 + +func _process(delta: float) -> void: + var movement: Vector2 + movement.y = Input.get_axis("camera_up", "camera_down") + movement.x = Input.get_axis("camera_left", "camera_right") + + position += movement * delta * camera_speed diff --git a/scripts/Camera.gd.uid b/scripts/Camera.gd.uid new file mode 100644 index 0000000..57f63ed --- /dev/null +++ b/scripts/Camera.gd.uid @@ -0,0 +1 @@ +uid://bxhqx5445f6r3 diff --git a/scripts/Citizen.gd b/scripts/Citizen.gd new file mode 100644 index 0000000..339b709 --- /dev/null +++ b/scripts/Citizen.gd @@ -0,0 +1,61 @@ +extends Unit +class_name Citizen + +signal task_available(task: CitizenManager.Task) + +var task: CitizenManager.Task = null +var carried_item: ItemNode = null +const item_node_scene: PackedScene = preload("res://objects/resource.tscn") + +func _process(delta: float) -> void: + super(delta) + $Body.flip_h = !(facing >= PI/2 or facing <= -PI/2) + $Arms.flip_h = !(facing >= PI/2 or facing <= -PI/2) + $Body.z_index = 0 if (facing > 0) else 1 + $Body.frame = 0 if (facing > 0) else 1 + + #target = get_global_mouse_position() + + +func assign_task(t: CitizenManager.Task): + task = t + var ok: bool = await task.execute(self) + if !ok: + task_available.emit(task) + task = null + +func pickup_item_from_building(item: Item, building: Machine) -> bool: + if building.fetch_item_from_storage(item, 1): + var item_node: ItemNode = item_node_scene.instantiate() + pickup_item_node(item_node) + item_node.item_type = item + return true + return false + +func store_item_in_contruction_site(construction_site: Building) -> bool: + if carried_item == null: + return false + construction_site.add_build_material(carried_item) + return true + +func store_item_in_machine(machine: Machine) -> bool: + if carried_item == null: + return false + if !machine.can_accept_item(carried_item.item_type): + return false + return machine.offer_item(carried_item) + +func pickup_item_node(item_node: ItemNode): + $Arms.add_child(item_node) + #item_node.z_index = -1 + item_node.position = Vector2(0,0) + carried_item = item_node + +func drop_item_node(): + if carried_item == null: + return + carried_item.reparent(get_parent()) + carried_item = null + +func is_idle() -> bool: + return task == null diff --git a/scripts/Citizen.gd.uid b/scripts/Citizen.gd.uid new file mode 100644 index 0000000..90d3cc8 --- /dev/null +++ b/scripts/Citizen.gd.uid @@ -0,0 +1 @@ +uid://b80nc18ya55my diff --git a/scripts/Conveyor.gd b/scripts/Conveyor.gd new file mode 100644 index 0000000..c44d7d0 --- /dev/null +++ b/scripts/Conveyor.gd @@ -0,0 +1,46 @@ +extends Machine + +@export var separation: float = 16.0; + +func _ready() -> void: + remove_accepted_item_nodes = false + +func set_start(node: Machine): + global_position = node.global_position + add_source(node) + #$Line.points = [Vector2(0,0)] + $Line.belt_stopped = true + #node.connect("item_available", accept_item) + +func add_point(point: Vector2): + $Line.points.append(to_local(point)) + +func set_end(node: Machine): + $Line.points[1] = to_local(node.global_position) + #$Line.points.append(to_local(node.global_position)) + $Line.calculate_length() + add_sink(node) + $Line.belt_stopped = false + #connect("item_available", node.accept_item) + +func can_accept_item(item: Item) -> bool: + return super(item) \ + and !$Line.belt_stopped \ + and $Line.get_first_object_progress() >= separation + +func offer_item(node: ItemNode) -> bool: + if $Line.belt_stopped: + return false + var ok: bool = super(node) + if ok: + $Line.add_transported_object(node) + return ok + +func _on_line_node_at_end(node: Node) -> void: + if node is ItemNode: + if can_send_item(node.item_type): + fetch_item_from_storage(node.item_type, 1) + var sent: bool = send_item(node) + if sent: + $Line.remove_transported_object(node) + diff --git a/scripts/Conveyor.gd.uid b/scripts/Conveyor.gd.uid new file mode 100644 index 0000000..5ba6858 --- /dev/null +++ b/scripts/Conveyor.gd.uid @@ -0,0 +1 @@ +uid://dkv4h3rp0ml1t diff --git a/scripts/DetectionArea.gd b/scripts/DetectionArea.gd new file mode 100644 index 0000000..98a370f --- /dev/null +++ b/scripts/DetectionArea.gd @@ -0,0 +1,46 @@ +@tool +extends Area2D +class_name DetectionArea + +signal enemy_detected(enemy: Enemy) + +@export var radius: float = 1000: + set(value): + radius = value + if Engine.is_editor_hint(): + update_radii() +@export var requires_line_of_sight: bool = true + +enum ActiveState {DISABLED, PREVIEW, ACTIVE} +@export var active_state: ActiveState = ActiveState.PREVIEW + +func _ready() -> void: + update_radii() + +func update_radii() -> void: + $CollisionShape2D.shape = $CollisionShape2D.shape.duplicate() + $CollisionShape2D.shape.radius = radius + $PointLight2D.texture = $PointLight2D.texture.duplicate() + $PointLight2D.texture.width = radius * 2 + $PointLight2D.texture.height = radius * 2 + +func _process(delta: float) -> void: + if Engine.is_editor_hint(): + return + for body in get_overlapping_bodies(): + if body is Enemy: + if !body.sighted: + var sighted: bool = true + if requires_line_of_sight: + # perform LOS check + var params: PhysicsRayQueryParameters2D = PhysicsRayQueryParameters2D.new() + params.collision_mask = 0b11 + params.from = global_position + params.to = body.global_position + var result: Dictionary = get_world_2d().direct_space_state.intersect_ray(params) + sighted = result.has("collider") and result["collider"] == body + + if sighted: + enemy_detected.emit(body) + body.sighted = true + diff --git a/scripts/DetectionArea.gd.uid b/scripts/DetectionArea.gd.uid new file mode 100644 index 0000000..da09075 --- /dev/null +++ b/scripts/DetectionArea.gd.uid @@ -0,0 +1 @@ +uid://dkqr1sxxunr2w diff --git a/scripts/Enemy.gd b/scripts/Enemy.gd new file mode 100644 index 0000000..39db807 --- /dev/null +++ b/scripts/Enemy.gd @@ -0,0 +1,17 @@ +extends Unit + +class_name Enemy + +var sighted: bool = false: + set(value): + sighted = value + visible = sighted + +func _ready() -> void: + target = target + visible = sighted + +func _process(delta: float) -> void: + super(delta) + + $Sprite2D.flip_h = !(facing >= PI/2 or facing <= -PI/2) diff --git a/scripts/Enemy.gd.uid b/scripts/Enemy.gd.uid new file mode 100644 index 0000000..e8d4ff4 --- /dev/null +++ b/scripts/Enemy.gd.uid @@ -0,0 +1 @@ +uid://vxnx03ef25s8 diff --git a/scripts/GameManager.gd b/scripts/GameManager.gd new file mode 100644 index 0000000..e4fe8ad --- /dev/null +++ b/scripts/GameManager.gd @@ -0,0 +1,44 @@ +extends Node2D +class_name GameManager + +enum MouseState { SELECT, BUILD, BUILD_CONNECTION_FIRST, BUILD_CONNECTION_SECOND } + +var mouse_state: MouseState +var building_object: Building = null + +func build_object(scene: PackedScene): + mouse_state = MouseState.BUILD + building_object = scene.instantiate() + $TileMap.add_child(building_object) + building_object.start_placement() + building_object.connect("selected", on_building_selected) + building_object.connect("task_available", $CitizenManager.add_task) + +func build_two_point_object(scene: PackedScene): + build_object(scene) + mouse_state = MouseState.BUILD_CONNECTION_FIRST + +func on_building_selected(building: Machine) -> void: + if mouse_state == MouseState.BUILD_CONNECTION_FIRST: + building_object.set_start(building) + mouse_state = MouseState.BUILD_CONNECTION_SECOND + elif mouse_state == MouseState.BUILD_CONNECTION_SECOND: + building_object.set_end(building) + building_object.build() + mouse_state = MouseState.SELECT + +func _input(event: InputEvent) -> void: + if event is InputEventMouse: + if mouse_state == MouseState.BUILD: + building_object.position = get_global_mouse_position() + + if event is InputEventMouseButton: + if mouse_state == MouseState.BUILD: + building_object.position = get_global_mouse_position() + building_object.place() + mouse_state = MouseState.SELECT + if mouse_state == MouseState.BUILD_CONNECTION_SECOND: + building_object.add_point(get_global_mouse_position()) + #if mouse_state == MouseState.BUILD_CONNECTION_FIRST + + diff --git a/scripts/GameManager.gd.uid b/scripts/GameManager.gd.uid new file mode 100644 index 0000000..62c7b2a --- /dev/null +++ b/scripts/GameManager.gd.uid @@ -0,0 +1 @@ +uid://tndb4f3lkc7g diff --git a/scripts/Item.gd b/scripts/Item.gd new file mode 100644 index 0000000..7e5d872 --- /dev/null +++ b/scripts/Item.gd @@ -0,0 +1,6 @@ +extends Resource + +class_name Item + +@export var name: String = "" +@export var texture: Texture2D diff --git a/scripts/Item.gd.uid b/scripts/Item.gd.uid new file mode 100644 index 0000000..4319e31 --- /dev/null +++ b/scripts/Item.gd.uid @@ -0,0 +1 @@ +uid://bha4kv6d0iba0 diff --git a/scripts/ItemNode.gd b/scripts/ItemNode.gd new file mode 100644 index 0000000..d461d87 --- /dev/null +++ b/scripts/ItemNode.gd @@ -0,0 +1,9 @@ +extends Node2D + +class_name ItemNode + +@export var item_type: Item: + set(value): + item_type = value + $Sprite2D.texture = item_type.texture + #name = item_type.name diff --git a/scripts/ItemNode.gd.uid b/scripts/ItemNode.gd.uid new file mode 100644 index 0000000..5b73386 --- /dev/null +++ b/scripts/ItemNode.gd.uid @@ -0,0 +1 @@ +uid://ccu24smgm1u4 diff --git a/scripts/Machine.gd b/scripts/Machine.gd new file mode 100644 index 0000000..6e7dbfd --- /dev/null +++ b/scripts/Machine.gd @@ -0,0 +1,112 @@ +extends Building + +class_name Machine + +#signal item_available(node: ItemNode) + +@export var accepted_items: Array[Item] +@export var produced_item: Item +const item_node_scene: PackedScene = preload("res://objects/resource.tscn") +var remove_accepted_item_nodes: bool = true + +@export var sources: Array[Machine] +@export var source_limit: int = 0 +@export var sinks: Array[Machine] +@export var sink_limit: int = 0 + +@export var stored_items: Array[Item] +@export var storage_limit: int = 10 + +func _ready() -> void: + connect("input_event", on_input_event) + +func place() -> void: + super() + +func on_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void: + if event is InputEventMouseButton: + if event.button_mask & MOUSE_BUTTON_MASK_LEFT: + selected.emit(self) + +func add_source(source: Machine) -> bool: + if sources.size() < source_limit: + sources.append(source) + if !source.sinks.has(self): + source.sinks.append(self) + return true + return false + +func add_sink(sink: Machine) -> bool: + if sinks.size() < sink_limit: + sinks.append(sink) + if !sink.sources.has(self): + sink.sources.append(self) + return true + return false + +func offer_item(node: ItemNode) -> bool: + return store_item(node) + +func can_accept_item(item: Item) -> bool: + return (accepted_items.has(item) or accepted_items.is_empty()) \ + and (stored_items.size() < storage_limit) \ + and is_functional() + +func produce() -> bool: + if stored_items.size() < storage_limit: + # create a new item if there's room + stored_items.append(produced_item) + if stored_items.has(produced_item): + # send items if we have them + if can_send_item(produced_item): + var item_node: ItemNode = unstore_item(produced_item) + if !send_item(item_node): + # TODO: just blow up the item for now + item_node.queue_free() + return true + return false + +func unstore_item(item: Item) -> ItemNode: + if fetch_item_from_storage(item, 1): + var item_node: ItemNode = item_node_scene.instantiate(PackedScene.GEN_EDIT_STATE_DISABLED) + item_node.item_type = item + add_child(item_node) + item_node.global_position = global_position + return item_node + return null + +func send_item(item_node: ItemNode) -> bool: + var machines: Array[Machine] = sinks.duplicate() + machines.shuffle() + for sink in machines: + if sink.offer_item(item_node): + return true + return false + +func can_send_item(item: Item) -> bool: + return is_functional() and sinks.any(func(machine:Machine): return machine.can_accept_item(item)) + + +func store_item(item_node: ItemNode) -> bool: + if stored_items.size() < storage_limit: + stored_items.append(item_node.item_type) + if remove_accepted_item_nodes: + item_node.queue_free() + return true + return false + +func fetch_item_from_storage(item: Item, count: int) -> bool: + var idxs: Array[int] = [] + for idx in range(stored_items.size()): + if stored_items[idx] == item: + idxs.append(idx) + count -= 1 + if count <= 0: + break + if count <= 0: + for idx in idxs: + stored_items.remove_at(idx) + return true + else: + return false + diff --git a/scripts/Machine.gd.uid b/scripts/Machine.gd.uid new file mode 100644 index 0000000..d928cd6 --- /dev/null +++ b/scripts/Machine.gd.uid @@ -0,0 +1 @@ +uid://bhpjq1ppxvler diff --git a/scripts/Miner.gd b/scripts/Miner.gd new file mode 100644 index 0000000..71d4d7c --- /dev/null +++ b/scripts/Miner.gd @@ -0,0 +1,29 @@ +extends "res://scripts/Machine.gd" + +@export var production_period: float = 0.0 +var production_timer: float = 0.0 + + +func _ready() -> void: + super() + determine_resource() + +func place() -> void: + super() + determine_resource() + +func determine_resource() -> void: + var tile_coord: Vector2i = $"..".local_to_map(position) + var ore: Resource = $"..".get_cell_tile_data(tile_coord).get_custom_data("Ore") + if ore != null: + produced_item = ore + +func _process(delta: float) -> void: + if !is_functional(): + return + if produced_item != null: + if production_period > 0: + production_timer += delta + if production_timer >= production_period: + production_timer -= production_period + produce() diff --git a/scripts/Miner.gd.uid b/scripts/Miner.gd.uid new file mode 100644 index 0000000..2b00158 --- /dev/null +++ b/scripts/Miner.gd.uid @@ -0,0 +1 @@ +uid://cdor1505oo2oj diff --git a/scripts/PathfindObstacle.gd b/scripts/PathfindObstacle.gd new file mode 100644 index 0000000..16f024c --- /dev/null +++ b/scripts/PathfindObstacle.gd @@ -0,0 +1,68 @@ +extends Node2D +class_name PathfindObstacle + +@export var radius: float = 32 +@export var added_weight: float = 0.0 +@export var solid: bool = false + +@export var enabled: bool = true: + set(value): + if value != enabled: + update(value) + enabled = value + +var world: World + +var previous_tiles: Array[Vector2i] = [] +var previous_position: Vector2 = Vector2() + +func _ready() -> void: + world = find_parent("TileMap") + previous_position = global_position + update(true) + +func _exit_tree() -> void: + update(false) + +func _process(delta: float) -> void: + if global_position != previous_position: + previous_position = global_position + if enabled: + update(false) + update(true) + +func get_overlapped_tiles() -> Array[Vector2i]: + var top_left_pos: Vector2i = world.local_to_map(world.to_local(global_position) - Vector2(radius, radius)) + var bottom_right_pos: Vector2i = world.local_to_map(world.to_local(global_position) + Vector2(radius, radius)) + var ret: Array[Vector2i] = [] + for x in range(top_left_pos.x, bottom_right_pos.x+1): + for y in range(top_left_pos.y, bottom_right_pos.y+1): + var tile: Vector2i = Vector2i(x,y) + if world.get_cell_source_id(tile): + continue + ret.append(tile) + return ret + +func update(enable: bool): + var tiles: Array[Vector2i] + if enable: + tiles = get_overlapped_tiles() + previous_tiles = tiles + else: + tiles = previous_tiles + + for tile in tiles: + if solid: + world.astar_grid.set_point_solid(tile, enable) + var weight: float = world.astar_grid.get_point_weight_scale(tile) + #print("Reading tile %s weight: %f" % [tile, weight]) + if enable: + weight += added_weight + else: + weight -= added_weight + #print("Updating tile %s with weight %f" % [tile, weight]) + #if weight > 1: + #world.set_cell(tile, 0, Vector2(1,1)) + #else: + #world.set_cell(tile, 0, Vector2(0,0)) + world.astar_grid.set_point_weight_scale(tile, weight) diff --git a/scripts/PathfindObstacle.gd.uid b/scripts/PathfindObstacle.gd.uid new file mode 100644 index 0000000..54439a5 --- /dev/null +++ b/scripts/PathfindObstacle.gd.uid @@ -0,0 +1 @@ +uid://inyhfjkw5h2u diff --git a/scripts/Processor.gd b/scripts/Processor.gd new file mode 100644 index 0000000..2c44ef0 --- /dev/null +++ b/scripts/Processor.gd @@ -0,0 +1,39 @@ +extends "res://scripts/Machine.gd" + +@export var ingredient_items: Dictionary[Item, int] +@export var production_time: float = 1.0 + +var production_timer: float = 0.0 + +func _process(delta: float) -> void: + if ready_to_produce(): + production_timer += delta + if production_timer >= production_time: + if !can_send_item(produced_item): + return + consume_ingredients() + if produce(): + production_timer -= production_time + +func ready_to_produce() -> bool: + if produced_item == null: + return false # that's not gonna work + var checklist: Dictionary[Item, int] = ingredient_items.duplicate() + for item in stored_items: + if checklist.has(item): + var count: int = checklist.get(item) + count -= 1 + if count > 0: + checklist.set(item, count) + else: + checklist.erase(item) + if checklist.is_empty(): + return true + return false + +func consume_ingredients() -> void: + for item in ingredient_items: + fetch_item_from_storage(item, ingredient_items[item]) + +func _on_conveyor_2_item_available(node: ItemNode) -> void: + pass # Replace with function body. diff --git a/scripts/Processor.gd.uid b/scripts/Processor.gd.uid new file mode 100644 index 0000000..07a7bf3 --- /dev/null +++ b/scripts/Processor.gd.uid @@ -0,0 +1 @@ +uid://bsc4h24tql7nr diff --git a/scripts/Projectile.gd b/scripts/Projectile.gd new file mode 100644 index 0000000..3a854d0 --- /dev/null +++ b/scripts/Projectile.gd @@ -0,0 +1,22 @@ +extends RigidBody2D + +@export var cancel_time: float = 3.0 +@export var cancel_speed: float = 50.0 +@export var lethal_speed: float = 100.0 + +var lifetime: float = 0.0 + +func _process(delta: float) -> void: + lifetime += delta + if lifetime >= cancel_time: + cancel() + elif linear_velocity.length() <= cancel_speed and lifetime >= 0.1: + cancel() + +func cancel() -> void: + queue_free() + +func _on_body_entered(body: Node) -> void: + if linear_velocity.length() >= lethal_speed: + if body is Enemy: + body.kill() diff --git a/scripts/Projectile.gd.uid b/scripts/Projectile.gd.uid new file mode 100644 index 0000000..0cdef86 --- /dev/null +++ b/scripts/Projectile.gd.uid @@ -0,0 +1 @@ +uid://c5sb5760mlui6 diff --git a/scripts/ResourceMover.gd b/scripts/ResourceMover.gd new file mode 100644 index 0000000..b2020bd --- /dev/null +++ b/scripts/ResourceMover.gd @@ -0,0 +1,74 @@ +extends Line2D + +signal node_at_end(node: Node) + +@export var speed: float = 10.0 +var length: float = 1000.0 +var transported_objects: Dictionary +var belt_stopped: bool = false + +func _ready() -> void: + calculate_length() + +func calculate_length() -> void: + length = 0.0 + var first: bool = true + var lastPoint: Vector2 + for point in points: + if first: + first = false + continue + else: + length += lastPoint.distance_to(point) + lastPoint = point + +func get_first_object_progress() -> float: + var least: float = length + for key in transported_objects.keys(): + var progress: float = transported_objects.get(key, 0.0) + if progress < least: + least = progress + return least + +func position_resource(res: Node2D, progress: float) -> void: + var first: bool = true + var segmentStartPos: Vector2 = Vector2() + var segmentStartProg: float = 0.0 + res.z_index = 1 + for point in points: + if first: + segmentStartPos = point + first = false + continue + var endProg: float = segmentStartProg + segmentStartPos.distance_to(point) + if progress <= endProg: + var x: float = (progress - segmentStartProg) / (endProg - segmentStartProg) + var pos: Vector2 = segmentStartPos.lerp(point, x) + res.position = pos + return + segmentStartProg = endProg + segmentStartPos = point + +func add_transported_object(res: Node) -> void: + if res is Node2D: + transported_objects.set(res, 0); + +func remove_transported_object(res: Node) -> void: + if res is Node2D: + var progress: float = transported_objects.get(res, 0.0) + transported_objects.erase(res) + if progress >= length: + belt_stopped = false + +func _process(delta: float) -> void: + for key in transported_objects.keys(): + var progress: float = transported_objects.get(key, 0.0) + if !belt_stopped: + progress += speed * delta + transported_objects.set(key, progress) + + position_resource(key, progress) + + if progress >= length: + belt_stopped = true + node_at_end.emit(key) diff --git a/scripts/ResourceMover.gd.uid b/scripts/ResourceMover.gd.uid new file mode 100644 index 0000000..2ba3bc4 --- /dev/null +++ b/scripts/ResourceMover.gd.uid @@ -0,0 +1 @@ +uid://bre6c0lytr0ow diff --git a/scripts/Spawner.gd b/scripts/Spawner.gd new file mode 100644 index 0000000..89ef239 --- /dev/null +++ b/scripts/Spawner.gd @@ -0,0 +1,18 @@ +extends Node2D + +@export var spawned_entity: PackedScene +@export var active: bool = false +@export var spawn_time: float = 1.0 + +var spawn_timer: float = 0.0 + +func _process(delta: float) -> void: + if !active: + return + spawn_timer += delta + if spawn_timer >= spawn_time: + spawn_timer -= spawn_time + var entity: Node = spawned_entity.instantiate() + add_sibling(entity) + if entity is Node2D: + entity.global_position = global_position diff --git a/scripts/Spawner.gd.uid b/scripts/Spawner.gd.uid new file mode 100644 index 0000000..befdc85 --- /dev/null +++ b/scripts/Spawner.gd.uid @@ -0,0 +1 @@ +uid://2rysy0w0dk7c diff --git a/scripts/Turret.gd b/scripts/Turret.gd new file mode 100644 index 0000000..5d21a86 --- /dev/null +++ b/scripts/Turret.gd @@ -0,0 +1,69 @@ +extends "res://scripts/Machine.gd" + +@export var bullet_scene: PackedScene +@export var bullet_item: Item +@export var fire_period: float = 0.5 +@export var detection_poll_time: float = 0.5 + +var detection_cooldown = 0.0 +var fire_cooldown: float = 0.0 +var current_target: Enemy = null + +func _ready() -> void: + super() + detection_cooldown = randf() * detection_poll_time + +func _process(delta: float) -> void: + # clear target if it's dead or gone + if current_target != null: + check_target_status() + + # find a target if we don't have one + if current_target == null: + detection_cooldown -= delta + if detection_cooldown <= 0: + detection_cooldown += detection_poll_time + search_for_enemy() + + # fire at the target if we have one + if current_target != null: + if fire_cooldown <= 0: + if fetch_item_from_storage(bullet_item, 1): + fire_at_target() + + if fire_cooldown > 0: + fire_cooldown -= delta + +func check_target_status() -> void: + if current_target.is_queued_for_deletion(): + current_target = null + +func search_for_enemy() -> void: + var enemies: Array[Node] = get_tree().get_nodes_in_group("Enemy") + var closest: float = 9999999999 + for enemy in enemies: + if enemy is Enemy: + if !enemy.sighted: + continue + var distance_sqr = global_position.distance_squared_to(enemy.global_position) + if distance_sqr <= closest: + var params: PhysicsRayQueryParameters2D = PhysicsRayQueryParameters2D.new() + params.collision_mask = 0b11 + params.from = global_position + params.to = enemy.global_position + var result: Dictionary = get_world_2d().direct_space_state.intersect_ray(params) + if result.has("collider"): + if !result["collider"] is PhysicsBody2D: + continue + var body: PhysicsBody2D = result["collider"] + if body is Enemy: + current_target = body + closest = body.global_position.distance_squared_to(global_position) + +func fire_at_target() -> void: + fire_cooldown += fire_period + var bullet: RigidBody2D = bullet_scene.instantiate() + add_child(bullet) + var angle: float = global_position.angle_to_point(current_target.global_position) + bullet.rotation = angle + bullet.apply_impulse(Vector2(1000,0).rotated(angle)) diff --git a/scripts/Turret.gd.uid b/scripts/Turret.gd.uid new file mode 100644 index 0000000..ca5d5ca --- /dev/null +++ b/scripts/Turret.gd.uid @@ -0,0 +1 @@ +uid://dqwkwjkvo374n diff --git a/scripts/Unit.gd b/scripts/Unit.gd new file mode 100644 index 0000000..0106bfc --- /dev/null +++ b/scripts/Unit.gd @@ -0,0 +1,160 @@ +extends RigidBody2D + +class_name Unit + +enum TaskStatus { + INTERRUPTED, + DESTINATION_REACHED, + ITEM_PICKED_UP, + ITEM_DROPPED, +} +signal task_updated(task_status: TaskStatus) + +@export var movement_force: float = 100 +@export var max_speed: float = 10 +@export var path_give_up_theshold: float = 96.0 +@export var stuck_speed: float = 5.0 +@export var stuck_time: float = 1.0 +@export var target_distance: float = 64.0 + +static var splat_scene: PackedScene = preload("res://objects/splat.tscn") +var moving: bool = false +var target: Vector2 = Vector2(1628, 1565): + set(value): + moving = true + target = value + find_path() +var path: PackedVector2Array +var path_ptr: int = 0 +var stuck_timer: float = 0.0 +var stuck: bool = false + +var facing: float = 0.1 + +func _process(delta: float) -> void: + #$PathDebugLine.global_position = Vector2() + if moving: + if global_position.distance_squared_to(target) > target_distance**2: + move(delta) + else: + moving = false + send_task_update(TaskStatus.DESTINATION_REACHED) + +func move(delta: float) -> void: + var direction: Vector2 + if !stuck: + var last_path_point: Vector2 = get_last_path_point() + var path_point: Vector2 = get_next_path_point() + # find out how far we are from the path + var prev_dist_sqr: float = position.distance_squared_to(last_path_point) if !last_path_point.is_zero_approx() else 999999 + var next_dist_sqr: float = position.distance_squared_to(path_point) + # if we're too far from the path, give up on it and find a new one + if next_dist_sqr > (path_give_up_theshold ** 2): + find_path() + path_point = get_next_path_point() + # if we've reached the path point, move to the next one + if next_dist_sqr < prev_dist_sqr: + path_ptr += 1 + path_point = get_next_path_point() + + #var direction: Vector2 = (Vector2(randf() - 0.5, randf() - 0.5) * 2) * 10000 + direction = (path_point - position).normalized() + else: + direction = (Vector2(randf() - 0.5, randf() - 0.5) * 2) + + facing = direction.angle() + + var target_velocity: Vector2 = direction * max_speed + var force: Vector2 = ((target_velocity - linear_velocity) / max_speed) * movement_force + apply_force(force) + #$ForceDebugLine.points[1] = force + + if linear_velocity.length() < stuck_speed: + stuck_timer += delta + if stuck_timer >= stuck_time: + global_position = get_next_path_point() + stuck_timer = 0 + #set_stuck_mode(true) + else: + #if stuck: + #set_stuck_mode(false) + stuck_timer = 0 + +func get_last_path_point() -> Vector2: + if path == null or path.is_empty(): + find_path() + if path_ptr >= path.size() and path.size() >= 2: + return path[-2] + if path.size() <= 1: + return Vector2() + if path != null and !path.is_empty(): + return $"..".map_to_local(path[path_ptr - 1]) + else: + return Vector2() + +func get_next_path_point() -> Vector2: + if path == null or path.is_empty(): + find_path() + if path_ptr >= path.size() and !path.is_empty(): + return path[-1] + if path != null and !path.is_empty(): + return $"..".map_to_local(path[path_ptr]) + else: + return position + +func find_path() -> void: + path_ptr = 0 + var astar_grid: AStarGrid2D = $"..".astar_grid + if astar_grid == null: + return + var source_coords: Vector2i = $"..".local_to_map(position) + var target_coords: Vector2i = $"..".local_to_map(target) + path = astar_grid.get_point_path(source_coords, target_coords, true) + + var debug_points: PackedVector2Array + #debug_points.resize(path.size()) + for point in path: + #var point: Vector2 = path[idx] + var global_point: Vector2 = $"..".map_to_local(point) + debug_points.append(global_point) + #$PathDebugLine.points = debug_points + +func set_stuck_mode(stk: bool) -> void: + stuck = stk + $Sprite2D.modulate = Color(0.75, 0.25, 1.0) if stuck else Color(1,1,1,1) + var astar_grid: AStarGrid2D = $"..".astar_grid + if astar_grid == null: + return + var source_coords: Vector2i = $"..".local_to_map(position) + if stuck: + astar_grid.set_point_weight_scale(source_coords, astar_grid.get_point_weight_scale(source_coords) * 50) + else: + astar_grid.set_point_weight_scale(source_coords, astar_grid.get_point_weight_scale(source_coords) / 50) + +func send_task_update(task_status: TaskStatus) -> void: + task_updated.emit(task_status) + +func wait_for_task_status(task_status: TaskStatus) -> bool: + while true: + var status_received: TaskStatus = await task_updated; + if status_received == task_status: + return true + elif status_received == TaskStatus.INTERRUPTED: + return false + return false + +func go_to_destination(destination: Vector2) -> bool: + target = destination + return await wait_for_task_status(TaskStatus.DESTINATION_REACHED) + +func kill() -> void: + #var astar_grid: AStarGrid2D = $"..".astar_grid + #var source_coords: Vector2i = $"..".local_to_map(position) + #var scale: float = astar_grid.get_point_weight_scale(source_coords) + #print("Tile %s weight scale read: %f" % [source_coords, scale]) + #astar_grid.set_point_weight_scale(source_coords, scale + 0.1) + var splat: Node2D = splat_scene.instantiate() + splat.global_position = global_position + add_sibling(splat) + + queue_free() diff --git a/scripts/Unit.gd.uid b/scripts/Unit.gd.uid new file mode 100644 index 0000000..eb6e5fd --- /dev/null +++ b/scripts/Unit.gd.uid @@ -0,0 +1 @@ +uid://dgputtkapbv8w diff --git a/scripts/World.gd b/scripts/World.gd new file mode 100644 index 0000000..d028b73 --- /dev/null +++ b/scripts/World.gd @@ -0,0 +1,21 @@ +extends TileMapLayer +class_name World + +var astar_grid: AStarGrid2D = AStarGrid2D.new() +#var citizen_scene: PackedScene = preload("res://objects/citizen.tscn") + +func _enter_tree() -> void: + astar_grid.region = get_used_rect() + astar_grid.diagonal_mode = AStarGrid2D.DiagonalMode.DIAGONAL_MODE_ONLY_IF_NO_OBSTACLES + astar_grid.update() + + for cell in get_used_cells(): + var tile_data: TileData = get_cell_tile_data(cell) + if tile_data.get_collision_polygons_count(0) > 0: + astar_grid.set_point_solid(cell) + +#func _ready() -> void: + #for i in range(200): + #var citizen: Citizen = citizen_scene.instantiate() + #citizen.position = Vector2(randf_range(1200, 1800), randf_range(1300,2000)) + #add_child(citizen) diff --git a/scripts/World.gd.uid b/scripts/World.gd.uid new file mode 100644 index 0000000..3af67b3 --- /dev/null +++ b/scripts/World.gd.uid @@ -0,0 +1 @@ +uid://dentfojljr2f0 diff --git a/scripts/spawners_active_button.gd b/scripts/spawners_active_button.gd new file mode 100644 index 0000000..44bc5b5 --- /dev/null +++ b/scripts/spawners_active_button.gd @@ -0,0 +1,5 @@ +extends CheckButton + +func _toggled(toggled_on: bool) -> void: + for node in get_tree().get_nodes_in_group("Spawners"): + node.active = toggled_on diff --git a/scripts/spawners_active_button.gd.uid b/scripts/spawners_active_button.gd.uid new file mode 100644 index 0000000..e08ceee --- /dev/null +++ b/scripts/spawners_active_button.gd.uid @@ -0,0 +1 @@ +uid://de84jpof8rcc3 diff --git a/scripts/splat.gd b/scripts/splat.gd new file mode 100644 index 0000000..ba24a40 --- /dev/null +++ b/scripts/splat.gd @@ -0,0 +1,11 @@ +extends Sprite2D + +@export var lifetime: float = 120 + +func _ready() -> void: + rotation_degrees = randf_range(0, 360) + +func _process(delta: float) -> void: + lifetime -= delta + if lifetime <= 0: + queue_free() diff --git a/scripts/splat.gd.uid b/scripts/splat.gd.uid new file mode 100644 index 0000000..c20455a --- /dev/null +++ b/scripts/splat.gd.uid @@ -0,0 +1 @@ +uid://3ush0k3p0d8i diff --git a/scripts/storage.gd b/scripts/storage.gd new file mode 100644 index 0000000..6d61279 --- /dev/null +++ b/scripts/storage.gd @@ -0,0 +1,16 @@ +extends Machine + +func _ready() -> void: + super() + +func _process(delta: float) -> void: + if stored_items.is_empty(): + return + var item: Item = stored_items.pick_random() + if item == null: + return + if !can_send_item(item): + return + var item_node: ItemNode = unstore_item(item) + if item_node != null: + send_item(item_node) diff --git a/scripts/storage.gd.uid b/scripts/storage.gd.uid new file mode 100644 index 0000000..a34c596 --- /dev/null +++ b/scripts/storage.gd.uid @@ -0,0 +1 @@ +uid://b1g3m8gfjrkef diff --git a/scripts/watchtower.gd b/scripts/watchtower.gd new file mode 100644 index 0000000..2c389c3 --- /dev/null +++ b/scripts/watchtower.gd @@ -0,0 +1,9 @@ +extends Building + +func place() -> void: + super() + $DetectionArea.active_state = DetectionArea.ActiveState.PREVIEW + +func build() -> void: + super() + $DetectionArea.active_state = DetectionArea.ActiveState.ACTIVE diff --git a/scripts/watchtower.gd.uid b/scripts/watchtower.gd.uid new file mode 100644 index 0000000..41239e7 --- /dev/null +++ b/scripts/watchtower.gd.uid @@ -0,0 +1 @@ +uid://ck2p0rdh6q5vw