diff --git a/README.md b/README.md index 7702e58..f908e59 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Boden/Wetter-Stimmung — siehe Commit 84bc081 und `svmap_io.gd`.)* Spätere Werkzeuge melden sich mit `snapshot(keys)` vor und `commit(desc, before, after)` nach der Änderung an — Terrain-Strokes und Spawn-Zonen landen damit automatisch in derselben History. -- **Objekt-Platzierung mit Ghost-Preview (`src/editor/interaction.gd`):** +- **Objekt-Platzierung mit Ghost-Preview (`core/editor/interaction.gd`):** Bibliothek links (deutsche Namen + Poly-Zahl), Klick startet den Platzier-Modus — eine transparente Vorschau schwebt am Cursor auf dem Boden (Höhe kommt aus dem Terrain), Klick setzt, ESC bricht ab (Rechte @@ -94,7 +94,7 @@ synchron ziehen (IDs sind der Vertrag, Entscheidung 20). Auf dem Terrain-Werkzeug (t_9aba04f1) aufgebaut, nach dem Chef-Grundsatz: -- **Bibliothek-Browser mit Gruppen (`src/editor/library_browser.gd`):** +- **Bibliothek-Browser mit Gruppen (`core/editor/library_browser.gd`):** *(Stand 25.10.2026, Military-Pack-Umstellung)* Die Bibliothek ist das komplette Military-Desert-Pack (418 Modelle + 5 Kombis = 423 Objekte aus `library/objects.json`), sortiert in 19 deutsche Kategorien aus dem @@ -106,7 +106,7 @@ Auf dem Terrain-Werkzeug (t_9aba04f1) aufgebaut, nach dem Chef-Grundsatz: (Panzer mit Turm und Kanone, Hummer mit Rädern, Hubschrauber mit Rotoren); die Einzelteile stehen zusätzlich unter „Fahrzeugteile“. Unbekannte Kategorien (z. B. spätere Bauteil-Module) bekommen automatisch eine eigene - Gruppe. Jeder Button zeigt ein 128-px-Thumbnail (`library/thumbs/*.png` — + Gruppe. Jeder Button zeigt ein 128-px-Thumbnail (`core/thumbs/*.png` — erzeugt von `tools/sync_objects.sh`/`tools/gen_thumbs.gd` und committed; fehlt ein PNG, fällt der Button aufs Text-Layout zurück). Deutsche Namen kommen aus `name_de` im Manifest (ohne UI → headless testbar). Kollision: @@ -138,7 +138,7 @@ Export-Workflow. Auf der Objekt-Bibliothek (t_3a998ae4) aufgebaut, nach dem Chef-Grundsatz: -- **Spawn-Zonen malen (`src/editor/spawn_tool.gd`):** Werkzeug +- **Spawn-Zonen malen (`core/editor/spawn_tool.gd`):** Werkzeug „🚩 Spawn-Zonen malen“ — Team Blau 🔵 / Team Rot 🔴 (TDM-Konvention: IDs A…/B…, mapformat § spawn_zones), Klick setzt eine farbige flache Kreis-Zone auf dem Terrain (Vorschau-Kreis folgt der Maus), Radius @@ -238,7 +238,7 @@ Undo für alles): Mehrfachauswahl + Gruppieren + Gruppen-Verschieben, auf dem UX-Fundament (t_40d855d0) aufgebaut, nach dem Chef-Grundsatz: -- **Mehrfachauswahl (`src/editor/interaction.gd`):** Umschalt+Klick fügt +- **Mehrfachauswahl (`core/editor/interaction.gd`):** Umschalt+Klick fügt ein Objekt hinzu/entfernt es, Rahmen-Aufziehen (Rubberband) über leeren Boden wählt ALLE Objekte im Rahmen (Umschalt + Rahmen = zusätzliche zur Auswahl). Loser Klick auf leere Fläche hebt die Auswahl auf. ALLE @@ -287,7 +287,7 @@ auch ungespeicherte! — sofort als Spiel in einem EIGENEN Fenster. Der Editor bleibt offen. Im Spiel: WASD laufen, Maus umsehen, Shift sprinten, Leertaste springen, ESC beendet das Test-Fenster sauber (kein Prozess-Kill nötig). -- **Temp-Export (`src/editor/test_run.gd`):** Die Map wird nach +- **Temp-Export (`core/editor/test_run.gd`):** Die Map wird nach `user://testrun/.svmap` exportiert (deterministischer Name aus dem Map-Namen, erneuter Testlauf überschreibt) — über dieselbe `SvmapIO.save_to_file`-Validierung wie das echte Speichern. Ist die Map @@ -317,7 +317,7 @@ Tastenkürzel-Karte 1 von 3 (Sly-Freigabe 16.10., finale Belegung). Shortcut-Karten — Karten 2/3 ergänzen dort. - **Konventionen (alle Karten):** Tastaturcode-basiert — InputMap-Actions mit - PHYSISCHEN `KEY_*`-Konstanten (`src/editor/shortcut_keys.gd`, registriert in + PHYSISCHEN `KEY_*`-Konstanten (`core/editor/shortcut_keys.gd`, registriert in `main._ready`, idempotent). Physische Codes = deutsche (QWERTZ) und Windows-Layouts identisch, keine OS-Hardcodes. Jede Objekt-Operation = EIN ActionHistory-Eintrag (Ausnahme: reine Kamera-Aktionen). @@ -327,7 +327,7 @@ Shortcut-Karten — Karten 2/3 ergänzen dort. Orbit bleibt Default — beim Flug-Exit werden Ziel/Winkel/Abstand aus Flugposition/Blickrichtung zurückgerechnet (kein Kamera-Sprung, getestet). Mathe pur in - `src/editor/fly_math.gd`, Kamera dünn (`src/viewport/orbit_camera.gd`). + `core/editor/fly_math.gd`, Kamera dünn (`core/viewport/orbit_camera.gd`). Konflikt-Auflösung: RMB hat ABSOLUTEN Vorrang für den Flug — in JEDEM Werkzeugzustand (Terrain, Bauen, Spawn, Platzieren; Karte t_2470de89, kein `rmb_filter` mehr), Mausrad im Flug gehört dem Tempo (interaction @@ -337,7 +337,7 @@ Shortcut-Karten — Karten 2/3 ergänzen dort. Flug dreht sich nur die Blickrichtung. - **Esc** = Prioritätskette Werkzeug verlassen → Ghost-Preview abbrechen → Auswahl aufheben, als pure, headless-getestete Funktion - (`src/editor/shortcut_policy.gd`). + (`core/editor/shortcut_policy.gd`). - **Entf (DELETE)** = Auswahl SOFORT löschen ohne Rückfrage (Sly-Yolo) — wirkt auf Szene-Auswahl UND Objektbaum-Markierung (Baum und Szene sind synchron), Strg+Z deckt es ab. War schon mehrfach-fähig, jetzt diff --git a/README_INSTALL.md b/README_INSTALL.md index bc449e6..155c9ef 100644 --- a/README_INSTALL.md +++ b/README_INSTALL.md @@ -80,6 +80,6 @@ Roh-Modelle und Texturen weiterzugeben. Das heißt konkret: --- *Technischer Hintergrund: die Modelle werden zur Laufzeit per GLTFDocument -aus dem `models/`-Ordner geladen (siehe `src/viewport/glb_mesh_store.gd`, +aus dem `models/`-Ordner geladen (siehe `core/viewport/glb_mesh_store.gd`, Quellen-Reihenfolge: Einstellungen → Nachbar-Ordner `../scopedvr-client` → `models/`). Erster Treffer gewinnt.* diff --git a/addons/modular_builder/modular_builder_editor_ui.gd b/addons/modular_builder/modular_builder_editor_ui.gd index aba23a2..8fa4fdb 100644 --- a/addons/modular_builder/modular_builder_editor_ui.gd +++ b/addons/modular_builder/modular_builder_editor_ui.gd @@ -2,7 +2,7 @@ extends EditorPlugin const PIECE_SCRIPT = preload("res://addons/modular_builder/modular_piece.gd") -const DETAIL_SCRIPT = preload("res://addons/modular_builder/modular_building_detail.gd") +const DETAIL_SCRIPT = preload("res://core/vendor/modular_builder/modular_building_detail.gd") const MESH_BAKER = preload("res://addons/modular_builder/modular_mesh_baker.gd") const TOOL_NONE := "" const TOOL_FOUNDATION := "foundation" diff --git a/addons/modular_builder/modular_building_detail.gd b/addons/modular_builder/modular_building_detail.gd deleted file mode 100644 index afe295d..0000000 --- a/addons/modular_builder/modular_building_detail.gd +++ /dev/null @@ -1,284 +0,0 @@ -@tool -class_name ModularBuilderDetail -extends Node3D - -enum DetailType { WINDOW, DOOR, HATCH, PILLAR, FENCE, PARAPET } -enum DetailMode { OPENING, SEPARATE_OBJECT } -enum WindowStyle { SINGLE_PANE, CROSS_PANE } -enum DoorStyle { FLAT, PANELED } - -@export var detail_type: DetailType = DetailType.WINDOW: - set(value): - detail_type = value - notify_property_list_changed() - _rebuild() -@export var detail_mode: DetailMode = DetailMode.OPENING: - set(value): - detail_mode = value - notify_property_list_changed() - _rebuild() -@export var center_align: bool = false: - set(value): - center_align = value - _apply_pillar_alignment() - notify_property_list_changed() -@export_storage var pillar_direction: Vector3 = Vector3.UP -@export_storage var pillar_alignment_basis: Basis = Basis.IDENTITY -@export var window_style: WindowStyle = WindowStyle.SINGLE_PANE: - set(value): - window_style = value - _rebuild() -@export var door_style: DoorStyle = DoorStyle.FLAT: - set(value): - door_style = value - _rebuild() -@export_range(0.01, 5.0, 0.001, "suffix:m") var width: float = 1.0: - set(value): - width = value - _rebuild() -@export_range(0.2, 5.0, 0.001, "suffix:m") var height: float = 1.0: - set(value): - height = value - _rebuild() -@export_range(0.02, 0.5, 0.001, "suffix:m") var frame_depth: float = 0.08: - set(value): - frame_depth = value - _rebuild() -@export_range(0.1, 8.0, 0.001, "suffix:m") var fence_height: float = 0.7: - set(value): - fence_height = value - _rebuild() -@export_range(0, 100, 1, "suffix: posts") var fence_divisions: int = 1: - set(value): - fence_divisions = value - _rebuild() -@export_storage var path_points: PackedVector3Array = PackedVector3Array() -@export_range(0.01, 0.5, 0.001, "suffix:m") var frame_width: float = 0.08: - set(value): - frame_width = value - _rebuild() -@export var follow_host_thickness: bool = true: - set(value): - follow_host_thickness = value - _rebuild() -@export var surface_material: Material: - set(value): - surface_material = value - _rebuild() -@export var frame_material: Material: - set(value): - frame_material = value - _rebuild() -@export var panel_material: Material: - set(value): - panel_material = value - _rebuild() - -func _validate_property(property: Dictionary) -> void: - var separate_object := detail_mode == DetailMode.SEPARATE_OBJECT - var is_window := detail_type == DetailType.WINDOW - var is_door := detail_type == DetailType.DOOR - var has_frame_and_panel := separate_object and detail_type != DetailType.PILLAR and detail_type != DetailType.FENCE and detail_type != DetailType.PARAPET - var show_property := true - match StringName(property.name): - &"detail_mode": - show_property = detail_type != DetailType.PILLAR and detail_type != DetailType.FENCE and detail_type != DetailType.PARAPET - &"center_align": - show_property = detail_type == DetailType.PILLAR - &"fence_height", &"fence_divisions": - show_property = detail_type == DetailType.FENCE or detail_type == DetailType.PARAPET - &"path_points": - show_property = false - &"width": - show_property = detail_type != DetailType.FENCE and detail_type != DetailType.PARAPET - if detail_type == DetailType.PILLAR: - property.hint = PROPERTY_HINT_RANGE - property.hint_string = "0.01,5.0,0.001,suffix:m" - &"height": - show_property = detail_type != DetailType.FENCE and detail_type != DetailType.PARAPET - &"window_style": - show_property = is_window and separate_object - &"door_style": - show_property = is_door and separate_object - &"frame_width", &"frame_material", &"panel_material": - show_property = has_frame_and_panel - &"follow_host_thickness": - show_property = has_frame_and_panel - &"frame_depth": - show_property = has_frame_and_panel and not follow_host_thickness - &"surface_material": - show_property = separate_object - if not show_property: - property.usage = PROPERTY_USAGE_NO_EDITOR - -func _ready() -> void: - set_notify_transform(true) - _rebuild() - -func _notification(what: int) -> void: - if what == NOTIFICATION_TRANSFORM_CHANGED and is_inside_tree(): - var host := get_parent() - if host != null and host.has_method("_rebuild"): - host.call("_rebuild") - -func _on_host_thickness_changed() -> void: - _rebuild(false) - -func _apply_pillar_alignment() -> void: - if detail_type != DetailType.PILLAR: - return - var direction := pillar_direction.normalized() - if direction.is_zero_approx(): - direction = Vector3.UP - if center_align: - var object_axes := pillar_alignment_basis.orthonormalized() - var best_axis := direction - var best_dot := -1.0 - for axis in [object_axes.x, object_axes.y, object_axes.z]: - var normalized_axis: Vector3 = axis.normalized() - var alignment := absf(direction.dot(normalized_axis)) - if alignment > best_dot: - best_dot = alignment - best_axis = normalized_axis if direction.dot(normalized_axis) >= 0.0 else -normalized_axis - direction = best_axis - var reference_axis := Vector3.FORWARD if absf(direction.dot(Vector3.UP)) > 0.99 else Vector3.UP - var x_axis := reference_axis.cross(direction).normalized() - var z_axis := x_axis.cross(direction).normalized() - transform.basis = Basis(x_axis, direction, z_axis).orthonormalized() - if center_align and pillar_direction.length() > 0.0: - height = pillar_direction.length() - -func _rebuild(notify_host: bool = true) -> void: - if not is_inside_tree(): - return - for child in get_children(): - if child.name == "DetailGeometry": - remove_child(child) - child.queue_free() - var host := get_parent() - if notify_host and host != null and host.has_method("_rebuild"): - host.call("_rebuild") - if detail_mode == DetailMode.OPENING and detail_type != DetailType.FENCE and detail_type != DetailType.PARAPET: - return - var holder := Node3D.new() - holder.name = "DetailGeometry" - add_child(holder) - var scene_root: Node = null - if Engine.is_editor_hint() and not has_meta("modular_builder_preview"): - scene_root = get_tree().edited_scene_root - if scene_root: - holder.owner = scene_root - var effective_depth := _effective_frame_depth() - var frame := minf(maxf(frame_width, 0.01), minf(width, height) * 0.45) - if detail_type == DetailType.FENCE or detail_type == DetailType.PARAPET: - _build_fence_geometry(holder) - return - if detail_type == DetailType.PILLAR: - _add_box(holder, "PillarBody", Vector3(width, height, width), Vector3.ZERO, surface_material) - return - if detail_type == DetailType.HATCH: - _add_box(holder, "LeftFrame", Vector3(frame, effective_depth, height), Vector3(-width * 0.5 + frame * 0.5, 0.0, 0.0), _frame_material()) - _add_box(holder, "RightFrame", Vector3(frame, effective_depth, height), Vector3(width * 0.5 - frame * 0.5, 0.0, 0.0), _frame_material()) - _add_box(holder, "NearFrame", Vector3(width, effective_depth, frame), Vector3(0.0, 0.0, -height * 0.5 + frame * 0.5), _frame_material()) - _add_box(holder, "FarFrame", Vector3(width, effective_depth, frame), Vector3(0.0, 0.0, height * 0.5 - frame * 0.5), _frame_material()) - _add_box(holder, "HatchPanel", Vector3(width - frame * 2.0, effective_depth * 0.35, height - frame * 2.0), Vector3(0.0, effective_depth * 0.4, 0.0), _panel_material()) - return - _add_box(holder, "LeftFrame", Vector3(frame, height, effective_depth), Vector3(-width * 0.5 + frame * 0.5, 0.0, 0.0), _frame_material()) - _add_box(holder, "RightFrame", Vector3(frame, height, effective_depth), Vector3(width * 0.5 - frame * 0.5, 0.0, 0.0), _frame_material()) - _add_box(holder, "TopFrame", Vector3(width, frame, effective_depth), Vector3(0.0, height * 0.5 - frame * 0.5, 0.0), _frame_material()) - if detail_type != DetailType.DOOR: - _add_box(holder, "BottomFrame", Vector3(width, frame, effective_depth), Vector3(0.0, -height * 0.5 + frame * 0.5, 0.0), _frame_material()) - if detail_type == DetailType.WINDOW: - _add_box(holder, "WindowPanel", Vector3(maxf(width - frame * 2.0, 0.001), maxf(height - frame * 2.0, 0.001), effective_depth * 0.35), Vector3.ZERO, _panel_material()) - if window_style == WindowStyle.CROSS_PANE: - _add_box(holder, "VerticalMullion", Vector3(frame * 0.55, height - frame * 2.0, effective_depth * 0.4), Vector3.ZERO, _frame_material()) - _add_box(holder, "HorizontalMullion", Vector3(width - frame * 2.0, frame * 0.55, effective_depth * 0.4), Vector3.ZERO, _frame_material()) - elif detail_type == DetailType.DOOR: - _add_box(holder, "DoorPanel", Vector3(width - frame * 2.0, height - frame, effective_depth * 0.45), Vector3(0.0, -frame * 0.5, 0.0), _panel_material()) - if door_style == DoorStyle.PANELED: - var inset_depth := maxf(effective_depth * 0.04, 0.005) - var panel_width := (width - frame * 2.0) * 0.82 - var panel_height := maxf((height - frame) * 0.28, 0.05) - for panel_index in range(2): - var panel_y := -frame * 0.5 + (panel_index - 0.5) * (panel_height + frame * 0.25) - _add_box(holder, "DoorInset_%d" % panel_index, Vector3(panel_width, panel_height, inset_depth), Vector3(0.0, panel_y, effective_depth * 0.24), _frame_material()) - -func _effective_frame_depth() -> float: - if follow_host_thickness: - var host := get_parent() - if host != null: - var host_thickness = host.get("thickness") - if host_thickness is float or host_thickness is int: - var depth := float(host_thickness) - if detail_type == DetailType.WINDOW or detail_type == DetailType.DOOR: - depth *= 1.25 - return maxf(depth, 0.02) - return frame_depth - -func _build_fence_geometry(holder: Node3D) -> void: - if path_points.size() < 2 or fence_height <= 0.0: - return - var start := path_points[0] - var finish := path_points[1] - var path := finish - start - var path_length := path.length() - if path_length < 0.05: - return - var path_axis := path / path_length - var up_axis := Vector3.UP - path_axis * path_axis.dot(Vector3.UP) - if up_axis.length_squared() < 0.001: - up_axis = Vector3.FORWARD - path_axis * path_axis.dot(Vector3.FORWARD) - up_axis = up_axis.normalized() - var side_axis := path_axis.cross(up_axis).normalized() - var post_width := 0.16 if detail_type == DetailType.PARAPET else 0.08 - var post_count := fence_divisions + 2 - var posts: Array[Vector3] = [] - for i in range(post_count): - var base := start.lerp(finish, float(i) / float(post_count - 1)) - posts.append(base) - _add_oriented_box(holder, "Post_%d" % i, base + up_axis * fence_height * 0.5, path_axis, up_axis, side_axis, Vector3(post_width, fence_height, post_width)) - for i in range(posts.size() - 1): - var a := posts[i] - var b := posts[i + 1] - var segment := b - a - var segment_length := segment.length() - if detail_type == DetailType.PARAPET: - _add_oriented_box(holder, "Rail_%d" % i, (a + b) * 0.5 + up_axis * fence_height * 0.78, segment.normalized(), up_axis, side_axis, Vector3(segment_length, post_width * 0.8, post_width * 0.8)) - else: - for height_ratio in [0.28, 0.78]: - _add_oriented_box(holder, "Rail_%d_%d" % [i, int(height_ratio * 100.0)], (a + b) * 0.5 + up_axis * fence_height * height_ratio, segment.normalized(), up_axis, side_axis, Vector3(segment_length, post_width, post_width)) - -func _add_oriented_box(holder: Node3D, node_name: String, center: Vector3, axis_x: Vector3, axis_y: Vector3, axis_z: Vector3, dimensions: Vector3) -> void: - var mesh_instance := MeshInstance3D.new() - mesh_instance.name = node_name - var box := BoxMesh.new() - box.size = dimensions - mesh_instance.mesh = box - var basis := Basis(axis_x.normalized(), axis_y.normalized(), axis_z.normalized()).orthonormalized() - mesh_instance.transform = Transform3D(basis, center) - mesh_instance.material_override = surface_material - holder.add_child(mesh_instance) - if Engine.is_editor_hint() and not has_meta("modular_builder_preview"): - var scene_root := get_tree().edited_scene_root - if scene_root: - mesh_instance.owner = scene_root - -func _frame_material() -> Material: - return frame_material if frame_material != null else surface_material - -func _panel_material() -> Material: - return panel_material if panel_material != null else surface_material - -func _add_box(holder: Node3D, node_name: String, box_size: Vector3, box_position: Vector3, material: Material = null) -> void: - var mesh_instance := MeshInstance3D.new() - mesh_instance.name = node_name - var box := BoxMesh.new() - box.size = box_size - mesh_instance.mesh = box - mesh_instance.position = box_position - mesh_instance.material_override = material if material != null else surface_material - holder.add_child(mesh_instance) - if Engine.is_editor_hint() and not has_meta("modular_builder_preview"): - var scene_root := get_tree().edited_scene_root - if scene_root: - mesh_instance.owner = scene_root diff --git a/addons/modular_builder/modular_building_detail.gd.uid b/addons/modular_builder/modular_building_detail.gd.uid deleted file mode 100644 index 5611ebc..0000000 --- a/addons/modular_builder/modular_building_detail.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dsttda167kuhi diff --git a/addons/modular_builder/modular_piece.gd b/addons/modular_builder/modular_piece.gd index 9f29f34..f74043e 100644 --- a/addons/modular_builder/modular_piece.gd +++ b/addons/modular_builder/modular_piece.gd @@ -1,6 +1,6 @@ @tool class_name ModularBuilderPiece -extends "res://addons/modular_builder/modular_piece_geometry.gd" +extends "res://core/vendor/modular_builder/modular_piece_geometry.gd" func _ready() -> void: _rebuild() diff --git a/addons/modular_builder/modular_piece_geometry.gd b/addons/modular_builder/modular_piece_geometry.gd deleted file mode 100644 index 1c0950d..0000000 --- a/addons/modular_builder/modular_piece_geometry.gd +++ /dev/null @@ -1,748 +0,0 @@ -@tool -class_name ModularBuilderPieceGeometry -extends Node3D - -const DETAIL_SCRIPT_PATH := "res://addons/modular_builder/modular_building_detail.gd" -const DETAIL_TYPE_HATCH := 2 -const DETAIL_TYPE_PILLAR := 3 - -enum PieceType { FOUNDATION_SQUARE, FOUNDATION_TRIANGLE, FLOOR, WALL, BUILDING, GABLE_WALL, ROOF_GABLE, ROOF_SHED, GABLE_WALL_RIGHT, ROOF_PYRAMID, STAIRS, FENCE } - -@export var piece_type: PieceType = PieceType.FOUNDATION_SQUARE: - set(value): - piece_type = value - notify_property_list_changed() - _rebuild() -@export_range(0.5, 8.0, 0.001, "suffix:m") var unit_size: float = 2.0: - set(value): - unit_size = value - _rebuild() -@export_range(0.01, 1.0, 0.001, "suffix:m") var thickness: float = 0.2: - set(value): - thickness = value - _rebuild() - for child in get_children(): - if child.has_method("_on_host_thickness_changed"): - child.call("_on_host_thickness_changed") -@export_range(0.1, 8.0, 0.001, "suffix:m") var rise: float = 1.0: - set(value): - rise = value - _rebuild() -@export_range(0.01, 32.0, 0.001, "suffix:m") var roof_width: float = 2.0: - set(value): - roof_width = value - _rebuild() -@export_range(1, 100, 1, "suffix: steps") var stair_count: int = 10: - set(value): - stair_count = value - _rebuild() -@export_range(0.01, 8.0, 0.001, "suffix:m") var stair_width: float = 1.0: - set(value): - stair_width = value - _rebuild() -@export_range(0, 100, 1, "suffix: posts") var fence_divisions: int = 1: - set(value): - fence_divisions = value - _rebuild() -@export_range(0.1, 8.0, 0.001, "suffix:m") var fence_height: float = 1.0: - set(value): - fence_height = value - _rebuild() -@export var symmetric_dimensions: bool = true: - set(value): - if symmetric_dimensions == value: - return - if not value: - _capture_mesh_dimensions() - symmetric_dimensions = value - notify_property_list_changed() - if value: - scale = Vector3.ONE - else: - _apply_dimension_scale() -@export_range(0.01, 100.0, 0.001, "suffix:m") var dimension_width: float = 2.0: - set(value): - dimension_width = value - _apply_dimension_scale() -@export_range(0.01, 100.0, 0.001, "suffix:m") var dimension_height: float = 2.0: - set(value): - dimension_height = value - _apply_dimension_scale() -@export_range(0.01, 100.0, 0.001, "suffix:m") var dimension_depth: float = 2.0: - set(value): - dimension_depth = value - _apply_dimension_scale() -@export_storage var _dimension_reference: Vector3 = Vector3.ZERO -@export var center_align: bool = false: - set(value): - center_align = value - _rebuild() -@export var surface_material: Material: - set(value): - surface_material = value - _rebuild() -@export var custom_points: PackedVector3Array = PackedVector3Array(): - set(value): - custom_points = value - _rebuild() -@export var centered_origin: bool = false: - set(value): - centered_origin = value - _rebuild() - -func _rebuild() -> void: - pass - -func _capture_mesh_dimensions() -> void: - var geometry := get_node_or_null("Geometry") as MeshInstance3D - if geometry == null or geometry.mesh == null: - return - var dimensions := geometry.mesh.get_aabb().size - if dimensions.x > 0.001: - dimension_width = dimensions.x - if dimensions.y > 0.001: - dimension_height = dimensions.y - if dimensions.z > 0.001: - dimension_depth = dimensions.z - _dimension_reference = dimensions - -func _apply_dimension_scale() -> void: - if symmetric_dimensions or _dimension_reference.x <= 0.001 or _dimension_reference.y <= 0.001 or _dimension_reference.z <= 0.001: - return - var target := Vector3(dimension_width, dimension_height, dimension_depth) - if piece_type == PieceType.FOUNDATION_SQUARE or piece_type == PieceType.FOUNDATION_TRIANGLE or piece_type == PieceType.FLOOR: - target.y = _dimension_reference.y - if piece_type == PieceType.WALL: - target.z = _dimension_reference.z - scale = Vector3(target.x / _dimension_reference.x, target.y / _dimension_reference.y, target.z / _dimension_reference.z) - -func _make_mesh() -> ArrayMesh: - if piece_type == PieceType.GABLE_WALL and custom_points.size() >= 2: - return _make_gable_wall_mesh() - if piece_type == PieceType.GABLE_WALL_RIGHT and custom_points.size() >= 2: - return _make_right_gable_wall_mesh() - if (piece_type == PieceType.ROOF_GABLE or piece_type == PieceType.ROOF_SHED or piece_type == PieceType.ROOF_PYRAMID) and custom_points.size() >= 2: - return _make_roof_mesh() - if piece_type == PieceType.STAIRS and custom_points.size() >= 2: - return _make_stair_mesh() - if piece_type == PieceType.FENCE and custom_points.size() >= 2: - return _make_fence_mesh() - if custom_points.size() >= 2 and piece_type == PieceType.WALL: - return _make_custom_wall_mesh() - if custom_points.size() >= 3 and piece_type == PieceType.FLOOR: - return _make_custom_floor_mesh() - if custom_points.size() >= 3 and (piece_type == PieceType.FOUNDATION_SQUARE or piece_type == PieceType.FOUNDATION_TRIANGLE): - return _make_custom_foundation_mesh() - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var s := unit_size - var polygon: Array[Vector2] - match piece_type: - PieceType.FOUNDATION_TRIANGLE: - polygon = [Vector2(-s * 0.5, -s * 0.5), Vector2(s * 0.5, -s * 0.5), Vector2(-s * 0.5, s * 0.5)] - _: - polygon = [Vector2(-s * 0.5, -s * 0.5), Vector2(s * 0.5, -s * 0.5), Vector2(s * 0.5, s * 0.5), Vector2(-s * 0.5, s * 0.5)] - var y0 := -thickness * 0.5 if centered_origin else 0.0 - var y1 := thickness * 0.5 if centered_origin else thickness - if piece_type == PieceType.WALL: - polygon = [Vector2(-s * 0.5, -thickness * 0.5), Vector2(s * 0.5, -thickness * 0.5), Vector2(s * 0.5, thickness * 0.5), Vector2(-s * 0.5, thickness * 0.5)] - y0 = -s * 0.5 if centered_origin else 0.0 - y1 = s * 0.5 if centered_origin else s - if piece_type == PieceType.FOUNDATION_SQUARE or piece_type == PieceType.FOUNDATION_TRIANGLE: - var hatch_mesh := _make_hatch_surface_mesh(polygon, y1, y0) - if hatch_mesh != null: - return hatch_mesh - for i in range(1, polygon.size() - 1): - _add_tri(vertices, normals, Vector3(polygon[0].x, y1, polygon[0].y), Vector3(polygon[i + 1].x, y1, polygon[i + 1].y), Vector3(polygon[i].x, y1, polygon[i].y)) - _add_tri(vertices, normals, Vector3(polygon[0].x, y0, polygon[0].y), Vector3(polygon[i].x, y0, polygon[i].y), Vector3(polygon[i + 1].x, y0, polygon[i + 1].y)) - for i in range(polygon.size()): - var j := (i + 1) % polygon.size() - var a := polygon[i] - var b := polygon[j] - _add_tri(vertices, normals, Vector3(a.x, y0, a.y), Vector3(b.x, y0, b.y), Vector3(b.x, y1, b.y)) - _add_tri(vertices, normals, Vector3(a.x, y0, a.y), Vector3(b.x, y1, b.y), Vector3(a.x, y1, a.y)) - var arrays: Array = [] - arrays.resize(Mesh.ARRAY_MAX) - arrays[Mesh.ARRAY_VERTEX] = vertices - arrays[Mesh.ARRAY_NORMAL] = normals - var result := ArrayMesh.new() - result.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) - return result - -func _make_gable_wall_mesh() -> ArrayMesh: - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var base_points := _get_centered_gable_base() if center_align else PackedVector3Array([custom_points[0], custom_points[1]]) - var a: Vector3 = base_points[0] - var b: Vector3 = base_points[1] - var direction := (b - a).normalized() - var side := Vector3(-direction.z, 0.0, direction.x).normalized() * thickness * 0.5 - var peak := (a + b) * 0.5 + Vector3.UP * rise - var front_a := a + side - var front_b := b + side - var front_peak := peak + side - var back_a := a - side - var back_b := b - side - var back_peak := peak - side - _add_tri(vertices, normals, front_a, front_b, front_peak) - _add_tri(vertices, normals, back_b, back_a, back_peak) - _add_quad(vertices, normals, front_a, back_a, back_b, front_b) - _add_quad(vertices, normals, front_b, back_b, back_peak, front_peak) - _add_quad(vertices, normals, front_peak, back_peak, back_a, front_a) - return _array_mesh(vertices, normals) - -func _make_right_gable_wall_mesh() -> ArrayMesh: - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var base_points := _get_centered_gable_base() if center_align else PackedVector3Array([custom_points[0], custom_points[1]]) - var a: Vector3 = base_points[0] - var b: Vector3 = base_points[1] - var direction := (b - a).normalized() - var side := Vector3(-direction.z, 0.0, direction.x).normalized() * thickness * 0.5 - var peak := b + Vector3.UP * rise - var front_a := a + side - var front_b := b + side - var front_peak := peak + side - var back_a := a - side - var back_b := b - side - var back_peak := peak - side - _add_tri(vertices, normals, front_a, front_b, front_peak) - _add_tri(vertices, normals, back_peak, back_b, back_a) - _add_quad(vertices, normals, front_a, back_a, back_b, front_b) - _add_quad(vertices, normals, front_b, back_b, back_peak, front_peak) - _add_quad(vertices, normals, front_peak, back_peak, back_a, front_a) - return _array_mesh(vertices, normals) - -func _make_roof_mesh() -> ArrayMesh: - if piece_type == PieceType.ROOF_SHED and custom_points.size() == 2: - return _make_shed_roof_mesh() - if custom_points.size() >= 4: - return _make_oriented_roof_mesh() - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var first: Vector3 = custom_points[0] - var second: Vector3 = custom_points[1] - var min_x := minf(first.x, second.x) - var max_x := maxf(first.x, second.x) - var min_z := minf(first.z, second.z) - var max_z := maxf(first.z, second.z) - var span_x := max_x - min_x - var span_z := max_z - min_z - if span_x < 0.02 or span_z < 0.02: - return _array_mesh(vertices, normals) - var panels: Array = [] - if piece_type == PieceType.ROOF_GABLE: - if span_x <= span_z: - var ridge_x := (min_x + max_x) * 0.5 - panels.append([Vector3(min_x, 0.0, min_z), Vector3(min_x, 0.0, max_z), Vector3(ridge_x, rise, max_z), Vector3(ridge_x, rise, min_z)]) - panels.append([Vector3(ridge_x, rise, min_z), Vector3(ridge_x, rise, max_z), Vector3(max_x, 0.0, max_z), Vector3(max_x, 0.0, min_z)]) - else: - var ridge_z := (min_z + max_z) * 0.5 - panels.append([Vector3(min_x, 0.0, min_z), Vector3(max_x, 0.0, min_z), Vector3(max_x, rise, ridge_z), Vector3(min_x, rise, ridge_z)]) - panels.append([Vector3(min_x, rise, ridge_z), Vector3(max_x, rise, ridge_z), Vector3(max_x, 0.0, max_z), Vector3(min_x, 0.0, max_z)]) - else: - if span_x <= span_z: - var low_x := first.x - var high_x := second.x - panels.append([Vector3(low_x, 0.0, min_z), Vector3(low_x, 0.0, max_z), Vector3(high_x, rise, max_z), Vector3(high_x, rise, min_z)]) - else: - var low_z := first.z - var high_z := second.z - panels.append([Vector3(min_x, 0.0, low_z), Vector3(max_x, 0.0, low_z), Vector3(max_x, rise, high_z), Vector3(min_x, rise, high_z)]) - for panel in panels: - _append_solid_panel(vertices, normals, panel) - return _array_mesh(vertices, normals) - -func _make_shed_roof_mesh() -> ArrayMesh: - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var low: Vector3 = custom_points[0] - var high: Vector3 = custom_points[1] - var slope := high - low - var horizontal := Vector3(slope.x, 0.0, slope.z) - if horizontal.length_squared() < 0.0001 or roof_width <= 0.0: - return _array_mesh(vertices, normals) - var across := Vector3(horizontal.z, 0.0, -horizontal.x).normalized() * roof_width * 0.5 - var panel := [low - across, low + across, high + across, high - across] - _append_solid_panel(vertices, normals, panel) - return _array_mesh(vertices, normals) - -func _make_oriented_roof_mesh() -> ArrayMesh: - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var p0: Vector3 = custom_points[0] - var p1: Vector3 = custom_points[1] - var p2: Vector3 = custom_points[2] - var p3: Vector3 = custom_points[3] - var edge_01 := Vector2(p1.x - p0.x, p1.z - p0.z).length() - var edge_12 := Vector2(p2.x - p1.x, p2.z - p1.z).length() - var panels: Array = [] - if piece_type == PieceType.ROOF_GABLE: - if edge_01 <= edge_12: - var ridge_01 := (p0 + p1) * 0.5 + Vector3.UP * rise - var ridge_23 := (p2 + p3) * 0.5 + Vector3.UP * rise - panels.append([p0, p3, ridge_23, ridge_01]) - panels.append([ridge_01, ridge_23, p2, p1]) - else: - var ridge_12 := (p1 + p2) * 0.5 + Vector3.UP * rise - var ridge_30 := (p3 + p0) * 0.5 + Vector3.UP * rise - panels.append([p0, p1, ridge_12, ridge_30]) - panels.append([ridge_30, ridge_12, p2, p3]) - elif piece_type == PieceType.ROOF_PYRAMID: - var peak := (p0 + p1 + p2 + p3) * 0.25 + Vector3.UP * rise - panels.append([p0, p1, peak]) - panels.append([p1, p2, peak]) - panels.append([p2, p3, peak]) - panels.append([p3, p0, peak]) - else: - # The four points define the low and high edges. Keep their centers - # fixed when adjusting both edge widths in the Inspector. - var base_width := Vector2(p1.x - p0.x, p1.z - p0.z).length() - if base_width > 0.001 and roof_width > 0.0: - var direction := Vector3(p1.x - p0.x, 0.0, p1.z - p0.z).normalized() - var low_center := (p0 + p1) * 0.5 - var high_center := (p2 + p3) * 0.5 - var half_width := roof_width * 0.5 - panels.append([ - low_center - direction * half_width, - low_center + direction * half_width, - high_center + direction * half_width, - high_center - direction * half_width, - ]) - else: - panels.append([p0, p1, p2, p3]) - for panel in panels: - _append_solid_panel(vertices, normals, panel) - return _array_mesh(vertices, normals) - -func _make_stair_mesh() -> ArrayMesh: - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var start: Vector3 = custom_points[0] - var finish: Vector3 = custom_points[1] - var horizontal := Vector3(finish.x - start.x, 0.0, finish.z - start.z) - var run := horizontal.length() - var rise_amount := finish.y - start.y - if run < 0.05 or rise_amount <= 0.05 or stair_count < 1 or stair_width <= 0.0: - return _array_mesh(vertices, normals) - var forward := horizontal / run - var width_axis := Vector3(-forward.z, 0.0, forward.x) * stair_width * 0.5 - var profile := PackedVector2Array([Vector2(0.0, 0.0), Vector2(run, 0.0), Vector2(run, rise_amount)]) - for step_index in range(stair_count - 1, -1, -1): - var tread_start := run * float(step_index) / stair_count - var tread_end := run * float(step_index + 1) / stair_count - var tread_height := rise_amount * float(step_index + 1) / stair_count - profile.append(Vector2(tread_start, tread_height)) - if step_index > 0: - profile.append(Vector2(tread_start, rise_amount * float(step_index) / stair_count)) - var triangulation := Geometry2D.triangulate_polygon(profile) - for side_sign in [-1.0, 1.0]: - for triangle_index in range(0, triangulation.size(), 3): - var a := profile[triangulation[triangle_index]] - var b := profile[triangulation[triangle_index + 1]] - var c := profile[triangulation[triangle_index + 2]] - var point_a: Vector3 = start + forward * a.x + Vector3.UP * a.y + width_axis * side_sign - var point_b: Vector3 = start + forward * b.x + Vector3.UP * b.y + width_axis * side_sign - var point_c: Vector3 = start + forward * c.x + Vector3.UP * c.y + width_axis * side_sign - if side_sign > 0.0: - _add_tri(vertices, normals, point_a, point_b, point_c) - else: - _add_tri(vertices, normals, point_c, point_b, point_a) - for profile_index in range(profile.size()): - var next_index := (profile_index + 1) % profile.size() - var a := profile[profile_index] - var b := profile[next_index] - var point_a_left := start + forward * a.x + Vector3.UP * a.y - width_axis - var point_b_left := start + forward * b.x + Vector3.UP * b.y - width_axis - var point_b_right := start + forward * b.x + Vector3.UP * b.y + width_axis - var point_a_right := start + forward * a.x + Vector3.UP * a.y + width_axis - _add_quad(vertices, normals, point_a_left, point_b_left, point_b_right, point_a_right) - return _array_mesh(vertices, normals) - -func _make_fence_mesh() -> ArrayMesh: - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var start: Vector3 = custom_points[0] - var finish: Vector3 = custom_points[1] - var path := finish - start - var path_length := path.length() - if path_length < 0.05 or fence_height <= 0.0: - return _array_mesh(vertices, normals) - var path_axis := path / path_length - var post_count := fence_divisions + 2 - var post_positions: Array[Vector3] = [] - for post_index in range(post_count): - var base_position := start.lerp(finish, float(post_index) / float(post_count - 1)) - post_positions.append(base_position) - var side_axis := path_axis.cross(Vector3.UP).normalized() - if side_axis.length_squared() < 0.001: - side_axis = Vector3.FORWARD - _append_oriented_box(vertices, normals, base_position + Vector3.UP * fence_height * 0.5, path_axis, Vector3.UP, side_axis, Vector3(thickness, fence_height, thickness)) - for section_index in range(post_positions.size() - 1): - var section_start := post_positions[section_index] - var section_end := post_positions[section_index + 1] - var section_axis := (section_end - section_start).normalized() - var rail_up := Vector3.UP - section_axis * section_axis.dot(Vector3.UP) - if rail_up.length_squared() < 0.001: - rail_up = Vector3.FORWARD - section_axis * section_axis.dot(Vector3.FORWARD) - rail_up = rail_up.normalized() - var rail_side := section_axis.cross(rail_up).normalized() - var section_length := section_start.distance_to(section_end) - for height_ratio in [0.28, 0.78]: - var rail_center: Vector3 = (section_start + section_end) * 0.5 + Vector3.UP * fence_height * height_ratio - _append_oriented_box(vertices, normals, rail_center, section_axis, rail_up, rail_side, Vector3(section_length, thickness, thickness)) - return _array_mesh(vertices, normals) - -func _append_oriented_box(vertices: PackedVector3Array, normals: PackedVector3Array, center: Vector3, axis_x: Vector3, axis_y: Vector3, axis_z: Vector3, dimensions: Vector3) -> void: - var x := axis_x.normalized() * dimensions.x * 0.5 - var y := axis_y.normalized() * dimensions.y * 0.5 - var z := axis_z.normalized() * dimensions.z * 0.5 - var nnn := center - x - y - z - var pnn := center + x - y - z - var ppn := center + x + y - z - var npn := center - x + y - z - var nnp := center - x - y + z - var pnp := center + x - y + z - var ppp := center + x + y + z - var npp := center - x + y + z - _add_quad(vertices, normals, nnp, pnp, ppp, npp) - _add_quad(vertices, normals, pnn, nnn, npn, ppn) - _add_quad(vertices, normals, npp, ppp, ppn, npn) - _add_quad(vertices, normals, nnn, pnn, pnp, nnp) - _add_quad(vertices, normals, nnn, nnp, npp, npn) - _add_quad(vertices, normals, pnp, pnn, ppn, ppp) - -func _get_centered_gable_base() -> PackedVector3Array: - var selected_a := to_global(custom_points[0]) - var selected_b := to_global(custom_points[1]) - var search_root: Node = get_parent() - while search_root != null and not search_root is ModularBuilderPieceGeometry: - search_root = search_root.get_parent() - if search_root == null: - return PackedVector3Array([custom_points[0], custom_points[1]]) - var walls: Array[ModularBuilderPieceGeometry] = [] - _collect_centering_walls(search_root, walls) - var centered_a := selected_a - var centered_b := selected_b - var nearest_a := INF - var nearest_b := INF - for wall in walls: - if wall.custom_points.size() < 2: - continue - var wall_a := wall.to_global(wall.custom_points[0] + Vector3.UP * wall.unit_size) - var wall_b := wall.to_global(wall.custom_points[1] + Vector3.UP * wall.unit_size) - var tolerance: float = wall.thickness + 0.04 - for endpoint in [wall_a, wall_b]: - var distance_a := selected_a.distance_to(endpoint) - if distance_a < nearest_a and distance_a <= tolerance: - nearest_a = distance_a - centered_a = endpoint - var distance_b := selected_b.distance_to(endpoint) - if distance_b < nearest_b and distance_b <= tolerance: - nearest_b = distance_b - centered_b = endpoint - if nearest_a < INF and nearest_b < INF and centered_a.distance_to(centered_b) >= 0.02: - return PackedVector3Array([to_local(centered_a), to_local(centered_b)]) - return PackedVector3Array([custom_points[0], custom_points[1]]) - -func _collect_centering_walls(node: Node, walls: Array[ModularBuilderPieceGeometry]) -> void: - if node is ModularBuilderPieceGeometry and node.piece_type == PieceType.WALL: - walls.append(node) - for child in node.get_children(): - _collect_centering_walls(child, walls) - -func _append_solid_panel(vertices: PackedVector3Array, normals: PackedVector3Array, panel: Array) -> void: - if panel.size() < 3: - return - var p0: Vector3 = panel[0] - var p1: Vector3 = panel[1] - var p2: Vector3 = panel[2] - var normal: Vector3 = (p1 - p0).cross(p2 - p0).normalized() - if normal.is_zero_approx(): - return - var half_depth: Vector3 = normal * thickness * 0.5 - var front: Array[Vector3] = [] - var back: Array[Vector3] = [] - for point in panel: - front.append(point + half_depth) - back.append(point - half_depth) - for i in range(1, panel.size() - 1): - _add_tri(vertices, normals, front[0], front[i], front[i + 1]) - _add_tri(vertices, normals, back[i + 1], back[i], back[0]) - for i in range(panel.size()): - var next := (i + 1) % panel.size() - _add_quad(vertices, normals, front[i], back[i], back[next], front[next]) - -func _make_custom_wall_mesh() -> ArrayMesh: - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var wall_points: PackedVector3Array = _get_centered_wall_points() if center_align else custom_points - var a: Vector3 = wall_points[0] - var b: Vector3 = wall_points[1] - var direction := (b - a).normalized() - var length := a.distance_to(b) - var side := Vector3(-direction.z, 0.0, direction.x).normalized() * thickness * 0.5 - var height := Vector3.UP * unit_size - var openings: Array[PackedVector2Array] = [] - for child in get_children(): - if _is_detail_node(child) and int(child.get("detail_type")) != DETAIL_TYPE_HATCH and int(child.get("detail_type")) != DETAIL_TYPE_PILLAR: - var detail := child as Node3D - var center := Vector2((detail.position - a).dot(direction), detail.position.y - a.y) - var axis_x := Vector2(detail.transform.basis.x.dot(direction), detail.transform.basis.x.y).normalized() - var axis_y := Vector2(detail.transform.basis.y.dot(direction), detail.transform.basis.y.y).normalized() - var opening := PackedVector2Array([ - center - axis_x * float(detail.get("width")) * 0.5 - axis_y * float(detail.get("height")) * 0.5, - center + axis_x * float(detail.get("width")) * 0.5 - axis_y * float(detail.get("height")) * 0.5, - center + axis_x * float(detail.get("width")) * 0.5 + axis_y * float(detail.get("height")) * 0.5, - center - axis_x * float(detail.get("width")) * 0.5 + axis_y * float(detail.get("height")) * 0.5 - ]) - var wall_rect := PackedVector2Array([Vector2(0.0, 0.0), Vector2(length, 0.0), Vector2(length, unit_size), Vector2(0.0, unit_size)]) - for clipped_opening in Geometry2D.intersect_polygons(opening, wall_rect): - if clipped_opening.size() >= 3: - openings.append(clipped_opening) - var xs: Array[float] = [0.0, length] - var ys: Array[float] = [0.0, unit_size] - for opening in openings: - for point in opening: - xs.append(clampf(point.x, 0.0, length)) - ys.append(clampf(point.y, 0.0, unit_size)) - xs.sort() - ys.sort() - for xi in range(xs.size() - 1): - for yi in range(ys.size() - 1): - var u0: float = xs[xi] - var u1: float = xs[xi + 1] - var v0: float = ys[yi] - var v1: float = ys[yi + 1] - var mid := Vector2((u0 + u1) * 0.5, (v0 + v1) * 0.5) - var cell := PackedVector2Array([Vector2(u0, v0), Vector2(u1, v0), Vector2(u1, v1), Vector2(u0, v1)]) - var remaining: Array[PackedVector2Array] = [cell] - for opening in openings: - var next_remaining: Array[PackedVector2Array] = [] - for polygon in remaining: - for clipped in Geometry2D.clip_polygons(polygon, opening): - if clipped.size() >= 3: - next_remaining.append(clipped) - remaining = next_remaining - for polygon in remaining: - var indices := Geometry2D.triangulate_polygon(polygon) - for ti in range(0, indices.size(), 3): - var p0: Vector2 = polygon[indices[ti]] - var p1: Vector2 = polygon[indices[ti + 1]] - var p2: Vector2 = polygon[indices[ti + 2]] - var f0 := a + direction * p0.x + Vector3.UP * p0.y - var f1 := a + direction * p1.x + Vector3.UP * p1.y - var f2 := a + direction * p2.x + Vector3.UP * p2.y - _add_tri(vertices, normals, f0 + side, f1 + side, f2 + side) - _add_tri(vertices, normals, f2 - side, f1 - side, f0 - side) - # Close the wall body at its ends, top, and base. - _add_quad(vertices, normals, a - side, a + side, a + side + height, a - side + height) - _add_quad(vertices, normals, b + side, b - side, b - side + height, b + side + height) - _add_quad(vertices, normals, a + side + height, b + side + height, b - side + height, a - side + height) - _add_quad(vertices, normals, a - side, b - side, b + side, a + side) - for opening in openings: - for edge_index in range(opening.size()): - var p0 := opening[edge_index] - var p1 := opening[(edge_index + 1) % opening.size()] - var a0 := a + direction * p0.x + Vector3.UP * p0.y - var a1 := a + direction * p1.x + Vector3.UP * p1.y - _add_quad(vertices, normals, a0 + side, a0 - side, a1 - side, a1 + side) - return _array_mesh(vertices, normals) - -func _get_centered_wall_points() -> PackedVector3Array: - if custom_points.size() < 2: - return custom_points - var selected_a := to_global(custom_points[0]) - var selected_b := to_global(custom_points[1]) - var search_root: Node = get_parent() - while search_root != null and not search_root is ModularBuilderPieceGeometry: - search_root = search_root.get_parent() - if search_root == null: - return custom_points - var walls: Array[ModularBuilderPieceGeometry] = [] - _collect_centering_walls(search_root, walls) - var centered_a := selected_a - var centered_b := selected_b - var nearest_a := INF - var nearest_b := INF - for wall in walls: - if wall == self or wall.custom_points.size() < 2: - continue - var direction := (wall.custom_points[1] - wall.custom_points[0]).normalized() - var side := Vector3(-direction.z, 0.0, direction.x).normalized() * wall.thickness * 0.5 - for endpoint in wall.custom_points: - var center := wall.to_global(endpoint + Vector3.UP * wall.unit_size) - for surface_corner in [center + side, center - side]: - var distance_a := selected_a.distance_to(surface_corner) - if distance_a < nearest_a and distance_a <= wall.thickness + 0.04: - nearest_a = distance_a - centered_a = center - var distance_b := selected_b.distance_to(surface_corner) - if distance_b < nearest_b and distance_b <= wall.thickness + 0.04: - nearest_b = distance_b - centered_b = center - if nearest_a < INF and nearest_b < INF and centered_a.distance_to(centered_b) >= 0.02: - return PackedVector3Array([to_local(centered_a), to_local(centered_b)]) - return custom_points - -func _make_custom_floor_mesh() -> ArrayMesh: - var polygon: Array[Vector2] = [] - for point in custom_points: - polygon.append(Vector2(point.x, point.z)) - var hatch_mesh := _make_hatch_surface_mesh(polygon, custom_points[0].y, custom_points[0].y - thickness) - if hatch_mesh != null: - return hatch_mesh - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var points := custom_points - var bottom: Array[Vector3] = [] - for point in points: - bottom.append(point - Vector3.UP * thickness) - for i in range(1, points.size() - 1): - _add_tri(vertices, normals, points[0], points[i + 1], points[i]) - _add_tri(vertices, normals, bottom[0], bottom[i], bottom[i + 1]) - for i in range(points.size()): - var j := (i + 1) % points.size() - _add_quad(vertices, normals, bottom[i], bottom[j], points[j], points[i]) - return _array_mesh(vertices, normals) - -func _make_hatch_surface_mesh(polygon: Array[Vector2], top_y: float, bottom_y: float) -> ArrayMesh: - var openings: Array[PackedVector2Array] = [] - for child in get_children(): - if _is_detail_node(child) and int(child.get("detail_type")) == DETAIL_TYPE_HATCH: - var detail := child as Node3D - var center := Vector2(detail.position.x, detail.position.z) - var axis_x := Vector2(detail.transform.basis.x.x, detail.transform.basis.x.z).normalized() - var axis_y := Vector2(detail.transform.basis.z.x, detail.transform.basis.z.z).normalized() - var opening := PackedVector2Array([ - center - axis_x * float(detail.get("width")) * 0.5 - axis_y * float(detail.get("height")) * 0.5, - center + axis_x * float(detail.get("width")) * 0.5 - axis_y * float(detail.get("height")) * 0.5, - center + axis_x * float(detail.get("width")) * 0.5 + axis_y * float(detail.get("height")) * 0.5, - center - axis_x * float(detail.get("width")) * 0.5 + axis_y * float(detail.get("height")) * 0.5 - ]) - openings.append(opening) - if openings.is_empty() or polygon.size() < 3: - return null - var min_x := polygon[0].x - var max_x := polygon[0].x - var min_z := polygon[0].y - var max_z := polygon[0].y - var xs: Array[float] = [] - var zs: Array[float] = [] - for point in polygon: - min_x = minf(min_x, point.x) - max_x = maxf(max_x, point.x) - min_z = minf(min_z, point.y) - max_z = maxf(max_z, point.y) - xs.append(point.x) - zs.append(point.y) - for opening in openings: - for point in opening: - xs.append(clampf(point.x, min_x, max_x)) - zs.append(clampf(point.y, min_z, max_z)) - xs.sort() - zs.sort() - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - var source_polygon := PackedVector2Array() - for point in polygon: - source_polygon.append(point) - for xi in range(xs.size() - 1): - for zi in range(zs.size() - 1): - var x0: float = xs[xi] - var x1: float = xs[xi + 1] - var z0: float = zs[zi] - var z1: float = zs[zi + 1] - if x1 - x0 < 0.0001 or z1 - z0 < 0.0001: - continue - var cell := PackedVector2Array([Vector2(x0, z0), Vector2(x1, z0), Vector2(x1, z1), Vector2(x0, z1)]) - var remaining: Array[PackedVector2Array] = [] - for clipped_surface in Geometry2D.intersect_polygons(source_polygon, cell): - remaining.append(clipped_surface) - for opening in openings: - var next_remaining: Array[PackedVector2Array] = [] - for surface_polygon in remaining: - for clipped_surface in Geometry2D.clip_polygons(surface_polygon, opening): - if clipped_surface.size() >= 3: - next_remaining.append(clipped_surface) - remaining = next_remaining - for clipped_surface in remaining: - var triangulated := Geometry2D.triangulate_polygon(clipped_surface) - for ti in range(0, triangulated.size(), 3): - var a: Vector2 = clipped_surface[triangulated[ti]] - var b: Vector2 = clipped_surface[triangulated[ti + 1]] - var c: Vector2 = clipped_surface[triangulated[ti + 2]] - _add_tri(vertices, normals, Vector3(a.x, top_y, a.y), Vector3(c.x, top_y, c.y), Vector3(b.x, top_y, b.y)) - _add_tri(vertices, normals, Vector3(a.x, bottom_y, a.y), Vector3(b.x, bottom_y, b.y), Vector3(c.x, bottom_y, c.y)) - for i in range(polygon.size()): - var j := (i + 1) % polygon.size() - var a := polygon[i] - var b := polygon[j] - _add_quad(vertices, normals, Vector3(a.x, bottom_y, a.y), Vector3(b.x, bottom_y, b.y), Vector3(b.x, top_y, b.y), Vector3(a.x, top_y, a.y)) - for opening in openings: - var visible_edges := Geometry2D.intersect_polygons(opening, source_polygon) - for visible_opening in visible_edges: - for edge_index in range(visible_opening.size()): - var p0 := visible_opening[edge_index] - var p1 := visible_opening[(edge_index + 1) % visible_opening.size()] - _add_quad(vertices, normals, Vector3(p0.x, bottom_y, p0.y), Vector3(p0.x, top_y, p0.y), Vector3(p1.x, top_y, p1.y), Vector3(p1.x, bottom_y, p1.y)) - return _array_mesh(vertices, normals) - -func _is_detail_node(node: Node) -> bool: - if not node is Node3D or node.get_script() == null: - return false - return node.get_script().resource_path == DETAIL_SCRIPT_PATH - -func _make_custom_foundation_mesh() -> ArrayMesh: - var polygon: Array[Vector2] = [] - for point in custom_points: - polygon.append(Vector2(point.x, point.z)) - var bottom_y := -thickness * 0.5 if centered_origin else 0.0 - var top_y := thickness * 0.5 if centered_origin else thickness - var hatch_mesh := _make_hatch_surface_mesh(polygon, top_y, bottom_y) - if hatch_mesh != null: - return hatch_mesh - var vertices := PackedVector3Array() - var normals := PackedVector3Array() - for i in range(1, custom_points.size() - 1): - var a := custom_points[0] - var b := custom_points[i] - var c := custom_points[i + 1] - _add_tri(vertices, normals, Vector3(a.x, top_y, a.z), Vector3(c.x, top_y, c.z), Vector3(b.x, top_y, b.z)) - _add_tri(vertices, normals, Vector3(a.x, bottom_y, a.z), Vector3(b.x, bottom_y, b.z), Vector3(c.x, bottom_y, c.z)) - for i in range(custom_points.size()): - var j := (i + 1) % custom_points.size() - var a := custom_points[i] - var b := custom_points[j] - _add_quad(vertices, normals, Vector3(a.x, bottom_y, a.z), Vector3(b.x, bottom_y, b.z), Vector3(b.x, top_y, b.z), Vector3(a.x, top_y, a.z)) - return _array_mesh(vertices, normals) - -func _add_quad(v: PackedVector3Array, n: PackedVector3Array, a: Vector3, b: Vector3, c: Vector3, d: Vector3) -> void: - _add_tri(v, n, a, b, c) - _add_tri(v, n, a, c, d) - -func _array_mesh(v: PackedVector3Array, n: PackedVector3Array) -> ArrayMesh: - var arrays: Array = [] - arrays.resize(Mesh.ARRAY_MAX) - arrays[Mesh.ARRAY_VERTEX] = v - arrays[Mesh.ARRAY_NORMAL] = n - var result := ArrayMesh.new() - result.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) - return result - -func _add_tri(v: PackedVector3Array, n: PackedVector3Array, a: Vector3, b: Vector3, c: Vector3) -> void: - var normal := (b - a).cross(c - a).normalized() - v.append(a) - v.append(b) - v.append(c) - n.append(normal) - n.append(normal) - n.append(normal) - # Also generate reversed faces to show both sides. - # This keeps floors and foundations visible from below with any material. - v.append(c) - v.append(b) - v.append(a) - n.append(-normal) - n.append(-normal) - n.append(-normal) diff --git a/addons/modular_builder/modular_piece_geometry.gd.uid b/addons/modular_builder/modular_piece_geometry.gd.uid deleted file mode 100644 index 0e7655e..0000000 --- a/addons/modular_builder/modular_piece_geometry.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dp1333xlylabf diff --git a/addons/modular_builder/scopedvr_export_ui.gd b/addons/modular_builder/scopedvr_export_ui.gd index b964793..d974bb4 100644 --- a/addons/modular_builder/scopedvr_export_ui.gd +++ b/addons/modular_builder/scopedvr_export_ui.gd @@ -133,8 +133,8 @@ func _export(oid: String, name_roh: String) -> void: if not editor_dir.is_empty(): var img := await _thumbnail_bilden(mesh) if img != null: - DirAccess.make_dir_recursive_absolute(editor_dir + "/library/thumbs") - img.save_png(editor_dir + "/library/thumbs/" + oid + ".png") + DirAccess.make_dir_recursive_absolute(editor_dir + "/core/thumbs") + img.save_png(editor_dir + "/core/thumbs/" + oid + ".png") # 6) Editor-Sync (Registry-Kopie; vorhandene Thumbnails bleiben stehen). var schritt4 := _lauf(objekt_tool, ["editor", oid]) diff --git a/core b/core index 3ee60fb..d196086 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 3ee60fb9297a3a850f0a504a7032f44dc8ad2dea +Subproject commit d196086cce09fb729f6ff013e7e8216b56c5e977 diff --git a/docs/bauen.md b/docs/bauen.md index a936afb..bee5fcf 100644 --- a/docs/bauen.md +++ b/docs/bauen.md @@ -19,7 +19,7 @@ Ein Bauteil ist ein **ganz normales Bibliotheks-Objekt** (`bau_*`, Kategorie und Server lesen dieselbe Datei. * Poly-Budget zählt wie bei jedem Objekt (`poly` = Dreiecke des Teils). -## Teile (Katalog: `src/editor/bau_katalog.gd`) +## Teile (Katalog: `core/editor/bau_katalog.gd`) | Gruppe | Teile | | --- | --- | @@ -34,7 +34,7 @@ Ein Bauteil ist ein **ganz normales Bibliotheks-Objekt** (`bau_*`, Kategorie Fertige Pack-Objekte (Container, Hangar-Tore, Betonsperren) stehen NICHT im Bauen-Tab, sondern wie alle Objekte in der Objekt-Bibliothek unten. -## Snap (`src/editor/build_snap.gd`) +## Snap (`core/editor/build_snap.gd`) * **XZ:** Wände auf die nächste Zellkante — und zwar GANZ in die Zelle, in der die Maus ist (Außenseite bündig mit der Kante, kein Überhang, Ecken schließen ohne diff --git a/docs/server-sektion.md b/docs/server-sektion.md index 5f40c5a..40bdf8a 100644 --- a/docs/server-sektion.md +++ b/docs/server-sektion.md @@ -41,8 +41,8 @@ im Editor dann Adresse `127.0.0.1`) oder ein Reverse-Proxy mit https (Haken - **Server-Log** mit Filter. ## Code -`src/server/` (AdminClient, ServerStore, AdminTexte, MapPush), -`src/ui/panels/server_panel.gd`, `SvmapIO.to_signed_text`. +`core/server/` (AdminClient, ServerStore, AdminTexte, MapPush), +`core/ui/panels/server_panel.gd`, `SvmapIO.to_signed_text`. ## Tests `tests/test_server_sektion.gd` (Unit), `tests/run_server_sektion_e2e.sh` diff --git a/docs/tasten.md b/docs/tasten.md index 6912a83..b9b5ef0 100644 --- a/docs/tasten.md +++ b/docs/tasten.md @@ -5,12 +5,12 @@ of truth** für alle Shortcut-Karten — FINALE Version nach allen drei Karten: Karte 1/3 (t_c46d31c2): Navigation, Auswahl, Löschen · Karte 2/3 (t_55257792): Objektmanipulation + Terrain · Karte 3/3 (t_11b5c25b): Datei & Undo, Werkzeugwechsel, Hilfe, Test. Das Kurzhilfe-Overlay im Editor (Taste **H**) -zeigt dieselbe Tabelle (Quelle: `src/ui/help_text.gd`). +zeigt dieselbe Tabelle (Quelle: `core/ui/help_text.gd`). Konventionen (alle Karten): - Tastaturcode-basiert: InputMap-Actions mit physischen `KEY_*`-Konstanten - (`src/editor/shortcut_keys.gd`). Die physische Taste liegt unabhängig vom + (`core/editor/shortcut_keys.gd`). Die physische Taste liegt unabhängig vom Tastaturlayout gleich — deutsches (QWERTZ) und Windows-Layout verhalten sich identisch, keine OS-Hardcodes (PLAN.md Plattform-Regel). - Jede Objekt-Operation = **EIN** ActionHistory-Eintrag (Strg+Z nimmt die diff --git a/library/loadout_katalog.json b/library/loadout_katalog.json deleted file mode 100644 index 9e2c58f..0000000 --- a/library/loadout_katalog.json +++ /dev/null @@ -1,3206 +0,0 @@ -{ - "version": 1, - "waffen": { - "ar1": { - "name": "AR-1 Sturmgewehr", - "slots": { - "bar_bottom": { - "default": "ar1_handle_bottom", - "optional": true, - "options": [ - "ar1_handle_bottom", - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "ar1_handle_left", - "optional": true, - "options": [ - "ar1_handle_left", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "ar1_handle_right", - "optional": true, - "options": [ - "ar1_handle_right", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_top": { - "default": "", - "optional": true, - "options": [ - "tactical_laser_aiming", - "tactical_laser_aiming_system", - "tactical_flashlight", - "tactical_flashlight_02" - ] - }, - "gunstock": { - "default": "ar1_buttstock_light", - "optional": false, - "options": [ - "ar1_buttstock_heavy", - "ar1_buttstock_light" - ] - }, - "magazine": { - "default": "ar1_magazine_extended", - "optional": false, - "options": [ - "ar1_magazine", - "ar1_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "ar1_sight", - "optional": true, - "options": [ - "ar1_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "ar10": { - "name": "AR-10 Kompakt", - "slots": { - "bar_bottom": { - "default": "ar10_handguard", - "optional": true, - "options": [ - "ar10_handguard", - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "ar10_magazine_extended", - "optional": false, - "options": [ - "ar10_magazine", - "ar10_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "ar10_sight", - "optional": true, - "options": [ - "ar10_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "ar2": { - "name": "AR-2", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "barrel": { - "default": "ar2_barrel_mod", - "optional": false, - "options": [ - "ar2_barrel_mod", - "ar2_barrel_stock" - ] - }, - "gunstock": { - "default": "ar2_buttstock_heavy", - "optional": false, - "options": [ - "ar2_buttstock_heavy", - "ar2_buttstock_light" - ] - }, - "magazine": { - "default": "ar2_magazine", - "optional": false, - "options": [ - "ar2_magazine", - "ar2_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "ar2_sight_01", - "optional": true, - "options": [ - "ar2_sight_01", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "ar3": { - "name": "AR-3 Lang", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_top": { - "default": "", - "optional": true, - "options": [ - "tactical_laser_aiming", - "tactical_laser_aiming_system", - "tactical_flashlight", - "tactical_flashlight_02" - ] - }, - "barrel": { - "default": "ar3_barrel_mod", - "optional": false, - "options": [ - "ar3_barrel_mod", - "ar3_barrel_stock" - ] - }, - "gunstock": { - "default": "ar3_buttstock_heavy", - "optional": false, - "options": [ - "ar3_buttstock_heavy", - "ar3_buttstock_light" - ] - }, - "magazine": { - "default": "ar3_magazine", - "optional": false, - "options": [ - "ar3_magazine", - "ar3_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "ar4": { - "name": "AR-4 Werfer", - "slots": { - "bar_bottom": { - "default": "ar4_grenade_launcher", - "optional": true, - "options": [ - "ar4_grenade_launcher", - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_top": { - "default": "", - "optional": true, - "options": [ - "tactical_laser_aiming", - "tactical_laser_aiming_system", - "tactical_flashlight", - "tactical_flashlight_02" - ] - }, - "magazine": { - "default": "ar4_magazine", - "optional": false, - "options": [ - "ar4_magazine", - "ar4_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "ar5": { - "name": "AR-5", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_top": { - "default": "", - "optional": true, - "options": [ - "tactical_laser_aiming", - "tactical_laser_aiming_system", - "tactical_flashlight", - "tactical_flashlight_02" - ] - }, - "gunstock": { - "default": "ar5_buttstock_heavy", - "optional": false, - "options": [ - "ar5_buttstock_heavy", - "ar5_buttstock_light" - ] - }, - "magazine": { - "default": "ar5_magazine", - "optional": false, - "options": [ - "ar5_magazine", - "ar5_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "ar6": { - "name": "AR-6 Kurz", - "slots": { - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_top": { - "default": "", - "optional": true, - "options": [ - "tactical_laser_aiming", - "tactical_laser_aiming_system", - "tactical_flashlight", - "tactical_flashlight_02" - ] - }, - "magazine": { - "default": "ar6_magazine_extended", - "optional": false, - "options": [ - "ar6_magazine", - "ar6_magazine_extended" - ] - }, - "muzzle": { - "default": "ar6_muzzle", - "optional": true, - "options": [ - "ar6_muzzle", - "ar6_grenade_launcher", - "ar6_handguard", - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "ar6_sight", - "optional": true, - "options": [ - "ar6_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "ar7": { - "name": "AR-7 Schwer", - "slots": { - "bar_bottom_01": { - "default": "ar7_grenade_launcher", - "optional": false, - "options": [ - "ar7_grenade_launcher" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "ar7_magazine", - "optional": false, - "options": [ - "ar7_magazine", - "ar7_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "ar8": { - "name": "AR-8", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_top": { - "default": "", - "optional": true, - "options": [ - "tactical_laser_aiming", - "tactical_laser_aiming_system", - "tactical_flashlight", - "tactical_flashlight_02" - ] - }, - "magazine": { - "default": "ar8_magazine", - "optional": false, - "options": [ - "ar8_magazine", - "ar8_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "ar8_sight", - "optional": true, - "options": [ - "ar8_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "ar9": { - "name": "AR-9", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "ar9_magazine", - "optional": false, - "options": [ - "ar9_magazine", - "ar9_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "ar9_sight", - "optional": true, - "options": [ - "ar9_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "flare_gun": { - "name": "Leuchtpistole", - "slots": {} - }, - "gl1": { - "name": "Granatwerfer M79", - "slots": {} - }, - "gl2": { - "name": "Granatwerfer MGL", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_top": { - "default": "", - "optional": true, - "options": [ - "tactical_laser_aiming", - "tactical_laser_aiming_system", - "tactical_flashlight", - "tactical_flashlight_02" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "gl3": { - "name": "Granatwerfer M320", - "slots": { - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "gl4": { - "name": "Granatwerfer Grosskaliber", - "slots": { - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "gl5": { - "name": "Granatwerfer Rohr 40mm", - "slots": { - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "gl6": { - "name": "Granatwerfer RPG", - "slots": { - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "m40": { - "name": "M40", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bipod": { - "default": "", - "optional": true, - "options": [ - "sr1_bipod" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - } - } - }, - "mg1": { - "name": "M249", - "slots": { - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bipod": { - "default": "mg1_bipod", - "optional": true, - "options": [ - "mg1_bipod" - ] - }, - "handle": { - "default": "mg1_handle", - "optional": true, - "options": [ - "mg1_handle" - ] - }, - "magazine": { - "default": "mg1_magazine", - "optional": false, - "options": [ - "mg1_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "mg2": { - "name": "PKM", - "slots": { - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_top": { - "default": "", - "optional": true, - "options": [ - "tactical_laser_aiming", - "tactical_laser_aiming_system", - "tactical_flashlight", - "tactical_flashlight_02" - ] - }, - "bipod": { - "default": "mg2_bipod", - "optional": true, - "options": [ - "mg2_bipod" - ] - }, - "gunstock": { - "default": "mg2_buttstock_heavy", - "optional": false, - "options": [ - "mg2_buttstock_heavy", - "mg2_buttstock_light" - ] - }, - "handle": { - "default": "mg2_handle", - "optional": true, - "options": [ - "mg2_handle" - ] - }, - "magazine": { - "default": "mg2_magazine", - "optional": false, - "options": [ - "mg2_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "mg2_sight", - "optional": true, - "options": [ - "mg2_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "mg3": { - "name": "M60", - "slots": { - "bipod": { - "default": "mg3_bipod", - "optional": true, - "options": [ - "mg3_bipod" - ] - }, - "magazine": { - "default": "mg3_magazine", - "optional": false, - "options": [ - "mg3_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "mg4": { - "name": "MG4", - "slots": { - "bipod": { - "default": "mg4_bipod", - "optional": true, - "options": [ - "mg4_bipod" - ] - }, - "gunstock": { - "default": "mg4_buttstock_heavy", - "optional": false, - "options": [ - "mg4_buttstock_heavy", - "mg4_buttstock_light" - ] - }, - "handle": { - "default": "mg4_handle", - "optional": true, - "options": [ - "mg4_handle" - ] - }, - "magazine": { - "default": "mg4_magazine", - "optional": false, - "options": [ - "mg4_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "mg5": { - "name": "RPD", - "slots": {} - }, - "mg6": { - "name": "M2", - "slots": { - "bipod": { - "default": "mg6_bipod", - "optional": true, - "options": [ - "mg6_bipod" - ] - }, - "magazine": { - "default": "mg6_magazine", - "optional": false, - "options": [ - "mg6_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - } - } - }, - "pistol1": { - "name": "Pistole", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "pistol1_magazine", - "optional": false, - "options": [ - "pistol1_magazine", - "pistol1_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "pistol2": { - "name": "Pistole P226", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "pistol2_magazine", - "optional": false, - "options": [ - "pistol2_magazine", - "pistol2_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "pistol3": { - "name": "Pistole G17", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "pistol3_magazine_extended", - "optional": false, - "options": [ - "pistol3_magazine", - "pistol3_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "pistol4": { - "name": "Pistole M1911", - "slots": {} - }, - "pistol5": { - "name": "Revolver .357", - "slots": {} - }, - "pistol6": { - "name": "Pistole USP .45", - "slots": { - "magazine": { - "default": "pistol6_magazine", - "optional": false, - "options": [ - "pistol6_magazine", - "pistol6_magazine_extended" - ] - } - } - }, - "shotgun1": { - "name": "Pumpe 12ga", - "slots": { - "gunstock": { - "default": "shotgun1_buttstock_heavy", - "optional": false, - "options": [ - "shotgun1_buttstock_heavy", - "shotgun1_buttstock_light" - ] - }, - "magazine": { - "default": "shotgun1_magazine", - "optional": false, - "options": [ - "shotgun1_magazine", - "shotgun1_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "shotgun2": { - "name": "Kurzflinte 12ga", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "shotgun2_magazine", - "optional": false, - "options": [ - "shotgun2_magazine", - "shotgun2_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "shotgun3": { - "name": "Pumpe 20ga", - "slots": { - "gunstock": { - "default": "shotgun3_buttstock_light", - "optional": false, - "options": [ - "shotgun3_buttstock_heavy", - "shotgun3_buttstock_light" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "shotgun4": { - "name": "Pumpe 12ga Lang", - "slots": { - "gunstock": { - "default": "shotgun4_buttstock_heavy", - "optional": false, - "options": [ - "shotgun4_buttstock_heavy", - "shotgun4_buttstock_light" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "shotgun5": { - "name": "Halbauto 12ga", - "slots": {} - }, - "shotgun6": { - "name": "Auto-Shotgun", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "shotgun6_magazine", - "optional": false, - "options": [ - "shotgun6_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg1": { - "name": "MP5", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "gunstock": { - "default": "smg1_buttstock_light", - "optional": false, - "options": [ - "smg1_buttstock_heavy", - "smg1_buttstock_light" - ] - }, - "magazine": { - "default": "smg1_magazine", - "optional": false, - "options": [ - "smg1_magazine_extended", - "smg1_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg10": { - "name": "Scorpion Evo", - "slots": { - "magazine": { - "default": "smg10_magazine_extended", - "optional": false, - "options": [ - "smg10_magazine_extended", - "smg10_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg11": { - "name": "Sterling", - "slots": { - "gunstock": { - "default": "smg11_buttstock", - "optional": false, - "options": [ - "smg11_buttstock" - ] - }, - "magazine": { - "default": "smg11_magazine", - "optional": false, - "options": [ - "smg11_magazine", - "smg11_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg12": { - "name": "Micro Uzi", - "slots": { - "bar_handle": { - "default": "smg12_handle", - "optional": true, - "options": [ - "smg12_handle" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_top": { - "default": "", - "optional": true, - "options": [ - "tactical_laser_aiming", - "tactical_laser_aiming_system", - "tactical_flashlight", - "tactical_flashlight_02" - ] - }, - "magazine": { - "default": "smg12_magazine", - "optional": false, - "options": [ - "smg12_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - } - } - }, - "smg2": { - "name": "MP5K", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "gunstock": { - "default": "smg2_buttstock_heavy", - "optional": false, - "options": [ - "smg2_buttstock_heavy", - "smg2_buttstock_light" - ] - }, - "magazine": { - "default": "smg2_magazine_extended", - "optional": false, - "options": [ - "smg2_magazine", - "smg2_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg3": { - "name": "MP7", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "gunstock": { - "default": "smg3_buttstock_light", - "optional": false, - "options": [ - "smg3_buttstock_heavy", - "smg3_buttstock_light" - ] - }, - "magazine": { - "default": "smg3_magazine_extended", - "optional": false, - "options": [ - "smg3_magazine_extended", - "smg3_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg4": { - "name": "MP9", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "gunstock": { - "default": "smg4_buttstock_heavy", - "optional": false, - "options": [ - "smg4_buttstock_heavy", - "smg4_buttstock_light" - ] - }, - "magazine": { - "default": "smg4_magazine", - "optional": false, - "options": [ - "smg4_magazine_extended", - "smg4_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg5": { - "name": "Uzi", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "gunstock": { - "default": "smg5_buttstock_light", - "optional": false, - "options": [ - "smg5_buttstock_heavy", - "smg5_buttstock_light" - ] - }, - "magazine": { - "default": "smg5_magazine", - "optional": false, - "options": [ - "smg5_magazine_extended", - "smg5_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "smg5_sight", - "optional": true, - "options": [ - "smg5_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg6": { - "name": "MAC-10", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "gunstock": { - "default": "smg6_buttstock_light", - "optional": false, - "options": [ - "smg6_buttstock_heavy", - "smg6_buttstock_light" - ] - }, - "magazine": { - "default": "smg6_magazine", - "optional": false, - "options": [ - "smg6_magazine_extended", - "smg6_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "smg6_sight", - "optional": true, - "options": [ - "smg6_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg7": { - "name": "PP-19 Bizon", - "slots": { - "gunstock": { - "default": "smg7_buttstock_heavy", - "optional": false, - "options": [ - "smg7_buttstock_heavy", - "smg7_buttstock_light" - ] - }, - "magazine": { - "default": "smg7_magazine", - "optional": false, - "options": [ - "smg7_magazine_extended", - "smg7_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "smg7_sight", - "optional": true, - "options": [ - "smg7_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg8": { - "name": "P90", - "slots": { - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "smg8_magazine", - "optional": false, - "options": [ - "smg8_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "smg8_sight", - "optional": true, - "options": [ - "smg8_sight", - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "smg9": { - "name": "Kriss Vector", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "magazine": { - "default": "smg9_magazine", - "optional": false, - "options": [ - "smg9_magazine_extended", - "smg9_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "sr1": { - "name": "AWM", - "slots": { - "bar_bottom": { - "default": "", - "optional": true, - "options": [ - "foregrip_horisontal", - "foregrip_small", - "foregrip_vertical_01", - "foregrip_vertical_02", - "foregrip_vertical_03", - "foregrip_vertical_04", - "foregrip_vertical_05", - "foregrip_vertical_06", - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bipod": { - "default": "sr1_bipod", - "optional": true, - "options": [ - "sr1_bipod" - ] - }, - "magazine": { - "default": "sr1_magazine_extended", - "optional": false, - "options": [ - "sr1_magazine", - "sr1_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "sight_10", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "sr2": { - "name": "SR-25", - "slots": { - "bar_left": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bar_right": { - "default": "", - "optional": true, - "options": [ - "tactical_flashlight", - "tactical_flashlight_02", - "tactical_laser_aiming", - "tactical_laser_aiming_system" - ] - }, - "bipod": { - "default": "sr2_bipod", - "optional": true, - "options": [ - "sr2_bipod" - ] - }, - "gunstock": { - "default": "sr2_buttstock_heavy", - "optional": false, - "options": [ - "sr2_buttstock_heavy", - "sr2_buttstock_light" - ] - }, - "magazine": { - "default": "sr2_magazine", - "optional": false, - "options": [ - "sr2_magazine", - "sr2_magazine_extended" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "sight_11", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "sr3": { - "name": "M24", - "slots": { - "bipod": { - "default": "sr3_bipod", - "optional": true, - "options": [ - "sr3_bipod" - ] - }, - "magazine": { - "default": "sr3_magazine", - "optional": false, - "options": [ - "sr3_magazine_extended", - "sr3_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "sight_10", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "sr4": { - "name": "SVD Dragunow", - "slots": { - "magazine": { - "default": "sr4_magazine", - "optional": false, - "options": [ - "sr4_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "sight_08", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "sr5": { - "name": "Remington 700", - "slots": { - "magazine": { - "default": "sr5_magazine", - "optional": false, - "options": [ - "sr5_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "sight_06", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "sr6": { - "name": "TAC-50", - "slots": { - "bipod": { - "default": "sr6_bipod", - "optional": true, - "options": [ - "sr6_bipod" - ] - }, - "magazine": { - "default": "sr6_magazine_extended", - "optional": false, - "options": [ - "sr6_magazine_extended", - "sr6_magazine" - ] - }, - "muzzle": { - "default": "", - "optional": true, - "options": [ - "muzzle_compensator_01", - "muzzle_compensator_02", - "muzzle_flash_hider_01", - "muzzle_flash_hider_02", - "muzzle_suppressor_01", - "muzzle_suppressor_02", - "muzzle_suppressor_03" - ] - }, - "sight": { - "default": "sight_07", - "optional": true, - "options": [ - "sight_01", - "sight_02", - "sight_03", - "sight_04", - "sight_05", - "sight_06", - "sight_07", - "sight_08", - "sight_09", - "sight_10", - "sight_11", - "sight_collimator", - "sight_holographic", - "sight_offset" - ] - } - } - }, - "taser_gun": { - "name": "Taser", - "slots": {} - } - } -} \ No newline at end of file diff --git a/library/thumbs/acacia_003.png b/library/thumbs/acacia_003.png deleted file mode 100644 index 3875411..0000000 Binary files a/library/thumbs/acacia_003.png and /dev/null differ diff --git a/library/thumbs/acacia_003.png.import b/library/thumbs/acacia_003.png.import deleted file mode 100644 index 9496a2e..0000000 --- a/library/thumbs/acacia_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bsnwxasr4kxnw" -path="res://.godot/imported/acacia_003.png-780c300e868256b9a9eb8bee97e274d7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/acacia_003.png" -dest_files=["res://.godot/imported/acacia_003.png-780c300e868256b9a9eb8bee97e274d7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/acacia_005.png b/library/thumbs/acacia_005.png deleted file mode 100644 index 3c10af8..0000000 Binary files a/library/thumbs/acacia_005.png and /dev/null differ diff --git a/library/thumbs/acacia_005.png.import b/library/thumbs/acacia_005.png.import deleted file mode 100644 index 5f8a6b0..0000000 --- a/library/thumbs/acacia_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dpng4qbmhgaxn" -path="res://.godot/imported/acacia_005.png-13391d2a2fbb9e1af9a9899676d6255b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/acacia_005.png" -dest_files=["res://.godot/imported/acacia_005.png-13391d2a2fbb9e1af9a9899676d6255b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/acacia_006.png b/library/thumbs/acacia_006.png deleted file mode 100644 index 8ac1e72..0000000 Binary files a/library/thumbs/acacia_006.png and /dev/null differ diff --git a/library/thumbs/acacia_006.png.import b/library/thumbs/acacia_006.png.import deleted file mode 100644 index e0686d1..0000000 --- a/library/thumbs/acacia_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://0vjob86u0mkh" -path="res://.godot/imported/acacia_006.png-543980dded5a44fa5e3d06584f5fe696.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/acacia_006.png" -dest_files=["res://.godot/imported/acacia_006.png-543980dded5a44fa5e3d06584f5fe696.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/air_defense_001.png b/library/thumbs/air_defense_001.png deleted file mode 100644 index e24da7b..0000000 Binary files a/library/thumbs/air_defense_001.png and /dev/null differ diff --git a/library/thumbs/air_defense_001.png.import b/library/thumbs/air_defense_001.png.import deleted file mode 100644 index 6583c72..0000000 --- a/library/thumbs/air_defense_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dxjkjfi837uo7" -path="res://.godot/imported/air_defense_001.png-b437d643c7024a7d8c111897c2ab61ec.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/air_defense_001.png" -dest_files=["res://.godot/imported/air_defense_001.png-b437d643c7024a7d8c111897c2ab61ec.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/air_defense_002.png b/library/thumbs/air_defense_002.png deleted file mode 100644 index 5a6c9c9..0000000 Binary files a/library/thumbs/air_defense_002.png and /dev/null differ diff --git a/library/thumbs/air_defense_002.png.import b/library/thumbs/air_defense_002.png.import deleted file mode 100644 index fdf2821..0000000 --- a/library/thumbs/air_defense_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dmkfqnti7k861" -path="res://.godot/imported/air_defense_002.png-53fc58f2e7263c151a9515b088d1f631.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/air_defense_002.png" -dest_files=["res://.godot/imported/air_defense_002.png-53fc58f2e7263c151a9515b088d1f631.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/air_defense_platform_001.png b/library/thumbs/air_defense_platform_001.png deleted file mode 100644 index a676ea6..0000000 Binary files a/library/thumbs/air_defense_platform_001.png and /dev/null differ diff --git a/library/thumbs/air_defense_platform_001.png.import b/library/thumbs/air_defense_platform_001.png.import deleted file mode 100644 index 09795c5..0000000 --- a/library/thumbs/air_defense_platform_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cyvumt7k7tfkt" -path="res://.godot/imported/air_defense_platform_001.png-f3f7931f8c44d060f84082b8977bf627.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/air_defense_platform_001.png" -dest_files=["res://.godot/imported/air_defense_platform_001.png-f3f7931f8c44d060f84082b8977bf627.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/air_defense_platform_002.png b/library/thumbs/air_defense_platform_002.png deleted file mode 100644 index e33a5d1..0000000 Binary files a/library/thumbs/air_defense_platform_002.png and /dev/null differ diff --git a/library/thumbs/air_defense_platform_002.png.import b/library/thumbs/air_defense_platform_002.png.import deleted file mode 100644 index 218b9d5..0000000 --- a/library/thumbs/air_defense_platform_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://blm2ew1gswl1e" -path="res://.godot/imported/air_defense_platform_002.png-0a5ce0c8e1362f387319264873cf529f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/air_defense_platform_002.png" -dest_files=["res://.godot/imported/air_defense_platform_002.png-0a5ce0c8e1362f387319264873cf529f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/antenna_001.png b/library/thumbs/antenna_001.png deleted file mode 100644 index 765a196..0000000 Binary files a/library/thumbs/antenna_001.png and /dev/null differ diff --git a/library/thumbs/antenna_001.png.import b/library/thumbs/antenna_001.png.import deleted file mode 100644 index b46d840..0000000 --- a/library/thumbs/antenna_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cu2km1kitwe32" -path="res://.godot/imported/antenna_001.png-4dad960bc19a6b3ab31294105028d1e9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/antenna_001.png" -dest_files=["res://.godot/imported/antenna_001.png-4dad960bc19a6b3ab31294105028d1e9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/apc_001.png b/library/thumbs/apc_001.png deleted file mode 100644 index d48571c..0000000 Binary files a/library/thumbs/apc_001.png and /dev/null differ diff --git a/library/thumbs/apc_001.png.import b/library/thumbs/apc_001.png.import deleted file mode 100644 index df7dd0d..0000000 --- a/library/thumbs/apc_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ckp5nasktsw6d" -path="res://.godot/imported/apc_001.png-9e80d2bf93d5fc993e616b7b32e8b724.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/apc_001.png" -dest_files=["res://.godot/imported/apc_001.png-9e80d2bf93d5fc993e616b7b32e8b724.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/apc_002.png b/library/thumbs/apc_002.png deleted file mode 100644 index d262e0a..0000000 Binary files a/library/thumbs/apc_002.png and /dev/null differ diff --git a/library/thumbs/apc_002.png.import b/library/thumbs/apc_002.png.import deleted file mode 100644 index b7bfca3..0000000 --- a/library/thumbs/apc_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b75b4yhnejh2m" -path="res://.godot/imported/apc_002.png-523f4a9b408f9b8c5eb6be67985b0502.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/apc_002.png" -dest_files=["res://.godot/imported/apc_002.png-523f4a9b408f9b8c5eb6be67985b0502.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/apc_cap.png b/library/thumbs/apc_cap.png deleted file mode 100644 index 675b864..0000000 Binary files a/library/thumbs/apc_cap.png and /dev/null differ diff --git a/library/thumbs/apc_cap.png.import b/library/thumbs/apc_cap.png.import deleted file mode 100644 index 77ac6f9..0000000 --- a/library/thumbs/apc_cap.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://08m553i6la3k" -path="res://.godot/imported/apc_cap.png-23a774749caddf07feaf320bf58cabdd.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/apc_cap.png" -dest_files=["res://.godot/imported/apc_cap.png-23a774749caddf07feaf320bf58cabdd.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/apc_cap_1.png b/library/thumbs/apc_cap_1.png deleted file mode 100644 index aa217f7..0000000 Binary files a/library/thumbs/apc_cap_1.png and /dev/null differ diff --git a/library/thumbs/apc_cap_1.png.import b/library/thumbs/apc_cap_1.png.import deleted file mode 100644 index 7ac2109..0000000 --- a/library/thumbs/apc_cap_1.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dkxw5r6shmdeo" -path="res://.godot/imported/apc_cap_1.png-d621f9e71ef0b7877f2b15a48d673ee9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/apc_cap_1.png" -dest_files=["res://.godot/imported/apc_cap_1.png-d621f9e71ef0b7877f2b15a48d673ee9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/apc_weapon.png b/library/thumbs/apc_weapon.png deleted file mode 100644 index 5cea823..0000000 Binary files a/library/thumbs/apc_weapon.png and /dev/null differ diff --git a/library/thumbs/apc_weapon.png.import b/library/thumbs/apc_weapon.png.import deleted file mode 100644 index 81e5eb1..0000000 --- a/library/thumbs/apc_weapon.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://clmsnievmhcdv" -path="res://.godot/imported/apc_weapon.png-c1a66e252a3e0b0605bbbabef999fd28.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/apc_weapon.png" -dest_files=["res://.godot/imported/apc_weapon.png-c1a66e252a3e0b0605bbbabef999fd28.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barracks_001.png b/library/thumbs/barracks_001.png deleted file mode 100644 index 6c723e1..0000000 Binary files a/library/thumbs/barracks_001.png and /dev/null differ diff --git a/library/thumbs/barracks_001.png.import b/library/thumbs/barracks_001.png.import deleted file mode 100644 index b5dd30f..0000000 --- a/library/thumbs/barracks_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bhqfuk76plea1" -path="res://.godot/imported/barracks_001.png-155b2e8dc1723ecd52306bc4563ba954.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barracks_001.png" -dest_files=["res://.godot/imported/barracks_001.png-155b2e8dc1723ecd52306bc4563ba954.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_001.png b/library/thumbs/barrel_001.png deleted file mode 100644 index 6cf0f22..0000000 Binary files a/library/thumbs/barrel_001.png and /dev/null differ diff --git a/library/thumbs/barrel_001.png.import b/library/thumbs/barrel_001.png.import deleted file mode 100644 index 2d54f99..0000000 --- a/library/thumbs/barrel_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://8d3x37mwv6xr" -path="res://.godot/imported/barrel_001.png-6908404f7d70f7a5c32b5535b30c54e6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_001.png" -dest_files=["res://.godot/imported/barrel_001.png-6908404f7d70f7a5c32b5535b30c54e6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_002.png b/library/thumbs/barrel_002.png deleted file mode 100644 index 25079d5..0000000 Binary files a/library/thumbs/barrel_002.png and /dev/null differ diff --git a/library/thumbs/barrel_002.png.import b/library/thumbs/barrel_002.png.import deleted file mode 100644 index 47efb14..0000000 --- a/library/thumbs/barrel_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://x036pdk80s03" -path="res://.godot/imported/barrel_002.png-9223e213854153a1cae1e6683aba7a93.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_002.png" -dest_files=["res://.godot/imported/barrel_002.png-9223e213854153a1cae1e6683aba7a93.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_003.png b/library/thumbs/barrel_003.png deleted file mode 100644 index 286909d..0000000 Binary files a/library/thumbs/barrel_003.png and /dev/null differ diff --git a/library/thumbs/barrel_003.png.import b/library/thumbs/barrel_003.png.import deleted file mode 100644 index 6ad086b..0000000 --- a/library/thumbs/barrel_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://clandxfaibniy" -path="res://.godot/imported/barrel_003.png-dced15cfc3e6c765081d15d50c27a968.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_003.png" -dest_files=["res://.godot/imported/barrel_003.png-dced15cfc3e6c765081d15d50c27a968.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_004.png b/library/thumbs/barrel_004.png deleted file mode 100644 index 09fda6d..0000000 Binary files a/library/thumbs/barrel_004.png and /dev/null differ diff --git a/library/thumbs/barrel_004.png.import b/library/thumbs/barrel_004.png.import deleted file mode 100644 index 802e472..0000000 --- a/library/thumbs/barrel_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://r3uuorqbq6g7" -path="res://.godot/imported/barrel_004.png-94267e67e4b759e20fe5900b875a4eef.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_004.png" -dest_files=["res://.godot/imported/barrel_004.png-94267e67e4b759e20fe5900b875a4eef.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_005.png b/library/thumbs/barrel_005.png deleted file mode 100644 index 17ad7ec..0000000 Binary files a/library/thumbs/barrel_005.png and /dev/null differ diff --git a/library/thumbs/barrel_005.png.import b/library/thumbs/barrel_005.png.import deleted file mode 100644 index 99d81bf..0000000 --- a/library/thumbs/barrel_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d1bivgvwdvioh" -path="res://.godot/imported/barrel_005.png-9542d468a6873a8fd580ad9cdef4fd0f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_005.png" -dest_files=["res://.godot/imported/barrel_005.png-9542d468a6873a8fd580ad9cdef4fd0f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_006.png b/library/thumbs/barrel_006.png deleted file mode 100644 index b0a863e..0000000 Binary files a/library/thumbs/barrel_006.png and /dev/null differ diff --git a/library/thumbs/barrel_006.png.import b/library/thumbs/barrel_006.png.import deleted file mode 100644 index 24b5d70..0000000 --- a/library/thumbs/barrel_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://3vp6eyi4g2bj" -path="res://.godot/imported/barrel_006.png-5890db03d20712e23b0aeb0f28d480ae.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_006.png" -dest_files=["res://.godot/imported/barrel_006.png-5890db03d20712e23b0aeb0f28d480ae.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_007.png b/library/thumbs/barrel_007.png deleted file mode 100644 index 3f3e77b..0000000 Binary files a/library/thumbs/barrel_007.png and /dev/null differ diff --git a/library/thumbs/barrel_007.png.import b/library/thumbs/barrel_007.png.import deleted file mode 100644 index d047158..0000000 --- a/library/thumbs/barrel_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b4atq8e72m7my" -path="res://.godot/imported/barrel_007.png-d90f90a76918ff4bbd0adc316d5ffdf8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_007.png" -dest_files=["res://.godot/imported/barrel_007.png-d90f90a76918ff4bbd0adc316d5ffdf8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_008.png b/library/thumbs/barrel_008.png deleted file mode 100644 index d2ecc9e..0000000 Binary files a/library/thumbs/barrel_008.png and /dev/null differ diff --git a/library/thumbs/barrel_008.png.import b/library/thumbs/barrel_008.png.import deleted file mode 100644 index 8571a04..0000000 --- a/library/thumbs/barrel_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://co0hauu3itiu3" -path="res://.godot/imported/barrel_008.png-5f57f9825de2472879e769759a4679a8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_008.png" -dest_files=["res://.godot/imported/barrel_008.png-5f57f9825de2472879e769759a4679a8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_009.png b/library/thumbs/barrel_009.png deleted file mode 100644 index 1988fe1..0000000 Binary files a/library/thumbs/barrel_009.png and /dev/null differ diff --git a/library/thumbs/barrel_009.png.import b/library/thumbs/barrel_009.png.import deleted file mode 100644 index 8073c70..0000000 --- a/library/thumbs/barrel_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cwb0huh22ist2" -path="res://.godot/imported/barrel_009.png-b83ebf0290fccdfee558913551761413.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_009.png" -dest_files=["res://.godot/imported/barrel_009.png-b83ebf0290fccdfee558913551761413.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_010.png b/library/thumbs/barrel_010.png deleted file mode 100644 index cb94d3e..0000000 Binary files a/library/thumbs/barrel_010.png and /dev/null differ diff --git a/library/thumbs/barrel_010.png.import b/library/thumbs/barrel_010.png.import deleted file mode 100644 index 6fd2708..0000000 --- a/library/thumbs/barrel_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://nwboqq7bq5cc" -path="res://.godot/imported/barrel_010.png-8e9db8f1f68c4fdee8260e5894adfe86.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_010.png" -dest_files=["res://.godot/imported/barrel_010.png-8e9db8f1f68c4fdee8260e5894adfe86.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_011.png b/library/thumbs/barrel_011.png deleted file mode 100644 index 1f70721..0000000 Binary files a/library/thumbs/barrel_011.png and /dev/null differ diff --git a/library/thumbs/barrel_011.png.import b/library/thumbs/barrel_011.png.import deleted file mode 100644 index c7192b9..0000000 --- a/library/thumbs/barrel_011.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bf2orfs8g27pk" -path="res://.godot/imported/barrel_011.png-e6f72afda072cf9838ed06700c6b5ebd.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_011.png" -dest_files=["res://.godot/imported/barrel_011.png-e6f72afda072cf9838ed06700c6b5ebd.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_012.png b/library/thumbs/barrel_012.png deleted file mode 100644 index b538937..0000000 Binary files a/library/thumbs/barrel_012.png and /dev/null differ diff --git a/library/thumbs/barrel_012.png.import b/library/thumbs/barrel_012.png.import deleted file mode 100644 index fdd4810..0000000 --- a/library/thumbs/barrel_012.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dddfloskgqjui" -path="res://.godot/imported/barrel_012.png-69afd264c2078adae3355c1036520a7e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_012.png" -dest_files=["res://.godot/imported/barrel_012.png-69afd264c2078adae3355c1036520a7e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrel_013.png b/library/thumbs/barrel_013.png deleted file mode 100644 index a85c05d..0000000 Binary files a/library/thumbs/barrel_013.png and /dev/null differ diff --git a/library/thumbs/barrel_013.png.import b/library/thumbs/barrel_013.png.import deleted file mode 100644 index 23749b1..0000000 --- a/library/thumbs/barrel_013.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://8wcuxv0v56js" -path="res://.godot/imported/barrel_013.png-3b6581a9a4637f3f79f372095dbc1b6a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrel_013.png" -dest_files=["res://.godot/imported/barrel_013.png-3b6581a9a4637f3f79f372095dbc1b6a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_001.png b/library/thumbs/barrier_001.png deleted file mode 100644 index f061b98..0000000 Binary files a/library/thumbs/barrier_001.png and /dev/null differ diff --git a/library/thumbs/barrier_001.png.import b/library/thumbs/barrier_001.png.import deleted file mode 100644 index b94b061..0000000 --- a/library/thumbs/barrier_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://drn6mij5p6hv5" -path="res://.godot/imported/barrier_001.png-f4f9b068e708eb35cf4f0689fd3c6f74.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_001.png" -dest_files=["res://.godot/imported/barrier_001.png-f4f9b068e708eb35cf4f0689fd3c6f74.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_002.png b/library/thumbs/barrier_002.png deleted file mode 100644 index 5251114..0000000 Binary files a/library/thumbs/barrier_002.png and /dev/null differ diff --git a/library/thumbs/barrier_002.png.import b/library/thumbs/barrier_002.png.import deleted file mode 100644 index 43cb674..0000000 --- a/library/thumbs/barrier_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dbhbgk7y8j54p" -path="res://.godot/imported/barrier_002.png-226efbbe1880285f86c95e9a1be7518e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_002.png" -dest_files=["res://.godot/imported/barrier_002.png-226efbbe1880285f86c95e9a1be7518e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_003.png b/library/thumbs/barrier_003.png deleted file mode 100644 index 22d927a..0000000 Binary files a/library/thumbs/barrier_003.png and /dev/null differ diff --git a/library/thumbs/barrier_003.png.import b/library/thumbs/barrier_003.png.import deleted file mode 100644 index ab189b8..0000000 --- a/library/thumbs/barrier_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ccvfh73fkfikq" -path="res://.godot/imported/barrier_003.png-22cd5cdb2ab7396c5afef5360b5067dd.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_003.png" -dest_files=["res://.godot/imported/barrier_003.png-22cd5cdb2ab7396c5afef5360b5067dd.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_004.png b/library/thumbs/barrier_004.png deleted file mode 100644 index 7109612..0000000 Binary files a/library/thumbs/barrier_004.png and /dev/null differ diff --git a/library/thumbs/barrier_004.png.import b/library/thumbs/barrier_004.png.import deleted file mode 100644 index dbac986..0000000 --- a/library/thumbs/barrier_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bgc3wwy6b41b0" -path="res://.godot/imported/barrier_004.png-980b996df5a61642aa5a8982d9429ff5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_004.png" -dest_files=["res://.godot/imported/barrier_004.png-980b996df5a61642aa5a8982d9429ff5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_005.png b/library/thumbs/barrier_005.png deleted file mode 100644 index 88e1dda..0000000 Binary files a/library/thumbs/barrier_005.png and /dev/null differ diff --git a/library/thumbs/barrier_005.png.import b/library/thumbs/barrier_005.png.import deleted file mode 100644 index 51fe862..0000000 --- a/library/thumbs/barrier_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dmkxussbxmumo" -path="res://.godot/imported/barrier_005.png-9239fc40b7d66072393ec05a176a0899.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_005.png" -dest_files=["res://.godot/imported/barrier_005.png-9239fc40b7d66072393ec05a176a0899.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_006.png b/library/thumbs/barrier_006.png deleted file mode 100644 index bea628a..0000000 Binary files a/library/thumbs/barrier_006.png and /dev/null differ diff --git a/library/thumbs/barrier_006.png.import b/library/thumbs/barrier_006.png.import deleted file mode 100644 index cf1a8c6..0000000 --- a/library/thumbs/barrier_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cjhuexnsl151p" -path="res://.godot/imported/barrier_006.png-a42842c6692537da809bd937c042edfc.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_006.png" -dest_files=["res://.godot/imported/barrier_006.png-a42842c6692537da809bd937c042edfc.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_007.png b/library/thumbs/barrier_007.png deleted file mode 100644 index e719e05..0000000 Binary files a/library/thumbs/barrier_007.png and /dev/null differ diff --git a/library/thumbs/barrier_007.png.import b/library/thumbs/barrier_007.png.import deleted file mode 100644 index fb3de59..0000000 --- a/library/thumbs/barrier_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://shriffj4a6cq" -path="res://.godot/imported/barrier_007.png-18ef1a4c7bc9c8b4fdc1b04d8b91dad1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_007.png" -dest_files=["res://.godot/imported/barrier_007.png-18ef1a4c7bc9c8b4fdc1b04d8b91dad1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_008.png b/library/thumbs/barrier_008.png deleted file mode 100644 index b18ee67..0000000 Binary files a/library/thumbs/barrier_008.png and /dev/null differ diff --git a/library/thumbs/barrier_008.png.import b/library/thumbs/barrier_008.png.import deleted file mode 100644 index 4266d03..0000000 --- a/library/thumbs/barrier_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cgio2t6y3iuik" -path="res://.godot/imported/barrier_008.png-f615e24e39cbfa5c4030021171d3bcc5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_008.png" -dest_files=["res://.godot/imported/barrier_008.png-f615e24e39cbfa5c4030021171d3bcc5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_009.png b/library/thumbs/barrier_009.png deleted file mode 100644 index 805fa6f..0000000 Binary files a/library/thumbs/barrier_009.png and /dev/null differ diff --git a/library/thumbs/barrier_009.png.import b/library/thumbs/barrier_009.png.import deleted file mode 100644 index b9dcdec..0000000 --- a/library/thumbs/barrier_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://btki2yug25x23" -path="res://.godot/imported/barrier_009.png-f723a86b81fe9b5d3d1a1ae7a8338df0.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_009.png" -dest_files=["res://.godot/imported/barrier_009.png-f723a86b81fe9b5d3d1a1ae7a8338df0.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_010.png b/library/thumbs/barrier_010.png deleted file mode 100644 index 73eabdb..0000000 Binary files a/library/thumbs/barrier_010.png and /dev/null differ diff --git a/library/thumbs/barrier_010.png.import b/library/thumbs/barrier_010.png.import deleted file mode 100644 index 827063f..0000000 --- a/library/thumbs/barrier_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cjs7nqt4rl4qr" -path="res://.godot/imported/barrier_010.png-eb2f5f66658412f8d13ad87794ce497c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_010.png" -dest_files=["res://.godot/imported/barrier_010.png-eb2f5f66658412f8d13ad87794ce497c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_011.png b/library/thumbs/barrier_011.png deleted file mode 100644 index 506a77a..0000000 Binary files a/library/thumbs/barrier_011.png and /dev/null differ diff --git a/library/thumbs/barrier_011.png.import b/library/thumbs/barrier_011.png.import deleted file mode 100644 index 8f88b07..0000000 --- a/library/thumbs/barrier_011.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://j0rac170fjwn" -path="res://.godot/imported/barrier_011.png-6f858b9fbbf01e80766f67abd167b690.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_011.png" -dest_files=["res://.godot/imported/barrier_011.png-6f858b9fbbf01e80766f67abd167b690.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_012.png b/library/thumbs/barrier_012.png deleted file mode 100644 index 19e3578..0000000 Binary files a/library/thumbs/barrier_012.png and /dev/null differ diff --git a/library/thumbs/barrier_012.png.import b/library/thumbs/barrier_012.png.import deleted file mode 100644 index 559e838..0000000 --- a/library/thumbs/barrier_012.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://e6r8uhiswdsx" -path="res://.godot/imported/barrier_012.png-977a45ba313cbc8a3475c3b4dd181d97.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_012.png" -dest_files=["res://.godot/imported/barrier_012.png-977a45ba313cbc8a3475c3b4dd181d97.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_013.png b/library/thumbs/barrier_013.png deleted file mode 100644 index 22de458..0000000 Binary files a/library/thumbs/barrier_013.png and /dev/null differ diff --git a/library/thumbs/barrier_013.png.import b/library/thumbs/barrier_013.png.import deleted file mode 100644 index 8f2423f..0000000 --- a/library/thumbs/barrier_013.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://6bx8ua6gpxf2" -path="res://.godot/imported/barrier_013.png-873e6d19995610db66444c98f588223d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_013.png" -dest_files=["res://.godot/imported/barrier_013.png-873e6d19995610db66444c98f588223d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_014.png b/library/thumbs/barrier_014.png deleted file mode 100644 index 653844f..0000000 Binary files a/library/thumbs/barrier_014.png and /dev/null differ diff --git a/library/thumbs/barrier_014.png.import b/library/thumbs/barrier_014.png.import deleted file mode 100644 index a92aaa9..0000000 --- a/library/thumbs/barrier_014.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://kbu8pt3aad80" -path="res://.godot/imported/barrier_014.png-e442cc785a151929218fc114716542eb.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_014.png" -dest_files=["res://.godot/imported/barrier_014.png-e442cc785a151929218fc114716542eb.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_015.png b/library/thumbs/barrier_015.png deleted file mode 100644 index f53e531..0000000 Binary files a/library/thumbs/barrier_015.png and /dev/null differ diff --git a/library/thumbs/barrier_015.png.import b/library/thumbs/barrier_015.png.import deleted file mode 100644 index f20381a..0000000 --- a/library/thumbs/barrier_015.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ss1sahmrwvw5" -path="res://.godot/imported/barrier_015.png-86f147870fb8e12c093ac67292be870c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_015.png" -dest_files=["res://.godot/imported/barrier_015.png-86f147870fb8e12c093ac67292be870c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_016.png b/library/thumbs/barrier_016.png deleted file mode 100644 index 1affe04..0000000 Binary files a/library/thumbs/barrier_016.png and /dev/null differ diff --git a/library/thumbs/barrier_016.png.import b/library/thumbs/barrier_016.png.import deleted file mode 100644 index 82f9240..0000000 --- a/library/thumbs/barrier_016.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dtqjw5f0m65x7" -path="res://.godot/imported/barrier_016.png-3038acd7ed4790ba4581f5f0397bc15d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_016.png" -dest_files=["res://.godot/imported/barrier_016.png-3038acd7ed4790ba4581f5f0397bc15d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/barrier_017.png b/library/thumbs/barrier_017.png deleted file mode 100644 index 54d1840..0000000 Binary files a/library/thumbs/barrier_017.png and /dev/null differ diff --git a/library/thumbs/barrier_017.png.import b/library/thumbs/barrier_017.png.import deleted file mode 100644 index d9d9721..0000000 --- a/library/thumbs/barrier_017.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c4s5d1sbxon0h" -path="res://.godot/imported/barrier_017.png-5da73739577e9b74184fd835032bda12.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/barrier_017.png" -dest_files=["res://.godot/imported/barrier_017.png-5da73739577e9b74184fd835032bda12.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_boden.png b/library/thumbs/bau_boden.png deleted file mode 100644 index 553f004..0000000 Binary files a/library/thumbs/bau_boden.png and /dev/null differ diff --git a/library/thumbs/bau_boden.png.import b/library/thumbs/bau_boden.png.import deleted file mode 100644 index 15f281d..0000000 --- a/library/thumbs/bau_boden.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://df5wy3ry0lc4m" -path="res://.godot/imported/bau_boden.png-3bbfce417cc510d42a93a1f5a71bdba2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_boden.png" -dest_files=["res://.godot/imported/bau_boden.png-3bbfce417cc510d42a93a1f5a71bdba2.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_bruestung.png b/library/thumbs/bau_bruestung.png deleted file mode 100644 index ef51bc7..0000000 Binary files a/library/thumbs/bau_bruestung.png and /dev/null differ diff --git a/library/thumbs/bau_bruestung.png.import b/library/thumbs/bau_bruestung.png.import deleted file mode 100644 index b192b2d..0000000 --- a/library/thumbs/bau_bruestung.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c8vfg7jkteqqi" -path="res://.godot/imported/bau_bruestung.png-24dc182f945bd7272efdf0c647695d1f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_bruestung.png" -dest_files=["res://.godot/imported/bau_bruestung.png-24dc182f945bd7272efdf0c647695d1f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_ecke_aussen.png b/library/thumbs/bau_dach_ecke_aussen.png deleted file mode 100644 index b9d320b..0000000 Binary files a/library/thumbs/bau_dach_ecke_aussen.png and /dev/null differ diff --git a/library/thumbs/bau_dach_ecke_aussen.png.import b/library/thumbs/bau_dach_ecke_aussen.png.import deleted file mode 100644 index b13945f..0000000 --- a/library/thumbs/bau_dach_ecke_aussen.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://djm3tfu1hf0wu" -path="res://.godot/imported/bau_dach_ecke_aussen.png-e588c4f52ecd2b419b53da2ed03fba41.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_ecke_aussen.png" -dest_files=["res://.godot/imported/bau_dach_ecke_aussen.png-e588c4f52ecd2b419b53da2ed03fba41.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_ecke_innen.png b/library/thumbs/bau_dach_ecke_innen.png deleted file mode 100644 index cd24ae4..0000000 Binary files a/library/thumbs/bau_dach_ecke_innen.png and /dev/null differ diff --git a/library/thumbs/bau_dach_ecke_innen.png.import b/library/thumbs/bau_dach_ecke_innen.png.import deleted file mode 100644 index 24652d0..0000000 --- a/library/thumbs/bau_dach_ecke_innen.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://drk0drrumym47" -path="res://.godot/imported/bau_dach_ecke_innen.png-76568d9aa31ff8a708208e9950258766.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_ecke_innen.png" -dest_files=["res://.godot/imported/bau_dach_ecke_innen.png-76568d9aa31ff8a708208e9950258766.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_giebel.png b/library/thumbs/bau_dach_giebel.png deleted file mode 100644 index 385910f..0000000 Binary files a/library/thumbs/bau_dach_giebel.png and /dev/null differ diff --git a/library/thumbs/bau_dach_giebel.png.import b/library/thumbs/bau_dach_giebel.png.import deleted file mode 100644 index fb021a2..0000000 --- a/library/thumbs/bau_dach_giebel.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dcja1snb22xuj" -path="res://.godot/imported/bau_dach_giebel.png-69ec60c74c73d4ea6788b7215c9efadd.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_giebel.png" -dest_files=["res://.godot/imported/bau_dach_giebel.png-69ec60c74c73d4ea6788b7215c9efadd.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_giebel_4.png b/library/thumbs/bau_dach_giebel_4.png deleted file mode 100644 index 385910f..0000000 Binary files a/library/thumbs/bau_dach_giebel_4.png and /dev/null differ diff --git a/library/thumbs/bau_dach_giebel_4.png.import b/library/thumbs/bau_dach_giebel_4.png.import deleted file mode 100644 index eac6d4a..0000000 --- a/library/thumbs/bau_dach_giebel_4.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bt6lbs34ymm1a" -path="res://.godot/imported/bau_dach_giebel_4.png-168cdf0c90f3e99c7b117e37cec1b44c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_giebel_4.png" -dest_files=["res://.godot/imported/bau_dach_giebel_4.png-168cdf0c90f3e99c7b117e37cec1b44c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_giebel_6.png b/library/thumbs/bau_dach_giebel_6.png deleted file mode 100644 index 385910f..0000000 Binary files a/library/thumbs/bau_dach_giebel_6.png and /dev/null differ diff --git a/library/thumbs/bau_dach_giebel_6.png.import b/library/thumbs/bau_dach_giebel_6.png.import deleted file mode 100644 index 5e56820..0000000 --- a/library/thumbs/bau_dach_giebel_6.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dbvqftv8ptl76" -path="res://.godot/imported/bau_dach_giebel_6.png-fa634574bba400175ee1613d1760412b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_giebel_6.png" -dest_files=["res://.godot/imported/bau_dach_giebel_6.png-fa634574bba400175ee1613d1760412b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_giebel_ende.png b/library/thumbs/bau_dach_giebel_ende.png deleted file mode 100644 index 43f9adf..0000000 Binary files a/library/thumbs/bau_dach_giebel_ende.png and /dev/null differ diff --git a/library/thumbs/bau_dach_giebel_ende.png.import b/library/thumbs/bau_dach_giebel_ende.png.import deleted file mode 100644 index 2f5c77c..0000000 --- a/library/thumbs/bau_dach_giebel_ende.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d4mwoant504rw" -path="res://.godot/imported/bau_dach_giebel_ende.png-2b3b413e0bbd5a2e891b2db4f2cb998a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_giebel_ende.png" -dest_files=["res://.godot/imported/bau_dach_giebel_ende.png-2b3b413e0bbd5a2e891b2db4f2cb998a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_plateau.png b/library/thumbs/bau_dach_plateau.png deleted file mode 100644 index 997db21..0000000 Binary files a/library/thumbs/bau_dach_plateau.png and /dev/null differ diff --git a/library/thumbs/bau_dach_plateau.png.import b/library/thumbs/bau_dach_plateau.png.import deleted file mode 100644 index 6e28012..0000000 --- a/library/thumbs/bau_dach_plateau.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dd36il31xybcr" -path="res://.godot/imported/bau_dach_plateau.png-a214f27a54f2e159ae179f49a5e43f35.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_plateau.png" -dest_files=["res://.godot/imported/bau_dach_plateau.png-a214f27a54f2e159ae179f49a5e43f35.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_pyramide.png b/library/thumbs/bau_dach_pyramide.png deleted file mode 100644 index 548e550..0000000 Binary files a/library/thumbs/bau_dach_pyramide.png and /dev/null differ diff --git a/library/thumbs/bau_dach_pyramide.png.import b/library/thumbs/bau_dach_pyramide.png.import deleted file mode 100644 index e861ce8..0000000 --- a/library/thumbs/bau_dach_pyramide.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dc3wyq1p7b1nm" -path="res://.godot/imported/bau_dach_pyramide.png-41cae7902969d995a1f103dfb55939d5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_pyramide.png" -dest_files=["res://.godot/imported/bau_dach_pyramide.png-41cae7902969d995a1f103dfb55939d5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_pyramide_4.png b/library/thumbs/bau_dach_pyramide_4.png deleted file mode 100644 index 548e550..0000000 Binary files a/library/thumbs/bau_dach_pyramide_4.png and /dev/null differ diff --git a/library/thumbs/bau_dach_pyramide_4.png.import b/library/thumbs/bau_dach_pyramide_4.png.import deleted file mode 100644 index 2f56477..0000000 --- a/library/thumbs/bau_dach_pyramide_4.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://y5g22t4cndf0" -path="res://.godot/imported/bau_dach_pyramide_4.png-b23be54768ab1d080337a426aa59d63d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_pyramide_4.png" -dest_files=["res://.godot/imported/bau_dach_pyramide_4.png-b23be54768ab1d080337a426aa59d63d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_pyramide_6.png b/library/thumbs/bau_dach_pyramide_6.png deleted file mode 100644 index 548e550..0000000 Binary files a/library/thumbs/bau_dach_pyramide_6.png and /dev/null differ diff --git a/library/thumbs/bau_dach_pyramide_6.png.import b/library/thumbs/bau_dach_pyramide_6.png.import deleted file mode 100644 index 071986f..0000000 --- a/library/thumbs/bau_dach_pyramide_6.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cao1art7cdwnm" -path="res://.godot/imported/bau_dach_pyramide_6.png-76fda4b6ce5077d861a5cf721b328832.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_pyramide_6.png" -dest_files=["res://.godot/imported/bau_dach_pyramide_6.png-76fda4b6ce5077d861a5cf721b328832.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_dach_schraege.png b/library/thumbs/bau_dach_schraege.png deleted file mode 100644 index 8475dd5..0000000 Binary files a/library/thumbs/bau_dach_schraege.png and /dev/null differ diff --git a/library/thumbs/bau_dach_schraege.png.import b/library/thumbs/bau_dach_schraege.png.import deleted file mode 100644 index 1a28f63..0000000 --- a/library/thumbs/bau_dach_schraege.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://chval4fuxxbsh" -path="res://.godot/imported/bau_dach_schraege.png-42e12c1909f5a82025bdac6cbeafbc9e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_dach_schraege.png" -dest_files=["res://.godot/imported/bau_dach_schraege.png-42e12c1909f5a82025bdac6cbeafbc9e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_fundament.png b/library/thumbs/bau_fundament.png deleted file mode 100644 index 6a80337..0000000 Binary files a/library/thumbs/bau_fundament.png and /dev/null differ diff --git a/library/thumbs/bau_fundament.png.import b/library/thumbs/bau_fundament.png.import deleted file mode 100644 index 343bb4e..0000000 --- a/library/thumbs/bau_fundament.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bduavlchxv6xj" -path="res://.godot/imported/bau_fundament.png-70e4ef08b18cebf2a03a95bd914310b5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_fundament.png" -dest_files=["res://.godot/imported/bau_fundament.png-70e4ef08b18cebf2a03a95bd914310b5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_giebelwand.png b/library/thumbs/bau_giebelwand.png deleted file mode 100644 index c85449d..0000000 Binary files a/library/thumbs/bau_giebelwand.png and /dev/null differ diff --git a/library/thumbs/bau_giebelwand.png.import b/library/thumbs/bau_giebelwand.png.import deleted file mode 100644 index a5d7118..0000000 --- a/library/thumbs/bau_giebelwand.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bpm4yqyeuqgip" -path="res://.godot/imported/bau_giebelwand.png-32ecb79875e09f944dcbd2bd941916fb.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_giebelwand.png" -dest_files=["res://.godot/imported/bau_giebelwand.png-32ecb79875e09f944dcbd2bd941916fb.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_giebelwand_4.png b/library/thumbs/bau_giebelwand_4.png deleted file mode 100644 index c85449d..0000000 Binary files a/library/thumbs/bau_giebelwand_4.png and /dev/null differ diff --git a/library/thumbs/bau_giebelwand_4.png.import b/library/thumbs/bau_giebelwand_4.png.import deleted file mode 100644 index 949d5e5..0000000 --- a/library/thumbs/bau_giebelwand_4.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dvf3l17nuahbv" -path="res://.godot/imported/bau_giebelwand_4.png-31bd67d6005e218e8ee8915ba9b2723f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_giebelwand_4.png" -dest_files=["res://.godot/imported/bau_giebelwand_4.png-31bd67d6005e218e8ee8915ba9b2723f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_giebelwand_6.png b/library/thumbs/bau_giebelwand_6.png deleted file mode 100644 index c85449d..0000000 Binary files a/library/thumbs/bau_giebelwand_6.png and /dev/null differ diff --git a/library/thumbs/bau_giebelwand_6.png.import b/library/thumbs/bau_giebelwand_6.png.import deleted file mode 100644 index e23b644..0000000 --- a/library/thumbs/bau_giebelwand_6.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://crpyxcrmio21s" -path="res://.godot/imported/bau_giebelwand_6.png-80357dac5fdcf76c9bb8a094c69cceda.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_giebelwand_6.png" -dest_files=["res://.godot/imported/bau_giebelwand_6.png-80357dac5fdcf76c9bb8a094c69cceda.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_pfeiler.png b/library/thumbs/bau_pfeiler.png deleted file mode 100644 index 4f8b898..0000000 Binary files a/library/thumbs/bau_pfeiler.png and /dev/null differ diff --git a/library/thumbs/bau_pfeiler.png.import b/library/thumbs/bau_pfeiler.png.import deleted file mode 100644 index 618343b..0000000 --- a/library/thumbs/bau_pfeiler.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c4elt0wtyqfc3" -path="res://.godot/imported/bau_pfeiler.png-968aff13d0261f0bdf50d8e26ce3d81d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_pfeiler.png" -dest_files=["res://.godot/imported/bau_pfeiler.png-968aff13d0261f0bdf50d8e26ce3d81d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_treppe.png b/library/thumbs/bau_treppe.png deleted file mode 100644 index e20cf3e..0000000 Binary files a/library/thumbs/bau_treppe.png and /dev/null differ diff --git a/library/thumbs/bau_treppe.png.import b/library/thumbs/bau_treppe.png.import deleted file mode 100644 index 26d86fd..0000000 --- a/library/thumbs/bau_treppe.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://drcqrvbsee3tf" -path="res://.godot/imported/bau_treppe.png-0268448bc9522a7f21f4de09af77dce0.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_treppe.png" -dest_files=["res://.godot/imported/bau_treppe.png-0268448bc9522a7f21f4de09af77dce0.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_wand.png b/library/thumbs/bau_wand.png deleted file mode 100644 index ed18606..0000000 Binary files a/library/thumbs/bau_wand.png and /dev/null differ diff --git a/library/thumbs/bau_wand.png.import b/library/thumbs/bau_wand.png.import deleted file mode 100644 index 4e32f94..0000000 --- a/library/thumbs/bau_wand.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cot5xrbwq6bvs" -path="res://.godot/imported/bau_wand.png-b00d51a7f7d5502bb1bf60bd88b3c511.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_wand.png" -dest_files=["res://.godot/imported/bau_wand.png-b00d51a7f7d5502bb1bf60bd88b3c511.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_wand_fenster.png b/library/thumbs/bau_wand_fenster.png deleted file mode 100644 index d154316..0000000 Binary files a/library/thumbs/bau_wand_fenster.png and /dev/null differ diff --git a/library/thumbs/bau_wand_fenster.png.import b/library/thumbs/bau_wand_fenster.png.import deleted file mode 100644 index fe790e3..0000000 --- a/library/thumbs/bau_wand_fenster.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://br3bdm1noh1po" -path="res://.godot/imported/bau_wand_fenster.png-549483d27cc792bb51ac6c4e55ff159c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_wand_fenster.png" -dest_files=["res://.godot/imported/bau_wand_fenster.png-549483d27cc792bb51ac6c4e55ff159c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_wand_scharte.png b/library/thumbs/bau_wand_scharte.png deleted file mode 100644 index 9f08d68..0000000 Binary files a/library/thumbs/bau_wand_scharte.png and /dev/null differ diff --git a/library/thumbs/bau_wand_scharte.png.import b/library/thumbs/bau_wand_scharte.png.import deleted file mode 100644 index cb40a9f..0000000 --- a/library/thumbs/bau_wand_scharte.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://5stjyq6slxl4" -path="res://.godot/imported/bau_wand_scharte.png-d313e772da5ba1f6818177542c4ae32a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_wand_scharte.png" -dest_files=["res://.godot/imported/bau_wand_scharte.png-d313e772da5ba1f6818177542c4ae32a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bau_wand_tuer.png b/library/thumbs/bau_wand_tuer.png deleted file mode 100644 index 39cc930..0000000 Binary files a/library/thumbs/bau_wand_tuer.png and /dev/null differ diff --git a/library/thumbs/bau_wand_tuer.png.import b/library/thumbs/bau_wand_tuer.png.import deleted file mode 100644 index ce5b2b5..0000000 --- a/library/thumbs/bau_wand_tuer.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d0dbwpq57hlgy" -path="res://.godot/imported/bau_wand_tuer.png-0e3eee4e1c0c21db87bbc5915fb3a00c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bau_wand_tuer.png" -dest_files=["res://.godot/imported/bau_wand_tuer.png-0e3eee4e1c0c21db87bbc5915fb3a00c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/blade_001.png b/library/thumbs/blade_001.png deleted file mode 100644 index 0c6982a..0000000 Binary files a/library/thumbs/blade_001.png and /dev/null differ diff --git a/library/thumbs/blade_001.png.import b/library/thumbs/blade_001.png.import deleted file mode 100644 index ac29c90..0000000 --- a/library/thumbs/blade_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c2xp4qw84nfm6" -path="res://.godot/imported/blade_001.png-0bc1c0b9b886fa84319ab57a844915fe.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/blade_001.png" -dest_files=["res://.godot/imported/blade_001.png-0bc1c0b9b886fa84319ab57a844915fe.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/blade_002.png b/library/thumbs/blade_002.png deleted file mode 100644 index 9cc8d8f..0000000 Binary files a/library/thumbs/blade_002.png and /dev/null differ diff --git a/library/thumbs/blade_002.png.import b/library/thumbs/blade_002.png.import deleted file mode 100644 index 2bbff22..0000000 --- a/library/thumbs/blade_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b8hxsbrheb3w0" -path="res://.godot/imported/blade_002.png-ea1e12b88aa72764299e283d73be3772.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/blade_002.png" -dest_files=["res://.godot/imported/blade_002.png-ea1e12b88aa72764299e283d73be3772.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_001.png b/library/thumbs/box_001.png deleted file mode 100644 index 1a59233..0000000 Binary files a/library/thumbs/box_001.png and /dev/null differ diff --git a/library/thumbs/box_001.png.import b/library/thumbs/box_001.png.import deleted file mode 100644 index 6512f5b..0000000 --- a/library/thumbs/box_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b4ax75gpoe6am" -path="res://.godot/imported/box_001.png-f57686d4aba53b7e81d8c935c8880b4f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_001.png" -dest_files=["res://.godot/imported/box_001.png-f57686d4aba53b7e81d8c935c8880b4f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_002.png b/library/thumbs/box_002.png deleted file mode 100644 index f4e1347..0000000 Binary files a/library/thumbs/box_002.png and /dev/null differ diff --git a/library/thumbs/box_002.png.import b/library/thumbs/box_002.png.import deleted file mode 100644 index 720964e..0000000 --- a/library/thumbs/box_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dlcrn3bwh1cbf" -path="res://.godot/imported/box_002.png-5ff5bab49a47efb7a4d5ec6915b69b45.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_002.png" -dest_files=["res://.godot/imported/box_002.png-5ff5bab49a47efb7a4d5ec6915b69b45.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_003.png b/library/thumbs/box_003.png deleted file mode 100644 index d6e68f7..0000000 Binary files a/library/thumbs/box_003.png and /dev/null differ diff --git a/library/thumbs/box_003.png.import b/library/thumbs/box_003.png.import deleted file mode 100644 index eb8bb15..0000000 --- a/library/thumbs/box_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dcsubl8p7c8p5" -path="res://.godot/imported/box_003.png-687334f4c406cbc15897bbc146841e92.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_003.png" -dest_files=["res://.godot/imported/box_003.png-687334f4c406cbc15897bbc146841e92.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_004.png b/library/thumbs/box_004.png deleted file mode 100644 index 7db894c..0000000 Binary files a/library/thumbs/box_004.png and /dev/null differ diff --git a/library/thumbs/box_004.png.import b/library/thumbs/box_004.png.import deleted file mode 100644 index d3b3188..0000000 --- a/library/thumbs/box_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://7infi8h1h28x" -path="res://.godot/imported/box_004.png-b2ec246d8832091924b42850fa83ae3e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_004.png" -dest_files=["res://.godot/imported/box_004.png-b2ec246d8832091924b42850fa83ae3e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_005.png b/library/thumbs/box_005.png deleted file mode 100644 index 8acc2b9..0000000 Binary files a/library/thumbs/box_005.png and /dev/null differ diff --git a/library/thumbs/box_005.png.import b/library/thumbs/box_005.png.import deleted file mode 100644 index c4a6720..0000000 --- a/library/thumbs/box_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cfe5j170txkck" -path="res://.godot/imported/box_005.png-6b46c0a1e8e74a5960fd7e02053e95e8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_005.png" -dest_files=["res://.godot/imported/box_005.png-6b46c0a1e8e74a5960fd7e02053e95e8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_006.png b/library/thumbs/box_006.png deleted file mode 100644 index ff094d0..0000000 Binary files a/library/thumbs/box_006.png and /dev/null differ diff --git a/library/thumbs/box_006.png.import b/library/thumbs/box_006.png.import deleted file mode 100644 index b223462..0000000 --- a/library/thumbs/box_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dcykj0beb31kr" -path="res://.godot/imported/box_006.png-33d89b507878e5afc2d8bafc008102a1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_006.png" -dest_files=["res://.godot/imported/box_006.png-33d89b507878e5afc2d8bafc008102a1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_007.png b/library/thumbs/box_007.png deleted file mode 100644 index dd70ef2..0000000 Binary files a/library/thumbs/box_007.png and /dev/null differ diff --git a/library/thumbs/box_007.png.import b/library/thumbs/box_007.png.import deleted file mode 100644 index a735017..0000000 --- a/library/thumbs/box_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c0sk3hgbb6daa" -path="res://.godot/imported/box_007.png-6fd9a3e5e1c9de23f917b78669e9a747.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_007.png" -dest_files=["res://.godot/imported/box_007.png-6fd9a3e5e1c9de23f917b78669e9a747.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_008.png b/library/thumbs/box_008.png deleted file mode 100644 index 4b7af5e..0000000 Binary files a/library/thumbs/box_008.png and /dev/null differ diff --git a/library/thumbs/box_008.png.import b/library/thumbs/box_008.png.import deleted file mode 100644 index a43e8fd..0000000 --- a/library/thumbs/box_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d2ynvj116h1ra" -path="res://.godot/imported/box_008.png-e9c7be915a57c8848a0565a098087cf7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_008.png" -dest_files=["res://.godot/imported/box_008.png-e9c7be915a57c8848a0565a098087cf7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_009.png b/library/thumbs/box_009.png deleted file mode 100644 index 478d3d7..0000000 Binary files a/library/thumbs/box_009.png and /dev/null differ diff --git a/library/thumbs/box_009.png.import b/library/thumbs/box_009.png.import deleted file mode 100644 index 3652c0d..0000000 --- a/library/thumbs/box_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://e1pnnjhgpfjr" -path="res://.godot/imported/box_009.png-5901914c5b16e8f2e59487f9d3514e9b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_009.png" -dest_files=["res://.godot/imported/box_009.png-5901914c5b16e8f2e59487f9d3514e9b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_010.png b/library/thumbs/box_010.png deleted file mode 100644 index 53f9470..0000000 Binary files a/library/thumbs/box_010.png and /dev/null differ diff --git a/library/thumbs/box_010.png.import b/library/thumbs/box_010.png.import deleted file mode 100644 index 398867b..0000000 --- a/library/thumbs/box_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dpw1i2soeg0oo" -path="res://.godot/imported/box_010.png-e6423f0d4052bb79e4c034964a0ae587.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_010.png" -dest_files=["res://.godot/imported/box_010.png-e6423f0d4052bb79e4c034964a0ae587.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_011.png b/library/thumbs/box_011.png deleted file mode 100644 index 7478731..0000000 Binary files a/library/thumbs/box_011.png and /dev/null differ diff --git a/library/thumbs/box_011.png.import b/library/thumbs/box_011.png.import deleted file mode 100644 index d948329..0000000 --- a/library/thumbs/box_011.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c0y6x2hlgl1f1" -path="res://.godot/imported/box_011.png-63fa4d68288032d5941ad6c5cd8a2108.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_011.png" -dest_files=["res://.godot/imported/box_011.png-63fa4d68288032d5941ad6c5cd8a2108.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_012.png b/library/thumbs/box_012.png deleted file mode 100644 index 999ab7a..0000000 Binary files a/library/thumbs/box_012.png and /dev/null differ diff --git a/library/thumbs/box_012.png.import b/library/thumbs/box_012.png.import deleted file mode 100644 index 06398d4..0000000 --- a/library/thumbs/box_012.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cwvro43pb88ye" -path="res://.godot/imported/box_012.png-5b8b9676bfbfc7b152203fe7a0be4a23.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_012.png" -dest_files=["res://.godot/imported/box_012.png-5b8b9676bfbfc7b152203fe7a0be4a23.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_013.png b/library/thumbs/box_013.png deleted file mode 100644 index 662f207..0000000 Binary files a/library/thumbs/box_013.png and /dev/null differ diff --git a/library/thumbs/box_013.png.import b/library/thumbs/box_013.png.import deleted file mode 100644 index d8c59ed..0000000 --- a/library/thumbs/box_013.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b4wos88frshbo" -path="res://.godot/imported/box_013.png-fe3ac89c0e7361bc47797b865564502a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_013.png" -dest_files=["res://.godot/imported/box_013.png-fe3ac89c0e7361bc47797b865564502a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_014.png b/library/thumbs/box_014.png deleted file mode 100644 index b4bdaa7..0000000 Binary files a/library/thumbs/box_014.png and /dev/null differ diff --git a/library/thumbs/box_014.png.import b/library/thumbs/box_014.png.import deleted file mode 100644 index 44db59b..0000000 --- a/library/thumbs/box_014.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://clqa7fvr1ijvo" -path="res://.godot/imported/box_014.png-82c4102d61f75bbfeafe5d7b9381f479.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_014.png" -dest_files=["res://.godot/imported/box_014.png-82c4102d61f75bbfeafe5d7b9381f479.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_015.png b/library/thumbs/box_015.png deleted file mode 100644 index e71162c..0000000 Binary files a/library/thumbs/box_015.png and /dev/null differ diff --git a/library/thumbs/box_015.png.import b/library/thumbs/box_015.png.import deleted file mode 100644 index 6233f08..0000000 --- a/library/thumbs/box_015.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://8ni3pgocqepn" -path="res://.godot/imported/box_015.png-d23910d15416e73013b732b028bfca6e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_015.png" -dest_files=["res://.godot/imported/box_015.png-d23910d15416e73013b732b028bfca6e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_016.png b/library/thumbs/box_016.png deleted file mode 100644 index 1f5eeea..0000000 Binary files a/library/thumbs/box_016.png and /dev/null differ diff --git a/library/thumbs/box_016.png.import b/library/thumbs/box_016.png.import deleted file mode 100644 index 5de12cd..0000000 --- a/library/thumbs/box_016.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://uoyv3t570mmc" -path="res://.godot/imported/box_016.png-42f73789abe16ed719ac0b2ec3d4b3f4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_016.png" -dest_files=["res://.godot/imported/box_016.png-42f73789abe16ed719ac0b2ec3d4b3f4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_017.png b/library/thumbs/box_017.png deleted file mode 100644 index d034d28..0000000 Binary files a/library/thumbs/box_017.png and /dev/null differ diff --git a/library/thumbs/box_017.png.import b/library/thumbs/box_017.png.import deleted file mode 100644 index b784f4b..0000000 --- a/library/thumbs/box_017.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://exse4rpkggsj" -path="res://.godot/imported/box_017.png-f486df437b4509aa595c28c5c58eff18.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_017.png" -dest_files=["res://.godot/imported/box_017.png-f486df437b4509aa595c28c5c58eff18.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_018.png b/library/thumbs/box_018.png deleted file mode 100644 index da779e1..0000000 Binary files a/library/thumbs/box_018.png and /dev/null differ diff --git a/library/thumbs/box_018.png.import b/library/thumbs/box_018.png.import deleted file mode 100644 index 6f6dcfc..0000000 --- a/library/thumbs/box_018.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c5jfr0tnkerkx" -path="res://.godot/imported/box_018.png-c7a342567e30b3dca16e5ad83c879d1b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_018.png" -dest_files=["res://.godot/imported/box_018.png-c7a342567e30b3dca16e5ad83c879d1b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_019.png b/library/thumbs/box_019.png deleted file mode 100644 index 465096d..0000000 Binary files a/library/thumbs/box_019.png and /dev/null differ diff --git a/library/thumbs/box_019.png.import b/library/thumbs/box_019.png.import deleted file mode 100644 index e658f7c..0000000 --- a/library/thumbs/box_019.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b24ievpudu6v6" -path="res://.godot/imported/box_019.png-bd8115a187718913d17f6b8d3a0f12bb.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_019.png" -dest_files=["res://.godot/imported/box_019.png-bd8115a187718913d17f6b8d3a0f12bb.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_020.png b/library/thumbs/box_020.png deleted file mode 100644 index aae9193..0000000 Binary files a/library/thumbs/box_020.png and /dev/null differ diff --git a/library/thumbs/box_020.png.import b/library/thumbs/box_020.png.import deleted file mode 100644 index 1dec5f8..0000000 --- a/library/thumbs/box_020.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cq1agqq8wtxyl" -path="res://.godot/imported/box_020.png-c9be7a0c65636ebbd0395e16295f5b8b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_020.png" -dest_files=["res://.godot/imported/box_020.png-c9be7a0c65636ebbd0395e16295f5b8b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_021.png b/library/thumbs/box_021.png deleted file mode 100644 index ffaa67a..0000000 Binary files a/library/thumbs/box_021.png and /dev/null differ diff --git a/library/thumbs/box_021.png.import b/library/thumbs/box_021.png.import deleted file mode 100644 index b1eac97..0000000 --- a/library/thumbs/box_021.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://yu780r8avr2w" -path="res://.godot/imported/box_021.png-24a05aa1bf7080c58d9573206d889049.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_021.png" -dest_files=["res://.godot/imported/box_021.png-24a05aa1bf7080c58d9573206d889049.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_022.png b/library/thumbs/box_022.png deleted file mode 100644 index 699a278..0000000 Binary files a/library/thumbs/box_022.png and /dev/null differ diff --git a/library/thumbs/box_022.png.import b/library/thumbs/box_022.png.import deleted file mode 100644 index ec875b5..0000000 --- a/library/thumbs/box_022.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bitte36hx4ir0" -path="res://.godot/imported/box_022.png-9a925567ec394c1b1f0f2c3d3e8a4915.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_022.png" -dest_files=["res://.godot/imported/box_022.png-9a925567ec394c1b1f0f2c3d3e8a4915.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_023.png b/library/thumbs/box_023.png deleted file mode 100644 index 33b31f2..0000000 Binary files a/library/thumbs/box_023.png and /dev/null differ diff --git a/library/thumbs/box_023.png.import b/library/thumbs/box_023.png.import deleted file mode 100644 index 6309813..0000000 --- a/library/thumbs/box_023.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bnn6kx5wjwfvs" -path="res://.godot/imported/box_023.png-da49f1789b05b100ef5817aee4074fb0.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_023.png" -dest_files=["res://.godot/imported/box_023.png-da49f1789b05b100ef5817aee4074fb0.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_024.png b/library/thumbs/box_024.png deleted file mode 100644 index ccbb693..0000000 Binary files a/library/thumbs/box_024.png and /dev/null differ diff --git a/library/thumbs/box_024.png.import b/library/thumbs/box_024.png.import deleted file mode 100644 index 412b39d..0000000 --- a/library/thumbs/box_024.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://757ay5rftfjw" -path="res://.godot/imported/box_024.png-d7a8bc6344beb9cbcab1fe9bbda6a716.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_024.png" -dest_files=["res://.godot/imported/box_024.png-d7a8bc6344beb9cbcab1fe9bbda6a716.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_025.png b/library/thumbs/box_025.png deleted file mode 100644 index 8b0b6c9..0000000 Binary files a/library/thumbs/box_025.png and /dev/null differ diff --git a/library/thumbs/box_025.png.import b/library/thumbs/box_025.png.import deleted file mode 100644 index e1adf33..0000000 --- a/library/thumbs/box_025.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bnj3ti10yhqbg" -path="res://.godot/imported/box_025.png-170e9be82e64e9837f6fc4a688003044.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_025.png" -dest_files=["res://.godot/imported/box_025.png-170e9be82e64e9837f6fc4a688003044.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_026.png b/library/thumbs/box_026.png deleted file mode 100644 index fa5ea10..0000000 Binary files a/library/thumbs/box_026.png and /dev/null differ diff --git a/library/thumbs/box_026.png.import b/library/thumbs/box_026.png.import deleted file mode 100644 index 1232bf5..0000000 --- a/library/thumbs/box_026.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://jmp0uq7uyhjs" -path="res://.godot/imported/box_026.png-9c16b0dde796c9be4dfc500ba9ae49a1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_026.png" -dest_files=["res://.godot/imported/box_026.png-9c16b0dde796c9be4dfc500ba9ae49a1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_027.png b/library/thumbs/box_027.png deleted file mode 100644 index 09e9c22..0000000 Binary files a/library/thumbs/box_027.png and /dev/null differ diff --git a/library/thumbs/box_027.png.import b/library/thumbs/box_027.png.import deleted file mode 100644 index 052f5e4..0000000 --- a/library/thumbs/box_027.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cxgmxncmhneob" -path="res://.godot/imported/box_027.png-bb9941939707bac102c551f6e04a93ad.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_027.png" -dest_files=["res://.godot/imported/box_027.png-bb9941939707bac102c551f6e04a93ad.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_028.png b/library/thumbs/box_028.png deleted file mode 100644 index 5d8b202..0000000 Binary files a/library/thumbs/box_028.png and /dev/null differ diff --git a/library/thumbs/box_028.png.import b/library/thumbs/box_028.png.import deleted file mode 100644 index ecb01c7..0000000 --- a/library/thumbs/box_028.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://6pypbdb50ecd" -path="res://.godot/imported/box_028.png-853b1e7eba86189e3c1a661d4a12c509.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_028.png" -dest_files=["res://.godot/imported/box_028.png-853b1e7eba86189e3c1a661d4a12c509.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_029.png b/library/thumbs/box_029.png deleted file mode 100644 index f51d55e..0000000 Binary files a/library/thumbs/box_029.png and /dev/null differ diff --git a/library/thumbs/box_029.png.import b/library/thumbs/box_029.png.import deleted file mode 100644 index 4521b4d..0000000 --- a/library/thumbs/box_029.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://eqotu2qidpun" -path="res://.godot/imported/box_029.png-f04be45008bf942765d6e218c65cdb28.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_029.png" -dest_files=["res://.godot/imported/box_029.png-f04be45008bf942765d6e218c65cdb28.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_030.png b/library/thumbs/box_030.png deleted file mode 100644 index cd2721c..0000000 Binary files a/library/thumbs/box_030.png and /dev/null differ diff --git a/library/thumbs/box_030.png.import b/library/thumbs/box_030.png.import deleted file mode 100644 index 0c5c218..0000000 --- a/library/thumbs/box_030.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bu4t76prticai" -path="res://.godot/imported/box_030.png-4000e0fd6fa771b870a97d01ed198ece.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_030.png" -dest_files=["res://.godot/imported/box_030.png-4000e0fd6fa771b870a97d01ed198ece.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/box_031.png b/library/thumbs/box_031.png deleted file mode 100644 index 9940540..0000000 Binary files a/library/thumbs/box_031.png and /dev/null differ diff --git a/library/thumbs/box_031.png.import b/library/thumbs/box_031.png.import deleted file mode 100644 index 24815b3..0000000 --- a/library/thumbs/box_031.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c56xlvkv4hmdq" -path="res://.godot/imported/box_031.png-e1053b5ffb00711055bec54b2586cdd4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/box_031.png" -dest_files=["res://.godot/imported/box_031.png-e1053b5ffb00711055bec54b2586cdd4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/building_001.png b/library/thumbs/building_001.png deleted file mode 100644 index 9afbb78..0000000 Binary files a/library/thumbs/building_001.png and /dev/null differ diff --git a/library/thumbs/building_001.png.import b/library/thumbs/building_001.png.import deleted file mode 100644 index 3570a84..0000000 --- a/library/thumbs/building_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://biq11fg873opn" -path="res://.godot/imported/building_001.png-72ceb91ddb3f741152c84cda2254a555.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/building_001.png" -dest_files=["res://.godot/imported/building_001.png-72ceb91ddb3f741152c84cda2254a555.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bush_002.png b/library/thumbs/bush_002.png deleted file mode 100644 index 69b48c7..0000000 Binary files a/library/thumbs/bush_002.png and /dev/null differ diff --git a/library/thumbs/bush_002.png.import b/library/thumbs/bush_002.png.import deleted file mode 100644 index 15d793b..0000000 --- a/library/thumbs/bush_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bvwgcwf1tqtyi" -path="res://.godot/imported/bush_002.png-342dc41ff625fbe87ac10b834d8b12e3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bush_002.png" -dest_files=["res://.godot/imported/bush_002.png-342dc41ff625fbe87ac10b834d8b12e3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bush_006.png b/library/thumbs/bush_006.png deleted file mode 100644 index c45ca70..0000000 Binary files a/library/thumbs/bush_006.png and /dev/null differ diff --git a/library/thumbs/bush_006.png.import b/library/thumbs/bush_006.png.import deleted file mode 100644 index 8b40385..0000000 --- a/library/thumbs/bush_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cfoy6lnosuawr" -path="res://.godot/imported/bush_006.png-8579110de96beb6c9c2b2210a2d004a8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bush_006.png" -dest_files=["res://.godot/imported/bush_006.png-8579110de96beb6c9c2b2210a2d004a8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/bush_007.png b/library/thumbs/bush_007.png deleted file mode 100644 index 60354a4..0000000 Binary files a/library/thumbs/bush_007.png and /dev/null differ diff --git a/library/thumbs/bush_007.png.import b/library/thumbs/bush_007.png.import deleted file mode 100644 index 0649436..0000000 --- a/library/thumbs/bush_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ob0auhkag3in" -path="res://.godot/imported/bush_007.png-a3a498c489b306ec21348308a325f473.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/bush_007.png" -dest_files=["res://.godot/imported/bush_007.png-a3a498c489b306ec21348308a325f473.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_001.png b/library/thumbs/cactus_001.png deleted file mode 100644 index d909f6c..0000000 Binary files a/library/thumbs/cactus_001.png and /dev/null differ diff --git a/library/thumbs/cactus_001.png.import b/library/thumbs/cactus_001.png.import deleted file mode 100644 index 0841161..0000000 --- a/library/thumbs/cactus_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cnpl6qkkcial3" -path="res://.godot/imported/cactus_001.png-6d62347f5ef865a05d3d4cf4ba4dbebe.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_001.png" -dest_files=["res://.godot/imported/cactus_001.png-6d62347f5ef865a05d3d4cf4ba4dbebe.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_002.png b/library/thumbs/cactus_002.png deleted file mode 100644 index f75a6ec..0000000 Binary files a/library/thumbs/cactus_002.png and /dev/null differ diff --git a/library/thumbs/cactus_002.png.import b/library/thumbs/cactus_002.png.import deleted file mode 100644 index fe4e8a9..0000000 --- a/library/thumbs/cactus_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bmqr8fbm8aqi6" -path="res://.godot/imported/cactus_002.png-bd7b29ebd474a995e925a85a89120992.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_002.png" -dest_files=["res://.godot/imported/cactus_002.png-bd7b29ebd474a995e925a85a89120992.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_003.png b/library/thumbs/cactus_003.png deleted file mode 100644 index 6bb5b2e..0000000 Binary files a/library/thumbs/cactus_003.png and /dev/null differ diff --git a/library/thumbs/cactus_003.png.import b/library/thumbs/cactus_003.png.import deleted file mode 100644 index 0efe5b6..0000000 --- a/library/thumbs/cactus_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c8x2ac0df6ge7" -path="res://.godot/imported/cactus_003.png-1e59436907eea405bed86d8252c7966e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_003.png" -dest_files=["res://.godot/imported/cactus_003.png-1e59436907eea405bed86d8252c7966e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_004.png b/library/thumbs/cactus_004.png deleted file mode 100644 index de0ac2e..0000000 Binary files a/library/thumbs/cactus_004.png and /dev/null differ diff --git a/library/thumbs/cactus_004.png.import b/library/thumbs/cactus_004.png.import deleted file mode 100644 index 21c2817..0000000 --- a/library/thumbs/cactus_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cga1nrd847sbx" -path="res://.godot/imported/cactus_004.png-622109ebbaadd926f8a8e9cc6ee684b3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_004.png" -dest_files=["res://.godot/imported/cactus_004.png-622109ebbaadd926f8a8e9cc6ee684b3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_005.png b/library/thumbs/cactus_005.png deleted file mode 100644 index ffec729..0000000 Binary files a/library/thumbs/cactus_005.png and /dev/null differ diff --git a/library/thumbs/cactus_005.png.import b/library/thumbs/cactus_005.png.import deleted file mode 100644 index e2ca8aa..0000000 --- a/library/thumbs/cactus_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bedpnfe5jg3j7" -path="res://.godot/imported/cactus_005.png-f76ac7c67bae0a4815787eb86e291b71.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_005.png" -dest_files=["res://.godot/imported/cactus_005.png-f76ac7c67bae0a4815787eb86e291b71.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_006.png b/library/thumbs/cactus_006.png deleted file mode 100644 index 064342e..0000000 Binary files a/library/thumbs/cactus_006.png and /dev/null differ diff --git a/library/thumbs/cactus_006.png.import b/library/thumbs/cactus_006.png.import deleted file mode 100644 index 3f5fe78..0000000 --- a/library/thumbs/cactus_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cg8x33vcnux8v" -path="res://.godot/imported/cactus_006.png-b84f9762fd6bbe11b2291b5141f2a99c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_006.png" -dest_files=["res://.godot/imported/cactus_006.png-b84f9762fd6bbe11b2291b5141f2a99c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_007.png b/library/thumbs/cactus_007.png deleted file mode 100644 index fbb3074..0000000 Binary files a/library/thumbs/cactus_007.png and /dev/null differ diff --git a/library/thumbs/cactus_007.png.import b/library/thumbs/cactus_007.png.import deleted file mode 100644 index 9ded1e5..0000000 --- a/library/thumbs/cactus_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://lh3s5sksx31v" -path="res://.godot/imported/cactus_007.png-2feb613362e8ebf64227022dbcffcfb4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_007.png" -dest_files=["res://.godot/imported/cactus_007.png-2feb613362e8ebf64227022dbcffcfb4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_008.png b/library/thumbs/cactus_008.png deleted file mode 100644 index 2a86b7f..0000000 Binary files a/library/thumbs/cactus_008.png and /dev/null differ diff --git a/library/thumbs/cactus_008.png.import b/library/thumbs/cactus_008.png.import deleted file mode 100644 index 465aaa1..0000000 --- a/library/thumbs/cactus_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://brdj5ti0abs86" -path="res://.godot/imported/cactus_008.png-9a596b44a0b983d134a316a9aaaff84b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_008.png" -dest_files=["res://.godot/imported/cactus_008.png-9a596b44a0b983d134a316a9aaaff84b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_009.png b/library/thumbs/cactus_009.png deleted file mode 100644 index 7ef0227..0000000 Binary files a/library/thumbs/cactus_009.png and /dev/null differ diff --git a/library/thumbs/cactus_009.png.import b/library/thumbs/cactus_009.png.import deleted file mode 100644 index 5d03ce1..0000000 --- a/library/thumbs/cactus_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c2lg8rvrhc70n" -path="res://.godot/imported/cactus_009.png-f3c8c90a545e9638badbcd631538648a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_009.png" -dest_files=["res://.godot/imported/cactus_009.png-f3c8c90a545e9638badbcd631538648a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_010.png b/library/thumbs/cactus_010.png deleted file mode 100644 index a709ad9..0000000 Binary files a/library/thumbs/cactus_010.png and /dev/null differ diff --git a/library/thumbs/cactus_010.png.import b/library/thumbs/cactus_010.png.import deleted file mode 100644 index 44fbeb5..0000000 --- a/library/thumbs/cactus_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://4x6us402quml" -path="res://.godot/imported/cactus_010.png-110dcd70d75d5a14dcdda8034e1489b2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_010.png" -dest_files=["res://.godot/imported/cactus_010.png-110dcd70d75d5a14dcdda8034e1489b2.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_011.png b/library/thumbs/cactus_011.png deleted file mode 100644 index 506ff6d..0000000 Binary files a/library/thumbs/cactus_011.png and /dev/null differ diff --git a/library/thumbs/cactus_011.png.import b/library/thumbs/cactus_011.png.import deleted file mode 100644 index 81cdee4..0000000 --- a/library/thumbs/cactus_011.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d23nmj61bcjq6" -path="res://.godot/imported/cactus_011.png-17b73d85a2b1ee2b7485d8284dbf3e37.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_011.png" -dest_files=["res://.godot/imported/cactus_011.png-17b73d85a2b1ee2b7485d8284dbf3e37.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_012.png b/library/thumbs/cactus_012.png deleted file mode 100644 index 21423fe..0000000 Binary files a/library/thumbs/cactus_012.png and /dev/null differ diff --git a/library/thumbs/cactus_012.png.import b/library/thumbs/cactus_012.png.import deleted file mode 100644 index 95d4332..0000000 --- a/library/thumbs/cactus_012.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://buhs4733phpd" -path="res://.godot/imported/cactus_012.png-bfc84d581184432bb8b8332ee4ce21a1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_012.png" -dest_files=["res://.godot/imported/cactus_012.png-bfc84d581184432bb8b8332ee4ce21a1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_013.png b/library/thumbs/cactus_013.png deleted file mode 100644 index 4271fcd..0000000 Binary files a/library/thumbs/cactus_013.png and /dev/null differ diff --git a/library/thumbs/cactus_013.png.import b/library/thumbs/cactus_013.png.import deleted file mode 100644 index 7c43ee4..0000000 --- a/library/thumbs/cactus_013.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dp6fb8u33pyit" -path="res://.godot/imported/cactus_013.png-f62c695e6c86fdf7d7d245c5d36a76ee.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_013.png" -dest_files=["res://.godot/imported/cactus_013.png-f62c695e6c86fdf7d7d245c5d36a76ee.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_014.png b/library/thumbs/cactus_014.png deleted file mode 100644 index 45abb17..0000000 Binary files a/library/thumbs/cactus_014.png and /dev/null differ diff --git a/library/thumbs/cactus_014.png.import b/library/thumbs/cactus_014.png.import deleted file mode 100644 index 5a99dfe..0000000 --- a/library/thumbs/cactus_014.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cgkcadtfplqkl" -path="res://.godot/imported/cactus_014.png-84828cb1bd96d0e84f3bda3351c73fe2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_014.png" -dest_files=["res://.godot/imported/cactus_014.png-84828cb1bd96d0e84f3bda3351c73fe2.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cactus_015.png b/library/thumbs/cactus_015.png deleted file mode 100644 index 2abe908..0000000 Binary files a/library/thumbs/cactus_015.png and /dev/null differ diff --git a/library/thumbs/cactus_015.png.import b/library/thumbs/cactus_015.png.import deleted file mode 100644 index 1d210b2..0000000 --- a/library/thumbs/cactus_015.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b6myrk0su04vp" -path="res://.godot/imported/cactus_015.png-ba018b7464c50ca37758c835d3b0d304.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cactus_015.png" -dest_files=["res://.godot/imported/cactus_015.png-ba018b7464c50ca37758c835d3b0d304.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cart_001.png b/library/thumbs/cart_001.png deleted file mode 100644 index 7d9023a..0000000 Binary files a/library/thumbs/cart_001.png and /dev/null differ diff --git a/library/thumbs/cart_001.png.import b/library/thumbs/cart_001.png.import deleted file mode 100644 index 96c9ac9..0000000 --- a/library/thumbs/cart_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cmx3er8wpq4qq" -path="res://.godot/imported/cart_001.png-a2bfe5035a63151cc33219b259883cd7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cart_001.png" -dest_files=["res://.godot/imported/cart_001.png-a2bfe5035a63151cc33219b259883cd7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/checkpoint_001.png b/library/thumbs/checkpoint_001.png deleted file mode 100644 index 5a8ef88..0000000 Binary files a/library/thumbs/checkpoint_001.png and /dev/null differ diff --git a/library/thumbs/checkpoint_001.png.import b/library/thumbs/checkpoint_001.png.import deleted file mode 100644 index 2e9d49c..0000000 --- a/library/thumbs/checkpoint_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cy2em5lkr3a0x" -path="res://.godot/imported/checkpoint_001.png-37bed8b3aca940f550540e9eecf7e6c3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/checkpoint_001.png" -dest_files=["res://.godot/imported/checkpoint_001.png-37bed8b3aca940f550540e9eecf7e6c3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cistern_001.png b/library/thumbs/cistern_001.png deleted file mode 100644 index 2acb3d2..0000000 Binary files a/library/thumbs/cistern_001.png and /dev/null differ diff --git a/library/thumbs/cistern_001.png.import b/library/thumbs/cistern_001.png.import deleted file mode 100644 index 99fd11e..0000000 --- a/library/thumbs/cistern_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dn2k5xiv5c5n8" -path="res://.godot/imported/cistern_001.png-54cfb0b8bf7dd74ff512ce73962f4ad6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cistern_001.png" -dest_files=["res://.godot/imported/cistern_001.png-54cfb0b8bf7dd74ff512ce73962f4ad6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cistern_002.png b/library/thumbs/cistern_002.png deleted file mode 100644 index 6c8741c..0000000 Binary files a/library/thumbs/cistern_002.png and /dev/null differ diff --git a/library/thumbs/cistern_002.png.import b/library/thumbs/cistern_002.png.import deleted file mode 100644 index cc97d49..0000000 --- a/library/thumbs/cistern_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://0h16f3gjgeso" -path="res://.godot/imported/cistern_002.png-84f30b05975ba91f4027e6134d3fc065.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cistern_002.png" -dest_files=["res://.godot/imported/cistern_002.png-84f30b05975ba91f4027e6134d3fc065.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cistern_003.png b/library/thumbs/cistern_003.png deleted file mode 100644 index 875e22d..0000000 Binary files a/library/thumbs/cistern_003.png and /dev/null differ diff --git a/library/thumbs/cistern_003.png.import b/library/thumbs/cistern_003.png.import deleted file mode 100644 index f0ad3e3..0000000 --- a/library/thumbs/cistern_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bdii624lhc7on" -path="res://.godot/imported/cistern_003.png-34e2961a2a81c44a513547a21b2046ad.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cistern_003.png" -dest_files=["res://.godot/imported/cistern_003.png-34e2961a2a81c44a513547a21b2046ad.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/cistern_004.png b/library/thumbs/cistern_004.png deleted file mode 100644 index 9689bf6..0000000 Binary files a/library/thumbs/cistern_004.png and /dev/null differ diff --git a/library/thumbs/cistern_004.png.import b/library/thumbs/cistern_004.png.import deleted file mode 100644 index 7c1d802..0000000 --- a/library/thumbs/cistern_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://sl043fjou35j" -path="res://.godot/imported/cistern_004.png-8d0890e39d84d3d26a62d91c16863fef.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/cistern_004.png" -dest_files=["res://.godot/imported/cistern_004.png-8d0890e39d84d3d26a62d91c16863fef.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/coil_001.png b/library/thumbs/coil_001.png deleted file mode 100644 index 7173f85..0000000 Binary files a/library/thumbs/coil_001.png and /dev/null differ diff --git a/library/thumbs/coil_001.png.import b/library/thumbs/coil_001.png.import deleted file mode 100644 index ec62c26..0000000 --- a/library/thumbs/coil_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://drouenbewaov" -path="res://.godot/imported/coil_001.png-bff111ba3d9ab37d9ad8042a31016ab1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/coil_001.png" -dest_files=["res://.godot/imported/coil_001.png-bff111ba3d9ab37d9ad8042a31016ab1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/concrete_wall_001.png b/library/thumbs/concrete_wall_001.png deleted file mode 100644 index d97369c..0000000 Binary files a/library/thumbs/concrete_wall_001.png and /dev/null differ diff --git a/library/thumbs/concrete_wall_001.png.import b/library/thumbs/concrete_wall_001.png.import deleted file mode 100644 index 1f8bdb2..0000000 --- a/library/thumbs/concrete_wall_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dw7neaaf768e5" -path="res://.godot/imported/concrete_wall_001.png-cda17ee8c586c3a991b6aaca3754d9f2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/concrete_wall_001.png" -dest_files=["res://.godot/imported/concrete_wall_001.png-cda17ee8c586c3a991b6aaca3754d9f2.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/concrete_wall_002.png b/library/thumbs/concrete_wall_002.png deleted file mode 100644 index 3673415..0000000 Binary files a/library/thumbs/concrete_wall_002.png and /dev/null differ diff --git a/library/thumbs/concrete_wall_002.png.import b/library/thumbs/concrete_wall_002.png.import deleted file mode 100644 index fd691df..0000000 --- a/library/thumbs/concrete_wall_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bxxeanim6i2j6" -path="res://.godot/imported/concrete_wall_002.png-979a60a3e766d7d69d8254f0e9b56a6c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/concrete_wall_002.png" -dest_files=["res://.godot/imported/concrete_wall_002.png-979a60a3e766d7d69d8254f0e9b56a6c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/concrete_wall_destroyed_001.png b/library/thumbs/concrete_wall_destroyed_001.png deleted file mode 100644 index 9201564..0000000 Binary files a/library/thumbs/concrete_wall_destroyed_001.png and /dev/null differ diff --git a/library/thumbs/concrete_wall_destroyed_001.png.import b/library/thumbs/concrete_wall_destroyed_001.png.import deleted file mode 100644 index b6ab5e5..0000000 --- a/library/thumbs/concrete_wall_destroyed_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b8wtbri6f8hp7" -path="res://.godot/imported/concrete_wall_destroyed_001.png-d0ea3525a3718e130a2a5568bf89a43b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/concrete_wall_destroyed_001.png" -dest_files=["res://.godot/imported/concrete_wall_destroyed_001.png-d0ea3525a3718e130a2a5568bf89a43b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/concrete_wall_destroyed_002.png b/library/thumbs/concrete_wall_destroyed_002.png deleted file mode 100644 index a0d57dd..0000000 Binary files a/library/thumbs/concrete_wall_destroyed_002.png and /dev/null differ diff --git a/library/thumbs/concrete_wall_destroyed_002.png.import b/library/thumbs/concrete_wall_destroyed_002.png.import deleted file mode 100644 index 970c6a4..0000000 --- a/library/thumbs/concrete_wall_destroyed_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dxylpd18bexn5" -path="res://.godot/imported/concrete_wall_destroyed_002.png-50f11137c894029f63b41af4305374b4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/concrete_wall_destroyed_002.png" -dest_files=["res://.godot/imported/concrete_wall_destroyed_002.png-50f11137c894029f63b41af4305374b4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/concrete_wall_destroyed_003.png b/library/thumbs/concrete_wall_destroyed_003.png deleted file mode 100644 index 11081dd..0000000 Binary files a/library/thumbs/concrete_wall_destroyed_003.png and /dev/null differ diff --git a/library/thumbs/concrete_wall_destroyed_003.png.import b/library/thumbs/concrete_wall_destroyed_003.png.import deleted file mode 100644 index 1c63aae..0000000 --- a/library/thumbs/concrete_wall_destroyed_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://n41mrea0dnoc" -path="res://.godot/imported/concrete_wall_destroyed_003.png-b211f68e8f6b60dd7cdd2a8058122d3f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/concrete_wall_destroyed_003.png" -dest_files=["res://.godot/imported/concrete_wall_destroyed_003.png-b211f68e8f6b60dd7cdd2a8058122d3f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/concrete_wall_destroyed_004.png b/library/thumbs/concrete_wall_destroyed_004.png deleted file mode 100644 index e48098d..0000000 Binary files a/library/thumbs/concrete_wall_destroyed_004.png and /dev/null differ diff --git a/library/thumbs/concrete_wall_destroyed_004.png.import b/library/thumbs/concrete_wall_destroyed_004.png.import deleted file mode 100644 index 8b3bfea..0000000 --- a/library/thumbs/concrete_wall_destroyed_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://tua01wiox5nv" -path="res://.godot/imported/concrete_wall_destroyed_004.png-5848e14866db3c180f01e738008adcc3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/concrete_wall_destroyed_004.png" -dest_files=["res://.godot/imported/concrete_wall_destroyed_004.png-5848e14866db3c180f01e738008adcc3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/conditioner_001.png b/library/thumbs/conditioner_001.png deleted file mode 100644 index dd61a9e..0000000 Binary files a/library/thumbs/conditioner_001.png and /dev/null differ diff --git a/library/thumbs/conditioner_001.png.import b/library/thumbs/conditioner_001.png.import deleted file mode 100644 index 2c83d54..0000000 --- a/library/thumbs/conditioner_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bjwonhrlw4nsu" -path="res://.godot/imported/conditioner_001.png-3dc9a3709a07992a90584df4fca72dc6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/conditioner_001.png" -dest_files=["res://.godot/imported/conditioner_001.png-3dc9a3709a07992a90584df4fca72dc6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/conditioner_002.png b/library/thumbs/conditioner_002.png deleted file mode 100644 index 6fdc2f8..0000000 Binary files a/library/thumbs/conditioner_002.png and /dev/null differ diff --git a/library/thumbs/conditioner_002.png.import b/library/thumbs/conditioner_002.png.import deleted file mode 100644 index 4461639..0000000 --- a/library/thumbs/conditioner_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://5oj0uarsfby" -path="res://.godot/imported/conditioner_002.png-f2f9601acfdf91ae6b805dd446f50d17.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/conditioner_002.png" -dest_files=["res://.godot/imported/conditioner_002.png-f2f9601acfdf91ae6b805dd446f50d17.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/construction_001.png b/library/thumbs/construction_001.png deleted file mode 100644 index f88ced7..0000000 Binary files a/library/thumbs/construction_001.png and /dev/null differ diff --git a/library/thumbs/construction_001.png.import b/library/thumbs/construction_001.png.import deleted file mode 100644 index 375309d..0000000 --- a/library/thumbs/construction_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bw11b0cqn1ju7" -path="res://.godot/imported/construction_001.png-16a5954fc035a641cc3ec6765f573545.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/construction_001.png" -dest_files=["res://.godot/imported/construction_001.png-16a5954fc035a641cc3ec6765f573545.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/construction_002.png b/library/thumbs/construction_002.png deleted file mode 100644 index 4af02ed..0000000 Binary files a/library/thumbs/construction_002.png and /dev/null differ diff --git a/library/thumbs/construction_002.png.import b/library/thumbs/construction_002.png.import deleted file mode 100644 index f7110c9..0000000 --- a/library/thumbs/construction_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dbly31kixa54d" -path="res://.godot/imported/construction_002.png-4df30dd083c163d742cc75d9cfdf01db.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/construction_002.png" -dest_files=["res://.godot/imported/construction_002.png-4df30dd083c163d742cc75d9cfdf01db.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_001.png b/library/thumbs/container_001.png deleted file mode 100644 index a30b6e0..0000000 Binary files a/library/thumbs/container_001.png and /dev/null differ diff --git a/library/thumbs/container_001.png.import b/library/thumbs/container_001.png.import deleted file mode 100644 index 651dbfa..0000000 --- a/library/thumbs/container_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cfk3n0s55m3ik" -path="res://.godot/imported/container_001.png-8bf19bad436e9d6d6588e5ff64cc78be.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_001.png" -dest_files=["res://.godot/imported/container_001.png-8bf19bad436e9d6d6588e5ff64cc78be.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_001_offen1.png b/library/thumbs/container_001_offen1.png deleted file mode 100644 index 0a62d42..0000000 Binary files a/library/thumbs/container_001_offen1.png and /dev/null differ diff --git a/library/thumbs/container_001_offen1.png.import b/library/thumbs/container_001_offen1.png.import deleted file mode 100644 index 7945369..0000000 --- a/library/thumbs/container_001_offen1.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://btjpsdieswfhj" -path="res://.godot/imported/container_001_offen1.png-725108fda9fc4bae4e75d8737617f24a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_001_offen1.png" -dest_files=["res://.godot/imported/container_001_offen1.png-725108fda9fc4bae4e75d8737617f24a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_001_offen2.png b/library/thumbs/container_001_offen2.png deleted file mode 100644 index 5c30fb4..0000000 Binary files a/library/thumbs/container_001_offen2.png and /dev/null differ diff --git a/library/thumbs/container_001_offen2.png.import b/library/thumbs/container_001_offen2.png.import deleted file mode 100644 index 3255244..0000000 --- a/library/thumbs/container_001_offen2.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bngbmgxfh4ft7" -path="res://.godot/imported/container_001_offen2.png-ac048e0498e6a7edec41677c95acbe22.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_001_offen2.png" -dest_files=["res://.godot/imported/container_001_offen2.png-ac048e0498e6a7edec41677c95acbe22.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_001_ohne.png b/library/thumbs/container_001_ohne.png deleted file mode 100644 index b41182d..0000000 Binary files a/library/thumbs/container_001_ohne.png and /dev/null differ diff --git a/library/thumbs/container_001_ohne.png.import b/library/thumbs/container_001_ohne.png.import deleted file mode 100644 index e811142..0000000 --- a/library/thumbs/container_001_ohne.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cgdt3h13rqdug" -path="res://.godot/imported/container_001_ohne.png-e8a4d4481a3212fe1399f5abe48dc49f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_001_ohne.png" -dest_files=["res://.godot/imported/container_001_ohne.png-e8a4d4481a3212fe1399f5abe48dc49f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_002.png b/library/thumbs/container_002.png deleted file mode 100644 index 08ccfc2..0000000 Binary files a/library/thumbs/container_002.png and /dev/null differ diff --git a/library/thumbs/container_002.png.import b/library/thumbs/container_002.png.import deleted file mode 100644 index 9ee6f82..0000000 --- a/library/thumbs/container_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bendte7uy1vum" -path="res://.godot/imported/container_002.png-a722ed2bcb596ea12b1c07f3328cac92.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_002.png" -dest_files=["res://.godot/imported/container_002.png-a722ed2bcb596ea12b1c07f3328cac92.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_002_offen1.png b/library/thumbs/container_002_offen1.png deleted file mode 100644 index 6dd2d11..0000000 Binary files a/library/thumbs/container_002_offen1.png and /dev/null differ diff --git a/library/thumbs/container_002_offen1.png.import b/library/thumbs/container_002_offen1.png.import deleted file mode 100644 index 97f2faf..0000000 --- a/library/thumbs/container_002_offen1.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://chcsxajuvgspk" -path="res://.godot/imported/container_002_offen1.png-61a1ea8088ec6a0d737e55e04ef9603d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_002_offen1.png" -dest_files=["res://.godot/imported/container_002_offen1.png-61a1ea8088ec6a0d737e55e04ef9603d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_002_offen2.png b/library/thumbs/container_002_offen2.png deleted file mode 100644 index ed51212..0000000 Binary files a/library/thumbs/container_002_offen2.png and /dev/null differ diff --git a/library/thumbs/container_002_offen2.png.import b/library/thumbs/container_002_offen2.png.import deleted file mode 100644 index 4ffab38..0000000 --- a/library/thumbs/container_002_offen2.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dw56ic7fws26" -path="res://.godot/imported/container_002_offen2.png-15b6d9bade0ee7bc41522048722c4faa.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_002_offen2.png" -dest_files=["res://.godot/imported/container_002_offen2.png-15b6d9bade0ee7bc41522048722c4faa.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_002_ohne.png b/library/thumbs/container_002_ohne.png deleted file mode 100644 index 4a8ef89..0000000 Binary files a/library/thumbs/container_002_ohne.png and /dev/null differ diff --git a/library/thumbs/container_002_ohne.png.import b/library/thumbs/container_002_ohne.png.import deleted file mode 100644 index 55426ca..0000000 --- a/library/thumbs/container_002_ohne.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dwc0jmnhnch4k" -path="res://.godot/imported/container_002_ohne.png-31e74fa68f10023ca6e8312f3b689d2c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_002_ohne.png" -dest_files=["res://.godot/imported/container_002_ohne.png-31e74fa68f10023ca6e8312f3b689d2c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_003.png b/library/thumbs/container_003.png deleted file mode 100644 index 6a0794e..0000000 Binary files a/library/thumbs/container_003.png and /dev/null differ diff --git a/library/thumbs/container_003.png.import b/library/thumbs/container_003.png.import deleted file mode 100644 index ce5b574..0000000 --- a/library/thumbs/container_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dupngc2xv7it8" -path="res://.godot/imported/container_003.png-8e71cac16092f8b115b801fd094ee53e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_003.png" -dest_files=["res://.godot/imported/container_003.png-8e71cac16092f8b115b801fd094ee53e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_003_offen1.png b/library/thumbs/container_003_offen1.png deleted file mode 100644 index 12b3fc5..0000000 Binary files a/library/thumbs/container_003_offen1.png and /dev/null differ diff --git a/library/thumbs/container_003_offen1.png.import b/library/thumbs/container_003_offen1.png.import deleted file mode 100644 index a1d9c6d..0000000 --- a/library/thumbs/container_003_offen1.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dprnj64lwdete" -path="res://.godot/imported/container_003_offen1.png-8d5eab9b669b706ea4aa37ad53c4ba95.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_003_offen1.png" -dest_files=["res://.godot/imported/container_003_offen1.png-8d5eab9b669b706ea4aa37ad53c4ba95.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_003_offen2.png b/library/thumbs/container_003_offen2.png deleted file mode 100644 index 6a3b777..0000000 Binary files a/library/thumbs/container_003_offen2.png and /dev/null differ diff --git a/library/thumbs/container_003_offen2.png.import b/library/thumbs/container_003_offen2.png.import deleted file mode 100644 index ddb6640..0000000 --- a/library/thumbs/container_003_offen2.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c2kpdcvfpfapd" -path="res://.godot/imported/container_003_offen2.png-7c9deb6f88b261c0b4aecf35b01f8314.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_003_offen2.png" -dest_files=["res://.godot/imported/container_003_offen2.png-7c9deb6f88b261c0b4aecf35b01f8314.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_003_ohne.png b/library/thumbs/container_003_ohne.png deleted file mode 100644 index c4fb612..0000000 Binary files a/library/thumbs/container_003_ohne.png and /dev/null differ diff --git a/library/thumbs/container_003_ohne.png.import b/library/thumbs/container_003_ohne.png.import deleted file mode 100644 index ebeee07..0000000 --- a/library/thumbs/container_003_ohne.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://df4oqdfkq2odt" -path="res://.godot/imported/container_003_ohne.png-22a7100a50dcef57430f90c79791e125.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_003_ohne.png" -dest_files=["res://.godot/imported/container_003_ohne.png-22a7100a50dcef57430f90c79791e125.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_004.png b/library/thumbs/container_004.png deleted file mode 100644 index b786200..0000000 Binary files a/library/thumbs/container_004.png and /dev/null differ diff --git a/library/thumbs/container_004.png.import b/library/thumbs/container_004.png.import deleted file mode 100644 index 6db70e6..0000000 --- a/library/thumbs/container_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dx6067mlj6jdc" -path="res://.godot/imported/container_004.png-b64686f0d94fc9085c5c0aa547d48baa.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_004.png" -dest_files=["res://.godot/imported/container_004.png-b64686f0d94fc9085c5c0aa547d48baa.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_004_offen1.png b/library/thumbs/container_004_offen1.png deleted file mode 100644 index eb88c8c..0000000 Binary files a/library/thumbs/container_004_offen1.png and /dev/null differ diff --git a/library/thumbs/container_004_offen1.png.import b/library/thumbs/container_004_offen1.png.import deleted file mode 100644 index 2c88928..0000000 --- a/library/thumbs/container_004_offen1.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ij0up66wkdei" -path="res://.godot/imported/container_004_offen1.png-06087770f1b66fc9590ac9dfceebe7a6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_004_offen1.png" -dest_files=["res://.godot/imported/container_004_offen1.png-06087770f1b66fc9590ac9dfceebe7a6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_004_offen2.png b/library/thumbs/container_004_offen2.png deleted file mode 100644 index 2ba16d1..0000000 Binary files a/library/thumbs/container_004_offen2.png and /dev/null differ diff --git a/library/thumbs/container_004_offen2.png.import b/library/thumbs/container_004_offen2.png.import deleted file mode 100644 index bf936ee..0000000 --- a/library/thumbs/container_004_offen2.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://6so0720te2wu" -path="res://.godot/imported/container_004_offen2.png-ae6f991a964a2789eb52bbdca8dc99d9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_004_offen2.png" -dest_files=["res://.godot/imported/container_004_offen2.png-ae6f991a964a2789eb52bbdca8dc99d9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_004_ohne.png b/library/thumbs/container_004_ohne.png deleted file mode 100644 index 08f658d..0000000 Binary files a/library/thumbs/container_004_ohne.png and /dev/null differ diff --git a/library/thumbs/container_004_ohne.png.import b/library/thumbs/container_004_ohne.png.import deleted file mode 100644 index 7d66069..0000000 --- a/library/thumbs/container_004_ohne.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://0g2gmbbh2ltg" -path="res://.godot/imported/container_004_ohne.png-5fbe39a60bd4f74e4a899e22aaec7052.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_004_ohne.png" -dest_files=["res://.godot/imported/container_004_ohne.png-5fbe39a60bd4f74e4a899e22aaec7052.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_005.png b/library/thumbs/container_005.png deleted file mode 100644 index ac22293..0000000 Binary files a/library/thumbs/container_005.png and /dev/null differ diff --git a/library/thumbs/container_005.png.import b/library/thumbs/container_005.png.import deleted file mode 100644 index 5df3d94..0000000 --- a/library/thumbs/container_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bf57o5pnj355e" -path="res://.godot/imported/container_005.png-4f4de2a8131876e78f34401f38877c7a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_005.png" -dest_files=["res://.godot/imported/container_005.png-4f4de2a8131876e78f34401f38877c7a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_005_offen1.png b/library/thumbs/container_005_offen1.png deleted file mode 100644 index 9ae7891..0000000 Binary files a/library/thumbs/container_005_offen1.png and /dev/null differ diff --git a/library/thumbs/container_005_offen1.png.import b/library/thumbs/container_005_offen1.png.import deleted file mode 100644 index 598f534..0000000 --- a/library/thumbs/container_005_offen1.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b05yavnc71m3q" -path="res://.godot/imported/container_005_offen1.png-8690fc5534a36230b3eed962443bff34.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_005_offen1.png" -dest_files=["res://.godot/imported/container_005_offen1.png-8690fc5534a36230b3eed962443bff34.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_005_offen2.png b/library/thumbs/container_005_offen2.png deleted file mode 100644 index 857abc2..0000000 Binary files a/library/thumbs/container_005_offen2.png and /dev/null differ diff --git a/library/thumbs/container_005_offen2.png.import b/library/thumbs/container_005_offen2.png.import deleted file mode 100644 index 9611deb..0000000 --- a/library/thumbs/container_005_offen2.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b7sjub4cbkxvg" -path="res://.godot/imported/container_005_offen2.png-e489310c39c72eae0567321deb8ea3cf.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_005_offen2.png" -dest_files=["res://.godot/imported/container_005_offen2.png-e489310c39c72eae0567321deb8ea3cf.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_005_ohne.png b/library/thumbs/container_005_ohne.png deleted file mode 100644 index 9058d09..0000000 Binary files a/library/thumbs/container_005_ohne.png and /dev/null differ diff --git a/library/thumbs/container_005_ohne.png.import b/library/thumbs/container_005_ohne.png.import deleted file mode 100644 index a9ca61a..0000000 --- a/library/thumbs/container_005_ohne.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bnsu2xyjabygv" -path="res://.godot/imported/container_005_ohne.png-cca3bca3fe3c4fb400950a1c006ccd92.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_005_ohne.png" -dest_files=["res://.godot/imported/container_005_ohne.png-cca3bca3fe3c4fb400950a1c006ccd92.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_006.png b/library/thumbs/container_006.png deleted file mode 100644 index 2d3fdba..0000000 Binary files a/library/thumbs/container_006.png and /dev/null differ diff --git a/library/thumbs/container_006.png.import b/library/thumbs/container_006.png.import deleted file mode 100644 index 193266b..0000000 --- a/library/thumbs/container_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://gub8lvdvu8ig" -path="res://.godot/imported/container_006.png-3c1e5e6a379105a7a4b0cabe5ef38940.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_006.png" -dest_files=["res://.godot/imported/container_006.png-3c1e5e6a379105a7a4b0cabe5ef38940.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_006_offen1.png b/library/thumbs/container_006_offen1.png deleted file mode 100644 index dd29452..0000000 Binary files a/library/thumbs/container_006_offen1.png and /dev/null differ diff --git a/library/thumbs/container_006_offen1.png.import b/library/thumbs/container_006_offen1.png.import deleted file mode 100644 index 42dc471..0000000 --- a/library/thumbs/container_006_offen1.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bxxe0may3yeqc" -path="res://.godot/imported/container_006_offen1.png-e48ae560414dc7eaebdb9ab27cabffe5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_006_offen1.png" -dest_files=["res://.godot/imported/container_006_offen1.png-e48ae560414dc7eaebdb9ab27cabffe5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_006_offen2.png b/library/thumbs/container_006_offen2.png deleted file mode 100644 index bcff00a..0000000 Binary files a/library/thumbs/container_006_offen2.png and /dev/null differ diff --git a/library/thumbs/container_006_offen2.png.import b/library/thumbs/container_006_offen2.png.import deleted file mode 100644 index 72a0bdb..0000000 --- a/library/thumbs/container_006_offen2.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c4e8fd4t7r7m6" -path="res://.godot/imported/container_006_offen2.png-625b70d0d67725f796bf54ac92fca681.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_006_offen2.png" -dest_files=["res://.godot/imported/container_006_offen2.png-625b70d0d67725f796bf54ac92fca681.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_006_ohne.png b/library/thumbs/container_006_ohne.png deleted file mode 100644 index 332cd4c..0000000 Binary files a/library/thumbs/container_006_ohne.png and /dev/null differ diff --git a/library/thumbs/container_006_ohne.png.import b/library/thumbs/container_006_ohne.png.import deleted file mode 100644 index 43be22a..0000000 --- a/library/thumbs/container_006_ohne.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dhrrb85snu41i" -path="res://.godot/imported/container_006_ohne.png-7974c20bd4edf4927c656fe6fc90b81e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_006_ohne.png" -dest_files=["res://.godot/imported/container_006_ohne.png-7974c20bd4edf4927c656fe6fc90b81e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_007.png b/library/thumbs/container_007.png deleted file mode 100644 index 97ab265..0000000 Binary files a/library/thumbs/container_007.png and /dev/null differ diff --git a/library/thumbs/container_007.png.import b/library/thumbs/container_007.png.import deleted file mode 100644 index d52e21b..0000000 --- a/library/thumbs/container_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://csnvgkhlhmvwt" -path="res://.godot/imported/container_007.png-a3b38086b62d724e69e380c542022675.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_007.png" -dest_files=["res://.godot/imported/container_007.png-a3b38086b62d724e69e380c542022675.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_007_offen1.png b/library/thumbs/container_007_offen1.png deleted file mode 100644 index f3f4ece..0000000 Binary files a/library/thumbs/container_007_offen1.png and /dev/null differ diff --git a/library/thumbs/container_007_offen1.png.import b/library/thumbs/container_007_offen1.png.import deleted file mode 100644 index a01bf66..0000000 --- a/library/thumbs/container_007_offen1.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://denqy1bllro0l" -path="res://.godot/imported/container_007_offen1.png-e038946d3d569077182fe8624d8d0d02.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_007_offen1.png" -dest_files=["res://.godot/imported/container_007_offen1.png-e038946d3d569077182fe8624d8d0d02.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_007_offen2.png b/library/thumbs/container_007_offen2.png deleted file mode 100644 index a3c4733..0000000 Binary files a/library/thumbs/container_007_offen2.png and /dev/null differ diff --git a/library/thumbs/container_007_offen2.png.import b/library/thumbs/container_007_offen2.png.import deleted file mode 100644 index a814fd1..0000000 --- a/library/thumbs/container_007_offen2.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bqkr34vaxvy5c" -path="res://.godot/imported/container_007_offen2.png-ded39ed55a00a5b1688c26cad378b653.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_007_offen2.png" -dest_files=["res://.godot/imported/container_007_offen2.png-ded39ed55a00a5b1688c26cad378b653.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_007_ohne.png b/library/thumbs/container_007_ohne.png deleted file mode 100644 index 1d87d85..0000000 Binary files a/library/thumbs/container_007_ohne.png and /dev/null differ diff --git a/library/thumbs/container_007_ohne.png.import b/library/thumbs/container_007_ohne.png.import deleted file mode 100644 index 2c69561..0000000 --- a/library/thumbs/container_007_ohne.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bqm02u41bb737" -path="res://.godot/imported/container_007_ohne.png-bfcd83f47c7ec33ca986f3a5ca9daae9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_007_ohne.png" -dest_files=["res://.godot/imported/container_007_ohne.png-bfcd83f47c7ec33ca986f3a5ca9daae9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_008.png b/library/thumbs/container_008.png deleted file mode 100644 index 489e5d0..0000000 Binary files a/library/thumbs/container_008.png and /dev/null differ diff --git a/library/thumbs/container_008.png.import b/library/thumbs/container_008.png.import deleted file mode 100644 index 821e5bb..0000000 --- a/library/thumbs/container_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bsncqq2cfvjo4" -path="res://.godot/imported/container_008.png-7fba02e7b86a9baed57720df6aae0703.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_008.png" -dest_files=["res://.godot/imported/container_008.png-7fba02e7b86a9baed57720df6aae0703.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_008_offen1.png b/library/thumbs/container_008_offen1.png deleted file mode 100644 index 31d97f5..0000000 Binary files a/library/thumbs/container_008_offen1.png and /dev/null differ diff --git a/library/thumbs/container_008_offen1.png.import b/library/thumbs/container_008_offen1.png.import deleted file mode 100644 index fde932c..0000000 --- a/library/thumbs/container_008_offen1.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cbvq06me7e21h" -path="res://.godot/imported/container_008_offen1.png-3b36a26198ee2840738646efa562a9d7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_008_offen1.png" -dest_files=["res://.godot/imported/container_008_offen1.png-3b36a26198ee2840738646efa562a9d7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_008_offen2.png b/library/thumbs/container_008_offen2.png deleted file mode 100644 index 5d55a85..0000000 Binary files a/library/thumbs/container_008_offen2.png and /dev/null differ diff --git a/library/thumbs/container_008_offen2.png.import b/library/thumbs/container_008_offen2.png.import deleted file mode 100644 index f31c954..0000000 --- a/library/thumbs/container_008_offen2.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://i6qdinbukrrw" -path="res://.godot/imported/container_008_offen2.png-acbf05005956828cdbebad15f60ba922.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_008_offen2.png" -dest_files=["res://.godot/imported/container_008_offen2.png-acbf05005956828cdbebad15f60ba922.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/container_008_ohne.png b/library/thumbs/container_008_ohne.png deleted file mode 100644 index d9d4ce8..0000000 Binary files a/library/thumbs/container_008_ohne.png and /dev/null differ diff --git a/library/thumbs/container_008_ohne.png.import b/library/thumbs/container_008_ohne.png.import deleted file mode 100644 index 65c45a8..0000000 --- a/library/thumbs/container_008_ohne.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://yrbfa8pcdvlh" -path="res://.godot/imported/container_008_ohne.png-4b391d87bf6eb80cdc2265187e867d46.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/container_008_ohne.png" -dest_files=["res://.godot/imported/container_008_ohne.png-4b391d87bf6eb80cdc2265187e867d46.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_001.png b/library/thumbs/deadwood_001.png deleted file mode 100644 index dc27646..0000000 Binary files a/library/thumbs/deadwood_001.png and /dev/null differ diff --git a/library/thumbs/deadwood_001.png.import b/library/thumbs/deadwood_001.png.import deleted file mode 100644 index 829a90f..0000000 --- a/library/thumbs/deadwood_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://brb6m7wgu8dts" -path="res://.godot/imported/deadwood_001.png-f28c3c0c92269003bec26508e0b20668.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_001.png" -dest_files=["res://.godot/imported/deadwood_001.png-f28c3c0c92269003bec26508e0b20668.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_002.png b/library/thumbs/deadwood_002.png deleted file mode 100644 index fb3a0e7..0000000 Binary files a/library/thumbs/deadwood_002.png and /dev/null differ diff --git a/library/thumbs/deadwood_002.png.import b/library/thumbs/deadwood_002.png.import deleted file mode 100644 index cf13f3b..0000000 --- a/library/thumbs/deadwood_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c3sqh234ydke8" -path="res://.godot/imported/deadwood_002.png-cec0f90af7376c404a06bb78c23ebda3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_002.png" -dest_files=["res://.godot/imported/deadwood_002.png-cec0f90af7376c404a06bb78c23ebda3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_003.png b/library/thumbs/deadwood_003.png deleted file mode 100644 index 1acd41a..0000000 Binary files a/library/thumbs/deadwood_003.png and /dev/null differ diff --git a/library/thumbs/deadwood_003.png.import b/library/thumbs/deadwood_003.png.import deleted file mode 100644 index cb36593..0000000 --- a/library/thumbs/deadwood_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://x57sc4my1wy2" -path="res://.godot/imported/deadwood_003.png-4be618655e160aec86af87940831a8a7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_003.png" -dest_files=["res://.godot/imported/deadwood_003.png-4be618655e160aec86af87940831a8a7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_004.png b/library/thumbs/deadwood_004.png deleted file mode 100644 index ae2bb48..0000000 Binary files a/library/thumbs/deadwood_004.png and /dev/null differ diff --git a/library/thumbs/deadwood_004.png.import b/library/thumbs/deadwood_004.png.import deleted file mode 100644 index 634f306..0000000 --- a/library/thumbs/deadwood_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://duw8nsvr05otv" -path="res://.godot/imported/deadwood_004.png-805bbe6c31c6d49016ad18abe73f9a97.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_004.png" -dest_files=["res://.godot/imported/deadwood_004.png-805bbe6c31c6d49016ad18abe73f9a97.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_005.png b/library/thumbs/deadwood_005.png deleted file mode 100644 index 814e2a0..0000000 Binary files a/library/thumbs/deadwood_005.png and /dev/null differ diff --git a/library/thumbs/deadwood_005.png.import b/library/thumbs/deadwood_005.png.import deleted file mode 100644 index 8ee0018..0000000 --- a/library/thumbs/deadwood_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://coiwt4gpm0y3m" -path="res://.godot/imported/deadwood_005.png-bf7123c4da741b43de939b722c45523a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_005.png" -dest_files=["res://.godot/imported/deadwood_005.png-bf7123c4da741b43de939b722c45523a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_006.png b/library/thumbs/deadwood_006.png deleted file mode 100644 index 031293b..0000000 Binary files a/library/thumbs/deadwood_006.png and /dev/null differ diff --git a/library/thumbs/deadwood_006.png.import b/library/thumbs/deadwood_006.png.import deleted file mode 100644 index 22bd0bf..0000000 --- a/library/thumbs/deadwood_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dbl117rcr4wtl" -path="res://.godot/imported/deadwood_006.png-3071c4f7f3c819dd33e0c46edd978817.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_006.png" -dest_files=["res://.godot/imported/deadwood_006.png-3071c4f7f3c819dd33e0c46edd978817.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_007.png b/library/thumbs/deadwood_007.png deleted file mode 100644 index b3cfb4b..0000000 Binary files a/library/thumbs/deadwood_007.png and /dev/null differ diff --git a/library/thumbs/deadwood_007.png.import b/library/thumbs/deadwood_007.png.import deleted file mode 100644 index ab698b1..0000000 --- a/library/thumbs/deadwood_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://8epd0swcraef" -path="res://.godot/imported/deadwood_007.png-b486eba00371c647515c54de3ead67b9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_007.png" -dest_files=["res://.godot/imported/deadwood_007.png-b486eba00371c647515c54de3ead67b9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_008.png b/library/thumbs/deadwood_008.png deleted file mode 100644 index 8b319a0..0000000 Binary files a/library/thumbs/deadwood_008.png and /dev/null differ diff --git a/library/thumbs/deadwood_008.png.import b/library/thumbs/deadwood_008.png.import deleted file mode 100644 index 2d09bee..0000000 --- a/library/thumbs/deadwood_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://h16yvecq54xv" -path="res://.godot/imported/deadwood_008.png-2c4256f293f49578747e207b0598e2aa.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_008.png" -dest_files=["res://.godot/imported/deadwood_008.png-2c4256f293f49578747e207b0598e2aa.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_009.png b/library/thumbs/deadwood_009.png deleted file mode 100644 index a7160c1..0000000 Binary files a/library/thumbs/deadwood_009.png and /dev/null differ diff --git a/library/thumbs/deadwood_009.png.import b/library/thumbs/deadwood_009.png.import deleted file mode 100644 index 40e91ea..0000000 --- a/library/thumbs/deadwood_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bvh8c71joh4kt" -path="res://.godot/imported/deadwood_009.png-172bedab14e97224549ce1ea138bcc22.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_009.png" -dest_files=["res://.godot/imported/deadwood_009.png-172bedab14e97224549ce1ea138bcc22.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_010.png b/library/thumbs/deadwood_010.png deleted file mode 100644 index fd49f52..0000000 Binary files a/library/thumbs/deadwood_010.png and /dev/null differ diff --git a/library/thumbs/deadwood_010.png.import b/library/thumbs/deadwood_010.png.import deleted file mode 100644 index c4a9d21..0000000 --- a/library/thumbs/deadwood_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d3dd8hmm48f2u" -path="res://.godot/imported/deadwood_010.png-a4a0fbe79417b0c4c43f3883a8f90101.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_010.png" -dest_files=["res://.godot/imported/deadwood_010.png-a4a0fbe79417b0c4c43f3883a8f90101.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_011.png b/library/thumbs/deadwood_011.png deleted file mode 100644 index cf79597..0000000 Binary files a/library/thumbs/deadwood_011.png and /dev/null differ diff --git a/library/thumbs/deadwood_011.png.import b/library/thumbs/deadwood_011.png.import deleted file mode 100644 index 08a75ff..0000000 --- a/library/thumbs/deadwood_011.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cpgudb46fonl6" -path="res://.godot/imported/deadwood_011.png-9e34b11b130169051a78a21bfcfdc822.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_011.png" -dest_files=["res://.godot/imported/deadwood_011.png-9e34b11b130169051a78a21bfcfdc822.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_012.png b/library/thumbs/deadwood_012.png deleted file mode 100644 index 11352a4..0000000 Binary files a/library/thumbs/deadwood_012.png and /dev/null differ diff --git a/library/thumbs/deadwood_012.png.import b/library/thumbs/deadwood_012.png.import deleted file mode 100644 index e042230..0000000 --- a/library/thumbs/deadwood_012.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dfj3l6ryvbifx" -path="res://.godot/imported/deadwood_012.png-635f89d7c877e49214b4784479a35c3f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_012.png" -dest_files=["res://.godot/imported/deadwood_012.png-635f89d7c877e49214b4784479a35c3f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_013.png b/library/thumbs/deadwood_013.png deleted file mode 100644 index 501cfbe..0000000 Binary files a/library/thumbs/deadwood_013.png and /dev/null differ diff --git a/library/thumbs/deadwood_013.png.import b/library/thumbs/deadwood_013.png.import deleted file mode 100644 index 3ebb8a6..0000000 --- a/library/thumbs/deadwood_013.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b7efle2j6s4ap" -path="res://.godot/imported/deadwood_013.png-58f7af4217f66d31b974a9d5a31acf77.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_013.png" -dest_files=["res://.godot/imported/deadwood_013.png-58f7af4217f66d31b974a9d5a31acf77.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_016.png b/library/thumbs/deadwood_016.png deleted file mode 100644 index bcf3558..0000000 Binary files a/library/thumbs/deadwood_016.png and /dev/null differ diff --git a/library/thumbs/deadwood_016.png.import b/library/thumbs/deadwood_016.png.import deleted file mode 100644 index 2dfd54c..0000000 --- a/library/thumbs/deadwood_016.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://db4vsy75vwufd" -path="res://.godot/imported/deadwood_016.png-3c17df23501a769577dac84f67fb94ab.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_016.png" -dest_files=["res://.godot/imported/deadwood_016.png-3c17df23501a769577dac84f67fb94ab.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/deadwood_023.png b/library/thumbs/deadwood_023.png deleted file mode 100644 index 6a462f9..0000000 Binary files a/library/thumbs/deadwood_023.png and /dev/null differ diff --git a/library/thumbs/deadwood_023.png.import b/library/thumbs/deadwood_023.png.import deleted file mode 100644 index 4808f75..0000000 --- a/library/thumbs/deadwood_023.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ee1xpayr4wed" -path="res://.godot/imported/deadwood_023.png-6d1be86486a5cd5b5d632ec212616a32.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/deadwood_023.png" -dest_files=["res://.godot/imported/deadwood_023.png-6d1be86486a5cd5b5d632ec212616a32.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_001.png b/library/thumbs/decal_001.png deleted file mode 100644 index 4d75b55..0000000 Binary files a/library/thumbs/decal_001.png and /dev/null differ diff --git a/library/thumbs/decal_001.png.import b/library/thumbs/decal_001.png.import deleted file mode 100644 index 8d93b41..0000000 --- a/library/thumbs/decal_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c7lew1osrqr5r" -path="res://.godot/imported/decal_001.png-68af75e7d3b189a9b8f35077c0acc969.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_001.png" -dest_files=["res://.godot/imported/decal_001.png-68af75e7d3b189a9b8f35077c0acc969.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_002.png b/library/thumbs/decal_002.png deleted file mode 100644 index 68a4b05..0000000 Binary files a/library/thumbs/decal_002.png and /dev/null differ diff --git a/library/thumbs/decal_002.png.import b/library/thumbs/decal_002.png.import deleted file mode 100644 index 73edbe0..0000000 --- a/library/thumbs/decal_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://xqi68v0ratl5" -path="res://.godot/imported/decal_002.png-6e946a4d5f537563d71cf4dbb167dcbb.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_002.png" -dest_files=["res://.godot/imported/decal_002.png-6e946a4d5f537563d71cf4dbb167dcbb.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_003.png b/library/thumbs/decal_003.png deleted file mode 100644 index 54f9682..0000000 Binary files a/library/thumbs/decal_003.png and /dev/null differ diff --git a/library/thumbs/decal_003.png.import b/library/thumbs/decal_003.png.import deleted file mode 100644 index 10bebc5..0000000 --- a/library/thumbs/decal_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://pecgxgai7fs1" -path="res://.godot/imported/decal_003.png-0e9065b2b7b75f2e78b2f1c6272c220b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_003.png" -dest_files=["res://.godot/imported/decal_003.png-0e9065b2b7b75f2e78b2f1c6272c220b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_004.png b/library/thumbs/decal_004.png deleted file mode 100644 index 5ac3a01..0000000 Binary files a/library/thumbs/decal_004.png and /dev/null differ diff --git a/library/thumbs/decal_004.png.import b/library/thumbs/decal_004.png.import deleted file mode 100644 index 4ac5017..0000000 --- a/library/thumbs/decal_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://hjsxl3jr1hl5" -path="res://.godot/imported/decal_004.png-858e9176d35a41debf44faae6db109e3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_004.png" -dest_files=["res://.godot/imported/decal_004.png-858e9176d35a41debf44faae6db109e3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_005.png b/library/thumbs/decal_005.png deleted file mode 100644 index c288d78..0000000 Binary files a/library/thumbs/decal_005.png and /dev/null differ diff --git a/library/thumbs/decal_005.png.import b/library/thumbs/decal_005.png.import deleted file mode 100644 index 4fb9963..0000000 --- a/library/thumbs/decal_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dpycwrna8l1u" -path="res://.godot/imported/decal_005.png-bd96cf980efd50247e6c62ecc1f5f782.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_005.png" -dest_files=["res://.godot/imported/decal_005.png-bd96cf980efd50247e6c62ecc1f5f782.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_006.png b/library/thumbs/decal_006.png deleted file mode 100644 index 2957b45..0000000 Binary files a/library/thumbs/decal_006.png and /dev/null differ diff --git a/library/thumbs/decal_006.png.import b/library/thumbs/decal_006.png.import deleted file mode 100644 index d45debc..0000000 --- a/library/thumbs/decal_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b5vb3tdhktjcs" -path="res://.godot/imported/decal_006.png-50c01155f3daeaf3dcba442645f158cb.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_006.png" -dest_files=["res://.godot/imported/decal_006.png-50c01155f3daeaf3dcba442645f158cb.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_007.png b/library/thumbs/decal_007.png deleted file mode 100644 index 1d2c6bd..0000000 Binary files a/library/thumbs/decal_007.png and /dev/null differ diff --git a/library/thumbs/decal_007.png.import b/library/thumbs/decal_007.png.import deleted file mode 100644 index bfa1263..0000000 --- a/library/thumbs/decal_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bcjttf21fewn1" -path="res://.godot/imported/decal_007.png-5f7778d29e953b74e18890b08a49f549.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_007.png" -dest_files=["res://.godot/imported/decal_007.png-5f7778d29e953b74e18890b08a49f549.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_008.png b/library/thumbs/decal_008.png deleted file mode 100644 index 534e068..0000000 Binary files a/library/thumbs/decal_008.png and /dev/null differ diff --git a/library/thumbs/decal_008.png.import b/library/thumbs/decal_008.png.import deleted file mode 100644 index c13dacd..0000000 --- a/library/thumbs/decal_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://kl1dc8qqllob" -path="res://.godot/imported/decal_008.png-e16f368c5d752df29a8262449fbf8ef9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_008.png" -dest_files=["res://.godot/imported/decal_008.png-e16f368c5d752df29a8262449fbf8ef9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_009.png b/library/thumbs/decal_009.png deleted file mode 100644 index 6394f5c..0000000 Binary files a/library/thumbs/decal_009.png and /dev/null differ diff --git a/library/thumbs/decal_009.png.import b/library/thumbs/decal_009.png.import deleted file mode 100644 index 9955075..0000000 --- a/library/thumbs/decal_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://1tg6k788p7u4" -path="res://.godot/imported/decal_009.png-cc6008bb693478e50bc6ba24e12587ab.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_009.png" -dest_files=["res://.godot/imported/decal_009.png-cc6008bb693478e50bc6ba24e12587ab.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_010.png b/library/thumbs/decal_010.png deleted file mode 100644 index ea8a275..0000000 Binary files a/library/thumbs/decal_010.png and /dev/null differ diff --git a/library/thumbs/decal_010.png.import b/library/thumbs/decal_010.png.import deleted file mode 100644 index 4f61b8f..0000000 --- a/library/thumbs/decal_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ce82gtlto5kyu" -path="res://.godot/imported/decal_010.png-6d84f541f5018792f5c892e2609e9e01.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_010.png" -dest_files=["res://.godot/imported/decal_010.png-6d84f541f5018792f5c892e2609e9e01.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_011.png b/library/thumbs/decal_011.png deleted file mode 100644 index 1622aed..0000000 Binary files a/library/thumbs/decal_011.png and /dev/null differ diff --git a/library/thumbs/decal_011.png.import b/library/thumbs/decal_011.png.import deleted file mode 100644 index 5e2fd50..0000000 --- a/library/thumbs/decal_011.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://vx21uyfes5b5" -path="res://.godot/imported/decal_011.png-474cd535fcd041fc1a81343867ed0d3e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_011.png" -dest_files=["res://.godot/imported/decal_011.png-474cd535fcd041fc1a81343867ed0d3e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_012.png b/library/thumbs/decal_012.png deleted file mode 100644 index 11012bf..0000000 Binary files a/library/thumbs/decal_012.png and /dev/null differ diff --git a/library/thumbs/decal_012.png.import b/library/thumbs/decal_012.png.import deleted file mode 100644 index b95aa8e..0000000 --- a/library/thumbs/decal_012.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dut423cqtpll6" -path="res://.godot/imported/decal_012.png-7e7b204bd7d38ed9a5aa9dec9d0b9b1f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_012.png" -dest_files=["res://.godot/imported/decal_012.png-7e7b204bd7d38ed9a5aa9dec9d0b9b1f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_013.png b/library/thumbs/decal_013.png deleted file mode 100644 index 50f7f10..0000000 Binary files a/library/thumbs/decal_013.png and /dev/null differ diff --git a/library/thumbs/decal_013.png.import b/library/thumbs/decal_013.png.import deleted file mode 100644 index 3971a1d..0000000 --- a/library/thumbs/decal_013.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://l8a5euv86nnp" -path="res://.godot/imported/decal_013.png-d1d7f33771bae77f4d48612083713353.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_013.png" -dest_files=["res://.godot/imported/decal_013.png-d1d7f33771bae77f4d48612083713353.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/decal_014.png b/library/thumbs/decal_014.png deleted file mode 100644 index 2326e96..0000000 Binary files a/library/thumbs/decal_014.png and /dev/null differ diff --git a/library/thumbs/decal_014.png.import b/library/thumbs/decal_014.png.import deleted file mode 100644 index ff88793..0000000 --- a/library/thumbs/decal_014.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c28q30s5tbmpy" -path="res://.godot/imported/decal_014.png-23c17aec05e74b62e025628861fa7fad.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/decal_014.png" -dest_files=["res://.godot/imported/decal_014.png-23c17aec05e74b62e025628861fa7fad.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/door_001.png b/library/thumbs/door_001.png deleted file mode 100644 index 0e5bf19..0000000 Binary files a/library/thumbs/door_001.png and /dev/null differ diff --git a/library/thumbs/door_001.png.import b/library/thumbs/door_001.png.import deleted file mode 100644 index e72d681..0000000 --- a/library/thumbs/door_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://tr06b7hh5j2y" -path="res://.godot/imported/door_001.png-b8d425f237b80043934c6dea52020585.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/door_001.png" -dest_files=["res://.godot/imported/door_001.png-b8d425f237b80043934c6dea52020585.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/door_002.png b/library/thumbs/door_002.png deleted file mode 100644 index 73df013..0000000 Binary files a/library/thumbs/door_002.png and /dev/null differ diff --git a/library/thumbs/door_002.png.import b/library/thumbs/door_002.png.import deleted file mode 100644 index d3c7514..0000000 --- a/library/thumbs/door_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bwud8kkshrkff" -path="res://.godot/imported/door_002.png-49871e5d71846ceed8c7febd8b9f5c79.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/door_002.png" -dest_files=["res://.godot/imported/door_002.png-49871e5d71846ceed8c7febd8b9f5c79.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/door_003.png b/library/thumbs/door_003.png deleted file mode 100644 index 6b0ca0e..0000000 Binary files a/library/thumbs/door_003.png and /dev/null differ diff --git a/library/thumbs/door_003.png.import b/library/thumbs/door_003.png.import deleted file mode 100644 index 059484f..0000000 --- a/library/thumbs/door_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cqk4exg0hksc1" -path="res://.godot/imported/door_003.png-11d2cfc9619e70ab67b7c6ed8e645944.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/door_003.png" -dest_files=["res://.godot/imported/door_003.png-11d2cfc9619e70ab67b7c6ed8e645944.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/dune_010.png b/library/thumbs/dune_010.png deleted file mode 100644 index 7e09184..0000000 Binary files a/library/thumbs/dune_010.png and /dev/null differ diff --git a/library/thumbs/dune_010.png.import b/library/thumbs/dune_010.png.import deleted file mode 100644 index 1ee9da0..0000000 --- a/library/thumbs/dune_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://oavouedycf5f" -path="res://.godot/imported/dune_010.png-47ada087b2f72388133252dbd65d04b1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/dune_010.png" -dest_files=["res://.godot/imported/dune_010.png-47ada087b2f72388133252dbd65d04b1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/fence_001.png b/library/thumbs/fence_001.png deleted file mode 100644 index 50a32dd..0000000 Binary files a/library/thumbs/fence_001.png and /dev/null differ diff --git a/library/thumbs/fence_001.png.import b/library/thumbs/fence_001.png.import deleted file mode 100644 index a809c11..0000000 --- a/library/thumbs/fence_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bpa7plvahnvhp" -path="res://.godot/imported/fence_001.png-ec4e4f1b214c09cf1b143ed85cd504da.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/fence_001.png" -dest_files=["res://.godot/imported/fence_001.png-ec4e4f1b214c09cf1b143ed85cd504da.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/fence_002.png b/library/thumbs/fence_002.png deleted file mode 100644 index 4ba98f0..0000000 Binary files a/library/thumbs/fence_002.png and /dev/null differ diff --git a/library/thumbs/fence_002.png.import b/library/thumbs/fence_002.png.import deleted file mode 100644 index 87e1c91..0000000 --- a/library/thumbs/fence_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://42jlkxottfgg" -path="res://.godot/imported/fence_002.png-69777ba7859f7d985a5f6745d28d0cd4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/fence_002.png" -dest_files=["res://.godot/imported/fence_002.png-69777ba7859f7d985a5f6745d28d0cd4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/fighter_jet_001.png b/library/thumbs/fighter_jet_001.png deleted file mode 100644 index af43bd5..0000000 Binary files a/library/thumbs/fighter_jet_001.png and /dev/null differ diff --git a/library/thumbs/fighter_jet_001.png.import b/library/thumbs/fighter_jet_001.png.import deleted file mode 100644 index 8aaa944..0000000 --- a/library/thumbs/fighter_jet_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c1chndfgaoj8o" -path="res://.godot/imported/fighter_jet_001.png-684e5c4646d54d1915f19ed30028ecc9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/fighter_jet_001.png" -dest_files=["res://.godot/imported/fighter_jet_001.png-684e5c4646d54d1915f19ed30028ecc9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/fighter_jet_002.png b/library/thumbs/fighter_jet_002.png deleted file mode 100644 index 9a520df..0000000 Binary files a/library/thumbs/fighter_jet_002.png and /dev/null differ diff --git a/library/thumbs/fighter_jet_002.png.import b/library/thumbs/fighter_jet_002.png.import deleted file mode 100644 index 4bc89ec..0000000 --- a/library/thumbs/fighter_jet_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bwliah1ow4gv3" -path="res://.godot/imported/fighter_jet_002.png-cc56851a34fa8e09a76457f845d8ffce.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/fighter_jet_002.png" -dest_files=["res://.godot/imported/fighter_jet_002.png-cc56851a34fa8e09a76457f845d8ffce.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/fighter_jet_003.png b/library/thumbs/fighter_jet_003.png deleted file mode 100644 index 33d24b2..0000000 Binary files a/library/thumbs/fighter_jet_003.png and /dev/null differ diff --git a/library/thumbs/fighter_jet_003.png.import b/library/thumbs/fighter_jet_003.png.import deleted file mode 100644 index d26e819..0000000 --- a/library/thumbs/fighter_jet_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cqwfnx4vwnpvx" -path="res://.godot/imported/fighter_jet_003.png-ac6585bf4bc24f0c39e8a52826e61971.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/fighter_jet_003.png" -dest_files=["res://.godot/imported/fighter_jet_003.png-ac6585bf4bc24f0c39e8a52826e61971.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/fighter_jet_004.png b/library/thumbs/fighter_jet_004.png deleted file mode 100644 index d773f4b..0000000 Binary files a/library/thumbs/fighter_jet_004.png and /dev/null differ diff --git a/library/thumbs/fighter_jet_004.png.import b/library/thumbs/fighter_jet_004.png.import deleted file mode 100644 index 1f83985..0000000 --- a/library/thumbs/fighter_jet_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dj2kl8dhnogl" -path="res://.godot/imported/fighter_jet_004.png-4504fec326ed66f81b9b11f9545aafa7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/fighter_jet_004.png" -dest_files=["res://.godot/imported/fighter_jet_004.png-4504fec326ed66f81b9b11f9545aafa7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/flashlight_001.png b/library/thumbs/flashlight_001.png deleted file mode 100644 index 49ec57f..0000000 Binary files a/library/thumbs/flashlight_001.png and /dev/null differ diff --git a/library/thumbs/flashlight_001.png.import b/library/thumbs/flashlight_001.png.import deleted file mode 100644 index 691f827..0000000 --- a/library/thumbs/flashlight_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dfw2apb7qh6df" -path="res://.godot/imported/flashlight_001.png-0a0e31f8fb7fdd4ec1ba71870617801a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/flashlight_001.png" -dest_files=["res://.godot/imported/flashlight_001.png-0a0e31f8fb7fdd4ec1ba71870617801a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/flashlight_002.png b/library/thumbs/flashlight_002.png deleted file mode 100644 index 94f8f26..0000000 Binary files a/library/thumbs/flashlight_002.png and /dev/null differ diff --git a/library/thumbs/flashlight_002.png.import b/library/thumbs/flashlight_002.png.import deleted file mode 100644 index 1157624..0000000 --- a/library/thumbs/flashlight_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://csf16sblar7h2" -path="res://.godot/imported/flashlight_002.png-ba06f97bef57e4533db5acf3cfd463ed.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/flashlight_002.png" -dest_files=["res://.godot/imported/flashlight_002.png-ba06f97bef57e4533db5acf3cfd463ed.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/generator_001.png b/library/thumbs/generator_001.png deleted file mode 100644 index 454c4c3..0000000 Binary files a/library/thumbs/generator_001.png and /dev/null differ diff --git a/library/thumbs/generator_001.png.import b/library/thumbs/generator_001.png.import deleted file mode 100644 index f7973b1..0000000 --- a/library/thumbs/generator_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bhguehdkjm71i" -path="res://.godot/imported/generator_001.png-e0dda0415f29ad20657bbf9e4da09e82.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/generator_001.png" -dest_files=["res://.godot/imported/generator_001.png-e0dda0415f29ad20657bbf9e4da09e82.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/generator_002.png b/library/thumbs/generator_002.png deleted file mode 100644 index a2e4499..0000000 Binary files a/library/thumbs/generator_002.png and /dev/null differ diff --git a/library/thumbs/generator_002.png.import b/library/thumbs/generator_002.png.import deleted file mode 100644 index d80ed18..0000000 --- a/library/thumbs/generator_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cc0fl2o0fwa1i" -path="res://.godot/imported/generator_002.png-b2f80d2862a71660c2c96604603bb9f7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/generator_002.png" -dest_files=["res://.godot/imported/generator_002.png-b2f80d2862a71660c2c96604603bb9f7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/generator_003.png b/library/thumbs/generator_003.png deleted file mode 100644 index c5788a4..0000000 Binary files a/library/thumbs/generator_003.png and /dev/null differ diff --git a/library/thumbs/generator_003.png.import b/library/thumbs/generator_003.png.import deleted file mode 100644 index 7e86562..0000000 --- a/library/thumbs/generator_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bw0u2vv7sg4e8" -path="res://.godot/imported/generator_003.png-87b0de2871b2b32836b413355fee6d82.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/generator_003.png" -dest_files=["res://.godot/imported/generator_003.png-87b0de2871b2b32836b413355fee6d82.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/generator_004.png b/library/thumbs/generator_004.png deleted file mode 100644 index 283ee98..0000000 Binary files a/library/thumbs/generator_004.png and /dev/null differ diff --git a/library/thumbs/generator_004.png.import b/library/thumbs/generator_004.png.import deleted file mode 100644 index e225e40..0000000 --- a/library/thumbs/generator_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d0hd3u3xkdciu" -path="res://.godot/imported/generator_004.png-a3cc90004c67a0efbc11a395a09ead03.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/generator_004.png" -dest_files=["res://.godot/imported/generator_004.png-a3cc90004c67a0efbc11a395a09ead03.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/grass_003.png b/library/thumbs/grass_003.png deleted file mode 100644 index 6fe4520..0000000 Binary files a/library/thumbs/grass_003.png and /dev/null differ diff --git a/library/thumbs/grass_003.png.import b/library/thumbs/grass_003.png.import deleted file mode 100644 index 7f1a1ca..0000000 --- a/library/thumbs/grass_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://kxti6habu4h1" -path="res://.godot/imported/grass_003.png-62a074749d8321fa5f73515e1aced027.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/grass_003.png" -dest_files=["res://.godot/imported/grass_003.png-62a074749d8321fa5f73515e1aced027.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/grass_004.png b/library/thumbs/grass_004.png deleted file mode 100644 index 0975367..0000000 Binary files a/library/thumbs/grass_004.png and /dev/null differ diff --git a/library/thumbs/grass_004.png.import b/library/thumbs/grass_004.png.import deleted file mode 100644 index f5efd3d..0000000 --- a/library/thumbs/grass_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dhxqqpaqt8wkl" -path="res://.godot/imported/grass_004.png-c9f7d5fb66b507a04f6ee20c8308917e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/grass_004.png" -dest_files=["res://.godot/imported/grass_004.png-c9f7d5fb66b507a04f6ee20c8308917e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/grass_005.png b/library/thumbs/grass_005.png deleted file mode 100644 index 8231384..0000000 Binary files a/library/thumbs/grass_005.png and /dev/null differ diff --git a/library/thumbs/grass_005.png.import b/library/thumbs/grass_005.png.import deleted file mode 100644 index 39b97e4..0000000 --- a/library/thumbs/grass_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://djbf1xwlqph60" -path="res://.godot/imported/grass_005.png-00c1fb7fe7a0c2ed68d9b53cfb3a59a0.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/grass_005.png" -dest_files=["res://.godot/imported/grass_005.png-00c1fb7fe7a0c2ed68d9b53cfb3a59a0.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/grass_006.png b/library/thumbs/grass_006.png deleted file mode 100644 index 4c9824b..0000000 Binary files a/library/thumbs/grass_006.png and /dev/null differ diff --git a/library/thumbs/grass_006.png.import b/library/thumbs/grass_006.png.import deleted file mode 100644 index b29d5a6..0000000 --- a/library/thumbs/grass_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dummnwoaakbi8" -path="res://.godot/imported/grass_006.png-f0522c28e88a97994c6a96c21e4bf1ab.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/grass_006.png" -dest_files=["res://.godot/imported/grass_006.png-f0522c28e88a97994c6a96c21e4bf1ab.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/grass_007.png b/library/thumbs/grass_007.png deleted file mode 100644 index 5b7c42f..0000000 Binary files a/library/thumbs/grass_007.png and /dev/null differ diff --git a/library/thumbs/grass_007.png.import b/library/thumbs/grass_007.png.import deleted file mode 100644 index f59a0f3..0000000 --- a/library/thumbs/grass_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dqsb1237co8jt" -path="res://.godot/imported/grass_007.png-c9c8e6e7cd08ce2dcce6fa4f42521816.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/grass_007.png" -dest_files=["res://.godot/imported/grass_007.png-c9c8e6e7cd08ce2dcce6fa4f42521816.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/grass_008.png b/library/thumbs/grass_008.png deleted file mode 100644 index 607a0b3..0000000 Binary files a/library/thumbs/grass_008.png and /dev/null differ diff --git a/library/thumbs/grass_008.png.import b/library/thumbs/grass_008.png.import deleted file mode 100644 index df901cf..0000000 --- a/library/thumbs/grass_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c7x1l2afmoqop" -path="res://.godot/imported/grass_008.png-741e9b52d2ba1b3ae28392eba50cffa4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/grass_008.png" -dest_files=["res://.godot/imported/grass_008.png-741e9b52d2ba1b3ae28392eba50cffa4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ground_001.png b/library/thumbs/ground_001.png deleted file mode 100644 index c139b2a..0000000 Binary files a/library/thumbs/ground_001.png and /dev/null differ diff --git a/library/thumbs/ground_001.png.import b/library/thumbs/ground_001.png.import deleted file mode 100644 index 3e54d87..0000000 --- a/library/thumbs/ground_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cpouetex3y7tw" -path="res://.godot/imported/ground_001.png-35027dd2c2a7236950c50255cfd82047.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ground_001.png" -dest_files=["res://.godot/imported/ground_001.png-35027dd2c2a7236950c50255cfd82047.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ground_002.png b/library/thumbs/ground_002.png deleted file mode 100644 index c60d283..0000000 Binary files a/library/thumbs/ground_002.png and /dev/null differ diff --git a/library/thumbs/ground_002.png.import b/library/thumbs/ground_002.png.import deleted file mode 100644 index 3a3b184..0000000 --- a/library/thumbs/ground_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cqrbrema1q5ip" -path="res://.godot/imported/ground_002.png-4519bce5795bd222a1e346c36f4c2521.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ground_002.png" -dest_files=["res://.godot/imported/ground_002.png-4519bce5795bd222a1e346c36f4c2521.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ground_003.png b/library/thumbs/ground_003.png deleted file mode 100644 index a20115d..0000000 Binary files a/library/thumbs/ground_003.png and /dev/null differ diff --git a/library/thumbs/ground_003.png.import b/library/thumbs/ground_003.png.import deleted file mode 100644 index 2993f86..0000000 --- a/library/thumbs/ground_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cafdetlj1g1q2" -path="res://.godot/imported/ground_003.png-84ba3043d24fe48f707e1c5f225c46f3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ground_003.png" -dest_files=["res://.godot/imported/ground_003.png-84ba3043d24fe48f707e1c5f225c46f3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ground_004.png b/library/thumbs/ground_004.png deleted file mode 100644 index 80a8ab4..0000000 Binary files a/library/thumbs/ground_004.png and /dev/null differ diff --git a/library/thumbs/ground_004.png.import b/library/thumbs/ground_004.png.import deleted file mode 100644 index e4c8cc7..0000000 --- a/library/thumbs/ground_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b01gbyck4hmt" -path="res://.godot/imported/ground_004.png-85e24224b5aec66797c7d96843dd84ae.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ground_004.png" -dest_files=["res://.godot/imported/ground_004.png-85e24224b5aec66797c7d96843dd84ae.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ground_005.png b/library/thumbs/ground_005.png deleted file mode 100644 index c1edc99..0000000 Binary files a/library/thumbs/ground_005.png and /dev/null differ diff --git a/library/thumbs/ground_005.png.import b/library/thumbs/ground_005.png.import deleted file mode 100644 index 4ac9eea..0000000 --- a/library/thumbs/ground_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dlctx83x50wq3" -path="res://.godot/imported/ground_005.png-124df14a12a13946e64532611c6b31b1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ground_005.png" -dest_files=["res://.godot/imported/ground_005.png-124df14a12a13946e64532611c6b31b1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ground_006.png b/library/thumbs/ground_006.png deleted file mode 100644 index 6e4cdb0..0000000 Binary files a/library/thumbs/ground_006.png and /dev/null differ diff --git a/library/thumbs/ground_006.png.import b/library/thumbs/ground_006.png.import deleted file mode 100644 index 8fb4f86..0000000 --- a/library/thumbs/ground_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dbxb1j8iwbfp3" -path="res://.godot/imported/ground_006.png-57c9b245cc641b399c8ec89700ef8a6d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ground_006.png" -dest_files=["res://.godot/imported/ground_006.png-57c9b245cc641b399c8ec89700ef8a6d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ground_007.png b/library/thumbs/ground_007.png deleted file mode 100644 index e0f77af..0000000 Binary files a/library/thumbs/ground_007.png and /dev/null differ diff --git a/library/thumbs/ground_007.png.import b/library/thumbs/ground_007.png.import deleted file mode 100644 index 474349e..0000000 --- a/library/thumbs/ground_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://mq84f6isca1m" -path="res://.godot/imported/ground_007.png-aa9e32c4f4b3747ac78984fd3601b98b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ground_007.png" -dest_files=["res://.godot/imported/ground_007.png-aa9e32c4f4b3747ac78984fd3601b98b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ground_008.png b/library/thumbs/ground_008.png deleted file mode 100644 index 5338900..0000000 Binary files a/library/thumbs/ground_008.png and /dev/null differ diff --git a/library/thumbs/ground_008.png.import b/library/thumbs/ground_008.png.import deleted file mode 100644 index 8303fe0..0000000 --- a/library/thumbs/ground_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c8g4tmxhckwix" -path="res://.godot/imported/ground_008.png-c84ae196721042e62c2422ad0ba7fb5b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ground_008.png" -dest_files=["res://.godot/imported/ground_008.png-c84ae196721042e62c2422ad0ba7fb5b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ground_009.png b/library/thumbs/ground_009.png deleted file mode 100644 index fc96d27..0000000 Binary files a/library/thumbs/ground_009.png and /dev/null differ diff --git a/library/thumbs/ground_009.png.import b/library/thumbs/ground_009.png.import deleted file mode 100644 index 3a76c6c..0000000 --- a/library/thumbs/ground_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cqxjluesevpgd" -path="res://.godot/imported/ground_009.png-b1694714a472f3f74987adb42a39fb96.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ground_009.png" -dest_files=["res://.godot/imported/ground_009.png-b1694714a472f3f74987adb42a39fb96.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/gsm_001.png b/library/thumbs/gsm_001.png deleted file mode 100644 index 467f9d3..0000000 Binary files a/library/thumbs/gsm_001.png and /dev/null differ diff --git a/library/thumbs/gsm_001.png.import b/library/thumbs/gsm_001.png.import deleted file mode 100644 index 194838e..0000000 --- a/library/thumbs/gsm_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://js75fxtglx73" -path="res://.godot/imported/gsm_001.png-df68d6cba546ba50f51a8922bdecfa3b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/gsm_001.png" -dest_files=["res://.godot/imported/gsm_001.png-df68d6cba546ba50f51a8922bdecfa3b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_001.png b/library/thumbs/hangar_001.png deleted file mode 100644 index 3aa1b78..0000000 Binary files a/library/thumbs/hangar_001.png and /dev/null differ diff --git a/library/thumbs/hangar_001.png.import b/library/thumbs/hangar_001.png.import deleted file mode 100644 index c43f84a..0000000 --- a/library/thumbs/hangar_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://oxdxsm1ga37" -path="res://.godot/imported/hangar_001.png-eb54fbdf876c8243861649eb3bf91dde.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_001.png" -dest_files=["res://.godot/imported/hangar_001.png-eb54fbdf876c8243861649eb3bf91dde.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_002.png b/library/thumbs/hangar_002.png deleted file mode 100644 index 3d2dfe1..0000000 Binary files a/library/thumbs/hangar_002.png and /dev/null differ diff --git a/library/thumbs/hangar_002.png.import b/library/thumbs/hangar_002.png.import deleted file mode 100644 index d06bdf7..0000000 --- a/library/thumbs/hangar_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bhmgksiexoq4n" -path="res://.godot/imported/hangar_002.png-c970230bcd3c831f675d566bc91c1b88.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_002.png" -dest_files=["res://.godot/imported/hangar_002.png-c970230bcd3c831f675d566bc91c1b88.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_003.png b/library/thumbs/hangar_003.png deleted file mode 100644 index 6d330e8..0000000 Binary files a/library/thumbs/hangar_003.png and /dev/null differ diff --git a/library/thumbs/hangar_003.png.import b/library/thumbs/hangar_003.png.import deleted file mode 100644 index bb7bdcd..0000000 --- a/library/thumbs/hangar_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bytr0yfoa1ff2" -path="res://.godot/imported/hangar_003.png-a880e4fb19d1bc80ed656bc79a10ffe8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_003.png" -dest_files=["res://.godot/imported/hangar_003.png-a880e4fb19d1bc80ed656bc79a10ffe8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_004.png b/library/thumbs/hangar_004.png deleted file mode 100644 index bd1ad6e..0000000 Binary files a/library/thumbs/hangar_004.png and /dev/null differ diff --git a/library/thumbs/hangar_004.png.import b/library/thumbs/hangar_004.png.import deleted file mode 100644 index d57a898..0000000 --- a/library/thumbs/hangar_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://crfn6k8kq7skr" -path="res://.godot/imported/hangar_004.png-c3a19fd627a4ef6b9c13782b73e45af4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_004.png" -dest_files=["res://.godot/imported/hangar_004.png-c3a19fd627a4ef6b9c13782b73e45af4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_005.png b/library/thumbs/hangar_005.png deleted file mode 100644 index e205479..0000000 Binary files a/library/thumbs/hangar_005.png and /dev/null differ diff --git a/library/thumbs/hangar_005.png.import b/library/thumbs/hangar_005.png.import deleted file mode 100644 index cf9385a..0000000 --- a/library/thumbs/hangar_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bn2gr2b7332vh" -path="res://.godot/imported/hangar_005.png-d6f18a95e1af4b98dd8e22ff851cd6ef.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_005.png" -dest_files=["res://.godot/imported/hangar_005.png-d6f18a95e1af4b98dd8e22ff851cd6ef.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_006.png b/library/thumbs/hangar_006.png deleted file mode 100644 index 9827602..0000000 Binary files a/library/thumbs/hangar_006.png and /dev/null differ diff --git a/library/thumbs/hangar_006.png.import b/library/thumbs/hangar_006.png.import deleted file mode 100644 index f4a1dad..0000000 --- a/library/thumbs/hangar_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://de7pl4g7cdwan" -path="res://.godot/imported/hangar_006.png-4a1736a659d25f7758fd6e8f5aa707bc.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_006.png" -dest_files=["res://.godot/imported/hangar_006.png-4a1736a659d25f7758fd6e8f5aa707bc.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_007.png b/library/thumbs/hangar_007.png deleted file mode 100644 index 8b1c2c8..0000000 Binary files a/library/thumbs/hangar_007.png and /dev/null differ diff --git a/library/thumbs/hangar_007.png.import b/library/thumbs/hangar_007.png.import deleted file mode 100644 index 1b89bec..0000000 --- a/library/thumbs/hangar_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://30hgrq6alxw4" -path="res://.godot/imported/hangar_007.png-50f4d50e813a53b887dded9944507470.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_007.png" -dest_files=["res://.godot/imported/hangar_007.png-50f4d50e813a53b887dded9944507470.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_008.png b/library/thumbs/hangar_008.png deleted file mode 100644 index 3cc281e..0000000 Binary files a/library/thumbs/hangar_008.png and /dev/null differ diff --git a/library/thumbs/hangar_008.png.import b/library/thumbs/hangar_008.png.import deleted file mode 100644 index 989b53f..0000000 --- a/library/thumbs/hangar_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ccrcd7yexl8h5" -path="res://.godot/imported/hangar_008.png-fec0f6b877ea90ead304d14d718901e7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_008.png" -dest_files=["res://.godot/imported/hangar_008.png-fec0f6b877ea90ead304d14d718901e7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_door_001.png b/library/thumbs/hangar_door_001.png deleted file mode 100644 index a01a4f4..0000000 Binary files a/library/thumbs/hangar_door_001.png and /dev/null differ diff --git a/library/thumbs/hangar_door_001.png.import b/library/thumbs/hangar_door_001.png.import deleted file mode 100644 index 53ce892..0000000 --- a/library/thumbs/hangar_door_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://xxw5jfn6q3nq" -path="res://.godot/imported/hangar_door_001.png-1c53e2a7ea53328f7c88fe96a7b87688.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_door_001.png" -dest_files=["res://.godot/imported/hangar_door_001.png-1c53e2a7ea53328f7c88fe96a7b87688.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_door_002.png b/library/thumbs/hangar_door_002.png deleted file mode 100644 index 95a4c10..0000000 Binary files a/library/thumbs/hangar_door_002.png and /dev/null differ diff --git a/library/thumbs/hangar_door_002.png.import b/library/thumbs/hangar_door_002.png.import deleted file mode 100644 index 77b990d..0000000 --- a/library/thumbs/hangar_door_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://0f782ov24am3" -path="res://.godot/imported/hangar_door_002.png-727219d020b0c232f8ff19b304b0b374.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_door_002.png" -dest_files=["res://.godot/imported/hangar_door_002.png-727219d020b0c232f8ff19b304b0b374.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hangar_door_003.png b/library/thumbs/hangar_door_003.png deleted file mode 100644 index 4d2a911..0000000 Binary files a/library/thumbs/hangar_door_003.png and /dev/null differ diff --git a/library/thumbs/hangar_door_003.png.import b/library/thumbs/hangar_door_003.png.import deleted file mode 100644 index 20b6a51..0000000 --- a/library/thumbs/hangar_door_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bh6py8abiecad" -path="res://.godot/imported/hangar_door_003.png-f362f2ed20232ad584661da6d00dc6b7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hangar_door_003.png" -dest_files=["res://.godot/imported/hangar_door_003.png-f362f2ed20232ad584661da6d00dc6b7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hedgehog_001.png b/library/thumbs/hedgehog_001.png deleted file mode 100644 index 3c7048c..0000000 Binary files a/library/thumbs/hedgehog_001.png and /dev/null differ diff --git a/library/thumbs/hedgehog_001.png.import b/library/thumbs/hedgehog_001.png.import deleted file mode 100644 index c1af853..0000000 --- a/library/thumbs/hedgehog_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cqn1wnj0csnx" -path="res://.godot/imported/hedgehog_001.png-c0de09a690126fa7000e529ef7bd1de9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hedgehog_001.png" -dest_files=["res://.godot/imported/hedgehog_001.png-c0de09a690126fa7000e529ef7bd1de9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/helicopter_001.png b/library/thumbs/helicopter_001.png deleted file mode 100644 index 782028d..0000000 Binary files a/library/thumbs/helicopter_001.png and /dev/null differ diff --git a/library/thumbs/helicopter_001.png.import b/library/thumbs/helicopter_001.png.import deleted file mode 100644 index 274853e..0000000 --- a/library/thumbs/helicopter_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c3k1ayhalsfnj" -path="res://.godot/imported/helicopter_001.png-48dcbabadc240f08effc9be38ec5926e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/helicopter_001.png" -dest_files=["res://.godot/imported/helicopter_001.png-48dcbabadc240f08effc9be38ec5926e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/helicopter_platform_001.png b/library/thumbs/helicopter_platform_001.png deleted file mode 100644 index 55d1658..0000000 Binary files a/library/thumbs/helicopter_platform_001.png and /dev/null differ diff --git a/library/thumbs/helicopter_platform_001.png.import b/library/thumbs/helicopter_platform_001.png.import deleted file mode 100644 index 2849bf8..0000000 --- a/library/thumbs/helicopter_platform_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b7ujf1j8tds8i" -path="res://.godot/imported/helicopter_platform_001.png-91d59d034ee83fa8462d56aa432fa8a5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/helicopter_platform_001.png" -dest_files=["res://.godot/imported/helicopter_platform_001.png-91d59d034ee83fa8462d56aa432fa8a5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hummer_001.png b/library/thumbs/hummer_001.png deleted file mode 100644 index b6bc800..0000000 Binary files a/library/thumbs/hummer_001.png and /dev/null differ diff --git a/library/thumbs/hummer_001.png.import b/library/thumbs/hummer_001.png.import deleted file mode 100644 index 8c2c99f..0000000 --- a/library/thumbs/hummer_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c2uartd0dn3iu" -path="res://.godot/imported/hummer_001.png-3f79a46666397570a3d70387ae48e6fe.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hummer_001.png" -dest_files=["res://.godot/imported/hummer_001.png-3f79a46666397570a3d70387ae48e6fe.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hummer_002.png b/library/thumbs/hummer_002.png deleted file mode 100644 index 6789ed2..0000000 Binary files a/library/thumbs/hummer_002.png and /dev/null differ diff --git a/library/thumbs/hummer_002.png.import b/library/thumbs/hummer_002.png.import deleted file mode 100644 index eee5688..0000000 --- a/library/thumbs/hummer_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bur6cisexpp2k" -path="res://.godot/imported/hummer_002.png-53858e9042ad9ae3a0b1816313bed35a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hummer_002.png" -dest_files=["res://.godot/imported/hummer_002.png-53858e9042ad9ae3a0b1816313bed35a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hummer_003.png b/library/thumbs/hummer_003.png deleted file mode 100644 index ded3669..0000000 Binary files a/library/thumbs/hummer_003.png and /dev/null differ diff --git a/library/thumbs/hummer_003.png.import b/library/thumbs/hummer_003.png.import deleted file mode 100644 index 232cfe2..0000000 --- a/library/thumbs/hummer_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dx5g2bynue8ks" -path="res://.godot/imported/hummer_003.png-88bc74051bc7fdd5d0ed031b49d21c06.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hummer_003.png" -dest_files=["res://.godot/imported/hummer_003.png-88bc74051bc7fdd5d0ed031b49d21c06.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/hummer_004.png b/library/thumbs/hummer_004.png deleted file mode 100644 index 37979fc..0000000 Binary files a/library/thumbs/hummer_004.png and /dev/null differ diff --git a/library/thumbs/hummer_004.png.import b/library/thumbs/hummer_004.png.import deleted file mode 100644 index 495f6b6..0000000 --- a/library/thumbs/hummer_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d3w8lpx2muutn" -path="res://.godot/imported/hummer_004.png-ce8bec3fe83bc361ba6d639be469e313.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/hummer_004.png" -dest_files=["res://.godot/imported/hummer_004.png-ce8bec3fe83bc361ba6d639be469e313.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ladder_001.png b/library/thumbs/ladder_001.png deleted file mode 100644 index 75a22d4..0000000 Binary files a/library/thumbs/ladder_001.png and /dev/null differ diff --git a/library/thumbs/ladder_001.png.import b/library/thumbs/ladder_001.png.import deleted file mode 100644 index 27720d0..0000000 --- a/library/thumbs/ladder_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bnyw2hcwnplu1" -path="res://.godot/imported/ladder_001.png-d8cc903452c6d78c74cf5d383c5807b5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ladder_001.png" -dest_files=["res://.godot/imported/ladder_001.png-d8cc903452c6d78c74cf5d383c5807b5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ladder_002.png b/library/thumbs/ladder_002.png deleted file mode 100644 index 293bbba..0000000 Binary files a/library/thumbs/ladder_002.png and /dev/null differ diff --git a/library/thumbs/ladder_002.png.import b/library/thumbs/ladder_002.png.import deleted file mode 100644 index 84bf815..0000000 --- a/library/thumbs/ladder_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bnntdaecyuisd" -path="res://.godot/imported/ladder_002.png-423ce791a50ef51fab2a7c0ea7a1a7e2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ladder_002.png" -dest_files=["res://.godot/imported/ladder_002.png-423ce791a50ef51fab2a7c0ea7a1a7e2.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/ladder_003.png b/library/thumbs/ladder_003.png deleted file mode 100644 index 4162fd9..0000000 Binary files a/library/thumbs/ladder_003.png and /dev/null differ diff --git a/library/thumbs/ladder_003.png.import b/library/thumbs/ladder_003.png.import deleted file mode 100644 index 4514a32..0000000 --- a/library/thumbs/ladder_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dpmrqkuydjhd6" -path="res://.godot/imported/ladder_003.png-62e8538615d1fe963aea5b5846240cd9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/ladder_003.png" -dest_files=["res://.godot/imported/ladder_003.png-62e8538615d1fe963aea5b5846240cd9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/lamp_001.png b/library/thumbs/lamp_001.png deleted file mode 100644 index 1356f8e..0000000 Binary files a/library/thumbs/lamp_001.png and /dev/null differ diff --git a/library/thumbs/lamp_001.png.import b/library/thumbs/lamp_001.png.import deleted file mode 100644 index d8c7199..0000000 --- a/library/thumbs/lamp_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bpkh0ald131kr" -path="res://.godot/imported/lamp_001.png-f8a1e460702bb531d4763b0483f75f84.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/lamp_001.png" -dest_files=["res://.godot/imported/lamp_001.png-f8a1e460702bb531d4763b0483f75f84.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/log_001.png b/library/thumbs/log_001.png deleted file mode 100644 index 7ead406..0000000 Binary files a/library/thumbs/log_001.png and /dev/null differ diff --git a/library/thumbs/log_001.png.import b/library/thumbs/log_001.png.import deleted file mode 100644 index 9b375c9..0000000 --- a/library/thumbs/log_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cae7hw0m4wqg1" -path="res://.godot/imported/log_001.png-73c5c5d56174605389838077bd2f8592.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/log_001.png" -dest_files=["res://.godot/imported/log_001.png-73c5c5d56174605389838077bd2f8592.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/machine_gun_001.png b/library/thumbs/machine_gun_001.png deleted file mode 100644 index 38673ab..0000000 Binary files a/library/thumbs/machine_gun_001.png and /dev/null differ diff --git a/library/thumbs/machine_gun_001.png.import b/library/thumbs/machine_gun_001.png.import deleted file mode 100644 index 1532cd8..0000000 --- a/library/thumbs/machine_gun_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://xh1oboycufg3" -path="res://.godot/imported/machine_gun_001.png-160c84097c9fbc2e267e64152bac502f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/machine_gun_001.png" -dest_files=["res://.godot/imported/machine_gun_001.png-160c84097c9fbc2e267e64152bac502f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/machine_gun_002.png b/library/thumbs/machine_gun_002.png deleted file mode 100644 index 8631c3b..0000000 Binary files a/library/thumbs/machine_gun_002.png and /dev/null differ diff --git a/library/thumbs/machine_gun_002.png.import b/library/thumbs/machine_gun_002.png.import deleted file mode 100644 index 52c72bc..0000000 --- a/library/thumbs/machine_gun_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c1x5nyxrgi37a" -path="res://.godot/imported/machine_gun_002.png-008f9004386e8a91ee9cd63522bb5314.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/machine_gun_002.png" -dest_files=["res://.godot/imported/machine_gun_002.png-008f9004386e8a91ee9cd63522bb5314.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/machine_gun_003.png b/library/thumbs/machine_gun_003.png deleted file mode 100644 index 52d110d..0000000 Binary files a/library/thumbs/machine_gun_003.png and /dev/null differ diff --git a/library/thumbs/machine_gun_003.png.import b/library/thumbs/machine_gun_003.png.import deleted file mode 100644 index 434bc31..0000000 --- a/library/thumbs/machine_gun_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cchq1yofpovw3" -path="res://.godot/imported/machine_gun_003.png-61e1abcdcda76600cd283aad18b2c305.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/machine_gun_003.png" -dest_files=["res://.godot/imported/machine_gun_003.png-61e1abcdcda76600cd283aad18b2c305.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/machine_gun_003_schild.png b/library/thumbs/machine_gun_003_schild.png deleted file mode 100644 index 52d110d..0000000 Binary files a/library/thumbs/machine_gun_003_schild.png and /dev/null differ diff --git a/library/thumbs/machine_gun_003_schild.png.import b/library/thumbs/machine_gun_003_schild.png.import deleted file mode 100644 index 6f1a273..0000000 --- a/library/thumbs/machine_gun_003_schild.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://jq8jyfhi8ebn" -path="res://.godot/imported/machine_gun_003_schild.png-fa6116f91b2355bd0e7c01e96067558f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/machine_gun_003_schild.png" -dest_files=["res://.godot/imported/machine_gun_003_schild.png-fa6116f91b2355bd0e7c01e96067558f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/machine_gun_004.png b/library/thumbs/machine_gun_004.png deleted file mode 100644 index 97ad936..0000000 Binary files a/library/thumbs/machine_gun_004.png and /dev/null differ diff --git a/library/thumbs/machine_gun_004.png.import b/library/thumbs/machine_gun_004.png.import deleted file mode 100644 index 07e3d8c..0000000 --- a/library/thumbs/machine_gun_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cc7gunrt8jror" -path="res://.godot/imported/machine_gun_004.png-f0145f29d9db02247be422964da070a5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/machine_gun_004.png" -dest_files=["res://.godot/imported/machine_gun_004.png-f0145f29d9db02247be422964da070a5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/machine_gun_005.png b/library/thumbs/machine_gun_005.png deleted file mode 100644 index 3de1977..0000000 Binary files a/library/thumbs/machine_gun_005.png and /dev/null differ diff --git a/library/thumbs/machine_gun_005.png.import b/library/thumbs/machine_gun_005.png.import deleted file mode 100644 index 34382d3..0000000 --- a/library/thumbs/machine_gun_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d02ib6fweovil" -path="res://.godot/imported/machine_gun_005.png-7c27346e2064ebd4d0b87f5e8f0eec40.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/machine_gun_005.png" -dest_files=["res://.godot/imported/machine_gun_005.png-7c27346e2064ebd4d0b87f5e8f0eec40.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/military_transport_aircraft_001.png b/library/thumbs/military_transport_aircraft_001.png deleted file mode 100644 index 5eab53f..0000000 Binary files a/library/thumbs/military_transport_aircraft_001.png and /dev/null differ diff --git a/library/thumbs/military_transport_aircraft_001.png.import b/library/thumbs/military_transport_aircraft_001.png.import deleted file mode 100644 index af73277..0000000 --- a/library/thumbs/military_transport_aircraft_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cdsdyfdep87dm" -path="res://.godot/imported/military_transport_aircraft_001.png-1292aea2a52c50f46d09f85ccd3a2e5b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/military_transport_aircraft_001.png" -dest_files=["res://.godot/imported/military_transport_aircraft_001.png-1292aea2a52c50f46d09f85ccd3a2e5b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/mortar_001.png b/library/thumbs/mortar_001.png deleted file mode 100644 index 6f84f92..0000000 Binary files a/library/thumbs/mortar_001.png and /dev/null differ diff --git a/library/thumbs/mortar_001.png.import b/library/thumbs/mortar_001.png.import deleted file mode 100644 index 083d4ee..0000000 --- a/library/thumbs/mortar_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://v84fuy7v5cs" -path="res://.godot/imported/mortar_001.png-72b6720d77f7d348dc3d6eb7352b6f29.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/mortar_001.png" -dest_files=["res://.godot/imported/mortar_001.png-72b6720d77f7d348dc3d6eb7352b6f29.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/observation_tower_001.png b/library/thumbs/observation_tower_001.png deleted file mode 100644 index 05a7066..0000000 Binary files a/library/thumbs/observation_tower_001.png and /dev/null differ diff --git a/library/thumbs/observation_tower_001.png.import b/library/thumbs/observation_tower_001.png.import deleted file mode 100644 index 475d975..0000000 --- a/library/thumbs/observation_tower_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dbic4ojgqldwf" -path="res://.godot/imported/observation_tower_001.png-9725f2bca87b2c58f206dd179517bb08.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/observation_tower_001.png" -dest_files=["res://.godot/imported/observation_tower_001.png-9725f2bca87b2c58f206dd179517bb08.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/observation_tower_002.png b/library/thumbs/observation_tower_002.png deleted file mode 100644 index ddd1fdc..0000000 Binary files a/library/thumbs/observation_tower_002.png and /dev/null differ diff --git a/library/thumbs/observation_tower_002.png.import b/library/thumbs/observation_tower_002.png.import deleted file mode 100644 index 0925c56..0000000 --- a/library/thumbs/observation_tower_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://chiebx5wma6r3" -path="res://.godot/imported/observation_tower_002.png-372e3f8d8c7330185f226a168ad9c901.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/observation_tower_002.png" -dest_files=["res://.godot/imported/observation_tower_002.png-372e3f8d8c7330185f226a168ad9c901.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_001.png b/library/thumbs/obstacle_001.png deleted file mode 100644 index 87c0b9b..0000000 Binary files a/library/thumbs/obstacle_001.png and /dev/null differ diff --git a/library/thumbs/obstacle_001.png.import b/library/thumbs/obstacle_001.png.import deleted file mode 100644 index bce8e65..0000000 --- a/library/thumbs/obstacle_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b6d6aiegl1n0g" -path="res://.godot/imported/obstacle_001.png-3021b85a3bac580a2b2e3766a57a66c3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_001.png" -dest_files=["res://.godot/imported/obstacle_001.png-3021b85a3bac580a2b2e3766a57a66c3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_002.png b/library/thumbs/obstacle_002.png deleted file mode 100644 index 7cd7be6..0000000 Binary files a/library/thumbs/obstacle_002.png and /dev/null differ diff --git a/library/thumbs/obstacle_002.png.import b/library/thumbs/obstacle_002.png.import deleted file mode 100644 index 06de7e6..0000000 --- a/library/thumbs/obstacle_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bkg1ju0lxdf5g" -path="res://.godot/imported/obstacle_002.png-c4ad31398e160b997446f9f780c6954f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_002.png" -dest_files=["res://.godot/imported/obstacle_002.png-c4ad31398e160b997446f9f780c6954f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_003.png b/library/thumbs/obstacle_003.png deleted file mode 100644 index 6438a66..0000000 Binary files a/library/thumbs/obstacle_003.png and /dev/null differ diff --git a/library/thumbs/obstacle_003.png.import b/library/thumbs/obstacle_003.png.import deleted file mode 100644 index 1e0d537..0000000 --- a/library/thumbs/obstacle_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b7tdyurwsi0uq" -path="res://.godot/imported/obstacle_003.png-dc0c167f635d3846efbce47f1a4d7293.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_003.png" -dest_files=["res://.godot/imported/obstacle_003.png-dc0c167f635d3846efbce47f1a4d7293.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_004.png b/library/thumbs/obstacle_004.png deleted file mode 100644 index 7b58aa8..0000000 Binary files a/library/thumbs/obstacle_004.png and /dev/null differ diff --git a/library/thumbs/obstacle_004.png.import b/library/thumbs/obstacle_004.png.import deleted file mode 100644 index 76860f8..0000000 --- a/library/thumbs/obstacle_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b7vmv3keroksj" -path="res://.godot/imported/obstacle_004.png-2d3f262f72281c2fee4b42b5c89c798a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_004.png" -dest_files=["res://.godot/imported/obstacle_004.png-2d3f262f72281c2fee4b42b5c89c798a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_005.png b/library/thumbs/obstacle_005.png deleted file mode 100644 index 3c5f4aa..0000000 Binary files a/library/thumbs/obstacle_005.png and /dev/null differ diff --git a/library/thumbs/obstacle_005.png.import b/library/thumbs/obstacle_005.png.import deleted file mode 100644 index 80c5256..0000000 --- a/library/thumbs/obstacle_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c2nq5302is5nq" -path="res://.godot/imported/obstacle_005.png-26c09b94401d6835c5cb54ae56b3777a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_005.png" -dest_files=["res://.godot/imported/obstacle_005.png-26c09b94401d6835c5cb54ae56b3777a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_006.png b/library/thumbs/obstacle_006.png deleted file mode 100644 index e008157..0000000 Binary files a/library/thumbs/obstacle_006.png and /dev/null differ diff --git a/library/thumbs/obstacle_006.png.import b/library/thumbs/obstacle_006.png.import deleted file mode 100644 index e9fea0d..0000000 --- a/library/thumbs/obstacle_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://daxxt4wxe0gdd" -path="res://.godot/imported/obstacle_006.png-5babc26643ec6b2274882f229a5b0bd5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_006.png" -dest_files=["res://.godot/imported/obstacle_006.png-5babc26643ec6b2274882f229a5b0bd5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_007.png b/library/thumbs/obstacle_007.png deleted file mode 100644 index 5231bdc..0000000 Binary files a/library/thumbs/obstacle_007.png and /dev/null differ diff --git a/library/thumbs/obstacle_007.png.import b/library/thumbs/obstacle_007.png.import deleted file mode 100644 index 108459f..0000000 --- a/library/thumbs/obstacle_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://fbb2wc4ueccy" -path="res://.godot/imported/obstacle_007.png-b43a588a90e749088f048b2f07a766b8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_007.png" -dest_files=["res://.godot/imported/obstacle_007.png-b43a588a90e749088f048b2f07a766b8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_008.png b/library/thumbs/obstacle_008.png deleted file mode 100644 index facc3db..0000000 Binary files a/library/thumbs/obstacle_008.png and /dev/null differ diff --git a/library/thumbs/obstacle_008.png.import b/library/thumbs/obstacle_008.png.import deleted file mode 100644 index f7862eb..0000000 --- a/library/thumbs/obstacle_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://btgirrxjoluyw" -path="res://.godot/imported/obstacle_008.png-7ae4876c971358c1303e82d316d4ffa6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_008.png" -dest_files=["res://.godot/imported/obstacle_008.png-7ae4876c971358c1303e82d316d4ffa6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_009.png b/library/thumbs/obstacle_009.png deleted file mode 100644 index ac7f59f..0000000 Binary files a/library/thumbs/obstacle_009.png and /dev/null differ diff --git a/library/thumbs/obstacle_009.png.import b/library/thumbs/obstacle_009.png.import deleted file mode 100644 index 03004db..0000000 --- a/library/thumbs/obstacle_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bxhmucxkqh10m" -path="res://.godot/imported/obstacle_009.png-db55beebf207ae287791f8dbef16af0e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_009.png" -dest_files=["res://.godot/imported/obstacle_009.png-db55beebf207ae287791f8dbef16af0e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/obstacle_010.png b/library/thumbs/obstacle_010.png deleted file mode 100644 index 114b707..0000000 Binary files a/library/thumbs/obstacle_010.png and /dev/null differ diff --git a/library/thumbs/obstacle_010.png.import b/library/thumbs/obstacle_010.png.import deleted file mode 100644 index 5a7c77c..0000000 --- a/library/thumbs/obstacle_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://gv4u5ep8yxu4" -path="res://.godot/imported/obstacle_010.png-3630ea64fc3652f281e6a2d49636427a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/obstacle_010.png" -dest_files=["res://.godot/imported/obstacle_010.png-3630ea64fc3652f281e6a2d49636427a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/pallet_001.png b/library/thumbs/pallet_001.png deleted file mode 100644 index 28ccb5e..0000000 Binary files a/library/thumbs/pallet_001.png and /dev/null differ diff --git a/library/thumbs/pallet_001.png.import b/library/thumbs/pallet_001.png.import deleted file mode 100644 index 3032f11..0000000 --- a/library/thumbs/pallet_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bb3f7drsrv3cn" -path="res://.godot/imported/pallet_001.png-dfee26352fc997db59aabd4192397c98.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/pallet_001.png" -dest_files=["res://.godot/imported/pallet_001.png-dfee26352fc997db59aabd4192397c98.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/pallet_002.png b/library/thumbs/pallet_002.png deleted file mode 100644 index b64ed03..0000000 Binary files a/library/thumbs/pallet_002.png and /dev/null differ diff --git a/library/thumbs/pallet_002.png.import b/library/thumbs/pallet_002.png.import deleted file mode 100644 index ed67e44..0000000 --- a/library/thumbs/pallet_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bdpjb7f7l0bj2" -path="res://.godot/imported/pallet_002.png-268238cdbe16a041cbe36ada87c4ab13.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/pallet_002.png" -dest_files=["res://.godot/imported/pallet_002.png-268238cdbe16a041cbe36ada87c4ab13.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/pillar_001.png b/library/thumbs/pillar_001.png deleted file mode 100644 index db1fe9f..0000000 Binary files a/library/thumbs/pillar_001.png and /dev/null differ diff --git a/library/thumbs/pillar_001.png.import b/library/thumbs/pillar_001.png.import deleted file mode 100644 index 0e9f633..0000000 --- a/library/thumbs/pillar_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://gs5fj3y8oofo" -path="res://.godot/imported/pillar_001.png-f384f311afe6d8c2c1c19f62e24c4c3d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/pillar_001.png" -dest_files=["res://.godot/imported/pillar_001.png-f384f311afe6d8c2c1c19f62e24c4c3d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/pillar_002.png b/library/thumbs/pillar_002.png deleted file mode 100644 index 600c869..0000000 Binary files a/library/thumbs/pillar_002.png and /dev/null differ diff --git a/library/thumbs/pillar_002.png.import b/library/thumbs/pillar_002.png.import deleted file mode 100644 index 0df10d8..0000000 --- a/library/thumbs/pillar_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cj2jr7ry6ndom" -path="res://.godot/imported/pillar_002.png-34a37f49f925e1eb1aaacee8e8bdc542.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/pillar_002.png" -dest_files=["res://.godot/imported/pillar_002.png-34a37f49f925e1eb1aaacee8e8bdc542.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/pillar_003.png b/library/thumbs/pillar_003.png deleted file mode 100644 index 3a6c1f7..0000000 Binary files a/library/thumbs/pillar_003.png and /dev/null differ diff --git a/library/thumbs/pillar_003.png.import b/library/thumbs/pillar_003.png.import deleted file mode 100644 index 94430a9..0000000 --- a/library/thumbs/pillar_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://xukr7eaglupr" -path="res://.godot/imported/pillar_003.png-9f84aba109205db0887ca4882b87b733.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/pillar_003.png" -dest_files=["res://.godot/imported/pillar_003.png-9f84aba109205db0887ca4882b87b733.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/pillar_004.png b/library/thumbs/pillar_004.png deleted file mode 100644 index df4d143..0000000 Binary files a/library/thumbs/pillar_004.png and /dev/null differ diff --git a/library/thumbs/pillar_004.png.import b/library/thumbs/pillar_004.png.import deleted file mode 100644 index 4ca53c6..0000000 --- a/library/thumbs/pillar_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dccarrcra22u" -path="res://.godot/imported/pillar_004.png-0a3ed3a2c526ad1891e98ee97f4c20e6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/pillar_004.png" -dest_files=["res://.godot/imported/pillar_004.png-0a3ed3a2c526ad1891e98ee97f4c20e6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/pipe_001.png b/library/thumbs/pipe_001.png deleted file mode 100644 index e41b61c..0000000 Binary files a/library/thumbs/pipe_001.png and /dev/null differ diff --git a/library/thumbs/pipe_001.png.import b/library/thumbs/pipe_001.png.import deleted file mode 100644 index 562511c..0000000 --- a/library/thumbs/pipe_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://wi4fn21t17gk" -path="res://.godot/imported/pipe_001.png-82b60b1f6932b017c275ddcbdb76c907.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/pipe_001.png" -dest_files=["res://.godot/imported/pipe_001.png-82b60b1f6932b017c275ddcbdb76c907.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/protection_001.png b/library/thumbs/protection_001.png deleted file mode 100644 index c68d089..0000000 Binary files a/library/thumbs/protection_001.png and /dev/null differ diff --git a/library/thumbs/protection_001.png.import b/library/thumbs/protection_001.png.import deleted file mode 100644 index b39a28c..0000000 --- a/library/thumbs/protection_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b2i2bc1dee5v7" -path="res://.godot/imported/protection_001.png-71de7e24bbb7059521cc40f45c746dd3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/protection_001.png" -dest_files=["res://.godot/imported/protection_001.png-71de7e24bbb7059521cc40f45c746dd3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/protection_002.png b/library/thumbs/protection_002.png deleted file mode 100644 index 60c7b1a..0000000 Binary files a/library/thumbs/protection_002.png and /dev/null differ diff --git a/library/thumbs/protection_002.png.import b/library/thumbs/protection_002.png.import deleted file mode 100644 index 5da7db9..0000000 --- a/library/thumbs/protection_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cd0h47o72jyil" -path="res://.godot/imported/protection_002.png-5687bfb7db12eae55b05ff843ba00f3c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/protection_002.png" -dest_files=["res://.godot/imported/protection_002.png-5687bfb7db12eae55b05ff843ba00f3c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/protective_wall_001.png b/library/thumbs/protective_wall_001.png deleted file mode 100644 index 79172b0..0000000 Binary files a/library/thumbs/protective_wall_001.png and /dev/null differ diff --git a/library/thumbs/protective_wall_001.png.import b/library/thumbs/protective_wall_001.png.import deleted file mode 100644 index 8d7114e..0000000 --- a/library/thumbs/protective_wall_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c51jk5b2es66v" -path="res://.godot/imported/protective_wall_001.png-cfd0957f241a365ae53d568029e7d6f5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/protective_wall_001.png" -dest_files=["res://.godot/imported/protective_wall_001.png-cfd0957f241a365ae53d568029e7d6f5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/protective_wall_002.png b/library/thumbs/protective_wall_002.png deleted file mode 100644 index 350458a..0000000 Binary files a/library/thumbs/protective_wall_002.png and /dev/null differ diff --git a/library/thumbs/protective_wall_002.png.import b/library/thumbs/protective_wall_002.png.import deleted file mode 100644 index 63f04b2..0000000 --- a/library/thumbs/protective_wall_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c0bsa7bh3dmv6" -path="res://.godot/imported/protective_wall_002.png-eb0ed8ba5c86d95629903c33ece31f84.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/protective_wall_002.png" -dest_files=["res://.godot/imported/protective_wall_002.png-eb0ed8ba5c86d95629903c33ece31f84.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/protective_wall_003.png b/library/thumbs/protective_wall_003.png deleted file mode 100644 index f4d9a2a..0000000 Binary files a/library/thumbs/protective_wall_003.png and /dev/null differ diff --git a/library/thumbs/protective_wall_003.png.import b/library/thumbs/protective_wall_003.png.import deleted file mode 100644 index 16a25ec..0000000 --- a/library/thumbs/protective_wall_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://34q8x6ynrerm" -path="res://.godot/imported/protective_wall_003.png-3e3eb884b9155856e529f9a2432c9066.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/protective_wall_003.png" -dest_files=["res://.godot/imported/protective_wall_003.png-3e3eb884b9155856e529f9a2432c9066.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/protective_wall_004.png b/library/thumbs/protective_wall_004.png deleted file mode 100644 index e4c2b2e..0000000 Binary files a/library/thumbs/protective_wall_004.png and /dev/null differ diff --git a/library/thumbs/protective_wall_004.png.import b/library/thumbs/protective_wall_004.png.import deleted file mode 100644 index 5be9b44..0000000 --- a/library/thumbs/protective_wall_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bvy0eb8ooaxss" -path="res://.godot/imported/protective_wall_004.png-aec75f14c3de1ff70726d28c733cf360.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/protective_wall_004.png" -dest_files=["res://.godot/imported/protective_wall_004.png-aec75f14c3de1ff70726d28c733cf360.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/radiolocator_001.png b/library/thumbs/radiolocator_001.png deleted file mode 100644 index 160be82..0000000 Binary files a/library/thumbs/radiolocator_001.png and /dev/null differ diff --git a/library/thumbs/radiolocator_001.png.import b/library/thumbs/radiolocator_001.png.import deleted file mode 100644 index b160bf6..0000000 --- a/library/thumbs/radiolocator_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://brq1gcri651dv" -path="res://.godot/imported/radiolocator_001.png-3d9681496a07b32ad809cd774843940d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/radiolocator_001.png" -dest_files=["res://.godot/imported/radiolocator_001.png-3d9681496a07b32ad809cd774843940d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/radiolocator_002.png b/library/thumbs/radiolocator_002.png deleted file mode 100644 index 3485cc1..0000000 Binary files a/library/thumbs/radiolocator_002.png and /dev/null differ diff --git a/library/thumbs/radiolocator_002.png.import b/library/thumbs/radiolocator_002.png.import deleted file mode 100644 index 24dca04..0000000 --- a/library/thumbs/radiolocator_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bngtff4ba66yo" -path="res://.godot/imported/radiolocator_002.png-f233a8a2c282543f2de5f0117a68391a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/radiolocator_002.png" -dest_files=["res://.godot/imported/radiolocator_002.png-f233a8a2c282543f2de5f0117a68391a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/radiolocator_platform_001.png b/library/thumbs/radiolocator_platform_001.png deleted file mode 100644 index 78954cc..0000000 Binary files a/library/thumbs/radiolocator_platform_001.png and /dev/null differ diff --git a/library/thumbs/radiolocator_platform_001.png.import b/library/thumbs/radiolocator_platform_001.png.import deleted file mode 100644 index b8e4884..0000000 --- a/library/thumbs/radiolocator_platform_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://jx200km4k0pt" -path="res://.godot/imported/radiolocator_platform_001.png-2a7d3e430c0f9550970c5d6a28fbb10c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/radiolocator_platform_001.png" -dest_files=["res://.godot/imported/radiolocator_platform_001.png-2a7d3e430c0f9550970c5d6a28fbb10c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/radiolocator_platform_002.png b/library/thumbs/radiolocator_platform_002.png deleted file mode 100644 index e9bef08..0000000 Binary files a/library/thumbs/radiolocator_platform_002.png and /dev/null differ diff --git a/library/thumbs/radiolocator_platform_002.png.import b/library/thumbs/radiolocator_platform_002.png.import deleted file mode 100644 index 36179d3..0000000 --- a/library/thumbs/radiolocator_platform_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://vb0b5j4gwxcl" -path="res://.godot/imported/radiolocator_platform_002.png-4b3ea11b3671ddaf332e5f39e87f6960.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/radiolocator_platform_002.png" -dest_files=["res://.godot/imported/radiolocator_platform_002.png-4b3ea11b3671ddaf332e5f39e87f6960.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/radiostation_001.png b/library/thumbs/radiostation_001.png deleted file mode 100644 index aedb739..0000000 Binary files a/library/thumbs/radiostation_001.png and /dev/null differ diff --git a/library/thumbs/radiostation_001.png.import b/library/thumbs/radiostation_001.png.import deleted file mode 100644 index 9fb2c78..0000000 --- a/library/thumbs/radiostation_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ncoqtcn6fxrt" -path="res://.godot/imported/radiostation_001.png-657b34f6ccb3afe4130af73dec01b1e5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/radiostation_001.png" -dest_files=["res://.godot/imported/radiostation_001.png-657b34f6ccb3afe4130af73dec01b1e5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/radiostation_002.png b/library/thumbs/radiostation_002.png deleted file mode 100644 index 3cddc20..0000000 Binary files a/library/thumbs/radiostation_002.png and /dev/null differ diff --git a/library/thumbs/radiostation_002.png.import b/library/thumbs/radiostation_002.png.import deleted file mode 100644 index a09a7b8..0000000 --- a/library/thumbs/radiostation_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://daq6ej2fbbiwm" -path="res://.godot/imported/radiostation_002.png-b9bc6189d50b2bddd96dd9130dba12d6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/radiostation_002.png" -dest_files=["res://.godot/imported/radiostation_002.png-b9bc6189d50b2bddd96dd9130dba12d6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/road_006.png b/library/thumbs/road_006.png deleted file mode 100644 index eadd278..0000000 Binary files a/library/thumbs/road_006.png and /dev/null differ diff --git a/library/thumbs/road_006.png.import b/library/thumbs/road_006.png.import deleted file mode 100644 index 3dd683c..0000000 --- a/library/thumbs/road_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c8wgfvuwjebct" -path="res://.godot/imported/road_006.png-62fa04036764291dce3561c896c77adc.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/road_006.png" -dest_files=["res://.godot/imported/road_006.png-62fa04036764291dce3561c896c77adc.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/road_007.png b/library/thumbs/road_007.png deleted file mode 100644 index 9da7cdf..0000000 Binary files a/library/thumbs/road_007.png and /dev/null differ diff --git a/library/thumbs/road_007.png.import b/library/thumbs/road_007.png.import deleted file mode 100644 index 6c18f63..0000000 --- a/library/thumbs/road_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b8qu5ifwxba67" -path="res://.godot/imported/road_007.png-a78de1258326084707519b781f513113.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/road_007.png" -dest_files=["res://.godot/imported/road_007.png-a78de1258326084707519b781f513113.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/road_008.png b/library/thumbs/road_008.png deleted file mode 100644 index 23e483a..0000000 Binary files a/library/thumbs/road_008.png and /dev/null differ diff --git a/library/thumbs/road_008.png.import b/library/thumbs/road_008.png.import deleted file mode 100644 index 25b1fbb..0000000 --- a/library/thumbs/road_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bxv7y24wu5fsx" -path="res://.godot/imported/road_008.png-ed918547fd356c659826da65df06359a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/road_008.png" -dest_files=["res://.godot/imported/road_008.png-ed918547fd356c659826da65df06359a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/road_009.png b/library/thumbs/road_009.png deleted file mode 100644 index 4260e75..0000000 Binary files a/library/thumbs/road_009.png and /dev/null differ diff --git a/library/thumbs/road_009.png.import b/library/thumbs/road_009.png.import deleted file mode 100644 index c2a31db..0000000 --- a/library/thumbs/road_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bp8p1eak31c5k" -path="res://.godot/imported/road_009.png-1a72aba5864bf1649911aedfebf6177b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/road_009.png" -dest_files=["res://.godot/imported/road_009.png-1a72aba5864bf1649911aedfebf6177b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_003.png b/library/thumbs/rock_003.png deleted file mode 100644 index b736545..0000000 Binary files a/library/thumbs/rock_003.png and /dev/null differ diff --git a/library/thumbs/rock_003.png.import b/library/thumbs/rock_003.png.import deleted file mode 100644 index ef183b5..0000000 --- a/library/thumbs/rock_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b254mqm4vo7am" -path="res://.godot/imported/rock_003.png-8f604995530eb979d9a5d8aff5920fd3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_003.png" -dest_files=["res://.godot/imported/rock_003.png-8f604995530eb979d9a5d8aff5920fd3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_004.png b/library/thumbs/rock_004.png deleted file mode 100644 index e837410..0000000 Binary files a/library/thumbs/rock_004.png and /dev/null differ diff --git a/library/thumbs/rock_004.png.import b/library/thumbs/rock_004.png.import deleted file mode 100644 index 19abb9f..0000000 --- a/library/thumbs/rock_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cdo6uwkifcs3y" -path="res://.godot/imported/rock_004.png-2ab8621b9e84399bdc22816891cc2390.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_004.png" -dest_files=["res://.godot/imported/rock_004.png-2ab8621b9e84399bdc22816891cc2390.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_005.png b/library/thumbs/rock_005.png deleted file mode 100644 index 564d56a..0000000 Binary files a/library/thumbs/rock_005.png and /dev/null differ diff --git a/library/thumbs/rock_005.png.import b/library/thumbs/rock_005.png.import deleted file mode 100644 index f1a43ea..0000000 --- a/library/thumbs/rock_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bbh3fcaqd7w8r" -path="res://.godot/imported/rock_005.png-3e78608843b1c28b8b6fb0be7a3e6b1d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_005.png" -dest_files=["res://.godot/imported/rock_005.png-3e78608843b1c28b8b6fb0be7a3e6b1d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_006.png b/library/thumbs/rock_006.png deleted file mode 100644 index 8d69ced..0000000 Binary files a/library/thumbs/rock_006.png and /dev/null differ diff --git a/library/thumbs/rock_006.png.import b/library/thumbs/rock_006.png.import deleted file mode 100644 index 398e65c..0000000 --- a/library/thumbs/rock_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cfs37vno1jid" -path="res://.godot/imported/rock_006.png-90b05fb37f97e2d591174f74462401d8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_006.png" -dest_files=["res://.godot/imported/rock_006.png-90b05fb37f97e2d591174f74462401d8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_007.png b/library/thumbs/rock_007.png deleted file mode 100644 index c70d073..0000000 Binary files a/library/thumbs/rock_007.png and /dev/null differ diff --git a/library/thumbs/rock_007.png.import b/library/thumbs/rock_007.png.import deleted file mode 100644 index fa08d25..0000000 --- a/library/thumbs/rock_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://g58x7q0unqhm" -path="res://.godot/imported/rock_007.png-b1a39cb20d9bf9555f291dc31c62f47a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_007.png" -dest_files=["res://.godot/imported/rock_007.png-b1a39cb20d9bf9555f291dc31c62f47a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_008.png b/library/thumbs/rock_008.png deleted file mode 100644 index b2a2feb..0000000 Binary files a/library/thumbs/rock_008.png and /dev/null differ diff --git a/library/thumbs/rock_008.png.import b/library/thumbs/rock_008.png.import deleted file mode 100644 index 173a56d..0000000 --- a/library/thumbs/rock_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://gwjekiuijf60" -path="res://.godot/imported/rock_008.png-a8e696c7603db2ea6565def3a16b9a66.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_008.png" -dest_files=["res://.godot/imported/rock_008.png-a8e696c7603db2ea6565def3a16b9a66.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_009.png b/library/thumbs/rock_009.png deleted file mode 100644 index 25321e5..0000000 Binary files a/library/thumbs/rock_009.png and /dev/null differ diff --git a/library/thumbs/rock_009.png.import b/library/thumbs/rock_009.png.import deleted file mode 100644 index f423174..0000000 --- a/library/thumbs/rock_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dowcg0e426hud" -path="res://.godot/imported/rock_009.png-0782b9fec70bc3841d4d6d523311b4d4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_009.png" -dest_files=["res://.godot/imported/rock_009.png-0782b9fec70bc3841d4d6d523311b4d4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_010.png b/library/thumbs/rock_010.png deleted file mode 100644 index 0a7a981..0000000 Binary files a/library/thumbs/rock_010.png and /dev/null differ diff --git a/library/thumbs/rock_010.png.import b/library/thumbs/rock_010.png.import deleted file mode 100644 index b9d7400..0000000 --- a/library/thumbs/rock_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cq4q2yec74cmx" -path="res://.godot/imported/rock_010.png-343b605ca81d529a5bac94b6956086b9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_010.png" -dest_files=["res://.godot/imported/rock_010.png-343b605ca81d529a5bac94b6956086b9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_011.png b/library/thumbs/rock_011.png deleted file mode 100644 index a867cc8..0000000 Binary files a/library/thumbs/rock_011.png and /dev/null differ diff --git a/library/thumbs/rock_011.png.import b/library/thumbs/rock_011.png.import deleted file mode 100644 index 659f941..0000000 --- a/library/thumbs/rock_011.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://k0yrrki2qabv" -path="res://.godot/imported/rock_011.png-2e86f6bb3deba35593f1eb46804f930d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_011.png" -dest_files=["res://.godot/imported/rock_011.png-2e86f6bb3deba35593f1eb46804f930d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_012.png b/library/thumbs/rock_012.png deleted file mode 100644 index e636c34..0000000 Binary files a/library/thumbs/rock_012.png and /dev/null differ diff --git a/library/thumbs/rock_012.png.import b/library/thumbs/rock_012.png.import deleted file mode 100644 index b722544..0000000 --- a/library/thumbs/rock_012.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ccnxpp4cnt28n" -path="res://.godot/imported/rock_012.png-2a93b9be4281c83261bccf8b4a9f52c7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_012.png" -dest_files=["res://.godot/imported/rock_012.png-2a93b9be4281c83261bccf8b4a9f52c7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_013.png b/library/thumbs/rock_013.png deleted file mode 100644 index f21d481..0000000 Binary files a/library/thumbs/rock_013.png and /dev/null differ diff --git a/library/thumbs/rock_013.png.import b/library/thumbs/rock_013.png.import deleted file mode 100644 index f6bb026..0000000 --- a/library/thumbs/rock_013.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cful7s2q50dt6" -path="res://.godot/imported/rock_013.png-676670449b74a6032f554a982870d11e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_013.png" -dest_files=["res://.godot/imported/rock_013.png-676670449b74a6032f554a982870d11e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_014.png b/library/thumbs/rock_014.png deleted file mode 100644 index b5a3a97..0000000 Binary files a/library/thumbs/rock_014.png and /dev/null differ diff --git a/library/thumbs/rock_014.png.import b/library/thumbs/rock_014.png.import deleted file mode 100644 index 5aa4560..0000000 --- a/library/thumbs/rock_014.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://spstllxv8ka8" -path="res://.godot/imported/rock_014.png-1d42c8183bb42d4bc58b54669f9d5463.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_014.png" -dest_files=["res://.godot/imported/rock_014.png-1d42c8183bb42d4bc58b54669f9d5463.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_015.png b/library/thumbs/rock_015.png deleted file mode 100644 index 4eea36c..0000000 Binary files a/library/thumbs/rock_015.png and /dev/null differ diff --git a/library/thumbs/rock_015.png.import b/library/thumbs/rock_015.png.import deleted file mode 100644 index 6bf1eab..0000000 --- a/library/thumbs/rock_015.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dywjcswag5dce" -path="res://.godot/imported/rock_015.png-d1d281ede5e9048a6b1cdf54c35a7041.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_015.png" -dest_files=["res://.godot/imported/rock_015.png-d1d281ede5e9048a6b1cdf54c35a7041.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_016.png b/library/thumbs/rock_016.png deleted file mode 100644 index bde1a02..0000000 Binary files a/library/thumbs/rock_016.png and /dev/null differ diff --git a/library/thumbs/rock_016.png.import b/library/thumbs/rock_016.png.import deleted file mode 100644 index 404a912..0000000 --- a/library/thumbs/rock_016.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c5s5qpxvic06j" -path="res://.godot/imported/rock_016.png-2c5ebfee1ab0ef2b5ed13bd8f99edbe8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_016.png" -dest_files=["res://.godot/imported/rock_016.png-2c5ebfee1ab0ef2b5ed13bd8f99edbe8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_017.png b/library/thumbs/rock_017.png deleted file mode 100644 index f8ec409..0000000 Binary files a/library/thumbs/rock_017.png and /dev/null differ diff --git a/library/thumbs/rock_017.png.import b/library/thumbs/rock_017.png.import deleted file mode 100644 index d76640d..0000000 --- a/library/thumbs/rock_017.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://drkke18qhu5kh" -path="res://.godot/imported/rock_017.png-ecac74d36a1af80b6c0ea1982f1e16b4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_017.png" -dest_files=["res://.godot/imported/rock_017.png-ecac74d36a1af80b6c0ea1982f1e16b4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_018.png b/library/thumbs/rock_018.png deleted file mode 100644 index 0902abf..0000000 Binary files a/library/thumbs/rock_018.png and /dev/null differ diff --git a/library/thumbs/rock_018.png.import b/library/thumbs/rock_018.png.import deleted file mode 100644 index 281a40c..0000000 --- a/library/thumbs/rock_018.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cmlu5x8o8iclr" -path="res://.godot/imported/rock_018.png-14a54f7f50f1290864804b1ce7ffb11c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_018.png" -dest_files=["res://.godot/imported/rock_018.png-14a54f7f50f1290864804b1ce7ffb11c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_019.png b/library/thumbs/rock_019.png deleted file mode 100644 index 96ca6a0..0000000 Binary files a/library/thumbs/rock_019.png and /dev/null differ diff --git a/library/thumbs/rock_019.png.import b/library/thumbs/rock_019.png.import deleted file mode 100644 index 1ff576d..0000000 --- a/library/thumbs/rock_019.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ltakv1s6ut50" -path="res://.godot/imported/rock_019.png-b90180639ef0229a0dc99cf29a8f7f8a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_019.png" -dest_files=["res://.godot/imported/rock_019.png-b90180639ef0229a0dc99cf29a8f7f8a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_020.png b/library/thumbs/rock_020.png deleted file mode 100644 index 6954498..0000000 Binary files a/library/thumbs/rock_020.png and /dev/null differ diff --git a/library/thumbs/rock_020.png.import b/library/thumbs/rock_020.png.import deleted file mode 100644 index 6ff9253..0000000 --- a/library/thumbs/rock_020.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cs7u455lf7tj4" -path="res://.godot/imported/rock_020.png-729a5b5f8ac18c0e3ba3b7ca43577a9f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_020.png" -dest_files=["res://.godot/imported/rock_020.png-729a5b5f8ac18c0e3ba3b7ca43577a9f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_021.png b/library/thumbs/rock_021.png deleted file mode 100644 index de82092..0000000 Binary files a/library/thumbs/rock_021.png and /dev/null differ diff --git a/library/thumbs/rock_021.png.import b/library/thumbs/rock_021.png.import deleted file mode 100644 index 877758f..0000000 --- a/library/thumbs/rock_021.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c3xt18gvmbjc8" -path="res://.godot/imported/rock_021.png-1c83cf3cd7e310ed2209a49b4fc4630d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_021.png" -dest_files=["res://.godot/imported/rock_021.png-1c83cf3cd7e310ed2209a49b4fc4630d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_022.png b/library/thumbs/rock_022.png deleted file mode 100644 index f4f18fd..0000000 Binary files a/library/thumbs/rock_022.png and /dev/null differ diff --git a/library/thumbs/rock_022.png.import b/library/thumbs/rock_022.png.import deleted file mode 100644 index 1014c3c..0000000 --- a/library/thumbs/rock_022.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c0fm4ii5qria6" -path="res://.godot/imported/rock_022.png-8bb40a43b14ae45b08235d13f2161397.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_022.png" -dest_files=["res://.godot/imported/rock_022.png-8bb40a43b14ae45b08235d13f2161397.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_023.png b/library/thumbs/rock_023.png deleted file mode 100644 index 455b7ec..0000000 Binary files a/library/thumbs/rock_023.png and /dev/null differ diff --git a/library/thumbs/rock_023.png.import b/library/thumbs/rock_023.png.import deleted file mode 100644 index 2f6d7aa..0000000 --- a/library/thumbs/rock_023.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bme2keecsggkn" -path="res://.godot/imported/rock_023.png-07d74c2280b0d9349ed92cea35b2bbe0.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_023.png" -dest_files=["res://.godot/imported/rock_023.png-07d74c2280b0d9349ed92cea35b2bbe0.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_024.png b/library/thumbs/rock_024.png deleted file mode 100644 index cd458c1..0000000 Binary files a/library/thumbs/rock_024.png and /dev/null differ diff --git a/library/thumbs/rock_024.png.import b/library/thumbs/rock_024.png.import deleted file mode 100644 index 94de2bb..0000000 --- a/library/thumbs/rock_024.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://btknl71epllp7" -path="res://.godot/imported/rock_024.png-4e4b6ee3d0a9d2993fac5ef7548a48d1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_024.png" -dest_files=["res://.godot/imported/rock_024.png-4e4b6ee3d0a9d2993fac5ef7548a48d1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/rock_038.png b/library/thumbs/rock_038.png deleted file mode 100644 index ef28a61..0000000 Binary files a/library/thumbs/rock_038.png and /dev/null differ diff --git a/library/thumbs/rock_038.png.import b/library/thumbs/rock_038.png.import deleted file mode 100644 index c867836..0000000 --- a/library/thumbs/rock_038.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bhnrbk60qw13u" -path="res://.godot/imported/rock_038.png-b2c78a15fc403e51e414de65ca7d3cfa.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/rock_038.png" -dest_files=["res://.godot/imported/rock_038.png-b2c78a15fc403e51e414de65ca7d3cfa.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/sand_001.png b/library/thumbs/sand_001.png deleted file mode 100644 index 1ddf6c2..0000000 Binary files a/library/thumbs/sand_001.png and /dev/null differ diff --git a/library/thumbs/sand_001.png.import b/library/thumbs/sand_001.png.import deleted file mode 100644 index 69a233e..0000000 --- a/library/thumbs/sand_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c4iltdplrcp2l" -path="res://.godot/imported/sand_001.png-5e1ca41ab019d3535bae6fef96c84557.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/sand_001.png" -dest_files=["res://.godot/imported/sand_001.png-5e1ca41ab019d3535bae6fef96c84557.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/shell_001.png b/library/thumbs/shell_001.png deleted file mode 100644 index a3af9cb..0000000 Binary files a/library/thumbs/shell_001.png and /dev/null differ diff --git a/library/thumbs/shell_001.png.import b/library/thumbs/shell_001.png.import deleted file mode 100644 index 165d48a..0000000 --- a/library/thumbs/shell_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d4cchdjjnj3ao" -path="res://.godot/imported/shell_001.png-83e35ed2f69219f6e1d80dd8b538c692.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/shell_001.png" -dest_files=["res://.godot/imported/shell_001.png-83e35ed2f69219f6e1d80dd8b538c692.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/shell_002.png b/library/thumbs/shell_002.png deleted file mode 100644 index 435fd48..0000000 Binary files a/library/thumbs/shell_002.png and /dev/null differ diff --git a/library/thumbs/shell_002.png.import b/library/thumbs/shell_002.png.import deleted file mode 100644 index a3ae1a8..0000000 --- a/library/thumbs/shell_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://csm3cf7cs65" -path="res://.godot/imported/shell_002.png-8eba85d71659c4f4b037a7211b679969.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/shell_002.png" -dest_files=["res://.godot/imported/shell_002.png-8eba85d71659c4f4b037a7211b679969.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/shell_003.png b/library/thumbs/shell_003.png deleted file mode 100644 index 08c35d7..0000000 Binary files a/library/thumbs/shell_003.png and /dev/null differ diff --git a/library/thumbs/shell_003.png.import b/library/thumbs/shell_003.png.import deleted file mode 100644 index 2efde55..0000000 --- a/library/thumbs/shell_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://by2uh7amsyob2" -path="res://.godot/imported/shell_003.png-3ab61f81b8eb95aedb3ceaf47bd7e050.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/shell_003.png" -dest_files=["res://.godot/imported/shell_003.png-3ab61f81b8eb95aedb3ceaf47bd7e050.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/shell_004.png b/library/thumbs/shell_004.png deleted file mode 100644 index e51f303..0000000 Binary files a/library/thumbs/shell_004.png and /dev/null differ diff --git a/library/thumbs/shell_004.png.import b/library/thumbs/shell_004.png.import deleted file mode 100644 index 2cfaafe..0000000 --- a/library/thumbs/shell_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dbtfllusr5amv" -path="res://.godot/imported/shell_004.png-1e4532b7f31a4577ccd4cc94b78edf30.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/shell_004.png" -dest_files=["res://.godot/imported/shell_004.png-1e4532b7f31a4577ccd4cc94b78edf30.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/shell_005.png b/library/thumbs/shell_005.png deleted file mode 100644 index d73701c..0000000 Binary files a/library/thumbs/shell_005.png and /dev/null differ diff --git a/library/thumbs/shell_005.png.import b/library/thumbs/shell_005.png.import deleted file mode 100644 index aeff793..0000000 --- a/library/thumbs/shell_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dl62knhaie5ml" -path="res://.godot/imported/shell_005.png-abbcffccae87cc2ca4789a2f9fe94776.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/shell_005.png" -dest_files=["res://.godot/imported/shell_005.png-abbcffccae87cc2ca4789a2f9fe94776.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/shell_006.png b/library/thumbs/shell_006.png deleted file mode 100644 index 87bcf9b..0000000 Binary files a/library/thumbs/shell_006.png and /dev/null differ diff --git a/library/thumbs/shell_006.png.import b/library/thumbs/shell_006.png.import deleted file mode 100644 index 31c74a5..0000000 --- a/library/thumbs/shell_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://blhhuqo0lcegx" -path="res://.godot/imported/shell_006.png-a9e5250dd53c4d002c5f41d2a4299155.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/shell_006.png" -dest_files=["res://.godot/imported/shell_006.png-a9e5250dd53c4d002c5f41d2a4299155.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/shell_007.png b/library/thumbs/shell_007.png deleted file mode 100644 index cd28e2f..0000000 Binary files a/library/thumbs/shell_007.png and /dev/null differ diff --git a/library/thumbs/shell_007.png.import b/library/thumbs/shell_007.png.import deleted file mode 100644 index 8a56c26..0000000 --- a/library/thumbs/shell_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cxdeoes1nseti" -path="res://.godot/imported/shell_007.png-deddee0c9c962673d192124d3edb42f2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/shell_007.png" -dest_files=["res://.godot/imported/shell_007.png-deddee0c9c962673d192124d3edb42f2.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/shell_008.png b/library/thumbs/shell_008.png deleted file mode 100644 index 1abc069..0000000 Binary files a/library/thumbs/shell_008.png and /dev/null differ diff --git a/library/thumbs/shell_008.png.import b/library/thumbs/shell_008.png.import deleted file mode 100644 index 09033b4..0000000 --- a/library/thumbs/shell_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ysfusuctrrrx" -path="res://.godot/imported/shell_008.png-49531454964c30e12d334f117cc0054c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/shell_008.png" -dest_files=["res://.godot/imported/shell_008.png-49531454964c30e12d334f117cc0054c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/solar_battery_001.png b/library/thumbs/solar_battery_001.png deleted file mode 100644 index be98faf..0000000 Binary files a/library/thumbs/solar_battery_001.png and /dev/null differ diff --git a/library/thumbs/solar_battery_001.png.import b/library/thumbs/solar_battery_001.png.import deleted file mode 100644 index 1dab637..0000000 --- a/library/thumbs/solar_battery_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c4c77x5wdjodx" -path="res://.godot/imported/solar_battery_001.png-f2a3a5ed9d2b4456aed950914aed8b82.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/solar_battery_001.png" -dest_files=["res://.godot/imported/solar_battery_001.png-f2a3a5ed9d2b4456aed950914aed8b82.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_015.png b/library/thumbs/stone_015.png deleted file mode 100644 index 675889b..0000000 Binary files a/library/thumbs/stone_015.png and /dev/null differ diff --git a/library/thumbs/stone_015.png.import b/library/thumbs/stone_015.png.import deleted file mode 100644 index 1d3e12b..0000000 --- a/library/thumbs/stone_015.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dtb1og3iwfwe" -path="res://.godot/imported/stone_015.png-4ba9b789eaeecdde965de86d78ba2d5a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_015.png" -dest_files=["res://.godot/imported/stone_015.png-4ba9b789eaeecdde965de86d78ba2d5a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_016.png b/library/thumbs/stone_016.png deleted file mode 100644 index c26145b..0000000 Binary files a/library/thumbs/stone_016.png and /dev/null differ diff --git a/library/thumbs/stone_016.png.import b/library/thumbs/stone_016.png.import deleted file mode 100644 index af6517d..0000000 --- a/library/thumbs/stone_016.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dm2tlla3fnnkd" -path="res://.godot/imported/stone_016.png-7c05c0f51e6a01dd014765990c38cd83.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_016.png" -dest_files=["res://.godot/imported/stone_016.png-7c05c0f51e6a01dd014765990c38cd83.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_017.png b/library/thumbs/stone_017.png deleted file mode 100644 index 4c6cb9f..0000000 Binary files a/library/thumbs/stone_017.png and /dev/null differ diff --git a/library/thumbs/stone_017.png.import b/library/thumbs/stone_017.png.import deleted file mode 100644 index 39addcc..0000000 --- a/library/thumbs/stone_017.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://csker0nqhe4bk" -path="res://.godot/imported/stone_017.png-be36d9354ec1a59dc69d3e5d8c997c16.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_017.png" -dest_files=["res://.godot/imported/stone_017.png-be36d9354ec1a59dc69d3e5d8c997c16.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_018.png b/library/thumbs/stone_018.png deleted file mode 100644 index 6864ce3..0000000 Binary files a/library/thumbs/stone_018.png and /dev/null differ diff --git a/library/thumbs/stone_018.png.import b/library/thumbs/stone_018.png.import deleted file mode 100644 index 2517197..0000000 --- a/library/thumbs/stone_018.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ckq7e5ly4in85" -path="res://.godot/imported/stone_018.png-257610234a9167bc46bc5340d4848391.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_018.png" -dest_files=["res://.godot/imported/stone_018.png-257610234a9167bc46bc5340d4848391.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_019.png b/library/thumbs/stone_019.png deleted file mode 100644 index e387f59..0000000 Binary files a/library/thumbs/stone_019.png and /dev/null differ diff --git a/library/thumbs/stone_019.png.import b/library/thumbs/stone_019.png.import deleted file mode 100644 index e2cfeba..0000000 --- a/library/thumbs/stone_019.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cnbgtgfmkftoi" -path="res://.godot/imported/stone_019.png-4e1338ae1f517674b5f5bd9e8a44e6d4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_019.png" -dest_files=["res://.godot/imported/stone_019.png-4e1338ae1f517674b5f5bd9e8a44e6d4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_020.png b/library/thumbs/stone_020.png deleted file mode 100644 index b99fa49..0000000 Binary files a/library/thumbs/stone_020.png and /dev/null differ diff --git a/library/thumbs/stone_020.png.import b/library/thumbs/stone_020.png.import deleted file mode 100644 index e90b36c..0000000 --- a/library/thumbs/stone_020.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://diqog2ulfs17e" -path="res://.godot/imported/stone_020.png-4acfef624ea8523abd0cb9b554a4576b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_020.png" -dest_files=["res://.godot/imported/stone_020.png-4acfef624ea8523abd0cb9b554a4576b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_021.png b/library/thumbs/stone_021.png deleted file mode 100644 index 3bc82af..0000000 Binary files a/library/thumbs/stone_021.png and /dev/null differ diff --git a/library/thumbs/stone_021.png.import b/library/thumbs/stone_021.png.import deleted file mode 100644 index 3d27bbe..0000000 --- a/library/thumbs/stone_021.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ckrnyf636v4xr" -path="res://.godot/imported/stone_021.png-85bba5383dc73523a94be6de11b73ba6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_021.png" -dest_files=["res://.godot/imported/stone_021.png-85bba5383dc73523a94be6de11b73ba6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_022.png b/library/thumbs/stone_022.png deleted file mode 100644 index ce47763..0000000 Binary files a/library/thumbs/stone_022.png and /dev/null differ diff --git a/library/thumbs/stone_022.png.import b/library/thumbs/stone_022.png.import deleted file mode 100644 index e11b68f..0000000 --- a/library/thumbs/stone_022.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://byiyff8j7nipx" -path="res://.godot/imported/stone_022.png-bc779678d3fa032686f4657f29c7e55c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_022.png" -dest_files=["res://.godot/imported/stone_022.png-bc779678d3fa032686f4657f29c7e55c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_023.png b/library/thumbs/stone_023.png deleted file mode 100644 index 7764adc..0000000 Binary files a/library/thumbs/stone_023.png and /dev/null differ diff --git a/library/thumbs/stone_023.png.import b/library/thumbs/stone_023.png.import deleted file mode 100644 index e47498f..0000000 --- a/library/thumbs/stone_023.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dvc26b5luodxv" -path="res://.godot/imported/stone_023.png-532ac9191b2ae13c035a15a624255547.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_023.png" -dest_files=["res://.godot/imported/stone_023.png-532ac9191b2ae13c035a15a624255547.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_024.png b/library/thumbs/stone_024.png deleted file mode 100644 index 0e76d80..0000000 Binary files a/library/thumbs/stone_024.png and /dev/null differ diff --git a/library/thumbs/stone_024.png.import b/library/thumbs/stone_024.png.import deleted file mode 100644 index 4b1c58e..0000000 --- a/library/thumbs/stone_024.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://3h56equ5a4fp" -path="res://.godot/imported/stone_024.png-55f2358e3087999f25d2029f8eb2778a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_024.png" -dest_files=["res://.godot/imported/stone_024.png-55f2358e3087999f25d2029f8eb2778a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_025.png b/library/thumbs/stone_025.png deleted file mode 100644 index a7a6ec2..0000000 Binary files a/library/thumbs/stone_025.png and /dev/null differ diff --git a/library/thumbs/stone_025.png.import b/library/thumbs/stone_025.png.import deleted file mode 100644 index 5af85b8..0000000 --- a/library/thumbs/stone_025.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bj3dcn4b4nmm5" -path="res://.godot/imported/stone_025.png-1d053a5455a161fd0847ff0c71849249.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_025.png" -dest_files=["res://.godot/imported/stone_025.png-1d053a5455a161fd0847ff0c71849249.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/stone_026.png b/library/thumbs/stone_026.png deleted file mode 100644 index e5e8aea..0000000 Binary files a/library/thumbs/stone_026.png and /dev/null differ diff --git a/library/thumbs/stone_026.png.import b/library/thumbs/stone_026.png.import deleted file mode 100644 index 89f21eb..0000000 --- a/library/thumbs/stone_026.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://tn4oy7opc5x2" -path="res://.godot/imported/stone_026.png-77a63507c15c324b3f6d01cb430277d3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/stone_026.png" -dest_files=["res://.godot/imported/stone_026.png-77a63507c15c324b3f6d01cb430277d3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/table_001.png b/library/thumbs/table_001.png deleted file mode 100644 index 5b1a291..0000000 Binary files a/library/thumbs/table_001.png and /dev/null differ diff --git a/library/thumbs/table_001.png.import b/library/thumbs/table_001.png.import deleted file mode 100644 index 3a7dd5b..0000000 --- a/library/thumbs/table_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://i7clqq0rdhnc" -path="res://.godot/imported/table_001.png-846df9e741bea218022e3f9649b3f2e3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/table_001.png" -dest_files=["res://.godot/imported/table_001.png-846df9e741bea218022e3f9649b3f2e3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/table_002.png b/library/thumbs/table_002.png deleted file mode 100644 index 2160156..0000000 Binary files a/library/thumbs/table_002.png and /dev/null differ diff --git a/library/thumbs/table_002.png.import b/library/thumbs/table_002.png.import deleted file mode 100644 index 9ad50c6..0000000 --- a/library/thumbs/table_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cn6bj5h58agkc" -path="res://.godot/imported/table_002.png-a5b092fca0d8bdb1e7c19b35089bd00c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/table_002.png" -dest_files=["res://.godot/imported/table_002.png-a5b092fca0d8bdb1e7c19b35089bd00c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_001.png b/library/thumbs/tank_001.png deleted file mode 100644 index 5f2bec5..0000000 Binary files a/library/thumbs/tank_001.png and /dev/null differ diff --git a/library/thumbs/tank_001.png.import b/library/thumbs/tank_001.png.import deleted file mode 100644 index 253fb19..0000000 --- a/library/thumbs/tank_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://s7da2jrq1bsj" -path="res://.godot/imported/tank_001.png-c33a075408f31dd87e8a88ce274f91e1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_001.png" -dest_files=["res://.godot/imported/tank_001.png-c33a075408f31dd87e8a88ce274f91e1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_002.png b/library/thumbs/tank_002.png deleted file mode 100644 index 3b1cab9..0000000 Binary files a/library/thumbs/tank_002.png and /dev/null differ diff --git a/library/thumbs/tank_002.png.import b/library/thumbs/tank_002.png.import deleted file mode 100644 index 462ee7a..0000000 --- a/library/thumbs/tank_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bq5qxregnaxa3" -path="res://.godot/imported/tank_002.png-48966ff798887be9f746351b8c7144db.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_002.png" -dest_files=["res://.godot/imported/tank_002.png-48966ff798887be9f746351b8c7144db.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_003.png b/library/thumbs/tank_003.png deleted file mode 100644 index 4f90901..0000000 Binary files a/library/thumbs/tank_003.png and /dev/null differ diff --git a/library/thumbs/tank_003.png.import b/library/thumbs/tank_003.png.import deleted file mode 100644 index be50c9d..0000000 --- a/library/thumbs/tank_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c0s33henaeqsq" -path="res://.godot/imported/tank_003.png-e1f44eb822a36f0f29ec316f67b2ca5a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_003.png" -dest_files=["res://.godot/imported/tank_003.png-e1f44eb822a36f0f29ec316f67b2ca5a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_004.png b/library/thumbs/tank_004.png deleted file mode 100644 index bf834c0..0000000 Binary files a/library/thumbs/tank_004.png and /dev/null differ diff --git a/library/thumbs/tank_004.png.import b/library/thumbs/tank_004.png.import deleted file mode 100644 index 1f499f7..0000000 --- a/library/thumbs/tank_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bc7figva0ic8y" -path="res://.godot/imported/tank_004.png-f55a0b42642ef598afcfcd59cb21c10c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_004.png" -dest_files=["res://.godot/imported/tank_004.png-f55a0b42642ef598afcfcd59cb21c10c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_005.png b/library/thumbs/tank_005.png deleted file mode 100644 index 18604a1..0000000 Binary files a/library/thumbs/tank_005.png and /dev/null differ diff --git a/library/thumbs/tank_005.png.import b/library/thumbs/tank_005.png.import deleted file mode 100644 index a9e1ded..0000000 --- a/library/thumbs/tank_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://m5ah6ofker4o" -path="res://.godot/imported/tank_005.png-6584bb2e4ad4badc485eab27aa0abfd2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_005.png" -dest_files=["res://.godot/imported/tank_005.png-6584bb2e4ad4badc485eab27aa0abfd2.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_006.png b/library/thumbs/tank_006.png deleted file mode 100644 index aa645af..0000000 Binary files a/library/thumbs/tank_006.png and /dev/null differ diff --git a/library/thumbs/tank_006.png.import b/library/thumbs/tank_006.png.import deleted file mode 100644 index b66a47c..0000000 --- a/library/thumbs/tank_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c1ho0muqdt5gc" -path="res://.godot/imported/tank_006.png-eb992dee4b6f259b95063ad7d9257a82.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_006.png" -dest_files=["res://.godot/imported/tank_006.png-eb992dee4b6f259b95063ad7d9257a82.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_car_001.png b/library/thumbs/tank_car_001.png deleted file mode 100644 index deb37b6..0000000 Binary files a/library/thumbs/tank_car_001.png and /dev/null differ diff --git a/library/thumbs/tank_car_001.png.import b/library/thumbs/tank_car_001.png.import deleted file mode 100644 index 1cfc79d..0000000 --- a/library/thumbs/tank_car_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d1uspdcqy671j" -path="res://.godot/imported/tank_car_001.png-232603046df3985889070ff812d5f73c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_car_001.png" -dest_files=["res://.godot/imported/tank_car_001.png-232603046df3985889070ff812d5f73c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_car_002.png b/library/thumbs/tank_car_002.png deleted file mode 100644 index 55b553d..0000000 Binary files a/library/thumbs/tank_car_002.png and /dev/null differ diff --git a/library/thumbs/tank_car_002.png.import b/library/thumbs/tank_car_002.png.import deleted file mode 100644 index a9c8d21..0000000 --- a/library/thumbs/tank_car_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://crjupmrbyekbf" -path="res://.godot/imported/tank_car_002.png-e0d5a99c93e665f1a436528a74e9e63c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_car_002.png" -dest_files=["res://.godot/imported/tank_car_002.png-e0d5a99c93e665f1a436528a74e9e63c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_gun_001.png b/library/thumbs/tank_gun_001.png deleted file mode 100644 index bbd0da5..0000000 Binary files a/library/thumbs/tank_gun_001.png and /dev/null differ diff --git a/library/thumbs/tank_gun_001.png.import b/library/thumbs/tank_gun_001.png.import deleted file mode 100644 index 738fdc4..0000000 --- a/library/thumbs/tank_gun_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bjvtdvrb7eiy0" -path="res://.godot/imported/tank_gun_001.png-3927aac85abb07aef874d00583321214.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_gun_001.png" -dest_files=["res://.godot/imported/tank_gun_001.png-3927aac85abb07aef874d00583321214.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_gun_002.png b/library/thumbs/tank_gun_002.png deleted file mode 100644 index bbd0da5..0000000 Binary files a/library/thumbs/tank_gun_002.png and /dev/null differ diff --git a/library/thumbs/tank_gun_002.png.import b/library/thumbs/tank_gun_002.png.import deleted file mode 100644 index 25ad3b5..0000000 --- a/library/thumbs/tank_gun_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://yrjbjeu7drjq" -path="res://.godot/imported/tank_gun_002.png-0fd88b8217bb456d4e69ad3edc518588.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_gun_002.png" -dest_files=["res://.godot/imported/tank_gun_002.png-0fd88b8217bb456d4e69ad3edc518588.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_gun_003.png b/library/thumbs/tank_gun_003.png deleted file mode 100644 index 41b51f4..0000000 Binary files a/library/thumbs/tank_gun_003.png and /dev/null differ diff --git a/library/thumbs/tank_gun_003.png.import b/library/thumbs/tank_gun_003.png.import deleted file mode 100644 index c928101..0000000 --- a/library/thumbs/tank_gun_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://rfgcwnh7b6cg" -path="res://.godot/imported/tank_gun_003.png-b276bc3758d1340e786ce2a21903f610.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_gun_003.png" -dest_files=["res://.godot/imported/tank_gun_003.png-b276bc3758d1340e786ce2a21903f610.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_gun_004.png b/library/thumbs/tank_gun_004.png deleted file mode 100644 index 41b51f4..0000000 Binary files a/library/thumbs/tank_gun_004.png and /dev/null differ diff --git a/library/thumbs/tank_gun_004.png.import b/library/thumbs/tank_gun_004.png.import deleted file mode 100644 index 7f4416c..0000000 --- a/library/thumbs/tank_gun_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ccqoxatj1ltv5" -path="res://.godot/imported/tank_gun_004.png-acfdf6a77d17b632ac4fc5cea9fb24da.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_gun_004.png" -dest_files=["res://.godot/imported/tank_gun_004.png-acfdf6a77d17b632ac4fc5cea9fb24da.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_gun_005.png b/library/thumbs/tank_gun_005.png deleted file mode 100644 index 0ef4a51..0000000 Binary files a/library/thumbs/tank_gun_005.png and /dev/null differ diff --git a/library/thumbs/tank_gun_005.png.import b/library/thumbs/tank_gun_005.png.import deleted file mode 100644 index b152329..0000000 --- a/library/thumbs/tank_gun_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bljeq26jlq7bs" -path="res://.godot/imported/tank_gun_005.png-99e4a4b027675fc9ba9da42f400d8a41.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_gun_005.png" -dest_files=["res://.godot/imported/tank_gun_005.png-99e4a4b027675fc9ba9da42f400d8a41.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_gun_006.png b/library/thumbs/tank_gun_006.png deleted file mode 100644 index 0ef4a51..0000000 Binary files a/library/thumbs/tank_gun_006.png and /dev/null differ diff --git a/library/thumbs/tank_gun_006.png.import b/library/thumbs/tank_gun_006.png.import deleted file mode 100644 index 37bc8b8..0000000 --- a/library/thumbs/tank_gun_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bao5dy3lx3w4l" -path="res://.godot/imported/tank_gun_006.png-92666b31fd4ae46ea22f517d1364154d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_gun_006.png" -dest_files=["res://.godot/imported/tank_gun_006.png-92666b31fd4ae46ea22f517d1364154d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_tower_001.png b/library/thumbs/tank_tower_001.png deleted file mode 100644 index 1a00e70..0000000 Binary files a/library/thumbs/tank_tower_001.png and /dev/null differ diff --git a/library/thumbs/tank_tower_001.png.import b/library/thumbs/tank_tower_001.png.import deleted file mode 100644 index 7dded7c..0000000 --- a/library/thumbs/tank_tower_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ccrk564gir3dh" -path="res://.godot/imported/tank_tower_001.png-b4be93ceea2aa60acb735e895b002b13.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_tower_001.png" -dest_files=["res://.godot/imported/tank_tower_001.png-b4be93ceea2aa60acb735e895b002b13.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_tower_002.png b/library/thumbs/tank_tower_002.png deleted file mode 100644 index 606b614..0000000 Binary files a/library/thumbs/tank_tower_002.png and /dev/null differ diff --git a/library/thumbs/tank_tower_002.png.import b/library/thumbs/tank_tower_002.png.import deleted file mode 100644 index b868492..0000000 --- a/library/thumbs/tank_tower_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dc5i07vpia11j" -path="res://.godot/imported/tank_tower_002.png-31a276dd6d2c3563d5029ad741bf4225.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_tower_002.png" -dest_files=["res://.godot/imported/tank_tower_002.png-31a276dd6d2c3563d5029ad741bf4225.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_tower_003.png b/library/thumbs/tank_tower_003.png deleted file mode 100644 index cb18c82..0000000 Binary files a/library/thumbs/tank_tower_003.png and /dev/null differ diff --git a/library/thumbs/tank_tower_003.png.import b/library/thumbs/tank_tower_003.png.import deleted file mode 100644 index ec592b9..0000000 --- a/library/thumbs/tank_tower_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b6lw82uah2oto" -path="res://.godot/imported/tank_tower_003.png-1bddc8ac67991200fc01aa0104905a23.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_tower_003.png" -dest_files=["res://.godot/imported/tank_tower_003.png-1bddc8ac67991200fc01aa0104905a23.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_tower_004.png b/library/thumbs/tank_tower_004.png deleted file mode 100644 index 4d088e7..0000000 Binary files a/library/thumbs/tank_tower_004.png and /dev/null differ diff --git a/library/thumbs/tank_tower_004.png.import b/library/thumbs/tank_tower_004.png.import deleted file mode 100644 index 491c62c..0000000 --- a/library/thumbs/tank_tower_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bx0j38ylnr6w8" -path="res://.godot/imported/tank_tower_004.png-e178df64fc77393a76332f39c55165d1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_tower_004.png" -dest_files=["res://.godot/imported/tank_tower_004.png-e178df64fc77393a76332f39c55165d1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_tower_005.png b/library/thumbs/tank_tower_005.png deleted file mode 100644 index 93cd878..0000000 Binary files a/library/thumbs/tank_tower_005.png and /dev/null differ diff --git a/library/thumbs/tank_tower_005.png.import b/library/thumbs/tank_tower_005.png.import deleted file mode 100644 index 4c67a7a..0000000 --- a/library/thumbs/tank_tower_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://vh6e3dio2mv4" -path="res://.godot/imported/tank_tower_005.png-aebb87e93e44a3bc52a95eb8befc7d21.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_tower_005.png" -dest_files=["res://.godot/imported/tank_tower_005.png-aebb87e93e44a3bc52a95eb8befc7d21.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tank_tower_006.png b/library/thumbs/tank_tower_006.png deleted file mode 100644 index 7db461d..0000000 Binary files a/library/thumbs/tank_tower_006.png and /dev/null differ diff --git a/library/thumbs/tank_tower_006.png.import b/library/thumbs/tank_tower_006.png.import deleted file mode 100644 index df9c921..0000000 --- a/library/thumbs/tank_tower_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://do7q0034128nw" -path="res://.godot/imported/tank_tower_006.png-5da0ce988069b5643f991fa62f9be65c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tank_tower_006.png" -dest_files=["res://.godot/imported/tank_tower_006.png-5da0ce988069b5643f991fa62f9be65c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/target_001.png b/library/thumbs/target_001.png deleted file mode 100644 index 6c7648b..0000000 Binary files a/library/thumbs/target_001.png and /dev/null differ diff --git a/library/thumbs/target_001.png.import b/library/thumbs/target_001.png.import deleted file mode 100644 index 4273a62..0000000 --- a/library/thumbs/target_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://g3x5f182upqf" -path="res://.godot/imported/target_001.png-fa85c0fd8ac4f620dc0f5fa8b5b35b6a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/target_001.png" -dest_files=["res://.godot/imported/target_001.png-fa85c0fd8ac4f620dc0f5fa8b5b35b6a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/target_002.png b/library/thumbs/target_002.png deleted file mode 100644 index e207767..0000000 Binary files a/library/thumbs/target_002.png and /dev/null differ diff --git a/library/thumbs/target_002.png.import b/library/thumbs/target_002.png.import deleted file mode 100644 index db6641d..0000000 --- a/library/thumbs/target_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://lms6ht050t8p" -path="res://.godot/imported/target_002.png-333e6ad869b39f92a46771482c93902f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/target_002.png" -dest_files=["res://.godot/imported/target_002.png-333e6ad869b39f92a46771482c93902f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_001.png b/library/thumbs/tent_001.png deleted file mode 100644 index 749ec44..0000000 Binary files a/library/thumbs/tent_001.png and /dev/null differ diff --git a/library/thumbs/tent_001.png.import b/library/thumbs/tent_001.png.import deleted file mode 100644 index 8fa1dad..0000000 --- a/library/thumbs/tent_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dt4bphl5s2u3s" -path="res://.godot/imported/tent_001.png-7385b63f22f8d281970d821b6fb1fbb0.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_001.png" -dest_files=["res://.godot/imported/tent_001.png-7385b63f22f8d281970d821b6fb1fbb0.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_002.png b/library/thumbs/tent_002.png deleted file mode 100644 index 57f3589..0000000 Binary files a/library/thumbs/tent_002.png and /dev/null differ diff --git a/library/thumbs/tent_002.png.import b/library/thumbs/tent_002.png.import deleted file mode 100644 index 6d5d11b..0000000 --- a/library/thumbs/tent_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bsu6fo4pny11u" -path="res://.godot/imported/tent_002.png-c4b5f9b3df1d4dda0aa0caa8fce1729b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_002.png" -dest_files=["res://.godot/imported/tent_002.png-c4b5f9b3df1d4dda0aa0caa8fce1729b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_003.png b/library/thumbs/tent_003.png deleted file mode 100644 index 19d1cdb..0000000 Binary files a/library/thumbs/tent_003.png and /dev/null differ diff --git a/library/thumbs/tent_003.png.import b/library/thumbs/tent_003.png.import deleted file mode 100644 index 87e4a5e..0000000 --- a/library/thumbs/tent_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://crg6kt3c26gdj" -path="res://.godot/imported/tent_003.png-37e2a6d63864ffefeb79999c3d78e4cd.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_003.png" -dest_files=["res://.godot/imported/tent_003.png-37e2a6d63864ffefeb79999c3d78e4cd.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_004.png b/library/thumbs/tent_004.png deleted file mode 100644 index 0a54a5f..0000000 Binary files a/library/thumbs/tent_004.png and /dev/null differ diff --git a/library/thumbs/tent_004.png.import b/library/thumbs/tent_004.png.import deleted file mode 100644 index aa8094d..0000000 --- a/library/thumbs/tent_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dvfrvy68xi38m" -path="res://.godot/imported/tent_004.png-1c3a27cc0863a123f673c330be0c5511.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_004.png" -dest_files=["res://.godot/imported/tent_004.png-1c3a27cc0863a123f673c330be0c5511.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_005.png b/library/thumbs/tent_005.png deleted file mode 100644 index af1f00e..0000000 Binary files a/library/thumbs/tent_005.png and /dev/null differ diff --git a/library/thumbs/tent_005.png.import b/library/thumbs/tent_005.png.import deleted file mode 100644 index b0538fb..0000000 --- a/library/thumbs/tent_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ccomssilu5yod" -path="res://.godot/imported/tent_005.png-5d644613a4bf798c8fa67f8811f5aee0.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_005.png" -dest_files=["res://.godot/imported/tent_005.png-5d644613a4bf798c8fa67f8811f5aee0.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_006.png b/library/thumbs/tent_006.png deleted file mode 100644 index 9d3a6d1..0000000 Binary files a/library/thumbs/tent_006.png and /dev/null differ diff --git a/library/thumbs/tent_006.png.import b/library/thumbs/tent_006.png.import deleted file mode 100644 index b608d2d..0000000 --- a/library/thumbs/tent_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d2mniupi8lq33" -path="res://.godot/imported/tent_006.png-4a325af4134234696db8528e9bf076c2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_006.png" -dest_files=["res://.godot/imported/tent_006.png-4a325af4134234696db8528e9bf076c2.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_007.png b/library/thumbs/tent_007.png deleted file mode 100644 index 85d903d..0000000 Binary files a/library/thumbs/tent_007.png and /dev/null differ diff --git a/library/thumbs/tent_007.png.import b/library/thumbs/tent_007.png.import deleted file mode 100644 index 0b9b4b5..0000000 --- a/library/thumbs/tent_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://datgl70wb1ail" -path="res://.godot/imported/tent_007.png-2f8bc7bf597ee69ff966b16886cc55c5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_007.png" -dest_files=["res://.godot/imported/tent_007.png-2f8bc7bf597ee69ff966b16886cc55c5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_008.png b/library/thumbs/tent_008.png deleted file mode 100644 index 536c5bf..0000000 Binary files a/library/thumbs/tent_008.png and /dev/null differ diff --git a/library/thumbs/tent_008.png.import b/library/thumbs/tent_008.png.import deleted file mode 100644 index 28bc4c4..0000000 --- a/library/thumbs/tent_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://xff8xuxq62p3" -path="res://.godot/imported/tent_008.png-9da327cda8f04ce6a7263072826889ff.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_008.png" -dest_files=["res://.godot/imported/tent_008.png-9da327cda8f04ce6a7263072826889ff.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_009.png b/library/thumbs/tent_009.png deleted file mode 100644 index c9e38b8..0000000 Binary files a/library/thumbs/tent_009.png and /dev/null differ diff --git a/library/thumbs/tent_009.png.import b/library/thumbs/tent_009.png.import deleted file mode 100644 index d77563f..0000000 --- a/library/thumbs/tent_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bjlho0rj4ensq" -path="res://.godot/imported/tent_009.png-5a9ecbfb0cef4e4aa3b6af9eef242bae.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_009.png" -dest_files=["res://.godot/imported/tent_009.png-5a9ecbfb0cef4e4aa3b6af9eef242bae.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_010.png b/library/thumbs/tent_010.png deleted file mode 100644 index b562db8..0000000 Binary files a/library/thumbs/tent_010.png and /dev/null differ diff --git a/library/thumbs/tent_010.png.import b/library/thumbs/tent_010.png.import deleted file mode 100644 index 63612c1..0000000 --- a/library/thumbs/tent_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://uijfkbw2kitk" -path="res://.godot/imported/tent_010.png-9c3051d38a1d0ba05996098998070422.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_010.png" -dest_files=["res://.godot/imported/tent_010.png-9c3051d38a1d0ba05996098998070422.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_011.png b/library/thumbs/tent_011.png deleted file mode 100644 index 2e288e7..0000000 Binary files a/library/thumbs/tent_011.png and /dev/null differ diff --git a/library/thumbs/tent_011.png.import b/library/thumbs/tent_011.png.import deleted file mode 100644 index 21dd902..0000000 --- a/library/thumbs/tent_011.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c1qlj52ut2qme" -path="res://.godot/imported/tent_011.png-93daf7716b9aa0fca562610607122c58.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_011.png" -dest_files=["res://.godot/imported/tent_011.png-93daf7716b9aa0fca562610607122c58.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_012.png b/library/thumbs/tent_012.png deleted file mode 100644 index 77ed004..0000000 Binary files a/library/thumbs/tent_012.png and /dev/null differ diff --git a/library/thumbs/tent_012.png.import b/library/thumbs/tent_012.png.import deleted file mode 100644 index db43914..0000000 --- a/library/thumbs/tent_012.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dtrerhrrr6bbu" -path="res://.godot/imported/tent_012.png-6c8b99034ba7773c32c2382d5eef7a45.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_012.png" -dest_files=["res://.godot/imported/tent_012.png-6c8b99034ba7773c32c2382d5eef7a45.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_013.png b/library/thumbs/tent_013.png deleted file mode 100644 index 572b6c3..0000000 Binary files a/library/thumbs/tent_013.png and /dev/null differ diff --git a/library/thumbs/tent_013.png.import b/library/thumbs/tent_013.png.import deleted file mode 100644 index ab2ec90..0000000 --- a/library/thumbs/tent_013.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c73gf472npmoo" -path="res://.godot/imported/tent_013.png-8743f80bf583b6a3651911725a05e8c6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_013.png" -dest_files=["res://.godot/imported/tent_013.png-8743f80bf583b6a3651911725a05e8c6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tent_014.png b/library/thumbs/tent_014.png deleted file mode 100644 index e396378..0000000 Binary files a/library/thumbs/tent_014.png and /dev/null differ diff --git a/library/thumbs/tent_014.png.import b/library/thumbs/tent_014.png.import deleted file mode 100644 index b8d9945..0000000 --- a/library/thumbs/tent_014.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dpskwwxwixkjv" -path="res://.godot/imported/tent_014.png-1ef0aa893666a207a13fb8c8478e1503.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tent_014.png" -dest_files=["res://.godot/imported/tent_014.png-1ef0aa893666a207a13fb8c8478e1503.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tire_001.png b/library/thumbs/tire_001.png deleted file mode 100644 index bcfba99..0000000 Binary files a/library/thumbs/tire_001.png and /dev/null differ diff --git a/library/thumbs/tire_001.png.import b/library/thumbs/tire_001.png.import deleted file mode 100644 index 61dda48..0000000 --- a/library/thumbs/tire_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dsf76mlk4u1it" -path="res://.godot/imported/tire_001.png-9fa63333b1a839c808eb14a7e997e664.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tire_001.png" -dest_files=["res://.godot/imported/tire_001.png-9fa63333b1a839c808eb14a7e997e664.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tires_001.png b/library/thumbs/tires_001.png deleted file mode 100644 index 28cb7df..0000000 Binary files a/library/thumbs/tires_001.png and /dev/null differ diff --git a/library/thumbs/tires_001.png.import b/library/thumbs/tires_001.png.import deleted file mode 100644 index 0de8cee..0000000 --- a/library/thumbs/tires_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://7twmv0psktwm" -path="res://.godot/imported/tires_001.png-c94b9064e82d44940dd442e7f9a495d8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tires_001.png" -dest_files=["res://.godot/imported/tires_001.png-c94b9064e82d44940dd442e7f9a495d8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/toilet_001.png b/library/thumbs/toilet_001.png deleted file mode 100644 index 1820f09..0000000 Binary files a/library/thumbs/toilet_001.png and /dev/null differ diff --git a/library/thumbs/toilet_001.png.import b/library/thumbs/toilet_001.png.import deleted file mode 100644 index 5f602f2..0000000 --- a/library/thumbs/toilet_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c7lb2lxa6y3d8" -path="res://.godot/imported/toilet_001.png-819030e841b0b7ae9cebb38e304124e5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/toilet_001.png" -dest_files=["res://.godot/imported/toilet_001.png-819030e841b0b7ae9cebb38e304124e5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/toilet_002.png b/library/thumbs/toilet_002.png deleted file mode 100644 index 6420195..0000000 Binary files a/library/thumbs/toilet_002.png and /dev/null differ diff --git a/library/thumbs/toilet_002.png.import b/library/thumbs/toilet_002.png.import deleted file mode 100644 index dcf0853..0000000 --- a/library/thumbs/toilet_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c2evauos4cjmc" -path="res://.godot/imported/toilet_002.png-136da863f58d3f92a837bd90aabbd669.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/toilet_002.png" -dest_files=["res://.godot/imported/toilet_002.png-136da863f58d3f92a837bd90aabbd669.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tower_001.png b/library/thumbs/tower_001.png deleted file mode 100644 index c47a20d..0000000 Binary files a/library/thumbs/tower_001.png and /dev/null differ diff --git a/library/thumbs/tower_001.png.import b/library/thumbs/tower_001.png.import deleted file mode 100644 index 8e52bb8..0000000 --- a/library/thumbs/tower_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://btie0u7u5us1j" -path="res://.godot/imported/tower_001.png-c37deb0e247b1ea8acf1d07ac22da509.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tower_001.png" -dest_files=["res://.godot/imported/tower_001.png-c37deb0e247b1ea8acf1d07ac22da509.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tower_002.png b/library/thumbs/tower_002.png deleted file mode 100644 index bd73c6b..0000000 Binary files a/library/thumbs/tower_002.png and /dev/null differ diff --git a/library/thumbs/tower_002.png.import b/library/thumbs/tower_002.png.import deleted file mode 100644 index 39a026c..0000000 --- a/library/thumbs/tower_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bg8egveebkqtn" -path="res://.godot/imported/tower_002.png-c0f0ed4216f6809db7f3450467a14801.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tower_002.png" -dest_files=["res://.godot/imported/tower_002.png-c0f0ed4216f6809db7f3450467a14801.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tower_003.png b/library/thumbs/tower_003.png deleted file mode 100644 index 99ee0ef..0000000 Binary files a/library/thumbs/tower_003.png and /dev/null differ diff --git a/library/thumbs/tower_003.png.import b/library/thumbs/tower_003.png.import deleted file mode 100644 index 84ef0e2..0000000 --- a/library/thumbs/tower_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cqefoivn65l07" -path="res://.godot/imported/tower_003.png-69f1b18eb4d0497262af5f6c6b2b14ce.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tower_003.png" -dest_files=["res://.godot/imported/tower_003.png-69f1b18eb4d0497262af5f6c6b2b14ce.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tower_004.png b/library/thumbs/tower_004.png deleted file mode 100644 index 35b0a10..0000000 Binary files a/library/thumbs/tower_004.png and /dev/null differ diff --git a/library/thumbs/tower_004.png.import b/library/thumbs/tower_004.png.import deleted file mode 100644 index 4a5298e..0000000 --- a/library/thumbs/tower_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dcbh5utqixwk0" -path="res://.godot/imported/tower_004.png-6f158de3ef0e45b8f6f18568084ee234.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tower_004.png" -dest_files=["res://.godot/imported/tower_004.png-6f158de3ef0e45b8f6f18568084ee234.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/tower_005.png b/library/thumbs/tower_005.png deleted file mode 100644 index 4364599..0000000 Binary files a/library/thumbs/tower_005.png and /dev/null differ diff --git a/library/thumbs/tower_005.png.import b/library/thumbs/tower_005.png.import deleted file mode 100644 index 1a6dcee..0000000 --- a/library/thumbs/tower_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cgiiaafka6icd" -path="res://.godot/imported/tower_005.png-31d68f2ba97e336a5e53c9bb1b8ada87.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/tower_005.png" -dest_files=["res://.godot/imported/tower_005.png-31d68f2ba97e336a5e53c9bb1b8ada87.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/training_item_001.png b/library/thumbs/training_item_001.png deleted file mode 100644 index d709eb9..0000000 Binary files a/library/thumbs/training_item_001.png and /dev/null differ diff --git a/library/thumbs/training_item_001.png.import b/library/thumbs/training_item_001.png.import deleted file mode 100644 index 365063f..0000000 --- a/library/thumbs/training_item_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d260clhi0wwyy" -path="res://.godot/imported/training_item_001.png-ccfccc4ea1bf68656c94a86979f98367.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/training_item_001.png" -dest_files=["res://.godot/imported/training_item_001.png-ccfccc4ea1bf68656c94a86979f98367.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/training_item_002.png b/library/thumbs/training_item_002.png deleted file mode 100644 index 08dc236..0000000 Binary files a/library/thumbs/training_item_002.png and /dev/null differ diff --git a/library/thumbs/training_item_002.png.import b/library/thumbs/training_item_002.png.import deleted file mode 100644 index d388426..0000000 --- a/library/thumbs/training_item_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://legpdh1bx38h" -path="res://.godot/imported/training_item_002.png-314bbee51b1c0897dc425d734e878c92.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/training_item_002.png" -dest_files=["res://.godot/imported/training_item_002.png-314bbee51b1c0897dc425d734e878c92.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/training_item_003.png b/library/thumbs/training_item_003.png deleted file mode 100644 index f9e899c..0000000 Binary files a/library/thumbs/training_item_003.png and /dev/null differ diff --git a/library/thumbs/training_item_003.png.import b/library/thumbs/training_item_003.png.import deleted file mode 100644 index 0cd7d18..0000000 --- a/library/thumbs/training_item_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dr10bl6u2v5no" -path="res://.godot/imported/training_item_003.png-828718d310d77a0768a6ff95b9ee92d5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/training_item_003.png" -dest_files=["res://.godot/imported/training_item_003.png-828718d310d77a0768a6ff95b9ee92d5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/training_item_004.png b/library/thumbs/training_item_004.png deleted file mode 100644 index cc342ae..0000000 Binary files a/library/thumbs/training_item_004.png and /dev/null differ diff --git a/library/thumbs/training_item_004.png.import b/library/thumbs/training_item_004.png.import deleted file mode 100644 index e8bf6fe..0000000 --- a/library/thumbs/training_item_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b2562ekpsuvoa" -path="res://.godot/imported/training_item_004.png-0940defbc1998320991d7212f5569a78.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/training_item_004.png" -dest_files=["res://.godot/imported/training_item_004.png-0940defbc1998320991d7212f5569a78.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/training_item_005.png b/library/thumbs/training_item_005.png deleted file mode 100644 index 05a21ae..0000000 Binary files a/library/thumbs/training_item_005.png and /dev/null differ diff --git a/library/thumbs/training_item_005.png.import b/library/thumbs/training_item_005.png.import deleted file mode 100644 index 87c57af..0000000 --- a/library/thumbs/training_item_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bf6184tgvvaxh" -path="res://.godot/imported/training_item_005.png-738cc639936e11695955de0835e858fe.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/training_item_005.png" -dest_files=["res://.godot/imported/training_item_005.png-738cc639936e11695955de0835e858fe.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/training_item_006.png b/library/thumbs/training_item_006.png deleted file mode 100644 index 525605e..0000000 Binary files a/library/thumbs/training_item_006.png and /dev/null differ diff --git a/library/thumbs/training_item_006.png.import b/library/thumbs/training_item_006.png.import deleted file mode 100644 index a1c24bb..0000000 --- a/library/thumbs/training_item_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b2paoa51kaa24" -path="res://.godot/imported/training_item_006.png-80d4764e2a5fbe0b18552e6a98d5811b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/training_item_006.png" -dest_files=["res://.godot/imported/training_item_006.png-80d4764e2a5fbe0b18552e6a98d5811b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/training_item_007.png b/library/thumbs/training_item_007.png deleted file mode 100644 index 7ff78ed..0000000 Binary files a/library/thumbs/training_item_007.png and /dev/null differ diff --git a/library/thumbs/training_item_007.png.import b/library/thumbs/training_item_007.png.import deleted file mode 100644 index 5cedfe4..0000000 --- a/library/thumbs/training_item_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dcxu0tl1870tx" -path="res://.godot/imported/training_item_007.png-f28c4411b454f3834ec94679b7ffcfe7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/training_item_007.png" -dest_files=["res://.godot/imported/training_item_007.png-f28c4411b454f3834ec94679b7ffcfe7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_001.png b/library/thumbs/truck_001.png deleted file mode 100644 index 75e3ca9..0000000 Binary files a/library/thumbs/truck_001.png and /dev/null differ diff --git a/library/thumbs/truck_001.png.import b/library/thumbs/truck_001.png.import deleted file mode 100644 index ae32889..0000000 --- a/library/thumbs/truck_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bhy60eturmo2b" -path="res://.godot/imported/truck_001.png-3325680b287804d227a839ab10d2709a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_001.png" -dest_files=["res://.godot/imported/truck_001.png-3325680b287804d227a839ab10d2709a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_002.png b/library/thumbs/truck_002.png deleted file mode 100644 index 37d8f5d..0000000 Binary files a/library/thumbs/truck_002.png and /dev/null differ diff --git a/library/thumbs/truck_002.png.import b/library/thumbs/truck_002.png.import deleted file mode 100644 index 0b9b97e..0000000 --- a/library/thumbs/truck_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b2y7a7x3uuj56" -path="res://.godot/imported/truck_002.png-e754176ac420829ed2e0c229ec0bb8df.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_002.png" -dest_files=["res://.godot/imported/truck_002.png-e754176ac420829ed2e0c229ec0bb8df.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_002_aufbau.png b/library/thumbs/truck_002_aufbau.png deleted file mode 100644 index 37d8f5d..0000000 Binary files a/library/thumbs/truck_002_aufbau.png and /dev/null differ diff --git a/library/thumbs/truck_002_aufbau.png.import b/library/thumbs/truck_002_aufbau.png.import deleted file mode 100644 index ba5de30..0000000 --- a/library/thumbs/truck_002_aufbau.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cus8pd1c8hrp" -path="res://.godot/imported/truck_002_aufbau.png-8c345754c8e98f99a476b201aa981580.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_002_aufbau.png" -dest_files=["res://.godot/imported/truck_002_aufbau.png-8c345754c8e98f99a476b201aa981580.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_002_tank.png b/library/thumbs/truck_002_tank.png deleted file mode 100644 index 37d8f5d..0000000 Binary files a/library/thumbs/truck_002_tank.png and /dev/null differ diff --git a/library/thumbs/truck_002_tank.png.import b/library/thumbs/truck_002_tank.png.import deleted file mode 100644 index 0aa8e49..0000000 --- a/library/thumbs/truck_002_tank.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dryok08p6820j" -path="res://.godot/imported/truck_002_tank.png-dffb6c422697d547afb76f7a60549448.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_002_tank.png" -dest_files=["res://.godot/imported/truck_002_tank.png-dffb6c422697d547afb76f7a60549448.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_003.png b/library/thumbs/truck_003.png deleted file mode 100644 index 360177a..0000000 Binary files a/library/thumbs/truck_003.png and /dev/null differ diff --git a/library/thumbs/truck_003.png.import b/library/thumbs/truck_003.png.import deleted file mode 100644 index eef65ae..0000000 --- a/library/thumbs/truck_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dsgsqlhoy81t" -path="res://.godot/imported/truck_003.png-573f35fe4552fbce2ec7c480d1d95720.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_003.png" -dest_files=["res://.godot/imported/truck_003.png-573f35fe4552fbce2ec7c480d1d95720.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_004.png b/library/thumbs/truck_004.png deleted file mode 100644 index 569c6fb..0000000 Binary files a/library/thumbs/truck_004.png and /dev/null differ diff --git a/library/thumbs/truck_004.png.import b/library/thumbs/truck_004.png.import deleted file mode 100644 index 62c6abf..0000000 --- a/library/thumbs/truck_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bp0jmoifx53om" -path="res://.godot/imported/truck_004.png-258aa0e8d4a52aa3bac33102de1a9e3f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_004.png" -dest_files=["res://.godot/imported/truck_004.png-258aa0e8d4a52aa3bac33102de1a9e3f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_004_aufbau.png b/library/thumbs/truck_004_aufbau.png deleted file mode 100644 index 569c6fb..0000000 Binary files a/library/thumbs/truck_004_aufbau.png and /dev/null differ diff --git a/library/thumbs/truck_004_aufbau.png.import b/library/thumbs/truck_004_aufbau.png.import deleted file mode 100644 index 8da9fdb..0000000 --- a/library/thumbs/truck_004_aufbau.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bnlx2tqytt6ia" -path="res://.godot/imported/truck_004_aufbau.png-79ad47e5cbb9ac3b25de11d152aa663d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_004_aufbau.png" -dest_files=["res://.godot/imported/truck_004_aufbau.png-79ad47e5cbb9ac3b25de11d152aa663d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_004_plane.png b/library/thumbs/truck_004_plane.png deleted file mode 100644 index 569c6fb..0000000 Binary files a/library/thumbs/truck_004_plane.png and /dev/null differ diff --git a/library/thumbs/truck_004_plane.png.import b/library/thumbs/truck_004_plane.png.import deleted file mode 100644 index 9954976..0000000 --- a/library/thumbs/truck_004_plane.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cfxqbg0fympbw" -path="res://.godot/imported/truck_004_plane.png-7c13505831277b297a59417940bc9cfb.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_004_plane.png" -dest_files=["res://.godot/imported/truck_004_plane.png-7c13505831277b297a59417940bc9cfb.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_body_001.png b/library/thumbs/truck_body_001.png deleted file mode 100644 index 59ca593..0000000 Binary files a/library/thumbs/truck_body_001.png and /dev/null differ diff --git a/library/thumbs/truck_body_001.png.import b/library/thumbs/truck_body_001.png.import deleted file mode 100644 index 1273fc0..0000000 --- a/library/thumbs/truck_body_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ckr7nlw5sxgii" -path="res://.godot/imported/truck_body_001.png-a06304f26c98fb9796fd12f3333f6cd6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_body_001.png" -dest_files=["res://.godot/imported/truck_body_001.png-a06304f26c98fb9796fd12f3333f6cd6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_body_002.png b/library/thumbs/truck_body_002.png deleted file mode 100644 index 94d0dc2..0000000 Binary files a/library/thumbs/truck_body_002.png and /dev/null differ diff --git a/library/thumbs/truck_body_002.png.import b/library/thumbs/truck_body_002.png.import deleted file mode 100644 index 9e225b7..0000000 --- a/library/thumbs/truck_body_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dmuoiyehf5fxd" -path="res://.godot/imported/truck_body_002.png-1638adf81a3152371921a9eed6998814.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_body_002.png" -dest_files=["res://.godot/imported/truck_body_002.png-1638adf81a3152371921a9eed6998814.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_body_003.png b/library/thumbs/truck_body_003.png deleted file mode 100644 index 639120f..0000000 Binary files a/library/thumbs/truck_body_003.png and /dev/null differ diff --git a/library/thumbs/truck_body_003.png.import b/library/thumbs/truck_body_003.png.import deleted file mode 100644 index 3b5e6be..0000000 --- a/library/thumbs/truck_body_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ei5kwymgtmcx" -path="res://.godot/imported/truck_body_003.png-de8497709c0c5495ea42ac8ba0f5f0ce.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_body_003.png" -dest_files=["res://.godot/imported/truck_body_003.png-de8497709c0c5495ea42ac8ba0f5f0ce.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_body_004.png b/library/thumbs/truck_body_004.png deleted file mode 100644 index 2fab29b..0000000 Binary files a/library/thumbs/truck_body_004.png and /dev/null differ diff --git a/library/thumbs/truck_body_004.png.import b/library/thumbs/truck_body_004.png.import deleted file mode 100644 index 688a127..0000000 --- a/library/thumbs/truck_body_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://buu5pqdjf8ko3" -path="res://.godot/imported/truck_body_004.png-fcefd999515dd45b127151a5c07aa1bd.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_body_004.png" -dest_files=["res://.godot/imported/truck_body_004.png-fcefd999515dd45b127151a5c07aa1bd.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_body_005.png b/library/thumbs/truck_body_005.png deleted file mode 100644 index 0848772..0000000 Binary files a/library/thumbs/truck_body_005.png and /dev/null differ diff --git a/library/thumbs/truck_body_005.png.import b/library/thumbs/truck_body_005.png.import deleted file mode 100644 index 2a6c94a..0000000 --- a/library/thumbs/truck_body_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://073gsyir4ypg" -path="res://.godot/imported/truck_body_005.png-135b1a102127bf4f6246ab0fd3c14fb4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_body_005.png" -dest_files=["res://.godot/imported/truck_body_005.png-135b1a102127bf4f6246ab0fd3c14fb4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/truck_body_006.png b/library/thumbs/truck_body_006.png deleted file mode 100644 index 748f066..0000000 Binary files a/library/thumbs/truck_body_006.png and /dev/null differ diff --git a/library/thumbs/truck_body_006.png.import b/library/thumbs/truck_body_006.png.import deleted file mode 100644 index d8a79ee..0000000 --- a/library/thumbs/truck_body_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bc2bac73dm2jw" -path="res://.godot/imported/truck_body_006.png-cdadf65ca84bf9cf22ddbbc32dc6b3a8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/truck_body_006.png" -dest_files=["res://.godot/imported/truck_body_006.png-cdadf65ca84bf9cf22ddbbc32dc6b3a8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_001.png b/library/thumbs/wall_001.png deleted file mode 100644 index 89c2f27..0000000 Binary files a/library/thumbs/wall_001.png and /dev/null differ diff --git a/library/thumbs/wall_001.png.import b/library/thumbs/wall_001.png.import deleted file mode 100644 index 98bbcb2..0000000 --- a/library/thumbs/wall_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cdahfjyse2yvc" -path="res://.godot/imported/wall_001.png-a7df07abb2e42923b9bde4a49206f87b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_001.png" -dest_files=["res://.godot/imported/wall_001.png-a7df07abb2e42923b9bde4a49206f87b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_002.png b/library/thumbs/wall_002.png deleted file mode 100644 index bb65888..0000000 Binary files a/library/thumbs/wall_002.png and /dev/null differ diff --git a/library/thumbs/wall_002.png.import b/library/thumbs/wall_002.png.import deleted file mode 100644 index 087bcde..0000000 --- a/library/thumbs/wall_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://mw7m4gkc4lax" -path="res://.godot/imported/wall_002.png-e660cab6bd8385f7975c7f9a40ef04b6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_002.png" -dest_files=["res://.godot/imported/wall_002.png-e660cab6bd8385f7975c7f9a40ef04b6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_003.png b/library/thumbs/wall_003.png deleted file mode 100644 index 3c64174..0000000 Binary files a/library/thumbs/wall_003.png and /dev/null differ diff --git a/library/thumbs/wall_003.png.import b/library/thumbs/wall_003.png.import deleted file mode 100644 index aa68d0b..0000000 --- a/library/thumbs/wall_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://blnks8o5o5vgb" -path="res://.godot/imported/wall_003.png-6d8d080b4b2849e4fc1dbbc6257b9d47.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_003.png" -dest_files=["res://.godot/imported/wall_003.png-6d8d080b4b2849e4fc1dbbc6257b9d47.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_004.png b/library/thumbs/wall_004.png deleted file mode 100644 index 9dde84f..0000000 Binary files a/library/thumbs/wall_004.png and /dev/null differ diff --git a/library/thumbs/wall_004.png.import b/library/thumbs/wall_004.png.import deleted file mode 100644 index b5941c3..0000000 --- a/library/thumbs/wall_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cas82g46h5lkl" -path="res://.godot/imported/wall_004.png-9f0a18c7e97f0c9e41d31e14c760ea34.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_004.png" -dest_files=["res://.godot/imported/wall_004.png-9f0a18c7e97f0c9e41d31e14c760ea34.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_005.png b/library/thumbs/wall_005.png deleted file mode 100644 index 6fa7c41..0000000 Binary files a/library/thumbs/wall_005.png and /dev/null differ diff --git a/library/thumbs/wall_005.png.import b/library/thumbs/wall_005.png.import deleted file mode 100644 index ff34758..0000000 --- a/library/thumbs/wall_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cs1l5va2uy7h0" -path="res://.godot/imported/wall_005.png-d32848573c0c26326128391e91d15fdf.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_005.png" -dest_files=["res://.godot/imported/wall_005.png-d32848573c0c26326128391e91d15fdf.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_006.png b/library/thumbs/wall_006.png deleted file mode 100644 index 32d4a44..0000000 Binary files a/library/thumbs/wall_006.png and /dev/null differ diff --git a/library/thumbs/wall_006.png.import b/library/thumbs/wall_006.png.import deleted file mode 100644 index ad489a6..0000000 --- a/library/thumbs/wall_006.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c7jolqtw2ooak" -path="res://.godot/imported/wall_006.png-99be1e7d68aff756a01792ae7e47e91e.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_006.png" -dest_files=["res://.godot/imported/wall_006.png-99be1e7d68aff756a01792ae7e47e91e.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_007.png b/library/thumbs/wall_007.png deleted file mode 100644 index a95cfd2..0000000 Binary files a/library/thumbs/wall_007.png and /dev/null differ diff --git a/library/thumbs/wall_007.png.import b/library/thumbs/wall_007.png.import deleted file mode 100644 index 4e66f32..0000000 --- a/library/thumbs/wall_007.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://y54evbcyrynm" -path="res://.godot/imported/wall_007.png-71c030afd81ea92cbb10e04ad3ed696c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_007.png" -dest_files=["res://.godot/imported/wall_007.png-71c030afd81ea92cbb10e04ad3ed696c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_008.png b/library/thumbs/wall_008.png deleted file mode 100644 index 1805bc8..0000000 Binary files a/library/thumbs/wall_008.png and /dev/null differ diff --git a/library/thumbs/wall_008.png.import b/library/thumbs/wall_008.png.import deleted file mode 100644 index 9f526dd..0000000 --- a/library/thumbs/wall_008.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cimmo4ydn82bm" -path="res://.godot/imported/wall_008.png-7411bdb485f75b82505e121f69dbc317.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_008.png" -dest_files=["res://.godot/imported/wall_008.png-7411bdb485f75b82505e121f69dbc317.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_009.png b/library/thumbs/wall_009.png deleted file mode 100644 index 840459e..0000000 Binary files a/library/thumbs/wall_009.png and /dev/null differ diff --git a/library/thumbs/wall_009.png.import b/library/thumbs/wall_009.png.import deleted file mode 100644 index e21de4e..0000000 --- a/library/thumbs/wall_009.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ckpoj7l3o1mhf" -path="res://.godot/imported/wall_009.png-e4a71f36de9f49eb31ac428950d304fc.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_009.png" -dest_files=["res://.godot/imported/wall_009.png-e4a71f36de9f49eb31ac428950d304fc.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_010.png b/library/thumbs/wall_010.png deleted file mode 100644 index 16d1414..0000000 Binary files a/library/thumbs/wall_010.png and /dev/null differ diff --git a/library/thumbs/wall_010.png.import b/library/thumbs/wall_010.png.import deleted file mode 100644 index 24085c3..0000000 --- a/library/thumbs/wall_010.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://6j1rscrn11vl" -path="res://.godot/imported/wall_010.png-7fc3e673fb1b3ca1b47ee1f1ec50284b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_010.png" -dest_files=["res://.godot/imported/wall_010.png-7fc3e673fb1b3ca1b47ee1f1ec50284b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_011.png b/library/thumbs/wall_011.png deleted file mode 100644 index 3e3e50f..0000000 Binary files a/library/thumbs/wall_011.png and /dev/null differ diff --git a/library/thumbs/wall_011.png.import b/library/thumbs/wall_011.png.import deleted file mode 100644 index 9eb4eb8..0000000 --- a/library/thumbs/wall_011.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cy0vwmslkdn7l" -path="res://.godot/imported/wall_011.png-de0fb5cdcc9b8ed9d6e093aa25f8fc04.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_011.png" -dest_files=["res://.godot/imported/wall_011.png-de0fb5cdcc9b8ed9d6e093aa25f8fc04.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_012.png b/library/thumbs/wall_012.png deleted file mode 100644 index 19c97af..0000000 Binary files a/library/thumbs/wall_012.png and /dev/null differ diff --git a/library/thumbs/wall_012.png.import b/library/thumbs/wall_012.png.import deleted file mode 100644 index 9b0fc11..0000000 --- a/library/thumbs/wall_012.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cxp8vtp5x1nsg" -path="res://.godot/imported/wall_012.png-894dacb70a8cf1bf7821ed046a4e2efc.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_012.png" -dest_files=["res://.godot/imported/wall_012.png-894dacb70a8cf1bf7821ed046a4e2efc.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_013.png b/library/thumbs/wall_013.png deleted file mode 100644 index 3f74fe7..0000000 Binary files a/library/thumbs/wall_013.png and /dev/null differ diff --git a/library/thumbs/wall_013.png.import b/library/thumbs/wall_013.png.import deleted file mode 100644 index 3e8fefa..0000000 --- a/library/thumbs/wall_013.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://3wtin1gf2j8k" -path="res://.godot/imported/wall_013.png-9d832b5ff1ba885a766fc360539dec9b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_013.png" -dest_files=["res://.godot/imported/wall_013.png-9d832b5ff1ba885a766fc360539dec9b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_014.png b/library/thumbs/wall_014.png deleted file mode 100644 index 8b40265..0000000 Binary files a/library/thumbs/wall_014.png and /dev/null differ diff --git a/library/thumbs/wall_014.png.import b/library/thumbs/wall_014.png.import deleted file mode 100644 index 5bd692e..0000000 --- a/library/thumbs/wall_014.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dwyxruyfoubxc" -path="res://.godot/imported/wall_014.png-fe37d341eb78241693d17a372e9eb672.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_014.png" -dest_files=["res://.godot/imported/wall_014.png-fe37d341eb78241693d17a372e9eb672.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_015.png b/library/thumbs/wall_015.png deleted file mode 100644 index 9e49f88..0000000 Binary files a/library/thumbs/wall_015.png and /dev/null differ diff --git a/library/thumbs/wall_015.png.import b/library/thumbs/wall_015.png.import deleted file mode 100644 index f786c60..0000000 --- a/library/thumbs/wall_015.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://ep5vm4lpim0b" -path="res://.godot/imported/wall_015.png-d829fe92bc91c7d7fdc109c68f86a91b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_015.png" -dest_files=["res://.godot/imported/wall_015.png-d829fe92bc91c7d7fdc109c68f86a91b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_016.png b/library/thumbs/wall_016.png deleted file mode 100644 index 1819600..0000000 Binary files a/library/thumbs/wall_016.png and /dev/null differ diff --git a/library/thumbs/wall_016.png.import b/library/thumbs/wall_016.png.import deleted file mode 100644 index dddea0b..0000000 --- a/library/thumbs/wall_016.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bw106wuwba7i5" -path="res://.godot/imported/wall_016.png-9295c9d9b5cde3dcaf428208b4313e9d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_016.png" -dest_files=["res://.godot/imported/wall_016.png-9295c9d9b5cde3dcaf428208b4313e9d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_017.png b/library/thumbs/wall_017.png deleted file mode 100644 index 3fa6712..0000000 Binary files a/library/thumbs/wall_017.png and /dev/null differ diff --git a/library/thumbs/wall_017.png.import b/library/thumbs/wall_017.png.import deleted file mode 100644 index 285a25d..0000000 --- a/library/thumbs/wall_017.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dv5mp0kjndnlq" -path="res://.godot/imported/wall_017.png-f72f668e45c1686f6e55496417400800.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_017.png" -dest_files=["res://.godot/imported/wall_017.png-f72f668e45c1686f6e55496417400800.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_018.png b/library/thumbs/wall_018.png deleted file mode 100644 index 62160ae..0000000 Binary files a/library/thumbs/wall_018.png and /dev/null differ diff --git a/library/thumbs/wall_018.png.import b/library/thumbs/wall_018.png.import deleted file mode 100644 index 8e1d930..0000000 --- a/library/thumbs/wall_018.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dwiegiboem8dv" -path="res://.godot/imported/wall_018.png-8da427daea487af811ee7051252332d5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_018.png" -dest_files=["res://.godot/imported/wall_018.png-8da427daea487af811ee7051252332d5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_019.png b/library/thumbs/wall_019.png deleted file mode 100644 index 44ff7c0..0000000 Binary files a/library/thumbs/wall_019.png and /dev/null differ diff --git a/library/thumbs/wall_019.png.import b/library/thumbs/wall_019.png.import deleted file mode 100644 index 6548ea8..0000000 --- a/library/thumbs/wall_019.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://hko1isqno3q3" -path="res://.godot/imported/wall_019.png-2243791e42efeb4a9f075a07487aa055.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_019.png" -dest_files=["res://.godot/imported/wall_019.png-2243791e42efeb4a9f075a07487aa055.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_020.png b/library/thumbs/wall_020.png deleted file mode 100644 index dcd180e..0000000 Binary files a/library/thumbs/wall_020.png and /dev/null differ diff --git a/library/thumbs/wall_020.png.import b/library/thumbs/wall_020.png.import deleted file mode 100644 index b23786c..0000000 --- a/library/thumbs/wall_020.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dldpyeay7prkp" -path="res://.godot/imported/wall_020.png-789eeaa7bf9d9bb131b2cf494ede5ab9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_020.png" -dest_files=["res://.godot/imported/wall_020.png-789eeaa7bf9d9bb131b2cf494ede5ab9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_021.png b/library/thumbs/wall_021.png deleted file mode 100644 index 5bc4216..0000000 Binary files a/library/thumbs/wall_021.png and /dev/null differ diff --git a/library/thumbs/wall_021.png.import b/library/thumbs/wall_021.png.import deleted file mode 100644 index 61c44da..0000000 --- a/library/thumbs/wall_021.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://nscatca2vouo" -path="res://.godot/imported/wall_021.png-507641f2ef5487b21a0dadcbde56e999.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_021.png" -dest_files=["res://.godot/imported/wall_021.png-507641f2ef5487b21a0dadcbde56e999.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_022.png b/library/thumbs/wall_022.png deleted file mode 100644 index 3c933ac..0000000 Binary files a/library/thumbs/wall_022.png and /dev/null differ diff --git a/library/thumbs/wall_022.png.import b/library/thumbs/wall_022.png.import deleted file mode 100644 index 217b4f8..0000000 --- a/library/thumbs/wall_022.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://pxqa5mil2jvr" -path="res://.godot/imported/wall_022.png-01a5bc4887f4c7c3580d43f19a7a274b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_022.png" -dest_files=["res://.godot/imported/wall_022.png-01a5bc4887f4c7c3580d43f19a7a274b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_023.png b/library/thumbs/wall_023.png deleted file mode 100644 index aee4037..0000000 Binary files a/library/thumbs/wall_023.png and /dev/null differ diff --git a/library/thumbs/wall_023.png.import b/library/thumbs/wall_023.png.import deleted file mode 100644 index f62cf5f..0000000 --- a/library/thumbs/wall_023.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bbxs2ywe7ddhy" -path="res://.godot/imported/wall_023.png-792567ccf5d3211355de125b508d8dba.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_023.png" -dest_files=["res://.godot/imported/wall_023.png-792567ccf5d3211355de125b508d8dba.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_024.png b/library/thumbs/wall_024.png deleted file mode 100644 index 4a6ca10..0000000 Binary files a/library/thumbs/wall_024.png and /dev/null differ diff --git a/library/thumbs/wall_024.png.import b/library/thumbs/wall_024.png.import deleted file mode 100644 index 9abb2c3..0000000 --- a/library/thumbs/wall_024.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://k0afrdeyer1o" -path="res://.godot/imported/wall_024.png-68885831d471f0129aa8e67a5333c640.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_024.png" -dest_files=["res://.godot/imported/wall_024.png-68885831d471f0129aa8e67a5333c640.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_025.png b/library/thumbs/wall_025.png deleted file mode 100644 index d065861..0000000 Binary files a/library/thumbs/wall_025.png and /dev/null differ diff --git a/library/thumbs/wall_025.png.import b/library/thumbs/wall_025.png.import deleted file mode 100644 index 8cc5f32..0000000 --- a/library/thumbs/wall_025.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bbrag8q6l2l0m" -path="res://.godot/imported/wall_025.png-1576cf0e0e87e34c989ee14145199ffc.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_025.png" -dest_files=["res://.godot/imported/wall_025.png-1576cf0e0e87e34c989ee14145199ffc.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_051.png b/library/thumbs/wall_051.png deleted file mode 100644 index d8a2ff1..0000000 Binary files a/library/thumbs/wall_051.png and /dev/null differ diff --git a/library/thumbs/wall_051.png.import b/library/thumbs/wall_051.png.import deleted file mode 100644 index cc3b847..0000000 --- a/library/thumbs/wall_051.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cguhfqfqmmh3i" -path="res://.godot/imported/wall_051.png-593966e40100fed4cab652e15c81c34d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_051.png" -dest_files=["res://.godot/imported/wall_051.png-593966e40100fed4cab652e15c81c34d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_052.png b/library/thumbs/wall_052.png deleted file mode 100644 index 0d896a3..0000000 Binary files a/library/thumbs/wall_052.png and /dev/null differ diff --git a/library/thumbs/wall_052.png.import b/library/thumbs/wall_052.png.import deleted file mode 100644 index b187831..0000000 --- a/library/thumbs/wall_052.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bikrkhbmh0nl8" -path="res://.godot/imported/wall_052.png-ddd278194db22f838c643eb58c82f01d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_052.png" -dest_files=["res://.godot/imported/wall_052.png-ddd278194db22f838c643eb58c82f01d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_053.png b/library/thumbs/wall_053.png deleted file mode 100644 index 0b39499..0000000 Binary files a/library/thumbs/wall_053.png and /dev/null differ diff --git a/library/thumbs/wall_053.png.import b/library/thumbs/wall_053.png.import deleted file mode 100644 index 5defa01..0000000 --- a/library/thumbs/wall_053.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://m03vdoy81uu4" -path="res://.godot/imported/wall_053.png-2a07bb64df4ea3f3a088dde6f014372f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_053.png" -dest_files=["res://.godot/imported/wall_053.png-2a07bb64df4ea3f3a088dde6f014372f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_054.png b/library/thumbs/wall_054.png deleted file mode 100644 index f5e8391..0000000 Binary files a/library/thumbs/wall_054.png and /dev/null differ diff --git a/library/thumbs/wall_054.png.import b/library/thumbs/wall_054.png.import deleted file mode 100644 index 9dbeaaf..0000000 --- a/library/thumbs/wall_054.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dqs1fsqey5vbg" -path="res://.godot/imported/wall_054.png-56a916ece47c5617191a48a259606f50.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_054.png" -dest_files=["res://.godot/imported/wall_054.png-56a916ece47c5617191a48a259606f50.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_055.png b/library/thumbs/wall_055.png deleted file mode 100644 index 19f3f57..0000000 Binary files a/library/thumbs/wall_055.png and /dev/null differ diff --git a/library/thumbs/wall_055.png.import b/library/thumbs/wall_055.png.import deleted file mode 100644 index c64e4b1..0000000 --- a/library/thumbs/wall_055.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://4snr0e1bn4jg" -path="res://.godot/imported/wall_055.png-c87db99e5cff530f373e4c9e1b52b195.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_055.png" -dest_files=["res://.godot/imported/wall_055.png-c87db99e5cff530f373e4c9e1b52b195.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_056.png b/library/thumbs/wall_056.png deleted file mode 100644 index cda5fdf..0000000 Binary files a/library/thumbs/wall_056.png and /dev/null differ diff --git a/library/thumbs/wall_056.png.import b/library/thumbs/wall_056.png.import deleted file mode 100644 index 0b75e0e..0000000 --- a/library/thumbs/wall_056.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://326x51ump384" -path="res://.godot/imported/wall_056.png-710edc5890acdc7941b2d49eeff25eb8.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_056.png" -dest_files=["res://.godot/imported/wall_056.png-710edc5890acdc7941b2d49eeff25eb8.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_057.png b/library/thumbs/wall_057.png deleted file mode 100644 index 62ccaa5..0000000 Binary files a/library/thumbs/wall_057.png and /dev/null differ diff --git a/library/thumbs/wall_057.png.import b/library/thumbs/wall_057.png.import deleted file mode 100644 index ec2dd97..0000000 --- a/library/thumbs/wall_057.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bwjm5rrc8vriu" -path="res://.godot/imported/wall_057.png-4e731cf8b85a9035994c8a3d0819c70a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_057.png" -dest_files=["res://.godot/imported/wall_057.png-4e731cf8b85a9035994c8a3d0819c70a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_058.png b/library/thumbs/wall_058.png deleted file mode 100644 index ee733fb..0000000 Binary files a/library/thumbs/wall_058.png and /dev/null differ diff --git a/library/thumbs/wall_058.png.import b/library/thumbs/wall_058.png.import deleted file mode 100644 index fd3f546..0000000 --- a/library/thumbs/wall_058.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://rv6fd6v786hs" -path="res://.godot/imported/wall_058.png-f0bcf7077fea89bf15cedd68816654ec.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_058.png" -dest_files=["res://.godot/imported/wall_058.png-f0bcf7077fea89bf15cedd68816654ec.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_059.png b/library/thumbs/wall_059.png deleted file mode 100644 index 63ed43f..0000000 Binary files a/library/thumbs/wall_059.png and /dev/null differ diff --git a/library/thumbs/wall_059.png.import b/library/thumbs/wall_059.png.import deleted file mode 100644 index 8b2ac31..0000000 --- a/library/thumbs/wall_059.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c1l8a8gmrh2ck" -path="res://.godot/imported/wall_059.png-da744097d34bb57fbfbd4f1db59882c3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_059.png" -dest_files=["res://.godot/imported/wall_059.png-da744097d34bb57fbfbd4f1db59882c3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_060.png b/library/thumbs/wall_060.png deleted file mode 100644 index 7e89685..0000000 Binary files a/library/thumbs/wall_060.png and /dev/null differ diff --git a/library/thumbs/wall_060.png.import b/library/thumbs/wall_060.png.import deleted file mode 100644 index 5cb8db5..0000000 --- a/library/thumbs/wall_060.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cv5sd2q6b16af" -path="res://.godot/imported/wall_060.png-ff54fb8b3368079ce2db7c695e1be9f5.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_060.png" -dest_files=["res://.godot/imported/wall_060.png-ff54fb8b3368079ce2db7c695e1be9f5.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_061.png b/library/thumbs/wall_061.png deleted file mode 100644 index 2b32ba6..0000000 Binary files a/library/thumbs/wall_061.png and /dev/null differ diff --git a/library/thumbs/wall_061.png.import b/library/thumbs/wall_061.png.import deleted file mode 100644 index a138bc9..0000000 --- a/library/thumbs/wall_061.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bl3kxy3i0hklf" -path="res://.godot/imported/wall_061.png-3b05adb23e3a9755c496d5da7aecacb9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_061.png" -dest_files=["res://.godot/imported/wall_061.png-3b05adb23e3a9755c496d5da7aecacb9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_062.png b/library/thumbs/wall_062.png deleted file mode 100644 index 4544de4..0000000 Binary files a/library/thumbs/wall_062.png and /dev/null differ diff --git a/library/thumbs/wall_062.png.import b/library/thumbs/wall_062.png.import deleted file mode 100644 index a487da7..0000000 --- a/library/thumbs/wall_062.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://33vtilvkfhl" -path="res://.godot/imported/wall_062.png-29def86cb45f0eaddaa927ff7fdb35db.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_062.png" -dest_files=["res://.godot/imported/wall_062.png-29def86cb45f0eaddaa927ff7fdb35db.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_063.png b/library/thumbs/wall_063.png deleted file mode 100644 index 7551f37..0000000 Binary files a/library/thumbs/wall_063.png and /dev/null differ diff --git a/library/thumbs/wall_063.png.import b/library/thumbs/wall_063.png.import deleted file mode 100644 index 231db5a..0000000 --- a/library/thumbs/wall_063.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dy1uco0gdpw0y" -path="res://.godot/imported/wall_063.png-ae42b53522fbaebaaae369abb599e371.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_063.png" -dest_files=["res://.godot/imported/wall_063.png-ae42b53522fbaebaaae369abb599e371.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_064.png b/library/thumbs/wall_064.png deleted file mode 100644 index ae41973..0000000 Binary files a/library/thumbs/wall_064.png and /dev/null differ diff --git a/library/thumbs/wall_064.png.import b/library/thumbs/wall_064.png.import deleted file mode 100644 index 9739f61..0000000 --- a/library/thumbs/wall_064.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://gf12vtq7c7tq" -path="res://.godot/imported/wall_064.png-13c3efd20ee8f4799109bf71023993fb.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_064.png" -dest_files=["res://.godot/imported/wall_064.png-13c3efd20ee8f4799109bf71023993fb.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_065.png b/library/thumbs/wall_065.png deleted file mode 100644 index 99b2dd5..0000000 Binary files a/library/thumbs/wall_065.png and /dev/null differ diff --git a/library/thumbs/wall_065.png.import b/library/thumbs/wall_065.png.import deleted file mode 100644 index 85482fc..0000000 --- a/library/thumbs/wall_065.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://d087j5h5wkuta" -path="res://.godot/imported/wall_065.png-d3fdb42355c5c7b07d30456a43e62346.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_065.png" -dest_files=["res://.godot/imported/wall_065.png-d3fdb42355c5c7b07d30456a43e62346.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_066.png b/library/thumbs/wall_066.png deleted file mode 100644 index 2451ec5..0000000 Binary files a/library/thumbs/wall_066.png and /dev/null differ diff --git a/library/thumbs/wall_066.png.import b/library/thumbs/wall_066.png.import deleted file mode 100644 index 7570e01..0000000 --- a/library/thumbs/wall_066.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://brhftds4yts0y" -path="res://.godot/imported/wall_066.png-a5f66185e036f31f61248e820ff38a72.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_066.png" -dest_files=["res://.godot/imported/wall_066.png-a5f66185e036f31f61248e820ff38a72.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_067.png b/library/thumbs/wall_067.png deleted file mode 100644 index b417f58..0000000 Binary files a/library/thumbs/wall_067.png and /dev/null differ diff --git a/library/thumbs/wall_067.png.import b/library/thumbs/wall_067.png.import deleted file mode 100644 index 692c28e..0000000 --- a/library/thumbs/wall_067.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://nly86scuolck" -path="res://.godot/imported/wall_067.png-475a67747ddad062a801fb82560408e3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_067.png" -dest_files=["res://.godot/imported/wall_067.png-475a67747ddad062a801fb82560408e3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_068.png b/library/thumbs/wall_068.png deleted file mode 100644 index 66d76dc..0000000 Binary files a/library/thumbs/wall_068.png and /dev/null differ diff --git a/library/thumbs/wall_068.png.import b/library/thumbs/wall_068.png.import deleted file mode 100644 index ad02cd6..0000000 --- a/library/thumbs/wall_068.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://duh3kumdeynpe" -path="res://.godot/imported/wall_068.png-0e32735acb27b0060c7157aa4545a0c7.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_068.png" -dest_files=["res://.godot/imported/wall_068.png-0e32735acb27b0060c7157aa4545a0c7.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_069.png b/library/thumbs/wall_069.png deleted file mode 100644 index 0640e24..0000000 Binary files a/library/thumbs/wall_069.png and /dev/null differ diff --git a/library/thumbs/wall_069.png.import b/library/thumbs/wall_069.png.import deleted file mode 100644 index 5555107..0000000 --- a/library/thumbs/wall_069.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b7d4qh1u4m13r" -path="res://.godot/imported/wall_069.png-fae9505f23313b7d425f5e6a7174c172.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_069.png" -dest_files=["res://.godot/imported/wall_069.png-fae9505f23313b7d425f5e6a7174c172.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_070.png b/library/thumbs/wall_070.png deleted file mode 100644 index d05b5d3..0000000 Binary files a/library/thumbs/wall_070.png and /dev/null differ diff --git a/library/thumbs/wall_070.png.import b/library/thumbs/wall_070.png.import deleted file mode 100644 index 327bf4c..0000000 --- a/library/thumbs/wall_070.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b430r88s7n4pr" -path="res://.godot/imported/wall_070.png-8d3c006b53db852634611df91dc4a10c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_070.png" -dest_files=["res://.godot/imported/wall_070.png-8d3c006b53db852634611df91dc4a10c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_071.png b/library/thumbs/wall_071.png deleted file mode 100644 index cfadff0..0000000 Binary files a/library/thumbs/wall_071.png and /dev/null differ diff --git a/library/thumbs/wall_071.png.import b/library/thumbs/wall_071.png.import deleted file mode 100644 index e44c3b7..0000000 --- a/library/thumbs/wall_071.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bgcjm0epv3qkp" -path="res://.godot/imported/wall_071.png-c922bd3be479d6b935772de0fdf363d3.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_071.png" -dest_files=["res://.godot/imported/wall_071.png-c922bd3be479d6b935772de0fdf363d3.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_072.png b/library/thumbs/wall_072.png deleted file mode 100644 index b40480b..0000000 Binary files a/library/thumbs/wall_072.png and /dev/null differ diff --git a/library/thumbs/wall_072.png.import b/library/thumbs/wall_072.png.import deleted file mode 100644 index 79cac6e..0000000 --- a/library/thumbs/wall_072.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cewasyojsk17n" -path="res://.godot/imported/wall_072.png-cf2bbf1bf0b1e99fba0c57f4f05523a9.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_072.png" -dest_files=["res://.godot/imported/wall_072.png-cf2bbf1bf0b1e99fba0c57f4f05523a9.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_073.png b/library/thumbs/wall_073.png deleted file mode 100644 index 8cee78c..0000000 Binary files a/library/thumbs/wall_073.png and /dev/null differ diff --git a/library/thumbs/wall_073.png.import b/library/thumbs/wall_073.png.import deleted file mode 100644 index ac05f10..0000000 --- a/library/thumbs/wall_073.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cqe2wcli55th0" -path="res://.godot/imported/wall_073.png-f4411ee06eb71bfa8e652a92a7578796.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_073.png" -dest_files=["res://.godot/imported/wall_073.png-f4411ee06eb71bfa8e652a92a7578796.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_074.png b/library/thumbs/wall_074.png deleted file mode 100644 index 323c2b9..0000000 Binary files a/library/thumbs/wall_074.png and /dev/null differ diff --git a/library/thumbs/wall_074.png.import b/library/thumbs/wall_074.png.import deleted file mode 100644 index d3f16df..0000000 --- a/library/thumbs/wall_074.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://qlsxw6w5bcpl" -path="res://.godot/imported/wall_074.png-a3b401d529a584c6645a962f04980efa.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_074.png" -dest_files=["res://.godot/imported/wall_074.png-a3b401d529a584c6645a962f04980efa.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wall_100.png b/library/thumbs/wall_100.png deleted file mode 100644 index 5d5148f..0000000 Binary files a/library/thumbs/wall_100.png and /dev/null differ diff --git a/library/thumbs/wall_100.png.import b/library/thumbs/wall_100.png.import deleted file mode 100644 index 4351efe..0000000 --- a/library/thumbs/wall_100.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dioish4lg282" -path="res://.godot/imported/wall_100.png-0ea7e70e2a62c98e5fa94f551c7d6283.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wall_100.png" -dest_files=["res://.godot/imported/wall_100.png-0ea7e70e2a62c98e5fa94f551c7d6283.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/water_tower_001.png b/library/thumbs/water_tower_001.png deleted file mode 100644 index 5226d4c..0000000 Binary files a/library/thumbs/water_tower_001.png and /dev/null differ diff --git a/library/thumbs/water_tower_001.png.import b/library/thumbs/water_tower_001.png.import deleted file mode 100644 index 2b63ab8..0000000 --- a/library/thumbs/water_tower_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dbyyca7ufkc04" -path="res://.godot/imported/water_tower_001.png-bd80425f42a0258c9a3cb008a01fbe15.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/water_tower_001.png" -dest_files=["res://.godot/imported/water_tower_001.png-bd80425f42a0258c9a3cb008a01fbe15.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/water_tower_002.png b/library/thumbs/water_tower_002.png deleted file mode 100644 index a60a073..0000000 Binary files a/library/thumbs/water_tower_002.png and /dev/null differ diff --git a/library/thumbs/water_tower_002.png.import b/library/thumbs/water_tower_002.png.import deleted file mode 100644 index eed3f05..0000000 --- a/library/thumbs/water_tower_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cqerb5dftnhky" -path="res://.godot/imported/water_tower_002.png-32205fd234c44fc78f4bff17bd680dca.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/water_tower_002.png" -dest_files=["res://.godot/imported/water_tower_002.png-32205fd234c44fc78f4bff17bd680dca.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/water_tower_003.png b/library/thumbs/water_tower_003.png deleted file mode 100644 index ea4263f..0000000 Binary files a/library/thumbs/water_tower_003.png and /dev/null differ diff --git a/library/thumbs/water_tower_003.png.import b/library/thumbs/water_tower_003.png.import deleted file mode 100644 index e7721a2..0000000 --- a/library/thumbs/water_tower_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b0a5mo4f3t4w6" -path="res://.godot/imported/water_tower_003.png-c049aa70aaf6c0b3a692d50b9547f6b6.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/water_tower_003.png" -dest_files=["res://.godot/imported/water_tower_003.png-c049aa70aaf6c0b3a692d50b9547f6b6.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/water_tower_004.png b/library/thumbs/water_tower_004.png deleted file mode 100644 index 78a501e..0000000 Binary files a/library/thumbs/water_tower_004.png and /dev/null differ diff --git a/library/thumbs/water_tower_004.png.import b/library/thumbs/water_tower_004.png.import deleted file mode 100644 index 220f3e2..0000000 --- a/library/thumbs/water_tower_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c7qo223o3c0id" -path="res://.godot/imported/water_tower_004.png-3fb823386acbf8a1868badcf50bbb21a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/water_tower_004.png" -dest_files=["res://.godot/imported/water_tower_004.png-3fb823386acbf8a1868badcf50bbb21a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wheel_001.png b/library/thumbs/wheel_001.png deleted file mode 100644 index 52530a4..0000000 Binary files a/library/thumbs/wheel_001.png and /dev/null differ diff --git a/library/thumbs/wheel_001.png.import b/library/thumbs/wheel_001.png.import deleted file mode 100644 index 52de979..0000000 --- a/library/thumbs/wheel_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c6evv8d2xbmok" -path="res://.godot/imported/wheel_001.png-2f8aa6d1f44a0a6e76645de64e3f0229.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wheel_001.png" -dest_files=["res://.godot/imported/wheel_001.png-2f8aa6d1f44a0a6e76645de64e3f0229.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wheel_002.png b/library/thumbs/wheel_002.png deleted file mode 100644 index baf1f43..0000000 Binary files a/library/thumbs/wheel_002.png and /dev/null differ diff --git a/library/thumbs/wheel_002.png.import b/library/thumbs/wheel_002.png.import deleted file mode 100644 index 34c4292..0000000 --- a/library/thumbs/wheel_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bdvlrgqd2xfk" -path="res://.godot/imported/wheel_002.png-38a6c2736cf8fdb125e7964a2f8c3494.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wheel_002.png" -dest_files=["res://.godot/imported/wheel_002.png-38a6c2736cf8fdb125e7964a2f8c3494.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wheel_003.png b/library/thumbs/wheel_003.png deleted file mode 100644 index 70a2640..0000000 Binary files a/library/thumbs/wheel_003.png and /dev/null differ diff --git a/library/thumbs/wheel_003.png.import b/library/thumbs/wheel_003.png.import deleted file mode 100644 index 6a34bd1..0000000 --- a/library/thumbs/wheel_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cetyew4wx62hy" -path="res://.godot/imported/wheel_003.png-27b9e89b6c9daa4b0dca6a50c36b474d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wheel_003.png" -dest_files=["res://.godot/imported/wheel_003.png-27b9e89b6c9daa4b0dca6a50c36b474d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wheel_004.png b/library/thumbs/wheel_004.png deleted file mode 100644 index 3188e8d..0000000 Binary files a/library/thumbs/wheel_004.png and /dev/null differ diff --git a/library/thumbs/wheel_004.png.import b/library/thumbs/wheel_004.png.import deleted file mode 100644 index 65dc741..0000000 --- a/library/thumbs/wheel_004.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b1t3f3sgiu15d" -path="res://.godot/imported/wheel_004.png-7e4449a68dbd8dc0e2598c4aac312d82.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wheel_004.png" -dest_files=["res://.godot/imported/wheel_004.png-7e4449a68dbd8dc0e2598c4aac312d82.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wheel_005.png b/library/thumbs/wheel_005.png deleted file mode 100644 index 8787074..0000000 Binary files a/library/thumbs/wheel_005.png and /dev/null differ diff --git a/library/thumbs/wheel_005.png.import b/library/thumbs/wheel_005.png.import deleted file mode 100644 index 7b760f4..0000000 --- a/library/thumbs/wheel_005.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://0l0vc16t8oy8" -path="res://.godot/imported/wheel_005.png-0bee8e857378128d714c56f175b9c0d4.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wheel_005.png" -dest_files=["res://.godot/imported/wheel_005.png-0bee8e857378128d714c56f175b9c0d4.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wire_001.png b/library/thumbs/wire_001.png deleted file mode 100644 index 6dc044e..0000000 Binary files a/library/thumbs/wire_001.png and /dev/null differ diff --git a/library/thumbs/wire_001.png.import b/library/thumbs/wire_001.png.import deleted file mode 100644 index 4ca8621..0000000 --- a/library/thumbs/wire_001.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cu5lejlaa6bb8" -path="res://.godot/imported/wire_001.png-0ba71066d5ed86da0e6650cfddb71108.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wire_001.png" -dest_files=["res://.godot/imported/wire_001.png-0ba71066d5ed86da0e6650cfddb71108.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wire_002.png b/library/thumbs/wire_002.png deleted file mode 100644 index 499f97e..0000000 Binary files a/library/thumbs/wire_002.png and /dev/null differ diff --git a/library/thumbs/wire_002.png.import b/library/thumbs/wire_002.png.import deleted file mode 100644 index a24e4be..0000000 --- a/library/thumbs/wire_002.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cn2co73gakqqt" -path="res://.godot/imported/wire_002.png-c63a78a645bf9d27830f40eeafd26ce1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wire_002.png" -dest_files=["res://.godot/imported/wire_002.png-c63a78a645bf9d27830f40eeafd26ce1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/library/thumbs/wire_003.png b/library/thumbs/wire_003.png deleted file mode 100644 index f8823c5..0000000 Binary files a/library/thumbs/wire_003.png and /dev/null differ diff --git a/library/thumbs/wire_003.png.import b/library/thumbs/wire_003.png.import deleted file mode 100644 index dda50bb..0000000 --- a/library/thumbs/wire_003.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dhsml5w8kxhgk" -path="res://.godot/imported/wire_003.png-4dc22f37fedb065d7f40deda12ed8079.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://library/thumbs/wire_003.png" -dest_files=["res://.godot/imported/wire_003.png-4dc22f37fedb065d7f40deda12ed8079.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -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/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -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/project.godot b/project.godot index 9c61cd1..f929052 100644 --- a/project.godot +++ b/project.godot @@ -7,7 +7,7 @@ config_version=5 config/name="ScopedVR Map Editor" config/description="Standalone-Editor für ScopedVR-Maps (.svmap). Nutzbar ohne Godot-Kenntnisse." -run/main_scene="res://scenes/main.tscn" +run/main_scene="res://core/scenes/main.tscn" config/features=PackedStringArray("4.7") config/icon="res://icon.svg" diff --git a/scenes/main.tscn b/scenes/main.tscn deleted file mode 100644 index dec2022..0000000 --- a/scenes/main.tscn +++ /dev/null @@ -1,12 +0,0 @@ -[gd_scene load_steps=2 format=3] - -[ext_resource type="Script" path="res://src/ui/main.gd" id="1_main"] - -[node name="Main" type="Control"] -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -script = ExtResource("1_main") diff --git a/shaders/selection_outline.gdshader b/shaders/selection_outline.gdshader deleted file mode 100644 index 60d7f07..0000000 --- a/shaders/selection_outline.gdshader +++ /dev/null @@ -1,40 +0,0 @@ -shader_type spatial; -render_mode unshaded, cull_front, shadows_disabled, blend_mix; - -// Außenhüllen-Kontur (U6, Karte t_639135dd): dezente Auswahl-Markierung -// statt Vollflächen-Orange. Das Grundmaterial (inkl. Textur) bleibt komplett -// sichtbar — die Kontur lebt als eigene Hülle um das Modell: -// -// VERTEX += NORMAL * breite_m bläht das Volumen entlang der Normalen auf, -// cull_front rendert nur die RÜCKseiten der Hülle. Sichtbar bleibt darum -// genau der schmale Saum, der außerhalb der Silhouette liegt (der Rest -// wird vom Objekt selbst per Tiefentest verdeckt) — die klassische -// Inverted-Hull-Outline-Technik. -// -// Farbton, Deckkraft und Breite kommen aus dem Theme (theme/editor_theme.tres, -// Abschnitt "Editor") — der Shader selbst kennt keine festen Farben. -// -// Gestrichelte Variante (Spiegel-Zwilling): streifen_hz > 0 unterteilt die -// Kontur in Bänder entlang der Welthöhe — dünn + gestrichelt statt voll. - -uniform vec4 linien_farbe : source_color = vec4(1.0, 0.6, 0.15, 0.95); -uniform float breite_m : hint_range(0.0, 1.0) = 0.08; -uniform float streifen_hz : hint_range(0.0, 40.0) = 0.0; - -varying vec3 welt_pos; - -void vertex() { - VERTEX += NORMAL * breite_m; - welt_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; -} - -void fragment() { - if (streifen_hz > 0.5) { - // Gestrichelt (Zwilling): Bänder entlang der Welthöhe, ~55 % Strich. - if (fract(welt_pos.y * streifen_hz) > 0.55) { - discard; - } - } - ALBEDO = linien_farbe.rgb; - ALPHA = linien_farbe.a; -} diff --git a/shaders/selection_outline.gdshader.uid b/shaders/selection_outline.gdshader.uid deleted file mode 100644 index ae9b0ac..0000000 --- a/shaders/selection_outline.gdshader.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b1wjgw8l4w77m diff --git a/src/editor/bau_katalog.gd b/src/editor/bau_katalog.gd deleted file mode 100644 index 75a71fc..0000000 --- a/src/editor/bau_katalog.gd +++ /dev/null @@ -1,448 +0,0 @@ -extends RefCounted -class_name BauKatalog -## Bauteil-Katalog des Bauen-Modus (Karte "Bauen sauber integrieren", 25.10.). -## -## Ein Bauteil ist ein GANZ NORMALES Bibliotheks-Objekt (`bau_*`, Kategorie -## "bauteile"): gesetzte Teile stehen in doc["objects"], tragen ein -## Gruppen-Feld (= ein Gebäude) und laufen damit durch dieselbe Kette wie jedes -## Objekt — Undo, Kopieren, Löschen, Symmetrie, Speichern, Server-Registry, -## Client-Loader, Trimesh-Kollision. Es gibt keinen Sonderblock "gebaeude" mehr. -## -## Geometrie: die CC0-Runtime des Modular Builder (addons/modular_builder, -## Michel Savadim, v0.2.0 — Lizenz siehe ADDON_LIZENZ.txt). Hier wird sie nur -## PARAMETRIERT (Wandhöhe 3 m, 2-m-Raster) und auf die Fußpunkt-Konvention der -## Bibliothek normalisiert: Unterkante y = 0, XZ um die Mitte zentriert -## (docs/objekt_fragmente.md). Die Farbe ist die Material-Grundfarbe (glTF -## baseColorFactor) — keine Texturen, keine Lizenzfragen, 1 Draw-Call je Teil; -## Editor, Client und Thumbnails laden sie dadurch identisch. -## -## Meshes entstehen aus diesem Katalog (tools/gen_bauteile.gd schreibt GLB + -## Trimesh-JSON + Registry-Fragment), der Editor zeigt die GLBs wie jedes andere -## Objekt. mesh() ist die Quelle für Generator UND Tests. - -const GEO_SCRIPT := "res://addons/modular_builder/modular_piece_geometry.gd" -const DETAIL_SCRIPT := "res://addons/modular_builder/modular_building_detail.gd" -const KATEGORIE := "bauteile" -const PREFIX := "bau_" - -const RASTER_M := 2.0 # Zellgröße (XZ) -const WAND_H := 3.0 # Wandhöhe eines Geschosses -const DICKE_M := 0.2 # Wand-/Plattendicke - -# Geometrie-Typen der Addon-Runtime (PieceType-Enum, Kopie der Werte) -const T_FUNDAMENT := 0 -const T_BODEN := 2 -const T_WAND := 3 -const T_GIEBEL := 5 -const T_DACH_GIEBEL := 6 -const T_DACH_PYRAMIDE := 9 -const T_TREPPE := 10 -const D_FENSTER := 0 -const D_TUER := 1 - -## Snap-Arten (build_snap.gd): -## "zelle" Mitte einer 2×2-Zelle (Fundament, Boden, Dächer) -## "kante" Mitte einer Zellkante (Wände) — Drehung ergibt sich aus der Kante -## "ecke" Zell-Ecke (Pfeiler) -## "treppe" 4×2-m-Fläche über zwei Zellen -const GRUPPEN := [ - {"key": "grund", "label": "Fundament & Boden", "oids": ["bau_fundament", "bau_boden"]}, - {"key": "waende", "label": "Wände", "oids": ["bau_wand", "bau_wand_tuer", "bau_wand_fenster", - "bau_wand_scharte", "bau_bruestung", "bau_pfeiler"]}, - {"key": "dach", "label": "Dach & Giebel (klein 2 m)", "oids": ["bau_giebelwand", "bau_dach_giebel", "bau_dach_pyramide"]}, - {"key": "dach_mittel", "label": "Dach & Giebel (mittel 4 m)", "oids": ["bau_giebelwand_4", "bau_dach_giebel_4", "bau_dach_pyramide_4"]}, - {"key": "dach_gross", "label": "Dach & Giebel (groß 6 m)", "oids": ["bau_giebelwand_6", "bau_dach_giebel_6", "bau_dach_pyramide_6"]}, - {"key": "dach_teile", "label": "Dach aus Einzelteilen (45°)", "oids": ["bau_dach_schraege", "bau_dach_ecke_aussen", - "bau_dach_ecke_innen", "bau_dach_plateau", "bau_dach_giebel_ende"]}, - {"key": "treppe", "label": "Treppe", "oids": ["bau_treppe"]}, -] - -const QUADRAT := [[-1.0, 0.0, -1.0], [1.0, 0.0, -1.0], [1.0, 0.0, 1.0], [-1.0, 0.0, 1.0]] -const QUADRAT_4 := [[-2.0, 0.0, -2.0], [2.0, 0.0, -2.0], [2.0, 0.0, 2.0], [-2.0, 0.0, 2.0]] -const QUADRAT_6 := [[-3.0, 0.0, -3.0], [3.0, 0.0, -3.0], [3.0, 0.0, 3.0], [-3.0, 0.0, 3.0]] - -## Reihenfolge = Anzeige-Reihenfolge (GRUPPEN nutzt dieselben IDs). -## "traeger": darauf darf gestapelt werden (Oberkante zählt als Ebene). -const KINDS := { - "bau_fundament": { - "label": "Fundament", "info": "2×2 m, 20 cm dick — Basis für Wände", "snap": "zelle", "traeger": true, - "typ": T_FUNDAMENT, "punkte": QUADRAT, "farbe": Color(0.42, 0.42, 0.40), - }, - "bau_boden": { - "label": "Boden / Decke", "info": "2×2 m Platte — Fußboden oder Decke fürs nächste Geschoss", - "snap": "zelle", "traeger": true, - "typ": T_BODEN, "punkte": QUADRAT, "farbe": Color(0.50, 0.46, 0.40), - }, - "bau_wand": { - "label": "Wand", "info": "2 m breit, 3 m hoch", "snap": "kante", "traeger": true, - "typ": T_WAND, "punkte": [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]], "farbe": Color(0.62, 0.53, 0.38), - }, - "bau_wand_tuer": { - "label": "Wand mit Tür", "info": "Türöffnung 1,2 × 2,2 m — man läuft hindurch", "snap": "kante", "traeger": true, - "typ": T_WAND, "punkte": [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]], "farbe": Color(0.62, 0.53, 0.38), - "details": [{"typ": D_TUER, "pos": [1.0, 1.1, 0.0], "w": 1.2, "h": 2.2}], - }, - "bau_wand_fenster": { - "label": "Wand mit Fenster", "info": "Fensteröffnung 1,2 × 1,2 m, Brüstung 1,1 m", "snap": "kante", "traeger": true, - "typ": T_WAND, "punkte": [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]], "farbe": Color(0.62, 0.53, 0.38), - "details": [{"typ": D_FENSTER, "pos": [1.0, 1.7, 0.0], "w": 1.2, "h": 1.2}], - }, - "bau_wand_scharte": { - "label": "Wand mit Schießscharte", "info": "Schlitz 1,0 × 0,4 m auf Schulterhöhe", "snap": "kante", "traeger": true, - "typ": T_WAND, "punkte": [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]], "farbe": Color(0.62, 0.53, 0.38), - "details": [{"typ": D_FENSTER, "pos": [1.0, 1.5, 0.0], "w": 1.0, "h": 0.4}], - }, - "bau_bruestung": { - "label": "Brüstung", "info": "2 m breit, 1,1 m hoch — Deckung, Dachrand", "snap": "kante", "traeger": true, - "typ": T_WAND, "punkte": [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]], "farbe": Color(0.56, 0.48, 0.35), "hoehe": 1.1, - }, - "bau_pfeiler": { - "label": "Eckpfeiler", "info": "Schließt die Ecke, wo zwei Wände zusammenstoßen", "snap": "ecke", "traeger": true, - "box": Vector3(0.3, 3.0, 0.3), "farbe": Color(0.42, 0.42, 0.40), - }, - "bau_giebelwand": { - "label": "Giebelwand", "info": "Dreieck-Abschluss unter dem Satteldach (2 m breit, 1 m Spitze)", - "snap": "kante", "traeger": false, - "typ": T_GIEBEL, "punkte": [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]], "rise": 1.0, "farbe": Color(0.62, 0.53, 0.38), - }, - "bau_dach_giebel": { - "label": "Satteldach", "info": "2×2 m, First in Richtung der Vorschau (R dreht)", "snap": "zelle", "traeger": false, - "typ": T_DACH_GIEBEL, "punkte": QUADRAT, "rise": 1.0, "farbe": Color(0.40, 0.25, 0.18), - }, - "bau_dach_pyramide": { - "label": "Pyramidendach", "info": "2×2 m, Spitze in der Mitte", "snap": "zelle", "traeger": false, - "typ": T_DACH_PYRAMIDE, "punkte": QUADRAT, "rise": 1.0, "farbe": Color(0.40, 0.25, 0.18), - }, - # Große Dächer (Test-Befund 25.10.: 2×2 m reichte nur für eine Zelle). Immer 45° - # (Spitze = halbe Breite); Giebelwand und Dach gleicher Größe passen zusammen. - "bau_giebelwand_4": { - "label": "Giebelwand 4 m", "info": "Dreieck-Abschluss, 4 m breit, 2 m Spitze — zum Satteldach 4 m", - "snap": "kante", "traeger": false, - "typ": T_GIEBEL, "punkte": [[0.0, 0.0, 0.0], [4.0, 0.0, 0.0]], "rise": 2.0, "farbe": Color(0.62, 0.53, 0.38), - }, - "bau_dach_giebel_4": { - "label": "Satteldach 4×4 m", "info": "4×4 m, First in Richtung der Vorschau (R dreht)", "snap": "zelle", "traeger": false, - "typ": T_DACH_GIEBEL, "punkte": QUADRAT_4, "rise": 2.0, "farbe": Color(0.40, 0.25, 0.18), - }, - "bau_dach_pyramide_4": { - "label": "Pyramidendach 4×4 m", "info": "4×4 m, Spitze in der Mitte", "snap": "zelle", "traeger": false, - "typ": T_DACH_PYRAMIDE, "punkte": QUADRAT_4, "rise": 2.0, "farbe": Color(0.40, 0.25, 0.18), - }, - "bau_giebelwand_6": { - "label": "Giebelwand 6 m", "info": "Dreieck-Abschluss, 6 m breit, 3 m Spitze — zum Satteldach 6 m", - "snap": "kante", "traeger": false, - "typ": T_GIEBEL, "punkte": [[0.0, 0.0, 0.0], [6.0, 0.0, 0.0]], "rise": 3.0, "farbe": Color(0.62, 0.53, 0.38), - }, - "bau_dach_giebel_6": { - "label": "Satteldach 6×6 m", "info": "6×6 m, First in Richtung der Vorschau (R dreht)", "snap": "zelle", "traeger": false, - "typ": T_DACH_GIEBEL, "punkte": QUADRAT_6, "rise": 3.0, "farbe": Color(0.40, 0.25, 0.18), - }, - "bau_dach_pyramide_6": { - "label": "Pyramidendach 6×6 m", "info": "6×6 m, Spitze in der Mitte", "snap": "zelle", "traeger": false, - "typ": T_DACH_PYRAMIDE, "punkte": QUADRAT_6, "rise": 3.0, "farbe": Color(0.40, 0.25, 0.18), - }, - # Dach aus Einzelteilen: alles 2×2-Zellen mit 45° (2 m Lauf = 2 m Höhe), massiv - # (rundum geschlossen, keine Lücke von innen). "profil" → _dach_mesh(). Tiefe - # Kante = -Z lokal (R dreht), Ecken: tiefer Punkt bei (-X,-Z). - "bau_dach_schraege": { - "label": "Dachschräge 45°", "info": "2×2 m, 2 m hoch — eine Seite des Dachs; die tiefe Kante zeigt in Richtung der Vorschau (R dreht)", - "snap": "zelle", "traeger": false, "profil": "schraege", "farbe": Color(0.40, 0.25, 0.18), - }, - "bau_dach_ecke_aussen": { - "label": "Dachecke außen", "info": "Walm-Ecke (Grat): zwei Schrägen treffen sich an einer Hausecke, die tiefe Ecke zeigt nach außen", - "snap": "zelle", "traeger": false, "profil": "ecke_aussen", "farbe": Color(0.40, 0.25, 0.18), - }, - "bau_dach_ecke_innen": { - "label": "Dachecke innen", "info": "Kehle: zwei Schrägen laufen in einer einspringenden Ecke (L-/T-Dach) zusammen", - "snap": "zelle", "traeger": false, "profil": "ecke_innen", "farbe": Color(0.40, 0.25, 0.18), - }, - "bau_dach_plateau": { - "label": "Dachplateau", "info": "2×2 m Block, 2 m hoch, oben flach — Mittelstück zwischen zwei Schrägen (breite Häuser), Schornstein-Sockel", - "snap": "zelle", "traeger": true, "profil": "plateau", "farbe": Color(0.40, 0.25, 0.18), - }, - "bau_dach_giebel_ende": { - "label": "Dachstirn 45°", "info": "Senkrechte Dreieck-Stirn (2 m breit, 2 m hoch) — Giebel-Abschluss unter einer Schräge, wenn das Dach an der Seite offen bleibt", - "snap": "kante", "traeger": false, "profil": "stirn", "farbe": Color(0.62, 0.53, 0.38), - }, - "bau_treppe": { - "label": "Treppe", "info": "4 m lang, 2 m breit, 3 m hoch — führt in ein Geschoss darüber", - "snap": "treppe", "traeger": false, - "typ": T_TREPPE, "punkte": [[0.0, 0.0, 0.0], [4.0, 3.0, 0.0]], "stufen": 15, "breite": 2.0, - "farbe": Color(0.46, 0.45, 0.42), - }, -} - -static var _mesh_cache: Dictionary = {} - - -static func ist_bau(oid: String) -> bool: - return KINDS.has(oid) - - -static func oids() -> Array: - return KINDS.keys() - - -static func label(oid: String) -> String: - return str((KINDS.get(oid, {}) as Dictionary).get("label", oid)) - - -static func snap_art(oid: String) -> String: - return str((KINDS.get(oid, {}) as Dictionary).get("snap", "zelle")) - - -## Platte = flaches Zell-Teil, auf dem man steht (Fundament, Boden/Decke). -static func ist_platte(oid: String) -> bool: - return snap_art(oid) == "zelle" and ist_traeger(oid) - - -static func ist_traeger(oid: String) -> bool: - return bool((KINDS.get(oid, {}) as Dictionary).get("traeger", false)) - - -## Ausmaße (m) des normalisierten Meshes: x = Länge/Breite, y = Höhe, z = Tiefe. -static func groesse(oid: String) -> Vector3: - var m := mesh(oid) - return m.get_aabb().size if m != null else Vector3.ZERO - - -# ------------------------------------------------------------------- Mesh --- - -## Normalisiertes Mesh (Fußpunkt unten-Mitte, Vertex-Farben) oder null. -static func mesh(oid: String) -> ArrayMesh: - if _mesh_cache.has(oid): - return _mesh_cache[oid] - var kind: Dictionary = KINDS.get(oid, {}) - if kind.is_empty(): - return null - var roh: ArrayMesh - if kind.has("box"): - roh = _box_mesh(kind["box"]) - elif kind.has("profil"): - roh = _dach_mesh(str(kind["profil"])) - else: - roh = _addon_mesh(kind) - var fertig := _normalisieren(roh, kind["farbe"] as Color) - _mesh_cache[oid] = fertig - return fertig - - -static func _box_mesh(size: Vector3) -> ArrayMesh: - var bm := BoxMesh.new() - bm.size = size - var out := ArrayMesh.new() - out.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, bm.get_mesh_arrays()) - return out - - -## Massive Dach-Teile aus Dreiecken (Zelle 2×2 m, lokal x,z ∈ [-1,1], 45°). -## Oberfläche h(x,z): Schräge = z+1, Ecke außen = min(x,z)+1, Ecke innen = max(x,z)+1, -## Plateau = 2. Dach-Stirn: dünnes Dreieck-Prisma. -static func _dach_mesh(profil: String) -> ArrayMesh: - var tris: Array = [] # je Dreieck [a, b, c] als Vector3 - var V := func(x: float, y: float, z: float) -> Vector3: return Vector3(x, y, z) - var quad := func(a: Vector3, b: Vector3, c: Vector3, d: Vector3) -> void: - tris.append([a, b, c]) - tris.append([a, c, d]) - var tri := func(a: Vector3, b: Vector3, c: Vector3) -> void: - tris.append([a, b, c]) - var mitte := Vector3(0.0, 0.7, 0.0) - match profil: - "schraege": - quad.call(V.call(-1, 0, -1), V.call(1, 0, -1), V.call(1, 2, 1), V.call(-1, 2, 1)) # Hang - quad.call(V.call(-1, 0, 1), V.call(1, 0, 1), V.call(1, 2, 1), V.call(-1, 2, 1)) # Rückwand - tri.call(V.call(-1, 0, -1), V.call(-1, 0, 1), V.call(-1, 2, 1)) # Stirn links - tri.call(V.call(1, 0, -1), V.call(1, 0, 1), V.call(1, 2, 1)) # Stirn rechts - quad.call(V.call(-1, 0, -1), V.call(1, 0, -1), V.call(1, 0, 1), V.call(-1, 0, 1)) # Boden - "ecke_aussen": - tri.call(V.call(-1, 0, -1), V.call(1, 0, -1), V.call(1, 2, 1)) - tri.call(V.call(-1, 0, -1), V.call(1, 2, 1), V.call(-1, 0, 1)) - tri.call(V.call(1, 0, -1), V.call(1, 0, 1), V.call(1, 2, 1)) - tri.call(V.call(-1, 0, 1), V.call(1, 0, 1), V.call(1, 2, 1)) - quad.call(V.call(-1, 0, -1), V.call(1, 0, -1), V.call(1, 0, 1), V.call(-1, 0, 1)) - "ecke_innen": - tri.call(V.call(-1, 0, -1), V.call(1, 2, -1), V.call(1, 2, 1)) - tri.call(V.call(-1, 0, -1), V.call(1, 2, 1), V.call(-1, 2, 1)) - tri.call(V.call(-1, 0, -1), V.call(1, 0, -1), V.call(1, 2, -1)) - tri.call(V.call(-1, 0, -1), V.call(-1, 2, 1), V.call(-1, 0, 1)) - quad.call(V.call(1, 0, -1), V.call(1, 0, 1), V.call(1, 2, 1), V.call(1, 2, -1)) - quad.call(V.call(-1, 0, 1), V.call(1, 0, 1), V.call(1, 2, 1), V.call(-1, 2, 1)) - quad.call(V.call(-1, 0, -1), V.call(1, 0, -1), V.call(1, 0, 1), V.call(-1, 0, 1)) - "plateau": - var bm := BoxMesh.new() - bm.size = Vector3(2.0, 2.0, 2.0) - var arr := bm.get_mesh_arrays() - var out := ArrayMesh.new() - out.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) - return out - "stirn": - # Dünnes Dreieck-Prisma (Kante entlang X, 2 m breit, 2 m hoch, 0,2 m dick) - var d := 0.1 - tri.call(V.call(-1, 0, -d), V.call(1, 0, -d), V.call(-1, 2, -d)) - tri.call(V.call(-1, 0, d), V.call(-1, 2, d), V.call(1, 0, d)) - quad.call(V.call(-1, 0, -d), V.call(-1, 0, d), V.call(1, 0, d), V.call(1, 0, -d)) - quad.call(V.call(-1, 0, -d), V.call(-1, 2, -d), V.call(-1, 2, d), V.call(-1, 0, d)) - quad.call(V.call(1, 0, -d), V.call(1, 0, d), V.call(-1, 2, d), V.call(-1, 2, -d)) - mitte = Vector3(-0.33, 0.67, 0.0) - var pos := PackedVector3Array() - var nrm := PackedVector3Array() - for t in tris: - var a: Vector3 = t[0] - var b: Vector3 = t[1] - var c: Vector3 = t[2] - var n := (b - a).cross(c - a).normalized() - # nach außen drehen: Fläche muss vom Körper-Mittelpunkt wegzeigen - if n.dot((a + b + c) / 3.0 - mitte) < 0.0: - var tmp := b - b = c - c = tmp - n = -n - pos.append_array(PackedVector3Array([a, b, c])) - nrm.append_array(PackedVector3Array([n, n, n])) - var arrays := [] - arrays.resize(Mesh.ARRAY_MAX) - arrays[Mesh.ARRAY_VERTEX] = pos - arrays[Mesh.ARRAY_NORMAL] = nrm - var m := ArrayMesh.new() - m.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) - return m - - -static func _addon_mesh(kind: Dictionary) -> ArrayMesh: - var geo := Node3D.new() - geo.set_script(load(GEO_SCRIPT)) - geo.set("piece_type", int(kind["typ"])) - geo.set("unit_size", float(kind.get("hoehe", WAND_H))) - geo.set("thickness", DICKE_M) - if kind.has("rise"): - geo.set("rise", float(kind["rise"])) - if kind.has("stufen"): - geo.set("stair_count", int(kind["stufen"])) - geo.set("stair_width", float(kind["breite"])) - var pts := PackedVector3Array() - for p in (kind["punkte"] as Array): - pts.append(Vector3(float(p[0]), float(p[1]), float(p[2]))) - geo.set("custom_points", pts) - for d in (kind.get("details", []) as Array): - var detail := Node3D.new() - detail.set_script(load(DETAIL_SCRIPT)) - detail.set("detail_type", int(d["typ"])) - detail.set("width", float(d["w"])) - detail.set("height", float(d["h"])) - detail.position = Vector3(float(d["pos"][0]), float(d["pos"][1]), float(d["pos"][2])) - geo.add_child(detail) - var m: ArrayMesh = geo.call("_make_mesh") - geo.free() - return m - - -## Alle Flächen zu EINER Fläche verschmelzen, Fußpunkt-normalisieren, Material- -## Farbe setzen. -static func _normalisieren(roh: ArrayMesh, farbe: Color) -> ArrayMesh: - var aabb := roh.get_aabb() - var versatz := Vector3(aabb.position.x + aabb.size.x * 0.5, aabb.position.y, - aabb.position.z + aabb.size.z * 0.5) - var pos := PackedVector3Array() - var nrm := PackedVector3Array() - for s in roh.get_surface_count(): - var arr := roh.surface_get_arrays(s) - var v: PackedVector3Array = arr[Mesh.ARRAY_VERTEX] - var n: Variant = arr[Mesh.ARRAY_NORMAL] - var idx: Variant = arr[Mesh.ARRAY_INDEX] - var order: Array = [] - if idx is PackedInt32Array and not (idx as PackedInt32Array).is_empty(): - for i in (idx as PackedInt32Array): - order.append(i) - else: - for i in v.size(): - order.append(i) - for i in order: - pos.append(v[i] - versatz) - nrm.append((n as PackedVector3Array)[i] if n is PackedVector3Array else Vector3.UP) - # Die Addon-Geometrie hat Dreiecke gegen die Normalenrichtung gewickelt (sie - # rendert ohne Backface-Culling). Godot culled Rückseiten → Wicklung an die - # Normale anpassen, sonst sieht man Innenseiten und Dächer werden schwarz. - for t in range(0, pos.size() - 2, 3): - var gn := (pos[t + 2] - pos[t]).cross(pos[t + 1] - pos[t]) - if gn.dot(nrm[t]) < 0.0: - var tmp := pos[t + 1] - pos[t + 1] = pos[t + 2] - pos[t + 2] = tmp - var tn := nrm[t + 1] - nrm[t + 1] = nrm[t + 2] - nrm[t + 2] = tn - var arrays := [] - arrays.resize(Mesh.ARRAY_MAX) - arrays[Mesh.ARRAY_VERTEX] = pos - arrays[Mesh.ARRAY_NORMAL] = nrm - var out := ArrayMesh.new() - out.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) - var mat := StandardMaterial3D.new() - mat.albedo_color = farbe - mat.roughness = 0.9 - out.surface_set_material(0, mat) - return out - - -static func dreiecke(oid: String) -> int: - var m := mesh(oid) - return int(m.get_faces().size() / 3) if m != null else 0 - - -# ------------------------------------------------- Kollision / Registry ------ - -## Trimesh-Datei (library/kollisions/.json) — gleiche Felder wie die -## Pack-Dateien: Dreiecks-Suppe in Fußpunkt-Koordinaten. Türen, Fenster und -## Scharten sind echte Löcher (die Öffnung hat keine Dreiecke). -static func kollisions_json(oid: String) -> Dictionary: - var m := mesh(oid) - if m == null: - return {} - var verts: Array = [] - for v in m.get_faces(): - verts.append([snappedf(v.x, 0.0001), snappedf(v.y, 0.0001), snappedf(v.z, 0.0001)]) - var aabb := m.get_aabb() - return { - "oid": oid, - "quelle_glb": "res://assets/objekte/military_desert/%s/%s.glb" % [KATEGORIE, oid], - "dreiecke": int(verts.size() / 3), - "aabb_min": [snappedf(aabb.position.x, 0.001), snappedf(aabb.position.y, 0.001), snappedf(aabb.position.z, 0.001)], - "aabb_max": [snappedf(aabb.end.x, 0.001), snappedf(aabb.end.y, 0.001), snappedf(aabb.end.z, 0.001)], - "vertices": verts, - } - - -## Registry-Eintrag (Fragment library/objects.d/bauteile.json). -static func registry_eintrag(oid: String) -> Dictionary: - var g := groesse(oid) - return { - "poly": dreiecke(oid), - "collision": { - "quelle": "kollisions/%s.json" % oid, - "shape": "trimesh", - "size": [snappedf(g.x, 0.001), snappedf(g.y, 0.001), snappedf(g.z, 0.001)], - }, - "glb": "res://assets/objekte/military_desert/%s/%s.glb" % [KATEGORIE, oid], - "kategorie": KATEGORIE, - "name_de": label(oid), - } - - -## GLB schreiben (eigenes Mesh mit Vertex-Farben). Rückgabe: Godot-Fehlercode. -static func glb_schreiben(oid: String, pfad: String) -> int: - var m := mesh(oid) - if m == null: - return ERR_DOES_NOT_EXIST - var root := Node3D.new() - root.name = oid - var mi := MeshInstance3D.new() - mi.name = oid - mi.mesh = m - root.add_child(mi) - var gdoc := GLTFDocument.new() - var gstate := GLTFState.new() - var err := gdoc.append_from_scene(root, gstate) - if err == OK: - err = gdoc.write_to_filesystem(gstate, pfad) - root.free() - return err diff --git a/src/editor/bau_katalog.gd.uid b/src/editor/bau_katalog.gd.uid deleted file mode 100644 index 3ab1224..0000000 --- a/src/editor/bau_katalog.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://defuinyvy5j8i diff --git a/src/editor/bau_ops.gd b/src/editor/bau_ops.gd deleted file mode 100644 index 3a86fe8..0000000 --- a/src/editor/bau_ops.gd +++ /dev/null @@ -1,204 +0,0 @@ -extends RefCounted -class_name BauOps -## Dokument-Operationen des Bauen-Modus (pure Funktionen, headless testbar). -## -## Ein Gebäude = eine Gruppe (GroupOps, Feld "group" + group_names) aus `bau_*`- -## Objekten. Alles Weitere — Verschieben, Drehen, Kopieren, Löschen, Symmetrie, -## Speichern — läuft über die normalen Objekt-Funktionen. Dieser Teil kennt nur, -## was speziell am Bauen ist: Teil setzen/ersetzen, Gebäude-Gruppen, Migration -## der alten "gebaeude"-Sektion (Karte t_97ea59c5 → Umbau 25.10.). - - -static func teile_zahl(doc: Dictionary) -> int: - var n := 0 - for o in (doc.get("objects", []) as Array): - if o is Dictionary and BauKatalog.ist_bau(str((o as Dictionary).get("id", ""))): - n += 1 - return n - - -## Dreiecke aller Bauteile (grobe Poly-Übersicht für die Statuszeile). -static func dreiecke_gesamt(doc: Dictionary) -> int: - var n := 0 - for o in (doc.get("objects", []) as Array): - if o is Dictionary: - n += BauKatalog.dreiecke(str((o as Dictionary).get("id", ""))) - return n - - -## Neue Gebäude-Gruppe anlegen und benennen. Rückgabe: Gruppen-ID. -static func gruppe_neu(doc: Dictionary) -> int: - var gid := GroupOps.next_group_id(doc) - GroupState.set_group_name(doc, gid, "Gebäude %d" % (gebaeude_zahl(doc) + 1)) - return gid - - -## Anzahl Gebäude-Gruppen (Gruppen, deren erstes Mitglied ein Bauteil ist). -static func gebaeude_zahl(doc: Dictionary) -> int: - return gebaeude_gruppen(doc).size() - - -## [{gid, name, indizes, dreiecke}] für alle Gebäude-Gruppen. -static func gebaeude_gruppen(doc: Dictionary) -> Array: - var out: Array = [] - var objects: Array = doc.get("objects", []) - for gid in GroupOps.active_group_ids(doc): - var members := GroupOps.members_of(doc, int(gid)) - if members.is_empty(): - continue - var bau := false - var tris := 0 - for i in members: - var oid := str((objects[i] as Dictionary).get("id", "")) - if BauKatalog.ist_bau(oid): - bau = true - tris += BauKatalog.dreiecke(oid) - if bau: - out.append({"gid": int(gid), "name": GroupState.display_name(doc, int(gid)), - "indizes": members, "dreiecke": tris}) - return out - - -## Teil setzen oder ersetzen (snap = BuildSnap.berechne-Ergebnis, ok=true). -## Mutiert doc["objects"]; der Aufrufer macht snapshot/commit. -## gid: Zielgruppe (Gebäude); bei Symmetrie bekommt der Zwilling ein eigenes -## Spiegel-Gebäude (spiegel_gid, vom Aufrufer gemerkt: 1 Original-Gebäude ↔ 1 Spiegel). -## Rückgabe: {index, twin, ersetzt}. -static func setze_teil(doc: Dictionary, oid: String, snap: Dictionary, gid: int, - sym_mode: int, spiegel_gid := -1) -> Dictionary: - var objects: Array = doc["objects"] - var pos: Vector3 = snap["pos"] - var rot := float(snap["rot"]) - var ersetze := int(snap.get("ersetze", -1)) - if ersetze >= 0 and ersetze < objects.size(): - var o: Dictionary = objects[ersetze] - o["id"] = oid - o["pos"] = [pos.x, pos.y, pos.z] - SvmapIO.rot_setzen(o, Vector3(0.0, rot, 0.0)) - # Symmetrie: der Zwilling bekommt dasselbe Teil an seiner (gespiegelten) Stelle. - var key := SymmetryCore.sym_of(o) - if sym_mode != SymmetryCore.Mode.OFF and not key.is_empty(): - var partner := SymmetryCore.find_partner_index(objects, key, ersetze) - if partner >= 0 and objects[partner] is Dictionary: - (objects[partner] as Dictionary)["id"] = oid - return {"index": ersetze, "twin": -1, "ersetzt": true} - var neu := {"id": oid, "pos": [pos.x, pos.y, pos.z], "scale": 1.0, "rot_y_deg": rot, "group": gid} - objects.append(neu) - var index := objects.size() - 1 - var twin := -1 - if sym_mode != SymmetryCore.Mode.OFF: - var res: Dictionary = ObjectOps.symmetry_place_twin(doc, index, sym_mode) - twin = int(res.get("twin", -1)) - if twin >= 0 and spiegel_gid >= 0: - (objects[twin] as Dictionary)["group"] = spiegel_gid - return {"index": index, "twin": twin, "ersetzt": false} - - -## Eine ganze Gebäude-Gruppe als Indizes (für „Ganzes Gebäude wählen“). -static func gebaeude_von(doc: Dictionary, index: int) -> Array: - var objects: Array = doc.get("objects", []) - if index < 0 or index >= objects.size(): - return [] - var gid := GroupOps.group_id(objects[index]) - if gid == GroupOps.UNGROUPED: - return [index] - return GroupOps.members_of(doc, gid) - - -# ----------------------------------------------------------- Demo / Test ---- - -## Kleines Haus über die echte Klick-Logik setzen (Fundament, Wände, Tür, Fenster, -## Giebel, Dach, Treppe) — für Demo und Tests. Jeder Schritt = BuildSnap-Treffer -## wie im Editor. Rückgabe: Gruppen-ID. history kann null sein. -static func haus_demo(doc: Dictionary, history: Variant, mitte: Vector3) -> int: - var gid := gruppe_neu(doc) - var terrain := func(_x: float, _z: float) -> float: return mitte.y - var before: Dictionary = history.snapshot(["objects", "group_names"]) if history != null else {} - # 2×2 Zellen (4×4 m): Zellmitten bei (±1, ±1) relativ zur Mitte. - var ox := floorf(mitte.x / 2.0) * 2.0 - var oz := floorf(mitte.z / 2.0) * 2.0 - var schritte := [ - ["bau_fundament", Vector3(ox - 1, mitte.y, oz - 1), 0.0], - ["bau_fundament", Vector3(ox + 1, mitte.y, oz - 1), 0.0], - ["bau_fundament", Vector3(ox - 1, mitte.y, oz + 1), 0.0], - ["bau_fundament", Vector3(ox + 1, mitte.y, oz + 1), 0.0], - # Wände liegen GANZ in der Zelle, in der die Maus ist (Außenseite bündig mit - # der Kante) — deshalb zielen die Klicks 10 cm ins Hausinnere. - ["bau_wand", Vector3(ox - 1, mitte.y, oz - 1.9), 0.0], - ["bau_wand_fenster", Vector3(ox + 1, mitte.y, oz - 1.9), 0.0], - ["bau_wand_tuer", Vector3(ox - 1, mitte.y, oz + 1.9), 0.0], - ["bau_wand", Vector3(ox + 1, mitte.y, oz + 1.9), 0.0], - ["bau_wand", Vector3(ox - 1.9, mitte.y, oz - 1), 90.0], - ["bau_wand_scharte", Vector3(ox - 1.9, mitte.y, oz + 1), 90.0], - ["bau_wand", Vector3(ox + 1.9, mitte.y, oz - 1), 90.0], - ["bau_wand", Vector3(ox + 1.9, mitte.y, oz + 1), 90.0], - ] - for st in schritte: - _demo_setzen(doc, str(st[0]), st[1] as Vector3, float(st[2]), gid, terrain) - # Ein großes Satteldach (4×4 m) auf die Wandoberkante. - var oben := mitte.y + BauKatalog.WAND_H - _demo_setzen(doc, "bau_dach_giebel_4", Vector3(ox, oben, oz), 0.0, gid, terrain) - if history != null: - history.commit("Haus gebaut (Demo)", before, history.snapshot(["objects", "group_names"])) - return gid - - -static func _demo_setzen(doc: Dictionary, oid: String, hit: Vector3, dreh: float, gid: int, - gelaende: Callable) -> void: - var teile := BuildSnap.sammle_teile(doc) - var snap := BuildSnap.berechne(oid, hit, dreh, teile, gelaende) - if bool(snap["ok"]): - setze_teil(doc, oid, snap, gid, SymmetryCore.Mode.OFF) - - -# --------------------------------------------------------------- Migration -- - -## Alte Sektion doc["gebaeude"] (Karte t_97ea59c5, 10 prozedurale Teile ohne -## Registry) → bau_*-Objekte in EINER Gruppe, dann Sektion entfernen. Beste -## Näherung: Teil-Ursprünge der alten Teile lagen an Wandanfang/Zellmitte, die -## neuen Bauteile an der Mitte der Grundfläche; Höhen (2 m → 3 m) ändern sich. -## Rückgabe: Anzahl übernommener Teile. -const _ALT := { - "fundament": "bau_fundament", "boden": "bau_boden", "wand": "bau_wand", - "tuer": "bau_wand_tuer", "fenster": "bau_wand_fenster", - "giebelwand": "bau_giebelwand", "giebelwand_rechts": "bau_giebelwand", - "dach_giebel": "bau_dach_giebel", "dach_pyramide": "bau_dach_pyramide", - "treppe": "bau_treppe", -} - -static func migriere_gebaeude(doc: Dictionary) -> int: - if not doc.has("gebaeude"): - return 0 - var alt: Variant = doc["gebaeude"] - doc.erase("gebaeude") - if not (alt is Array) or (alt as Array).is_empty(): - return 0 - if not doc.has("objects") or not (doc["objects"] is Array): - doc["objects"] = [] - var objects: Array = doc["objects"] - var gid := gruppe_neu(doc) - var n := 0 - for teil in alt: - if not (teil is Dictionary): - continue - var oid: String = _ALT.get(str((teil as Dictionary).get("id", "")), "") - if oid.is_empty(): - continue - var p: Array = (teil as Dictionary).get("pos", [0.0, 0.0, 0.0]) - var rot := float((teil as Dictionary).get("rot", 0.0)) - var pos := Vector3(float(p[0]), float(p[1]), float(p[2])) - var local := Vector3.ZERO - match str((teil as Dictionary).get("id", "")): - "wand", "tuer", "fenster", "giebelwand", "giebelwand_rechts": - local = Vector3(1.0, 0.0, 0.0) # alt: Ursprung am Wandanfang - "treppe": - local = Vector3(2.0, 0.0, 0.0) # alt: 2 m lang ab Ursprung - "boden": - pos.y -= BauKatalog.DICKE_M # alt: Oberkante am Ursprung - pos += Basis(Vector3.UP, deg_to_rad(rot)) * local - objects.append({"id": oid, "pos": [pos.x, pos.y, pos.z], "scale": 1.0, - "rot_y_deg": fposmod(rot, 360.0), "group": gid}) - n += 1 - if n == 0: - GroupState.set_group_name(doc, gid, "") - return n diff --git a/src/editor/bau_ops.gd.uid b/src/editor/bau_ops.gd.uid deleted file mode 100644 index 1bd8d65..0000000 --- a/src/editor/bau_ops.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bh4sybddgu3mt diff --git a/src/editor/build_snap.gd b/src/editor/build_snap.gd deleted file mode 100644 index 36997a3..0000000 --- a/src/editor/build_snap.gd +++ /dev/null @@ -1,256 +0,0 @@ -extends RefCounted -class_name BuildSnap -## Raster- und Ebenen-Logik des Bauen-Modus (pure Funktionen, headless testbar). -## -## Warum neu: die alte Logik rastete jedes Teil NUR auf eine Zellecke und nahm -## als Höhe die Klickhöhe — ein Klick auf die Seite einer Wand setzte das neue -## Teil mitten in die Luft, Wände ließen sich nur über Rotationsraten an die -## richtige Kante bringen. Jetzt: -## • XZ: Zellen-Teile rasten in die Zellmitte, Wände auf die NÄCHSTE Zellkante -## (Drehung ergibt sich aus der Kante), Pfeiler auf die nächste Ecke, -## Treppen auf eine 4×2-m-Fläche über zwei Zellen. -## • Y: nie die Klickhöhe, sondern eine EBENE: Gelände (höchster Punkt unter -## der Grundfläche) oder Oberkante eines tragenden Bauteils darunter. Gewählt -## wird die höchste Ebene, die nicht mehr als TOL_M über dem Klickpunkt liegt. -## • Ein gleichartiges Teil auf demselben Platz wird ERSETZT (Tür in eine -## vorhandene Wand einsetzen); Klick auf die Oberkante stapelt stattdessen. -## -## Position eines Teils = Fußpunkt (Unterkante, Mitte der Grundfläche) — wie -## jedes Bibliotheks-Objekt (BauKatalog.mesh ist so normalisiert). - -const TOL_M := 0.35 # so weit darf eine Ebene ÜBER dem Klickpunkt liegen -const SHRINK_M := 0.05 # Grundflächen-Schnitt: minimale Überlappung ignorieren -const SAME_M := 0.08 # Toleranz für "gleiche Stelle" -const UEBERSTAND_M := 0.01 # Wand-Außenseite steht 1 cm vor der Plattenkante: keine deckungsgleichen - # Flächen (Z-Fighting/Flackern an Boden↔Wand) - - -## Ergebnis-Wörterbuch: -## ok false = hier nicht setzbar (grund erklärt warum) -## pos Vector3 Fußpunkt -## rot Y-Drehung in Grad -## ersetze Index des Objekts, das ersetzt wird (-1 = neues Teil) -## ebene gewählte Höhe (= pos.y) -## grund Klartext (bei ok=false) bzw. Hinweis -## -## teile: Array von {"i": Index, "oid": String, "pos": Vector3, "rot": float} -## (nur Bauteile, siehe sammle_teile). -## gelaende: Callable(x: float, z: float) -> float -## dreh: Nutzerdrehung in Grad (wird auf 90° gerastet) -## kamera_dir: Blickrichtung des Klickstrahls (für Zell-Wahl an Wandkanten), optional -## ebene_fix: feste Geschosshöhe (Geschoss-Wahl im Bauen-Tab); NAN = automatisch. -## Dann hängt die Höhe NICHT mehr an Wänden/Böden darunter — Decken und Böden -## lassen sich auch mitten im großen Raum setzen. -static func berechne(oid: String, hit: Vector3, dreh: float, teile: Array, - gelaende: Callable, hit_ist_objekt := false, kamera_dir := Vector3.ZERO, - ebene_fix := NAN) -> Dictionary: - var art := BauKatalog.snap_art(oid) - var gr := BauKatalog.groesse(oid) - var q := int(roundf(dreh / 90.0)) - var viertel := ((q % 4) + 4) % 4 - var p := Vector2(hit.x, hit.z) - # Treffer auf einem Objekt: Wände liegen GANZ in einer Zelle — die Quer-Achse - # kommt dann von der Wand (Decke/Dach landet in der Zelle der Wand). Bei anderen - # Objekten die Zelle auf der Kameraseite wählen (Klick liegt auf einer Grenze). - var wand_getroffen := {} - if hit_ist_objekt: - wand_getroffen = _wand_unter_klick(teile, p, hit.y) - if hit_ist_objekt and art != "kante": - if not wand_getroffen.is_empty(): - var wp: Vector3 = wand_getroffen["pos"] - if absf(sin(deg_to_rad(float(wand_getroffen["rot"])))) > 0.5: - p.x = wp.x - else: - p.y = wp.z - elif kamera_dir != Vector3.ZERO: - var d2 := Vector2(kamera_dir.x, kamera_dir.z) - if d2.length() > 0.01: - p -= d2.normalized() * 0.2 - var mitte := Vector2.ZERO - var rot := 0.0 - var r := BauKatalog.RASTER_M - match art: - "zelle": - # Teile über mehrere Zellen (große Dächer): gerade Zellzahl → Mitte auf - # einer Zellecke, ungerade → Mitte einer Zelle. - mitte = Vector2(_raster_mitte(p.x, gr.x), _raster_mitte(p.y, gr.z)) - rot = viertel * 90.0 - "ecke": - mitte = Vector2(roundf(p.x / r) * r, roundf(p.y / r) * r) - "treppe": - rot = viertel * 90.0 - if viertel % 2 == 0: # Lauf entlang X: Mitte auf gerader X-, ungerader Z-Linie - mitte = Vector2(roundf(p.x / r) * r, floorf(p.y / r) * r + r * 0.5) - else: - mitte = Vector2(floorf(p.x / r) * r + r * 0.5, roundf(p.y / r) * r) - _: # "kante" - var vorhanden := wand_getroffen - if not vorhanden.is_empty(): - # Klick auf eine vorhandene Wand (Seite = ersetzen, Oberkante = stapeln): - # GENAU ihre Lage übernehmen, nicht neu aus der Klickstelle raten. - var tp: Vector3 = vorhanden["pos"] - mitte = Vector2(tp.x, tp.z) - rot = 90.0 if absf(sin(deg_to_rad(float(vorhanden["rot"])))) > 0.5 else 0.0 - else: - # Wand liegt GANZ IN der Zelle, in der der Mauszeiger ist: Außenseite - # bündig mit der Zellkante (Boden/Fundament), nicht halb in der Luft. - # Dadurch schließen sich auch Ecken ohne Lücke (Test-Befund 25.10.). - var laenge := gr.x - var halbe_dicke := gr.z * 0.5 - var fx := p.x / r - var fz := p.y / r - var h_mitte := Vector2(_raster_mitte(p.x, laenge), roundf(fz) * r) # Kante entlang X - var v_mitte := Vector2(roundf(fx) * r, _raster_mitte(p.y, laenge)) # Kante entlang Z - if p.distance_squared_to(h_mitte) <= p.distance_squared_to(v_mitte): - mitte = h_mitte - mitte.y += (halbe_dicke - UEBERSTAND_M) * (1.0 if p.y >= h_mitte.y else -1.0) - rot = 0.0 - else: - mitte = v_mitte - mitte.x += (halbe_dicke - UEBERSTAND_M) * (1.0 if p.x >= v_mitte.x else -1.0) - rot = 90.0 - rot += 180.0 * float(viertel % 2) # R dreht die Wand um (Blickseite der Teile) - rot = fposmod(rot, 360.0) - var quer := absf(sin(deg_to_rad(rot))) > 0.5 # 90°/270°: X- und Z-Ausdehnung getauscht - var half := Vector2(gr.z, gr.x) * 0.5 if quer else Vector2(gr.x, gr.z) * 0.5 - var rect := Rect2(mitte - half, half * 2.0) - - # Ebenen sammeln: Gelände + Oberkanten tragender Teile unter der Grundfläche. - var gel_max := -INF - for sx in [0.0, 0.5, 1.0]: - for sz in [0.0, 0.5, 1.0]: - gel_max = maxf(gel_max, float(gelaende.call(rect.position.x + rect.size.x * sx, - rect.position.y + rect.size.y * sz))) - var ebenen: Array = [gel_max] - var kern := rect.grow(-SHRINK_M) - for t in teile: - var troid := str(t["oid"]) - var tr := teil_rect(t) - if not tr.intersects(kern): - continue - var top: float = (t["pos"] as Vector3).y + BauKatalog.groesse(troid).y - if not BauKatalog.ist_traeger(troid): - continue - if (art == "kante" or art == "ecke") and BauKatalog.ist_platte(troid): - # Wände/Pfeiler zählen von der UNTERKANTE einer Platte (Boden/Decke/ - # Fundament): jedes Geschoss liegt dadurch auf Vielfachen der Wandhöhe — - # mit oder ohne Decke darunter sitzen obere Wände gleich hoch - # (Test-Befund 25.10.). Die Platte selbst liegt auf der Wandoberkante. - ebenen.append((t["pos"] as Vector3).y) - else: - ebenen.append(top) - var ebene := ebene_fix if not is_nan(ebene_fix) else _waehle_ebene(ebenen, hit.y) - - # Platz belegt? Gleiche Art + gleiche Stelle + gleiche Ebene → ersetzen/ablehnen. - var ersetze := -1 - for t in teile: - var troid := str(t["oid"]) - if BauKatalog.snap_art(troid) != art: - continue - var tp: Vector3 = t["pos"] - if absf(tp.y - ebene) > SAME_M: - continue - if Vector2(tp.x, tp.z).distance_to(mitte) > SAME_M: - continue - if art == "kante" and absf(fposmod(float(t["rot"]), 180.0) - fposmod(rot, 180.0)) > 1.0: - continue - if art == "treppe" and absf(fposmod(float(t["rot"]), 360.0) - rot) > 1.0: - continue - if troid == oid and absf(fposmod(float(t["rot"]) - rot, 360.0)) < 1.0: - return {"ok": false, "pos": Vector3(mitte.x, ebene, mitte.y), "rot": rot, "ersetze": -1, - "ebene": ebene, "grund": "Hier steht schon %s." % BauKatalog.label(oid)} - ersetze = int(t["i"]) - break - return {"ok": true, "pos": Vector3(mitte.x, ebene, mitte.y), "rot": rot, "ersetze": ersetze, - "ebene": ebene, "grund": ""} - - -## Mitte eines Teils der Länge `laenge` entlang einer Achse: gerade Zellzahl → -## auf der nächsten Zellgrenze, ungerade → Mitte der Zelle. -static func _raster_mitte(wert: float, laenge: float) -> float: - var r := BauKatalog.RASTER_M - var zellen := maxi(1, int(roundf(laenge / r))) - if zellen % 2 == 0: - return roundf(wert / r) * r - return floorf(wert / r) * r + r * 0.5 - - -## Vorhandene Wand, auf die der Klick trifft (Seite oder Oberkante): Rückgabe das -## Teil-Wörterbuch oder {}. `p` = Klickpunkt in XZ, `y` = Klickhöhe. -static func _wand_unter_klick(teile: Array, p: Vector2, y: float) -> Dictionary: - var bester := {} - var bester_d := INF - for t in teile: - var troid := str(t["oid"]) - if BauKatalog.snap_art(troid) != "kante": - continue - var tr := teil_rect(t).grow(0.06) - if not tr.has_point(p): - continue - var unten: float = (t["pos"] as Vector3).y - var oben := unten + BauKatalog.groesse(troid).y - if y < unten - 0.1 or y > oben + 0.1: - continue - var d := p.distance_squared_to(tr.get_center()) - if d < bester_d: - bester_d = d - bester = t - return bester - - -## Höchste Ebene ≤ hit_y + TOL; gibt es keine (Klick tief unter allen), die tiefste. -static func _waehle_ebene(ebenen: Array, hit_y: float) -> float: - var best := -INF - var tiefste := INF - for e in ebenen: - var ev := float(e) - tiefste = minf(tiefste, ev) - if ev <= hit_y + TOL_M and ev > best: - best = ev - return best if best > -INF else tiefste - - -## Grundfläche (XZ) eines gesetzten Bauteils in Weltkoordinaten. -static func teil_rect(t: Dictionary) -> Rect2: - var gr := BauKatalog.groesse(str(t["oid"])) - var rot := float(t["rot"]) - var quer := absf(sin(deg_to_rad(rot))) > 0.5 - var half := Vector2(gr.z, gr.x) * 0.5 if quer else Vector2(gr.x, gr.z) * 0.5 - var pos: Vector3 = t["pos"] - return Rect2(Vector2(pos.x, pos.z) - half, half * 2.0) - - -## Alle Bauteile aus doc["objects"] (Index, oid, pos, rot) — nur `bau_*`. -static func sammle_teile(doc: Dictionary) -> Array: - var out: Array = [] - var objects: Array = doc.get("objects", []) - for i in objects.size(): - var o: Variant = objects[i] - if not (o is Dictionary): - continue - var oid := str((o as Dictionary).get("id", "")) - if not BauKatalog.ist_bau(oid): - continue - var pos: Array = (o as Dictionary).get("pos", [0.0, 0.0, 0.0]) - if pos.size() != 3: - continue - out.append({ - "i": i, "oid": oid, - "pos": Vector3(float(pos[0]), float(pos[1]), float(pos[2])), - "rot": float(SvmapIO.objekt_rotation(o as Dictionary).y), - }) - return out - - -## Höhe des untersten Geschosses (= Fußpunkt der tiefsten Platte/Wand im Umkreis von -## `radius` um `p`), sonst das Gelände bei `p`. Geschoss k liegt bei Basis + k·WAND_H. -static func geschoss_basis(teile: Array, p: Vector2, gelaende: Callable, radius := 40.0) -> float: - var tiefste := INF - for t in teile: - var tp: Vector3 = t["pos"] - if Vector2(tp.x, tp.z).distance_to(p) > radius: - continue - var oid := str(t["oid"]) - if BauKatalog.ist_platte(oid) or BauKatalog.snap_art(oid) == "kante": - tiefste = minf(tiefste, tp.y) - return tiefste if tiefste < INF else float(gelaende.call(p.x, p.y)) diff --git a/src/editor/build_snap.gd.uid b/src/editor/build_snap.gd.uid deleted file mode 100644 index 1d8709e..0000000 --- a/src/editor/build_snap.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://irnbwhk0eijq diff --git a/src/editor/fly_math.gd b/src/editor/fly_math.gd deleted file mode 100644 index 22276b5..0000000 --- a/src/editor/fly_math.gd +++ /dev/null @@ -1,71 +0,0 @@ -extends RefCounted -class_name FlyMath -## Freelook-Flug-Mathe (Karte t_c46d31c2, Karte 1/3) — bewusst pure Funktionen -## (kein Knoten, keine Kamera): speed_for/wheel_speed/move_delta/forward- und -## Euler-Umrechnung. tests/test_shortcuts.gd prüft headless; orbit_camera.gd -## ist nur der dünne Anwender. -## -## Euler-Konvention identisch zur Orbit-Kamera (_apply in orbit_camera.gd): -## Blickrichtung forward(yaw, pitch) = -## (−sin(yaw)·cos(pitch), −sin(pitch), −cos(yaw)·cos(pitch)) -## pitch positiv = Kamera schaut von OBEN herab (Orbit-Pitch 5…85°), -## im Flug erlaubt: −85…+85° (auch von unten hochschauen). - -const BASE_SPEED_MPS := 30.0 # Grundgeschwindigkeit (Mausrad ändert sie dauerhaft) -const FAST_MULT := 3.0 # Strg halten = schneller (Shooter-Konvention) -const SLOW_MULT := 0.3 # Alt halten = langsamer -const WHEEL_MULT := 1.15 # Mausrad-Tick: +15 % / −13 % -const SPEED_MIN_MPS := 2.0 -const SPEED_MAX_MPS := 300.0 - -const PITCH_MAX_DEG := 85.0 # Flug-Blick grenzwertig (±) — kein Gimbal-Kippen - - -## Flug-Tempo: Strg dominiert, wenn (unüblicherweise) beide Modifier unten sind. -static func speed_for(base_mps: float, fast: bool, slow: bool) -> float: - if fast: - return base_mps * FAST_MULT - if slow: - return base_mps * SLOW_MULT - return base_mps - - -## Mausrad-Tick: Grundgeschwindigkeit DAUERHAFT ändern (nicht nur solange -## gedrückt) — up=true schneller, down=false langsamer, immer geklemmt. -static func wheel_speed(base_mps: float, up: bool) -> float: - var next := base_mps * WHEEL_MULT if up else base_mps / WHEEL_MULT - return clampf(next, SPEED_MIN_MPS, SPEED_MAX_MPS) - - -## Bewegungs-Delta für einen Frame. forward = BLICKRICHTUNG (3D, mit Pitch — -## W/S fliegen dorthin, wo man hinsieht), right = horizontal-rechts, und -## vertikal ist Welt-UP (Leertaste/Shift heben/senken unabhängig vom Blick — -## Shooter-Konvention, Sly-Wunsch 17.10.). -## Diagonal-Eingaben werden normalisiert (kein √2-Tempo). Rückgabe: Meter. -static func move_delta(forward: Vector3, right: Vector3, fwd_input: float, - side_input: float, vert_input: float, speed_mps: float, delta_s: float) -> Vector3: - var dir := forward * fwd_input + right * side_input + Vector3.UP * vert_input - if dir.length_squared() < 0.0000001: - return Vector3.ZERO - return dir.normalized() * speed_mps * delta_s - - -## Blickrichtung → (yaw_deg, pitch_deg) in der Orbit-Konvention (siehe oben). -static func euler_from_forward(forward: Vector3) -> Vector2: - var f := forward - if f.length_squared() < 0.0000001: - return Vector2(0.0, 0.0) - f = f.normalized() - var pitch := rad_to_deg(asin(clampf(-f.y, -1.0, 1.0))) - var yaw := rad_to_deg(atan2(-f.x, -f.z)) - return Vector2(yaw, pitch) - - -## (yaw_deg, pitch_deg) → Blickrichtung (Inverse von euler_from_forward). -static func forward_from_euler(yaw_deg: float, pitch_deg: float) -> Vector3: - var yaw := deg_to_rad(yaw_deg) - var pitch := deg_to_rad(clampf(pitch_deg, -PITCH_MAX_DEG, PITCH_MAX_DEG)) - return Vector3( - -sin(yaw) * cos(pitch), - -sin(pitch), - -cos(yaw) * cos(pitch)) \ No newline at end of file diff --git a/src/editor/fly_math.gd.uid b/src/editor/fly_math.gd.uid deleted file mode 100644 index 9885ab3..0000000 --- a/src/editor/fly_math.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://btbsxedv3fvw diff --git a/src/editor/interaction.gd b/src/editor/interaction.gd deleted file mode 100644 index 266078f..0000000 --- a/src/editor/interaction.gd +++ /dev/null @@ -1,1729 +0,0 @@ -extends Node3D -## Maus-Interaktion im Editor-Viewport (M2 UX-Fundament, Karte t_40d855d0; -## Auswahl-System Erweiterung: Karte t_f6f29d86): -## - Ghost-Preview: beim Platzieren schwebt eine transparente Vorschau am -## Cursor, Klick setzt das Objekt (kein "überraschtes" Ergebnis). -## - Auswahl: angeklickte Objekte färben sich orange, Ziehen verschiebt, -## R-Taste ODER Mausrad dreht (15°-Raster), Entf löscht. -## - Mehrfachauswahl (Karte t_f6f29d86, erweitert t_c46d31c2): Umschalt+Klick -## ODER Strg+Klick fügt hinzu/entfernt, Rahmen-Aufziehen über leeren Boden -## wählt alles im Rahmen. Löschen/Duplizieren wirken auf die GANZE Auswahl. -## - Gruppen: Objekte mit gleicher "group"-ID ziehen/drehen gemeinsam -## (GroupOps), Gruppieren/Lösen über main-Buttons (Strg+G / Strg+Umschalt+G). -## - Undo: Jede Aktion = EINE ActionHistory-Stufe (auch Gruppen-Ziehen). -## Alle Meldungen laufen über main._set_status — Klartext + nächsten Schritt -## vorschlagen (Chef-Grundsatz, map-editor-README). -## -## Lebt im selben SubViewport-Welt-Knoten wie Kamera + Viewport-Bauer; -## main.gd verdrahtet Referenzen per setup(). - -const ROT_STEP_DEG := 15.0 -const TILT_STEP_DEG := 15.0 # Kipp-Schritt (Karte t_e166e656: Strg+R / Alt+R) -const DRAG_THRESHOLD_PX := 4.0 -const GRID_M := 1.0 # Raster-Snap-Weite (Objekt-Werkzeuge links, Karte t_3a998ae4) - -# Höhe beim Ziehen merken (Karte t_7567a06f): das Objekt behält seinen -# Abstand zum Terrain — ein angehobenes Objekt bleibt beim Verschieben oben. - -var main # Hauptfenster (script-erweitert, Variant — Referenzen per setup()) -var camera: Camera3D -var view_builder # script-erweitert, Variant - -# Platzier-Modus -var placing := false -var place_oid := "" -var place_rot_deg := 0.0 -var place_tilt_x := 0.0 # Kippen X beim Platzieren (Karte t_e166e656, Strg+R) -var place_tilt_z := 0.0 # Kippen Z beim Platzieren (Karte t_e166e656, Alt+R) -# U5 (t_5e3e97c9): Shift beim Setz-Klick = Serienmodus — weiter setzen wie -# bisher (Ghost bleibt an, jeder Klick setzt). Ohne Shift wird EIN Objekt -# gesetzt und das Werkzeug beendet sich selbst; das neue Objekt ist ausgewählt. -var _place_series := false -var _ghost: Node3D # Ghost-ROOT: Position = Objekt-Fußpunkt — - # identisch zur platzierten Marker-Position - # (Karte t_4092e3a0: Ghost == Platzierung). -var _ghost_mi: MeshInstance3D # Kind-Mesh, gehoben um half_height — - # exakt wie der Viewport-Bauer (map_view_builder). -var _ghost_active := false # Ghost sichtbar weil Cursor über der Map ist - -# Bauen-Modus (Bauteile bau_*): der Ghost rastet über BuildSnap (Kante/Zelle/ -# Ebene), jeder Klick setzt ein Teil in das laufende Gebäude (= Gruppe). -var build_group_id := -1 # laufendes Gebäude; -1 = nächstes Teil beginnt ein neues -var _build_last: Dictionary = {} # letztes BuildSnap-Ergebnis (pos/rot/ersetze/ok/grund) -var _build_hit: Dictionary = {} # letzter Treffer {punkt, obj, dir} -var _build_hint := "" # letzte Statuszeile des Ghosts (kein Spam) -var build_geschoss := -1 # -1 = Höhe automatisch, sonst festes Geschoss (0 = Boden, 1 = erste Decke …) -const BAU_GESCHOSS_MAX := 8 - -# Terrain-Höhen-Cache (Karte t_4092e3a0): der Objekt-Cursor trifft das GELÄNDE -# (TerrainField.raycast, wie Terrain-/Bauen-/Spawn-Werkzeug), nicht mehr nur -# die flache Basis-Ebene. Dekodiert einmal pro Map-Änderung, nicht pro Mausbewegung. -var _heights := PackedFloat32Array() -var _res := 0 -var _sx := 0.0 -var _sz := 0.0 - -# Auswahl + Greifen -var selected_index := -1 # PRIMÄR-Objekt (letzter Klick) — Grab/Status-Anker -var selected_indices: Array = [] # komplette Auswahl in Klick-Reihenfolge (int-Indizes) -var _dragging := false -var _drag_moved := false -var _press_pos := Vector2.ZERO -var _grab_offset := Vector3.ZERO # Einzel-Greifen (Rückwärtskompatibilität) -var _drag_lift := 0.0 # Terrain-Abstand des Objekts beim Anfassen (Höhe hebt sich mit) - -# Gruppen-/Mehrfach-Ziehen (Karte t_f6f29d86) -var _drag_members: Array = [] # Indizes, die GEMEINSAM ziehen -var _grab_offsets: Dictionary = {} # index (int) → Vector3 (y = 0) -var _drag_lifts: Dictionary = {} # index (int) → float (Terrain-Abstand beim Anfassen, t_7567a06f) -var _drag_primary := -1 # Anker-Objekt (Raster-Snap & Delta-Herkunft) -var _drag_is_group := false # Zieh-Menge = komplette svmap-Gruppe - -# Rahmen-Ausziehen (Rubberband) über leeren Boden -var _rubber_pending := false # Press auf leerer Fläche, noch nicht geschwenkt -var _rubber_active := false # Rahmen wird gerade aufgezogen -var _rubber_start := Vector2.ZERO -var _rubber_shift := false # Umschalt: Rahmen zur Auswahl HINZUFÜGEN - -# Strg halten = temporärer Snap-Zwang (Karte t_55257792): egal was der -# Raster-Snap-Schalter sagt — solange Strg unten ist, rastet Bewegen/Platzieren. -# Aus JEDEM durchgelassenen Input-Event aktualisiert (Maus- UND Taste). -var _ctrl_held := false - -# Greifen (Karte t_55257792, G — Blender-Semantik): die Auswahl hängt an der -# Maus, Linksklick setzt die neue Position (EIN Undo-Schritt), Esc bricht ab -# und stellt die EXAKTEN alten Positionen wieder her. -var _grabbing := false -var _grab_members: Array = [] # Indizes der Greif-Menge (inkl. Gruppe) -var _grab_primary := -1 -var _grab_originals: Dictionary = {} # idx (int) → [x, y, z] exakt (Rückabwicklung) -var _grab_lifts: Dictionary = {} # idx (int) → Terrain-Abstand beim Anfassen -var _grab_before: Dictionary = {} # History-Snapshot VOR dem Greifen -# Symmetrie-Zwillinge beim Greifen (M3, t_34908425): Mitglied → Partner-Index; -# Originale der Partner, die NICHT selbst greifen (für die Esc-Rückabwicklung). -var _grab_twin_map: Dictionary = {} # idx (int) → partner index (int) -var _grab_twin_originals: Dictionary = {} # partner idx (int) → [x, y, z] exakt - - -func setup(p_main, p_camera: Camera3D, p_builder) -> void: - main = p_main - camera = p_camera - view_builder = p_builder - refresh_terrain_cache() # t_4092e3a0: Cursor trifft das Gelände ab der ersten Mausbewegung - - -## Symmetrie-Modus aus dem Hauptfenster lesen (M3, t_34908425). Fehlt das Feld -## (ältere Test-Doppel, Setup-Reihenfolgen), gilt Aus — nie ein harter Fehler. -func _sym_mode() -> int: - var v: Variant = main.get("sym_mode") if main != null else null - return int(v) if v is int else SymmetryCore.Mode.OFF - - -## Kamera fragt: dreht das Mausrad gerade ein Objekt/eine Vorschau -## (dann zoomt das Rad NICHT)? Im Freelook-Flug (t_c46d31c2) blockt das Rad -## zusätzlich ALLE Objekt-Reaktionen — dort ändert es die Grundgeschwindigkeit. -func wheel_blocked() -> bool: - if _camera_flying(): - return true - return placing or selected_index >= 0 - - -func _camera_flying() -> bool: - return camera != null and camera.has_method("fly_active") \ - and bool(camera.call("fly_active")) - - -## Höhen-Cache auffrischen (Karte t_4092e3a0): NACH Terrain-Edits, Undo/Redo, -## Laden/Neu — main ruft das in _after_structure_change. Ein Decode pro -## Änderung statt pro Mausbewegung (129×129-Quantisierung bleibt billig). -func refresh_terrain_cache() -> void: - var terrain: Dictionary = main.doc.get("terrain", {}) - _res = int(terrain.get("resolution", 0)) - _sx = float(terrain.get("size_x_m", 0.0)) - _sz = float(terrain.get("size_z_m", 0.0)) - if _res >= 2 and _sx > 0.0 and _sz > 0.0: - _heights = SvmapIO.decode_heights(terrain) - else: - _heights = PackedFloat32Array() - - -func _ground_point(viewport_pos: Vector2) -> Variant: - # Cursor-Strahl → erster Treffer AUF DEM GELÄNDE (Karte t_4092e3a0): die - # Höhenform zählt, nicht die flache Basis-Ebene — sonst landet ein Objekt - # auf einem Hügel versetzt hinter dem Cursor. Gleicher Pfad wie Terrain-, - # Bauen- und Spawn-Werkzeug (TerrainField.raycast). Rückgabe null = kein - # Treffer (Strahl ins Leere / außerhalb der Map). - var terrain: Dictionary = main.doc.get("terrain", {}) - if terrain.is_empty(): - return null - var origin := camera.project_ray_origin(viewport_pos) - var dir := camera.project_ray_normal(viewport_pos) - if _res >= 2 and _heights.size() >= _res * _res: - return TerrainField.raycast(_heights, _res, _sx, _sz, origin, dir) - # Fallback (Map ohne brauchbares Höhenfeld): Basis-Ebene wie bisher. - var plane_y := float(terrain.get("min_height_m", 0.0)) - if absf(dir.y) < 0.0001: - return null - var t := (plane_y - origin.y) / dir.y - if t <= 0.0: - return null - return origin + dir * t - - -func _terrain_half() -> Vector2: - var terrain: Dictionary = main.doc.get("terrain", {}) - return Vector2(float(terrain.get("size_x_m", 1024.0)), float(terrain.get("size_z_m", 1024.0))) * 0.5 - - -## Cursor-Strahl → getroffenes Objekt. Rückgabe: Index in doc.objects oder -1. -## Zwei Stufen (Mauer-Klick-Fix 24.10.): Die Kugel-Näherung der Marker ist nur -## noch Vorfilter — entschieden wird über den EXAKTEN Treffer auf den echten -## Mesh-Dreiecken (nächstes getroffenes Objekt gewinnt). Nur wenn der Strahl -## kein Mesh trifft, zählt wie bisher die nächste Kugel (kleine Objekte und -## Platzhalter bleiben leicht anklickbar). -func _pick_object(viewport_pos: Vector2) -> int: - var origin := camera.project_ray_origin(viewport_pos) - var dir := camera.project_ray_normal(viewport_pos) - var ground: Variant = _ground_point(viewport_pos) - var ground_t := INF - if ground != null: - ground_t = (ground as Vector3).distance_to(origin) - var exact := -1 - var exact_t := INF - var best := -1 - var best_t := INF - for marker in view_builder.object_markers: - if marker == null or not is_instance_valid(marker): - continue - var center: Vector3 = marker.global_position + Vector3.UP * float(marker.get_meta("half_height", 1.0)) - var to_center := center - origin - var tca := to_center.dot(dir) - if tca <= 0.0: - continue - var d2 := to_center.length_squared() - tca * tca - var radius := float(marker.get_meta("pick_radius", 1.0)) - if d2 > radius * radius: - continue - var t := tca - sqrt(radius * radius - d2) - if t < best_t and t < ground_t + 0.01: - best = int(marker.get_meta("obj_index", -1)) - best_t = t - var mi := SelectionMath.marker_mesh(marker) - if mi != null and mi.mesh != null: - var mt := SelectionMath.ray_mesh_distance(mi.global_transform, - SelectionMath.mesh_faces(mi.mesh), origin, dir) - if mt >= 0.0 and mt < exact_t and mt < ground_t + 0.01: - exact = int(marker.get_meta("obj_index", -1)) - exact_t = mt - return exact if exact >= 0 else best - - -# ------------------------------------------------------------ Platzieren ---- - -func start_placement(oid: String) -> void: - place_oid = oid - placing = true - place_rot_deg = 0.0 - place_tilt_x = 0.0 - place_tilt_z = 0.0 - _place_series = BauKatalog.ist_bau(oid) # U5: Einmal-Modus; Bauteile = Serie (Esc beendet) - _ghost_active = false - _build_last = {} - _build_hit = {} - _build_hint = "" - refresh_terrain_cache() # Cursor trifft das GELÄNDE — Cache muss frisch sein - _ensure_ghost() - _ensure_ghost_visible() - var label: String = main.object_label(oid) - if BauKatalog.ist_bau(oid): - main.call("_set_status", "%s: Maus über die Karte — die Vorschau rastet auf Zelle/Kante ein. Klick setzt, R dreht, Esc beendet. Klick auf die Wandseite ersetzt das Teil (z. B. Tür), Klick auf die Oberkante stapelt." % label) - main.call("_highlight_library", oid) - return - var hinweis := "" if not GlbMeshStore.fehlt(oid) \ - else " (Platzhalter — echte GLB fehlt für %s)" % oid - main.call("_set_status", "%s%s: führe die Maus über die Karte — Klick setzt es. Mausrad dreht vorher, ESC bricht ab (Rechte Maustaste = Flug)." % [label, hinweis]) - main.call("_highlight_library", oid) - - -func cancel_placement() -> void: - if _ghost != null and is_instance_valid(_ghost): - _ghost.visible = false - placing = false - place_oid = "" - _place_series = false - _ghost_active = false - _build_last = {} - _build_hit = {} - build_geschoss = -1 - main.call("_highlight_library", "") - main.call("_base_tool_status") - - -## U5 (t_5e3e97c9): Ein Setz-Klick beendet das Platzier-Werkzeug und wählt -## GENAU das neue Objekt aus (Baum-Markierung + Inspektor folgen über -## select_object). Ghost aus, Kachel-Hervorhebung im Assets-Panel aus -## (_highlight_library("")), das Objekt-Werkzeug bleibt das aktive Werkzeug. -## from_tree=true: der Baum wird bereits von _apply_selection_view markiert — -## kein zweites Auswahl-Ereignis (Auswahl-Stabilität, Karten-Test). -## Aufruf VOR der Klartext-Statusmeldung: die letzte Meldung gewinnt. -func finish_placement_and_select(new_index: int) -> void: - if _ghost != null and is_instance_valid(_ghost): - _ghost.visible = false - placing = false - place_oid = "" - _place_series = false - _ghost_active = false - main.call("_highlight_library", "") - select_object(new_index, true) - - -func _ensure_ghost() -> void: - if _ghost != null and is_instance_valid(_ghost): - return - # Struktur WIE der Viewport-Bauer (map_view_builder._build_objects): - # Root auf dem Fußpunkt, Kind-Mesh um half_height gehoben. So kann Ghost - # und platziertes Objekt nie auseinanderfallen (Karte t_4092e3a0). - _ghost = Node3D.new() - _ghost_mi = MeshInstance3D.new() - var mat := StandardMaterial3D.new() - mat.albedo_color = Color(0.6, 0.9, 1.0, 0.45) - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - mat.emission_enabled = true - mat.emission = Color(0.2, 0.5, 0.8) * 0.4 - _ghost_mi.material_override = mat - _ghost.add_child(_ghost_mi) - add_child(_ghost) - _ghost.visible = false - - -func _ghost_refresh_mesh() -> void: - var lib: Dictionary = main.manifest.get("objects", {}) - var entry: Dictionary = lib.get(place_oid, {}) - var col: Dictionary = entry.get("collision", {}) - # Echtes GLB vorziehen (Karte t_9b50b231) — die Vorschau zeigt das - # Modell, das landet, nicht nur die Kollisionsform. Ohne GLB: Platzhalter. - var mesh := GlbMeshStore.mesh_fuer(place_oid) - if mesh == null: - mesh = MeshShapes.make_placeholder(str(col.get("shape", "box")), col, 1.0) - _ghost_mi.mesh = mesh - # Gleicher Lift wie beim platzierten Objekt: Mesh-Unterseite = Fußpunkt. - _ghost_mi.position.y = MeshShapes.half_height(mesh) - - -func _ensure_ghost_visible() -> void: - _ghost_refresh_mesh() - _ghost_rotation_anwenden() - _ghost.visible = true - - -## Ghost-Rotation inkl. Kippen (Karte t_e166e656): Euler (X-Kippen, Y-Drehung, -## Z-Kippen) — derselbe Weg wie beim platzierten Objekt (rot_setzen schreibt -## genau diese drei Werte). -func _ghost_rotation_anwenden() -> void: - if _ghost == null or not is_instance_valid(_ghost): - return - if BauKatalog.ist_bau(place_oid): - _bau_ghost_neu() # Drehung ergibt sich aus Kante/Zelle + R - return - _ghost.rotation_degrees = Vector3(place_tilt_x, place_rot_deg, place_tilt_z) - - -## Raster-Snap (wenn in main angeschaltet ODER Strg gehalten wird — temporärer -## Snap-Zwang, Karte t_55257792): X/Z auf ganze Meter rasten — Objekte passen -## dann nebeneinander wie Bauklötze. Höhe bleibt Terrain. -func _apply_grid(pos: Vector3) -> Vector3: - if not (bool(main.get("grid_snap")) or _ctrl_held): - return pos - pos.x = ObjectOps.snap_coord(pos.x, true, GRID_M) - pos.z = ObjectOps.snap_coord(pos.z, true, GRID_M) - return pos - - -## Raster-Snap-Erzwingung fürs Platzieren: Schalter an ODER Strg gehalten. -func _placement_grid_enabled() -> bool: - return bool(main.get("grid_snap")) or _ctrl_held - - -func _ghost_update(viewport_pos: Vector2) -> void: - if BauKatalog.ist_bau(place_oid): - _bau_ghost_update(viewport_pos) - return - var p: Variant = _ground_point(viewport_pos) - if p == null: - _ghost_active = false - _ghost.visible = false - return - _ghost_active = true - # EIN Pfad für Ghost UND Platzierung (Karte t_4092e3a0): Fußpunkt = - # Terrain-Höhe am gerasteten Punkt. Der sichtbare Lift hängt am Kind-Mesh. - _ghost.position = ObjectOps.placement_foot( - main.doc, p as Vector3, _placement_grid_enabled(), _terrain_half(), true) - _ghost.visible = true - - -func _place_object(viewport_pos: Vector2, mb_shift_held := false) -> void: - if BauKatalog.ist_bau(place_oid): - _place_bau(viewport_pos) - return - var p: Variant = _ground_point(viewport_pos) - if p == null: - main.call("_set_status", "Da war kein Boden unter dem Mauszeiger — klicke IN die Karte (die grüne Fläche).", true) - return - var half := _terrain_half() - var foot: Vector3 = ObjectOps.placement_foot( - main.doc, p as Vector3, _placement_grid_enabled(), half, false) - if absf(foot.x) > half.x or absf(foot.z) > half.y: - main.call("_set_status", "Das wäre außerhalb der Map gelandet — klicke innerhalb der grünen Fläche.", true) - return - - # Poly-Budget prüfen, BEVOR etwas passiert (hilfreiche Meldung statt Fehler). - # Symmetrie-Modus (M3, t_34908425): der Zwilling kostet Dasselbe nochmal — - # außer das Objekt liegt auf der Mitte/Achse (wird nicht gedoppelt). - var sym_mode: int = _sym_mode() - var sym_center := SymmetryCore.map_center(main.doc) - var sym_factor := 1.0 - if sym_mode != SymmetryCore.Mode.OFF \ - and not SymmetryCore.maps_to_self(sym_mode, foot, sym_center): - sym_factor = 2.0 - var lib: Dictionary = main.manifest.get("objects", {}) - var entry: Dictionary = lib.get(place_oid, {}) - var poly := float(entry.get("poly", 0)) - var used := SvmapDocument.poly_usage(main.doc, main.manifest) - var budget := float(SvmapIO.MAX_TOTAL_POLY) - if used + poly * sym_factor > budget: - main.call("_set_status", - "Kein Platz mehr im Poly-Budget (%s von %s belegt) — lass ein Objekt weg oder drück Strg+Z, um etwas zurückzunehmen." - % [main._fmt_int(int(used)), main._fmt_int(int(budget))], true) - return - - var before: Dictionary = main.history.snapshot(["objects"]) - # EIN Pfad für Ghost UND Platzierung (Karte t_4092e3a0): derselbe Fußpunkt - # wie die Vorschau — Raster-Snap + Terrain-Höhe am gerasteten Punkt. - var pos_f := [foot.x, foot.y, foot.z] - var neues_obj := { - "id": place_oid, - "pos": pos_f, - "scale": 1.0, # Karte t_e166e656: Scale ist FIX — immer Originalgröße - "rot_y_deg": float(place_rot_deg), - } - # Karte t_e166e656: gekippt platziert → rot-Feld (Euler xyz) in die Datei. - if absf(place_tilt_x) > 0.0001 or absf(place_tilt_z) > 0.0001: - SvmapIO.rot_setzen(neues_obj, Vector3(place_tilt_x, float(place_rot_deg), place_tilt_z)) - (main.doc["objects"] as Array).append(neues_obj) - var new_index: int = (main.doc["objects"] as Array).size() - 1 - # Symmetrie (M3, t_34908425): der Zwilling wandert in denselben Undo-Schritt - # (ein Commit für Quelle + Zwilling) und bekommt dieselbe sym-Kennung. - var twin_index := -1 - var on_axis := false - if sym_mode != SymmetryCore.Mode.OFF: - var symres: Dictionary = ObjectOps.symmetry_place_twin(main.doc, new_index, sym_mode) - twin_index = int(symres.get("twin", -1)) - on_axis = bool(symres.get("on_axis", false)) - main.history.commit("%s platzieren" % main.object_label(place_oid), - before, main.history.snapshot(["objects"])) - main.call("_after_structure_change") - # U5 (t_5e3e97c9): Shift gehalten = Serienmodus (weiter setzen wie bisher, - # Ghost bleibt an) — sonst beendet das Werkzeug sich selbst und DAS NEUE - # Objekt ist ausgewählt (Baum markiert, Inspektor gefüllt). - if mb_shift_held: - _place_series = true - select_object(new_index, true) - if twin_index >= 0: - main.call("_set_status", "Serienmodus (Shift) — ESC beendet. %s platziert, Zwilling jeweils mitgesetzt; Strg+Z nimmt BEIDE je Schritt zurück. Weitere Klicks setzen erneut." % main.object_label(place_oid)) - else: - main.call("_set_status", "Serienmodus (Shift) — ESC beendet. Weitere Klicks setzen erneut; Strg+Z nimmt je Schritt zurück.") - else: - var placed_oid := place_oid # U5: finish leert place_oid — Label vorher sichern - finish_placement_and_select(new_index) - if twin_index >= 0: - main.call("_set_status", "%s gesetzt und ausgewählt — der Spiegel-Zwilling wurde mitgesetzt; Strg+Z nimmt BEIDE zurück. Ziehen verschiebt, R oder Mausrad dreht, Entf löscht." % main.object_label(placed_oid)) - elif on_axis: - main.call("_set_status", "%s gesetzt und ausgewählt — liegt auf der Symmetrie-Mitte und wird NICHT gedoppelt. Ziehen verschiebt, R oder Mausrad dreht, Entf löscht." % main.object_label(placed_oid)) - else: - main.call("_set_status", "%s gesetzt und ausgewählt. Ziehen verschiebt, R oder Mausrad dreht, Entf löscht, Strg+Z nimmt es zurück." % main.object_label(placed_oid)) - - -# ----------------------------------------------------- Bauen (bau_*) ----- - -## Strahl → Treffer auf Gelände ODER einem gesetzten Objekt (Bauteile müssen -## sich auf Wänden/Böden stapeln lassen). Rückgabe {punkt, obj (-1 = Gelände), dir} -## oder {} bei Leerlauf. -func _build_ray_hit(viewport_pos: Vector2) -> Dictionary: - var origin := camera.project_ray_origin(viewport_pos) - var dir := camera.project_ray_normal(viewport_pos) - var ground: Variant = _ground_point(viewport_pos) - if build_geschoss >= 0: - return _build_ray_geschoss(origin, dir, ground) - var best_t := INF - var out := {} - if ground != null: - best_t = (ground as Vector3).distance_to(origin) - out = {"punkt": ground, "obj": -1, "dir": dir} - for marker in view_builder.object_markers: - if marker == null or not is_instance_valid(marker): - continue - var center: Vector3 = marker.global_position + Vector3.UP * float(marker.get_meta("half_height", 1.0)) - var to_center := center - origin - var tca := to_center.dot(dir) - if tca <= 0.0: - continue - var radius := float(marker.get_meta("pick_radius", 1.0)) - if to_center.length_squared() - tca * tca > radius * radius: - continue - var mi := SelectionMath.marker_mesh(marker) - if mi == null or mi.mesh == null: - continue - var mt := SelectionMath.ray_mesh_distance(mi.global_transform, - SelectionMath.mesh_faces(mi.mesh), origin, dir) - if mt >= 0.0 and mt < best_t: - best_t = mt - out = {"punkt": origin + dir * mt, "obj": int(marker.get_meta("obj_index", -1)), "dir": dir} - return out - - -## Feste Geschosshöhe: der Strahl trifft die waagerechte Ebene dieses Geschosses, -## egal ob darunter Wand, Boden oder nur Gelände ist (Decke mitten im Raum). -func _build_ray_geschoss(origin: Vector3, dir: Vector3, ground: Variant) -> Dictionary: - var xz := Vector2(origin.x, origin.z) - if ground != null: - xz = Vector2((ground as Vector3).x, (ground as Vector3).z) - var y := _bau_geschoss_hoehe(xz) - if absf(dir.y) < 0.001: - return {} - var t := (y - origin.y) / dir.y - if t <= 0.0: - return {} - return {"punkt": origin + dir * t, "obj": -1, "dir": dir, "ebene": y} - - -func _bau_gelaende_fn() -> Callable: - return func(x: float, z: float) -> float: - if _res >= 2 and _heights.size() >= _res * _res: - return TerrainField.height_at(_heights, _res, _sx, _sz, x, z) - return float(main.doc.get("terrain", {}).get("min_height_m", 0.0)) - - -func _bau_geschoss_hoehe(xz: Vector2) -> float: - var basis := BuildSnap.geschoss_basis(BuildSnap.sammle_teile(main.doc), xz, _bau_gelaende_fn()) - return basis + float(build_geschoss) * BauKatalog.WAND_H - - -## Bild↑/Bild↓ bzw. Knöpfe im Bauen-Tab: Geschoss wechseln (0 → zurück auf Automatik). -func bau_geschoss_aendern(delta: int) -> void: - var neu := build_geschoss - if delta > 0: - neu = 1 if build_geschoss < 0 else mini(build_geschoss + 1, BAU_GESCHOSS_MAX) - elif build_geschoss >= 0: - neu = build_geschoss - 1 # 0 → -1 (Automatik) - build_geschoss = neu - _build_hint = "" - if placing and not _build_hit.is_empty(): - _bau_ghost_neu() - main.call("_set_status", bau_geschoss_text()) - main.call("_refresh_bau_info") - - -func bau_geschoss_text() -> String: - if build_geschoss < 0: - return "Höhe: automatisch (Gelände bzw. Oberkante des Teils darunter). Bild↑ wählt ein festes Geschoss — dann sitzen Böden/Decken überall im Raum." - return "Höhe: festes Geschoss %d (%s). Bild↑/Bild↓ wechselt, bis „automatisch“ erreicht ist." % [ - build_geschoss, "Erdgeschoss-Boden" if build_geschoss == 0 else "%d × %d m über dem Boden" % [build_geschoss, int(BauKatalog.WAND_H)]] - - -func _bau_ghost_update(viewport_pos: Vector2) -> void: - _build_hit = _build_ray_hit(viewport_pos) - if _build_hit.is_empty(): - _ghost_active = false - _ghost.visible = false - _build_last = {} - return - _bau_ghost_neu() - - -## Snap neu berechnen (Mausbewegung ODER R-Taste) und den Ghost setzen. -func _bau_snap() -> Dictionary: - if _build_hit.is_empty(): - return {} - return BuildSnap.berechne(place_oid, _build_hit["punkt"] as Vector3, place_rot_deg, - BuildSnap.sammle_teile(main.doc), _bau_gelaende_fn(), - int(_build_hit.get("obj", -1)) >= 0, _build_hit.get("dir", Vector3.ZERO) as Vector3, - float(_build_hit.get("ebene", NAN))) - - -func _bau_ghost_neu() -> void: - _build_last = _bau_snap() - if _build_last.is_empty(): - return - var pos: Vector3 = _build_last["pos"] - var half := _terrain_half() - var innerhalb := absf(pos.x) <= half.x and absf(pos.z) <= half.y - _ghost.position = pos - _ghost.rotation_degrees = Vector3(0.0, float(_build_last["rot"]), 0.0) - _ghost_active = true - _ghost.visible = true - var mat := _ghost_mi.material_override as StandardMaterial3D - var hinweis := "" - if not bool(_build_last["ok"]) or not innerhalb: - mat.albedo_color = Color(1.0, 0.25, 0.2, 0.5) - hinweis = str(_build_last["grund"]) if not bool(_build_last["ok"]) else "Außerhalb der Map." - elif int(_build_last["ersetze"]) >= 0: - mat.albedo_color = Color(1.0, 0.7, 0.2, 0.55) - hinweis = "Klick ersetzt das vorhandene Teil durch %s (Strg+Z holt es zurück)." % main.object_label(place_oid) - else: - mat.albedo_color = Color(0.6, 0.9, 1.0, 0.45) - if hinweis != _build_hint: - _build_hint = hinweis - if not hinweis.is_empty(): - main.call("_set_status", hinweis) - - -## Klick im Bauen-Modus: Teil setzen/ersetzen — ein Undo-Schritt, Teil landet im -## laufenden Gebäude (Gruppe), Serie bleibt aktiv (Esc beendet). -func _place_bau(viewport_pos: Vector2) -> void: - _build_hit = _build_ray_hit(viewport_pos) - if _build_hit.is_empty(): - main.call("_set_status", "Da war nichts unter dem Mauszeiger — klicke IN die Karte (die grüne Fläche).", true) - return - var snap := _bau_snap() - if snap.is_empty(): - return - var pos: Vector3 = snap["pos"] - var half := _terrain_half() - if absf(pos.x) > half.x or absf(pos.z) > half.y: - main.call("_set_status", "Das wäre außerhalb der Map gelandet — klicke innerhalb der grünen Fläche.", true) - return - if not bool(snap["ok"]): - main.call("_set_status", str(snap["grund"]), true) - return - var objects: Array = main.doc["objects"] - var ersetzt := int(snap["ersetze"]) >= 0 - var lib: Dictionary = main.manifest.get("objects", {}) - var poly := float((lib.get(place_oid, {}) as Dictionary).get("poly", 0)) - var sym_mode: int = _sym_mode() - var sym_factor := 1.0 - if sym_mode != SymmetryCore.Mode.OFF and not SymmetryCore.maps_to_self( - sym_mode, pos, SymmetryCore.map_center(main.doc)): - sym_factor = 2.0 - if not ersetzt and objects.size() + int(sym_factor) > SvmapIO.MAX_OBJECTS: - main.call("_set_status", "Limit erreicht: In eine Map passen maximal %d Objekte — das Löschen von Objekten macht wieder Platz." % SvmapIO.MAX_OBJECTS, true) - return - var used := SvmapDocument.poly_usage(main.doc, main.manifest) - var budget := float(SvmapIO.MAX_TOTAL_POLY) - if used + poly * sym_factor > budget: - main.call("_set_status", - "Kein Platz mehr im Poly-Budget (%s von %s belegt) — lass ein Teil weg oder drück Strg+Z." - % [main._fmt_int(int(used)), main._fmt_int(int(budget))], true) - return - var keys := ["objects", "group_names"] - var before: Dictionary = main.history.snapshot(keys) - if not before.has("group_names"): - before["group_names"] = null # Undo entfernt die neu angelegten Gebäude-Namen wieder - var label: String = main.object_label(place_oid) - var gid := _bau_gruppe() - var spiegel := -1 - if sym_mode != SymmetryCore.Mode.OFF and sym_factor > 1.0: - spiegel = _bau_spiegel_gruppe(gid) - BauOps.setze_teil(main.doc, place_oid, snap, gid, sym_mode, spiegel) - main.history.commit("%s bauen" % label if not ersetzt else "%s einsetzen" % label, - before, main.history.snapshot(keys)) - main.call("_after_structure_change") - _build_hit = _build_ray_hit(viewport_pos) - _bau_ghost_neu() - main.call("_set_status", "%s %s (%s, %d Teile). Weiter klicken — R dreht, Esc beendet, Strg+Z nimmt das letzte Teil zurück." % [ - label, "eingesetzt" if ersetzt else "gesetzt", GroupState.display_name(main.doc, gid), - GroupOps.members_of(main.doc, gid).size()]) - main.call("_refresh_bau_info") - - -## Laufendes Gebäude (Gruppe): bestehende Gruppe weiterführen oder neue anlegen -## und benennen. Rückgabe: Gruppen-ID. -func _bau_gruppe() -> int: - if build_group_id >= 0 and not GroupOps.members_of(main.doc, build_group_id).is_empty(): - return build_group_id - build_group_id = BauOps.gruppe_neu(main.doc) - return build_group_id - - -## Gruppe für den Spiegel-Zwilling des laufenden Gebäudes (1 Gebäude ↔ 1 Spiegel). -var _bau_spiegel: Dictionary = {} # laufende ID → Spiegel-ID - -func _bau_spiegel_gruppe(gid: int) -> int: - var sp := int(_bau_spiegel.get(gid, -1)) - if sp >= 0 and not GroupOps.members_of(main.doc, sp).is_empty(): - return sp - sp = maxi(GroupOps.next_group_id(main.doc), gid + 1) - GroupState.set_group_name(main.doc, sp, "%s (Spiegel)" % GroupState.display_name(main.doc, gid)) - _bau_spiegel[gid] = sp - return sp - - -## Nächstes Teil beginnt ein NEUES Gebäude (Button „Neues Gebäude“). -func neues_gebaeude() -> void: - build_group_id = -1 - _bau_spiegel.clear() - - -## Demo-Hook: Ghost an einem Punkt parken (Screenshots ohne Maus). -func demo_park_bau(punkt: Vector3) -> void: - _build_hit = {"punkt": punkt, "obj": -1, "dir": Vector3.ZERO} - _bau_ghost_neu() - - -# --------------------------------------------------------------- Auswahl ---- - -## Einzel-Auswahl (Klick ins Objekt / Klick im Baum): ersetzt die Auswahl. -func select_object(idx: int, from_tree := false) -> void: - selected_indices = [idx] if idx >= 0 else [] - selected_index = idx - _apply_selection_view() - if not from_tree: - main.call("_mark_tree_selection", idx) - main.call("_selection_status", idx) - - -## Mehrere auf einmal (Rahmen-Ausziehen, Demo) — Reihenfolge bleibt erhalten. -func select_many(indices: Array, silent := false) -> void: - var objects: Array = main.doc.get("objects", []) - selected_indices = [] - for i in indices: - if i is int and i >= 0 and i < objects.size(): - selected_indices.append(i) - selected_index = selected_indices.back() if not selected_indices.is_empty() else -1 - _apply_selection_view() - if not silent: - main.call("_selection_status", selected_index) - - -## Umschalt+Klick: Objekt zur Auswahl HINZUFÜGEN (oder wieder rausnehmen). -func select_toggle(idx: int) -> void: - var objects: Array = main.doc.get("objects", []) - if idx < 0 or idx >= objects.size(): - return - var label: String = main.object_label(str(objects[idx].get("id", ""))) - if selected_indices.has(idx): - selected_indices.erase(idx) - if selected_index == idx: - selected_index = selected_indices.back() if not selected_indices.is_empty() else -1 - main.call("_set_status", "%s aus der Auswahl genommen — noch %d Objekte markiert. Umschalt-/Strg+Klick fügt wieder hinzu." % [label, selected_indices.size()]) - else: - selected_indices.append(idx) - selected_index = idx - main.call("_set_status", "%s zur Auswahl dazugeholt — jetzt %d Objekte. Mehr umschalten (Umschalt-/Strg+Klick), Rahmen aufziehen oder Strg+G zum Gruppieren." % [label, selected_indices.size()]) - _apply_selection_view() - main.call("_sync_selection_panel") - - -func clear_selection(silent := false) -> void: - if selected_index != -1 or not selected_indices.is_empty(): - selected_indices = [] - selected_index = -1 - view_builder.call("set_selected_multi", []) - if not silent: - main.call("_set_status", "Auswahl aufgehoben.") - main.call("_sync_selection_panel") - - -## Auswahl-Anzeige (Viewport-Färbung + Baum + Panel) aus dem aktuellen Stand. -func _apply_selection_view() -> void: - view_builder.call("set_selected_multi", selected_indices) - # Baum GANZ synchron (Karte t_c46d31c2): auch Abwählen per Strg+Klick im - # Viewport entfernt die Baum-Markierung wieder. - main.call("_mark_tree_selection_multi", selected_indices) - if selected_index >= 0: - main.call("_mark_tree_selection", selected_index) - - -## Ausgewählte Objekte zu EINER Gruppe machen (main-Button/Strg+G). -func group_selection() -> void: - var objects: Array = main.doc.get("objects", []) - var valid: Array = [] - for i in selected_indices: - if i is int and i >= 0 and i < objects.size(): - valid.append(i) - if valid.size() < 2: - main.call("_set_status", "Eine Gruppe braucht mindestens 2 Objekte — markiere zuerst mehrere (Umschalt+Klick oder Rahmen aufziehen).", true) - return - var before: Dictionary = main.history.snapshot(["objects"]) - var gid := GroupOps.group(main.doc, valid) - main.history.commit("Auswahl gruppieren (%d Objekte → Gruppe %d)" % [valid.size(), gid + 1], - before, main.history.snapshot(["objects"])) - _mark_dirty() - main.call("_refresh_history_buttons") - _apply_selection_view() - main.call("_sync_selection_panel") - main.call("_set_status", "Gruppe %d gebaut: %d Objekte ziehen und drehen jetzt GEMEINSAM. „Gruppe lösen“ (Strg+Umschalt+G) macht es rückgängig — die Objekte bleiben, nur die Bindung löst sich." % [gid + 1, valid.size()]) - - -## Gruppe(n) der Auswahl komplett lösen (main-Button/Strg+Umschalt+G). -func ungroup_selection() -> void: - var groups: Array = GroupOps.groups_of(main.doc, selected_indices) - if groups.is_empty(): - main.call("_set_status", "In der Auswahl steckt keine Gruppe — markiere zuerst ein Objekt aus einer Gruppe.", true) - return - var before: Dictionary = main.history.snapshot(["objects"]) - var freed := GroupOps.ungroup(main.doc, selected_indices) - main.history.commit("Gruppe gelöst (%d Objekte)" % freed, - before, main.history.snapshot(["objects"])) - _mark_dirty() - main.call("_refresh_history_buttons") - _apply_selection_view() - main.call("_sync_selection_panel") - main.call("_set_status", "Gruppe gelöst: %d Objekte sind wieder einzeln verschiebbar — Strg+Z baut die Gruppe wieder zusammen." % freed) - - -# ---------------------------------------------------- Drehen / Löschen ------ - -## Auswahl drehen (R / Mausrad / Button): bei mehreren Objekten oder einer -## Gruppe rotiert ALLES gemeinsam um den Gruppen-Mittelpunkt. Mausrad-Ticks -## derselben Auswahl laufen zu EINEM Undo-Schritt zusammen (merge_tag). -func rotate_selected(delta_deg: float, merge_suffix: String = "") -> void: - if selected_index < 0 or selected_indices.is_empty(): - return - var objects: Array = main.doc.get("objects", []) - if selected_index >= objects.size(): - return - var members := selected_indices.duplicate() - # Einzelnes Objekt, das in einer Gruppe steckt → die GANZE Gruppe drehen - # (Sly-Erwartung: die Gruppe dreht gemeinsam) und sichtbar markieren. - if members.size() == 1: - var gid := GroupOps.group_id(objects[members[0]]) - if gid != GroupOps.UNGROUPED: - members = GroupOps.members_of(main.doc, gid) - select_many(members, true) - main.call("_sync_selection_panel") - var before: Dictionary = main.history.snapshot(["objects"]) - GroupOps.rotate_members(main.doc, members, delta_deg) - _sync_members_to_markers(members) - # Symmetrie (M3, t_34908425): Zwillinge der gedrehten Auswahl auf den exakten - # Spiegel setzen (Punkt: +180°-Basis, Achse: Vorzeichen) — IM SELBEN Commit. - var twins: Array = ObjectOps.symmetry_sync_pairs( - main.doc, members, _sym_mode(), selected_index) - _sync_members_to_markers(twins) - var tag := "rotmulti:%s%s" % [str(members), merge_suffix] - main.history.commit("Auswahl gedreht (%d Objekte)" % members.size(), - before, main.history.snapshot(["objects"]), tag) - _mark_dirty() - main.call("_refresh_history_buttons") - main.call("_refresh_stats") - main.call("_sync_selection_panel") - - -## Auswahl KIPPEN (Karte t_e166e656 — Sly: „nicht nur rotieren, sondern auch -## kippen in sämtliche Achsen“). axis_x = Kippen um die X-Achse (vor/zurück -## neigen), sonst um die Z-Achse (links/rechts neigen). Ein Einzelobjekt in -## einer Gruppe kippt die GANZE Gruppe (wie beim Drehen), Mehrfachauswahl -## kippt jedes Objekt um denselben Betrag, Symmetrie-Zwillinge laufen im -## SELBEN Commit mit. rot/rot_y_deg bleiben über SvmapIO.rot_setzen synchron. -func tilt_selected(axis_x: bool, delta_deg: float, merge_suffix: String = "") -> void: - if selected_index < 0 or selected_indices.is_empty(): - return - var objects: Array = main.doc.get("objects", []) - if selected_index >= objects.size(): - return - var members := selected_indices.duplicate() - if members.size() == 1: - var gid := GroupOps.group_id(objects[members[0]]) - if gid != GroupOps.UNGROUPED: - members = GroupOps.members_of(main.doc, gid) - select_many(members, true) - main.call("_sync_selection_panel") - var before: Dictionary = main.history.snapshot(["objects"]) - var axis := "X" if axis_x else "Z" - for i in members: - var obj: Dictionary = objects[i] - var euler := SvmapIO.objekt_rotation(obj) - var neu := Vector3(euler.x, euler.y, euler.z) - if axis_x: - neu.x = fposmod(euler.x + delta_deg + 3600.0, 360.0) - else: - neu.z = fposmod(euler.z + delta_deg + 3600.0, 360.0) - SvmapIO.rot_setzen(obj, neu) - _sync_members_to_markers(members) - var twins: Array = ObjectOps.symmetry_sync_pairs( - main.doc, members, _sym_mode(), selected_index) - _sync_members_to_markers(twins) - var tag := ("tilt:%d" % selected_index if members.size() == 1 \ - else "tiltmulti:%s" % str(members)) + merge_suffix - main.history.commit("Auswahl gekippt (%s, %d Objekte)" % [axis, members.size()], - before, main.history.snapshot(["objects"]), tag) - _mark_dirty() - main.call("_refresh_history_buttons") - main.call("_refresh_stats") - main.call("_sync_selection_panel") - main.call("_set_status", "Auswahl um %s%s gekippt — Inspektor zeigt die Werte; Strg+Z nimmt den Schritt zurück." % [ - ("+%.0f°" % delta_deg) if delta_deg > 0.0 else ("%.0f°" % delta_deg), axis]) - - -## Nach Doc-Änderung die betroffenen Marker positionieren/drehen (kein Rebuild). -func _sync_members_to_markers(members: Array) -> void: - var objects: Array = main.doc.get("objects", []) - for i in members: - if i >= view_builder.object_markers.size(): - continue - var marker: Node3D = view_builder.object_markers[i] - if marker == null or not is_instance_valid(marker): - continue - var pos: Array = (objects[i] as Dictionary).get("pos", [0.0, 0.0, 0.0]) - marker.position = Vector3(float(pos[0]), float(pos[1]), float(pos[2])) - # Karte t_e166e656: volle 3-Achsen-Rotation (rot-Feld oder Fallback rot_y_deg). - marker.rotation_degrees = SvmapIO.objekt_rotation(objects[i] as Dictionary) - - -func delete_selected() -> void: - if selected_indices.is_empty() or selected_index < 0: - main.call("_set_status", "Nichts ausgewählt — klicke zuerst ein Objekt an, das gelöscht werden soll.", true) - return - var objects: Array = main.doc.get("objects", []) - var doomed: Array = [] - for i in selected_indices: - if i is int and i >= 0 and i < objects.size(): - doomed.append(i) - if doomed.is_empty(): - clear_selection(true) - return - # Symmetrie (M3, t_34908425): die Partner der Auswahl löschen sich MIT — - # ein Paar lebt oder stirbt zusammen, IM SELBEN Undo-Schritt. - doomed = ObjectOps.symmetry_expand_delete(main.doc, doomed, _sym_mode()) - var before: Dictionary = main.history.snapshot(["objects", "group_names"]) - if not before.has("group_names"): - before["group_names"] = null - var label: String - if doomed.size() == 1: - label = "%s löschen" % main.object_label(str(objects[doomed[0]].get("id", ""))) - else: - label = "%d Objekte löschen" % doomed.size() - # Rückwärts löschen, damit die Indizes währenddessen stimmen. - doomed.sort() - doomed.reverse() - for i in doomed: - objects.remove_at(i) - GroupState.prune_orphans(main.doc) # Gebäude ohne Teile verlieren ihren Namen - main.history.commit(label, before, main.history.snapshot(["objects", "group_names"])) - clear_selection(true) - main.call("_after_structure_change") - main.call("_set_status", "%s ist erledigt — Strg+Z (Rückgängig) holt %s zurück." % [ - label, "alles" if doomed.size() > 1 else "es"]) - - -# ------------------------------------------ Duplizieren/Höhe/Spiegeln ------ -## (Karte t_7567a06f — alle drei auch bei Sly bedienbar: Button rechts + -## Tastenkürzel, alles über ActionHistory, Klartext-Status-Hilfe.) - -## Strg+D / Button "Duplizieren" (Karte t_c46d31c2): JEDE Kopie rastet +2 m in -## X versetzt ein (Füßpunkt-Höhe unverändert, mit Raster-Snap eingerastet, wenn -## an) — bei Mehrfachauswahl werden ALLE Objekte kopiert, EIN Undo-Schritt für -## alle Kopien, die Kopien sind direkt als neue Auswahl angewählt. Poly-Budget -## und Objekt-Limit werden VOR dem Kopieren gesammelt geprüft. -func duplicate_selected() -> void: - var objects: Array = main.doc.get("objects", []) - var sources: Array = [] - for i in selected_indices: - if i is int and i >= 0 and i < objects.size(): - sources.append(i) - if sources.is_empty(): - main.call("_set_status", "Nichts ausgewählt — klicke zuerst ein Objekt an, das du kopieren willst.", true) - return - if objects.size() + sources.size() > SvmapIO.MAX_OBJECTS \ - and _sym_mode() == SymmetryCore.Mode.OFF: - main.call("_set_status", "Limit erreicht: In eine Map passen maximal %d Objekte — das Löschen von Objekten macht wieder Platz." % SvmapIO.MAX_OBJECTS, true) - return - var lib: Dictionary = main.manifest.get("objects", {}) - var sym_mode: int = _sym_mode() - var sym_center := SymmetryCore.map_center(main.doc) - var twins_planned := 0 - var poly_sum := 0.0 - for i in sources: - var src_obj: Dictionary = objects[i] - var scl := float(src_obj.get("scale", 1.0)) - var entry: Dictionary = lib.get(str(src_obj.get("id", "")), {}) - poly_sum += float(entry.get("poly", 0)) * scl * scl - # Symmetrie (M3, t_34908425): JEDE Kopie bekommt einen Zwilling (außer - # auf der Mitte/Achse) — Budget und Objekt-Limit VORAB mitrechnen. - if sym_mode != SymmetryCore.Mode.OFF: - var spos: Array = src_obj.get("pos", [0.0, 0.0, 0.0]) - if (spos as Array).size() == 3 and not SymmetryCore.maps_to_self( - sym_mode, Vector3(float(spos[0]), float(spos[1]), float(spos[2])), sym_center): - twins_planned += 1 - poly_sum += float(entry.get("poly", 0)) * scl * scl - if twins_planned > 0 and objects.size() + sources.size() + twins_planned > SvmapIO.MAX_OBJECTS: - main.call("_set_status", "Limit erreicht: In eine Map passen maximal %d Objekte — mit Symmetrie-Zwilllingen bräuchte es %d. Das Löschen von Objekten macht wieder Platz." % [SvmapIO.MAX_OBJECTS, objects.size() + sources.size() + twins_planned], true) - return - var used := SvmapDocument.poly_usage(main.doc, main.manifest) - var budget := float(SvmapIO.MAX_TOTAL_POLY) - if used + poly_sum > budget: - main.call("_set_status", "Für %s fehlt das Poly-Budget (%s von %s belegt) — Strg+Z nimmt etwas zurück, oder lösche ein anderes Objekt." % [ - "die Kopien" if sources.size() > 1 else "eine Kopie", - main._fmt_int(int(used)), main._fmt_int(int(budget))], true) - return - var before: Dictionary = main.history.snapshot(["objects", "group_names"]) - if not before.has("group_names"): - before["group_names"] = null # Undo entfernt die Namen der Kopie-Gruppen wieder - # Gebäude (Bauteile): Kopie rückt um die Gebäudebreite weg statt 2 m — sonst - # läge sie halb im Original. - var offset_x := ObjectOps.DUPLICATE_OFFSET_M.x - var bau_min := INF - var bau_max := -INF - for i in sources: - var so: Dictionary = objects[i] - if BauKatalog.ist_bau(str(so.get("id", ""))): - var spx := float((so.get("pos", [0.0, 0.0, 0.0]) as Array)[0]) - bau_min = minf(bau_min, spx) - bau_max = maxf(bau_max, spx) - if bau_min < INF: - offset_x = maxf(offset_x, ceilf((bau_max - bau_min + 4.0) / 2.0) * 2.0) - var new_indices: Array = ObjectOps.duplicate_objects(main.doc, sources, bool(main.get("grid_snap")), offset_x) - if new_indices.is_empty(): - clear_selection(true) - return - # Symmetrie (M3, t_34908425): jede Kopie bekommt ihren Zwilling (exakter - # Spiegel der KOPIE, neue sym-Kennung) — im selben Commit wie die Kopien. - var sym_twins: Array = [] - if sym_mode != SymmetryCore.Mode.OFF: - for c in new_indices: - if c is int: - var sres: Dictionary = ObjectOps.symmetry_place_twin(main.doc, c, sym_mode) - if int(sres.get("twin", -1)) >= 0: - sym_twins.append(int(sres["twin"])) - var label: String - if new_indices.size() == 1: - label = "%s duplizieren" % main.object_label(str((objects[sources[0]] as Dictionary).get("id", ""))) - else: - label = "%d Objekte duplizieren" % new_indices.size() - main.history.commit(label, before, main.history.snapshot(["objects", "group_names"])) - main.call("_after_structure_change") - # Kopien direkt anwählen — Sly kann sie gleich weiterziehen. Die frischen - # Zwillinge wandern mit in die Auswahl (beide Seiten sichtbar markiert). - var selected_new: Array = new_indices.duplicate() - selected_new.append_array(sym_twins) - select_many(selected_new) - if sym_twins.is_empty(): - main.call("_set_status", "%s: die Kopie(n) liegen +2 m versetzt und sind direkt angewählt — Ziehen verschiebt, Entf löscht, Strg+Z nimmt ALLE Kopien auf einmal zurück." % label) - else: - main.call("_set_status", "%s: %d Kopie(n) + %d Zwilling(e) sind direkt angewählt — jede Kopie bildet mit ihrem Zwilling ein neues Paar. Strg+Z nimmt ALLE auf einmal zurück." % [label, new_indices.size(), sym_twins.size()]) - - -## ▲/▼ / Strg+Bild↑/↓: AUSWAHL in 0,25-m-Schritten anheben/absenken -## (Karte t_55257792: die GANZE Auswahl, wie Entf/Strg+D auch). -## Mehrere Klicks in Serie = EIN Undo-Schritt (Merge-Tag, wie beim Drehen). -## Absenken stoppt am Terrain (nichts wird begraben), Anheben an der -## Match-Grenze (bounds.max) — Regeln in ObjectOps.lift_object. -func lift_selected(delta_m: float) -> void: - if selected_index < 0: - main.call("_set_status", "Nichts ausgewählt — klicke zuerst ein Objekt an, das du anheben oder absenken willst.", true) - return - if placing: - return - var objects: Array = main.doc.get("objects", []) - if selected_index >= objects.size(): - clear_selection(true) - return - var members := _lift_members() - var before: Dictionary = main.history.snapshot(["objects"]) - var applied_sum := 0.0 - for i in members: - applied_sum += ObjectOps.lift_object(main.doc, i, delta_m) - if absf(applied_sum) < 0.0001: - # Nichts passiert (Snapshot verwerfen): hilfsbereit erklären, WO die Grenze ist. - var ground: String - if delta_m > 0.0: - ground = "Die Match-Höhe ist erreicht — höher passt der Server nicht mehr." - else: - ground = "Die untere Match-Grenze ist erreicht — tiefer passt der Server nicht mehr (Versenken im Boden ist erlaubt, Karte t_e166e656)." - main.call("_set_status", ground) - return - var after: Dictionary = main.history.snapshot(["objects"]) - var tag := "lift:%d" % selected_index if members.size() == 1 \ - else "liftmulti:%s" % str(members) - main.history.commit(_lift_label(members, delta_m, applied_sum), - before, after, tag) - for i in members: - if i >= view_builder.object_markers.size(): - continue - var marker: Node3D = view_builder.object_markers[i] - if marker != null and is_instance_valid(marker): - marker.position.y = float((objects[i]["pos"] as Array)[1]) - main.dirty = true - main.call("_refresh_file_label") - main.call("_refresh_stats") - main.call("_refresh_history_buttons") - main.call("_sync_selection_panel") - # Karte t_e166e656: Versenk-Tiefe sichtbar machen (Stein halb im Boden). - var sel_pos: Array = (objects[selected_index]["pos"] as Array) - var boden := SvmapDocument.terrain_height_at(main.doc, float(sel_pos[0]), float(sel_pos[2])) - var tiefe := boden - float(sel_pos[1]) - var versenk := "" - if tiefe > 0.01: - versenk = " (%.2f m versenkt)" % tiefe - main.call("_set_status", "%s auf %.2f m%s — mehrmals drücken stapelt weiter; Strg+Z nimmt alle Stufen auf einmal zurück." % [ - _lift_label(members, delta_m, applied_sum), float(sel_pos[1]), versenk]) - - -## Heben/Absenken wirkt auf die GANZE Auswahl (Karte t_55257792) — ein einzelnes -## Objekt, das in einer Gruppe steckt, zieht die ganze Gruppe mit (wie Drehen). -func _lift_members() -> Array: - var members := selected_indices.duplicate() - if members.size() == 1: - var objects: Array = main.doc.get("objects", []) - var gid := GroupOps.group_id(objects[members[0]]) - if gid != GroupOps.UNGROUPED: - members = GroupOps.members_of(main.doc, gid) - select_many(members, true) - main.call("_sync_selection_panel") - return members - - -func _lift_label(members: Array, delta_m: float, applied_sum: float) -> String: - var dir := "angehoben" if delta_m > 0.0 else "abgesenkt" - if members.size() == 1: - return "Objekt %s (%s)" % [dir, "%.2f m" % applied_sum] - return "%d Objekte %s (%.2f m)" % [members.size(), dir, applied_sum] - - -## Strg+Bild↑ (Karte t_55257792): die AUSWAHL direkt auf das Terrain/Boden -## absetzen (Godot "Snap Object to Floor"-Äquivalent fürs Fußpunkt-Modell). -## EIN Undo-Schritt; steht alles schon am Boden → Meldung statt leerem Commit. -func snap_selection_to_floor() -> void: - if selected_indices.is_empty() or selected_index < 0: - main.call("_set_status", "Nichts ausgewählt — Strg+Bild↑ setzt die Auswahl auf den Boden. Klicke zuerst ein Objekt an.", true) - return - if placing: - return - var members := _lift_members() - var before: Dictionary = main.history.snapshot(["objects"]) - var changed := ObjectOps.snap_selection_to_floor(main.doc, members) - if changed == 0: - main.call("_set_status", "Steht schon alles auf dem Boden — nichts zu setzen.") - return - main.history.commit("Auswahl auf Boden gesetzt (%d Objekte)" % changed, - before, main.history.snapshot(["objects"])) - for i in members: - if i >= view_builder.object_markers.size(): - continue - var marker: Node3D = view_builder.object_markers[i] - if marker != null and is_instance_valid(marker): - var pos: Array = ((main.doc.get("objects", []) as Array)[i] as Dictionary).get("pos", [0.0, 0.0, 0.0]) - marker.position = Vector3(float(pos[0]), float(pos[1]), float(pos[2])) - _mark_dirty() - main.call("_refresh_stats") - main.call("_refresh_history_buttons") - main.call("_sync_selection_panel") - main.call("_set_status", "%d Objekt(e) auf den Boden gesetzt — Strg+Z nimmt es zurück." % changed) - - -## Pfeiltasten (Karte t_55257792): Auswahl im 2-m-Raster verschieben — EINE -## Zelle pro Tastendruck, Richtung = Kamera-Ausrichtung nächste Weltachse -## (MoveMath). Fußpunkt bleibt am Raster, Höhe wandert mit (t_7567a06f). -## EIN Undo-Schritt pro Tastendruck. -func nudge_selection(delta: Vector3) -> void: - if selected_indices.is_empty() or selected_index < 0: - main.call("_set_status", "Nichts ausgewählt — Pfeiltasten verschieben die Auswahl im 2-m-Raster. Klicke zuerst ein Objekt an.") - return - if placing: - return - var members := selected_indices.duplicate() - var objects: Array = main.doc.get("objects", []) - if members.size() == 1: - var gid := GroupOps.group_id(objects[members[0]]) - if gid != GroupOps.UNGROUPED: - members = GroupOps.members_of(main.doc, gid) - var before: Dictionary = main.history.snapshot(["objects"]) - var changed := ObjectOps.nudge_objects(main.doc, members, delta) - if changed == 0: - return # am Map-Rand geklemmt — Snapshot verwerfen, kein Commit - _sync_members_to_markers(members) - # Symmetrie (M3, t_34908425): Zwillinge mitführen — exakter Spiegel der - # verschobenen Quelle, im selben Commit (Pfeiltasten = 1 Undo-Schritt). - var twins: Array = ObjectOps.symmetry_sync_pairs( - main.doc, members, _sym_mode()) - _sync_members_to_markers(twins) - var desc := "Objekt verschoben (Pfeiltaste)" if members.size() == 1 \ - else "%d Objekte verschoben (Pfeiltasten)" % members.size() - main.history.commit(desc, before, main.history.snapshot(["objects"])) - _mark_dirty() - main.call("_refresh_history_buttons") - main.call("_refresh_stats") - main.call("_sync_selection_panel") - main.call("_set_status", "%s — 2 m pro Tastendruck. Greifen (G) setzt frei, Strg+Bild↑ setzt auf den Boden." % desc) - - -# ------------------------------------------------------------ Greifen (G) ---- -## Blender-Semantik (Karte t_55257792): G hängt die Auswahl an die Maus, -## Linksklick setzt die neue Position (EIN Undo-Schritt, Raster-Snap wie -## eingestellt bzw. Strg-Zwang), Esc bricht ab und setzt die EXAKTEN alten -## Positionen zurück. Die Auswahl wandert GEMEINSAM (Gruppe/Mehrfachauswahl), -## relative Anordnung bleibt exakt erhalten, Terrain-Abstand je Objekt bleibt. - -## Greifen starten. false = nichts ausgewählt (Meldung steht dann). -func grab_begin() -> bool: - if _grabbing: - return true - if placing: - return false - var objects: Array = main.doc.get("objects", []) - var members := selected_indices.duplicate() - if members.size() == 1: - var gid := GroupOps.group_id(objects[members[0]]) - if gid != GroupOps.UNGROUPED: - members = GroupOps.members_of(main.doc, gid) - select_many(members, true) - main.call("_sync_selection_panel") - if members.is_empty() or selected_index < 0: - main.call("_set_status", "Nichts ausgewählt — G greift die Auswahl, damit du sie mit der Maus frei setzen kannst. Klicke zuerst ein Objekt an.") - return false - _grab_members = members - _grab_primary = selected_index - _grab_originals = {} - _grab_lifts = {} - for i in members: - var pos: Array = (objects[i] as Dictionary).get("pos", [0.0, 0.0, 0.0]) - _grab_originals[i] = [float(pos[0]), float(pos[1]), float(pos[2])] - _grab_lifts[i] = float(pos[1]) - SvmapDocument.terrain_height_at( - main.doc, float(pos[0]), float(pos[2])) - # Symmetrie (M3, t_34908425): Zwillinge der Greif-Menge merken — sie ziehen - # live mit (exakter Spiegel) und Esc setzt sie EXAKT zurück. - _grab_twin_map = {} - _grab_twin_originals = {} - if _sym_mode() != SymmetryCore.Mode.OFF: - for i in members: - if not (i is int) or i < 0 or i >= objects.size() or not (objects[i] is Dictionary): - continue - var sym_key := SymmetryCore.sym_of(objects[i] as Dictionary) - if sym_key.is_empty(): - continue - var t := SymmetryCore.find_partner_index(objects, sym_key, i) - if t < 0: - continue - _grab_twin_map[i] = t - if not members.has(t) and not _grab_twin_originals.has(t): - var tpos: Array = (objects[t] as Dictionary).get("pos", [0.0, 0.0, 0.0]) - if (tpos as Array).size() == 3: - _grab_twin_originals[t] = [float(tpos[0]), float(tpos[1]), float(tpos[2])] - _grabbing = true - _grab_before = main.history.snapshot(["objects"]) - main.call("_set_status", "GREIFEN an: die Auswahl hängt an der Maus — Linksklick setzt sie neu (mit Raster-Snap), Esc bricht ab und setzt zurück.") - return true - - -## Auswahl live zur Cursor-Bodenposition ziehen (Maus-Bewegung ODER Demo-Hook -## mit Weltpunkt). Der Primär-Anker geht EXAKT zum Punkt (rastet, wenn Snap -## an bzw. Strg), die Mitglieder wandern mit demselben Delta mit. -func grab_move(hit: Vector3) -> void: - if not _grabbing: - return - var target := _apply_grid(hit) - var half := _terrain_half() - var primary_pos: Array = _grab_originals[_grab_primary] - var delta := Vector3(target.x - float(primary_pos[0]), 0.0, - target.z - float(primary_pos[2])) - var objects: Array = main.doc.get("objects", []) - for i in _grab_members: - var orig: Array = _grab_originals[i] - var nx := clampf(float(orig[0]) + delta.x, -half.x, half.x) - var nz := clampf(float(orig[2]) + delta.z, -half.y, half.y) - var ny := SvmapDocument.terrain_height_at(main.doc, nx, nz) + float(_grab_lifts[i]) - (objects[i] as Dictionary)["pos"] = [nx, ny, nz] - if i < view_builder.object_markers.size(): - var marker: Node3D = view_builder.object_markers[i] - if marker != null and is_instance_valid(marker): - marker.position = Vector3(nx, ny, nz) - # Symmetrie (M3, t_34908425): Zwillinge live mitziehen — doc + Marker, - # exakter Spiegel der gegriffenen Quelle. - _sym_grab_twin_move() - - -## Linksklick im Greifen: Positionen festschreiben — EIN Undo-Schritt. -func grab_confirm() -> void: - if not _grabbing: - return - _grabbing = false - var desc := "Objekt verschoben (greifen)" if _grab_members.size() == 1 \ - else "%d Objekte verschoben (greifen)" % _grab_members.size() - main.history.commit(desc, _grab_before, main.history.snapshot(["objects"])) - _grab_members = [] - _grab_originals = {} - _grab_lifts = {} - _grab_before = {} - _grab_twin_map = {} - _grab_twin_originals = {} - _mark_dirty() - main.call("_refresh_history_buttons") - main.call("_refresh_stats") - main.call("_sync_selection_panel") - main.call("_set_status", "%s — Strg+Z nimmt den ganzen Zug zurück. G greift erneut, Esc hebt immer ab." % desc) - - -## Esc im Greifen: EXAKTE Rückabwicklung auf die Positionen von grab_begin — -## byte-identisch (keine Float-Re-Rechnung), KEIN History-Eintrag. -func grab_cancel() -> void: - if not _grabbing: - return - _grabbing = false - var objects: Array = main.doc.get("objects", []) - for i in _grab_members: - var orig: Array = _grab_originals[i] - (objects[i] as Dictionary)["pos"] = [float(orig[0]), float(orig[1]), float(orig[2])] - if i < view_builder.object_markers.size(): - var marker: Node3D = view_builder.object_markers[i] - if marker != null and is_instance_valid(marker): - marker.position = Vector3(float(orig[0]), float(orig[1]), float(orig[2])) - # Symmetrie (M3, t_34908425): die MITgezogenen Zwillinge exakt zurücksetzen. - for t in _grab_twin_originals: - var torig: Array = _grab_twin_originals[t] - (objects[t] as Dictionary)["pos"] = [float(torig[0]), float(torig[1]), float(torig[2])] - if t < view_builder.object_markers.size(): - var tmarker: Node3D = view_builder.object_markers[t] - if tmarker != null and is_instance_valid(tmarker): - tmarker.position = Vector3(float(torig[0]), float(torig[1]), float(torig[2])) - _grab_members = [] - _grab_originals = {} - _grab_lifts = {} - _grab_before = {} - _grab_twin_map = {} - _grab_twin_originals = {} - main.call("_set_status", "Greifen abgebrochen — alles ist wieder, wie es war.") - - -## Symmetrie (M3): Zwillinge beim GREIFEN live mitziehen — doc + Marker, -## exakter Spiegel der Quelle. Gehören BEIDE Seiten eines Paares zur Greif- -## Menge, ist die Quelle das Primär-Objekt (sonst der niedrigere Index). -func _sym_grab_twin_move() -> void: - var sym_mode: int = _sym_mode() - if sym_mode == SymmetryCore.Mode.OFF or _grab_twin_map.is_empty(): - return - var objects: Array = main.doc.get("objects", []) - var center := SymmetryCore.map_center(main.doc) - var handled: Dictionary = {} - for i in _grab_members: - if not _grab_twin_map.has(i): - continue - var t: int = int(_grab_twin_map[i]) - var pair_key := "%d|%d" % [mini(i, t), maxi(i, t)] - if handled.has(pair_key): - continue - handled[pair_key] = true - var src_i: int = i - if _grab_members.has(t): - if _grab_primary == t: - src_i = t - elif _grab_primary != i and t < i: - src_i = t - var twin_i: int = t if src_i == i else i - if src_i >= objects.size() or not (objects[src_i] is Dictionary): - continue - var spos: Array = (objects[src_i] as Dictionary).get("pos", [0.0, 0.0, 0.0]) - if (spos as Array).size() != 3: - continue - var mp := SymmetryCore.mirror_point(sym_mode, - Vector3(float(spos[0]), float(spos[1]), float(spos[2])), center) - (objects[twin_i] as Dictionary)["pos"] = [mp.x, mp.y, mp.z] - if twin_i < view_builder.object_markers.size(): - var tm: Node3D = view_builder.object_markers[twin_i] - if tm != null and is_instance_valid(tm): - tm.position = Vector3(mp.x, mp.y, mp.z) - - -## Symmetrie (M3): Zwillinge beim ZIEHEN live mitführen (nur Marker — das doc -## schreibt _commit_drag über symmetry_sync_pairs). Quelle = Primär-Objekt, -## wenn beide Seiten eines Paares in der Zieh-Menge sind, sonst niedrigerer Index. -func _sym_drag_sync_live() -> void: - var sym_mode: int = _sym_mode() - if sym_mode == SymmetryCore.Mode.OFF or view_builder == null: - return - var objects: Array = main.doc.get("objects", []) - var center := SymmetryCore.map_center(main.doc) - var handled: Dictionary = {} - for i in _drag_members: - if not (i is int) or i < 0 or i >= objects.size() or not (objects[i] is Dictionary): - continue - var key := SymmetryCore.sym_of(objects[i] as Dictionary) - if key.is_empty(): - continue - var t := SymmetryCore.find_partner_index(objects, key, i) - if t < 0: - continue - var pair_key := "%d|%d" % [mini(i, t), maxi(i, t)] - if handled.has(pair_key): - continue - handled[pair_key] = true - var src_i: int = i - if _drag_members.has(t): - if _drag_primary == t: - src_i = t - elif _drag_primary != i and t < i: - src_i = t - var twin_i: int = t if src_i == i else i - if src_i >= view_builder.object_markers.size() or twin_i >= view_builder.object_markers.size(): - continue - var sm: Node3D = view_builder.object_markers[src_i] - var tm: Node3D = view_builder.object_markers[twin_i] - if sm == null or tm == null or not is_instance_valid(sm) or not is_instance_valid(tm): - continue - tm.position = SymmetryCore.mirror_point(sym_mode, sm.position, center) - - - - -## ⇄ Spiegeln (X: links↔rechts, Z: vor↔zurück) an der Stelle des Objekts — -## die Blickrichtung wird gespiegelt (sicher selbstinvers: doppelt = zurück). -func mirror_selected(axis: String) -> void: - if selected_index < 0: - main.call("_set_status", "Nichts ausgewählt — klicke zuerst ein Objekt an, das du spiegeln willst.", true) - return - var objects: Array = main.doc.get("objects", []) - if selected_index >= objects.size(): - clear_selection(true) - return - var before: Dictionary = main.history.snapshot(["objects"]) - var obj: Dictionary = objects[selected_index] - var old_rot := float(obj.get("rot_y_deg", 0.0)) - ObjectOps.mirror_object(obj, axis) - var new_rot := float(obj.get("rot_y_deg", 0.0)) - var marker: Node3D = view_builder.object_markers[selected_index] if selected_index < view_builder.object_markers.size() else null - if marker != null and is_instance_valid(marker): - marker.rotation.y = deg_to_rad(new_rot) - # Symmetrie (M3, t_34908425): der Zwilling dreht MIT (exakter Spiegel der - # neuen Blickrichtung) — im selben Commit wie die Quelle. - var twins: Array = ObjectOps.symmetry_sync_pairs( - main.doc, [selected_index], _sym_mode(), selected_index) - _sync_members_to_markers(twins) - var desc := "Objekt gespiegelt (links↔rechts)" if axis == "x" else "Objekt gespiegelt (vor↔zurück)" - main.history.commit(desc, before, main.history.snapshot(["objects"])) - main.dirty = true - main.call("_refresh_file_label") - main.call("_refresh_history_buttons") - main.call("_sync_selection_panel") - main.call("_set_status", "%s — Blickrichtung %.0f° → %.0f°. Strg+Z stellt die alte Richtung wieder her." % [ - desc, old_rot, new_rot]) - - -# ------------------------------------------------------------ Eingaben ------ - -func _unhandled_input(event: InputEvent) -> void: - # Strg-Zwang (Karte t_55257792) aus JEDEM durchgelassenen Event verfolgen — - # Maus-Events tragen den Modifier, Tasten-Events ebenso (nicht konsumieren!). - if event is InputEventKey: - _ctrl_held = (event as InputEventKey).ctrl_pressed - var p := MousePointer.from_input(event) - if p != null and handle_pointer(p): - get_viewport().set_input_as_handled() - - -## Rechte Maustaste kommt hier nie an (Karte t_2470de89): sie gehört mit -## absolutem Vorrang dem Freelook-Flug (orbit_camera.gd). Beim Platzieren -## bleibt das Objekt IN der Hand, Abwurf nur über Esc. -func handle_pointer(p: PointerEvent) -> bool: - if p.kind != PointerEvent.Kind.CANCEL: - _ctrl_held = p.ctrl - var mode: String = main.get("tool_mode") - if mode == "terrain" or mode == "spawns": - return false # Terrain-Pinsel / Spawn-Zonen haben das Zepter (eigene Werkzeuge) - match p.kind: - PointerEvent.Kind.MOVE: - _on_pointer_move(p.position) - PointerEvent.Kind.PRESS: - if _grabbing: - grab_confirm() - return true - _on_left_press(p) - return true - PointerEvent.Kind.RELEASE: - _on_left_release(p) - PointerEvent.Kind.SCROLL: - if _camera_flying(): - return false # Mausrad = Flug-Tempo (orbit_camera), kein Objekt-Drehen - if placing: - place_rot_deg = fmod(place_rot_deg + p.scroll * (90.0 if BauKatalog.ist_bau(place_oid) else ROT_STEP_DEG) + 3600.0, 360.0) - _ghost_rotation_anwenden() - return true - if selected_index >= 0 and not _grabbing: - rotate_selected(p.scroll * ROT_STEP_DEG) - return true - return false - - -func _on_pointer_move(pos: Vector2) -> void: - if placing: - _ghost_update(pos) - if _grabbing: - var gh: Variant = _ground_point(pos) - if gh != null: - grab_move(gh as Vector3) - return - if _rubber_pending or _rubber_active: - var dist := Vector2(pos.x - _press_pos.x, pos.y - _press_pos.y).length() - if dist > DRAG_THRESHOLD_PX: - _rubber_active = true - _rubber_pending = false - if _rubber_active: - main.call("_rubberband_update", _rubber_start, pos) - return - if _dragging and not placing and not _drag_members.is_empty(): - _drag_members_move(pos) - elif _dragging and not placing and selected_index >= 0: - # Einzel-Greifen (alter Pfad, ohne Gruppe/Mehrfachauswahl) - var p: Variant = _ground_point(pos) - if p == null: - return - var new_pos: Vector3 = _apply_grid((p as Vector3) + _grab_offset) - var half := _terrain_half() - new_pos.x = clampf(new_pos.x, -half.x, half.x) - new_pos.z = clampf(new_pos.z, -half.y, half.y) - # Höhe: der Terrain-Abstand bleibt beim Ziehen erhalten (angehoben - # schwebt weiter oben) — kein harter Terrain-Clamp mehr, t_7567a06f. - new_pos.y = SvmapDocument.terrain_height_at(main.doc, new_pos.x, new_pos.z) + _drag_lift - var dist := Vector2(pos.x - _press_pos.x, pos.y - _press_pos.y).length() - if dist > DRAG_THRESHOLD_PX: - _drag_moved = true - if _drag_moved: - var marker: Node3D = view_builder.object_markers[selected_index] - if marker != null and is_instance_valid(marker): - marker.position = new_pos - - -func _on_left_press(p: PointerEvent) -> void: - if placing: - _place_object(p.position, p.shift) # U5: Shift = Serienmodus - return - _press_pos = p.position - var hit := _pick_object(p.position) - if hit >= 0: - if p.shift or p.command: - # Umschalt+Klick / Strg+Klick (Karte t_c46d31c2): zur Auswahl - # hinzufügen/entfernen — kein Ziehen. - select_toggle(hit) - return - if not selected_indices.has(hit): - select_object(hit) - _begin_drag(hit, p.position) - else: - # Leere Stelle: Rahmen-Ausziehen vorbereiten; loser Klick = Auswahl weg. - _rubber_pending = true - _rubber_active = false - _rubber_start = p.position - _rubber_shift = p.shift - - -## Zieh-Menge festlegen: Mehrfachauswahl oder komplette Gruppe ziehen GEMEINSAM. -## Vom Gizmo im Drehen-Modus gesetzt: ein Klick auf das gewählte Objekt zieht -## es NICHT mehr weg (nur die Ringe drehen). -var no_drag_move := false - - -func _begin_drag(hit: int, viewport_pos: Vector2) -> void: - if no_drag_move and hit == selected_index: - return - var objects: Array = main.doc.get("objects", []) - _drag_members = [] - _grab_offsets = {} - _drag_lifts = {} - _drag_is_group = false - if selected_indices.size() > 1: - _drag_members = selected_indices.duplicate() - else: - var gid := GroupOps.group_id(objects[hit]) - if gid != GroupOps.UNGROUPED: - var members := GroupOps.members_of(main.doc, gid) - if members.size() > 1: - _drag_members = members - _drag_is_group = true - select_many(members, true) # ganze Gruppe sichtbar markieren - if _drag_members.is_empty(): - _drag_members = [selected_index] - _drag_primary = selected_index if selected_index >= 0 else hit - _dragging = true - _drag_moved = false - var p: Variant = _ground_point(viewport_pos) - if p != null: - for i in _drag_members: - if i >= view_builder.object_markers.size(): - continue - var marker: Node3D = view_builder.object_markers[i] - if marker != null and is_instance_valid(marker): - var off: Vector3 = marker.position - (p as Vector3) - off.y = 0.0 - _grab_offsets[i] = off - # Terrain-Abstand einfrieren (t_7567a06f, für die GANZE Zieh- - # Menge): ein Objekt mit Höhe behält beim Ziehen diesen Abstand - # zum Boden — bodennah bleibt bodennah, angehoben schwebt weiter. - var lift := marker.position.y \ - - SvmapDocument.terrain_height_at(main.doc, marker.position.x, marker.position.z) - _drag_lifts[i] = lift - if i == _drag_primary: - _grab_offset = off - _drag_lift = lift - else: - for i in _drag_members: - _grab_offsets[i] = Vector3.ZERO - _drag_lifts[i] = 0.0 - _grab_offset = Vector3.ZERO - _drag_lift = 0.0 - - -## Gemeinsames Ziehen: Delta vom Primär-Objekt auf ALLE Mitglieder — relative -## Anordnung bleibt exakt erhalten, Raster-Snap rastet die GANZE Gruppe. -func _drag_members_move(viewport_pos: Vector2) -> void: - var p: Variant = _ground_point(viewport_pos) - if p == null or not _grab_offsets.has(_drag_primary): - return - var half := _terrain_half() - var new_primary: Vector3 = _apply_grid((p as Vector3) + (_grab_offsets[_drag_primary] as Vector3)) - new_primary.x = clampf(new_primary.x, -half.x, half.x) - new_primary.z = clampf(new_primary.z, -half.y, half.y) - new_primary.y = SvmapDocument.terrain_height_at(main.doc, new_primary.x, new_primary.z) - var dist := Vector2(viewport_pos.x - _press_pos.x, viewport_pos.y - _press_pos.y).length() - if dist > DRAG_THRESHOLD_PX: - _drag_moved = true - if not _drag_moved: - return - var primary_marker: Node3D = view_builder.object_markers[_drag_primary] - if primary_marker == null or not is_instance_valid(primary_marker): - return - var delta: Vector3 = new_primary - primary_marker.position - delta.y = 0.0 - if delta.length_squared() < 0.0000001: - return - for i in _drag_members: - if i >= view_builder.object_markers.size(): - continue - var marker: Node3D = view_builder.object_markers[i] - if marker == null or not is_instance_valid(marker): - continue - var np: Vector3 = marker.position + delta - np.x = clampf(np.x, -half.x, half.x) - np.z = clampf(np.z, -half.y, half.y) - # Höhe: Terrain-Abstand bleibt erhalten (t_7567a06f, pro Objekt — - # angehoben schwebt weiter, bodennah bleibt bodennah). - np.y = SvmapDocument.terrain_height_at(main.doc, np.x, np.z) \ - + float(_drag_lifts.get(i, 0.0)) - marker.position = np - # Symmetrie (M3, t_34908425): Zwillinge LIVE mitziehen (nur Marker — - # das doc schreibt _commit_drag), exakter Spiegel der gezogenen Quelle. - _sym_drag_sync_live() - - -func _on_left_release(p: PointerEvent) -> void: - if _rubber_pending or _rubber_active: - var was_active := _rubber_active - _rubber_pending = false - _rubber_active = false - main.call("_rubberband_clear") - if was_active: - _finish_rubberband(p.position) - elif not _rubber_shift: - # Loser Klick auf leere Fläche: Auswahl aufheben (Klick statt Auswendiglernen). - if not selected_indices.is_empty(): - clear_selection() - return - if _dragging: - _dragging = false - if _drag_moved and not _drag_members.is_empty(): - _commit_drag() - _drag_moved = false - _drag_members = [] - _grab_offsets = {} - _drag_is_group = false - - -## Rahmen-Ausziehen abgeschlossen: alle Marker im Rahmen auswählen. -func _finish_rubberband(end_pos: Vector2) -> void: - var rect := SelectionMath.rect_from(_rubber_start, end_pos) - var positions: Array = [] - for marker in view_builder.object_markers: - if marker != null and is_instance_valid(marker): - positions.append(marker.global_position) - else: - positions.append(Vector3(INF, INF, INF)) # kaputter Marker: nie im Rahmen - var picked := SelectionMath.pick_in_rect(camera, positions, rect) - if _rubber_shift and not picked.is_empty(): - for i in picked: - if not selected_indices.has(i): - selected_indices.append(i) - selected_index = picked[picked.size() - 1] - elif not _rubber_shift: - selected_indices = picked - selected_index = picked.back() if not picked.is_empty() else -1 - _apply_selection_view() - main.call("_sync_selection_panel") - if selected_indices.is_empty(): - main.call("_set_status", "Der Rahmen hat kein Objekt erwischt — zieh ihn über die Objekte, die du zusammen bearbeiten willst.") - else: - main.call("_set_status", "Rahmen-Auswahl: %d Objekte markiert. Strg+G gruppier sie, oder ziehe sie gemeinsam weiter." % selected_indices.size()) - - -## Bewegte Marker → Doc schreiben, EIN Undo-Schritt für den ganzen Zug. -func _commit_drag() -> void: - var objects: Array = main.doc.get("objects", []) - var moved: Array = [] - for i in _drag_members: - if i >= objects.size() or i >= view_builder.object_markers.size(): - continue - var marker: Node3D = view_builder.object_markers[i] - if marker == null or not is_instance_valid(marker): - continue - moved.append(i) - if moved.is_empty(): - return - var before: Dictionary = main.history.snapshot(["objects"]) - for i in moved: - var pos: Vector3 = (view_builder.object_markers[i] as Node3D).position - objects[i]["pos"] = [float(pos.x), float(pos.y), float(pos.z)] - # Symmetrie (M3, t_34908425): Zwillinge der gezogenen Auswahl auf den exakten - # Spiegel setzen — IM SELBEN Commit (ein Zug = EIN Undo-Schritt für beide). - var twins: Array = ObjectOps.symmetry_sync_pairs( - main.doc, moved, _sym_mode(), _drag_primary) - _sync_members_to_markers(twins) - var desc: String - if _drag_is_group: - desc = "Gruppe verschoben (%d Objekte)" % moved.size() - elif moved.size() > 1: - desc = "%d Objekte verschoben" % moved.size() - else: - desc = "Objekt verschoben" - main.history.commit(desc, before, main.history.snapshot(["objects"])) - _mark_dirty() - main.call("_refresh_history_buttons") - main.call("_refresh_stats") - - -## Dirty-Markierung ohne Full-Rebuild (Auswahl/Marker bleiben bestehen). -func _mark_dirty() -> void: - main.set("dirty", true) - main.call("_refresh_file_label") - - -# ---------------------------------------------------- Screenshot-Hilfe ------ - -## Demo-Hook (Desktop-Smoke): Ghost außerhalb echter Maus-Ereignisse parken, -## damit ein Screenshot die Vorschau zeigen kann. -func demo_park_ghost(world_pos: Vector3, oid: String) -> void: - start_placement(oid) - placing = true - place_oid = oid - _ghost_refresh_mesh() - _ghost.position = world_pos - _ghost_rotation_anwenden() - _ghost.visible = true - _ghost_active = true - main.call("_highlight_library", oid) - main.call("_set_status", "%s: führe die Maus über die Karte — Klick setzt es. Mausrad dreht vorher, ESC bricht ab (Rechte Maustaste = Flug)." % main.object_label(oid)) - - -## Demo-Hook (Gruppen-Smoke, Karte t_f6f29d86): die Auswahl EXAKT so ziehen -## wie ein echter Drag-Release (Marker bewegen + EIN Commit). -func demo_drag_selection(delta: Vector3) -> void: - if selected_indices.is_empty(): - return - _drag_members = selected_indices.duplicate() - _drag_is_group = false - _drag_primary = selected_index - _dragging = true - _drag_moved = true - for i in _drag_members: - if i < view_builder.object_markers.size(): - var marker: Node3D = view_builder.object_markers[i] - if marker != null and is_instance_valid(marker): - marker.position += delta - _commit_drag() - _dragging = false - _drag_members = [] - _drag_moved = false diff --git a/src/editor/interaction.gd.uid b/src/editor/interaction.gd.uid deleted file mode 100644 index 4d72a94..0000000 --- a/src/editor/interaction.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cdfcdpiga4j0s diff --git a/src/editor/library_browser.gd b/src/editor/library_browser.gd deleted file mode 100644 index 65bbb0b..0000000 --- a/src/editor/library_browser.gd +++ /dev/null @@ -1,167 +0,0 @@ -extends RefCounted -class_name LibraryBrowser -## Objekt-Bibliothek des Editors (Karte t_3a998ae4): deutscher Name, Gruppen -## für den Bibliothek-Browser und Thumbnail-Laden (128-px-PNGs, einmalig per -## Headless-Render erzeugt — tools/gen_thumbs.gd). -## -## Bewusst OHNE UI: reine Daten/Funktionen, damit die Tests (tests/test_library.gd) -## headless alles prüfen können. Die IDs sind der Vertrag (Entscheidung 20) — -## Gruppen/Namen leben HIER im Editor (die objects.json bleibt 1:1 die Kopie -## der Server-Registry, damit ein Sync sie nicht verwüstet). - -## Deutsche Anzeige-Namen für Bibliotheks-IDs, die KEIN `name_de` im Manifest -## haben (IDs sind der Vertrag, Entscheidung 20). Seit der Military-Pack- -## Umstellung (25.10.2026) hat jedes Objekt ein `name_de` — die Liste bleibt -## leer und dient nur als Override-Möglichkeit. -const NAMES := {} - -## Fallback-Gruppe für Objekte ohne bekannte Kategorie. -const GROUP_ORDER := ["sonstiges"] -const GROUP_LABELS := { - "sonstiges": "Sonstiges", -} - -## Kategorien des Military-Desert-Packs (Manifest-Feld `kategorie`, siehe -## library/objects.json; Quelle der Slugs/Namen: scopedvr-match-server -## tools/pack_katalog.py). Reihenfolge = Anzeige-Reihenfolge. Unbekannte -## Kategorien (z. B. spätere Bauteil-Module) tauchen automatisch mit ihrem -## Slug als Gruppe auf, ganz vor "Sonstiges". -const KAT_ORDER := ["bauteile", "panzer", "radfahrzeuge", "luftfahrzeuge", "stellungen", "fahrzeugteile", "gebaeude", "zelte", "tuerme", "mauern", "sperren", "kisten", "technik", "ausruestung", "training", "baeume", "pflanzen", "felsen", "boden", "decals"] -const KAT_GROUPS := { - "bauteile": {"key": "bauteile", "label": "Bauteile (eigene Häuser)"}, - "panzer": {"key": "panzer", "label": "Panzer & Transportpanzer"}, - "radfahrzeuge": {"key": "radfahrzeuge", "label": "Radfahrzeuge"}, - "luftfahrzeuge": {"key": "luftfahrzeuge", "label": "Flugzeuge & Hubschrauber"}, - "stellungen": {"key": "stellungen", "label": "Geschütze & Stellungen"}, - "fahrzeugteile": {"key": "fahrzeugteile", "label": "Fahrzeugteile"}, - "gebaeude": {"key": "gebaeude", "label": "Gebäude & Hangars"}, - "zelte": {"key": "zelte", "label": "Zelte"}, - "tuerme": {"key": "tuerme", "label": "Türme & Masten"}, - "mauern": {"key": "mauern", "label": "Mauern & Wände"}, - "sperren": {"key": "sperren", "label": "Sperren & Zäune"}, - "kisten": {"key": "kisten", "label": "Kisten, Fässer & Container"}, - "technik": {"key": "technik", "label": "Technik & Funk"}, - "ausruestung": {"key": "ausruestung", "label": "Ausrüstung & Zubehör"}, - "training": {"key": "training", "label": "Training & Ziele"}, - "baeume": {"key": "baeume", "label": "Bäume & Totholz"}, - "pflanzen": {"key": "pflanzen", "label": "Pflanzen, Kakteen & Gras"}, - "felsen": {"key": "felsen", "label": "Felsen & Steine"}, - "boden": {"key": "boden", "label": "Boden, Straßen & Dünen"}, - "decals": {"key": "decals", "label": "Boden-Decals"}, -} - -## Anzeige-Größe der Vorschaubilder im Browser (Karte t_59fc0f21): vorher 40 px, -## jetzt Kacheln mit 128 px (25.10.: größer, deutlicher) (128-px-PNGs werden auf die Anzeige-Größe skaliert). -const THUMB_DISPLAY_PX := 128 - - -## Manifest-Cache (vom Editor beim Laden gesetzt): damit object_label() und -## group_of() auch ohne Manifest-Parameter den deutschen Namen / die Kategorie -## kennen (Statuszeile, Szenen-Baum, Inspector). -static var _manifest_cache: Dictionary = {} - - -static func setze_manifest(manifest: Dictionary) -> void: - _manifest_cache = (manifest.get("objects", {}) as Dictionary) if manifest.has("objects") else {} - - -static func object_label(oid: String) -> String: - if BauKatalog.ist_bau(oid): - return BauKatalog.label(oid) - if NAMES.has(oid): - return str(NAMES[oid]) - var entry: Dictionary = _manifest_cache.get(oid, {}) as Dictionary - var name_de := str(entry.get("name_de", "")) - if not name_de.is_empty(): - return name_de - return oid.capitalize() - - -## Gruppe einer ID (ohne Manifest-Eintrag → "sonstiges"). -static func group_of(oid: String) -> String: - if BauKatalog.ist_bau(oid): - return "bauteile" - var entry: Dictionary = _manifest_cache.get(oid, {}) as Dictionary - return group_of_entry(oid, entry) - - -## Gruppe eines Katalog-Eintrags: Manifest-Feld `kategorie` (KAT_GROUPS); -## unbekannte Kategorie → eigene Gruppe mit dem Slug als Schlüssel; kein -## Eintrag/keine Kategorie → "sonstiges". entry darf leer sein. -static func group_of_entry(_oid: String, entry: Dictionary) -> String: - var kat := str(entry.get("kategorie", "")) - if kat.is_empty(): - return "sonstiges" - if KAT_GROUPS.has(kat): - return str(KAT_GROUPS[kat]["key"]) - return kat - - -## Deutscher Anzeigename: Manifest-Feld `name_de`, sonst NAMES/fallback. -static func entry_label(oid: String, entry: Dictionary) -> String: - var name_de := str(entry.get("name_de", "")) - if not name_de.is_empty(): - return name_de - return object_label(oid) - - -## Gruppen für den Browser, geprüft gegen das Manifest: nur Gruppen mit -## Objekten erscheinen. Unbekannte Kategorien wandern als eigene Gruppe vor -## "Sonstiges" — neue Bibliotheks-Einträge brechen die UI nicht. -static func groups_in_order(manifest: Dictionary) -> Array: - var lib: Dictionary = manifest.get("objects", {}) - var by_group := {} - for oid in lib.keys(): - var entry: Dictionary = lib.get(oid, {}) as Dictionary - var key := group_of_entry(str(oid), entry) - if not by_group.has(key): - by_group[key] = [] - (by_group[key] as Array).append(str(oid)) - var reihenfolge: Array = KAT_ORDER.duplicate() - var fremde: Array = [] - for key in by_group.keys(): - if not reihenfolge.has(key) and not GROUP_ORDER.has(key): - fremde.append(key) - fremde.sort() - reihenfolge.append_array(fremde) - reihenfolge.append_array(GROUP_ORDER) - var out: Array = [] - for key in reihenfolge: - var ids: Array = (by_group.get(key, []) as Array) - ids.sort() - if ids.is_empty() and key != "sonstiges": - continue - out.append({"key": key, "label": _group_label(key), "ids": ids}) - return out - - -static func _group_label(key: String) -> String: - if GROUP_LABELS.has(key): - return str(GROUP_LABELS[key]) - for kat in KAT_GROUPS.values(): - if str(kat["key"]) == key: - return str(kat["label"]) - return key.capitalize() - - -## Thumbnail-Pfad (128-px-PNG, tools/gen_thumbs.gd erzeugt sie einmalig). -static func thumb_path(oid: String) -> String: - return "res://library/thumbs/%s.png" % oid - - -## Thumbnail als Textur laden — direkt über Image (kein Import-System nötig, -## geht damit auch frisch nach git pull ohne Import), auf Anzeige-Größe -## runtergerechnet. size_px steuert die Anzeige-Größe (Default = THUMB_DISPLAY_PX -## = 96, Karte t_59fc0f21; vorher fest 40). null = noch kein Thumbnail → -## Button fällt aufs Text-Layout zurück (Fehler sieht man nicht, man sieht -## einfach nur kein Bild). -static func load_thumb(oid: String, size_px := THUMB_DISPLAY_PX) -> Texture2D: - var path := thumb_path(oid) - if not FileAccess.file_exists(path): - return null - var img := Image.load_from_file(path) - if img == null: - return null - if img.get_width() != size_px or img.get_height() != size_px: - img.resize(size_px, size_px, Image.INTERPOLATE_LANCZOS) - return ImageTexture.create_from_image(img) diff --git a/src/editor/library_browser.gd.uid b/src/editor/library_browser.gd.uid deleted file mode 100644 index d4c7d10..0000000 --- a/src/editor/library_browser.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://o3jwxk87gtw diff --git a/src/editor/mouse_pointer.gd b/src/editor/mouse_pointer.gd deleted file mode 100644 index cff83d9..0000000 --- a/src/editor/mouse_pointer.gd +++ /dev/null @@ -1,39 +0,0 @@ -class_name MousePointer -extends RefCounted -## Übersetzt Maus und Esc-Taste in PointerEvent. Die rechte Maustaste fehlt -## absichtlich: sie gehört dem Freelook-Flug (orbit_camera.gd). - - -static func from_input(event: InputEvent) -> PointerEvent: - if event is InputEventMouseMotion: - var mm := event as InputEventMouseMotion - var p := PointerEvent.make(PointerEvent.Kind.MOVE, mm.position) - p.shift = mm.shift_pressed - p.ctrl = mm.ctrl_pressed - p.command = mm.is_command_or_control_pressed() - p.pressure = mm.pressure - return p - if event is InputEventMouseButton: - var mb := event as InputEventMouseButton - var kind := PointerEvent.Kind.MOVE - var scroll := 0 - match mb.button_index: - MOUSE_BUTTON_LEFT: - kind = PointerEvent.Kind.PRESS if mb.pressed else PointerEvent.Kind.RELEASE - MOUSE_BUTTON_WHEEL_UP, MOUSE_BUTTON_WHEEL_DOWN: - if not mb.pressed: - return null - kind = PointerEvent.Kind.SCROLL - scroll = 1 if mb.button_index == MOUSE_BUTTON_WHEEL_UP else -1 - _: - return null - var p := PointerEvent.make(kind, mb.position) - p.shift = mb.shift_pressed - p.ctrl = mb.ctrl_pressed - p.command = mb.is_command_or_control_pressed() - p.scroll = scroll - return p - if event is InputEventKey and (event as InputEventKey).pressed \ - and (event as InputEventKey).keycode == KEY_ESCAPE: - return PointerEvent.make(PointerEvent.Kind.CANCEL) - return null diff --git a/src/editor/mouse_pointer.gd.uid b/src/editor/mouse_pointer.gd.uid deleted file mode 100644 index 3b06f99..0000000 --- a/src/editor/mouse_pointer.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://1nyr0qwwdvnv diff --git a/src/editor/playtest/playtest_avatar.gd b/src/editor/playtest/playtest_avatar.gd deleted file mode 100644 index 8554ed2..0000000 --- a/src/editor/playtest/playtest_avatar.gd +++ /dev/null @@ -1,461 +0,0 @@ -class_name PlaytestAvatar -extends Node3D -## Playtest-Avatar (Karte t_17a35c59) — SPIEGEL des Bot-Avatars aus dem -## Quest-Client (scripts/match/bot_avatar.gd + MatchRemoteAvatar), Sly-Wunsch -## 20.10.: „das Player Model in den Map Editor … genau so wie im Spiel bei -## den Bots" + „direkt natürlich auch mit den Animationen bitte!". -## -## Quelle der Wahrheit: bot_avatar.gd. Dieses Modul übernimmt 1:1: -## - das GLB assets/avatars/quaternius_ual/ual1_standard.glb (Quaternius -## UAL, CC0) + das Rifle assets/weapons/m40_rifle.glb an hand_r — -## aufgelöst über den NACHBAR-KLON ../scopedvr-client (gleiche Auflösung -## wie GlbMeshStore/TestRun), NICHT dupliziert. Lädt mit GLTFDocument -## (die GLB liegt außerhalb res:// — kein Import-System). -## - die AnimationTree-Pipeline (A4/W14): BlendSpace1D Idle/Walk/Jog mit -## Blend-Punkten auf den Clip-Naturgeschwindigkeiten (0,0 / 0,979 / -## 2,620 m/s), sync = true, TimeScale-Subtrees für die Kadenz, darüber -## die StateMachine mit dem Motion-State. Crossfade ~0,2 s. -## - die Kadenz-Mathe (BOT2/vc23): Kadenz = m/s / Ziel-Schrittlänge -## (Walk 0,95 m / Jog 0,85 m), TimeScale = Kadenz × Zykluslänge / 2 -## Schritte pro Zyklus, Klammern CADENCE 1,0–4,5 und FOOT_SYNC 0,6–2,0. -## - die Gait-Schwellen (A2 §6.2): ≤ 0,3 m/s Idle, ≤ 2,6 m/s Walk, sonst -## Jog — im Editor aus der ECHTEN PlaytestBody-Geschwindigkeit gespeist. -## - die Frontachse (vc21-Fix): das UAL-GLB blickt nach +Z, der Body-Yaw -## richtet −Z aus → MODEL_YAW_OFFSET = π auf dem Modell-Kind. Blick- -## richtung == Bewegungsrichtung. -## - den Blend-Ruckel-Fix: Sollwerte werden in _process weich nachgezogen -## (BLEND_SMOOTH_S = 0,25 s), Parameter-Writes nur bei Änderung. -## -## NICHT gespiegelt (Match-only, kein Trigger im Editor-Testlauf): Engage/ -## Shoot/Hit/Death-One-Shots, Team-Tönung, Namensschild, Netzwerk-Interpo- -## lation, Ragdoll. Die StateMachine trägt deshalb nur den Motion-State — -## die Loop-Pipeline (die Sly sieht) ist identisch zum Spiel. -## -## Regel (wie KolliderBau/svmap_tint): Ändert der Client die Pipeline, wird -## dieser Spiegel MIT geändert. Bewusst KEINE Editor-eigenen Maße oder -## Anim-Parameter — Proportionen/Konstanten strikt aus der Client-Quelle. -## -## Fehlt der Client-Klon (oder die GLB): lade_avatar() gibt null zurück — -## PlaytestMode bleibt dann komplett in First Person (graceful, kein Crash). - -## ------------------------------------------------ Quelle (Client-Klon) ---- -## Relative Pfade IM Client-Repo (Nachbar-Klon, nicht dupliziert). -const MODEL_REL := "assets/avatars/quaternius_ual/ual1_standard.glb" -const RIFLE_REL := "assets/weapons/m40_rifle.glb" - -## ------------------------------------- Clips (MatchRemoteAvatar-Erbe) ----- -const CLIP_IDLE := "Idle" -const CLIP_WALK := "Walk" -const CLIP_JOG := "Jog_Fwd" - -## Server-/Inferenz-States (A1-Vertrag, bot_avatar.gd): 0=IDLE 1=WALK 2=JOG. -const STATE_IDLE := 0 -const STATE_WALK := 1 -const STATE_JOG := 2 - -## Gait-Schwellen (A2 §6.2, bot_avatar.gd): Velocity → State. -const IDLE_SPEED_MAX_MPS := 0.3 -const WALK_SPEED_MAX_MPS := 2.6 - -## Blend-Punkte = Clip-Naturgeschwindigkeiten (H1-Messung, bot_avatar.gd). -const WALK_NATURAL_MPS := 0.979 -const JOG_NATURAL_MPS := 2.620 -const BLEND_IDLE_MPS := 0.0 -const BLEND_MAX_MPS := 4.0 - -## Kadenz-Kalibrierung (BOT2/vc23, bot_avatar.gd): Ziel-Schrittlängen + Klammern. -const WALK_STEP_M := 0.95 -const JOG_STEP_M := 0.85 -const CADENCE_MIN := 1.0 -const CADENCE_MAX := 4.5 -const FOOT_SYNC_MIN := 0.6 -const FOOT_SYNC_MAX := 2.0 - -## Crossfade (A4) + Blend-Glättung (vc21-Ruckel-Fix, bot_avatar.gd). -const CROSSFADE_S := 0.2 -const BLEND_SMOOTH_S := 0.25 - -## Modell-Anker (bot_avatar.gd): Knoten = Kopf-Anker in Augenhöhe (1,65 m), -## GLB-Kind hängt mit negativem Y-Versatz (Füße am Boden, Modell 1,83 m). -const MODEL_EYE_HEIGHT := 1.65 -const MODEL_Y_OFFSET := -1.65 -## Frontachse (vc21-Messung): GLB blickt nach +Z → 180°-Korrektur auf dem -## Modell-Kind, damit die Front auf das lokale −Z (Body-Vorwärts) zeigt. -const MODEL_FORWARD_LOCAL := Vector3(0.0, 0.0, 1.0) -const MODEL_YAW_OFFSET := PI - -## Rifle-Mount (vc21-Messung, bot_avatar.gd): hand_r, Lauf → Hand-+Y, -## Rifle-oben → Hand-+Z = reine +90°-X-Drehung; Griff 0,067 m auf Hand-+Y. -const RIFLE_HAND_BONE := "hand_r" -const RIFLE_ROT_BASIS := Basis(Vector3(1.0, 0.0, 0.0), deg_to_rad(90.0)) -const RIFLE_POS := Vector3(0.0, 0.067, 0.0) - -## AnimationTree-Vertrag (bot_avatar.gd — Namen sind Teil des Vertrags). -const SM_MOTION := "Motion" -const P_BLEND := "parameters/Motion/Speed/blend_position" -const P_WALK_SCALE := "parameters/Motion/Speed/Walk/WalkTs/scale" -const P_JOG_SCALE := "parameters/Motion/Speed/Jog/JogTs/scale" -const P_PLAYBACK := "parameters/playback" - -## GLB-Instanz (Modell-Wurzel), AnimationPlayer (Clip-Lieferant), Tree. -var _model: Node3D = null -var _anim: AnimationPlayer = null -var _tree: AnimationTree = null -var _playback: AnimationNodeStateMachinePlayback = null -## Sichtbarer Zustand (Tests/Debug): Soll-Clip + Soll-Blend. -var _cur_clip := "" -var state := STATE_IDLE -var speed_mps := 0.0 -var _blend_cur := 0.0 -var _blend_target := 0.0 -var _walk_scale_cur := 1.0 -var _walk_scale_target := 1.0 -var _jog_scale_cur := 1.0 -var _jog_scale_target := 1.0 - - -## Client-Projektordner (Nachbar-Klon oder konfigurierter Pfad) — dieselbe -## Auflösung wie der alte Client-Start (test_run.gd). "" = keiner gefunden. -static func client_wurzel() -> String: - return TestRun.find_client(ProjectSettings.globalize_path("res://"), - TestRun.load_cfg()) - - -## Absoluter Modell-/Rifle-Pfad im Client-Klon ("" = kein Klon gefunden). -static func model_pfad() -> String: - var root := client_wurzel() - if root.is_empty(): - return "" - return root.path_join(MODEL_REL) - - -static func rifle_pfad() -> String: - var root := client_wurzel() - if root.is_empty(): - return "" - return root.path_join(RIFLE_REL) - - -## State aus der echten Geschwindigkeit (Spiegel von _track_velocity, -## bot_avatar.gd — dieselben Schwellen, ohne Netzwerk-Glättung). -static func zustand_fuer(speed: float) -> int: - if speed <= IDLE_SPEED_MAX_MPS: - return STATE_IDLE - if speed <= WALK_SPEED_MAX_MPS: - return STATE_WALK - return STATE_JOG - - -## Avatar aus dem Client-Klon laden (null = fehlt/nicht ladbar → graceful -## Fallback auf First Person beim Aufrufer). Baut Modell + AnimationTree -## + Rifle-Mount exakt wie bot_avatar._ready/_build_model/_build_anim_tree. -static func lade_avatar() -> PlaytestAvatar: - var glb_pfad := model_pfad() - if glb_pfad.is_empty() or not FileAccess.file_exists(glb_pfad): - push_warning("PLAYTEST_AVATAR: Modell fehlt (%s) — Third Person nicht verfügbar" % glb_pfad) - return null - var gltf := GLTFDocument.new() - var state := GLTFState.new() - if gltf.append_from_file(glb_pfad, state) != OK: - push_warning("PLAYTEST_AVATAR: GLB nicht ladbar: %s" % glb_pfad) - return null - var szene: Node = gltf.generate_scene(state) - if szene == null: - push_warning("PLAYTEST_AVATAR: GLB-Szene leer: %s" % glb_pfad) - return null - var avatar := PlaytestAvatar.new() - avatar.name = "Avatar" - avatar._model = szene as Node3D - if avatar._model == null: - push_warning("PLAYTEST_AVATAR: GLB-Wurzel kein Node3D: %s" % glb_pfad) - szene.free() - return null - avatar._model.name = "Body" - # Kopf-Anker-Konvention (bot_avatar._build_model): das GLB-Kind hängt mit - # MODEL_Y_OFFSET nach unten (GLB-Ursprung = Füße) — der Avatar-Node selbst - # sitzt bei PlaytestBody in Augenhöhe über dem Füßpunkt (set_avatar). - # vc21-Frontachse: GLB blickt nach +Z → 180° auf das Modell-Kind, damit - # die Modell-Front auf das Avatar-lokale −Z zeigt (= Body-Vorwärts). - avatar._model.position = Vector3(0.0, MODEL_Y_OFFSET, 0.0) - avatar._model.rotation.y = MODEL_YAW_OFFSET - avatar.add_child(avatar._model) - for child in avatar._model.find_children("*", "AnimationPlayer", true, false): - avatar._anim = child - if avatar._anim == null: - push_warning("PLAYTEST_AVATAR: kein AnimationPlayer im GLB — Avatar unbrauchbar") - avatar.free() - return null - # Importer-Semantik nachbilden: der Godot-Editor-Import (Client .import) - # streicht Animations-Namens-ENDUNGEN "-loop"/"_loop" und setzt dann - # Loop-Mode LOOP_LINEAR. GLTFDocument (Runtime-Ladung) liefert die rohen - # Namen ("Idle_Loop", "Walk_Loop", …) OHNE Loop-Mode — ohne diese - # Normalisierung hätten die Loops den falschen Namen (Bot-Vertrag: Idle/ - # Walk/Jog_Fwd) und würden nach einem Zyklus stehen bleiben. - avatar._normalisiere_clips() - if avatar._anim.get_animation_list().is_empty(): - push_warning("PLAYTEST_AVATAR: kein AnimationPlayer/Clips im GLB — Avatar unbrauchbar") - avatar.free() - return null - avatar._baue_anim_tree() - avatar._baue_rifle() - # Start-Anim: Idle (wie bot_avatar._ready — kein T-Pose-Blitz). - avatar.apply_state(STATE_IDLE, 0.0) - return avatar - - -## Importer-Semantik (siehe Aufrufkommentar): "_loop"/"-loop"-Endungen -## streichen, LOOP_LINEAR setzen — genau das, was der Client-.import mit -## derselben GLB macht (dort heißen die Clips Idle/Walk/Jog_Fwd, Loop-Mode -## im Asset korrekt, siehe bot_avatar.gd-Clip-Doku). -func _normalisiere_clips() -> void: - for lib_name in _anim.get_animation_library_list(): - var lib := _anim.get_animation_library(lib_name) - for clip_name in lib.get_animation_list(): - var animation: Animation = lib.get_animation(clip_name) - var lower := String(clip_name).to_lower() - if lower.ends_with("_loop") or lower.ends_with("-loop"): - var clean := String(clip_name).substr(0, String(clip_name).length() - 5) - lib.rename_animation(clip_name, clean) - animation.loop_mode = Animation.LOOP_LINEAR - - -## AnimationTree (A4-Pipeline, Motion-Zweig): BlendSpace1D Idle/Walk/Jog + -## TimeScale-Subtrees, darüber die StateMachine mit dem Motion-State. -## Verdrahtungs-Fallen (bot_avatar.gd A4-Sektion, Probe 18.10.): Clips als -## EIGENE Library auf die Tree kopieren (anim_player-Compatibility-Pfad -## überspringt die GLB-Default-Library), root_node = Modell-Wurzel -## (Track-Pfade "Armature/Skeleton3D:*"), Player bleibt reiner Clip-Lieferant. -func _baue_anim_tree() -> void: - _anim.stop() - var tree := AnimationTree.new() - tree.name = "AnimTree" - _model.add_child(tree) - var lib := AnimationLibrary.new() - for clip in _anim.get_animation_list(): - lib.add_animation(clip, _anim.get_animation(clip)) - tree.add_animation_library("", lib) - tree.root_node = tree.get_path_to(_model) - var motion := AnimationNodeBlendTree.new() - var blend := AnimationNodeBlendSpace1D.new() - var idle := AnimationNodeAnimation.new() - idle.animation = CLIP_IDLE - blend.add_blend_point(idle, BLEND_IDLE_MPS, 0, "Idle") - blend.add_blend_point(_speed_scaled_clip(CLIP_WALK, "WalkAnim", "WalkTs"), - WALK_NATURAL_MPS, 1, "Walk") - blend.add_blend_point(_speed_scaled_clip(CLIP_JOG, "JogAnim", "JogTs"), - JOG_NATURAL_MPS, 2, "Jog") - blend.min_space = 0.0 - blend.max_space = BLEND_MAX_MPS - blend.sync = true # vc21: gemeinsame Phase beim Blenden (kein Fuß-Pop) - motion.add_node("Speed", blend) - motion.connect_node("output", 0, "Speed") - var sm := AnimationNodeStateMachine.new() - sm.add_node(SM_MOTION, motion) - tree.tree_root = sm - tree.active = true - tree.process_callback = AnimationTree.ANIMATION_PROCESS_IDLE - _tree = tree - # _playback bewusst NICHT hier holen: der Baum hängt noch nicht im - # Szenenbaum — tree.get(P_PLAYBACK) liefert vorher null. Der Motion- - # Start passiert in apply_state() über _playback_holen() (nach dem - # Baum-Eintritt, wie _ensure_motion im Client). - - -## A4-Helfer (1:1 bot_avatar.gd): Clip-Subtree mit AnimationNodeTimeScale. -func _speed_scaled_clip(clip: String, anim_name: String, ts_name: String) -> AnimationNodeBlendTree: - var bt := AnimationNodeBlendTree.new() - var an := AnimationNodeAnimation.new() - an.animation = clip - var ts := AnimationNodeTimeScale.new() - bt.add_node(anim_name, an) - bt.add_node(ts_name, ts) - bt.connect_node(ts_name, 0, anim_name) - bt.connect_node("output", 0, ts_name) - return bt - - -## Rifle an hand_r (1:1 bot_avatar._build_rifle). Fehlt das Rifle-GLB oder -## der Knochen: warnen und ohne Waffe weiter (Avatar bleibt brauchbar). -func _baue_rifle() -> void: - var rifle_pfad_datei := rifle_pfad() - if rifle_pfad_datei.is_empty() or not FileAccess.file_exists(rifle_pfad_datei): - push_warning("PLAYTEST_AVATAR: Rifle fehlt (%s) — Avatar ohne Waffe" % rifle_pfad_datei) - return - var skeleton := _skeleton() - if skeleton == null: - push_warning("PLAYTEST_AVATAR: kein Skeleton3D — Rifle bleibt unattached") - return - if skeleton.find_bone(RIFLE_HAND_BONE) < 0: - push_warning("PLAYTEST_AVATAR: Hand-Knochen '%s' fehlt — Rifle bleibt unattached" % RIFLE_HAND_BONE) - return - var gltf := GLTFDocument.new() - var state := GLTFState.new() - if gltf.append_from_file(rifle_pfad_datei, state) != OK: - push_warning("PLAYTEST_AVATAR: Rifle-GLB nicht ladbar: %s" % rifle_pfad_datei) - return - var szene: Node = gltf.generate_scene(state) - if szene == null: - return - var attach := BoneAttachment3D.new() - attach.name = "RifleMount" - attach.bone_name = RIFLE_HAND_BONE - skeleton.add_child(attach) - var rifle := szene as Node3D - rifle.name = "Rifle" - rifle.basis = RIFLE_ROT_BASIS - rifle.position = RIFLE_POS - attach.add_child(rifle) - - -## Erstes Skeleton3D unter dem GLB (bot_avatar._build_model-Suche). -func _skeleton() -> Skeleton3D: - if _model == null: - return null - for child in _model.find_children("*", "Skeleton3D", true, false): - return child - return null - - -## ---------------------------------------------------------------- Anim ---- - -## Playtest-Movement-State anlegen (Kartenvorgabe: aus der ECHTEN Bewegung). -## mps < 0 = "nicht bekannt" → Kadenz unverändert lassen (wie bot_avatar). -func apply_state(new_state: int, new_speed_mps: float = -1.0) -> void: - if new_state != STATE_IDLE and new_state != STATE_WALK and new_state != STATE_JOG: - return # unbekannter State: nichts ändern (wie _clip_for_state ""). - state = new_state - if new_speed_mps >= 0.0: - speed_mps = new_speed_mps - var clip := _clip_for_state(state) - if clip.is_empty(): - return - _cur_clip = clip - if state == STATE_WALK: - _blend_target = WALK_NATURAL_MPS - _walk_scale_target = gait_scale_for(state, speed_mps) - _jog_scale_target = 1.0 - elif state == STATE_JOG: - _blend_target = JOG_NATURAL_MPS - _jog_scale_target = gait_scale_for(state, speed_mps) - _walk_scale_target = 1.0 - else: - _blend_target = BLEND_IDLE_MPS - _walk_scale_target = 1.0 - _jog_scale_target = 1.0 - if not is_processing(): - # Ohne _process-Treiber (Tests vor dem ersten Frame) sofort schreiben. - _blend_cur = _blend_target - _walk_scale_cur = _walk_scale_target - _jog_scale_cur = _jog_scale_target - _write_blend_params() - var playback := _playback_holen() - if playback != null: - # Wie bot_avatar._ensure_motion: Loop-State halten bzw. zurück. - # Der pre-tree start() der StateMachine kann beim Baum-Eintritt - # verworfen werden (leerer Knoten) → hier sauber (neu) starten. - var node := String(playback.get_current_node()) - if node.is_empty(): - playback.start(SM_MOTION) - elif node != SM_MOTION: - playback.travel(SM_MOTION) - - -## Bot2-Kadenz (1:1 bot_avatar.gd): Kadenz = m/s / Ziel-Schrittlänge, geklemmt. -func gait_cadence_for(s: int, mps: float) -> float: - var step := WALK_STEP_M if s == STATE_WALK else JOG_STEP_M - if s != STATE_WALK and s != STATE_JOG: - return 0.0 - return clampf(mps / maxf(step, 0.05), CADENCE_MIN, CADENCE_MAX) - - -## Bot2-TimeScale (1:1 bot_avatar.gd): Kadenz × Zykluslänge / 2 Schritte. -func gait_scale_for(s: int, mps: float) -> float: - var cadence := gait_cadence_for(s, mps) - if cadence <= 0.0: - return 1.0 - var cycle := _cycle_len_for(s) - if cycle <= 0.0: - return 1.0 - return clampf(cadence * cycle / 2.0, FOOT_SYNC_MIN, FOOT_SYNC_MAX) - - -func _cycle_len_for(s: int) -> float: - var clip := _clip_for_state(s) - if clip.is_empty() or _anim == null or not _anim.has_animation(clip): - return 0.0 - return _anim.get_animation(clip).length - - -## StateMachine-Playback faul holen: erst NACH dem Baum-Eintritt kann die -## Tree den "parameters/playback"-Parameter auflösen (vorher null). -func _playback_holen() -> AnimationNodeStateMachinePlayback: - if _playback == null and _tree != null: - _playback = _tree.get(P_PLAYBACK) as AnimationNodeStateMachinePlayback - return _playback - - -## Clip-Auflösung (1:1 bot_avatar._clip_for_state, ohne ENGAGE — Match-only). -func _clip_for_state(s: int) -> String: - match s: - STATE_IDLE: - return CLIP_IDLE - STATE_WALK: - return CLIP_WALK - STATE_JOG: - return CLIP_JOG - _: - return "" - - -## vc21: Welt-Richtung, in die das MESH blickt (Vertrag wie -## bot_avatar.model_forward: Front == Bewegungsrichtung). Hier wird die -## ECHTE Modell-Transform gemessen — der MODEL_YAW_OFFSET sitzt in diesem -## Spiegel auf dem Modell-Kind (nicht auf dem Node wie im Client), die -## Messung über _model.global_transform ist davon unabhängig korrekt. -func model_forward() -> Vector3: - if _model == null: - return Vector3(0.0, 0.0, -1.0) - var f: Vector3 = _model.global_transform.basis * MODEL_FORWARD_LOCAL - f.y = 0.0 - return f.normalized() - - -## Aktueller StateMachine-State ("" ohne Baum) — Tests/Debug. -func tree_state() -> String: - var playback := _playback_holen() - if playback == null: - return "" - return String(playback.get_current_node()) - - -## Soll-Clip des aktuellen States (wie bot_avatar.current_clip, ohne One-Shots). -func current_clip() -> String: - return _cur_clip - - -## AnimationTree aktiv? (Tests: "animiert überhaupt".) -func anim_running() -> bool: - return _tree != null and _tree.active - - -func _process(delta: float) -> void: - # vc21: Blend/Kadenz weich nachziehen (kein sichtbares Springen). - if _tree == null: - return - var k := clampf(delta / BLEND_SMOOTH_S, 0.0, 1.0) - _blend_cur = lerpf(_blend_cur, _blend_target, k) - _walk_scale_cur = lerpf(_walk_scale_cur, _walk_scale_target, k) - _jog_scale_cur = lerpf(_jog_scale_cur, _jog_scale_target, k) - _write_blend_params() - - -## vc21: geglätteten Stand in die Tree schreiben (nur bei Änderung). -func _write_blend_params() -> void: - if _tree == null: - return - if absf(float(_tree.get(P_BLEND)) - _blend_cur) > 0.0005: - _tree.set(P_BLEND, _blend_cur) - if absf(float(_tree.get(P_WALK_SCALE)) - _walk_scale_cur) > 0.0005: - _tree.set(P_WALK_SCALE, _walk_scale_cur) - if absf(float(_tree.get(P_JOG_SCALE)) - _jog_scale_cur) > 0.0005: - _tree.set(P_JOG_SCALE, _jog_scale_cur) diff --git a/src/editor/playtest/playtest_avatar.gd.uid b/src/editor/playtest/playtest_avatar.gd.uid deleted file mode 100644 index 4651d03..0000000 --- a/src/editor/playtest/playtest_avatar.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cvj6x35cenpbm diff --git a/src/editor/playtest/playtest_body.gd b/src/editor/playtest/playtest_body.gd deleted file mode 100644 index b365446..0000000 --- a/src/editor/playtest/playtest_body.gd +++ /dev/null @@ -1,581 +0,0 @@ -extends CharacterBody3D -class_name PlaytestBody -## Lauf-Modus Spieler (Karte t_1cdc1a72, Physik-Neubau t_1da96275): -## erste Person, WASD + Maus, Shift = rennen, Space = springen, Gravitation. -## -## ECHTE PHYSIK — identisch zum Quest-3-Client (Sly-Forderung 20.10.: -## „Die Möglichkeiten des Map Editors sollen ABSOLUT identisch mit der -## Quest-3-Version sein“). Dieser Body ist ein CharacterBody3D mit EXAKT -## denselben Parametern wie client/scripts/world/testmap_player.gd -## (TestmapPlayer): Kapsel 0.35 × 1.8, WALK/SPRINT/JUMP/GRAVITY, -## Step-Up 0.45 m nach move_and_slide (RayCast-Kanten-Abtastung, 1:1 -## gespiegelt inkl. Decken-Guard). Die Kollider kommen von KolliderBau -## (Spiegel von svmap_world.gd) — dieselben Trimeshe wie im Spiel. -## -## Der alte AABB-Blocking-Code (vorgecachte Kisten, eigener step()-Solver -## ohne Physik-Server) ist ENTFERNT — es gibt genau EINEN Bewegungscode, -## denselben wie auf der Quest. -## -## Steuerung: _physics_process pollt die Tasten (oder die Autopilot-Haken -## auto_move_dir/auto_jump/auto_run für Suiten und spätere Automatisierung) -## und fährt dieselbe Logik wie der Client. ESC wird NICHT hier gefangen: -## main.gd behandelt Esc VOR der normalen Esc-Kette, solange der Lauf-Modus -## aktiv ist („Esc = zurück zum Editor“). -## -## Koordinaten-Konvention (wie Client): Body-Ursprung = KAPSEL-MITTE, -## Kamera sitzt EYE_HEIGHT über der Mitte (TestmapPlayer.EYE_HEIGHT). - -signal exit_requested - -# --- Parameter 1:1 aus client/scripts/world/testmap_player.gd --------------- -const WALK_SPEED := 6.0 -const SPRINT_SPEED := 14.0 -const JUMP_SPEED := 4.5 -const GRAVITY := 9.8 -const EYE_HEIGHT := 0.65 # Kamera über der Kapsel-Mitte (Kapsel 1.8 m) -const KILL_Y_DROP_M := -200.0 # Notfall: unter die Welt gefallen → Respawn -const KAPSEL_RADIUS := 0.35 -const KAPSEL_HEIGHT := 1.8 -const HALF_H := 0.9 # Kapsel-Halbhöhe (Kapsel 1.8 m) — Füße = y − 0.9 -const STEP_HEIGHT := 0.45 # = TestmapPlayer.STEP_HEIGHT (Karte t_f9adf97c) -const STEP_PROBE_DIST := 0.7 -const STEP_LIFT_EPS := 0.02 - -# --- Editor-seitige Konventionen (unverändert gegenüber dem alten Body) ----- -const DEFAULT_MOUSE_SENS := 0.25 # Grad pro Pixel Mausbewegung -const PITCH_LIMIT := 89.0 # Kopfüber/Nackenschmerz-Grenze -const TELEPORT_REICHWEITE := 4000.0 - -## Spielbare Parameter -var mouse_sens: float = DEFAULT_MOUSE_SENS - -## Map-Dokument (nur LESEND — Terrain-Raster für Spawn/HUD/Notfall) -var doc: Dictionary = {} -## Fliegen / God-Mode (Karte t_aaff5dcc, Taste G): KEINE Gravitation, Bewegung -## in Blickrichtung (inkl. Nickwinkel), Space = steigen, Noclip — der Tester -## kommt auch über Wände/Hügel schnell ans Ziel. -var fly_mode := false -## Autopilot-Haken (wie TestmapPlayer.auto_move_dir, Karte t_f9adf97c): -## nicht-leer = DIESER Welt-Vektor ist der Bewegungswunsch (Tastatur aus). -var auto_move_dir := Vector3.ZERO -## Autopilot-Ergänzung für Suiten: Sprung/Run erzwingen ohne Tastatur. -var auto_jump := false -var auto_run := false -## Suite-Hook: nicht-leer = komplettes Input-Dictionary überschreibt ALLES -## (gleiche Form wie der alte step()-Input: fwd/back/left/right/run/jump). -var auto_input: Dictionary = {} - -## Bewegungszustand (Kompatibilität zur alten Oberfläche) -var yaw_deg: float = 0.0 # Gierwinkel Blickrichtung (Grad) -var pitch_deg: float = 0.0 # Nickwinkel Blickrichtung (Grad) -var on_floor: bool = false - -## Kinder: die Spiel-Kamera (Augen) — PlaytestMode hängt sie an und macht current -var look_cam: Camera3D - -## Höhenfeld-Cache (Zeile: res*res Meter) — von PlaytestMode via set_terrain() -## gefüllt (Spawn/HUD/jump_to_spawn; die PHYSIK läuft über den Trimesh-Kollider). -var heights: PackedFloat32Array = PackedFloat32Array() -var res: int = 0 -var size_x: float = 0.0 -var size_z: float = 0.0 -var hmin: float = 0.0 -var hmax: float = 0.0 - -var _spawn_pos := Vector3.ZERO - - -func _ready() -> void: - _spawn_pos = global_position - var cs := CollisionShape3D.new() - var capsule := CapsuleShape3D.new() - capsule.radius = KAPSEL_RADIUS - capsule.height = KAPSEL_HEIGHT - cs.shape = capsule - add_child(cs) - look_cam = Camera3D.new() - look_cam.name = "Camera" - look_cam.position.y = EYE_HEIGHT - look_cam.far = 4000.0 - add_child(look_cam) - look_cam.current = true - _baue_dritte_kamera() - _apply_look() - - -## Third-Person-Kamera (Karte t_17a35c59): SpringArm3D = RayCast hinter dem -## Spieler — die Kamera wird an die Kollision zurückgezogen (kein Clipping -## durch Wände). Pivot auf Augenhöhe, Arm-Länge 3,5 m + 0,3 m Margin, der -## eigene Body ist ausgeschlossen (sonst trifft der Strahl die eigene Kapsel). -func _baue_dritte_kamera() -> void: - spring = SpringArm3D.new() - spring.name = "ThirdPersonArm" - spring.position = Vector3(0.0, EYE_HEIGHT, 0.0) - spring.spring_length = 3.5 - spring.margin = 0.3 - spring.collision_mask = 1 - tpp_cam = Camera3D.new() - tpp_cam.name = "ThirdPersonCamera" - tpp_cam.far = 4000.0 - spring.add_child(tpp_cam) - add_child(spring) - spring.add_excluded_object(get_rid()) - tpp_cam.current = false - - -## Kinder: die Third-Person-Kamera (SpringArm + Kamera) — Karte t_17a35c59. -var spring: SpringArm3D = null -var tpp_cam: Camera3D = null - -## Playtest-Avatar (Spiegel des Bot-Rigs, playtest_avatar.gd). null = kein -## Client-Klon/Modell → Third Person bleibt gesperrt (graceful Fallback). -var avatar: Node3D = null - -## Perspektive (Taste V, persistiert in PlaytestSettings): false = First -## Person (Standard), true = Third Person (Avatar sichtbar, Kamera hinten). -var perspektive_dritte := false - - -## Blickrichtung auf Körper + Kameras übertragen. -## Der BODY rotiert mit dem Blick-Yaw (wie TestmapPlayer.rotate_y) — das -## trägt die Avatar-Front (Kind des Körpers) und die Third-Person-Kamera. -## Die WASD-Bewegung selbst folgt dem Yaw über _fahren (parallel gefixt in -## 52919b3, dort aus yaw_deg gebaut — beide Wege ergeben dieselbe Richtung). -## Vor beiden Fixes blieb der Body ungedreht (Beweis-Probe -## tests/probe_move_dir.gd: yaw −90° + W → −Z statt +X = weltachsen-fixiert). -func _apply_look() -> void: - # 1:1 TestmapPlayer: der BODY trägt den Yaw (rotate_y), die Kamera nur - # den Pitch — sonst doppelt sich die Drehung (Kamera hängt am Körper). - rotation.y = deg_to_rad(yaw_deg) - if look_cam == null: - return - look_cam.rotation = Vector3(deg_to_rad(pitch_deg), 0.0, 0.0) - look_cam.position = Vector3(0.0, EYE_HEIGHT, 0.0) - # Third Person: die SpringArm-Kamera teilt dieselbe Blickachse (Yaw über - # den Körper, Pitch über den Arm) — Blickrichtung == Kamerarichtung. - if spring != null: - spring.rotation = Vector3(deg_to_rad(pitch_deg), 0.0, 0.0) - - -## Füß-Höhe über der Welt (Kapsel-Mitte minus Halbhöhe) — HUD/Tests. -func fuss_hoehe() -> float: - return global_position.y - HALF_H - - -## Volle 3D-Blickrichtung (Karte t_aaff5dcc): -Z um Pitch (X) und Yaw (Y) -## gedreht — genau die Blickachse der Kamera. Fliegen bewegt entlang DIESEM -## Vektor (Blick nach unten = abwärts fliegen), Gehen nur horizontal. -func view_direction() -> Vector3: - var yaw_rad := deg_to_rad(yaw_deg) - var pitch_rad := deg_to_rad(pitch_deg) - return Vector3(-sin(yaw_rad) * cos(pitch_rad), sin(pitch_rad), - -cos(yaw_rad) * cos(pitch_rad)) - - -## Echter Physics-Step: Input zusammenbauen (Tasten ODER Autopilot) → fahren. -func _physics_process(delta: float) -> void: - var input := {} - if not auto_input.is_empty(): - input = auto_input - else: - input = { - "fwd": Input.is_key_pressed(KEY_W), - "back": Input.is_key_pressed(KEY_S), - "left": Input.is_key_pressed(KEY_A), - "right": Input.is_key_pressed(KEY_D), - "run": Input.is_key_pressed(KEY_SHIFT) or auto_run, - "jump": Input.is_key_pressed(KEY_SPACE) or auto_jump, - } - if auto_move_dir.length_squared() > 0.0: - input["auto_dir"] = auto_move_dir - _fahren(delta, input) - - -## Ein Bewegungs-Schritt (physics frame) mit EXPLIZITEM Input ausführen. -## input = {fwd, back, left, right, run, jump: bool, auto_dir: Vector3}. -## DIESE Methode ist 1:1 die _physics_process des TestmapPlayers — -## identische Bewegungsmathe, identische Step-Up-Aufrufreihenfolge. -func _fahren(delta: float, input: Dictionary) -> void: - # --- Fliegen / God-Mode (Karte t_aaff5dcc, Taste G) ---------------------- - # Keine Gravitation, Bewegung in der VOLLEN Blickrichtung, Space = steigen, - # Noclip (direkt positionieren — kein move_and_slide, kein Kollider). - if fly_mode: - var fly_speed := WALK_SPEED if not bool(input.get("run", false)) else SPRINT_SPEED - var fly_yaw_rad := deg_to_rad(yaw_deg) - var fly_right := Vector3(cos(fly_yaw_rad), 0.0, -sin(fly_yaw_rad)) - var wish3: Vector3 - var ad: Variant = input.get("auto_dir", null) - if ad is Vector3 and (ad as Vector3).length_squared() > 0.0: - wish3 = (ad as Vector3).normalized() * fly_speed - else: - wish3 = view_direction() * (1.0 if bool(input.get("fwd", false)) else 0.0) \ - - view_direction() * (1.0 if bool(input.get("back", false)) else 0.0) \ - + fly_right * (1.0 if bool(input.get("right", false)) else 0.0) \ - - fly_right * (1.0 if bool(input.get("left", false)) else 0.0) - if bool(input.get("jump", false)): - wish3 += Vector3.UP - if wish3.length_squared() > 0.0: - wish3 = wish3.normalized() * fly_speed - velocity = wish3 - position += velocity * delta - on_floor = false - _apply_look() - return - - # Welt-Richtung aus dem Blickwinkel (y-only, wie Client). WICHTIG: aus - # yaw_deg bauen, NICHT aus transform.basis (Sly-Befund 20.10.: WASD lief - # sonst stur in eine Himmelsrichtung). Seit t_17a35c59 rotiert der - # Körperknoten ZUSÄTZLICH mit dem Yaw (_apply_look — Avatar-Front und - # Third-Person-Kamera hängen daran); die Bewegung bleibt bewusst an - # yaw_deg gekoppelt — beide Wege führen auf dieselbe Richtung, die - # Entkopplung hält die Bewegung unabhängig vom Avatar-Zustand. - # Identisch zu view_direction(). - var yaw_rad := deg_to_rad(yaw_deg) - var forward := Vector3(-sin(yaw_rad), 0.0, -cos(yaw_rad)) - var right := Vector3(cos(yaw_rad), 0.0, -sin(yaw_rad)) - var dir := Vector3.ZERO - var ad2: Variant = input.get("auto_dir", null) - if ad2 is Vector3 and (ad2 as Vector3).length_squared() > 0.0: - dir = ad2 as Vector3 - else: - if bool(input.get("fwd", false)): - dir += forward - if bool(input.get("back", false)): - dir -= forward - if bool(input.get("right", false)): - dir += right - if bool(input.get("left", false)): - dir -= right - var speed := SPRINT_SPEED if bool(input.get("run", false)) else WALK_SPEED - if dir.length_squared() > 0.0: - dir = dir.normalized() * speed - velocity.x = dir.x - velocity.z = dir.z - if is_on_floor() and bool(input.get("jump", false)): - velocity.y = JUMP_SPEED - if not is_on_floor(): - velocity.y -= GRAVITY * delta - var pre_pos := global_position - move_and_slide() - # Stufen-Hilfe (Karte t_f9adf97c, 1:1 aus TestmapPlayer): nach - # move_and_slide() prüfen, ob die horizontale Bewegung von einer Wand - # gestoppt wurde, während der Wunsch weiter in die Wand zeigt. - var wish_xz := Vector3(dir.x, 0.0, dir.z) - var blocked := false - if wish_xz.length_squared() > 0.0001: - if is_on_wall() and get_wall_normal().dot(wish_xz.normalized()) < -0.1: - blocked = true - else: - var got := global_position - pre_pos - got.y = 0.0 - var want := wish_xz * delta - if got.length() < want.length() * 0.4: - blocked = true - if blocked: - try_step_up(wish_xz) - if global_position.y < KILL_Y_DROP_M: - # Sicherheitsnetz (sollte mit Trimesh-Terrain nicht passieren). - global_position = _spawn_pos - velocity = Vector3.ZERO - on_floor = is_on_floor() - _apply_look() - - -## ------------------------------------------------------------------ -## Stufen-Hilfe — 1:1 aus client/scripts/world/testmap_player.gd -## (Karte t_f9adf97c): Stufen bis STEP_HEIGHT erklimmen. Nach -## move_and_slide(), wenn die horizontale Bewegung von einer Wand gestoppt -## wurde UND der Bewegungswunsch in die Wand zeigt: -## Ray 1 (Fußhöhe vorwärts) → Wand-/Kanten-Fläche finden, -## Ray 2 (Kopfhöhe vorwärts) → Wand überragt die Stufenhöhe? → blockt, -## Ray 3 (über der Kante abwärts) → neue Standfläche messen, -## Decken-Strahl → Platz für die Kapsel über der Stufe? -## ------------------------------------------------------------------ -func _capsule_half_height() -> float: - for child in get_children(): - var cs := child as CollisionShape3D - if cs != null and cs.shape is CapsuleShape3D: - return (cs.shape as CapsuleShape3D).height * 0.5 - return 0.9 - - -func try_step_up(wish: Vector3) -> bool: - var dir := Vector3(wish.x, 0.0, wish.z) - if not is_on_floor() or dir.length_squared() < 0.0001: - return false - dir = dir.normalized() - var space := get_world_3d().direct_space_state - if space == null: - return false - var half_h := _capsule_half_height() - var feet := global_position.y - half_h - var mask := collision_mask # nur die Welt tasten, nicht den eigenen Körper - var exclude: Array[RID] = [get_rid()] - - # Ray 1: vorwärts in Knöchelhöhe — gibt es überhaupt eine Stufe/Wand? - var ankle := global_position + Vector3(0.0, -half_h + 0.05, 0.0) - var q1 := PhysicsRayQueryParameters3D.create( - ankle + dir * 0.1, ankle + dir * STEP_PROBE_DIST, mask, exclude) - var hit1 := space.intersect_ray(q1) - if hit1.is_empty(): - return false - if (hit1["normal"] as Vector3).dot(dir) > -0.3: - return false # Fläche zeigt nicht gegen die Laufrichtung (Rampe/Kante) - - # Ray 2: vorwärts knapp ÜBER der maximalen Stufenhöhe — trifft er die - # Wand noch, ist sie höher als STEP_HEIGHT → kein Anheben. - var top_probe := global_position + Vector3(0.0, -half_h + STEP_HEIGHT + 0.01, 0.0) - var q2 := PhysicsRayQueryParameters3D.create( - top_probe + dir * 0.1, top_probe + dir * STEP_PROBE_DIST, mask, exclude) - if not space.intersect_ray(q2).is_empty(): - return false # Wand überragt die Stufenhöhe - - # Ray 3: über der Kante abwärts — neue Standfläche messen (Startpunkt - # liegt über Ray 2 frei, also außerhalb der Wand). - var edge := (hit1["position"] as Vector3) + dir * 0.1 - var q3 := PhysicsRayQueryParameters3D.create( - Vector3(edge.x, feet + STEP_HEIGHT + 0.05, edge.z), - Vector3(edge.x, feet - 0.05, edge.z), mask, exclude) - var hit3 := space.intersect_ray(q3) - if hit3.is_empty(): - return false - var new_feet := (hit3["position"] as Vector3).y - if new_feet < feet - 0.01: # Abgrund statt Fläche? Nichts anheben. - return false - var diff := new_feet - feet - if diff > STEP_HEIGHT + 0.005 or diff <= 0.0: - return false - if (hit3["normal"] as Vector3).y < 0.5: - return false # keine begehbare Fläche (Decke/Schräge von unten) - - # Decken-Check: Platz für die volle Kapselhöhe über der neuen Standfläche? - # An der Ziel-XZ prüfen (etwas vorwärts — dort landt die Kapsel nach dem - # Schritt), sonst entgeht die Terrassen-Decke über dem Stufenkopf. - var check := global_position + dir * 0.45 - var q4 := PhysicsRayQueryParameters3D.create( - Vector3(check.x, new_feet + 0.05, check.z), - Vector3(check.x, new_feet + half_h * 2.0 + 0.05, check.z), - mask, exclude) - if not space.intersect_ray(q4).is_empty(): - return false # Decke zu tief (z. B. Terrassen-Untersicht): unten bleiben - - # Sanftes Anheben: Positions-Snap auf die neue Standfläche … - global_position.y = new_feet + half_h + STEP_LIFT_EPS - # … und Bewegung fortführen: der zweite move_and_slide()-Schritt trägt - # die Kapsel VOR die Kante auf die neue Stufe (sonst steht sie nur - # tangential auf der Kante und fällt zurück). - move_and_slide() - return true - - -## Maus-Bewegung (nur der Spieler selbst fängt sie — die Editor-Werkzeuge -## sind im Lauf-Modus eingefroren). -func _unhandled_input(event: InputEvent) -> void: - if event is InputEventMouseMotion: - var mm := event as InputEventMouseMotion - yaw_deg = wrapf(yaw_deg - mm.relative.x * mouse_sens, -180.0, 180.0) - pitch_deg = clampf(pitch_deg - mm.relative.y * mouse_sens, - -PITCH_LIMIT, PITCH_LIMIT) - _apply_look() - get_viewport().set_input_as_handled() - - -## ESC-Request — wird von main.gd angerufen (die Esc-Priorität gehört dort -## hin, damit die normale Esc-Kette NICHT auch noch zieht). -func request_exit() -> void: - exit_requested.emit() - - -## Terrain-Raster EINMALIG aus dem Dokument dekodieren (R16/LE/Base64 → -## Meter-Array). Nutzt den Standard-Decoder SvmapIO.decode_heights (derselbe -## Code wie beim Editor-Rendering) — nichts neu rechnen. Die PHYSIK läuft -## über den Trimesh-Kollider (KolliderBau.terrain_form, identisch zum -## Client); dieses Raster dient Spawn/jump_to_spawn/HUD-Referenz. -func set_terrain(d: Dictionary) -> void: - doc = d - heights = PackedFloat32Array() - res = 0 - size_x = 0.0 - size_z = 0.0 - hmin = 0.0 - hmax = 0.0 - if d.is_empty(): - return - var terrain: Dictionary = d.get("terrain", {}) - res = int(terrain.get("resolution", 0)) - size_x = float(terrain.get("size_x_m", 0.0)) - size_z = float(terrain.get("size_z_m", 0.0)) - hmin = float(terrain.get("min_height_m", 0.0)) - hmax = float(terrain.get("max_height_m", 0.0)) - if res < 2 or size_x <= 0.0 or size_z <= 0.0: - return - var decoded: PackedFloat32Array = SvmapIO.decode_heights(terrain) - if decoded.size() < res * res: - return - heights = decoded - - -## Teleport zum Punkt unter dem Fadenkreuz (Karte t_96e3c4ee, Taste T im -## Testlauf): Strahl aus dem Auge gegen die ECHTE Physik-Welt (Trimesh- -## Terrain + Objekt-/Bauteil-Kollider — dieselben Flächen wie im Spiel). -## Gelandet wird auf dem Boden DARUNTER (Strahl senkrecht abwärts). Nie im -## Objekt landen: ist die Kapsel am Zielpunkt nicht frei, wird der Teleport -## abgelehnt (ok=false). Rückgabe: {ok, x, z, ground, msg}. -func teleport_to_ground(origin: Vector3, dir: Vector3) -> Dictionary: - var space := get_world_3d().direct_space_state - if space == null: - return {"ok": false, "x": 0.0, "z": 0.0, "ground": 0.0, - "msg": "Kein Boden unterm Fadenkreuz — hier kann der Test-Start nicht hin."} - var d := dir - if d.length_squared() > 0.000000001: - d = d.normalized() - var q := PhysicsRayQueryParameters3D.create(origin, origin + d * TELEPORT_REICHWEITE) - q.exclude = [get_rid()] - var hit := space.intersect_ray(q) - if hit.is_empty(): - return {"ok": false, "x": 0.0, "z": 0.0, "ground": 0.0, - "msg": "Kein Boden unterm Fadenkreuz — hier kann der Test-Start nicht hin."} - var ziel := hit["position"] as Vector3 - # Boden DARUNTER: senkrechter Strahl ab etwas über dem Treffer — trifft - # er nichts (Treffer war eine Wandfläche ohne Boden drunter), Terrain- - # Raster als Rückfallebene. - var ground := ziel.y - var q2 := PhysicsRayQueryParameters3D.create( - Vector3(ziel.x, ziel.y + 0.5, ziel.z), - Vector3(ziel.x, ziel.y - 50.0, ziel.z)) - q2.exclude = [get_rid()] - var hit2 := space.intersect_ray(q2) - if hit2.is_empty(): - ground = terrain_height(ziel.x, ziel.z) - else: - ground = (hit2["position"] as Vector3).y - var tx := ziel.x - var tz := ziel.z - # Landeplatz prüfen: passt die Kapsel dort frei? (Nie im Objekt landen.) - var probe := CapsuleShape3D.new() - probe.radius = KAPSEL_RADIUS - probe.height = KAPSEL_HEIGHT - var qp := PhysicsShapeQueryParameters3D.new() - qp.shape = probe - qp.transform = Transform3D(Basis.IDENTITY, - Vector3(tx, ground + HALF_H + 0.02, tz)) - qp.exclude = [get_rid()] - if not space.intersect_shape(qp, 1).is_empty(): - return {"ok": false, "x": tx, "z": tz, "ground": ground, - "msg": "Da steht etwas im Weg (%.1f, %.1f) — dort kannst du nicht landen." % [tx, tz]} - position = Vector3(tx, ground + HALF_H + 0.02, tz) - velocity = Vector3.ZERO - on_floor = true - _apply_look() - return {"ok": true, "x": tx, "z": tz, "ground": ground, "msg": ""} - - -## Terrain-Höhe an Welt-X/Z — aus dem DOCUMENT-Raster (nichts neu rechnen). -## Referenz für Spawn/jump_to_spawn/HUD; die Physik nutzt den Trimesh. -func terrain_height(x: float, z: float) -> float: - if res < 2 or size_x <= 0.0 or size_z <= 0.0: - return hmin - if heights.size() < res * res: - return hmin - var last := float(res - 1) - var fx := clampf((x / size_x + 0.5) * last, 0.0, last) - var fz := clampf((z / size_z + 0.5) * last, 0.0, last) - var xi := int(floor(fx)) - var zi := int(floor(fz)) - var tx := fx - float(xi) - var tz := fz - float(zi) - var xi1 := mini(xi + 1, res - 1) - var zi1 := mini(zi + 1, res - 1) - var h00 := _sample(xi, zi) - var h10 := _sample(xi1, zi) - var h01 := _sample(xi, zi1) - var h11 := _sample(xi1, zi1) - return lerpf(lerpf(h00, h10, tx), lerpf(h01, h11, tx), tz) - - -func _sample(xi: int, zi: int) -> float: - var idx := zi * res + xi - if idx < 0 or idx >= heights.size(): - return hmin - return heights[idx] - - -## Maus-Empfindlichkeit als Multiplikator setzen (Karte t_aaff5dcc, 0,1–5,0, -## Standard 1,0): die Body-Basis (DEFAULT_MOUSE_SENS Grad/Pixel) wird mit dem -## Multiplikator skaliert — jede PC/Maus-Kombination ist anders. -func set_sensitivity(mult: float) -> void: - var m := clampf(mult, PlaytestSettings.MIN_SENS, PlaytestSettings.MAX_SENS) - mouse_sens = DEFAULT_MOUSE_SENS * m - - -# ------------------------------------------ Avatar + Perspektive (V) ------- -# Karte t_17a35c59: derselbe Avatar wie die Bots im Spiel (Spiegel-Modul -# playtest_avatar.gd, GLB aus dem Nachbar-Klon), umschaltbar First/Third. - -## Avatar (aus PlaytestAvatar.lade_avatar) anhängen. Anker: Kopf-Anker- -## Konvention des Clients (bot_avatar.gd) — Avatar-Node in Augenhöhe -## (MODEL_EYE_HEIGHT 1,65 m) über dem Füßpunkt, GLB-Kind hängt mit -## MODEL_Y_OFFSET nach unten. null = kein Modell (Third bleibt gesperrt). -func set_avatar(node: Node3D) -> void: - if avatar != null and is_instance_valid(avatar): - avatar.queue_free() - avatar = node - if avatar == null: - perspektive_dritte = false - _apply_perspektive() - return - # add_child reparentet NICHT — ein Node mit altem Parent würde still - # abgelehnt (Probe 20.10.: Avatar blieb unter root). Erst lösen, dann - # als Kind anhängen. - if avatar.get_parent() != null: - avatar.get_parent().remove_child(avatar) - add_child(avatar) - avatar.position = Vector3(0.0, - PlaytestAvatar.MODEL_EYE_HEIGHT - HALF_H, 0.0) - # Start-Zustand sauber in den Baum schreiben (apply_state vor add_child - # könnte Tree-Parameter noch nicht flushen). - avatar.call("apply_state", PlaytestAvatar.STATE_IDLE, 0.0) - _apply_perspektive() - - -## Taste V: Perspektive umschalten. Rückgabe: neuer Zustand (true = Third). -## Ohne Avatar bleibt First Person aktiv (graceful Fallback — Meldung macht -## der Aufrufer/PlaytestMode). -func toggle_perspektive() -> bool: - var neu := not perspektive_dritte - if avatar == null: - neu = false - return set_perspektive(neu) - - -## Perspektive direkt setzen (Enter-Pfad liest PlaytestSettings). Rückgabe: -## der tatsächlich aktive Zustand (ohne Avatar nie Third). -func set_perspektive(dritte: bool) -> bool: - if avatar == null: - dritte = false - perspektive_dritte = dritte - _apply_perspektive() - return perspektive_dritte - - -## Sichtbarkeit + aktive Kamera je Perspektive: -## First Person — Avatar unsichtbar (Kapsel bleibt physisch aktiv, -## Kamera auf Augenhöhe wie Client-TestmapPlayer), -## Third Person — Avatar sichtbar, SpringArm-Kamera hinter/über dem -## Spieler mit Wand-Kollision (kein Clipping). -func _apply_perspektive() -> void: - if avatar != null and is_instance_valid(avatar): - avatar.visible = perspektive_dritte - if look_cam != null: - look_cam.current = not perspektive_dritte - if tpp_cam != null: - tpp_cam.current = perspektive_dritte - - -## Echte horizontale Geschwindigkeit (m/s) aus dem letzten Physik-Schritt — -## Quelle für die Avatar-Gait-Speisung (Stillstand/Walk/Jog aus der realen -## Bewegung, nicht aus dem Input-Wunsch). -func horizontale_geschwindigkeit() -> float: - var v := velocity - v.y = 0.0 - return v.length() diff --git a/src/editor/playtest/playtest_body.gd.uid b/src/editor/playtest/playtest_body.gd.uid deleted file mode 100644 index 035ed25..0000000 --- a/src/editor/playtest/playtest_body.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://csv8o2g8wdtue diff --git a/src/editor/playtest/playtest_mode.gd b/src/editor/playtest/playtest_mode.gd deleted file mode 100644 index ade88d2..0000000 --- a/src/editor/playtest/playtest_mode.gd +++ /dev/null @@ -1,536 +0,0 @@ -extends Node -## Lauf-Modus (Karte t_1cdc1a72): erste Person IM Map-Builder selbst — -## kein Client-Ordner, kein zweiter Prozess, kein VR/OpenXR, kein Server. -## -## Verantwortung dieses Zustands: -## - Beim Start: die map_view_builder-Ausgabe (Modelle + Pack-Texturen) -## 1:1 weiterverwenden (der Node3D-Baum bleibt stehen, nur Editor-UI/Input -## geht weg), Maus-Capture-Wunsch setzen, Panels ausblenden. -## - Kollider-Bau via KolliderBau (core/svmap/kollider_bau.gd — 1:1-Spiegel -## des Quest-Clients, Karte t_1da96275): Terrain-Trimesh + Objekt-Kollider -## (box/kugel/zylinder/verbund/trimesh inkl. library/kollisions-Quellen) -## + Bauteil-Trimeshe (bau_*-Objekte: Treppen/Türen/Wände begehbar -## wie echte Geometrie). -## - PlaytestBody (CharacterBody3D, IDENTISCHE Parameter wie der -## Testmap-Spieler inkl. Step-Up 0.45 m) anlegen, Terrain-Raster EINMAL -## dekodieren, Start = erster Spawnpunkt (Team Blau), sonst Kartenmitte. -## - ESC → exit_requested → main.gd stellt den Editor-Zustand 1:1 wieder her -## (Panels, Maus, Kamera, Auswahl, Dokument, Undo-Stapel unverändert). -## - HUD (Position, FPS, „ESC = zurück zum Editor") als CanvasLayer-Overlay. -## -## Bewusst KEIN _physics_process hier: alle Bewegung/Eingabe lebt im -## PlaytestBody; dieser Zustand managed nur Lifecycle + HUD. - -const BODY_SCRIPT := "res://src/editor/playtest/playtest_body.gd" -const KOLLIDER_SCRIPT := "res://core/svmap/kollider_bau.gd" -const AVATAR_SCRIPT := "res://src/editor/playtest/playtest_avatar.gd" - -## Der laufende Spieler (PlaytestBody, CharacterBody3D mit echter Physik) -var body: Node3D = null -## Welt-Kollider (Terrain + Objekte + Bauteile) — Kind dieses Modus, -## wird mit exit() abgeräumt. -var _kollider_root: Node3D = null - -## Editor-UI-Verweise (vom main.gd-Handler gesetzt): die Panels, die -## AUSGEBLENDET werden sollen (Variant statt Control-Typ — keine UI-Kopie). -var ui_panels: Array = [] # Array[Control] -var ui_status: Variant = null # Statuszeilen-Label (nur visible umschalten) -var help_label: Variant = null # Hilfe-Label (nur visible umschalten) - -## Maus-Capture-Wunsch (Suite testet diesen Zustand) -var _want_capture := false -## HUD-Elemente -var hud: CanvasLayer = null -var hud_pos: Label = null -var hud_fps: Label = null -var hud_hint: Label = null -var hud_msg: Label = null # Klartext-Nachricht (z. B. Test-Start via T) -var hud_dir: Label = null # Blickrichtung + Höhe (Karte t_aaff5dcc) -## Hilfe-Overlay (F1, Karte t_aaff5dcc): alle Tasten im Klartext. -var help_layer: CanvasLayer = null -## Kartenmitte/Achsen-Linien (Taste X, Karte t_aaff5dcc — praktisch beim -## gespiegelten Bauen, Karte M1): X-Rot/Z-Blau/Y-Grün durch die Kartenmitte. -var _axis_node: Node3D = null -## FPS-Smoothing (Anzeige, keine Physik) -var _fps_smooth := 0.0 -## Ist der Lauf-Modus gerade aktiv? (Reentrancy-Schutz für enter/exit) -var active := false -## Avatar-Modelle waren beim Start verfügbar? (Karte t_17a35c59 — ohne -## Client-Klon bleibt Third Person gesperrt, graceful Fallback.) -var _avatar_da := false - -signal exit_requested - - -## Starten: übernimmt die Sicht (Panels aus, Maus-Capture-Wunsch an) und -## legt den Spieler am Startpunkt an. Fallback-Reihenfolge (Karte t_96e3c4ee, -## je mit Klartext-Hinweis): gesetzter Test-Start (start_override) → erster -## Spawnpunkt (Team Blau) → Kartenmitte. start_override = Vector3 (nur x/z -## zählen, Höhe kommt automatisch vom Terrain) oder null (= altes Verhalten). -## view_builder = der map_view_builder-Node (Marker-Tree mit pick_radius/ -## half_height-Metas bleibt stehen und liefert die Hindernis-Blöcke). -func enter(doc: Dictionary, view_builder: Node3D, start_override: Variant = null) -> void: - if active: - return - active = true - _set_ui_visible(false) - _set_status_capture(true) - - body = load(BODY_SCRIPT).new() - body.call("set_terrain", doc) - var start := _spawn_start(doc) - if start_override != null: - var sp := start_override as Vector3 - start = Vector3(sp.x, 0.0, sp.z) - # Spawn AUF der Terrainhöhe: Kapsel-Mitte = Füße + Halbhöhe (+ Toleranz, - # die Physik lässt den Body sanft auf den Trimesh fallen — wie im Spiel). - body.position = Vector3(start.x, - body.terrain_height(start.x, start.z) + PlaytestBody.HALF_H + 0.05, - start.z) - if start_override == null: - var first := _first_spawn(doc) - if first.has(SpawnOps.YAW_KEY): - body.yaw_deg = float(first[SpawnOps.YAW_KEY]) - # Kollider 1:1 vom Quest-Client (Karte t_1da96275): Terrain-Trimesh + - # Objekt-Kollider aus der Registry + Bauteil-Trimeshe. Alles als Kind - # dieses Modus — exit() räumt es mit ab. - _baue_kollider(doc) - add_child(body) - # Maus-Empfindlichkeit aus den Einstellungen (Karte t_aaff5dcc): der - # gespeicherte Multiplikator (0,1–5,0) skaliert die Body-Basis. - body.call("set_sensitivity", PlaytestSettings.load_sens()) - - # Playtest-Avatar (Karte t_17a35c59): derselbe Rig wie die Bots im Spiel - # (GLB aus dem Nachbar-Klon ../scopedvr-client). Fehlt der Klon/Modell: - # graceful — First Person bleibt, Third Person wird per Meldung gesperrt. - var avatar: Node3D = load(AVATAR_SCRIPT).call("lade_avatar") as Node3D - _avatar_da = avatar != null - if _avatar_da: - body.call("set_avatar", avatar) - # Persistierte Perspektive (Taste V): Third nur mit Avatar — sonst - # First Person wie bisher + Klartext-Hinweis. - if PlaytestSettings.load_third(): - if _avatar_da: - body.call("set_perspektive", true) - else: - show_message("Gespeicherte Third-Person-Einstellung ist ohne Avatar-Modelle nicht verfügbar (Client-Klon ../scopedvr-client fehlt) — First Person aktiv.") - - _build_hud() - exit_requested.connect(_on_exit_requested, CONNECT_ONE_SHOT) - - -## Zurück in den Editor: HUD weg, Spieler weg, Panels sichtbar. -## Editor-Zustand (Kamera, Auswahl, Dokument, Undo-Stapel) wird NICHT hier -## angefasst — das macht main.gd nach dem Signal. -func exit() -> void: - if not active: - return - active = false - _set_status_capture(false) - _set_ui_visible(true) - if body != null: - body.queue_free() - body = null - if _kollider_root != null: - _kollider_root.queue_free() - _kollider_root = null - if hud != null: - hud.queue_free() - hud = null - if help_layer != null: - help_layer.queue_free() - help_layer = null - if _axis_node != null: - _axis_node.queue_free() - _axis_node = null - - -func _on_exit_requested() -> void: - exit() - - -## Status/Maus-Capture-Wunsch: nur der Zustand (Suite testet wants_capture). -func _set_status_capture(want: bool) -> void: - _want_capture = want - - -## Panelselemente ausblenden/einblenden. Nur die als ui_panels übergebenen -## Controls werden angefasst — keine weiteren. -func _set_ui_visible(vis: bool) -> void: - for p in ui_panels: - if p is Control: - (p as Control).visible = vis - if ui_status is Control: - (ui_status as Control).visible = vis - if help_label is Control: - (help_label as Control).visible = vis - - -## Start-Punkt: erster Spawn-Punkt aus dem Dokument (spawn_zones-Team „0", -## erster Eintrag der points-Liste); sonst Kartenmitte aus den Bounds. -## doc-Format (svmap): {"spawn_zones": {"0": {"points": [{"id", "pos": [x,y,z]}]}, ...}} -func _first_spawn(doc: Dictionary) -> Dictionary: - var team0 = (doc.get("spawn_zones", {}) as Dictionary).get("0", {}) - if team0 is Dictionary: - var points: Array = (team0 as Dictionary).get("points", []) - if not points.is_empty() and points[0] is Dictionary: - return points[0] - return {} - - -func _spawn_start(doc: Dictionary) -> Vector3: - var zones: Dictionary = doc.get("spawn_zones", {}) - var team0 = zones.get("0", {}) - if team0 is Dictionary: - var points: Array = (team0 as Dictionary).get("points", []) - if not points.is_empty() and points[0] is Dictionary: - var pos = (points[0] as Dictionary).get("pos", []) - if pos is Array and (pos as Array).size() >= 3: - return Vector3(float(pos[0]), 0.0, float(pos[2])) - var bounds: Dictionary = doc.get("bounds", {}) - var mn: Array = bounds.get("min", [-50.0, -10.0, -50.0]) - var mx: Array = bounds.get("max", [50.0, 80.0, 50.0]) - return Vector3((float(mn[0]) + float(mx[0])) * 0.5, 0.0, - (float(mn[2]) + float(mx[2])) * 0.5) - - -## Echter Kollider-Bau (Karte t_1da96275 — „Editor-Playtest-Physik = Quest 3 -## identisch"): der alte AABB-Blocking-Code ist ENTFERNT. Es gibt genau EINEN -## Kollider-Pfad, denselben wie der Quest-Client: -## - Terrain + Registry-Objekte: KolliderBau.baue_welt_kollider (1:1-Spiegel -## von svmap_world.gd — box/kugel/zylinder/verbund/trimesh inkl. -## library/kollisions-Quelldateien). -## - Bauteile (bau_*) sind normale Registry-Objekte mit Trimesh aus -## library/kollisions — Türen/Fenster bleiben Durchgänge, Treppen begehbar. -func _baue_kollider(doc: Dictionary) -> void: - var kb := load(KOLLIDER_SCRIPT) - _kollider_root = kb.call("baue_welt_kollider", doc) - add_child(_kollider_root) - - -# ------------------------------------------------------------------- HUD ---- - -func _build_hud() -> void: - hud = CanvasLayer.new() - hud.layer = 100 - var margin := MarginContainer.new() - margin.add_theme_constant_override("margin_left", 16) - margin.add_theme_constant_override("margin_top", 16) - margin.set_anchors_preset(Control.PRESET_TOP_LEFT) - hud.add_child(margin) - var vbox := VBoxContainer.new() - margin.add_child(vbox) - hud_pos = Label.new() - hud_fps = Label.new() - hud_hint = Label.new() - hud_msg = Label.new() - hud_dir = Label.new() - hud_hint.text = "WASD + Maus · Shift = rennen · Space = springen/steigen · G = Fliegen · V = 1./3.-Person · 1-4 = Spawnpunkt · T = Test-Start · H = HUD · X = Achsen · F1 = Hilfe · ESC = zurück zum Editor" - hud_msg.text = "" - for l: Label in [hud_pos, hud_dir, hud_fps, hud_hint, hud_msg]: - l.add_theme_font_size_override("font_size", 16) - l.add_theme_color_override("font_color", Color(0.55, 0.8, 1.0)) - vbox.add_child(l) - add_child(hud) - - -## Klartext-Nachricht im HUD (die Editor-Statuszeile ist im Lauf-Modus -## ausgeblendet — hier landet das Feedback für Taste T, Karte t_96e3c4ee). -func show_message(text: String) -> void: - if hud_msg != null and is_instance_valid(hud_msg): - hud_msg.text = text - - -## Taste T im Testlauf (Karte t_96e3c4ee, „jederzeit“): setzt den Test-Start -## auf den Punkt unterm Fadenkreuz und versetzt den Spieler SOFORT dorthin -## (Augenhöhe 1,70 m via look_cam-Offset, Kollision geprüft — nie in Objekten). -## Das Speichern (Sidecar) + Marker-Update macht main.gd mit der Rückgabe. -## Rückgabe: {ok, x, z, ground, msg} aus PlaytestBody.teleport_to_ground. -func teleport_crosshair() -> Dictionary: - if not active or body == null or body.look_cam == null: - return {"ok": false, "x": 0.0, "z": 0.0, "ground": 0.0, "msg": ""} - var vp: Viewport = body.look_cam.get_viewport() - var center: Vector2 = (vp.get_visible_rect().size if vp != null else Vector2(800, 600)) * 0.5 - var origin: Vector3 = body.look_cam.project_ray_origin(center) - var dir: Vector3 = body.look_cam.project_ray_normal(center) - var res: Dictionary = body.call("teleport_to_ground", origin, dir) - if bool(res.get("ok")): - show_message("Test-Start gesetzt: x=%.0f z=%.0f — du bist jetzt dort (Höhe automatisch)." % [ - float(res.get("x")), float(res.get("z"))]) - else: - show_message(str(res.get("msg", ""))) - return res - - -func _process(delta: float) -> void: - if not active or body == null: - return - _speise_avatar() - # FPS glätten (Anzeige-Genauigkeit, keine Physik-Betroffenheit) - if _fps_smooth <= 0.0: - _fps_smooth = 1.0 / maxf(delta, 0.0001) - else: - _fps_smooth = lerpf(_fps_smooth, 1.0 / maxf(delta, 0.0001), 0.1) - if hud_pos != null: - hud_pos.text = "Pos: %.1f, %.1f, %.1f" % [body.position.x, body.position.y, body.position.z] - if hud_dir != null: - # Höhe = FUSSPUNKT (Kapsel-Mitte minus Halbhöhe) — direkt vergleichbar - # mit der Terrainhöhe unter den Füßen (Karte t_1da96275). - hud_dir.text = "Blick: %.0f° / %.0f° · Höhe: %.1f m" % [ - float(body.get("yaw_deg")), float(body.get("pitch_deg")), - body.position.y - PlaytestBody.HALF_H] - if hud_fps != null: - hud_fps.text = "FPS: %d" % int(round(_fps_smooth)) - - -## Maus-Capture-Wunsch für die Suite/Debug sichtbar machen. -func wants_capture() -> bool: - return _want_capture - - -## ESC → Signal an main.gd (die Esc-Priorität gehört in main.gd, damit die -## normale Esc-Kette im Editor-Modus unangetastet bleibt). -func handle_escape() -> void: - if active and body != null: - exit_requested.emit() - - -# ------------------------------------------------- Komfort (t_aaff5dcc) ----- - -## Tasten im Lauf-Modus (Karte t_aaff5dcc): G = Fliegen/God-Mode, 1–4 = -## Sprung zu Spawnpunkt, H = HUD an/aus, F1 = Hilfe, X = Achsen. ESC/T bleiben -## bewusst bei main.gd (Esc-Kette + Test-Start-Vertrag). Die Editor-Tasten -## sind im Lauf-Modus eingefroren (main gibt hier nichts anderes durch). -func _unhandled_input(event: InputEvent) -> void: - if not active or body == null: - return - var key_evt := event as InputEventKey - if key_evt == null or not key_evt.is_pressed() or key_evt.echo: - return - var key := key_evt.keycode - var handled := true - match key: - KEY_G: - toggle_fly() - KEY_V: - toggle_perspektive() - KEY_1: - jump_to_spawn(1) - KEY_2: - jump_to_spawn(2) - KEY_3: - jump_to_spawn(3) - KEY_4: - jump_to_spawn(4) - KEY_H: - toggle_hud() - KEY_F1: - toggle_help() - KEY_X: - toggle_axis() - _: - handled = false - if handled: - get_viewport().set_input_as_handled() - - -## Empfindlichkeit live setzen (aus dem Einstellungen-Panel, Registry-Weg — -## main.gd bleibt unangetastet). mult = Multiplikator 0,1–5,0. -func apply_sensitivity(mult: float) -> void: - if body != null: - body.call("set_sensitivity", mult) - - -## Taste V (Karte t_17a35c59): First/Third-Person umschalten. Der neue -## Zustand wird persistiert (PlaytestSettings, wirksam über Neustarts). -## Ohne Avatar-Modelle (kein Client-Klon ../scopedvr-client) bleibt First -## Person aktiv und der Grund steht im HUD — kein Crash (graceful Fallback). -func toggle_perspektive() -> bool: - if body == null: - return false - var neu: bool = body.call("toggle_perspektive") - if not _avatar_da: - show_message("Kein Avatar-Modell gefunden (Client-Klon ../scopedvr-client fehlt) — Third Person nicht verfügbar.") - return false - PlaytestSettings.save_third(neu) - if neu: - show_message("Dritte Person AN — derselbe Avatar wie die Bots im Spiel. V = zurück zur ersten Person.") - else: - show_message("Erste Person AN (Standard). V = dritte Person.") - return neu - - -## Avatar-Gait aus der ECHTEN Bewegung speisen (Kartenvorgabe: Stillstand/ -## Walk/Jog aus der tatsächlichen Geschwindigkeit, Blickrichtung == -## Bewegungsrichtung über die Body-Rotation). Jeden Frame — die Kadenz- -## Mathe des Avatars glättet selbst (BLEND_SMOOTH_S, wie die Bots). -func _speise_avatar() -> void: - if body == null: - return - var av: Node3D = body.get("avatar") as Node3D - if av == null or not is_instance_valid(av): - return - var speed: float = body.call("horizontale_geschwindigkeit") - av.call("apply_state", PlaytestAvatar.zustand_fuer(speed), speed) - - -## Fliegen / God-Mode umschalten (Taste G). Rückgabe: neuer Zustand. -func toggle_fly() -> bool: - if body == null: - return false - var new_state: bool = not bool(body.get("fly_mode")) - body.set("fly_mode", new_state) - body.set("velocity", Vector3.ZERO) # kein Fall-Übernehmen aus dem Gang - if new_state: - show_message("Fliegen AN (God-Mode): keine Gravitation — Blickrichtung fliegen, Space = steigen, G = aus.") - else: - show_message("Fliegen AUS — wieder mit Gravitation.") - return new_state - - -## Spawnpunkt-Punkt für Taste index (1 = Team A/Zone 0, 2 = Team B/Zone 1, -## 3/4 = weitere Zonen 2/3): erster Punkt der Zone. Rückgabe {} = keine Zone. -## pos = [x,y,z] aus dem Dokument. -func _spawn_point_for(index: int) -> Dictionary: - if body == null: - return {} - var zones: Dictionary = (body.get("doc") as Dictionary).get("spawn_zones", {}) - var zone: Variant = zones.get(str(index - 1)) - if not (zone is Dictionary): - return {} - var points: Array = (zone as Dictionary).get("points", []) - if points.is_empty() or not (points[0] is Dictionary): - return {} - var p := points[0] as Dictionary - var pos: Array = p.get("pos", []) - if pos.size() < 3: - return {} - return {"pos": Vector3(float(pos[0]), float(pos[1]), float(pos[2])), - "label": str((zone as Dictionary).get("label", "Zone %d" % index)), - "yaw": p.get(SpawnOps.YAW_KEY, null)} - - -## Sprung zu einem Spawnpunkt (Tasten 1–4): exakt auf den Punkt gesetzt -## (x/z aus dem Dokument, Höhe vom Terrain — dieselbe Konvention wie der -## Lauf-Modus-Start). Rückgabe true = gelandet. -func jump_to_spawn(index: int) -> bool: - var sp := _spawn_point_for(index) - if sp.is_empty() or body == null: - show_message("Kein Spawnpunkt für Taste %d — die Karte hat diese Zone nicht." % index) - return false - var target: Vector3 = sp["pos"] - var y: float = body.terrain_height(target.x, target.z) - # Kapsel-Mitte = Füße + Halbhöhe (+ Toleranz) — die Physik lässt den Body - # sanft auf den Trimesh fallen (wie beim Start, Karte t_1da96275). - body.set("position", Vector3(target.x, y + PlaytestBody.HALF_H + 0.02, target.z)) - body.set("velocity", Vector3.ZERO) - body.set("on_floor", true) - if sp["yaw"] != null: - body.set("yaw_deg", float(sp["yaw"])) - show_message("Spawnpunkt %d = %s: x=%.1f z=%.1f (Höhe %.1f) — Blickrichtung steht im HUD." % [ - index, str(sp["label"]), target.x, target.z, y]) - return true - - -## HUD (Position/Blick/FPS/Hinweis) an/aus (Taste H). Rückgabe: sichtbar? -func toggle_hud() -> bool: - if hud == null: - return false - hud.visible = not hud.visible - if hud.visible: - show_message("HUD an.") # aus: Meldung wäre selbst unsichtbar - return hud.visible - - -## Hilfe-Overlay an/aus (Taste F1). Rückgabe: sichtbar? -func toggle_help() -> bool: - if help_layer == null: - _build_help() - help_layer.visible = not help_layer.visible - return help_layer.visible - - -## Kartenmitte/Achsen-Linien an/aus (Taste X). Rückgabe: sichtbar? -func toggle_axis() -> bool: - if _axis_node == null: - _build_axis() - _axis_node.visible = not _axis_node.visible - if _axis_node.visible: - show_message("Kartenmitte/Achsen AN (X = aus): X-Rot, Z-Blau, Mitte Grün.") - else: - show_message("Kartenmitte/Achsen AUS.") - return _axis_node.visible - - -## Hilfe-Overlay (F1): Panel mit allen Tasten im Klartext, mittig unten. -func _build_help() -> void: - help_layer = CanvasLayer.new() - help_layer.layer = 101 - var center := CenterContainer.new() - center.set_anchors_preset(Control.PRESET_FULL_RECT) - center.mouse_filter = Control.MOUSE_FILTER_IGNORE - help_layer.add_child(center) - var panel := PanelContainer.new() - center.add_child(panel) - var margin := MarginContainer.new() - margin.add_theme_constant_override("margin_left", 16) - margin.add_theme_constant_override("margin_right", 16) - margin.add_theme_constant_override("margin_top", 12) - margin.add_theme_constant_override("margin_bottom", 12) - panel.add_child(margin) - var label := Label.new() - label.text = "TESTLAUF — ALLE TASTEN -WASD — bewegen · Maus — umsehen -Shift — rennen · Space — springen / im Flug steigen -G — Fliegen (God-Mode) an/aus: keine Gravitation, Blickrichtung fliegen -V — Perspektive umschalten (erste / dritte Person) -1 — Sprung zu Team A (Spawnpunkt) · 2 — Team B -3 / 4 — weitere Spawnpunkte (Zonen 2/3) -T — Test-Start auf den Blickpunkt setzen (sofort dort) -H — HUD an/aus (Position, Blick, FPS, Höhe) -X — Kartenmitte/Achsen ein/aus (X-Rot, Z-Blau) -F1 — diese Hilfe · ESC — zurück zum Editor" - label.add_theme_font_size_override("font_size", 18) - margin.add_child(label) - add_child(help_layer) - help_layer.visible = false - - -## Achsen-Linien durch die Kartenmitte (Taste X): X-Achse rot, Z-Achse blau, -## senkrechte Mitte grün — beim gespiegelten Bauen (M1) auf einen Blick. -func _build_axis() -> void: - var doc: Dictionary = (body.get("doc") if body != null else {}) as Dictionary - var bounds: Dictionary = doc.get("bounds", {}) - var mn: Array = bounds.get("min", [-50.0, -10.0, -50.0]) - var mx: Array = bounds.get("max", [50.0, 80.0, 50.0]) - var cx := (float(mn[0]) + float(mx[0])) * 0.5 - var cz := (float(mn[2]) + float(mx[2])) * 0.5 - var y0: float = body.terrain_height(cx, cz) if body != null else 0.0 - var mesh := ImmediateMesh.new() - mesh.surface_begin(Mesh.PRIMITIVE_LINES) - # X-Achse (rot): ganze Kartenbreite durch die Mitte. - mesh.surface_set_color(Color(1.0, 0.25, 0.25)) - mesh.surface_add_vertex(Vector3(float(mn[0]), y0, cz)) - mesh.surface_add_vertex(Vector3(float(mx[0]), y0, cz)) - # Z-Achse (blau): ganze Kartentiefe durch die Mitte. - mesh.surface_set_color(Color(0.3, 0.5, 1.0)) - mesh.surface_add_vertex(Vector3(cx, y0, float(mn[2]))) - mesh.surface_add_vertex(Vector3(cx, y0, float(mx[2]))) - # Senkrechte Mitte (grün): vom Terrain bis zur oberen Grenze. - mesh.surface_set_color(Color(0.3, 1.0, 0.4)) - mesh.surface_add_vertex(Vector3(cx, y0, cz)) - mesh.surface_add_vertex(Vector3(cx, float(mx[1]), cz)) - mesh.surface_end() - var mi := MeshInstance3D.new() - mi.name = "PlaytestAchsen" - mi.mesh = mesh - # Vertexfarben sichtbar machen: unshaded + vertex_color_use_as_albedo - # (ohne das ignoriert der Default-Material-Shader die Linien-Farben). - var mat := StandardMaterial3D.new() - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.vertex_color_use_as_albedo = true - mat.no_fog = true - mi.material_override = mat - mi.position = Vector3.ZERO - _axis_node = mi - add_child(_axis_node) diff --git a/src/editor/playtest/playtest_mode.gd.uid b/src/editor/playtest/playtest_mode.gd.uid deleted file mode 100644 index 76bf77a..0000000 --- a/src/editor/playtest/playtest_mode.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://spymwdq2qcvr diff --git a/src/editor/playtest/playtest_settings.gd b/src/editor/playtest/playtest_settings.gd deleted file mode 100644 index f7b5360..0000000 --- a/src/editor/playtest/playtest_settings.gd +++ /dev/null @@ -1,84 +0,0 @@ -extends RefCounted -class_name PlaytestSettings -## Einstellungen-Speicher für den Lauf-Modus (Karte t_aaff5dcc, T3 Komfort) — -## bewusst NICHT im .svmap-Format und NICHT in main.gd: der Operator hat für -## Einstellungen den Registry-Weg vorgegeben (Panel meldet sich in -## src/ui/panels/registry.gd an), der Zustand lebt HIER als statischer Store. -## -## Ablage: user://scopedvr_playtest.cfg, Abschnitt [playtest]. -## Wert: Maus-Empfindlichkeit als Multiplikator (0,1–5,0, Standard 1,0) auf -## die Body-Basis 0,25 Grad/Pixel — jede PC/Maus-Kombination ist anders. -## -## Statischer Cache: ein Lese-Vorgang pro Editor-Start; save_sens() hält den -## Cache frisch. Tests können mit reset_cache() neu laden erzwingen. - -const CFG_PATH := "user://scopedvr_playtest.cfg" -const SECTION := "playtest" -const KEY_SENS := "maus_empfindlichkeit" -const DEFAULT_SENS := 1.0 -const MIN_SENS := 0.1 -const MAX_SENS := 5.0 -## Perspektive im Testlauf (Karte t_17a35c59, Taste V): false = First Person -## (Standard, wie bisher), true = Third Person (Avatar sichtbar). -const KEY_THIRD := "dritte_person" - -## Cache (null = noch nicht gelesen). static var ist Godot 4.1+. -static var _cache: Variant = null -## Cache für den Perspektive-Eintrag (null = noch nicht gelesen). -static var _cache_third: Variant = null - - -## Gespeicherte Empfindlichkeit lesen (geclampt auf 0,1–5,0), Standard 1,0. -static func load_sens() -> float: - if _cache != null: - return float(_cache) - var cfg := ConfigFile.new() - var raw: Variant = DEFAULT_SENS - if cfg.load(CFG_PATH) == OK: - raw = cfg.get_value(SECTION, KEY_SENS, DEFAULT_SENS) - var val := clampf(float(raw), MIN_SENS, MAX_SENS) - _cache = val - return val - - -## Empfindlichkeit speichern (geclampt auf 0,1–5,0) und Cache frisch halten. -## Rückgabe: der tatsächlich gespeicherte Wert. -static func save_sens(value: float) -> float: - var val := clampf(value, MIN_SENS, MAX_SENS) - var cfg := ConfigFile.new() - cfg.load(CFG_PATH) # Fehler → leere Config, nur unser Key wird angelegt. - cfg.set_value(SECTION, KEY_SENS, val) - cfg.save(CFG_PATH) - _cache = val - return val - - -## Gespeicherte Perspektive lesen (Karte t_17a35c59): true = Third Person. -## Default FALSE = First Person — der Testlauf startet so wie bisher. -static func load_third() -> bool: - if _cache_third != null: - return bool(_cache_third) - var cfg := ConfigFile.new() - var raw: Variant = false - if cfg.load(CFG_PATH) == OK: - raw = cfg.get_value(SECTION, KEY_THIRD, false) - var val := bool(raw) - _cache_third = val - return val - - -## Perspektive speichern (persistiert über Editor-Neustarts) und Cache frisch -## halten. Rückgabe: der tatsächlich gespeicherte Wert. -static func save_third(value: bool) -> bool: - var cfg := ConfigFile.new() - cfg.load(CFG_PATH) # Fehler → leere Config, nur unser Key wird angelegt. - cfg.set_value(SECTION, KEY_THIRD, value) - cfg.save(CFG_PATH) - _cache_third = value - return value - - -## Cache verwerfen (für Tests / frisches Neulesen von der Platte). -static func reset_cache() -> void: - _cache = null - _cache_third = null diff --git a/src/editor/playtest/playtest_settings.gd.uid b/src/editor/playtest/playtest_settings.gd.uid deleted file mode 100644 index 8751c34..0000000 --- a/src/editor/playtest/playtest_settings.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://1m7xfphtjvwd diff --git a/src/editor/playtest/test_start.gd b/src/editor/playtest/test_start.gd deleted file mode 100644 index 0918428..0000000 --- a/src/editor/playtest/test_start.gd +++ /dev/null @@ -1,92 +0,0 @@ -extends RefCounted -class_name TestStart -## Test-Startpunkt (Karte t_96e3c4ee): der Punkt, an dem „▶ Karte testen“ (F5) -## den Spieler absetzt — KEIN Spiel-Spawnpunkt (taucht nicht in doc, -## Spawn-Checks/Analysen oder Validator auf, ändert keine Zonen). -## -## Bewusste Entscheidungen dieser Karte: -## - Der Punkt lebt NUR editor-seitig (Sidecar, test_start_store.gd) — das -## .svmap-Format (Validator V1–V16, Client/Server) bleibt UNBERÜHRT. -## - Gespeichert wird nur x/z. Die Höhe kommt IMMER automatisch aus dem -## Terrain an der Stelle (SvmapDocument.terrain_height_at) — Terrain -## formen lässt den Punkt nicht schweben und versinken. -## - Fallback-Reihenfolge F5 (je mit Klartext-Hinweis): gesetzter Test-Start -## → erster Team-Spawnpunkt (Team Blau, wie bisher) → Kartenmitte. -## - Trifft der Klick ein Objekt/Bauteil: landet der Punkt auf dem BODEN -## DARUNTER (nie im Objekt schwebend) — das Tool meldet es im Klartext. -## -## Alles pure Statics (kein UI, kein Node-Zugriff) → headless testbar in -## tests/test_playtest_spawn.gd. - -## Kein Punkt gesetzt (Sentinel-Typ für Variant-Vergleiche in main.gd). - -## Start-Punkt für den Testlauf auflösen (Fallback-Kette). test_point ist -## Vector3 (nur x/z zählen) oder null. Rückgabe: -## {pos: Vector3 (y = Terrainhöhe), quelle: "test"|"team"|"mitte", -## status: Klartext für die Statuszeile} -static func resolve_start(doc: Dictionary, test_point: Variant) -> Dictionary: - if test_point != null: - var p: Vector3 = test_point - var y := SvmapDocument.terrain_height_at(doc, p.x, p.z) - return { - "pos": Vector3(p.x, y, p.z), - "quelle": "test", - "status": "Start an deinem gesetzten Test-Startpunkt (%.0f, %.0f, Höhe automatisch)." % [p.x, p.z], - } - # Erster Team-Spawnpunkt (Team Blau = „0“) — exakt wie bisher (t_1cdc1a72). - var zones: Dictionary = doc.get("spawn_zones", {}) - var team0 = zones.get("0", {}) - if team0 is Dictionary: - var points: Array = (team0 as Dictionary).get("points", []) - if not points.is_empty() and points[0] is Dictionary: - var pos = (points[0] as Dictionary).get("pos", []) - if pos is Array and (pos as Array).size() >= 3: - return { - "pos": Vector3(float(pos[0]), float(pos[1]), float(pos[2])), - "quelle": "team", - "status": "Kein Test-Start gesetzt — Start am ersten Team-Blau-Spawnpunkt.", - } - # Kartenmitte aus den Bounds. - var bounds: Dictionary = doc.get("bounds", {}) - var mn: Array = bounds.get("min", [-50.0, -10.0, -50.0]) - var mx: Array = bounds.get("max", [50.0, 80.0, 50.0]) - var cx := (float(mn[0]) + float(mx[0])) * 0.5 - var cz := (float(mn[2]) + float(mx[2])) * 0.5 - return { - "pos": Vector3(cx, SvmapDocument.terrain_height_at(doc, cx, cz), cz), - "quelle": "mitte", - "status": "Weder Test-Start noch Team-Spawnpunkte — Start in der Kartenmitte.", - } - - -## Strahl → erster Treffer auf einer AABB (Slab-Methode) oder -1.0. -## Für „Klick trifft Bauteil“ im Editor-Tool und „Fadenkreuz trifft Hindernis“ -## im Testlauf (kein Physik-Server im Editor/SubViewport). -## Rückgabe: Distanz t >= 0 (origin + dir * t) oder -1.0 = kein Treffer. -static func ray_aabb(origin: Vector3, dir: Vector3, box: AABB) -> float: - var d := dir - if d.length_squared() < 0.000000001: - return -1.0 - d = d.normalized() - var tmin := 0.0 - var tmax := INF - for axis in 3: - var o := origin[axis] - var dv := d[axis] - var lo := box.position[axis] - var hi := box.end[axis] - if absf(dv) < 0.0000001: - if o < lo or o > hi: - return -1.0 - continue - var t1 := (lo - o) / dv - var t2 := (hi - o) / dv - if t1 > t2: - var tmp := t1 - t1 = t2 - t2 = tmp - tmin = maxf(tmin, t1) - tmax = minf(tmax, t2) - if tmin > tmax: - return -1.0 - return tmin diff --git a/src/editor/playtest/test_start.gd.uid b/src/editor/playtest/test_start.gd.uid deleted file mode 100644 index 2a04600..0000000 --- a/src/editor/playtest/test_start.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b4barijsv6qs2 diff --git a/src/editor/playtest/test_start_store.gd b/src/editor/playtest/test_start_store.gd deleted file mode 100644 index 6023828..0000000 --- a/src/editor/playtest/test_start_store.gd +++ /dev/null @@ -1,64 +0,0 @@ -extends RefCounted -class_name TestStartStore -## Sidecar-Speicher für den Test-Startpunkt (Karte t_96e3c4ee) — bewusst -## NICHT im .svmap-Format (Validator V1–V16 + Client/Server bleiben unberührt; -## eine Map ohne den Punkt verhält sich exakt wie bisher). -## -## Ablage: user://scopedvr_teststart.cfg, Abschnitt [test_start], je Kartenpfad -## ein Schlüssel (globalisierter Pfad). Ungespeicherte Maps landen unter dem -## Sammel-Schlüssel UNGESPEICHERT (Session-Speicher über Neustarts hinaus nur, -## wenn die Map gespeichert wird — der Punkt wandert beim Speichern mit). -## Gespeichert werden nur x/z: die Höhe kommt immer automatisch vom Terrain. - -const CFG_PATH := "user://scopedvr_teststart.cfg" -const SECTION := "test_start" -const UNGESPEICHERT := "__ungespeichert__" - - -## Schlüssel für einen Kartenpfad (leer = ungespeicherte Map). -static func key_for(map_path: String) -> String: - if map_path.is_empty(): - return UNGESPEICHERT - return ProjectSettings.globalize_path(map_path) - - -## Gespeicherten Punkt lesen (Vector3 mit y=0 — Höhe kommt vom Terrain) -## oder null, wenn keiner gesetzt ist. -static func load_point(map_path: String) -> Variant: - var cfg := ConfigFile.new() - if cfg.load(CFG_PATH) != OK: - return null - var k := key_for(map_path) - var x: Variant = cfg.get_value(SECTION, k + "/x", null) - var z: Variant = cfg.get_value(SECTION, k + "/z", null) - if x == null or z == null: - return null - return Vector3(float(x), 0.0, float(z)) - - -## Punkt speichern (nur x/z — Höhe automatisch). -static func save_point(map_path: String, pos: Vector3) -> void: - var cfg := ConfigFile.new() - cfg.load(CFG_PATH) # Fehler → leere Config, Punkt wird neu angelegt. - var k := key_for(map_path) - cfg.set_value(SECTION, k + "/x", pos.x) - cfg.set_value(SECTION, k + "/z", pos.z) - cfg.save(CFG_PATH) - - -## Punkt löschen (Datei bleibt — andere Maps sind unberührt). -## Bewusst Sektions-Neuaufbau statt erase_section_key: Godots -## erase_section_key löscht Keys mit "/" im Namen still NICHT (Probe 20.10.). -static func clear_point(map_path: String) -> void: - var cfg := ConfigFile.new() - if cfg.load(CFG_PATH) != OK: - return - var k := key_for(map_path) - var keep := {} - for key in cfg.get_section_keys(SECTION): - if not key.begins_with(k + "/"): - keep[key] = cfg.get_value(SECTION, key) - cfg.erase_section(SECTION) - for key in keep: - cfg.set_value(SECTION, key, keep[key]) - cfg.save(CFG_PATH) diff --git a/src/editor/playtest/test_start_store.gd.uid b/src/editor/playtest/test_start_store.gd.uid deleted file mode 100644 index 6109a49..0000000 --- a/src/editor/playtest/test_start_store.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b3gc8f1aecsjl diff --git a/src/editor/playtest/test_start_tool.gd b/src/editor/playtest/test_start_tool.gd deleted file mode 100644 index 702c1ff..0000000 --- a/src/editor/playtest/test_start_tool.gd +++ /dev/null @@ -1,253 +0,0 @@ -extends Node3D -## Test-Startpunkt-Werkzeug (Karte t_96e3c4ee): „hinklicken, wo man beim -## Testen spawnt“ — ein Klick auf Boden/Terrain setzt den Test-Startpunkt. -## KEIN Spiel-Spawnpunkt: der Punkt lebt NICHT im .svmap (Sidecar via -## TestStartStore), taucht in keinem Spawn-Check/Keiner Analyse auf und hat -## KEINEN Undo-Eintrag (editor-seitiger Session-Zustand, wie die UI-Größe). -## -## Bedienung (Einbindung in main.gd, wie T1 den Lauf-Modus angemeldet hat): -## Toolbar-Knopf „🎯 Test-Start“ oder Taste T → Werkzeug an -## Linksklick auf den Boden → Test-Start setzen (Höhe automatisch) -## Linksklick auf Objekt/Bauteil → Punkt auf den Boden DARUNTER (Klartext- -## Hinweis: „auf dem Boden unter dem Objekt“) -## Entf (im Werkzeug) / „Löschen“-Knopf rechts → Test-Start löschen -## ESC → Werkzeug beenden -## Rechte Maustaste: bewusst NICHT behandelt — sie gehört dem Freelook-Flug -## (Karte t_2470de89, absolute Priorität wie in jedem anderen Werkzeug). -## -## Marker (schmale Säule + Ring, Editor-Akzentfarbe) bleibt sichtbar, solange -## ein Punkt gesetzt ist — auch außerhalb des Werkzeugs. Vorschau-Ring folgt -## dem Cursor nur IM Werkzeug (wie der Spawn-Zonen-Ghost). - -## Editor-Akzentfarbe (wie Statuszeile/Kurzhilfe in main.gd) — „Farbe aus dem -## Theme“ laut Karte; dieselbe Konstante, keine neue Farbwelt. -const ACCENT := Color(0.55, 0.8, 1.0) - -var main # Hauptfenster (script-erweitert, Variant) -var camera: Camera3D -var view_builder # Welt-Bauer (script-erweitert, Variant) -var interaction # Objekt-Interaktion (für Objekt-Treffer-Test, nur LESEND) - -var active := false - -# Terrain-Cache für Cursor-Raycast (nur LESEN — dieses Werkzeug formt nichts) -var _heights := PackedFloat32Array() -var _res := 0 -var _sx := 0.0 -var _sz := 0.0 - -var _ghost: Node3D -var _marker: Node3D -var _cursor_valid := false -var _cursor := Vector3.ZERO - - -func setup(p_main, p_camera: Camera3D, p_builder, p_interaction) -> void: - main = p_main - camera = p_camera - view_builder = p_builder - interaction = p_interaction - _ensure_ghost() - _ensure_marker() - - -# ------------------------------------------------------------ Aktivierung --- - -func activate() -> bool: - active = true - refresh_from_doc() - return true # nie verweigert — der Test-Start braucht kein Auflösungs-Limit - - -func deactivate() -> void: - active = false - _cursor_valid = false - if _ghost != null and is_instance_valid(_ghost): - _ghost.visible = false - - -## Nach Laden/Neu/Speichern (Pfadwechsel → anderer Sidecar-Schlüssel) und -## nach Terrain-Änderungen: Cache + Marker aus main.test_start_point frisch. -func refresh_from_doc() -> void: - var terrain: Dictionary = main.doc.get("terrain", {}) - _res = int(terrain.get("resolution", 0)) - _sx = float(terrain.get("size_x_m", 0.0)) - _sz = float(terrain.get("size_z_m", 0.0)) - if _res >= 2 and _sx > 0.0 and _sz > 0.0: - _heights = SvmapIO.decode_heights(terrain) - else: - _heights = PackedFloat32Array() - _update_marker() - - -# --------------------------------------------------------------- Eingaben --- - -func _unhandled_input(event: InputEvent) -> void: - var p := MousePointer.from_input(event) - if p != null and handle_pointer(p): - get_viewport().set_input_as_handled() - - -func handle_pointer(p: PointerEvent) -> bool: - if not active: - return false - if p.kind == PointerEvent.Kind.MOVE: - _update_cursor(p.position) - elif p.kind == PointerEvent.Kind.PRESS: - _click(p.position) - return true - return false - - -func _click(viewport_pos: Vector2) -> void: - # 1) Objekt-Treffer? (Kugel-Approx der interaction — derselbe Pfad wie die - # Auswahl; bewusst nur GERUFEN, interaction.gd bleibt unangetastet.) - var obj_idx: Variant = interaction.call("_pick_object", viewport_pos) - var hit_obj := false - if obj_idx is int and int(obj_idx) >= 0: - hit_obj = true - # 3) Punkt setzen: x/z vom Strahl-Treffer, Höhe IMMER vom Terrain (nie - # im Objekt schwebend, nie versunken). - var hit: Variant = _ray_hit(viewport_pos) - if hit == null: - main.call("_set_status", "Da war kein Boden unter dem Mauszeiger — klicke IN die Karte (die grüne Fläche).", true) - return - var p: Vector3 = _clamped(hit as Vector3) - var hinweis := "" - if hit_obj: - hinweis = "auf dem Boden unter dem Objekt" - main.call("_test_start_apply", p.x, p.z, hinweis) - - -func _update_cursor(viewport_pos: Vector2) -> void: - var hit: Variant = _ray_hit(viewport_pos) - if hit == null: - _cursor_valid = false - if _ghost != null and is_instance_valid(_ghost): - _ghost.visible = false - return - _cursor_valid = true - _cursor = _clamped(hit as Vector3) - if _ghost != null and is_instance_valid(_ghost): - _ghost.position = Vector3(_cursor.x, _cursor.y + 0.06, _cursor.z) - _ghost.visible = true - - -## Strahl → Punkt auf dem Terrain (wie Terrain-/Spawn-Werkzeug; -## TerrainField.raycast — favorisiert echte Geländeberührung). -func _ray_hit(viewport_pos: Vector2) -> Variant: - if _res >= 2 and _heights.size() >= _res * _res: - return TerrainField.raycast(_heights, _res, _sx, _sz, - camera.project_ray_origin(viewport_pos), camera.project_ray_normal(viewport_pos)) - var terrain: Dictionary = main.doc.get("terrain", {}) - if terrain.is_empty(): - return null - var plane_y := float(terrain.get("min_height_m", 0.0)) - var origin := camera.project_ray_origin(viewport_pos) - var dir := camera.project_ray_normal(viewport_pos) - if absf(dir.y) < 0.0001: - return null - var t := (plane_y - origin.y) / dir.y - if t <= 0.0: - return null - return origin + dir * t - - -func _clamped(p: Vector3) -> Vector3: - var half := Vector2(_sx, _sz) * 0.5 - p.x = clampf(p.x, -half.x, half.x) - p.z = clampf(p.z, -half.y, half.y) - p.y = SvmapDocument.terrain_height_at(main.doc, p.x, p.z) - return p - - -# ----------------------------------------------------------------- Marker --- - -## Marker an den gesetzten Punkt hängen (oder ausblenden). Höhe IMMER -## automatisch: Terrainhöhe an (x, z) — nach Terrain-Formen bleibt der -## Punkt auf dem Boden (kein Schweben, kein Versinken). -func _update_marker() -> void: - _ensure_marker() - var point: Variant = main.get("test_start_point") - if point == null: - _marker.visible = false - return - var p: Vector3 = point - p.y = SvmapDocument.terrain_height_at(main.doc, p.x, p.z) - _marker.position = p - _marker.visible = true - - -# ------------------------------------------------------- Optik (Ghost/Marker) -- - -func _accent_mat(alpha: float) -> StandardMaterial3D: - var mat := StandardMaterial3D.new() - mat.albedo_color = Color(ACCENT.r, ACCENT.g, ACCENT.b, alpha) - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.emission_enabled = true - mat.emission = ACCENT * 0.35 - return mat - - -func _ensure_ghost() -> void: - if _ghost != null and is_instance_valid(_ghost): - return - _ghost = Node3D.new() - _ghost.visible = false - add_child(_ghost) - var ring := MeshInstance3D.new() - var torus := TorusMesh.new() - torus.inner_radius = 0.65 - torus.outer_radius = 0.85 - torus.rings = 48 - torus.ring_segments = 6 - ring.mesh = torus - ring.position.y = 0.05 - ring.material_override = _accent_mat(0.6) - _ghost.add_child(ring) - - -## Marker: schmale Säule + Ring am Boden (Karten-Vorgabe), Akzentfarbe. -func _ensure_marker() -> void: - if _marker != null and is_instance_valid(_marker): - return - _marker = Node3D.new() - _marker.visible = false - add_child(_marker) - var pillar := MeshInstance3D.new() - var cyl := CylinderMesh.new() - cyl.top_radius = 0.12 - cyl.bottom_radius = 0.12 - cyl.height = 4.0 - pillar.mesh = cyl - pillar.position.y = 2.0 # Fußpunkt auf dem Terrain - pillar.material_override = _accent_mat(0.55) - _marker.add_child(pillar) - var ring := MeshInstance3D.new() - var torus := TorusMesh.new() - torus.inner_radius = 0.55 - torus.outer_radius = 0.75 - torus.rings = 48 - torus.ring_segments = 6 - ring.mesh = torus - ring.position.y = 0.05 - ring.material_override = _accent_mat(0.85) - _marker.add_child(ring) - - -# ------------------------------------------------------------ Demo/Tests ---- - -## Demo-Hook (Suite/Renderprobe): Punkt programmatisch setzen — macht exakt, -## was ein Klick machen würde (ohne echte Maus-Ereignisse). hinweis = derselbe -## Klartext wie beim echten Klick ("" = freier Boden, sonst „unter dem Objekt“). -func demo_set(x: float, z: float, hinweis := "") -> void: - main.call("_test_start_apply", x, z, hinweis) - - -## Demo-Hook: Ghost an Position parken (Renderprobe ohne Maus). -func demo_park_ghost(x: float, z: float) -> void: - _cursor = _clamped(Vector3(x, 0.0, z)) - _cursor_valid = true - _ghost.position = Vector3(_cursor.x, _cursor.y + 0.06, _cursor.z) - _ghost.visible = true diff --git a/src/editor/playtest/test_start_tool.gd.uid b/src/editor/playtest/test_start_tool.gd.uid deleted file mode 100644 index 228ca33..0000000 --- a/src/editor/playtest/test_start_tool.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://byjsw857bu1k8 diff --git a/src/editor/pointer_router.gd b/src/editor/pointer_router.gd deleted file mode 100644 index 782764b..0000000 --- a/src/editor/pointer_router.gd +++ /dev/null @@ -1,13 +0,0 @@ -class_name PointerRouter -extends RefCounted -## Gibt eine Zeige-Eingabe in derselben Reihenfolge an die Werkzeuge wie Godot -## die Maus: tiefer und später im Baum zuerst, das erste Werkzeug nimmt sie. -## Für Eingaben, die nicht über den Viewport kommen, also den VR-Controller. - - -static func dispatch(main: Node, p: PointerEvent) -> bool: - for key in ["test_start_tool", "spawn_tool", "terrain_tool", "gizmo", "interaction"]: - var werkzeug: Variant = main.get(key) - if werkzeug != null and bool(werkzeug.call("handle_pointer", p)): - return true - return false diff --git a/src/editor/pointer_router.gd.uid b/src/editor/pointer_router.gd.uid deleted file mode 100644 index 445bba9..0000000 --- a/src/editor/pointer_router.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bem4edb2s282 diff --git a/src/editor/shortcut_keys.gd b/src/editor/shortcut_keys.gd deleted file mode 100644 index 5327530..0000000 --- a/src/editor/shortcut_keys.gd +++ /dev/null @@ -1,121 +0,0 @@ -extends RefCounted -class_name ShortcutKeys -## InputMap-Actions der Editor-Tastatur-Shortcuts (Karte t_c46d31c2, Karte 1/3). -## -## Konvention (alle Shortcut-Karten): Tastaturcode-basiert — JEDER Action wird -## ein InputEventKey mit PHYSICAL keycode zugewiesen (KEY_*-Konstante). Die -## physische Taste liegt unabhängig vom Tastaturlayout an derselben Position -## (QWERTZ wie QWERTY bei W/A/S/D/Leertaste/Shift), damit deutsche und -## Windows-Tastaturen identisch bedienen — keine OS-Hardcodes (PLAN.md -## Plattform-Regel). -## -## Registrierung per Code statt project.godot: KEY_*-Konstanten bleiben im -## Quelltext lesbar und der Test kann exakt dieselben Konstanten prüfen. -## register() ist idempotent (mehrfacher Aufruf = keine Doppel-Events). - -## Action → Liste von Events. Einträge: -## KEY_X = einfache physische Taste -## {"key": KEY_X, "shift": true} = Taste + Modifier (z. B. Umschalt+F) -const ACTIONS := { - # --- Freelook-Flug (Rechte Maustaste halten bzw. Umschalt+F) ------------- - "editor_freelook_toggle": [{"key": KEY_F, "shift": true}], - "editor_freelook": [MOUSE_BUTTON_RIGHT], - "editor_fly_forward": [KEY_W], - "editor_fly_back": [KEY_S], - "editor_fly_left": [KEY_A], - "editor_fly_right": [KEY_D], - # Flug-Vertikal + Tempo (Shooter-Konvention, Sly-Wunsch 17.10.): - # Leertaste = hoch, Shift = runter (Half-Life/CS-Konvention), Strg halten = - # temporär schneller, Alt halten = langsamer. Mausrad bleibt Grundtempo. - # Konflikt-Freiheit: Leertaste/Shift/Strg SIND im Editor sonst nur als - # Modifier-Kombos belegt (Strg+Z, Umschalt+Klick …) — allein gedrückt - # triggern sie KEINE Werkzeug-Aktion (Tests: test_shortcuts.gd, - # Konflikt-Gruppe). Im Flugmodus gibt der Kamera-Einstieg den GUI-Fokus - # frei (orbit_camera._enter_fly), damit Leertaste keinen fokussierten - # Button auslöst. - "editor_fly_up": [KEY_SPACE], - "editor_fly_down": [KEY_SHIFT], - "editor_fly_fast": [KEY_CTRL], - "editor_fly_slow": [KEY_ALT], - # --- Auswahl / Objekt-Operationen ---------------------------------------- - "editor_focus_selection": [KEY_F], - "editor_cancel": [KEY_ESCAPE], - "editor_delete_selection": [KEY_DELETE], - "editor_duplicate_selection": [{"key": KEY_D, "ctrl": true}], - # Strg+LMB = Mehrfachauswahl umschalten (Maus-Event, handler prüft den - # Modifier direkt am InputEventMouseButton — Action dokumentiert die Idee). - "editor_multi_select": [{"key": KEY_NONE, "mouse_left_ctrl": true}], - # --- Objekt-Manipulation (Karte t_55257792, Karte 2/3) ------------------- - "editor_rotate_90": [KEY_R], - "editor_nudge_up": [KEY_UP], - "editor_nudge_down": [KEY_DOWN], - "editor_nudge_left": [KEY_LEFT], - "editor_nudge_right": [KEY_RIGHT], - "editor_lift_to_floor": [{"key": KEY_PAGEUP, "ctrl": true}], - "editor_grab": [KEY_G], - # --- Terrain-Pinsel (nur im Terrain-Werkzeug aktiv, main gated) ---------- - "editor_brush_smaller": [KEY_BRACKETLEFT], - "editor_brush_larger": [KEY_BRACKETRIGHT], - "editor_brush_raise": [KEY_1], - "editor_brush_lower": [KEY_2], - "editor_brush_smooth": [KEY_3], - "editor_brush_paint": [KEY_4], - "editor_brush_flatten": [KEY_5], - "editor_brush_ramp": [KEY_6], - # --- Datei & Undo (Karte t_11b5c25b, Karte 3/3) -------------------------- - # Strg+Z/Strg+Y laufen seit dem M2-UX-Fundament; hier NACHGEBUGGEN als - # dokumentierte Actions (alle 3 Shortcut-Karten: ACTIONS-Dict = Source of - # truth). Strg+Umschalt+Z ist der zweite Redo-Weg (beide belegt). - "editor_undo": [{"key": KEY_Z, "ctrl": true}], - "editor_redo_y": [{"key": KEY_Y, "ctrl": true}], - "editor_redo_shift_z": [{"key": KEY_Z, "ctrl": true, "shift": true}], - "editor_save": [{"key": KEY_S, "ctrl": true}], - "editor_save_as": [{"key": KEY_S, "ctrl": true, "shift": true}], - "editor_open_map": [{"key": KEY_O, "ctrl": true}], - "editor_new_map": [{"key": KEY_N, "ctrl": true}], - # --- Werkzeugwechsel (F-Tasten statt Ziffern, Slys Weiche) --------------- - "editor_tool_terrain": [KEY_F1], - "editor_tool_objects": [KEY_F2], - "editor_tool_bauen": [KEY_F3], - "editor_tool_spawns": [KEY_F4], - # --- Kurzhilfe-Overlay + Test-Platzhalter -------------------------------- - "editor_help_overlay": [KEY_H], - "editor_test_map": [KEY_F5], - # --- Höhenlinien fixieren (Karte t_89c0ec95) ------------------------------ - # L = Nutzer-Wahl „Linien immer an/aus" — ohne Fix sind sie NUR im - # Terrain-Werkzeug (F1) sichtbar (Werkzeug-Kopplung in main.gd). L ist - # sonst unbesetzt (Kollisions-Prüfung Karte t_89c0ec95: keine Taste in - # ACTIONS nutzt KEY_L, Ziffern bleiben Terrain-Pinsel allein vorbehalten). - "editor_contours_toggle": [KEY_L], -} - - -static func register() -> void: - for action in ACTIONS: - if InputMap.has_action(action): - continue - InputMap.add_action(action) - for entry in ACTIONS[action]: - InputMap.action_add_event(action, _make_event(entry)) - - -static func _make_event(entry) -> InputEvent: - if entry is Dictionary: - if entry.get("mouse_left_ctrl", false): - var mb := InputEventMouseButton.new() - mb.button_index = MOUSE_BUTTON_LEFT - mb.ctrl_pressed = true - return mb - var key := InputEventKey.new() - key.physical_keycode = int(entry.get("key", KEY_NONE)) - key.shift_pressed = bool(entry.get("shift", false)) - key.ctrl_pressed = bool(entry.get("ctrl", false)) - key.alt_pressed = bool(entry.get("alt", false)) - return key - if entry is int and entry >= MOUSE_BUTTON_NONE and entry <= MOUSE_BUTTON_RIGHT: - var mouse := InputEventMouseButton.new() - mouse.button_index = int(entry) - return mouse - var simple := InputEventKey.new() - simple.physical_keycode = int(entry) - return simple \ No newline at end of file diff --git a/src/editor/shortcut_keys.gd.uid b/src/editor/shortcut_keys.gd.uid deleted file mode 100644 index 3bf4d56..0000000 --- a/src/editor/shortcut_keys.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ctglyo67gpgdc diff --git a/src/editor/shortcut_policy.gd b/src/editor/shortcut_policy.gd deleted file mode 100644 index 21e7c8a..0000000 --- a/src/editor/shortcut_policy.gd +++ /dev/null @@ -1,48 +0,0 @@ -extends RefCounted -class_name ShortcutPolicy -## Esc-Verhalten des Map-Editors (Karte t_c46d31c2, Karte 1/3) — bewusst pure -## Funktion: main.gd fragt pro Esc-Taste ab WELCHE Zustandsänderung fällig ist -## und macht nur noch den Text. tests/test_shortcuts.gd prüft alle Kombos. -## -## Priorität (spec „Esc = Auswahl aufheben / Werkzeug abbrechen / Ghost abbrechen"): -## 1. aktives Sonder-Werkzeug verlassen (Terrain/Spawns → Objekt-Werkzeug) -## 2. Ghost-Preview (Platzieren) abbrechen -## 3. Auswahl aufheben -## Rückgabe-Werte: -## "exit_terrain" | "exit_spawns" | "exit_teststart" | "cancel_grab" -## "cancel_placement" | "clear_selection" | "none" -## grabbing (Karte t_55257792): G-Greifen läuft — Esc rollt die Positionen -## zurück (Blender-Semantik). Vorrang NACH Werkzeug-Exit (im Terrain- -## Werkzeug gibt es kein Greifen), VOR Platzieren/Greifen-Auswahlheben. -static func esc_action(tool_mode: String, placing: bool, has_selection: bool, - grabbing := false) -> String: - if tool_mode == "terrain": - return "exit_terrain" - if tool_mode == "spawns": - return "exit_spawns" - if tool_mode == "teststart": - # Karte t_96e3c4ee (Wiederanbindung 20.10.): Esc verlässt das - # Test-Start-Werkzeug — der gesetzte Punkt BLEIBT bestehen. - return "exit_teststart" - if grabbing: - return "cancel_grab" - if placing: - return "cancel_placement" - if has_selection: - return "clear_selection" - return "none" - - -## Karte 3/3 (t_11b5c25b): Dürfen die globalen Tasten (F1–F5, H) gerade wirken? -## Nein, wenn ein Textfeld/SpinBox fokussiert ist (Tippen geht vor) oder ein -## Dialog/Fenster offen ist (Taste soll nicht HINTER dem Dialog wirken). -## Pure Funktion — main.gd liefert nur die beiden Fakten (testbar, wie esc_action). -static func tool_keys_allowed(text_focused: bool, dialog_open: bool) -> bool: - return not text_focused and not dialog_open - - -## Karte 3/3: Verlust-Operation (Neue Map / Öffnen) bei ungespeicherten -## Änderungen → erst NACHFRAGEN (deutscher Dialog), sonst direkt ausführen. -## Pure Entscheidung — der Dialog selbst lebt in main.gd. -static func needs_dirty_confirm(dirty: bool) -> bool: - return dirty \ No newline at end of file diff --git a/src/editor/shortcut_policy.gd.uid b/src/editor/shortcut_policy.gd.uid deleted file mode 100644 index 8cde9b1..0000000 --- a/src/editor/shortcut_policy.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://0sobeix0nlyg diff --git a/src/editor/spawn_tool.gd b/src/editor/spawn_tool.gd deleted file mode 100644 index e30090c..0000000 --- a/src/editor/spawn_tool.gd +++ /dev/null @@ -1,713 +0,0 @@ -extends Node3D -## Spawn-Zonen-Werkzeug (M2, Karte t_c4162c5d): Zonen für Team Blau/Rot auf -## den Boden malen — im Editor-Modus (Chef-Grundsatz Sly: easy + Spaß). -## -## Bedienung: -## Linksklick = Zone setzen (Klick wie beim Objekt-Platzieren) -## Linksklick auf Zone = Zone auswählen; ZIEHEN verschiebt sie (Terrain-Höhe) -## Pfeilspitze ziehen = Blickrichtung der Zone (auch Conquest-Zonen; grau = Standard) -## Regel rechts = Radius der neuen Zonen; mit Auswahl: Radius DER Zone -## Entf = ausgewählte Zone löschen -## ESC = Auswahl weg / Werkzeug beendet (ESC in main.gd; -## Rechte Maustaste = immer Flug, t_2470de89) -## -## Jede Operation ist EIN Undo-Eintrag über die gemeinsame ActionHistory -## (Blöcke spawn_zones + design_notes, SpawnOps.snapshot_blocks). -## -## Feedback: halbtransparenter Kreis folgt dem Cursor auf dem Terrain -## (Vorschau VOR dem Klick — wie der Objekt-Ghost), die gesetzte Zone leuchtet. - -const MODE_HELP := "Linksklick: Zone setzen · Klick+Ziehen: Zone verschieben · Pfeilspitze ziehen: Blickrichtung · Entf: löschen ·\nRadius/Team rechts · Mittlere Maustaste: Kamera · Strg+Z: zurück" - -## Symmetrie (M4, Karte t_ffa207b1): Partner-Kopplung gespiegelter Spawn-Zonen. -## Liegt in design_notes (Loader-frei, rundtrip-sicher — wie spawn_radius_m): -## {"A5": "B3", "B3": "A5"} — direkte Partner-IDs, beide Richtungen gesetzt. -const SPAWN_MIRROR_KEY := "spawn_mirror" - -var main # Hauptfenster (script-erweitert, Variant) -var camera: Camera3D -var view_builder # Welt-Bauer (script-erweitert, Variant) -var interaction # Objekt-Interaktion (für Auswahl-Entkoppelung) - -var active := false -var team := 0 # 0 = Blau, 1 = Rot (TDM-Konvention) -var zone_radius := SpawnOps.DEFAULT_ZONE_RADIUS - -var selected_team := -1 -var selected_id := "" - -# Auswähl-Ziehen -var _dragging := false -var _drag_moved := false -var _press_pos := Vector2.ZERO -var _grab_offset := Vector3.ZERO - -# Pfeilspitze ziehen (Blickrichtung): Griff aus view_builder.yaw_handles(), {} = keiner -const ARROW_PICK_M := 2.5 -const ARROW_SNAP_DEG := 5.0 -var _arrow_grab: Dictionary = {} -var _arrow_yaw := 0.0 - -# Terrain-Cache für Cursor-Raycast (nur LESEN — dieses Werkzeug formt nichts) -var _heights := PackedFloat32Array() -var _res := 0 -var _sx := 0.0 -var _sz := 0.0 - -var _cursor_valid := false -var _cursor := Vector3.ZERO - -# Ghost-Ring (Radius-Ring) + Fläche als Vorschau -var _ghost: Node3D - - -func setup(p_main, p_camera: Camera3D, p_builder, p_interaction) -> void: - main = p_main - camera = p_camera - view_builder = p_builder - interaction = p_interaction - _ensure_ghost() - - -func _ensure_ghost() -> void: - if _ghost != null and is_instance_valid(_ghost): - return - _ghost = Node3D.new() - _ghost.visible = false - add_child(_ghost) - - -# ------------------------------------------------------------ Aktivierung --- - -func activate() -> bool: - active = true - selected_team = -1 - selected_id = "" - _dragging = false - _cursor_valid = false - _refresh_from_doc() - if view_builder != null: - view_builder.call("set_spawn_selected", -1, "") - refresh_selection_panel() - return true # nie verweigert — Spawn-Zonen brauchen kein Auflösungs-Limit - - -func deactivate() -> void: - active = false - _dragging = false - selected_team = -1 - selected_id = "" - if _ghost != null and is_instance_valid(_ghost): - _ghost.visible = false - - -## Nach Undo/Redo/Laden/Neu: Terrain-Cache neu lesen, Auswahl weg. -func refresh_from_doc() -> void: - _refresh_from_doc() - var still_there := false - if selected_team >= 0: - for p in SpawnOps.points(main.doc, selected_team): - if p is Dictionary and str(p.get("id", "")) == selected_id: - still_there = true - break - if not still_there: - selected_team = -1 - selected_id = "" - - -func _refresh_from_doc() -> void: - var terrain: Dictionary = main.doc.get("terrain", {}) - _res = int(terrain.get("resolution", 0)) - _sx = float(terrain.get("size_x_m", 0.0)) - _sz = float(terrain.get("size_z_m", 0.0)) - if _res >= 2 and _sx > 0.0 and _sz > 0.0: - _heights = SvmapIO.decode_heights(terrain) - else: - _heights = PackedFloat32Array() - - -# ------------------------------------------------------------ Werkzeug-UI --- - -func set_team(next_team: int) -> void: - team = clampi(next_team, 0, 1) - _refresh_ghost_look() - if active: - main.call("_set_status", "Neue Zonen landen für %s (IDs %s1, %s2, …). Bestehende Zonen anklicken zum Verschieben." % [ - SpawnOps.team_label(team), SpawnOps.team_prefix(team), SpawnOps.team_prefix(team)]) - - -func set_radius(m: float) -> void: - zone_radius = clampf(m, SpawnOps.MIN_ZONE_RADIUS, SpawnOps.MAX_ZONE_RADIUS) - _refresh_ghost_look() - # Ausgewählte Zone? Dann gilt die Regel SOFORT für sie (mit Undo, merge-gekoppelt). - if active and selected_team >= 0 and selected_id != "": - var before: Dictionary = SpawnOps.snapshot_blocks(main.history, main.doc) - SpawnOps.set_radius(main.doc, selected_id, zone_radius) - main.history.commit("Radius von %s: %d m" % [selected_id, int(zone_radius)], - before, SpawnOps.snapshot_blocks(main.history, main.doc), - "radius:%s" % selected_id) - main.call("_refresh_history_buttons") - main.call("_refresh_spawn_status") - _refresh_ghost_look() - var marker: Node3D = _marker_of(selected_team, selected_id) - if marker != null and is_instance_valid(marker): - view_builder.call("style_spawn_marker", marker, - SpawnOps.zone_radius(main.doc, selected_id), true) - - -# --------------------------------------------------------------- Eingaben --- - -func _unhandled_input(event: InputEvent) -> void: - var p := MousePointer.from_input(event) - if p != null and handle_pointer(p): - get_viewport().set_input_as_handled() - - -## Rechte Maustaste kommt hier nie an (Karte t_2470de89): sie gehört mit -## absolutem Vorrang dem Freelook-Flug. Deselect/Werkzeug beenden läuft über -## ESC (main.gd), die Auswahl bleibt im Flug erhalten. -func handle_pointer(p: PointerEvent) -> bool: - if not active: - return false - match p.kind: - PointerEvent.Kind.MOVE: - _update_cursor(p.position) - if not _arrow_grab.is_empty(): - _drag_arrow(p.position) - return false - if _dragging and selected_team >= 0: - var hit: Variant = _ray_hit(p.position) - if hit == null: - return false - var pos: Vector3 = _clamped(hit as Vector3) + _grab_offset - var half := _terrain_half() - pos.x = clampf(pos.x, -half.x + zone_radius, half.x - zone_radius) - pos.z = clampf(pos.z, -half.y + zone_radius, half.y - zone_radius) - pos.y = SvmapDocument.terrain_height_at(main.doc, pos.x, pos.z) - _drag_moved = true - var marker: Node3D = _marker_of(selected_team, selected_id) - if marker != null and is_instance_valid(marker): - marker.position = pos - PointerEvent.Kind.PRESS: - _on_left_press(p.position) - return true - PointerEvent.Kind.RELEASE: - _on_left_release() - return false - - -func _update_cursor(viewport_pos: Vector2) -> void: - var hit: Variant = _ray_hit(viewport_pos) - if hit == null: - _cursor_valid = false - if _ghost != null and is_instance_valid(_ghost): - _ghost.visible = false - return - _cursor_valid = true - _cursor = _clamped(hit as Vector3) - if _ghost != null and is_instance_valid(_ghost): - _ghost.position = Vector3(_cursor.x, _cursor.y + 0.15, _cursor.z) - _ghost.visible = true - - -## Strahl → Punkt auf dem Terrain (Favorisiert echte Geländeberührung wie -## der Terrain-Pinsel; ohne Höhenfeld: Bodenebene). -func _ray_hit(viewport_pos: Vector2) -> Variant: - if _res >= 2 and _heights.size() >= _res * _res: - return TerrainField.raycast(_heights, _res, _sx, _sz, - camera.project_ray_origin(viewport_pos), camera.project_ray_normal(viewport_pos)) - var terrain: Dictionary = main.doc.get("terrain", {}) - if terrain.is_empty(): - return null - var plane_y := float(terrain.get("min_height_m", 0.0)) - var origin := camera.project_ray_origin(viewport_pos) - var dir := camera.project_ray_normal(viewport_pos) - if absf(dir.y) < 0.0001: - return null - var t := (plane_y - origin.y) / dir.y - if t <= 0.0: - return null - return origin + dir * t - - -func _clamped(p: Vector3) -> Vector3: - var half := _terrain_half() - p.x = clampf(p.x, -half.x, half.x) - p.z = clampf(p.z, -half.y, half.y) - p.y = SvmapDocument.terrain_height_at(main.doc, p.x, p.z) - return p - - -func _terrain_half() -> Vector2: - return Vector2(_sx, _sz) * 0.5 - - -# ----------------------------------------------------- Setzen/Auswählen ----- - -func _on_left_press(viewport_pos: Vector2) -> void: - _arrow_grab = _pick_arrow(viewport_pos) - if not _arrow_grab.is_empty(): - _drag_arrow(viewport_pos) - return - var picked := _pick_spawn(viewport_pos) - if picked.is_empty(): - _place_zone(viewport_pos) - return - # Bestehende Zone anfassen → auswählen + Greifen vorbereiten. - selected_team = int(picked["team"]) - selected_id = str(picked["id"]) - view_builder.call("set_spawn_selected", selected_team, selected_id) - _dragging = true - _drag_moved = false - _press_pos = viewport_pos - _grab_offset = Vector3.ZERO - var hit: Variant = _ray_hit(viewport_pos) - var marker: Node3D = _marker_of(selected_team, selected_id) - if hit != null and marker != null and is_instance_valid(marker): - _grab_offset = marker.position - (_clamped(hit as Vector3)) - _grab_offset.y = 0.0 - refresh_selection_panel() - main.call("_set_status", "%s (%s) ausgewählt — ziehen zum Verschieben, Entf zum Löschen, der Radius-Regel rechts gilt jetzt für SIE." % [ - selected_id, SpawnOps.team_label(selected_team)]) - - -func _on_left_release() -> void: - if not _arrow_grab.is_empty(): - _commit_arrow() - return - if not _dragging: - return - _dragging = false - if not (_drag_moved and selected_team >= 0 and selected_id != ""): - _drag_moved = false - return - var marker: Node3D = _marker_of(selected_team, selected_id) - if marker == null or not is_instance_valid(marker): - _drag_moved = false - return - var half := _terrain_half() - var pos: Vector3 = marker.position - pos.x = clampf(pos.x, -half.x, half.x) - pos.z = clampf(pos.z, -half.y, half.y) - var before: Dictionary = SpawnOps.snapshot_blocks(main.history, main.doc) - SpawnOps.move_point(main.doc, selected_team, selected_id, pos.x, pos.z) - # Symmetrie (M4): Zwilling folgt der gespiegelten neuen Position. - var mirror_msg: String = spawn_mirror_move(main.doc, selected_team, selected_id, _sym_mode()) - main.history.commit("%s verschoben" % selected_id, - before, SpawnOps.snapshot_blocks(main.history, main.doc)) - main.call("_after_structure_change") - _point_selection_at_doc() - view_builder.call("set_spawn_selected", selected_team, selected_id) - main.call("_set_status", "%s verschoben — Strg+Z macht das rückgängig.%s" % [ - selected_id, "" if mirror_msg.is_empty() else " " + mirror_msg]) - _drag_moved = false - - -func _place_zone(viewport_pos: Vector2) -> void: - var hit: Variant = _ray_hit(viewport_pos) - if hit == null: - main.call("_set_status", "Da war kein Boden unter dem Mauszeiger — klicke IN die Karte (die grüne Fläche).", true) - return - var half := _terrain_half() - var pos := _clamped(hit as Vector3) - if absf(pos.x) > half.x - zone_radius or absf(pos.z) > half.y - zone_radius: - pos.x = clampf(pos.x, -half.x + zone_radius, half.x - zone_radius) - pos.z = clampf(pos.z, -half.y + zone_radius, half.y - zone_radius) - main.call("_set_status", "Der Kreis würde über den Rand hinausschauen — ich habe ihn ganz nach innen geschoben.") - var before: Dictionary = SpawnOps.snapshot_blocks(main.history, main.doc) - var point := SpawnOps.add_zone(main.doc, team, pos.x, pos.z) - var pid := str(point["id"]) - SpawnOps.set_radius(main.doc, pid, zone_radius) - # Symmetrie (M4): Zwilling im Gegner-Team — innerhalb desselben Undo-Schritts. - var mirror_res: Dictionary = spawn_mirror_add(main.doc, team, pid, _sym_mode()) - main.history.commit("Spawn-Zone %s (%s) gesetzt" % [pid, SpawnOps.team_label(team)], - before, SpawnOps.snapshot_blocks(main.history, main.doc)) - main.call("_after_structure_change") - # Frische Zone auswählen und anfassen — Radius-Regel gilt ab jetzt für SIE. - selected_team = team - selected_id = pid - view_builder.call("set_spawn_selected", selected_team, selected_id) - refresh_selection_panel() - var mirror_text := str(mirror_res["status"]) - main.call("_set_status", "Spawn-Zone %s (%s) gesetzt.%s Radius: Regler rechts · verschieben: klicken+ziehen · Entf löscht · Strg+Z macht alles rückgängig." % [ - pid, SpawnOps.team_label(team), "" if mirror_text.is_empty() else " " + mirror_text]) - - -## Kursor-Strahl → nächste Pfeilspitze in Greifweite oder {}. -func _pick_arrow(viewport_pos: Vector2) -> Dictionary: - var hit: Variant = _ray_hit(viewport_pos) - if hit == null: - return {} - var p: Vector3 = hit as Vector3 - var best := {} - var best_d := ARROW_PICK_M - for h in view_builder.yaw_handles(): - var tip: Vector3 = h["tip"] - var d := Vector2(p.x - tip.x, p.z - tip.z).length() - if d <= best_d: - best = h - best_d = d - return best - - -func _drag_arrow(viewport_pos: Vector2) -> void: - var hit: Variant = _ray_hit(viewport_pos) - var node: Node3D = _arrow_grab.get("node") - if hit == null or node == null or not is_instance_valid(node): - return - var c := node.global_position - var yaw := SpawnOps.yaw_towards(c, Vector2((hit as Vector3).x, (hit as Vector3).z)) - _arrow_yaw = fposmod(snappedf(yaw, ARROW_SNAP_DEG), 360.0) - var arrow: MeshInstance3D = view_builder.yaw_arrow_of(node) - if arrow != null: - arrow.rotation.y = deg_to_rad(_arrow_yaw) - main.call("_set_status", "Blickrichtung von %s: %d°" % [str(_arrow_grab["id"]), int(_arrow_yaw)]) - - -func _commit_arrow() -> void: - var grab := _arrow_grab - _arrow_grab = {} - if str(grab["kind"]) == "zone": - apply_zone_yaw(str(grab["id"]), _arrow_yaw) - return - selected_team = int(grab["team"]) - selected_id = str(grab["id"]) - set_selected_yaw(_arrow_yaw) - - -## Blickrichtung der ausgewählten Zone setzen (yaw = null: Standard). EIN Undo-Eintrag. -func set_selected_yaw(yaw: Variant) -> void: - if selected_team < 0 or selected_id == "": - return - var before: Dictionary = SpawnOps.snapshot_blocks(main.history, main.doc) - if not SpawnOps.set_point_yaw(main.doc, selected_team, selected_id, yaw): - return - spawn_mirror_yaw(main.doc, selected_id, yaw, _sym_mode()) - main.history.commit("Blickrichtung von %s" % selected_id, - before, SpawnOps.snapshot_blocks(main.history, main.doc)) - main.call("_after_structure_change") - view_builder.call("set_spawn_selected", selected_team, selected_id) - refresh_selection_panel() - main.call("_set_status", "Blickrichtung von %s: %s — Strg+Z macht das rückgängig." % [ - selected_id, "Standard (zur Kartenmitte)" if yaw == null else "%d°" % int(yaw)]) - - -## Dasselbe für eine Conquest-Zone (der Griff im Bild, das Panel geht über modus_panel). -func apply_zone_yaw(zid: String, yaw: Variant) -> void: - var zones: Variant = main.doc.get("conquest_zones", []) - if not (zones is Array): - return - var before := {"conquest_zones": (zones as Array).duplicate(true)} - for z in zones: - if z is Dictionary and str(z.get("id", "")) == zid: - SpawnOps.write_yaw(z, yaw) - main.history.commit("Blickrichtung von %s" % zid, before, - {"conquest_zones": (zones as Array).duplicate(true)}) - main.call("_after_structure_change") - main.call("_set_status", "Blickrichtung von %s: %d° — Strg+Z macht das rückgängig." % [zid, int(yaw)]) - - -## Kursor-Strahl → getroffene Zone ({team, id}) oder {}. -func _pick_spawn(viewport_pos: Vector2) -> Dictionary: - var hit: Variant = _ray_hit(viewport_pos) - if hit == null: - return {} - var p: Vector3 = hit as Vector3 - var best := {} - var best_d := INF - for marker in view_builder.spawn_markers: - if marker == null or not is_instance_valid(marker): - continue - var mpos: Vector3 = marker.global_position - var d := Vector2(p.x - mpos.x, p.z - mpos.z).length() - var pick_r := float(marker.get_meta("spawn_pick_radius", 4.0)) - if d <= pick_r and d < best_d: - best = {"team": int(marker.get_meta("spawn_team", -1)), "id": str(marker.get_meta("spawn_id", ""))} - best_d = d - return best - - -func _marker_of(team_i: int, pid: String) -> Node3D: - for marker in view_builder.spawn_markers: - if marker == null or not is_instance_valid(marker): - continue - if int(marker.get_meta("spawn_team", -1)) == team_i and str(marker.get_meta("spawn_id", "")) == pid: - return marker - return null - - -func _point_selection_at_doc() -> void: - # Nach rebuild: Auswahl-Referenzen im DOC halten (selbes Team/ID-Prinzip). - for p in SpawnOps.points(main.doc, selected_team): - if p is Dictionary and str(p.get("id", "")) == selected_id: - return - selected_team = -1 - selected_id = "" - - -func _clear_selection() -> void: - selected_team = -1 - selected_id = "" - if _dragging: - _dragging = false - view_builder.call("set_spawn_selected", -1, "") - refresh_selection_panel() - - -func delete_selected() -> void: - if selected_team < 0 or selected_id == "": - main.call("_set_status", "Nichts ausgewählt — klicke zuerst eine Spawn-Zone an, die weg soll.", true) - return - var label := "%s (%s)" % [selected_id, SpawnOps.team_label(selected_team)] - var before: Dictionary = SpawnOps.snapshot_blocks(main.history, main.doc) - if not SpawnOps.remove_point(main.doc, selected_team, selected_id): - _clear_selection() - return - # Symmetrie (M4): Zwilling mit entfernen (innerhalb desselben Undo-Schritts). - var mirror_msg: String = spawn_mirror_delete(main.doc, selected_id, _sym_mode()) - main.history.commit("%s löschen" % label, before, - SpawnOps.snapshot_blocks(main.history, main.doc)) - _clear_selection() - main.call("_after_structure_change") - main.call("_set_status", "Spawn-Zone %s gelöscht — Strg+Z holt sie zurück.%s %s braucht mindestens %d Zonen!" % [ - label, "" if mirror_msg.is_empty() else " " + mirror_msg, - SpawnOps.team_label(team), SvmapIO.MIN_SPAWN_POINTS_PER_TEAM]) - - -## Panel-Zeile rechts (Welche Zone ist an?) synchron halten — ohne Statuszeile anzufassen. -func refresh_selection_panel() -> void: - if main.has_method("_sync_spawn_selection"): - main.call("_sync_spawn_selection") - - -# ------------------------------------------------- Symmetrie (M4) Statics --- -## Karte t_ffa207b1: Gespiegelte Spawn-Zonen. ENTScheidung (Spec vc27, -## „Teams bleiben einander gegenüber fair"): der Zwilling landet im GEGNER- -## Team — Blau (West) ↔ Rot (Ost), denn genau auf den Gegenseiten liegen die -## Default-Streifen der beiden Teams. Jede gesetzte Zone gibt dem anderen Team -## automatisch die faire Gegenstelle. Alles pure Statics (kein -## UI, kein Node-Zugriff) → headless testbar; spawn_ops.gd bleibt unangetastet. - -## Partner-ID einer Spawn-Zone ("" = keiner). -static func spawn_mirror_partner(doc: Dictionary, pid: String) -> String: - var m := _mirror_map_of(doc) - return str(m.get(pid, "")) - - -static func _mirror_map_of(doc: Dictionary) -> Dictionary: - var notes = doc.get("design_notes", {}) - if not (notes is Dictionary): - return {} - var m = (notes as Dictionary).get(SPAWN_MIRROR_KEY, {}) - return m if m is Dictionary else {} - - -static func _mirror_map_set(doc: Dictionary, pid_a: String, pid_b: String) -> void: - var notes = doc.get("design_notes", {}) - if not (notes is Dictionary): - notes = {} - doc["design_notes"] = notes - var m = (notes as Dictionary).get(SPAWN_MIRROR_KEY, {}) - if not (m is Dictionary): - m = {} - (notes as Dictionary)[SPAWN_MIRROR_KEY] = m - m[pid_a] = pid_b - m[pid_b] = pid_a - - -static func _mirror_map_clear(doc: Dictionary, pid_a: String, pid_b: String) -> void: - var m := _mirror_map_of(doc) - if m.is_empty(): - return - m.erase(pid_a) - m.erase(pid_b) - - -## Gespiegelte Spawn-Zone zu `pid` anlegen (Symmetrie an). Rückgabe: -## {"ok": bool, "status": Klartext}. ok=false + V9-Text = Zwilling NICHT -## gespeichert (Grenzen scharf — Spec vc27). Auf der Symmetrie-Mitte liegende -## Zonen werden nicht gedoppelt (Spec). -static func spawn_mirror_add(doc: Dictionary, team: int, pid: String, mode: int) -> Dictionary: - if mode == SymmetryCore.Mode.OFF: - return {"ok": true, "status": ""} - var original := _spawn_point_of(doc, team, pid) - if original.is_empty(): - return {"ok": false, "status": "Spawn-Zone %s nicht gefunden — Zwilling nicht gesetzt." % pid} - var pos := _spawn_pos_of(original) - var center := SymmetryCore.map_center(doc) - if SymmetryCore.maps_to_self(mode, pos, center): - return {"ok": true, "status": "Spawn-Zone %s liegt auf der Symmetrie-Mitte — nicht gedoppelt." % pid} - var mirror_pos := SymmetryCore.mirror_point(mode, pos, center) - var bounds: Dictionary = doc.get("bounds", {}) - if not bounds.is_empty() and not SvmapIO._inside_bounds( - [mirror_pos.x, mirror_pos.y, mirror_pos.z], bounds): - return {"ok": false, "status": "❌ V9: Gespiegelter Spawn läge außerhalb der Match-Grenzen — nicht gesetzt."} - var twin := SpawnOps.add_zone(doc, 1 - team, mirror_pos.x, mirror_pos.z) - var twin_id := str(twin["id"]) - SpawnOps.set_radius(doc, twin_id, SpawnOps.zone_radius(doc, pid)) - _mirror_map_set(doc, pid, twin_id) - if SpawnOps.has_yaw(original): - SpawnOps.write_yaw(twin, SymmetryCore.mirror_facing(mode, float(original[SpawnOps.YAW_KEY]))) - return {"ok": true, "status": "Gespiegelte Zone %s (%s) gesetzt." % [ - twin_id, SpawnOps.team_label(1 - team)]} - - -## Verschiebung spiegeln: Zwilling bekommt die gespiegelte Position der NEUEN -## Position des Originals (y = Terrain-Höhe am gespiegelten Punkt, wie beim -## normalen Verschieben). Rückgabe: Klartext-Status ("" = nichts zu tun). -static func spawn_mirror_move(doc: Dictionary, team: int, pid: String, mode: int) -> String: - if mode == SymmetryCore.Mode.OFF: - return "" - var partner := spawn_mirror_partner(doc, pid) - if partner.is_empty(): - return "" - var original := _spawn_point_of(doc, team, pid) - if original.is_empty(): - return "" - var pos := _spawn_pos_of(original) - var center := SymmetryCore.map_center(doc) - if SymmetryCore.maps_to_self(mode, pos, center): - return "" - var mirror_pos := SymmetryCore.mirror_point(mode, pos, center) - var partner_team := _team_of_point(doc, partner) - if partner_team < 0: - return "" - if not SpawnOps.move_point(doc, partner_team, partner, mirror_pos.x, mirror_pos.z): - return "" - return "Gespiegelte Zone %s mitverschoben." % partner - - -## Blickrichtung spiegeln: Zwilling schaut gespiegelt (yaw = null: auch er auf Standard). -static func spawn_mirror_yaw(doc: Dictionary, pid: String, yaw: Variant, mode: int) -> void: - if mode == SymmetryCore.Mode.OFF: - return - var partner := spawn_mirror_partner(doc, pid) - var partner_team := _team_of_point(doc, partner) if not partner.is_empty() else -1 - if partner_team >= 0: - SpawnOps.set_point_yaw(doc, partner_team, partner, - null if yaw == null else SymmetryCore.mirror_facing(mode, float(yaw))) - - -## Löschung spiegeln (entfernen → beide weg, inkl. Radius-Eintrag und -## Partner-Map). Rückgabe: Klartext-Status ("" = nur das Original war weg). -static func spawn_mirror_delete(doc: Dictionary, pid: String, mode: int) -> String: - if mode == SymmetryCore.Mode.OFF: - return "" - var partner := spawn_mirror_partner(doc, pid) - if partner.is_empty(): - return "" - var partner_team := _team_of_point(doc, partner) - if partner_team < 0: - _mirror_map_clear(doc, pid, partner) - return "" - if SpawnOps.remove_point(doc, partner_team, partner): - _mirror_map_clear(doc, pid, partner) - return "Gespiegelte Zone %s (%s) mit entfernt." % [partner, SpawnOps.team_label(partner_team)] - return "" - - -static func _spawn_point_of(doc: Dictionary, team: int, pid: String) -> Dictionary: - for p in SpawnOps.points(doc, team): - if p is Dictionary and str(p.get("id", "")) == pid: - return p as Dictionary - return {} - - -static func _team_of_point(doc: Dictionary, pid: String) -> int: - for team in [0, 1]: - if not _spawn_point_of(doc, team, pid).is_empty(): - return team - return -1 - - -static func _spawn_pos_of(point: Dictionary) -> Vector3: - var pos: Array = point.get("pos", [0.0, 0.0, 0.0]) - return Vector3(float(pos[0]), float(pos[1]), float(pos[2])) - - -# ------------------------------------------------------------ Ghost-Optik --- - -func _refresh_ghost_look() -> void: - if _ghost == null or not is_instance_valid(_ghost): - return - # Kreisfläche: flacher Cylinder (Zonen-Scheibe), teamfarbig halbtransparent. - for child in _ghost.get_children(): - child.queue_free() - var disc := MeshInstance3D.new() - var cyl := CylinderMesh.new() - cyl.top_radius = zone_radius - cyl.bottom_radius = zone_radius - cyl.height = 0.25 - disc.mesh = cyl - disc.position.y = 0.12 - var col: Color = view_builder.TEAM_COLORS[team] - var mat := StandardMaterial3D.new() - mat.albedo_color = Color(col.r, col.g, col.b, 0.4) - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.emission_enabled = true - mat.emission = col * 0.35 - disc.material_override = mat - _ghost.add_child(disc) - var ring := MeshInstance3D.new() - var torus := TorusMesh.new() - torus.inner_radius = zone_radius - 0.2 - torus.outer_radius = zone_radius + 0.2 - torus.rings = 48 - torus.ring_segments = 6 - ring.mesh = torus - ring.position.y = 0.05 - ring.material_override = mat - _ghost.add_child(ring) - - -# ------------------------------------------------------- Demo/Screenshot ---- - -## Demo-Hook (Desktop-Smoke): Zone programmatisch setzen (inkl. History). -## Macht exakt, was ein Klick machen würde — ohne echte Maus-Ereignisse. -func demo_place(zone_team: int, x: float, z: float, radius: float) -> String: - var before: Dictionary = SpawnOps.snapshot_blocks(main.history, main.doc) - var point := SpawnOps.add_zone(main.doc, zone_team, x, z) - var pid := str(point["id"]) - if radius > 0.0: - SpawnOps.set_radius(main.doc, pid, radius) - # Symmetrie (M4): Zwilling im Gegner-Team — innerhalb desselben Undo-Schritts. - spawn_mirror_add(main.doc, zone_team, pid, _sym_mode()) - main.history.commit("Spawn-Zone %s (%s) gesetzt" % [pid, SpawnOps.team_label(zone_team)], - before, SpawnOps.snapshot_blocks(main.history, main.doc)) - return pid - - -## Demo-Hook: Zone programmatisch verschieben (inkl. History). -func demo_move(zone_team: int, pid: String, x: float, z: float) -> void: - var before: Dictionary = SpawnOps.snapshot_blocks(main.history, main.doc) - SpawnOps.move_point(main.doc, zone_team, pid, x, z) - # Symmetrie (M4): Zwilling folgt der gespiegelten neuen Position. - spawn_mirror_move(main.doc, zone_team, pid, _sym_mode()) - main.history.commit("%s verschoben" % pid, - before, SpawnOps.snapshot_blocks(main.history, main.doc)) - - -## Aktiver Symmetrie-Modus aus main (M1-Schalter). Defensive über main.get(): -## Mock-Mains (Tests) haben sym_mode nicht — dann gilt OFF (altes Verhalten), -## statt mit SCRIPT ERROR abzustürzen (Lektion: SCRIPT ERROR in -s-Suiten = rot). -func _sym_mode() -> int: - var v: Variant = main.get("sym_mode") if main != null else null - return SymmetryCore.Mode.OFF if v == null else int(v) - - -## Demo-Hook: Ghost an Position parken (für Screenshots ohne Maus). -func demo_park_ghost(x: float, z: float, team_i: int, radius: float) -> void: - set_team(team_i) - if radius > 0.0: - set_radius_demo_only(radius) - _refresh_ghost_look() - _cursor = Vector3(x, SvmapDocument.terrain_height_at(main.doc, x, z), z) - _cursor_valid = true - _ghost.position = Vector3(_cursor.x, _cursor.y + 0.15, _cursor.z) - _ghost.visible = true - - -## Nur-Editor-Radius (kein Doc-Eintrag, kein Undo) für die Vorschau im Demo-Hook. -func set_radius_demo_only(m: float) -> void: - zone_radius = clampf(m, SpawnOps.MIN_ZONE_RADIUS, SpawnOps.MAX_ZONE_RADIUS) \ No newline at end of file diff --git a/src/editor/spawn_tool.gd.uid b/src/editor/spawn_tool.gd.uid deleted file mode 100644 index 44902a0..0000000 --- a/src/editor/spawn_tool.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dcr747fch22k diff --git a/src/editor/symmetry_ops.gd b/src/editor/symmetry_ops.gd deleted file mode 100644 index d117e50..0000000 --- a/src/editor/symmetry_ops.gd +++ /dev/null @@ -1,647 +0,0 @@ -extends RefCounted -class_name SymmetryOps -## M5 Ein-Klick „Karte symmetrisch machen“ + Symmetrie-Check (Karte t_60014669, -## Spec /opt/data/scopedvr/KARTEN_MIRROR_vc27.md). Baut auf M1–M4 auf: -## Spiegel-Mathe und Partner-Links kommen aus SymmetryCore, das Anwenden auf -## Objekten aus ObjectOps, auf Bauteilen (normale Objekte) und auf Spawn-Zonen aus -## dem Spawn-Spiegel-Mechanismus (spawn_tool.gd — dort NUR BENUTZT, nie -## geändert). Diese Datei orchestriert den GANZEN Vorgang und den Check: -## -## analyze(doc, mode) → ehrliche Bestandsaufnahme (nur lesen): Paare, die -## schon passen, Paare, die widersprechen, Elemente -## ohne Zwilling, abweichende Boden-Zellen. -## apply(doc, mode, quelle_hoch) → gleicht die Karte an: alles aus der -## Quell-Hälfte wird ERGÄNZT (Objekte, Bau-Teile, -## Spawn-Punkte, Boden zellgenau); widersprüchliche -## Paare bekommen die Quelle zugesprochen (nichts wird -## gelöscht, die Zahl wurde vorher genannt). -## check(doc, mode) → Klartext-Bericht: „Alles symmetrisch ✓“ oder -## „N Stellen weichen ab: Objekt #12, Boden (31,17) …“ -## -## Seiten-Logik ohne Mode-Wirrwarr: Jedes Element wird mit seinem Spiegelbild -## verglichen. Die „linke“/„vordere“ Seite eines Paares ist die, deren -## Spiegelbild weiter rechts/hinten liegt (lex-Antwort: erst x, dann z). -## Die Quell-Hälfte-Wahl (quelle_hoch=false = links/vorn, true = rechts/hinten) -## entscheidet NUR, welche Seite eines Paares bei Widerspruch gewinnt und in -## welche Richtung einzelstehende Elemente ergänzt werden. -## -## Ein-Klick-Anwendung (Panel) macht den GANZEN Vorgang zu EINEM Undo-Schritt: -## ActionHistory snapshotet das ganze Dokument — hier wird nur mutiert, das -## Committen bleibt beim Aufrufer (Panel/main, Muster wie beim Resize R3). -## -## Alles static + reine Funktionen (mutieren nur das übergebene doc) → -## headless testbar wie SymmetryCore/ObjectOps. - -const SpawnToolScript := preload("res://src/editor/spawn_tool.gd") - -## Wie nah ein Spiegelbild an einem Element liegen darf, damit sie als Paar -## gelten (Meter, XZ-Ebene). Handgebaute Karten sitzen nie auf den Millimeter — -## aber exakt gespiegelte Paare aus M2–M4 liegen auf 0. -const PAIR_TOLERANCE_M := 1.0 -## Ab wann Höhen als verschieden gelten (Terrain-R16-Schritt ist viel kleiner). -const HEIGHT_EPS_M := 0.02 -## Kleine Vergleichstoleranzen für Position/Drehung/Maßstab/Farbe. -const POS_EPS_M := 0.01 -const ROT_EPS_DEG := 0.5 -const VALUE_EPS := 0.01 -## Wie viele Beispiele der Klartext-Bericht maximal einzeln nennt. -const MAX_EXAMPLES := 8 - - -# ------------------------------------------------------------ Seiten-Logik -- - -## Klartext-Namen der beiden Hälften für den Modus ([niedrige Seite, hohe]). -static func side_labels(mode: int) -> Array: - if mode == SymmetryCore.Mode.AXIS_Z: - return ["vorn", "hinten"] - return ["links", "rechts"] - - -static func _center_of(doc: Dictionary) -> Vector2: - return SymmetryCore.map_center(doc) - - -static func _mirror(mode: int, doc: Dictionary, p: Vector3) -> Vector3: - return SymmetryCore.mirror_point(mode, p, _center_of(doc)) - - -static func _pos_of(arr: Array) -> Vector3: - if (arr as Array).size() < 3: - return Vector3.ZERO - return Vector3(float(arr[0]), float(arr[1]), float(arr[2])) - - -## „self“ = liegt auf Mitte/Achse (wird nie gedoppelt, nie geprüft). -## „low“ = lex-erste Seite (links bzw. vorn), „high“ = die andere. -## Bei Punkt-Spiegelung entscheidet auf der Mittel-Linie z statt x. -static func _side_of(mode: int, p: Vector3, doc: Dictionary) -> String: - if SymmetryCore.maps_to_self(mode, p, _center_of(doc)): - return "self" - var m := _mirror(mode, doc, p) - if p.x < m.x - 0.0001: - return "low" - if p.x > m.x + 0.0001: - return "high" - return "low" if p.z < m.z - 0.0001 else "high" - - -## Templat-loses Sammeln: items = [{"idx": int, "pos": Vector3}]. Paarung -## IMMERS vom low-Spiegel aus (deterministisch, Richtung der Quell-Wahl -## ändert die Paare nicht). Rückgabe: -## pairs: [{"low": idx, "high": idx, "mirror": Vector3}] -## singles_low / singles_high: idx-Listen der Zwillinglosen -static func _pair_items(mode: int, doc: Dictionary, items: Array) -> Dictionary: - var out := {"pairs": [], "singles_low": [], "singles_high": []} - var low_pool: Array = [] - var high_pool: Array = [] - for it in items: - if not (it is Dictionary): - continue - var side: String = _side_of(mode, it["pos"], doc) - if side == "self": - continue - if side == "low": - low_pool.append(it) - else: - high_pool.append(it) - var used: Dictionary = {} - for d in low_pool: - var m := _mirror(mode, doc, d["pos"]) - var best: int = -1 - var best_d: float = PAIR_TOLERANCE_M - for k in high_pool.size(): - if used.has(k): - continue - var t: Dictionary = high_pool[k] - var dxy := Vector2(m.x - t["pos"].x, m.z - t["pos"].z).length() - if dxy <= best_d: - best = k - best_d = dxy - if best >= 0: - used[best] = true - out["pairs"].append({ - "low": int(d["idx"]), - "high": int(high_pool[best]["idx"]), - "mirror": m, - }) - for k in high_pool.size(): - if not used.has(k): - out["singles_high"].append(int(high_pool[k]["idx"])) - for d in low_pool: - var paired := false - for p in out["pairs"]: - if int(p["low"]) == int(d["idx"]): - paired = true - break - if not paired: - out["singles_low"].append(int(d["idx"])) - return out - - -# -------------------------------------------------------------- analyze() --- - -## Ehrliche Bestandsaufnahme (liest NUR). Siehe Klassenkopf für die Struktur. -static func analyze(doc: Dictionary, mode: int) -> Dictionary: - var an := { - "mode": mode, - "objects": {"pairs": [], "singles_low": [], "singles_high": [], "diff": 0}, - "spawns": {"pairs": [], "singles_low": [], "singles_high": [], "diff": 0}, - "terrain_cells": [], - "material_cells": [], # Material-Raster (fein, Karte 24.10.) — eigenes Gitter - "deviations": [], - "links": 0, # positionierende Paare ohne sym-Kopplung (werden verknüpft) - "conflicts": 0, # widersprüchliche Paare + Boden-Zellen - "adds": 0, # Zwillinge, die ergänzt werden - "_dev_total": 0, - "total_changes": 0, - "total_deviations": 0, - } - if mode == SymmetryCore.Mode.OFF: - return an - _analyze_objects(doc, mode, an) - _analyze_spawns(doc, mode, an) - _analyze_terrain(doc, mode, an) - an["conflicts"] = int(an["objects"]["diff"]) \ - + int(an["spawns"]["diff"]) + (an["terrain_cells"] as Array).size() \ - + (an["material_cells"] as Array).size() - an["adds"] = (an["objects"]["singles_low"] as Array).size() \ - + (an["objects"]["singles_high"] as Array).size() \ - + (an["spawns"]["singles_low"] as Array).size() \ - + (an["spawns"]["singles_high"] as Array).size() - an["total_deviations"] = int(an["_dev_total"]) - an["total_changes"] = int(an["conflicts"]) + int(an["adds"]) + int(an["links"]) - return an - - -## Meldet eine Abweichung: Zähler ZÄHLT IMMER, die Beispielliste ist gekappt. -static func _push_dev(an: Dictionary, label: String) -> void: - an["_dev_total"] = int(an["_dev_total"]) + 1 - var devs: Array = an["deviations"] - if devs.size() < MAX_EXAMPLES: - devs.append(label) - - -static func _valid_link(list: Array, idx: int) -> int: - ## sym-Partner-Index NUR wenn der Partner wirklich existiert — sonst gilt - ## das Element als verkoppelt-lost und läuft über die Paarung mit. - var item: Dictionary = list[idx] - var key := SymmetryCore.sym_of(item) - if key.is_empty(): - return -1 - return SymmetryCore.find_partner_index(list, key, idx) - - -## Frische gemeinsame sym-Kennung für ein Paar. Hingen die Elemente vorher an -## ANDEREN Partnern, verlieren diese ihre Kennung mit — sonst bliebe ein -## V16-Waise übrig (eine Kennung = GENAU 2 Elemente). Merkwurzeln einer -## beschädigten Karte können so pro Lauf kleiner werden; ein zweiter Klick -## erledigt den Rest. -static func _fresh_pair_link(doc: Dictionary, list: Array, donor_i: int, - twin_i: int) -> void: - for idx in [donor_i, twin_i]: - var key := SymmetryCore.sym_of(list[idx]) - if key.is_empty(): - continue - var old_partner := SymmetryCore.find_partner_index(list, key, idx) - if old_partner >= 0 and old_partner != donor_i and old_partner != twin_i: - SymmetryCore.clear_sym(list[old_partner]) - SymmetryCore.clear_sym(list[idx]) - var nk := SymmetryCore.next_sym_key(doc) - SymmetryCore.set_sym(list[donor_i], nk) - SymmetryCore.set_sym(list[twin_i], nk) - - -## Spawn-Gegenstück: Kopplung design_notes.spawn_mirror sauber neu setzen -## (beide Richtungen überschreiben, alte Partner beidseitig auskoppeln). -static func _fresh_spawn_link(doc: Dictionary, donor_id: String, - twin_id: String) -> void: - for pid in [donor_id, twin_id]: - var old := _spawn_linked(doc, pid) - if not old.is_empty() and old != donor_id and old != twin_id: - SpawnToolScript._mirror_map_clear(doc, pid, old) - SpawnToolScript._mirror_map_set(doc, donor_id, twin_id) - - -static func _obj_pair_differs(src: Dictionary, twin: Dictionary, mp: Vector3, - mode: int) -> bool: - var tpos := _pos_of(twin.get("pos", [])) - if Vector2(mp.x - tpos.x, mp.z - tpos.z).length() > POS_EPS_M: - return true - if absf(tpos.y - mp.y) > POS_EPS_M: - return true - # 3 Achsen (Karte t_e166e656): der Vergleich läuft über die gespiegelte - # Euler-Orientierung (für reines Y-Drehen identisch zur alten rot_y-Regel). - var gespiegelt := SymmetryCore.mirror_rot_euler(mode, SvmapIO.objekt_rotation(src)) - var twin_euler := SvmapIO.objekt_rotation(twin) - var trot := fposmod(twin_euler.y - gespiegelt.y, 360.0) - var rotd := minf(trot, 360.0 - trot) - if rotd > ROT_EPS_DEG: - return true - var kipp := fposmod(twin_euler.x - gespiegelt.x + 180.0, 360.0) - 180.0 - if absf(kipp) > ROT_EPS_DEG: - return true - kipp = fposmod(twin_euler.z - gespiegelt.z + 180.0, 360.0) - 180.0 - if absf(kipp) > ROT_EPS_DEG: - return true - if absf(float(twin.get("scale", 1.0)) - float(src.get("scale", 1.0))) > VALUE_EPS: - return true - if str(twin.get("id", "")) != str(src.get("id", "")): - return true - var s_tint: Variant = src.get("tint", null) - var t_tint: Variant = twin.get("tint", null) - if (s_tint is Array) != (t_tint is Array): - return true - if s_tint is Array and t_tint is Array: - var sa: Array = s_tint - var ta: Array = t_tint - if (sa as Array).size() != (ta as Array).size(): - return true - for k in sa.size(): - if absf(float(sa[k]) - float(ta[k])) > VALUE_EPS: - return true - return false - - -static func _analyze_objects(doc: Dictionary, mode: int, an: Dictionary) -> void: - var objects: Array = doc.get("objects", []) - var items: Array = [] - for i in objects.size(): - var obj = objects[i] - if not (obj is Dictionary): - continue - var pos: Array = obj.get("pos", []) - if (pos as Array).size() < 3: - continue - items.append({"idx": i, "pos": _pos_of(pos)}) - var paired := _pair_items(mode, doc, items) - var pairs: Array = paired["pairs"] - var diff_n := 0 - for p in pairs: - var low_i: int = p["low"] - var high_i: int = p["high"] - var low_ok: bool = _valid_link(objects, low_i) == high_i - var high_ok: bool = _valid_link(objects, high_i) == low_i - if not (low_ok and high_ok): - an["links"] = int(an["links"]) + 1 - var donor: Dictionary = objects[low_i] - var twin: Dictionary = objects[high_i] - var differs := _obj_pair_differs(donor, twin, p["mirror"], mode) - if differs: - diff_n += 1 - _push_dev(an, "Objekt #%d" % low_i) - an["objects"]["pairs"] = pairs - an["objects"]["singles_low"] = paired["singles_low"] - an["objects"]["singles_high"] = paired["singles_high"] - an["objects"]["diff"] = diff_n - for idx in (paired["singles_low"] as Array) + (paired["singles_high"] as Array): - _push_dev(an, "Objekt #%d hat keinen Zwilling" % int(idx)) - - -# ------------------------------------------------------------------ Spawns -- -## Nur Teams 0/1 (TDM-Konvention wie M4): der Spiegel-Zwilling eines Spawn- -## Punkts liegt im GEGNER-Team. Kopplung läuft über design_notes.spawn_mirror. - -static func _spawn_items(doc: Dictionary) -> Array: - var items: Array = [] - for team in [0, 1]: - for p in SpawnOps.points(doc, team): - if not (p is Dictionary): - continue - var pos: Array = p.get("pos", []) - if (pos as Array).size() < 3: - continue - items.append({ - "team": team, - "id": str(p.get("id", "")), - "pos": _pos_of(pos), - }) - return items - - -static func _spawn_linked(doc: Dictionary, pid: String) -> String: - return SpawnToolScript.spawn_mirror_partner(doc, pid) - - -static func _analyze_spawns(doc: Dictionary, mode: int, an: Dictionary) -> void: - var items := _spawn_items(doc) - var paired := _pair_items_spawn(mode, doc, items) - var pairs: Array = paired["pairs"] - var diff_n := 0 - for p in pairs: - var low_ok: bool = _spawn_linked(doc, str(p["low_id"])) == str(p["high_id"]) - var high_ok: bool = _spawn_linked(doc, str(p["high_id"])) == str(p["low_id"]) - if not (low_ok and high_ok): - an["links"] = int(an["links"]) + 1 - var donor: Dictionary = p["low_point"] - var mp := SymmetryCore.mirror_point(mode, donor["pos"], _center_of(doc)) - var twin: Dictionary = p["high_point"] - if Vector2(mp.x - twin["pos"].x, mp.z - twin["pos"].z).length() > POS_EPS_M: - diff_n += 1 - _push_dev(an, "Spawn-Punkt %s" % str(p["low_id"])) - an["spawns"]["pairs"] = pairs - an["spawns"]["singles_low"] = paired["singles_low"] - an["spawns"]["singles_high"] = paired["singles_high"] - an["spawns"]["diff"] = diff_n - for s in (paired["singles_low"] as Array) + (paired["singles_high"] as Array): - _push_dev(an, "Spawn-Punkt %s hat keinen Zwilling" % str(s["id"])) - - -## Spawn-Variante der Paarung: items tragen team/id; Singles bleiben Objekte -## ({team, id, pos}) statt idx (Spawn-Punkte hängen an Teams, nicht am Array). -static func _pair_items_spawn(mode: int, doc: Dictionary, items: Array) -> Dictionary: - var out := {"pairs": [], "singles_low": [], "singles_high": []} - var low_pool: Array = [] - var high_pool: Array = [] - for it in items: - var side: String = _side_of(mode, it["pos"], doc) - if side == "self": - continue - if side == "low": - low_pool.append(it) - else: - high_pool.append(it) - var used: Dictionary = {} - for d in low_pool: - var m := _mirror(mode, doc, d["pos"]) - var best: int = -1 - var best_d: float = PAIR_TOLERANCE_M - for k in high_pool.size(): - if used.has(k): - continue - var t: Dictionary = high_pool[k] - var dxy := Vector2(m.x - t["pos"].x, m.z - t["pos"].z).length() - if dxy <= best_d: - best = k - best_d = dxy - if best >= 0: - used[best] = true - out["pairs"].append({ - "low_team": int(d["team"]), "low_id": str(d["id"]), - "high_team": int(high_pool[best]["team"]), - "high_id": str(high_pool[best]["id"]), - "low_point": d, "high_point": high_pool[best], - }) - for k in high_pool.size(): - if not used.has(k): - out["singles_high"].append(high_pool[k]) - for d in low_pool: - var paired := false - for p in out["pairs"]: - if str(p["low_id"]) == str(d["id"]): - paired = true - break - if not paired: - out["singles_low"].append(d) - return out - - -# ---------------------------------------------------------------- Terrain --- - -## Abweichende Zell-PAARE (je einmal, kanonisch = lex-erste Zelle des Paares). -static func _analyze_terrain(doc: Dictionary, mode: int, an: Dictionary) -> void: - var terrain: Dictionary = doc.get("terrain", {}) - var res := int(terrain.get("resolution", 0)) - if res < 2: - return - var heights := SvmapIO.decode_heights(terrain) - if heights.size() < res * res: - return - var cells: Array = an["terrain_cells"] - var eps := HEIGHT_EPS_M # absolut in Metern - for j in res: - for i in res: - var mc := SymmetryCore.mirror_cell(mode, i, j, res) - if mc.x == i and mc.y == j: - continue - # Nur das lex-erste Paarmitglied behandeln (keine Doppel-Meldung). - var is_low := i < mc.x or (i == mc.x and j < mc.y) - if not is_low: - continue - var ia := j * res + i - var ib := mc.y * res + mc.x - var dh := absf(heights[ia] - heights[ib]) - if dh > eps: - cells.append(Vector2i(i, j)) - if cells.size() <= MAX_EXAMPLES: - _push_dev(an, "Boden (%d,%d)" % [i, j]) - # Material auf seinem eigenen Raster (Byte exakt vergleichen). - var mres := SvmapIO.material_resolution(terrain) - var mats := SvmapIO.decode_materials(terrain) - if mres < 2 or mats.size() < mres * mres: - return - var mix := SvmapIO.decode_mix(terrain) # weiche Ränder: b + Anteil mitvergleichen - var mb: PackedByteArray = mix[0] - var mw: PackedByteArray = mix[1] - var mcells: Array = an["material_cells"] - for j in mres: - for i in mres: - var mc := SymmetryCore.mirror_cell(mode, i, j, mres) - if not (i < mc.x or (i == mc.x and j < mc.y)): - continue - var ia := j * mres + i - var ib := mc.y * mres + mc.x - if mats[ia] != mats[ib] or mb[ia] != mb[ib] or mw[ia] != mw[ib]: - mcells.append(Vector2i(i, j)) - if mcells.size() <= MAX_EXAMPLES: - _push_dev(an, "Boden-Material (%d,%d)" % [i, j]) - - -# ----------------------------------------------------------------- check() -- - -## Klartext-Bericht (nur lesen). report: {"ok": bool, "text": String, -## "deviations": Array}. „Alles symmetrisch ✓“ / „N Stellen weichen ab: …“. -static func check(doc: Dictionary, mode: int) -> Dictionary: - if mode == SymmetryCore.Mode.OFF: - return {"ok": false, - "text": "Der Symmetrie-Modus ist Aus — erst einen Modus wählen (Punkt / Achse), dann prüfen.", - "deviations": [], "analyze": analyze(doc, mode)} - var an := analyze(doc, mode) - var devs: Array = an["deviations"] - var total := int(an["total_deviations"]) - var text := "" - if total == 0: - text = "Alles symmetrisch ✓" - else: - var shown: Array = [] - for d in devs: - shown.append(str(d)) - var rest := total - shown.size() - var listing := ", ".join(PackedStringArray(shown)) - if rest > 0: - listing += " … und %d weitere" % rest - text = "%d Stellen weichen ab: %s" % [total, listing] - return {"ok": total == 0, "text": text, "deviations": devs, - "analyze": an} - - -# ----------------------------------------------------------------- apply() -- - -## Karte angleichen. quelle_hoch=false → links/vorn ist die Quelle (Gewinner -## bei Widersprüchen), true → rechts/hinten. Mutiert doc IN PLACE (Pattern -## wie die übrigen Tools: der Aufrufer snapshotet drum herum für EIN Undo). -## Rückgabe: {"ok": bool, "report": Klartext (mehrzeilig), "counts": {...}}. -static func apply(doc: Dictionary, mode: int, quelle_hoch: bool) -> Dictionary: - if mode == SymmetryCore.Mode.OFF: - return {"ok": false, "report": "Der Symmetrie-Modus ist Aus — ohne Modus weiß ich nicht, wie gespiegelt werden soll.", - "counts": {}} - var an := analyze(doc, mode) - var c := { - "objects_added": 0, "objects_fixed": 0, "objects_linked": 0, - "spawns_added": 0, "spawns_fixed": 0, "spawns_linked": 0, - "terrain_cells": 0, "skipped": 0, - } - _apply_objects(doc, mode, an, quelle_hoch, c) - _apply_terrain(doc, mode, an, quelle_hoch, c) - # Spawns ZULETZT: die Zwillinge sitzen auf der Terrain-Höhe — die stimmt - # erst nach dem Boden-Ausgleich (M2/M4-Konvention: y = Terrainhöhe). - _apply_spawns(doc, mode, an, quelle_hoch, c) - return {"ok": true, "counts": c, "report": _apply_report(c, quelle_hoch, mode)} - - -static func _apply_report(c: Dictionary, quelle_hoch: bool, mode: int) -> String: - var erg: Array = [] - for entry in [["objects_added", "Objekte ergänzt"], - ["spawns_added", "Spawn-Punkte ergänzt"], ["terrain_cells", "Bodenstellen angeglichen"], - ["objects_fixed", "Objekt-Widersprüche"], - ["spawns_fixed", "Spawn-Widersprüche"], ["objects_linked", "Objekt-Paare verknüpft"], - ["spawns_linked", "Spawn-Paare verknüpft"]]: - var n := int(c[entry[0]]) - if n > 0: - erg.append("%d %s" % [n, entry[1]]) - if erg.is_empty(): - return "Nichts zu tun — die Karte ist schon symmetrisch ✓" - var sides := side_labels(mode) - var conflict_sum := int(c["objects_fixed"]) + int(c["spawns_fixed"]) + int(c["terrain_cells"]) - var text := "Fertig ✓ — " + ", ".join(PackedStringArray(erg)) - if conflict_sum > 0: - text += ". Bei %d Widersprüchen hat %s gewonnen" % [conflict_sum, str(sides[1] if quelle_hoch else sides[0])] - return text + ". Ein Strg+Z macht alles rückgängig." - - -static func _write_object_from(twin: Dictionary, donor: Dictionary, mp: Vector3, - mode: int) -> void: - twin["pos"] = [mp.x, mp.y, mp.z] - # 3 Achsen (Karte t_e166e656): Kippen wird mitgespiegelt; für reines - # Y-Drehen exakt die alte mirror_rot_y-Regel (gleiche Zahlenwerte). - SvmapIO.rot_setzen(twin, SymmetryCore.mirror_rot_euler( - mode, SvmapIO.objekt_rotation(donor))) - twin["scale"] = donor.get("scale", 1.0) - if donor.has("tint"): - twin["tint"] = (donor["tint"] as Array).duplicate() - else: - twin.erase("tint") - twin["id"] = donor.get("id", "") - - -static func _apply_objects(doc: Dictionary, mode: int, an: Dictionary, - quelle_hoch: bool, c: Dictionary) -> void: - var objects: Array = doc.get("objects", []) - if (objects as Array).is_empty(): - return - # a) Paare: verknüpfen + Widersprüche zugunsten der Quelle entscheiden. - for p in (an["objects"]["pairs"] as Array): - var low_i: int = p["low"] - var high_i: int = p["high"] - var donor_i: int = high_i if quelle_hoch else low_i - var twin_i: int = low_i if quelle_hoch else high_i - var donor: Dictionary = objects[donor_i] - var twin: Dictionary = objects[twin_i] - var key_d := SymmetryCore.sym_of(donor) - var key_t := SymmetryCore.sym_of(twin) - if key_d != key_t or key_d.is_empty(): - # Ohne/widerstreitende Kopplung: frische gemeinsame Kennung. - _fresh_pair_link(doc, objects, donor_i, twin_i) - c["objects_linked"] = int(c["objects_linked"]) + 1 - var mp := SymmetryCore.mirror_point(mode, _pos_of(donor.get("pos", [])), _center_of(doc)) - if _obj_pair_differs(donor, twin, mp, mode): - _write_object_from(twin, donor, mp, mode) - c["objects_fixed"] = int(c["objects_fixed"]) + 1 - # b) Zwillinglose ergänzen (aus welcher Seite auch immer — nichts gelöscht). - for idx in (an["objects"]["singles_low"] as Array) + (an["objects"]["singles_high"] as Array): - var res := ObjectOps.symmetry_place_twin(doc, int(idx), mode) - if int(res["twin"]) >= 0: - c["objects_added"] = int(c["objects_added"]) + 1 - else: - c["skipped"] = int(c["skipped"]) + 1 - - -static func _apply_terrain(doc: Dictionary, mode: int, an: Dictionary, - quelle_hoch: bool, c: Dictionary) -> void: - _apply_materials(doc, mode, an, quelle_hoch, c) - var cells: Array = an["terrain_cells"] - if (cells as Array).is_empty(): - return - var terrain: Dictionary = doc.get("terrain", {}) - var res := int(terrain.get("resolution", 0)) - if res < 2: - return - var heights := SvmapIO.decode_heights(terrain) - var hmin := float(terrain.get("min_height_m", 0.0)) - var hmax := float(terrain.get("max_height_m", 1.0)) - for cell in cells: - var cc: Vector2i = cell - var mc := SymmetryCore.mirror_cell(mode, cc.x, cc.y, res) - var src := cc if not quelle_hoch else mc - var dst := mc if not quelle_hoch else cc - var si: int = src.y * res + src.x - var di: int = dst.y * res + dst.x - heights[di] = heights[si] - c["terrain_cells"] = int(c["terrain_cells"]) + 1 - terrain["heightmap_r16_b64"] = TerrainField.encode(heights, hmin, hmax) - - -## Material-Schicht angleichen (eigenes feines Raster, Karte 24.10.). -static func _apply_materials(doc: Dictionary, mode: int, an: Dictionary, - quelle_hoch: bool, c: Dictionary) -> void: - var cells: Array = an.get("material_cells", []) - if cells.is_empty(): - return - var terrain: Dictionary = doc.get("terrain", {}) - var mres := SvmapIO.material_resolution(terrain) - var mats := SvmapIO.decode_materials(terrain) - if mres < 2 or mats.size() < mres * mres: - return - var mix := SvmapIO.decode_mix(terrain) - var mb: PackedByteArray = mix[0] - var mw: PackedByteArray = mix[1] - for cell in cells: - var cc: Vector2i = cell - var mc := SymmetryCore.mirror_cell(mode, cc.x, cc.y, mres) - var src := cc if not quelle_hoch else mc - var dst := mc if not quelle_hoch else cc - var di := dst.y * mres + dst.x - var si := src.y * mres + src.x - mats[di] = mats[si] - mb[di] = mb[si] - mw[di] = mw[si] - c["terrain_cells"] = int(c["terrain_cells"]) + 1 - terrain["materials_r8_b64"] = SvmapIO.encode_materials(mats) - SvmapIO.encode_mix(terrain, mb, mw) - - -static func _apply_spawns(doc: Dictionary, mode: int, an: Dictionary, - quelle_hoch: bool, c: Dictionary) -> void: - # a) Paare: verknüpfen (design_notes.spawn_mirror) + Quelle entscheidet. - for p in (an["spawns"]["pairs"] as Array): - var donor_team: int = int(p["high_team"]) if quelle_hoch else int(p["low_team"]) - var donor_id: String = str(p["high_id"]) if quelle_hoch else str(p["low_id"]) - var linked_d := _spawn_linked(doc, donor_id) - var twin_id: String = str(p["low_id"]) if quelle_hoch else str(p["high_id"]) - if linked_d != twin_id: - # Beide Richtungen sauber neu setzen, alte Partner auskoppeln. - _fresh_spawn_link(doc, donor_id, twin_id) - c["spawns_linked"] = int(c["spawns_linked"]) + 1 - var donor_point: Dictionary = p["low_point"] if not quelle_hoch else p["high_point"] - var mp := SymmetryCore.mirror_point(mode, donor_point["pos"], _center_of(doc)) - var twin_point: Dictionary = p["high_point"] if not quelle_hoch else p["low_point"] - if Vector2(mp.x - twin_point["pos"].x, mp.z - twin_point["pos"].z).length() > POS_EPS_M: - var msg := SpawnToolScript.spawn_mirror_move(doc, donor_team, donor_id, mode) - if not msg.is_empty(): - c["spawns_fixed"] = int(c["spawns_fixed"]) + 1 - # b) Zwillinglose ergänzen (Team wechselt beim Spiegeln — M4-Regel). - for s in (an["spawns"]["singles_low"] as Array) + (an["spawns"]["singles_high"] as Array): - var res := SpawnToolScript.spawn_mirror_add(doc, int(s["team"]), str(s["id"]), mode) - if bool(res["ok"]) and str(res["status"]).contains("gesetzt"): - c["spawns_added"] = int(c["spawns_added"]) + 1 - else: - c["skipped"] = int(c["skipped"]) + 1 diff --git a/src/editor/symmetry_ops.gd.uid b/src/editor/symmetry_ops.gd.uid deleted file mode 100644 index 1ba1588..0000000 --- a/src/editor/symmetry_ops.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://csb4dkvi508of diff --git a/src/editor/terrain_tool.gd b/src/editor/terrain_tool.gd deleted file mode 100644 index 0404d18..0000000 --- a/src/editor/terrain_tool.gd +++ /dev/null @@ -1,765 +0,0 @@ -extends Node3D -## Terrain-Pinsel (M2, Karte t_9aba04f1): Höhenfeld heben/senken/glätten im -## 3D-Viewport — im Terrain-Modus (Chef-Grundsatz Sly: maximal easy + Spaß). -## -## Bedienung: -## Linksklick-Ziehen = gewählter Pinsel-Modus (Heben / Senken / Glätten) -## Strg+Linksklick = das Gegenteil (bei Heben senkt er, bei Senken hebt -## er — Invert-Konvention wie Blender/Photoshop; im -## Malen-Modus malt Strg+Klick Gras zurück). Karte -## t_2470de89: die RECHTE Maustaste gehört IMMER dem -## Freelook-Flug — sie startet hier keinen Strich mehr. -## Der ganze Strich = EIN Undo-Eintrag (Strg+Z stellt die Form VOR dem -## Strich wieder her, nicht nur eine Zwischenstufe). -## -## Feedback: Pinsel-Ring folgt dem Cursor AUF dem Gelände (ray-march auf das -## Höhenfeld), das Mesh folgt dem Strich LIVE (Vertices pro Frame neu). -## -## Der Doc wird nur ZUM Strich-Ende verändert (encode → heightmap_r16_b64) -## — während des Strichs lebt ein dekodiertes PackedFloat32Array, das Mesh -## liest daraus. Undo/Redo läuft über die gemeinsame ActionHistory (terrain-Block). - -const SMOOTH_RATE_DIVISOR := 20.0 # Stärke-Slider (m/s) → Glätt-Tempo (Anteil/s) -const MODE_LABELS := ["Heben", "Senken", "Glätten", "Malen", "Einebnen", "Rampe"] -const FLATTEN_RATE_DIVISOR := 8.0 # Stärke-Slider → Einebnen-Tempo (Anteil/s) - -var main # Hauptfenster (script-erweitert, Variant) -var camera: Camera3D -var view_builder # TerrainMesh-Ansicht (script-erweitert, Variant) -var interaction # Objekt-Interaktion (für Modus-Wechsel) - -var active := false -var brush_mode: int = TerrainField.Mode.RAISE -var brush_radius := 12.0 # Meter -## Kante beim Malen: 0 = hart, 1 = ganz weich (Karte 25.10.). -var brush_weichheit := 0.4 -## Pinsel-Falloff (Karte 25.10.): 0 = hart (linear), 1 = weich (quadratisch). -var brush_falloff := 0.5 -## Druck 0.05–1 (Pen-Druck / Controller-Trigger / Maus = 1.0), skaliert die Stärke. -var pressure := 1.0 -var brush_strength := 8.0 # Meter pro Sekunde (Heben/Senken) -var paint_material: int = 0 # Material-ID im Malen-Modus (0=Gras, 1=Sand, 2=Fels) - -# Stroke-Zustand -var _stroking := false -var _stroke_mode: int = TerrainField.Mode.RAISE -var _stroke_material: int = 0 -var _flatten_target := 0.0 # Einebnen: Höhe unter dem Cursor beim Strichstart -var _ramp_a := Vector2.ZERO # Rampe: Startpunkt (Welt-X/Z) + Höhe -var _ramp_ha := 0.0 -var _ramp_b := Vector2.ZERO # Rampe: aktueller Endpunkt -var _heights := PackedFloat32Array() -var _mats := PackedByteArray() # Material-Schicht (res²) — seit _refresh_ - # _from_doc immer dekodiert (t_55ed041a), - # Mal-Strich schreibt live hinein. -var _res := 0 -var _mres := 0 # Raster der Material-Schicht (feines Raster, Karte 24.10.; alt = _res) -var _mix_b := PackedByteArray() # zweites Material je Punkt (weiche Ränder, Karte 25.10.) -var _mix_w := PackedByteArray() # Anteil des zweiten Materials 0–255 -var _sx := 0.0 -var _sz := 0.0 -var _hmin := 0.0 -var _hmax := 0.0 -var _cursor_valid := false -var _cursor := Vector3.ZERO - -# Pinsel-Ring -var _ring: MeshInstance3D -var _ramp_line: MeshInstance3D # Rampen-Vorschau: Linie Start → Cursor -var _ring_radius := -1.0 -var _ring_mode := -1 - - -func setup(p_main, p_camera: Camera3D, p_builder, p_interaction) -> void: - main = p_main - camera = p_camera - view_builder = p_builder - interaction = p_interaction - _ensure_ring() - - -func _ensure_ring() -> void: - if _ring != null and is_instance_valid(_ring): - return - _ring = MeshInstance3D.new() - _ring.visible = false - add_child(_ring) - _ramp_line = MeshInstance3D.new() - _ramp_line.visible = false - _ramp_line.mesh = ImmediateMesh.new() - var lm := StandardMaterial3D.new() - lm.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - lm.albedo_color = Color(1.0, 0.85, 0.3) - lm.no_depth_test = true - _ramp_line.material_override = lm - add_child(_ramp_line) - - -# ------------------------------------------------------------ Aktivierung --- - -## Terrain-Modus einschalten. false = abgelehnt (Auflösungs-Limit) — main -## bleibt dann im Objekt-Modus und erklärt warum. -func activate() -> bool: - var terrain: Dictionary = main.doc.get("terrain", {}) - var res := int(terrain.get("resolution", 0)) - if res > TerrainField.EDITOR_MAX_RESOLUTION: - main.call("_set_status", - "Diese Map hat eine Terrain-Auflösung von %d — das Editor-MVP formt Terrain nur bis %d (Performance). Neu angelegte Maps erfüllen das automatisch." % [res, TerrainField.EDITOR_MAX_RESOLUTION], - true) - return false - if not _refresh_from_doc(): - return false - active = true - _stroking = false - _ring.visible = false - return true - - -func deactivate() -> void: - active = false - if _stroking: - _end_stroke() - if _ring != null and is_instance_valid(_ring): - _ring.visible = false - if _ramp_line != null and is_instance_valid(_ramp_line): - _ramp_line.visible = false - - -## Nach Undo/Redo/Laden/Neue-Map: Feld neu dekodieren (Cache ist sonst alt). -func refresh_from_doc() -> bool: - if not _refresh_from_doc(): - return false - return true - - -func _refresh_from_doc() -> bool: - var terrain: Dictionary = main.doc.get("terrain", {}) - if terrain.is_empty(): - return false - _res = int(terrain.get("resolution", 0)) - _sx = float(terrain.get("size_x_m", 0.0)) - _sz = float(terrain.get("size_z_m", 0.0)) - _hmin = float(terrain.get("min_height_m", 0.0)) - _hmax = float(terrain.get("max_height_m", 0.0)) - if _res < 2 or _sx <= 0.0 or _sz <= 0.0 or _hmax <= _hmin: - return false - _heights = SvmapIO.decode_heights(terrain) - # Material-Schicht mit dekodieren (Karte t_55ed041a): der Live-Rebuild - # beim Heben/Senken/Glätten braucht sie, sonst fällt das Mesh während - # des Strichs auf alles-Gras zurück (Sand/Fels „verschwinden" live). - _mats = SvmapIO.decode_materials(terrain) - _mres = SvmapIO.material_resolution(terrain) - _load_mix(terrain) - return _heights.size() >= _res * _res - - -# ------------------------------------------------------------ Pinsel-Optionen - -func set_brush_mode(mode: int) -> void: - # Clamp bis PAINT (3) — der alte Clamp 0..2 hätte den Malen-Modus still - # zu Glätten degradiert (Karte t_55257792, Ziffer 4 = Malen). - brush_mode = clampi(mode, 0, MODE_LABELS.size() - 1) - _refresh_ring_mesh() - - -func set_radius(m: float) -> void: - brush_radius = clampf(m, 1.0, 64.0) # ab 1 m (Karte 25.10., feines Raster) - _refresh_ring_mesh() - - -## Misch-Schicht (Karte 25.10.) aus dem terrain-Block — fehlt sie, Nullen. -func _load_mix(terrain: Dictionary) -> void: - var mix := SvmapIO.decode_mix(terrain) - _mix_b = mix[0] - _mix_w = mix[1] - - -## Materialpunkt als ein int (a | b<<8 | w<<16) — Spiegeln kopiert alle drei. -func _punkt(idx: int) -> int: - return int(_mats[idx]) | (int(_mix_b[idx]) << 8) | (int(_mix_w[idx]) << 16) - - -## Anteil (0–255) des Materials m an einem gepackten Punkt. -static func _anteil(v: int, m: int) -> int: - var a := v & 0xFF - var b := (v >> 8) & 0xFF - var w := (v >> 16) & 0xFF - return (255 - w if a == m else 0) + (w if b == m else 0) - - -func _setze_punkt(idx: int, v: int) -> void: - _mats[idx] = v & 0xFF - _mix_b[idx] = (v >> 8) & 0xFF - _mix_w[idx] = (v >> 16) & 0xFF - - -## Regler „Kante: hart ↔ weich“ (nur Malen). -func set_weichheit(w: float) -> void: - brush_weichheit = clampf(w, 0.0, 1.0) - - -func set_falloff(f: float) -> void: - brush_falloff = clampf(f, 0.0, 1.0) - - -## Druck setzen (XR-Controller-Trigger 0–1 ruft das direkt; Pen/Maus laufen -## über _unhandled_input). Wert wird über TerrainField.pressure_of begrenzt. -func set_pressure(p: float) -> void: - pressure = TerrainField.pressure_of(p, 0.0) - - -func set_strength(mps: float) -> void: - brush_strength = clampf(mps, 1.0, 20.0) - - -func set_paint_material(id: int) -> void: - paint_material = clampi(id, 0, SvmapIO.MATERIAL_IDS.size() - 1) - _refresh_ring_mesh() - - -# --------------------------------------------------------------- Eingaben --- - -func _unhandled_input(event: InputEvent) -> void: - var p := MousePointer.from_input(event) - if p == null: - return - # Stift: pressure > 0; Maus meldet 0 (oder 1) → bleibt voll. - if p.kind == PointerEvent.Kind.MOVE: - p.pressure = TerrainField.pressure_of(p.pressure, _trigger_axis()) - if handle_pointer(p): - get_viewport().set_input_as_handled() - - -## Rechte Maustaste kommt hier nie an: sie gehört mit absolutem Vorrang dem -## Freelook-Flug (orbit_camera.gd, Karte t_2470de89), in jedem Werkzeugzustand. -func handle_pointer(p: PointerEvent) -> bool: - if not active: - return false - match p.kind: - PointerEvent.Kind.MOVE: - _update_cursor(p.position) - pressure = p.pressure - PointerEvent.Kind.PRESS: - # Karte t_2470de89: Strg = Invert-Modifier. Heben↔Senken - # tauschen (Blender/Photoshop-Konvention), im Malen-Modus - # malt Strg+Klick Gras zurück (alter Radierer-Weg). - var mode := brush_mode - var mat := -1 - if p.ctrl: - match brush_mode: - TerrainField.Mode.RAISE: - mode = TerrainField.Mode.LOWER - TerrainField.Mode.LOWER: - mode = TerrainField.Mode.RAISE - TerrainField.Mode.PAINT: - mat = 0 # Gras zurückmalen - _begin_stroke(mode, mat) - return true - PointerEvent.Kind.RELEASE: - _end_stroke() - return true - return false - - -## Gamepad-Trigger (rechts) des ersten Pads; 0 ohne Pad. Nur Eingabe-Lesen, -## keine OS-Annahme. -func _trigger_axis() -> float: - var pads := Input.get_connected_joypads() - if pads.is_empty(): - return 0.0 - return Input.get_joy_axis(pads[0], JOY_AXIS_TRIGGER_RIGHT) - - -func _update_cursor(viewport_pos: Vector2) -> void: - var hit: Variant = TerrainField.raycast(_heights, _res, _sx, _sz, - camera.project_ray_origin(viewport_pos), camera.project_ray_normal(viewport_pos)) - if hit == null: - _cursor_valid = false - if _ring != null: - _ring.visible = false - return - _cursor_valid = true - _cursor = hit as Vector3 - var half_x := _sx * 0.5 - var half_z := _sz * 0.5 - _cursor.x = clampf(_cursor.x, -half_x, half_x) - _cursor.z = clampf(_cursor.z, -half_z, half_z) - # Ring minimal über dem Gelände, damit er nicht im Mesh verschwindet. - _ring.position = Vector3(_cursor.x, _height_at_stroke(_cursor.x, _cursor.z) + 0.3, _cursor.z) - _ring.visible = true - - -func _height_at_stroke(x: float, z: float) -> float: - return TerrainField.height_at(_heights, _res, _sx, _sz, x, z) - - -# ----------------------------------------------------------------- Stroke --- - -func _begin_stroke(mode: int, material_id: int = -1) -> void: - if _stroking: - return - if not _cursor_valid: - main.call("_set_status", - "Der Pinsel braucht einen Punkt AUF dem Gelände — führe die Maus über die Karte und halte dann die Maustaste gedrückt.", - true) - return - _stroke_mode = mode - _stroke_material = paint_material if material_id < 0 else material_id - _stroking = true - if mode == TerrainField.Mode.FLATTEN: - _flatten_target = _height_at_stroke(_cursor.x, _cursor.z) - elif mode == TerrainField.Mode.RAMP: - _ramp_a = Vector2(_cursor.x, _cursor.z) - _ramp_ha = _height_at_stroke(_cursor.x, _cursor.z) - _ramp_b = _ramp_a - # Im Malen-Modus lebt die Material-Schicht während des Strichs - # (dekodiert — Legacy-Maps ohne Schicht starten mit alles-Gras). - if mode == TerrainField.Mode.PAINT: - _mats = SvmapIO.decode_materials(main.doc.get("terrain", {})) - _mres = SvmapIO.material_resolution(main.doc.get("terrain", {})) - _load_mix(main.doc.get("terrain", {})) - _refresh_ring_mesh() - main.call("_set_status", "%s läuft — Maustaste gedrückt halten. Beim Loslassen wird der ganze Strich EIN Rückgängig-Schritt (Strg+Z)." % _stroke_label()) - - -## Lesbarer Stroke-Name: Heben/Senken/Glätten bzw. „Malen (Sand)". -func _stroke_label() -> String: - if _stroke_mode == TerrainField.Mode.PAINT: - return "Malen (%s)" % SvmapIO.MATERIAL_IDS[clampi(_stroke_material, 0, SvmapIO.MATERIAL_IDS.size() - 1)] - return MODE_LABELS[_stroke_mode] - - -func _process(delta: float) -> void: - if not _stroking or not _cursor_valid: - return - if _stroke_mode == TerrainField.Mode.PAINT: - var painted := _paint_step(_cursor.x, _cursor.z) - if painted: - # Karte t_7a0a6b79: Malen lebt im Sub-Rect — update_terrain bekommt - # das betroffene Zellrechteck (inkl. Spiegelzellen) und leitet nur - # die Splat-Region neu ab; das Mesh selbst bleibt unangetastet - # (Vertex-Farben hängen NICHT vom Material ab). - if view_builder.has_method("set_terrain_mix"): - view_builder.call("set_terrain_mix", _mix_b, _mix_w) - view_builder.call("update_terrain", _heights, _mats, _splat_rect) - _ring.position.y = _height_at_stroke(_cursor.x, _cursor.z) + 0.3 - return - if _stroke_mode == TerrainField.Mode.RAMP: - # Rampe wirkt erst beim Loslassen — hier nur der Endpunkt + Ring-Hinweis. - _ramp_b = Vector2(_cursor.x, _cursor.z) - _update_ramp_line() - return - var amount := _step_amount(_stroke_mode, delta) - # Während des Strichs NICHT auf die Format-Range clampen — die zieht der - # Range-Expander danach nach (sonst friert Heben/Senken an der Kante ein). - var changed := _height_step(_cursor.x, _cursor.z, amount) - if changed: - _expand_range_if_needed() - # Karte t_55ed041a: Material-Schicht MITGEBEN — ohne sie hat der - # Live-Rebuild alles als Gras gerendert (Sand/Fels „verschwanden" - # während des Heben/Senk-Strichs und kehrten erst am Stroke-Ende - # mit dem Vollrebuild zurück). - view_builder.call("update_terrain", _heights, _mats) - _ring.position.y = _height_at_stroke(_cursor.x, _cursor.z) + 0.3 - - -## Stärke dieses Frames: Meter (Heben/Senken) bzw. Mischfaktor 0–1 (Glätten/ -## Einebnen) — skaliert mit dem Druck. -func _step_amount(mode: int, dt: float) -> float: - match mode: - TerrainField.Mode.SMOOTH: - return clampf(brush_strength / SMOOTH_RATE_DIVISOR * dt * pressure, 0.0, 1.0) - TerrainField.Mode.FLATTEN: - return clampf(brush_strength / FLATTEN_RATE_DIVISOR * dt * pressure, 0.0, 1.0) - return brush_strength * dt * pressure - - -## Höhe spannt das Höhenfeld automatisch auf, wenn der Pinsel über die -## Format-Grenzen (min/max_height) hinaus will — sonst wäre Senken auf einer -## frisch angelegten (flachen) Map unmöglich und langes Heben würde clampen. -## Die Range gehört zum terrain-Block → Undo stellt sie mit zurück. Spannweite -## bleibt ≤ 500 m (V6). -func _expand_range_if_needed() -> void: - var lo := TerrainField._min_h(_heights) - var hi := TerrainField._max_h(_heights) - if lo < _hmin: - _hmin = floorf(lo - 1.0) - if hi > _hmax: - _hmax = ceilf(hi + 1.0) - if _hmax - _hmin > 500.0: - if lo < _hmin: - _hmin = _hmax - 500.0 - else: - _hmax = _hmin + 500.0 - - -func _end_stroke() -> void: - if not _stroking: - return - _stroking = false - if _stroke_mode == TerrainField.Mode.RAMP: - _ramp_line.visible = false - if not _ramp_apply(): - main.call("_set_status", "Rampe: Start und Ende liegen zu nah beieinander — Klick, ziehen, loslassen.") - return # nichts geändert → kein leerer Undo-Eintrag - # Doc erst jetzt ändern: der GANZE Strich ist ein History-Eintrag. - var before: Dictionary = main.history.snapshot(["terrain"]) - var terrain: Dictionary = main.doc.get("terrain", {}) - if _stroke_mode == TerrainField.Mode.PAINT: - terrain["materials_r8_b64"] = SvmapIO.encode_materials(_mats) - SvmapIO.encode_mix(terrain, _mix_b, _mix_w) - main.history.commit("Boden gemalt (%s)" % SvmapIO.MATERIAL_IDS[clampi(_stroke_material, 0, SvmapIO.MATERIAL_IDS.size() - 1)], - before, main.history.snapshot(["terrain"])) - else: - terrain["min_height_m"] = _hmin - terrain["max_height_m"] = _hmax - terrain["heightmap_r16_b64"] = TerrainField.encode(_heights, _hmin, _hmax) - main.history.commit("Boden geformt (%s)" % MODE_LABELS[_stroke_mode], - before, main.history.snapshot(["terrain"])) - main.call("_on_terrain_stroke_committed") - - -## Rampe anwenden (Strichende): Start-Höhe = Höhe beim Klick, End-Höhe = Höhe -## unter dem Endpunkt. Breite = 2 × Radius. Symmetrie wie bei den Pinseln. -func _ramp_apply() -> bool: - if _ramp_a.distance_to(_ramp_b) < 1.0: - return false - var hb := _height_at_stroke(_ramp_b.x, _ramp_b.y) - var width := brush_radius * 2.0 - var snap := {} - var g := _world_to_grid(_ramp_a.x, _ramp_a.y) - if _sym_active(): - var g2 := _world_to_grid(_ramp_b.x, _ramp_b.y) - var r := _brush_region(g).merge(_brush_region(g2)) - snap = _snap_heights(r) - var changed := TerrainField.apply_ramp(_heights, _res, _sx, _sz, - _ramp_a, _ramp_b, _ramp_ha, hb, width, brush_falloff) - if changed and not snap.is_empty(): - _mirror_heights(snap, g) - if changed: - _expand_range_if_needed() - view_builder.call("update_terrain", _heights, _mats) - return changed - - -## Rampen-Vorschau: gelbe Linie vom Startpunkt zum Cursor (auf Geländehöhe). -func _update_ramp_line() -> void: - var im := _ramp_line.mesh as ImmediateMesh - im.clear_surfaces() - im.surface_begin(Mesh.PRIMITIVE_LINES) - im.surface_add_vertex(Vector3(_ramp_a.x, _ramp_ha + 0.5, _ramp_a.y)) - im.surface_add_vertex(Vector3(_ramp_b.x, _height_at_stroke(_ramp_b.x, _ramp_b.y) + 0.5, _ramp_b.y)) - im.surface_end() - _ramp_line.visible = true - - -## Programmgesteuerter Stroke (Demo/Screenshot-Hook): macht exakt, was eine -## Maus auch tun würde — inkl. History-Eintrag. -func demo_stroke(x: float, z: float, mode: int, seconds: float) -> void: - _refresh_from_doc() - _cursor = Vector3(x, 0.0, z) - _cursor_valid = true - _begin_stroke(mode) - var steps := int(ceil(seconds / 0.05)) - var dt := seconds / float(maxi(steps, 1)) - var save_x := _cursor.x - var save_z := _cursor.z - for i in steps: - var amount := _step_amount(mode, dt) - if mode == TerrainField.Mode.PAINT: - _paint_step(save_x, save_z) - continue - _height_step(save_x, save_z, amount) - _expand_range_if_needed() - _end_stroke() - _refresh_from_doc() - - -## Demo-Hook: Pinsel-Ring sichtbar an einer Weltposition parken (für -## Screenshots ohne echte Maus-Ereignisse). -func demo_park_brush(x: float, z: float) -> void: - _refresh_ring_mesh() - _cursor = Vector3(x, 0.0, z) - _cursor_valid = true - _ring.position = Vector3(x, _height_at_stroke(x, z) + 0.3, z) - _ring.visible = true - - -# ------------------------------------------------------------- Symmetrie ---- -## M2 (Karte t_f9eff526): Im Symmetrie-Modus (main.sym_mode ≠ AUS) schreibt -## jeder Strich seine Zellen EXAKT gespiegelt in die andere Kartenseite — -## Höhe ist ein Skalar → 1:1 identisch übernommen, Material ebenso. Die -## Zell-Abbildung kommt aus M1 (SymmetryCore.mirror_cell), nichts neu erfunden. -## -## Ablauf pro Pinsel-Schritt: -## 1. Pinsel EINMAL an der Strich-Position anwenden — bewusst NICHT zweimal -## (Strichpunkt + Spiegelpunkt): sonst bekämen Zellen im Überlappband den -## Effekt doppelt und an der Rastermitte entstünde ein Grat. -## 2. Die seit dem Snapshot geänderten Zellen des Pinsel-Rechtecks ermitteln -## und jede Änderung in die gespiegelte Schwesterzelle kopieren. -## Liegt der Strich genau auf der Mitte/Achse, bildet mirror_cell die Zellen -## auf sich selbst bzw. auf Partner mit IDENTISCHEm Wert ab (spiegelsymmetrischer -## Fußabdruck, gleicher Falloff-Abstand) → nichts wird gedoppelt. -## Überlappen Fußabdruck und Spiegelbild (Strich nahe der Mitte), gewinnt pro -## Zellpaar die Seite, die NÄHER am Strichpunkt liegt — die andere Hälfte ist -## exakte Kopie der Strich-Seite; bei exaktem Gleichstand entscheidet der -## kleinere Grid-Index (deterministisch, Row-major-Verarbeitung). -## Bei Modus AUS: keine Snapshot-/Kopierarbeit — exakt das alte Verhalten. - -## Zusätzlicher Rand um die grobe Pinsel-Region (TerrainField arbeitet mit -## floor/ceil ± 1; hier großzügig ± 2 — der Snapshot-Vergleich entscheidet -## ohnehin zellgenau, was wirklich geändert wurde). -const SYM_REGION_MARGIN := 2 - -func _sym_mode() -> int: - if main == null: - return SymmetryCore.Mode.OFF - # .get statt direkter Property: Haupts ohne sym_mode-Feld (z. B. alte - # Test-Stubs, Tools außerhalb des Editors) fallen auf AUS zurück — - # exakt das Verhalten vor M2. - var mode: Variant = main.get("sym_mode") - if mode == null or not (mode is int): - return SymmetryCore.Mode.OFF - return int(mode) - - -func _sym_active() -> bool: - return _sym_mode() != SymmetryCore.Mode.OFF - - -## Welt-X/Z → Raster-Koordinaten (gleiche Konvention wie TerrainField.height_at: -## Index 0 = −X/−Z-Ecke, x-Index läuft MIT +WeltX). -func _world_to_grid(x: float, z: float) -> Vector2: - return _world_to_grid_r(x, z, _res) - - -## Wie _world_to_grid, aber auf einem beliebigen Raster (Material: _mres). -func _world_to_grid_r(x: float, z: float, r: int) -> Vector2: - var last := float(r - 1) - return Vector2((x / _sx + 0.5) * last, (z / _sz + 0.5) * last) - - -## Grobes Rechteck um die Raster-Position (g), das den Pinsel-Fußabdruck -## jedes Modus garantiert abdeckt (Radius in Zellen + Margin). -func _brush_region(g: Vector2) -> Rect2i: - return _brush_region_r(g, _res) - - -## Wie _brush_region, auf dem Raster r (Material-Schicht: _mres). -func _brush_region_r(g: Vector2, r: int) -> Rect2i: - var cell_x := _sx / float(r - 1) - var cell_z := _sz / float(r - 1) - var rx := brush_radius / cell_x + float(SYM_REGION_MARGIN) - var rz := brush_radius / cell_z + float(SYM_REGION_MARGIN) - var x0 := maxi(int(floorf(g.x - rx)), 0) - var x1 := mini(int(ceilf(g.x + rx)), r - 1) - var z0 := maxi(int(floorf(g.y - rz)), 0) - var z1 := mini(int(ceilf(g.y + rz)), r - 1) - return Rect2i(x0, z0, x1 - x0 + 1, z1 - z0 + 1) - - -## Abstand einer Rasterzelle zum Strichpunkt in Metern (gleiche Zell-Metrik -## wie TerrainField.apply_brush: Zellindex-Abstand × Zellgröße). -func _cell_dist(pos: Vector2i, g: Vector2, cell_x: float, cell_z: float) -> float: - var dx := (float(pos.x) - g.x) * cell_x - var dz := (float(pos.y) - g.y) * cell_z - return sqrt(dx * dx + dz * dz) - - -## Ein Pinsel-Schritt HÖHE (Heben/Senken/Glätten) inkl. Spiegel-Kopie. -## amount: Meter (Heben/Senken) bzw. Mischfaktor 0–1 (Glätten) — unverändert -## zur bisherigen apply_brush-Semantik; ohne Clamp (Range-Expander zieht nach). -func _height_step(x: float, z: float, amount: float) -> bool: - var g := _world_to_grid(x, z) - var snap := {} - if _sym_active(): - snap = _snap_heights(_brush_region(g)) - var changed := TerrainField.apply_brush(_heights, _res, _sx, _sz, - -100000.0, 100000.0, x, z, brush_radius, _stroke_mode, amount, - brush_falloff, _flatten_target) - if changed and not snap.is_empty(): - _mirror_heights(snap, g) - return changed - - -## Ein Pinsel-Schritt MATERIAL (Malen) inkl. Spiegel-Kopie. -func _paint_step(x: float, z: float) -> bool: - # Material lebt auf seinem eigenen (feinen) Raster _mres (Karte 24.10.). - var g := _world_to_grid_r(x, z, _mres) - # VOR dem Pinsel: Zellrect des Fußabdrucks merken (deckt Spiegelzellen mit) - # — der Live-Splat-Refresh (t_7a0a6b79) leitet genau diese Region neu ab. - _splat_rect = _splat_region(g) - var snap := {} - if _sym_active() and _mats.size() >= _mres * _mres: - snap = _snap_mats(_brush_region_r(g, _mres)) - var changed := TerrainField.apply_material_brush_mix(_mats, _mix_b, _mix_w, _mres, - _sx, _sz, x, z, brush_radius, _stroke_material, brush_weichheit, pressure) - if changed and not snap.is_empty(): - _mirror_mats(snap, g) - return changed - - -## Snapshot {Vector2i(x, z) → Höhe} über das Pinsel-Rechteck (NUR bei -## Symmetrie AN erzeugt — bei AUS bleibt es bei exakt dem alten Verhalten). -func _snap_heights(rect: Rect2i) -> Dictionary: - var snap := {} - for z: int in range(rect.position.y, rect.end.y): - for x: int in range(rect.position.x, rect.end.x): - snap[Vector2i(x, z)] = _heights[z * _res + x] - return snap - - -## Spiegel-Pass für die Höhe: jede seit dem Snapshot geänderte Zelle wird in -## ihre gespiegelte Schwester kopiert (Strich-Seite ist Master, siehe oben). -func _mirror_heights(snap: Dictionary, g: Vector2) -> void: - var sym := _sym_mode() - var cell_x := _sx / float(_res - 1) - var cell_z := _sz / float(_res - 1) - var done := {} - var positions: Array = snap.keys() - # Row-major (kleinster Index zuerst): der Gleichstand-Tie-Break „kleinerer - # Index gewinnt“ ist damit deterministisch, und ein Paar wird genau einmal - # an seinem kleineren Index entschieden. - positions.sort_custom(func(a: Vector2i, b: Vector2i) -> bool: - return (a.y * _res + a.x) < (b.y * _res + b.x)) - for pos: Vector2i in positions: - if done.has(pos): - continue - var idx: int = pos.y * _res + pos.x - var mirror: Vector2i = SymmetryCore.mirror_cell(sym, pos.x, pos.y, _res) - done[pos] = true - if mirror == pos: - continue # Selbstabbildung (Rastermitte/Achse) — nichts zu kopieren - var midx: int = mirror.y * _res + mirror.x - var value: float = _heights[idx] - if snap.has(mirror): - # Beide Seiten wurden vom Pinsel geändert (Fußabdruck überlappt - # sein Spiegelbild): näher am Strichpunkt gewinnt, Gleichstand - # → kleinere Index (== diese pos, da Row-major zuerst kam). - if _cell_dist(mirror, g, cell_x, cell_z) < _cell_dist(pos, g, cell_x, cell_z): - value = _heights[midx] - _heights[idx] = value - _heights[midx] = value - done[mirror] = true - - -## Snapshot {Vector2i(x, z) → Material-ID} über das Pinsel-Rechteck. -func _snap_mats(rect: Rect2i) -> Dictionary: - var snap := {} - for z: int in range(rect.position.y, rect.end.y): - for x: int in range(rect.position.x, rect.end.x): - snap[Vector2i(x, z)] = _punkt(z * _mres + x) - return snap - - -## Spiegel-Pass für die Material-Schicht (identische Paar-Logik wie _mirror_heights). -func _mirror_mats(snap: Dictionary, g: Vector2) -> void: - var sym := _sym_mode() - var cell_x := _sx / float(_mres - 1) - var cell_z := _sz / float(_mres - 1) - var done := {} - var positions: Array = snap.keys() - positions.sort_custom(func(a: Vector2i, b: Vector2i) -> bool: - return (a.y * _mres + a.x) < (b.y * _mres + b.x)) - # Karte 25.10. (Sly: harte gerade Kanten mit Symmetrie): NUR Punkte spiegeln, - # die dieser Pinsel-Schritt wirklich verändert hat. Vorher wurde das ganze - # Snapshot-Quadrat auf die Gegenseite kopiert — weiche Verläufe drüben - # wurden an den Quadratkanten hart abgeschnitten. - for pos: Vector2i in positions: - if done.has(pos): - continue - done[pos] = true - var idx: int = pos.y * _mres + pos.x - if _punkt(idx) == int(snap[pos]): - continue # nicht bemalt → Gegenseite bleibt unangetastet - var mirror: Vector2i = SymmetryCore.mirror_cell(sym, pos.x, pos.y, _mres) - if mirror == pos: - continue - var midx: int = mirror.y * _mres + mirror.x - var value: int = _punkt(idx) - if snap.has(mirror) and _punkt(midx) != int(snap[mirror]): - # Beide Seiten bemalt (Pinsel überlappt sein Spiegelbild, z. B. nahe - # der Kartenmitte): der Wert mit dem GRÖSSEREN Anteil des Mal- - # Materials gewinnt. Vorher „näher am Strichpunkt“ — das zog entlang - # der Mittelsenkrechte eine harte gerade Kante durch weiche Verläufe - # (Sly 25.10.). Max ist stetig und symmetrisch. - if _anteil(_punkt(midx), _stroke_material) > _anteil(value, _stroke_material): - value = _punkt(midx) - _setze_punkt(idx, value) - done[mirror] = true - _setze_punkt(midx, value) - - -# ----------------------------------------------------------- Ring-Optik ----- - -func _refresh_ring_mesh() -> void: - if _ring == null: - return - if _ring_radius == brush_radius and _ring_mode == brush_mode: - return - _ring_radius = brush_radius - _ring_mode = brush_mode - var torus := TorusMesh.new() - torus.inner_radius = brush_radius - 0.25 - torus.outer_radius = brush_radius + 0.25 - torus.rings = 48 - torus.ring_segments = 8 - _ring.mesh = torus - var mat := StandardMaterial3D.new() - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - match brush_mode: - TerrainField.Mode.RAISE: - mat.albedo_color = Color(0.4, 1.0, 0.45, 0.9) - TerrainField.Mode.LOWER: - mat.albedo_color = Color(1.0, 0.45, 0.3, 0.9) - TerrainField.Mode.PAINT: - # Ring in der Farbe des gewählten Materials (Karte t_603ec1a8). - var mc: int = clampi(paint_material, 0, SvmapIO.MATERIAL_IDS.size() - 1) - mat.albedo_color = (terrain_mesh_color(mc) as Color) - mat.albedo_color.a = 0.9 - TerrainField.Mode.FLATTEN: - mat.albedo_color = Color(1.0, 0.85, 0.3, 0.9) - TerrainField.Mode.RAMP: - mat.albedo_color = Color(0.85, 0.5, 1.0, 0.9) - _: - mat.albedo_color = Color(0.4, 0.7, 1.0, 0.9) - mat.emission_enabled = true - mat.emission = (mat.albedo_color as Color) * 0.5 - _ring.material_override = mat - - -## Material-ID → Renderer-Farbe (gleiche Palette wie terrain_mesh.gd). -func terrain_mesh_color(id: int) -> Color: - match id: - 1: - return Color(0.78, 0.70, 0.45) # Sand - 2: - return Color(0.45, 0.44, 0.42) # Fels - _: - return Color(0.30, 0.45, 0.22) # Gras - - -# ------------------------------------------------ Live-Splat-Sub-Rect (Karte -# t_7a0a6b79): Zellrechteck des letzten Mal-Schritts für das Live-Update der -# Splat-Gewichtstextur. Am Dateiende angefügt (Karten-Regel). - -## Zellrect des letzten Mal-Schritts (Pinsel-Fußabdruck ∪ gespiegelte -## Schwesterzellen) — vom Stroke-Code als 3. Parameter an update_terrain -## (view_builder) weitergereicht. -var _splat_rect := Rect2i() - - -## Zellrect des Pinsel-Fußabdrucks (∪ Spiegelzellen): dieselben Region- -## Grenzen wie apply_material_brush, mit dem SYM_REGION_MARGIN-Rand — der -## deckt auch die Kernel-Nachbarschaft der Splat-Ableitung mit ab. -## g und Ergebnis im Material-Raster (_mres) — so rechnet auch die Splat. -func _splat_region(g: Vector2) -> Rect2i: - var rect := _brush_region_r(g, _mres) - var sym := _sym_mode() - if sym == SymmetryCore.Mode.OFF: - return rect - var a := SymmetryCore.mirror_cell(sym, rect.position.x, rect.position.y, _mres) - var b := SymmetryCore.mirror_cell(sym, rect.end.x - 1, rect.end.y - 1, _mres) - return rect.merge(Rect2i(mini(a.x, b.x), mini(a.y, b.y), - absi(a.x - b.x) + 1, absi(a.y - b.y) + 1)) diff --git a/src/editor/terrain_tool.gd.uid b/src/editor/terrain_tool.gd.uid deleted file mode 100644 index 101a4a2..0000000 --- a/src/editor/terrain_tool.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bo7va0ktrfvrj diff --git a/src/editor/test_run.gd b/src/editor/test_run.gd deleted file mode 100644 index 018b744..0000000 --- a/src/editor/test_run.gd +++ /dev/null @@ -1,110 +0,0 @@ -class_name TestRun -extends RefCounted -## ALT (Karte t_1cdc1a72): dieser Client-Start ist seit dem Lauf-Modus im -## Map-Builder selbst NICHT mehr der Standard-Weg — „▶ Karte testen" startet -## jetzt IN DIESER APP (src/editor/playtest/, kein Client-Ordner, kein -## zweiter Prozess, kein VR). Der Rückbau dieser Datei kommt in einer -## späteren Karte; bis dahin bleibt die Export-/Such-Logik als Fallback -## erhalten und getestet (tests/test_testrun.gd). -## -## Ursprünglicher Zweck (Karte t_b84af40f): Export der AKTUELLEN Map nach Temp -## + Start des scopedvr-client als EIGENES Fenster im Testlauf-Modus -## (--testmap ). Der Editor bleibt offen — der Client ist ein eigener -## Prozess; das Spiel beendet sich selbst sauber (ESC = „Zurück zum Editor"). -## -## Client-Suche (erste Treffer-Zeile gewinnt): -## 1. Konfigurationsdatei user://scopedvr_editor.cfg, Abschnitt [test]: -## client_dir="/pfad/zu/scopedvr-client" -## 2. Klon neben dem Editor: /../scopedvr-client -## (erkennbar an project.godot im Ordner). -## -## Godot-Binary für den Start: das Binary, unter dem der Editor selbst läuft -## (OS.get_executable_path — Sly startet den Editor über den Godot-Editor, -## also kann DAS auch den Client starten). Läuft der Editor irgendwann als -## exportierte App, muss [test] godot_path gesetzt werden. -## -## Alles static + testbar ohne UI (tests/test_testrun.gd). - -const CFG_PATH := "user://scopedvr_editor.cfg" -const TESTRUN_DIR := "user://testrun" - - -static func load_cfg() -> ConfigFile: - var cfg := ConfigFile.new() - if FileAccess.file_exists(CFG_PATH): - cfg.load(CFG_PATH) # Fehler → Default-Logik greift weiter unten. - return cfg - - -## Liefert den Client-Projektordner (mit project.godot) oder "". -static func find_client(project_dir: String, cfg: ConfigFile = null) -> String: - var candidates: Array = [] - if cfg != null: - var configured := str(cfg.get_value("test", "client_dir", "")) - # Explizit gesetzter Pfad gewinnt, sobald der ORDNER existiert - # (bewusst ohne project.godot-Check — wer ihn konfiguriert, weiß es besser). - if not configured.is_empty() and DirAccess.dir_exists_absolute(configured): - return configured - var parent := project_dir.simplify_path().get_base_dir() - candidates.append(parent.path_join("scopedvr-client")) - for candidate in candidates: - var dir := str(candidate).simplify_path() - if FileAccess.file_exists(dir.path_join("project.godot")): - return dir - return "" - - -## Godot-Binary zum Starten des Clients (Editor-Binary oder Konfiguration). -static func find_godot(cfg: ConfigFile = null) -> String: - var exe := OS.get_executable_path() - if exe.get_file().to_lower().contains("godot"): - return exe - if cfg != null: - return str(cfg.get_value("test", "godot_path", "")) - return "" - - -## Deterministischer Temp-Pfad aus dem Map-Namen (erneuter Testlauf -## überschreibt die alte Export-Datei — kein Müll-Berg). -static func temp_map_path(doc: Dictionary) -> String: - var raw := str(doc.get("info", {}).get("name", "")).strip_edges() - if raw.is_empty(): - raw = "karte" - var safe := "" - for ch in raw: - var c := ch.to_lower() - if (c >= "a" and c <= "z") or (c >= "0" and c <= "9") or ch == "_" or ch == "-" or ch == " ": - safe += ch - else: - safe += "_" - safe = safe.strip_edges().replace(" ", "_").rstrip("_") - if safe.is_empty(): - safe = "karte" - return TESTRUN_DIR.path_join(safe + ".svmap") - - -## Exportiert das AKTUELLE Dokument (auch ungespeicherte Maps!) nach Temp. -## Rückgabe: {ok, errors, path} — path ist globalisiert (für den Client-Prozess). -static func export_temp_map(doc: Dictionary) -> Dictionary: - var rel := temp_map_path(doc) - DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path(TESTRUN_DIR)) - var result := SvmapIO.save_to_file(rel, doc) - result["path"] = ProjectSettings.globalize_path(rel) - return result - - -## Hand-Haltungs-Tool: liegt im Client-Projekt, weil es dessen Rig und Waffen -## direkt benutzt (kein VR, eigenes Fenster). -static func hand_pose_args(client_dir: String) -> PackedStringArray: - return PackedStringArray(["--xr-mode", "off", "--path", client_dir, - "res://tools/hand_pose_tool/hand_pose_tool.tscn"]) - - -## Import-Lauf für den Client, nötig nach neuem Stand (neue Modelle/Skripte). -static func import_args(client_dir: String) -> PackedStringArray: - return PackedStringArray(["--headless", "--path", client_dir, "--import"]) - - -## Argumentliste für den Client-Start (getestet: exakt diese Form). -static func launch_args(client_dir: String, map_path: String) -> PackedStringArray: - return PackedStringArray(["--path", client_dir, "--", "--testmap", map_path, "--mock-master"]) diff --git a/src/editor/test_run.gd.uid b/src/editor/test_run.gd.uid deleted file mode 100644 index 4ba94ac..0000000 --- a/src/editor/test_run.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cd3gmuvpf5ldv diff --git a/src/editor/updater.gd b/src/editor/updater.gd deleted file mode 100644 index 17a62df..0000000 --- a/src/editor/updater.gd +++ /dev/null @@ -1,428 +0,0 @@ -class_name EditorUpdater -extends RefCounted -## Editor-Selbstupdate (Karte t_d95f087a) — Update-Check über Git, Update- -## Ausführung (git pull + Godot-Import-Lauf) und plattformneutrale Restart- -## Auflösung. Alles static und ohne UI (tests/test_updater.gd). -## -## Regeln (Karte + Sly-Ansatz „das Programm sich selbst updaten lassen“): -## - Transport = Git (Klon des Editors), KEIN Binary-Download. -## - Keine Linux-Pfade hartkodiert: git (default "git") und ein optionaler -## Restart-Befehl kommen aus user://scopedvr_editor.cfg, Abschnitt [update] -## (git_command / restart_command). Ohne Konfiguration: unter Linux wird -## erkannt, ob eine systemd-User-Unit „map-editor“ existiert — dann klingelt -## ein Transient-Timer-Kick (systemd-run) den Unit-Neustart (der Kick läuft -## im EIGENEN Scope und überlebt die Stop-Phase). Sonst: der Editor startet -## sich selbst neu (mode "self", self_restart_args). -## - Import-Lauf-Lektion 17.10.: ein --import-Lauf kann mit Exit-Code 0 -## ENDEN und trotzdem Parse-/Script-Fehler enthalten (class_name-Cache). -## Die Ausgabe wird deshalb zusätzlich gescannt — bei Fehlern wird NICHT -## neu gestartet (Abbruch mit Meldung), sonst würde Sly einen Editor ohne -## Map-Ansicht sehen. -## - Offline / Tunnel weg → status "unreachable" → die UI bleibt still -## (kein Banner, kein Fehler-Geballer). -## - Git darf NIE interaktiv werden (Karte t_1457e935): kein GUI-Credential- -## Dialog mitten im Editor! Jeder git-Lauf läuft deshalb mit -## credential.helper=store und abgeschaltetem Askpass (spawn_argv) — -## fehlen die Zugangsdaten, endet der Lauf sofort mit einer klaren -## Fehlermeldung (status "auth_failed"), nie mit einem Prompt oder Hang. -## Hintergrund 17.10.: der systemd-User-Manager exportiert SSH_ASKPASS -## (ksshaskpass) — ein nackter git-Spawn hat damit mitten im Editor das -## Login-Fenster geöffnet. GIT_ASKPASS-/core.askPass-Override schlägt das -## geerbte SSH_ASKPASS (verifiziert am PC, 17.10.). - -const BRANCH := "main" -const UNIT_NAME := "map-editor" - -## Statuszeilen-Text für den auth_failed-Pfad (UI + Tests). -const AUTH_ERROR_TEXT := "Updates nicht prüfbar — Zugangsdaten fehlen (kein Login-Dialog geöffnet)." - - -## Belt-and-braces (Karte t_1457e935): argv für einen NICHT-interaktiven -## git-Lauf bauen. Rückgabe: [0] = Programm, Rest = Argumente. -## - "-c credential.helper=" leert ERST alle geerbten Helfer (sonst öffnet -## z. B. der Windows-Credential-Manager sein GUI-Fenster), danach -## "-c credential.helper=store": ausschließlich der Credential-Store -## (~/.git-credentials per HOME). -## - POSIX: Spawn über /usr/bin/env mit GIT_TERMINAL_PROMPT=0 und -## GIT_ASKPASS=/bin/true — das überstimmt auch ein GEERBTES SSH_ASKPASS -## (KDE/GNOME-Login-Dialog!). HOME kommt aus der eigenen Umgebung -## (OS.get_environment, kein Hardcode) und wird nur mitgegeben, wenn da. -## - Fallback ohne env-Wrapper (env fehlt / kein HOME): trotzdem kein Prompt -## möglich, weil core.askPass=/bin/true das Askpass-Fallback abschaltet. -static func spawn_argv(git_exe: String, project_dir: String, args: PackedStringArray) -> PackedStringArray: - var git_args := PackedStringArray(["-C", project_dir, - "-c", "credential.helper=", "-c", "credential.helper=store"]) - if not OS.has_feature("windows"): - git_args.append_array(PackedStringArray(["-c", "core.askPass=/bin/true"])) - git_args.append_array(args) - var home := OS.get_environment("HOME") - if not OS.has_feature("windows") and FileAccess.file_exists("/usr/bin/env") \ - and not home.is_empty(): - var out := PackedStringArray(["/usr/bin/env", - "GIT_TERMINAL_PROMPT=0", "GIT_ASKPASS=/bin/true", "HOME=" + home]) - out.append(git_exe) - out.append_array(git_args) - return out - var out := PackedStringArray([git_exe]) - out.append_array(git_args) - return out - - -## Ein Git-Kommando im Projektordner ausführen — IMMER nicht-interaktiv -## (spawn_argv). Rückgabe {ok, code, output} (output = stdout+stderr gemischt, -## damit Fehlerklassifikation sehen kann, was git gesagt hat). -static func git_run(git_exe: String, project_dir: String, args: PackedStringArray) -> Dictionary: - var argv := spawn_argv(git_exe, project_dir, args) - var exe := str(argv[0]) - var rest := argv.slice(1) - var output: Array = [] - var code := OS.execute(exe, rest, output, true) - var text := "" - for line in output: - text += str(line) - return {"ok": code == 0, "code": code, "output": text} - - -## Pure Prüfung (testbar): deutet die git-Ausgabe auf FEHLENDE Zugangsdaten? -## (Askpass ist abgeschaltet — „could not read Username“ ist dann der -## dokumentierte Nicht-Interaktiv-Fehler, kein Anlass für einen Retry.) -static func looks_like_auth_error(output: String) -> bool: - return output.contains("could not read Username") \ - or output.contains("Authentication failed") \ - or output.contains("terminal prompts disabled") \ - or output.contains("Unauthorized") - - -## Git-Binary: Konfiguration (user://scopedvr_editor.cfg → [update] -## git_command) gewinnt, sonst das Standard-"git" (PATH). -static func git_exe(cfg: ConfigFile = null) -> String: - if cfg != null: - var custom := str(cfg.get_value("update", "git_command", "")) - if not custom.is_empty(): - return custom - return "git" - - -## Lokaler HEAD-SHA. "" = kein Git-Repository (oder git nicht gefunden). -static func head_sha(git_exe: String, project_dir: String) -> String: - var r := git_run(git_exe, project_dir, PackedStringArray(["rev-parse", "HEAD"])) - if not bool(r["ok"]): - return "" - var text := str(r["output"]).strip_edges() - if text.is_empty(): - return "" - return text.split("\n")[0].strip_edges() - - -## Remote-SHA per git ls-remote (cheap, lesend — keine lokalen Referenzen -## verändert). "" = nicht erreichbar / Branch fehlt / Credentials fehlen. -static func remote_sha(git_exe: String, project_dir: String, branch: String) -> String: - var r := git_run(git_exe, project_dir, PackedStringArray([ - "ls-remote", "origin", "refs/heads/%s" % branch])) - if not bool(r["ok"]): - return "" - var text := str(r["output"]).strip_edges() - if text.is_empty(): - return "" - return sha_aus_ls_remote(text, branch) - - -## Update-Check: lokaler HEAD vs. origin/main. -## Rückgabe {status, local, remote, error} — status: -## "update_available" | "up_to_date" | "unreachable" | "error" | "auth_failed" -## "error" = kein Repo/git nicht da (Editor-spezifisches Problem) -## "unreachable" = Origin nicht erreichbar (offline, Tunnel weg) -## "auth_failed" = Zugangsdaten fehlen → UI zeigt klaren Hinweis, NIEMALS -## einen Login-Prompt (Karte t_1457e935). -static func check_update(git_exe: String, project_dir: String) -> Dictionary: - var local := head_sha(git_exe, project_dir) - if local.is_empty(): - return {"status": "error", "local": "", "remote": "", - "error": "Kein Git-Repository (oder git nicht gefunden)."} - var r := git_run(git_exe, project_dir, PackedStringArray([ - "ls-remote", "origin", "refs/heads/%s" % BRANCH])) - if not bool(r["ok"]): - var text := str(r["output"]) - if looks_like_auth_error(text): - return {"status": "auth_failed", "local": local, "remote": "", - "error": AUTH_ERROR_TEXT} - return {"status": "unreachable", "local": local, "remote": "", - "error": "Origin nicht erreichbar (offline oder Tunnel weg)."} - var text2 := str(r["output"]).strip_edges() - if text2.is_empty(): - return {"status": "unreachable", "local": local, "remote": "", - "error": "Origin nicht erreichbar (offline oder Tunnel weg)."} - var remote := sha_aus_ls_remote(text2, BRANCH) - if remote.is_empty(): - # Kein echter Commit in der Ausgabe (nur Warnungen/leer) — NICHT als - # Update deuten, sonst hängt das Banner endlos (Karte t_50a07d4b-Live-Bug). - return {"status": "unreachable", "local": local, "remote": "", - "error": "Origin lieferte keinen Commit (nur Warnungen)."} - if local == remote: - return {"status": "up_to_date", "local": local, "remote": remote, "error": ""} - # Befund 25.10.: „Update verfügbar“ blieb nach dem Update stehen, weil nur - # HEAD != origin/main geprüft wurde. Steht der Klon auf einem anderen - # Branch oder VOR main (z. B. Feature-Branch), ist das KEIN Update: - # nur melden, wenn der Remote-Commit NICHT schon in HEAD steckt. - if remote_in_head(git_exe, project_dir, remote): - return {"status": "up_to_date", "local": local, "remote": remote, "error": ""} - return {"status": "update_available", "local": local, "remote": remote, "error": ""} - - -## Ist `remote` schon Vorfahre von HEAD (Klon gleich oder VORAUS)? Unbekannter -## Commit (Exit 128) = noch nicht geholt = echtes Update → false. -static func remote_in_head(git_exe: String, project_dir: String, remote: String) -> bool: - var r := git_run(git_exe, project_dir, PackedStringArray([ - "merge-base", "--is-ancestor", remote, "HEAD"])) - return bool(r["ok"]) - - -## Aus der gemischten ls-remote-Ausgabe den Commit für `branch` lesen. -## WARUM: `git_run` mischt stdout+stderr, und der git-Client schreibt bei einer -## HTTP-Umleitung zuerst "warning: Umleitung nach ..." — die alte Fassung nahm -## stumpf die ERSTE Zeile und hielt "warning" für den Ziel-Commit. Ergebnis war -## ein Banner "Update verfügbar: → warning", das nie verschwand, obwohl -## der Pull korrekt lief (live belegt 20.10., Klon stand auf origin/main). -## Regeln: nur Zeilen "\t" zählen, sha = echter Hex-String. -static func sha_aus_ls_remote(text: String, branch: String) -> String: - var ziel := "refs/heads/%s" % branch - var locker := "" - for zeile in text.split("\n"): - var z := zeile.strip_edges() - if z.is_empty(): - continue - var klein := z.to_lower() - if klein.begins_with("warning") or klein.begins_with("hint") \ - or klein.begins_with("fatal") or klein.begins_with("error"): - continue - var teile := z.split("\t") - if teile.size() < 2: - continue - var sha := teile[0].strip_edges() - if not ist_sha(sha): - continue - if teile[1].strip_edges() == ziel: - return sha - if locker.is_empty(): - locker = sha - return locker - - -## Sieht der Text wie ein Git-Objekt-Hash aus (7-40 Hex-Zeichen)? -static func ist_sha(text: String) -> bool: - var t := text.strip_edges() - if t.length() < 7 or t.length() > 40: - return false - for i in t.length(): - var c := t[i] - if c >= "0" and c <= "9": - continue - if c >= "a" and c <= "f": - continue - if c >= "A" and c <= "F": - continue - return false - return true - - -## Kurzer SHA für Anzeigen (7 Zeichen, wie git log --oneline). -static func short_sha(sha: String) -> String: - return sha.substr(0, 7) - - -## Banner-Text (pure, testbar). -static func banner_text(local_sha: String, remote_sha: String) -> String: - return "🔄 Update verfügbar: %s → %s" % [short_sha(local_sha), short_sha(remote_sha)] - - -## Klartext-Status für die Statuszeile (Karte t_f73a1cc5): Wenn lokale -## (meist von Godot erzeugte) Dateien das Update blockieren WÜRDEN, legt der -## Pull sie selbst beiseite — Sly liest diesen Satz statt einer rohen Git- -## Zeile („Bitte verschieben oder entfernen Sie diese…“). -const AUTO_STASH_INFO_TEXT := "Update blockiert: eigene erzeugte Dateien — werden automatisch beiseitegelegt und das Update läuft weiter." -## Ehrliche Meldung, wenn das Zurückholen kollidiert ist (Stash bleibt als -## Sicherung liegen; Godot baut die erzeugten Dateien beim Import neu). -const STASH_KEPT_TEXT := "Erzeugte Dateien bleiben beiseitegelegt — beim nächsten Start neu aufgebaut (Sicherungs-Stash bleibt liegen, nichts verloren)." -## Kennung der eigenen Auto-Stashes (Verwerfen alter Einträge, damit sie -## sich nicht anhäufen). -const AUTO_STASH_MESSAGE := "auto: Selbst-Update" - - -## Update ausführen: git pull --ff-only (Klon zieht nur nach, dreht nichts -## um). Vorher werden lokal Erzeugtes/Geändertes AUTOMATISCH beiseitegelegt -## (Karte t_f73a1cc5): `git stash push -u` erfasst GEÄNDERT **und** UNTRACKED -## Dateien (`--autostash` allein reicht nicht — es lässt untracked liegen; -## genau die haben am 19.10. den Pull blockiert). Nach dem Pull wird das -## Beiseitegelegte zurückgeholt; kollidiert das (Typfall: lose `.import`- -## Datei trifft auf dieselbe Datei neu getrackt), bleibt der Stash als -## Sicherung liegen und die Statuszeile bekommt den Klartext — NIE ein halb -## gepoppter Zustand. Rückgabe {ok, output, errors, info} (info = Klartext -## fürs Statuszeile-Fenster, leer wenn nichts besonderes passiert ist). -static func pull(git_exe: String, project_dir: String) -> Dictionary: - var stash_info := _stash_local_changes(git_exe, project_dir) - # Gezielt origin/main ziehen (nicht den Upstream des aktuellen Branches). - var r := git_run(git_exe, project_dir, PackedStringArray(["pull", "--ff-only", "origin", BRANCH])) - var errors: Array = [] - var text := str(r["output"]).strip_edges() - var info := "" - if not bool(r["ok"]): - # Pull fehlgeschlagen (z. B. offline): Beiseitegelegtes zurückholen, - # damit nichts „verschwindet", wenn der Fehler nur am Netz lag. - if not stash_info.is_empty(): - _restore_stash(git_exe, project_dir) - errors.append("git pull --ff-only fehlgeschlagen (Exit-Code %s):" % str(r["code"])) - if not text.is_empty(): - errors.append(text) - else: - errors.append("(keine Ausgabe — git nicht gefunden oder Verbindung sofort weg)") - if looks_like_auth_error(text): - errors.append("Zugangsdaten fehlen — es wird bewusst KEIN Login-Dialog geöffnet (Credential-Store prüfen).") - else: - if not stash_info.is_empty(): - info = AUTO_STASH_INFO_TEXT - var restored := _restore_stash(git_exe, project_dir) - if not bool(restored["ok"]): - info += "\n" + STASH_KEPT_TEXT - # Der Map-Kern ist ein Submodul: ein Pull allein holt ihn nicht nach. - var sub := git_run(git_exe, project_dir, PackedStringArray(["submodule", "update", "--init", "--recursive"])) - if not bool(sub["ok"]): - errors.append("git submodule update fehlgeschlagen (Exit-Code %s):" % str(sub["code"])) - errors.append(str(sub["output"]).strip_edges()) - if looks_like_auth_error(str(sub["output"])): - errors.append("Zugangsdaten fehlen — es wird bewusst KEIN Login-Dialog geöffnet (Credential-Store prüfen).") - return {"ok": false, "output": str(sub["output"]), "errors": errors, "info": info} - return {"ok": bool(r["ok"]), "output": str(r["output"]), "errors": errors, "info": info} - - -## Lokales Beiseitelegen vor dem Pull (Karte t_f73a1cc5). Rückgabe: Referenz -## auf den eigenen Auto-Stash (z. B. "stash@{0}") oder "" wenn es nichts zu -## beiseitelegen gab / der Stash nicht angelegt werden konnte. -## - Zuerst alte EIGENE Auto-Stashes verwerfen (gleiche Kennung) — sie -## enthalten nur erzeugte Dateien und dürfen sich nicht anhäufen. -## - "No local changes to save" endet ebenfalls mit Exit 0 → NICHT am Text -## matchen, sondern prüfen, ob ein Eintrag mit unserer Kennung entstand. -static func _stash_local_changes(git_exe: String, project_dir: String) -> String: - _drop_auto_stashes(git_exe, project_dir) - var r := git_run(git_exe, project_dir, PackedStringArray([ - "stash", "push", "-u", "-m", AUTO_STASH_MESSAGE])) - if not bool(r["ok"]): - return "" - return _auto_stash_ref(git_exe, project_dir) - - -## Referenz des eigenen Auto-Stashes ("stash@{N}") oder "". -static func _auto_stash_ref(git_exe: String, project_dir: String) -> String: - var r := git_run(git_exe, project_dir, PackedStringArray([ - "stash", "list", "--pretty=format:%gd|%s"])) - if not bool(r["ok"]): - return "" - for line in str(r["output"]).split("\n"): - var parts := str(line).strip_edges().split("|", true, 1) - if parts.size() == 2 and str(parts[1]).contains(AUTO_STASH_MESSAGE): - return str(parts[0]) - return "" - - -## Alle EIGENEN Auto-Stashes (Kennung AUTO_STASH_MESSAGE) verwerfen — von -## hinten, weil die Indizes sich beim Drop verschieben. -static func _drop_auto_stashes(git_exe: String, project_dir: String) -> void: - var r := git_run(git_exe, project_dir, PackedStringArray([ - "stash", "list", "--pretty=format:%gd|%s"])) - if not bool(r["ok"]): - return - var refs: Array = [] - for line in str(r["output"]).split("\n"): - var parts := str(line).strip_edges().split("|", true, 1) - if parts.size() == 2 and str(parts[1]).contains(AUTO_STASH_MESSAGE): - refs.append(str(parts[0])) - refs.reverse() - for ref in refs: - git_run(git_exe, project_dir, PackedStringArray(["stash", "drop", ref])) - - -## Beiseitegelegtes zurückholen. apply (nicht pop), damit die Referenz nicht -## am Stack verschiebt; bei Erfolg wird der Eintrag gedroppt. Kollidiert das -## Zurückholen (Typfall: erzeugte Datei ist inzwischen getrackt), wird mit -## `git reset --hard` der halb gepoppte Zustand weggeräumt und der Stash ALS -## SICHERUNG LIEGEN GELASSEN — kein Datenverlust, Godot erzeugt die Dateien -## beim nächsten Import-Lauf neu. Bewusst KEIN `git clean`: untracked -## Nutzdaten (z. B. Maps/) dürfen nie angefasst werden. -## Rückgabe {ok, kept, output}. -static func _restore_stash(git_exe: String, project_dir: String) -> Dictionary: - var ref := _auto_stash_ref(git_exe, project_dir) - if ref.is_empty(): - return {"ok": true, "kept": false, "output": ""} - var r := git_run(git_exe, project_dir, PackedStringArray(["stash", "apply", ref])) - if bool(r["ok"]): - git_run(git_exe, project_dir, PackedStringArray(["stash", "drop", ref])) - return {"ok": true, "kept": false, "output": str(r["output"])} - git_run(git_exe, project_dir, PackedStringArray(["reset", "--hard"])) - return {"ok": false, "kept": true, "output": str(r["output"])} - - -## Import-Lauf: --headless --path --import. Muss NACH dem -## Pull laufen (neue class_name-Dateien in den Cache), FEHLSCHLAG = Update- -## Abbruch OHNE Neustart (Lektion 17.10.). Rückgabe {ok, errors, output}. -static func run_import(godot_exe: String, project_dir: String) -> Dictionary: - var args := PackedStringArray(["--headless", "--path", project_dir, "--import"]) - var output: Array = [] - var code := OS.execute(godot_exe, args, output, true) - var errors := import_errors(output) - if code != 0: - errors.append("Import-Lauf fehlgeschlagen (Exit-Code %s)" % str(code)) - return {"ok": errors.is_empty(), "errors": errors, "output": _output_text(output)} - - -## Pure Prüfung (testbar): enthält die Import-Ausgabe Parse-/Script-Fehler? -## Exit-Code 0 allein beweist NICHT einen sauberen Import (Lektion 17.10.). -static func import_errors(output: Array) -> Array: - var errors: Array = [] - for line in output: - var text := str(line) - if text.contains("Parse Error") or text.contains("SCRIPT ERROR"): - errors.append(text.strip_edges()) - return errors - - -static func _output_text(output: Array) -> String: - var text := "" - for line in output: - text += str(line) - return text - - -## Restart-Auflösung (plattformneutral, getestet): -## 1. cfg [update] restart_command gesetzt → mode "command", argv = an -## Leerzeichen gesplittet. (z. B. systemd-Unit-Kick, Batch-Skript — jede -## Plattform setzt hier ihren eigenen Befehl ein.) -## 2. Linux + systemd-User-Unit „map-editor“ existiert → Transient-Timer- -## Kick (systemd-run, 3 s): der Kick läuft in einem EIGENEN Scope und -## wird beim Stoppen des Editors (Unit-Neustart) nicht mitgekillt. -## 3. Sonst: mode "self" — der Editor startet sich selbst neu (gleiche -## Godot-Binary, --editor --path ) und beendet sich danach. -static func resolve_restart(cfg: ConfigFile = null) -> Dictionary: - if cfg != null: - var cmd := str(cfg.get_value("update", "restart_command", "")) - if not cmd.is_empty(): - return {"mode": "command", "argv": PackedStringArray(cmd.split(" ", false))} - if OS.has_feature("linux"): - var probe: Array = [] - var code := OS.execute("systemctl", PackedStringArray([ - "--user", "list-unit-files", UNIT_NAME + ".service", "--no-legend"]), - probe, true) - var text := "" - for line in probe: - text += str(line) - if code == 0 and not text.strip_edges().is_empty(): - return {"mode": "command", "argv": PackedStringArray([ - "systemd-run", "--user", "--on-active=3s", - "systemctl", "--user", "restart", UNIT_NAME + ".service"])} - return {"mode": "self", "argv": PackedStringArray()} - - -## Argumente für den Selbst-Restart: dieselbe Godot-Binary startet die -## Map-Editor-APP über deren main.tscn (kein "--editor" — das würde den -## Godot-Editor-Shell öffnen, nicht unsere App; Live-Befund 17.10.: -## Nach dem Selbst-Update ging der Godot-Editor auf statt dem Map Editor). -static func self_restart_args(project_dir: String) -> PackedStringArray: - return PackedStringArray(["--path", project_dir]) \ No newline at end of file diff --git a/src/editor/updater.gd.uid b/src/editor/updater.gd.uid deleted file mode 100644 index 3edbb95..0000000 --- a/src/editor/updater.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://nxdbipruop30 diff --git a/src/server/admin_client.gd b/src/server/admin_client.gd deleted file mode 100644 index ccc41b2..0000000 --- a/src/server/admin_client.gd +++ /dev/null @@ -1,112 +0,0 @@ -class_name AdminClient -extends Node -## Client der Match-Server-Admin-API v1 (Doku: docs/admin-api.md im -## scopedvr-match-server-Repo). Knoten in den Baum hängen, dann -## `var res = await client.call_api("GET", "/status")`. -## -## Antwort: {ok: bool (HTTP 2xx), status: int, body: Dictionary, transport_error: String} -## transport_error ist deutsch und leer, wenn der Server geantwortet hat. -## Das Token geht NUR als Header raus und wird nie geloggt oder zurückgegeben. - -const TIMEOUT_S := 30.0 -const MAX_RESPONSE_BYTES := 8 * 1024 * 1024 - -var host: String = "" -var port: int = 24580 -var tls: bool = false -var token: String = "" - - -## Server-Eintrag aus dem ServerStore übernehmen. -func use(entry: Dictionary) -> void: - host = str(entry.get("host", "")) - port = int(entry.get("port", 24580)) - tls = bool(entry.get("tls", false)) - token = str(entry.get("token", "")) - - -static func base_url(p_host: String, p_port: int, p_tls: bool) -> String: - var h := p_host - if h.contains(":") and not h.begins_with("["): - h = "[%s]" % h # IPv6 - return "%s://%s:%d/api/v1" % ["https" if p_tls else "http", h, p_port] - - -## Prüft die Eingabe für „Server hinzufügen“. Leerer Text = ok. -static func check_address(p_host: String, p_port: int) -> String: - var h := p_host.strip_edges() - if h.is_empty(): - return "Bitte eine Adresse eingeben (IP oder Name)." - if h.contains("/") or h.contains(" ") or h.contains("://"): - return "Nur die Adresse eintragen, ohne http:// und ohne Schrägstriche (z. B. 192.168.1.20)." - if p_port < 1 or p_port > 65535: - return "Der Port muss zwischen 1 und 65535 liegen." - return "" - - -func call_api(method: String, path: String, body: Variant = null, query: Dictionary = {}, raw: PackedByteArray = PackedByteArray()) -> Dictionary: - var err := check_address(host, port) - if err != "": - return _transport_fail(err) - var url := base_url(host, port, tls) + path - if not query.is_empty(): - var parts: PackedStringArray = [] - for k in query.keys(): - parts.append("%s=%s" % [str(k).uri_encode(), str(query[k]).uri_encode()]) - url += "?" + "&".join(parts) - var headers: PackedStringArray = ["Accept: application/json"] - if token != "": - headers.append("Authorization: Bearer " + token) - var payload := raw - if body != null: - payload = JSON.stringify(body).to_utf8_buffer() - headers.append("Content-Type: application/json") - elif not raw.is_empty(): - headers.append("Content-Type: application/octet-stream") - var http := HTTPRequest.new() - http.timeout = TIMEOUT_S - http.body_size_limit = MAX_RESPONSE_BYTES - http.accept_gzip = false - add_child(http) - var m := _method(method) - var rerr := http.request_raw(url, headers, m, payload) - if rerr != OK: - http.queue_free() - return _transport_fail("Anfrage konnte nicht gestartet werden (Fehler %d)." % rerr) - var done: Array = await http.request_completed - http.queue_free() - var result: int = done[0] - if result != HTTPRequest.RESULT_SUCCESS: - return _transport_fail(_result_text(result)) - var code: int = done[1] - var parsed: Variant = JSON.parse_string((done[3] as PackedByteArray).get_string_from_utf8()) - var out: Dictionary = parsed if parsed is Dictionary else {} - return {"ok": code >= 200 and code < 300, "status": code, "body": out, "transport_error": ""} - - -static func _method(m: String) -> int: - match m.to_upper(): - "POST": return HTTPClient.METHOD_POST - "PUT": return HTTPClient.METHOD_PUT - "PATCH": return HTTPClient.METHOD_PATCH - "DELETE": return HTTPClient.METHOD_DELETE - return HTTPClient.METHOD_GET - - -static func _transport_fail(msg: String) -> Dictionary: - return {"ok": false, "status": 0, "body": {}, "transport_error": msg} - - -static func _result_text(result: int) -> String: - match result: - HTTPRequest.RESULT_CANT_CONNECT, HTTPRequest.RESULT_CONNECTION_ERROR: - return "Keine Verbindung zum Server. Läuft er, ist die Admin-API eingeschaltet, und stimmen Adresse und Port?" - HTTPRequest.RESULT_CANT_RESOLVE: - return "Die Adresse wurde nicht gefunden. Tippfehler?" - HTTPRequest.RESULT_TIMEOUT: - return "Der Server antwortet nicht (Zeitüberschreitung)." - HTTPRequest.RESULT_TLS_HANDSHAKE_ERROR: - return "Sichere Verbindung (https) fehlgeschlagen. Gibt der Server wirklich https her?" - HTTPRequest.RESULT_BODY_SIZE_LIMIT_EXCEEDED: - return "Die Antwort des Servers ist zu groß." - return "Verbindungsfehler (Code %d)." % result diff --git a/src/server/admin_client.gd.uid b/src/server/admin_client.gd.uid deleted file mode 100644 index 5985b57..0000000 --- a/src/server/admin_client.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dd3mjb50m63hm diff --git a/src/server/admin_texte.gd b/src/server/admin_texte.gd deleted file mode 100644 index c7adf5b..0000000 --- a/src/server/admin_texte.gd +++ /dev/null @@ -1,101 +0,0 @@ -class_name AdminTexte -extends RefCounted -## Verständliche deutsche Texte zu Admin-API-Antworten (kein Fachchinesisch, -## kein rohes JSON) – inklusive der Fehlerliste (422) beim Map-Upload. - -const TUNNEL_HINWEIS := "Tipp: Die Admin-API hört standardmäßig nur auf dem Server selbst (localhost). Von außen erreichst du sie sicher über einen SSH-Tunnel (z. B. ssh -L 24580:127.0.0.1:24580 benutzer@server, dann hier Adresse 127.0.0.1) oder über einen Reverse-Proxy mit https. Die Verbindung selbst ist sonst unverschlüsselt." - -## Erklärungen für häufige Prüfregeln der Map (Server und Editor nutzen dieselben IDs). -const REGEL_HILFE := { - "V1": "Die Datei ist zu groß.", - "V2": "Die Datei ist keine gültige Map-Datei.", - "V3": "Format-Version passt nicht – Editor und Server müssen zusammenpassen.", - "V4": "Ein Pflichtbereich der Map fehlt.", - "V6": "Das Terrain ist zu groß oder zu detailreich.", - "V8": "Zu viele Objekte oder zu viele Polygone – Objekte entfernen.", - "V11": "Pro Team werden mindestens 4 Spawn-Punkte gebraucht (Spawn-Zonen malen).", - "V14": "Die Map ragt über die erlaubte Größe hinaus.", -} - - -## Antwort → Text für den Nutzer ("" bei Erfolg ohne Besonderheiten). -static func erklaere(res: Dictionary) -> String: - if str(res.get("transport_error", "")) != "": - return str(res["transport_error"]) + "\n\n" + TUNNEL_HINWEIS - var status := int(res.get("status", 0)) - var body: Dictionary = res.get("body", {}) - var server_text := str(body.get("error", "")) - match status: - 401: - return "Das Token stimmt nicht (oder fehlt). Es steht beim Server in der Admin-Datei (state_file) – bitte neu eintragen." - 429: - return "Zu viele falsche Token-Versuche. Der Server sperrt dich kurz – bitte in ein paar Minuten erneut versuchen." - 404: - if str(body.get("code", "")) == "not_found": - return "Diese Funktion kennt der Server nicht. Ist er auf dem neuesten Stand?" - 413: - return "Die Datei ist größer als der Server erlaubt. " + server_text - 422: - return erklaere_map_fehler(body) - if server_text != "": - return server_text - if status >= 200 and status < 300: - return "" - return "Unerwartete Antwort vom Server (Status %d)." % status - - -## Fehlerliste einer abgelehnten Map als Aufzählung mit Hilfetexten. -static func erklaere_map_fehler(body: Dictionary) -> String: - var errs: Array = body.get("errors", []) - var out := "Der Server hat die Map abgelehnt" - out += " (%d Problem%s):\n" % [errs.size(), "" if errs.size() == 1 else "e"] if not errs.is_empty() else ".\n" - var hints := {} - for e in errs: - var t := str(e) - out += "• " + t + "\n" - var rule := t.split(":")[0].strip_edges() - for k in REGEL_HILFE.keys(): - if rule == k or rule.begins_with(k) and not rule.substr(k.length(), 1).is_valid_int(): - hints[k] = REGEL_HILFE[k] - if not hints.is_empty(): - out += "\nSo behebst du es:\n" - for k in hints.keys(): - out += "• %s: %s\n" % [k, hints[k]] - return out.strip_edges() - - -## Dateiname für den Upload: a–z, 0–9, _ und -, höchstens 40 Zeichen (wie der Server). -static func slugify(text: String) -> String: - var t := text.strip_edges().to_lower() - for pair in [["ä", "ae"], ["ö", "oe"], ["ü", "ue"], ["ß", "ss"]]: - t = t.replace(pair[0], pair[1]) - var out := "" - for c in t: - out += c if ((c >= "a" and c <= "z") or (c >= "0" and c <= "9") or c == "-") else "_" - while out.contains("__"): - out = out.replace("__", "_") - out = out.lstrip("_-").rstrip("_") - return out.substr(0, 40) - - -## Wirkung einer Einstellung in Klartext. -static func wirkung(effect: String) -> String: - match effect: - "live": return "sofort" - "next_map": return "ab der nächsten Map" - "restart": return "nach Server-Neustart" - return effect - - -static func neustart_zeitueberschreitung(seconds: int) -> String: - return "Der Server ist nach %d s nicht zurück. Er kommt nur von selbst wieder, wenn Docker (Restart-Policy), systemd oder tools/start_server.* ihn gestartet haben." % seconds - - -static func sperrdauer_text(minutes: int) -> String: - if minutes <= 0: - return "dauerhaft" - if minutes < 60: - return "%d Minuten" % minutes - if minutes < 1440: - return "%d Stunden" % (minutes / 60) - return "%d Tage" % (minutes / 1440) diff --git a/src/server/admin_texte.gd.uid b/src/server/admin_texte.gd.uid deleted file mode 100644 index 88dcc8e..0000000 --- a/src/server/admin_texte.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://baspf3qu07cwi diff --git a/src/server/map_push.gd b/src/server/map_push.gd deleted file mode 100644 index 28c0260..0000000 --- a/src/server/map_push.gd +++ /dev/null @@ -1,40 +0,0 @@ -class_name MapPush -extends RefCounted -## „Map auf Server pushen“: aktuelle Map lokal prüfen und signieren -## (SvmapIO.to_signed_text), dann per Admin-API hochladen. UI-frei und testbar. - -## opts: {name: String ("" = aus Map-Name), overwrite: bool, add_to_rotation: bool} -## Rückgabe: {ok, stage ("lokal"|"upload"), text (verständliche Meldung), -## id (Server-Map-ID), exists (bool: 409 – Nachfrage nötig), status} -static func push(client: AdminClient, doc: Dictionary, opts: Dictionary = {}) -> Dictionary: - var signed := SvmapIO.to_signed_text(doc) - if not bool(signed["ok"]): - var lines := "Die Map ist noch nicht gültig und wurde nicht hochgeladen:\n" - for e in signed["errors"]: - lines += "• %s\n" % str(e) - return {"ok": false, "stage": "lokal", "text": lines.strip_edges(), "id": "", "exists": false, "status": 0} - var info: Dictionary = doc.get("info", {}) - var slug := str(opts.get("name", "")).strip_edges() - if slug == "": - slug = AdminTexte.slugify(str(info.get("name", ""))) - if slug == "": - return {"ok": false, "stage": "lokal", "text": "Die Map braucht einen Namen (Tab „Map“), bevor sie hochgeladen werden kann.", "id": "", "exists": false, "status": 0} - var bytes: PackedByteArray = str(signed["text"]).to_utf8_buffer() - var query := {"name": slug} - if bool(opts.get("overwrite", false)): - query["overwrite"] = "1" - if bool(opts.get("add_to_rotation", false)): - query["add_to_rotation"] = "1" - var res: Dictionary = await client.call_api("POST", "/maps", null, query, bytes) - var body: Dictionary = res.get("body", {}) - if bool(res.get("ok", false)): - var msg := "Hochgeladen als „%s“ (%s, %d Objekte)." % [str(body.get("name", slug)), _groesse(bytes.size()), int(body.get("objects", 0))] - if bool(body.get("replaced", false)): - msg += " Die vorherige Version wurde ersetzt." - return {"ok": true, "stage": "upload", "text": msg, "id": str(body.get("id", "")), "exists": false, "status": 200} - var exists := int(res.get("status", 0)) == 409 and str(body.get("code", "")) == "exists" - return {"ok": false, "stage": "upload", "text": AdminTexte.erklaere(res), "id": "", "exists": exists, "status": int(res.get("status", 0))} - - -static func _groesse(n: int) -> String: - return "%.1f MB" % (n / 1048576.0) if n >= 1048576 else "%d KB" % maxi(1, n / 1024) diff --git a/src/server/map_push.gd.uid b/src/server/map_push.gd.uid deleted file mode 100644 index f15652d..0000000 --- a/src/server/map_push.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cmuts8c8t2d5i diff --git a/src/server/server_store.gd b/src/server/server_store.gd deleted file mode 100644 index 06eb350..0000000 --- a/src/server/server_store.gd +++ /dev/null @@ -1,114 +0,0 @@ -class_name ServerStore -extends RefCounted -## Gespeicherte Admin-Server des Editors (Name, Adresse, Port, https, Token). -## -## Das Token liegt NICHT im Klartext auf der Platte: die Datei ist mit einem -## aus Rechner-ID + Nutzerordner abgeleiteten Schlüssel verschlüsselt. Das hält -## Zufallsleser, Cloud-Sync und Screenshots von Ordnern raus – gegen Schadsoftware -## mit Zugriff auf deinen Benutzer schützt es nicht (dafür gibt es keine -## plattformübergreifende Lösung ohne Passwort-Manager). Tokens werden nie geloggt. - -const DEFAULT_PATH := "user://admin_server.dat" -const DEFAULT_PORT := 24580 -const MAX_SERVERS := 50 - -var path: String = DEFAULT_PATH -var servers: Array = [] # [{id, name, host, port, tls, token}] -var last_error: String = "" - - -func _init(p: String = DEFAULT_PATH) -> void: - path = p - - -func _key() -> String: - return ("svr-editor-admin|%s|%s" % [OS.get_unique_id(), OS.get_user_data_dir()]).sha256_text() - - -func load_store() -> void: - servers.clear() - last_error = "" - if not FileAccess.file_exists(path): - return - var fa := FileAccess.open_encrypted_with_pass(path, FileAccess.READ, _key()) - if fa == null: - last_error = "Gespeicherte Server konnten nicht gelesen werden (andere Installation oder beschädigte Datei)." - return - var parsed: Variant = JSON.parse_string(fa.get_as_text()) - if parsed is Array: - for e in parsed: - if e is Dictionary and str(e.get("host", "")) != "": - servers.append({ - "id": str(e.get("id", _new_id())), "name": str(e.get("name", e["host"])), - "host": str(e["host"]), "port": int(e.get("port", DEFAULT_PORT)), - "tls": bool(e.get("tls", false)), "token": str(e.get("token", ""))}) - - -func save_store() -> bool: - var fa := FileAccess.open_encrypted_with_pass(path, FileAccess.WRITE, _key()) - if fa == null: - last_error = "Server-Liste konnte nicht gespeichert werden (Fehler %d)." % FileAccess.get_open_error() - return false - fa.store_string(JSON.stringify(servers)) - return true - - -## Neuer oder aktualisierter Eintrag. Rückgabe: id ("" = Eingabe ungültig → last_error). -func upsert(entry: Dictionary) -> String: - var err := AdminClient.check_address(str(entry.get("host", "")), int(entry.get("port", 0))) - if err != "": - last_error = err - return "" - var e := { - "id": str(entry.get("id", "")), "name": str(entry.get("name", "")).strip_edges(), - "host": str(entry["host"]).strip_edges(), "port": int(entry["port"]), - "tls": bool(entry.get("tls", false)), "token": str(entry.get("token", "")).strip_edges()} - if e["name"] == "": - e["name"] = "%s:%d" % [e["host"], e["port"]] - if e["id"] == "": - if servers.size() >= MAX_SERVERS: - last_error = "Maximal %d gespeicherte Server." % MAX_SERVERS - return "" - e["id"] = _new_id() - servers.append(e) - else: - var i := index_of(e["id"]) - if i < 0: - servers.append(e) - else: - servers[i] = e - save_store() - return e["id"] - - -func remove(id: String) -> bool: - var i := index_of(id) - if i < 0: - return false - servers.remove_at(i) - save_store() - return true - - -func index_of(id: String) -> int: - for i in servers.size(): - if str(servers[i]["id"]) == id: - return i - return -1 - - -func get_entry(id: String) -> Dictionary: - var i := index_of(id) - return servers[i].duplicate() if i >= 0 else {} - - -## Für Anzeige/Logs: nie das Token. -func public_view(id: String) -> Dictionary: - var e := get_entry(id) - e.erase("token") - e["has_token"] = str(get_entry(id).get("token", "")) != "" - return e - - -static func _new_id() -> String: - return "s%d_%d" % [int(Time.get_unix_time_from_system()), randi() % 100000] diff --git a/src/server/server_store.gd.uid b/src/server/server_store.gd.uid deleted file mode 100644 index 2a1a4cc..0000000 --- a/src/server/server_store.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dkwfi2v8nu03w diff --git a/src/ui/help_text.gd b/src/ui/help_text.gd deleted file mode 100644 index 06d32b9..0000000 --- a/src/ui/help_text.gd +++ /dev/null @@ -1,97 +0,0 @@ -extends RefCounted -## Kurzhilfe-Overlay (Karte t_11b5c25b, Karte 3/3) — H schaltet das Panel an, -## H/Esc aus. Der Text spiegelt docs/tasten.md (Source of truth der Shortcut- -## Karten) als Kompakt-Tabelle für den Editor-Bildschirm. Bei neuen Tasten: -## docs/tasten.md UND hier pflegen. -## -## BBCode-Tabelle ([table=2]): Taste | Wirkung. Bei neuen Tasten die Zeile in -## der passenden Sektion ergänzen (text() aufbauen, _rows() macht die Zellen). - -static func text() -> String: - var out := "" - out += _header("Kamera & Steuerung") - out += _table(_rows([ - ["Mittlere Maustaste ziehen", "Orbit: um die Karte drehen"], - ["Mittlere Maustaste + Umschalt", "Pan: Karte verschieben"], - ["Mausrad", "Zoom"], - ["Rechte Maustaste halten", "Freelook-Flug in jedem Werkzeug: Maus = Umsehen, W/A/S/D = Bewegen, Leertaste hoch, Umschalt runter"], - ["Strg / Alt (im Flug)", "schneller (×3) / langsamer (×0,3); Mausrad ändert die Grundgeschwindigkeit"], - ["Umschalt+F", "Flugmodus dauerhaft an/aus"], - ["F", "Auswahl ins Bild zentrieren"], - ["L", "Höhenlinien fixieren (sonst nur im Terrain-Werkzeug)"], - ["H", "diese Hilfe an/aus (Esc schließt auch)"], - ])) - out += _header("Objekte auswählen & platzieren (F2)") - out += _table(_rows([ - ["Linksklick", "Objekt wählen; Umschalt/Strg+Klick: Mehrfachauswahl"], - ["Rahmen aufziehen", "alle Objekte im Rahmen wählen (Umschalt: hinzufügen)"], - ["Bibliothek: Klick / Doppelklick", "Objekt auswählen / Platzieren starten; Klick in die Karte setzt, Esc bricht ab"], - ["G", "greifen: Objekt hängt an der Maus (Klick setzt, Esc zurück)"], - ["Pfeiltasten", "im 2-m-Raster verschieben"], - ["Bild↑ / Bild↓", "0,25 m anheben / absenken; Strg+Bild↑ = auf den Boden setzen"], - ["Strg halten", "Snap-Zwang auf ganze Meter"], - ["Strg+D", "duplizieren"], - ["Entf", "löschen"], - ["Strg+G / Strg+Umschalt+G", "Gruppieren / Gruppe lösen"], - ["Esc", "abbrechen, dann Auswahl aufheben"], - ])) - out += _header("Objekte verschieben, drehen, kippen (Werkzeugleiste links oben in der 3D-Ansicht)") - out += _table(_rows([ - ["Verschieben", "Pfeile am Objekt ziehen (X rot, Y grün, Z blau); Mausrad ändert die Schrittweite"], - ["Drehen", "Ringe am Objekt ziehen: um alle drei Achsen, in 15°-Schritten; R = 90° um Y (Umschalt+R = −90°)"], - ["Kippen", "Strg+R / Strg+Umschalt+R = um X ±15°; Alt+R / Alt+Umschalt+R = um Z ±15° (auch beim Platzieren)"], - ["Spiegeln", "an der Stelle links↔rechts oder vor↔zurück (Panel Auswahl)"], - ["Strg+Z / Strg+Y", "jeder Zug ist ein Undo-Schritt"], - ])) - out += _header("Terrain formen (F1)") - out += _table(_rows([ - ["1 / 2 / 3", "Heben / Senken / Glätten"], - ["5 / 6", "Einebnen (Höhe vom Strichstart) / Rampe (Start klicken, ziehen, loslassen)"], - ["[ / ]", "Pinselgröße Klein / Mittel / Groß"], - ["Linksklick ziehen", "Boden formen; Strg+Klick = Gegenteil (Heben ↔ Senken)"], - ["Tablet/Controller", "Stärke folgt dem Druck (Maus = voll)"], - ])) - out += _header("Malen (4)") - out += _table(_rows([ - ["Material wählen", "Tab Malen: Kacheln mit Vorschau"], - ["Linksklick ziehen", "Material auf den Boden malen; Strg+Klick malt Steppe zurück"], - ["Kante", "Regler: hart ↔ weich auslaufend"], - ])) - out += _header("Bauen (F3)") - out += _table(_rows([ - ["Teil im Tab Bauen", "wählen, dann in die Karte klicken — Wände rasten an die Zellkante, Böden/Dächer in die Zellmitte"], - ["Klick auf Wandoberkante", "stapelt das nächste Geschoss; Klick auf die Seite ersetzt das Teil (Wand → Tür)"], - ["R / Esc", "Teil umdrehen bzw. drehen / Bauen beenden"], - ["Gebäude", "jedes Haus ist eine Gruppe: „Ganzes Gebäude auswählen“, kopieren, löschen im Tab Bauen"], - ])) - out += _header("Spawn-Zonen (F4) und Test-Start (T)") - out += _table(_rows([ - ["F4: Linksklick", "Zone setzen; Ziehen verschiebt, Entf löscht; Team und Radius im Tab Prüfen"], - ["T: Linksklick", "Test-Startpunkt setzen (nur für F5, kein Spawn)"], - ["F5", "▶ Karte testen"], - ])) - out += _header("Datei & Rückgängig") - out += _table(_rows([ - ["Strg+Z", "Rückgängig"], - ["Strg+Y / Strg+Umschalt+Z", "Wiederherstellen"], - ["Strg+S / Strg+Umschalt+S", "Speichern / Speichern unter"], - ["Strg+O / Strg+N", "Öffnen / Neue Map"], - ["Datei → Hand-Haltung der Waffen", "öffnet das Tool für Hände und Finger pro Waffe (eigenes Fenster)"], - ["Datei → Updates prüfen", "prüft auf eine neue Version; Banner „Jetzt updaten“ lädt und startet neu"], - ])) - return out - - -static func _header(title: String) -> String: - return "\n[color=#8cc9f2][b]%s[/b][/color]\n\n" % title - - -static func _table(rows: String) -> String: - return "[table=2]%s[/table]\n" % rows - - -static func _rows(pairs: Array) -> String: - var out := "" - for pair in pairs: - out += "[cell][b]%s[/b][/cell][cell]%s[/cell]" % [str(pair[0]), str(pair[1])] - return out diff --git a/src/ui/help_text.gd.uid b/src/ui/help_text.gd.uid deleted file mode 100644 index c1a819e..0000000 --- a/src/ui/help_text.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cmq500ivk0ro2 diff --git a/src/ui/inspector_panel.gd b/src/ui/inspector_panel.gd deleted file mode 100644 index 5ff9df3..0000000 --- a/src/ui/inspector_panel.gd +++ /dev/null @@ -1,700 +0,0 @@ -extends VBoxContainer -## Objekt-Inspektor (Karte t_bb0d11c9) — Godot/Unity-Style Eigenschaften-Panel -## oben im rechten Panel: Position/Drehung/Größe der markierten Objekte -## TIPPBAR (LineEdit) und ZIEHBAR (am Label ziehen, Godot-Konvention). -## -## Verdrahtung (main.gd): der Inspektor wird in _build_right_panel() als -## ERSTER Abschnitt eingehängt; refresh() läuft in _selection_status und -## _sync_selection_panel — damit füllen ALLE Auswahl-Wege das Panel -## (3D-Klick, Rahmen-Ausziehen, Map-Inhalt-Baum). -## -## Regeln der Karte: -## - Änderungen wirken LIVE im 3D-Fenster (Marker direkt umgesetzt, kein Rebuild). -## - JEDE Änderung ist EIN Strg+Z-Schritt: Tippen = ein Schritt beim Bestätigen -## (Enter/Klick woanders), Ziehen = ein Schritt beim Loslassen. -## - Mehrfachauswahl: Änderungen wirken auf ALLE markierten; ungleiche Werte -## zeigen „—“ und werden erst beim Tippen/Ziehen angeglichen. -## - SCALE IST FEST (Karte t_e166e656, Sly-Wunsch „Realismus“): die scale-Zeile -## ist bewusst ENTFERNT — neue Objekte bekommen immer scale 1.0, alte Karten -## laden mit ihrem gespeicherten scale (Format bleibt kompatibel). Hier gibt -## es nur den lesenden Hinweis „Größe fix“. -## - KIPPEN IN SÄMTLICHEN ACHSEN (Karte t_e166e656): das svmap-Feld `rot` -## (Euler x/y/z, OPTIONAL) trägt X/Z-Kippen; fehlt es, gilt rot_y_deg. -## rot/rot_y_deg bleiben über SvmapIO.rot_setzen synchron. -## - X/Z werden an der Map geklemmt, Y an den Match-Grenzen — Versenken UNTER -## die Terrain-Höhe ist ausdrücklich erlaubt (Steine im Boden), die -## Info-Zeile zeigt die Versenk-Tiefe. - -const EPS := 0.005 # Toleranz „gleicher Wert“ (Anzeige-Konsens) -const MIXED := "—" # Anzeige für ungleiche Werte in der Auswahl - - -func _clamp_norm_deg(f: float) -> float: - return fposmod(f + 180.0, 360.0) - 180.0 - - -class DragValue extends HBoxContainer: - ## Eine Zeile „Label + Wert“: am Label ziehen ändert den Wert live - ## (Godot-Inspector-Konvention), ins LineEdit tippen setzt ihn exakt. - ## Die Logik (Wert lesen/anwenden/Undo) liegt beim Inspektor — dieses - ## Widget ist nur die Eingabe-Maschine und ruft die Callables. - var step := 0.05 # Wert-Änderung pro Pixel beim Ziehen - var fmt := "%.2f" # Anzeige-Format - var suffix := "" - var min_v := -1000000.0 # Zieh-Grenzen (Anzeige + Doc werden geklemmt) - var max_v := 1000000.0 - var get_value: Callable # -> float (Wert des ersten markierten Objekts) - var is_mixed: Callable # -> bool (true = Werte in der Auswahl ungleich) - var begin_live: Callable # Undo-Basis merken (Zieh-Start) - var live_apply: Callable # (float) — live anwenden OHNE Undo-Commit - var end_live: Callable # (final: float, original: float) — Commit beim Loslassen - var commit: Callable # (float) — Tippen: Snapshot + anwenden + EIN Commit - - var label: Label - var edit: LineEdit - var _dragging := false - var _drag_base := 0.0 - var _drag_accum := 0.0 - - func _init() -> void: - add_theme_constant_override("separation", 6) - - func build(p_label: String, tip: String, edit_width: int) -> void: - label = Label.new() - label.text = p_label - # KEINE feste Mindestbreite — die kompakte X/Y/Z-Zeile (3 Widgetpaare - # nebeneinander) darf das Panel NICHT breiter drücken als das Fenster - # (Layout-Bruch bei UI-Größe Groß, Beweis-Probe 19.10.). Natürliche - # Breite von „X“/„Grad“/„Faktor“ reicht als Zieh-Fläche. - label.mouse_filter = Control.MOUSE_FILTER_STOP - label.tooltip_text = tip - label.gui_input.connect(_on_label_input) - add_child(label) - edit = LineEdit.new() - edit.custom_minimum_size = Vector2(edit_width, 0) - edit.select_all_on_focus = true - edit.text_submitted.connect(_on_text_submitted) - edit.focus_exited.connect(_on_focus_exited) - add_child(edit) - - func set_shown(v: float) -> void: - edit.text = (fmt % v) + suffix - - func set_mixed() -> void: - edit.text = "—" - - ## Probes/Tests: Ziehen programmgesteuert ausführen (gleicher Pfad wie Maus). - func probe_drag(pixels: float) -> void: - _start_drag() - _drag_accum += pixels - _apply_drag() - _finish_drag() - - func _start_drag() -> void: - _dragging = true - _drag_accum = 0.0 - _drag_base = float(get_value.call()) - begin_live.call() - - func _apply_drag() -> void: - var v := _clamp(_drag_base + _drag_accum * step) - live_apply.call(v) - set_shown(v) - - func _finish_drag() -> void: - if not _dragging: - return - _dragging = false - end_live.call(_clamp(_drag_base + _drag_accum * step), _drag_base) - - func _clamp(f: float) -> float: - return clampf(f, min_v, max_v) - - func _on_label_input(event: InputEvent) -> void: - if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: - if event.pressed: - _start_drag() - else: - _finish_drag() - elif event is InputEventMouseMotion and _dragging: - _drag_accum += event.relative.x - _apply_drag() - - func _parse(text: String) -> float: - var t := text.strip_edges().replace(",", ".") - if t.is_empty() or not t.is_valid_float(): - return NAN - return t.to_float() - - func _apply_text(text: String) -> void: - var v := _parse(text) - if is_nan(v): - set_shown(float(get_value.call())) # „—“/Müll → Anzeige wiederherstellen - return - commit.call(_clamp(v)) - - func _on_text_submitted(text: String) -> void: - _apply_text(text) - - func _on_focus_exited() -> void: - # Nur nachziehen, wenn der Text NICHT frisch bestätigt wurde (sonst - # würde Enter + Klick woanders DOPPELT committen). - if edit.text.is_empty(): - return - if edit.text.begins_with("—"): - return - # Bestätigte Werte wurden beim submitted bereits gesetzt und neu - # formatiert; weicht der Text noch ab (Klick weg ohne Enter), gilt das - # als bestätigt — EIN Undo-Schritt. - _apply_text(edit.text) - - -var _main # src/ui/main.gd (ungewollt typisiert — dynamisch) -var _head: Label -var _sub: Label -var _grid: GridContainer -var _info: Label -var _hint: Label -var _ground_btn: Button -var _farben_grid: GridContainer # Farbfeld-Raster (Karte t_b0edb807) -var _farbe_reset_btn: Button -var _farbe_status: Label -var _rows := {} # field -> DragValue -var _built := false - - -func setup(p_main) -> void: - _main = p_main - add_theme_constant_override("separation", 6) - - _head = Label.new() - _head.text = "Objekt-Inspektor" - _head.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - add_child(_head) - - _sub = Label.new() - _sub.text = "" - _sub.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - add_child(_sub) - - _hint = Label.new() - _hint.text = "Nichts ausgewählt.\nKlicke im Viewport ein Objekt an." - _hint.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - add_child(_hint) - - _grid = GridContainer.new() - _grid.columns = 1 - _grid.add_theme_constant_override("h_separation", 6) - _grid.add_theme_constant_override("v_separation", 6) - add_child(_grid) - - # --- Position X/Y/Z --- - _grid.add_child(_field("Position")) - var px := _make_row("pos_x", "X", "Position X in Meter — ZIEHEN am Label ändert live, TIPPEN setzt exakt (Enter bestätigt).", 0.05, "%.2f", " m") - var py := _make_row("pos_y", "Y", "Höhe (Fußpunkt) in Meter — ziehen/tippen. UNTER die Terrain-Höhe absenken ist erlaubt (Versenken, Karte t_e166e656), Untergrenze = Match-Grenze.", 0.05, "%.2f", " m") - var pz := _make_row("pos_z", "Z", "Position Z in Meter — ziehen/tippen.", 0.05, "%.2f", " m") - # Zieh-Grenzen grob an der Map orientieren (doc-Apply klemmt exakt). - var half_span: float = 1024.0 - px.min_v = -half_span - px.max_v = half_span - py.min_v = -200.0 # Versenken erlaubt (Karte t_e166e656) — _apply klemmt exakt an bounds.min.y - py.max_v = 80.0 - pz.min_v = -half_span - pz.max_v = half_span - var pos_row := HBoxContainer.new() - pos_row.add_theme_constant_override("separation", 6) - pos_row.add_child(px) - pos_row.add_child(py) - pos_row.add_child(pz) - _grid.add_child(pos_row) - - # --- Drehen & Kippen (Karte t_e166e656) --- - _grid.add_child(_field("Drehen & Kippen")) - _grid.add_child(_make_row("rot_y", "Drehen Y", "Blickrichtung in Grad (−180…180) — ziehen/tippen. Tasten: R (90°), Mausrad (15° fein).", 0.5, "%.1f", "°", -180.0, 180.0)) - _grid.add_child(_make_row("rot_x", "Kippen X", "Kippen um die X-Achse in Grad (−180…180) — vor/zurück neigen. Tasten: Strg+R / Strg+Umschalt+R.", 0.5, "%.1f", "°", -180.0, 180.0)) - _grid.add_child(_make_row("rot_z", "Kippen Z", "Kippen um die Z-Achse in Grad (−180…180) — links/rechts neigen. Tasten: Alt+R / Alt+Umschalt+R.", 0.5, "%.1f", "°", -180.0, 180.0)) - - # --- Größe (FEST, Karte t_e166e656) --- - _grid.add_child(_field("Größe")) - var gross_fix := Label.new() - gross_fix.text = "Größe fix (Original) — Assets bleiben in ihrer echten Größe." - gross_fix.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - _grid.add_child(gross_fix) - - var btn_row := HBoxContainer.new() - btn_row.add_theme_constant_override("separation", 6) - _ground_btn = Button.new() - _ground_btn.text = "Auf Boden setzen" - _ground_btn.custom_minimum_size = UIScale.v2(0, 40) - _ground_btn.tooltip_text = "Alle markierten Objekte exakt auf die Terrain-Höhe setzen (Strg+Bild↑ geht auch) — EIN Rückgängig-Schritt" - _ground_btn.pressed.connect(_on_ground) - btn_row.add_child(_ground_btn) - _grid.add_child(btn_row) - - # --- Farbe / Material (Karte t_b0edb807) --- - # Feste Palette als Farbfeld-Raster; Klick = Farbe auf ALLE markierten - # Objekte (EIN Undo-Schritt). „Zurücksetzen“ entfernt das tint-Feld → - # wieder die Pack-Farbe (Rückwärtskompatibel, wie vor der Karte). - _grid.add_child(_field("Farbe / Material")) - _farben_grid = GridContainer.new() - _farben_grid.columns = 4 - _farben_grid.add_theme_constant_override("h_separation", 6) - _farben_grid.add_theme_constant_override("v_separation", 6) - _grid.add_child(_farben_grid) - for eintrag in SvmapTint.PALETTE: - _farben_grid.add_child(_swatch(eintrag[1], str(eintrag[0]))) - var farbe_row := HBoxContainer.new() - farbe_row.add_theme_constant_override("separation", 6) - _farbe_reset_btn = Button.new() - _farbe_reset_btn.text = "Zurücksetzen (Pack-Farbe)" - _farbe_reset_btn.custom_minimum_size = UIScale.v2(0, 40) - _farbe_reset_btn.tooltip_text = "Farbe der markierten Objekte entfernen — sie zeigen wieder die Pack-Farbe — EIN Rückgängig-Schritt" - _farbe_reset_btn.pressed.connect(_on_farbe_reset) - farbe_row.add_child(_farbe_reset_btn) - _grid.add_child(farbe_row) - _farbe_status = Label.new() - _farbe_status.text = "" - _grid.add_child(_farbe_status) - - # --- Info (nur lesen) --- - _info = Label.new() - _info.text = "" - _info.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - add_child(_info) - - # Startzustand: keine Auswahl → nur Hinweis sichtbar (refresh() schaltet um). - _grid.visible = false - _info.visible = false - _ground_btn.visible = false - _built = true - - -func _field(text: String) -> Label: - var l := Label.new() - l.text = text - l.tooltip_text = "Werte gelten für ALLE markierten Objekte. „—“ = Werte sind verschieden und werden erst beim Tippen/Ziehen angeglichen." - return l - - -## Ein Farbfeld-Knopf (Karte t_b0edb807): flacher Farb-Button mit Tooltip. -func _swatch(c: Color, name: String) -> Button: - var btn := Button.new() - btn.custom_minimum_size = UIScale.v2(34, 34) - btn.tooltip_text = "%s — Farbe auf alle markierten Objekte anwenden (EIN Rückgängig-Schritt)" % name - btn.focus_mode = Control.FOCUS_NONE - var sb := StyleBoxFlat.new() - sb.bg_color = c - sb.set_corner_radius_all(6) - btn.add_theme_stylebox_override("normal", sb) - var sb_hover: StyleBoxFlat = sb.duplicate() - sb_hover.bg_color = c.lightened(0.08) # U7: Aufhellung statt Manuell-Mathe - btn.add_theme_stylebox_override("hover", sb_hover) - btn.add_theme_stylebox_override("pressed", sb_hover) - btn.add_theme_stylebox_override("focus", StyleBoxEmpty.new()) - btn.pressed.connect(_on_farbe_gewaehlt.bind(c, name)) - return btn - - -# ------------------------------------------------------------- Farbe/Material --- - -## Palette-Farbe auf ALLE markierten Objekte — EIN Undo-Schritt. -func _on_farbe_gewaehlt(c: Color, name: String) -> void: - var indices := _selected() - if indices.is_empty(): - return - var before: Dictionary = _main.history.snapshot(["objects"]) - var objects: Array = _main.doc.get("objects", []) - var changed := false - for i in indices: - var obj: Dictionary = objects[i] - var alt := SvmapTint.von(obj) - SvmapTint.setze(obj, c) - if not SvmapTint.gleich(alt, c): - changed = true - if not changed: - return # gleiche Farbe erneut → kein Leer-Schritt - _commit_common("Inspektor: Farbe %s" % name, before) - _main.view_builder.call("tint_refresh", indices) - - -## tint-Feld entfernen → Pack-Farbe — EIN Undo-Schritt. -func _on_farbe_reset() -> void: - var indices := _selected() - if indices.is_empty(): - return - var before: Dictionary = _main.history.snapshot(["objects"]) - var objects: Array = _main.doc.get("objects", []) - var changed := false - for i in indices: - var obj: Dictionary = objects[i] - if SvmapTint.hat(obj): - SvmapTint.entferne(obj) - changed = true - if not changed: - return # nichts hatte eine Farbe → kein Leer-Schritt - _commit_common("Inspektor: Farbe zurückgesetzt (Pack-Farbe)", before) - _main.view_builder.call("tint_refresh", indices) - - -## Status-Zeile der Farbsektion: Pack-Farbe / Palettenname / eigene Farbe / -## gemischt (Mehrfachauswahl mit verschiedenen Farben). -func _farbe_text(objs: Array) -> String: - if objs.is_empty(): - return "" - if objs.size() == 1: - var obj: Dictionary = objs[0] - if not SvmapTint.hat(obj): - return "Farbe: Pack-Farbe" - var c := SvmapTint.von(obj) - var pn := SvmapTint.palette_name(c) - return "Farbe: %s" % (pn if pn != "" else "eigene Farbe") - # Mehrfachauswahl: alle ohne Feld = Pack-Farbe, alle gleich = Name, sonst gemischt. - var first_hat := SvmapTint.hat(objs[0]) - var first_c := SvmapTint.von(objs[0]) - for obj in objs: - if SvmapTint.hat(obj) != first_hat: - return "Farbe: gemischt" - if first_hat and not SvmapTint.gleich(SvmapTint.von(obj), first_c): - return "Farbe: gemischt" - if not first_hat: - return "Farbe: Pack-Farbe" - var pn2 := SvmapTint.palette_name(first_c) - return "Farbe: %s" % (pn2 if pn2 != "" else "eigene Farbe") - - -func _make_row(field: String, lbl: String, tip: String, step: float, fmt: String, suffix: String, - min_v := -1000000.0, max_v := 1000000.0) -> DragValue: - var w := DragValue.new() - w.step = step - w.fmt = fmt - w.suffix = suffix - w.min_v = min_v - w.max_v = max_v - w.get_value = _get_value.bind(field) - w.is_mixed = _is_mixed.bind(field) - w.begin_live = _begin_live - w.live_apply = _live_apply.bind(field) - w.end_live = _end_live.bind(field) - w.commit = _commit.bind(field) - w.build(lbl, tip, UIScale.px(64)) - _rows[field] = w - return w - - -# ------------------------------------------------------------- Datenzugriff -- - -func _selected() -> Array: - if _main == null or _main.get("interaction") == null: - return [] - var objects: Array = _main.doc.get("objects", []) - var out: Array = [] - for i in _main.interaction.selected_indices: - if i is int and i >= 0 and i < objects.size(): - out.append(i) - return out - - -func _sel_objects() -> Array: - var objects: Array = _main.doc.get("objects", []) - var out: Array = [] - for i in _selected(): - var obj = objects[i] - if obj is Dictionary: - out.append(obj) - return out - - -func _entry(obj: Dictionary) -> Dictionary: - var manifest: Dictionary = _main.get("manifest") - if manifest == null or manifest.is_empty(): - return {} - var lib: Dictionary = manifest.get("objects", {}) - return lib.get(str(obj.get("id", "")), {}) - - -func _field_value(obj: Dictionary, field: String) -> float: - match field: - "pos_x": - var p: Array = obj.get("pos", [0.0, 0.0, 0.0]) - return float(p[0]) if (p as Array).size() == 3 else 0.0 - "pos_y": - var p: Array = obj.get("pos", [0.0, 0.0, 0.0]) - return float(p[1]) if (p as Array).size() == 3 else 0.0 - "pos_z": - var p: Array = obj.get("pos", [0.0, 0.0, 0.0]) - return float(p[2]) if (p as Array).size() == 3 else 0.0 - "rot_y": - return _clamp_norm_deg(SvmapIO.objekt_rotation(obj).y) - "rot_x": - return _clamp_norm_deg(SvmapIO.objekt_rotation(obj).x) - "rot_z": - return _clamp_norm_deg(SvmapIO.objekt_rotation(obj).z) - return 0.0 - - -func _get_value(field: String) -> float: - var objs := _sel_objects() - if objs.is_empty(): - return 0.0 - return _field_value(objs[0], field) - - -func _is_mixed(field: String) -> bool: - var objs := _sel_objects() - if objs.size() < 2: - return false - var first := _field_value(objs[0], field) - for obj in objs: - if absf(_field_value(obj, field) - first) > EPS: - return true - return false - - -# ------------------------------------------------------------ Anzeige (refresh) -- - -func refresh() -> void: - if not _built or _main == null or _main.doc.is_empty(): - return - var indices := _selected() - var objects: Array = _main.doc.get("objects", []) - var has := not indices.is_empty() - _grid.visible = has - _ground_btn.visible = has - _info.visible = has - _hint.visible = not has - if not has: - _head.text = "Objekt-Inspektor" - _sub.text = "" - return - - var objs := _sel_objects() - var m := objs.size() - # Kopf: Name(n) + ID + Kategorie + „N von M markiert“ + Poly. - var names := PackedStringArray() - for obj in objs: - if names.size() < 3: - names.append(str(LibraryBrowser.object_label(str(obj.get("id", "?"))))) - var more := " … +%d" % (m - 3) if m > 3 else "" - var name_txt := (" · ".join(names) + more) if m > 1 else str(LibraryBrowser.object_label(str(objs[0].get("id", "?")))) - _head.text = name_txt - var kat := "?" - var oid := str((objs[0] as Dictionary).get("id", "")) - var entry: Dictionary = _entry(objs[0]) - if not entry.is_empty(): - kat = str(entry.get("kategorie", "?")) - var poly := 0.0 - for obj in objs: - var e: Dictionary = _entry(obj) - poly += float(e.get("poly", 0)) * float(obj.get("scale", 1.0)) * float(obj.get("scale", 1.0)) - _sub.text = "ID: %s · Kategorie: %s · %d von %d Objekten markiert · Poly: %d" % [ - oid if m == 1 else "%s …" % oid, kat, m, objects.size(), int(poly)] - - for field in ["pos_x", "pos_y", "pos_z", "rot_y", "rot_x", "rot_z"]: - var w: DragValue = _rows[field] - if w.edit.has_focus(): - continue # nicht unter dem tippenden Nutzer wegziehen - if _is_mixed(field): - w.set_mixed() - else: - w.set_shown(_get_value(field)) - - # Farbsektion (Karte t_b0edb807): aktueller Farbstand der Auswahl. - _farbe_status.text = _farbe_text(objs) - - # Info-Block (nur lesen). - var lift := ObjectOps.lift_offset(_main.doc, indices[0]) - var lift_txt: String - if absf(lift) < ObjectOps.FLOAT_EPSILON: - lift_txt = "am Boden" - elif lift > 0.0: - lift_txt = "%+.2f m über dem Boden" % lift - else: - lift_txt = "%.2f m im Boden versenkt" % -lift - var e0: Dictionary = _entry(objs[0]) - var col: Dictionary = e0.get("collision", {}) - var col_size: Array = col.get("size", []) - var col_txt := "—" - if (col_size as Array).size() == 3: - var s := float(objs[0].get("scale", 1.0)) - col_txt = "%s %s × %s × %s m" % [ - ("Box" if str(col.get("shape", "box")) == "box" else str(col.get("shape", "?"))), - ("%.1f" % (float(col_size[0]) * s)), ("%.1f" % (float(col_size[1]) * s)), ("%.1f" % (float(col_size[2]) * s))] - var echt := _echt_modell(indices[0]) - _info.text = "Fußpunkt: y = %.2f m (%s)\nKollision: %s\nEchtes Modell: %s" % [ - float((objs[0] as Dictionary).get("pos", [0.0, 0.0, 0.0])[1]) if ((objs[0] as Dictionary).get("pos", [0.0, 0.0, 0.0]) as Array).size() == 3 else 0.0, - lift_txt, col_txt, "ja" if echt else "nein (Platzhalter)"] - - -func _echt_modell(idx: int) -> bool: - var markers: Array = _main.view_builder.object_markers - if idx < markers.size(): - var marker = markers[idx] - if marker != null and is_instance_valid(marker) and marker.has_meta("glb"): - return bool(marker.get_meta("glb")) - return not str(_entry(_main.doc["objects"][idx]).get("glb", "")).is_empty() - - -# ------------------------------------------------------------ Anwenden + Undo -- - -var _live_before: Dictionary = {} # Undo-Basis während des Ziehens -var _live_changed := false # hat das Ziehen das Doc wirklich geändert? - -func _begin_live() -> void: - _live_before = _main.history.snapshot(["objects"]) - _live_changed = false - -## Achtung Callable.bind hängt die gebundenen Argumente HINTER die -## Aufruf-Argumente: commit.call(v) → _commit(v, field). -func _live_apply(v: float, field: String) -> void: - if _apply(field, v): - _live_changed = true - -func _end_live(final: float, original: float, field: String) -> void: - if not _live_changed or absf(final - original) < 0.0001: - return # Ziehen ohne Änderung → kein Leer-Undo-Schritt - _commit_common("Inspektor: %s" % _desc_for(field, final), _live_before) - -func _commit(v: float, field: String) -> void: - var before: Dictionary = _main.history.snapshot(["objects"]) - if not _apply(field, v): - return # nichts geändert (alles geklemmt/identisch) → kein Leer-Schritt - _commit_common("Inspektor: %s" % _desc_for(field, v), before) - - -func _commit_common(desc: String, before: Dictionary) -> void: - _main.history.commit(desc, before, _main.history.snapshot(["objects"])) - _main.dirty = true - _main.call("_refresh_file_label") - _main.call("_refresh_stats") - _main.call("_refresh_history_buttons") - _main.call("_refresh_spawn_status") - _main.call("_set_status", "%s — Strg+Z macht es in EINEM Schritt rückgängig." % desc) - refresh() - - -func _desc_for(field: String, v: float) -> String: - var n := _sel_objects().size() - var mehr := "%d Objekte: " % n if n > 1 else "" - match field: - "pos_x": - return "%sPosition X = %.2f m" % [mehr, v] - "pos_y": - return "%sHöhe (Y) = %.2f m" % [mehr, v] - "pos_z": - return "%sPosition Z = %.2f m" % [mehr, v] - "rot_y": - return "%sDrehen (Y) = %.1f°" % [mehr, v] - "rot_x": - return "%sKippen (X) = %.1f°" % [mehr, v] - "rot_z": - return "%sKippen (Z) = %.1f°" % [mehr, v] - return "Inspektor-Änderung" - - -## Wert auf ALLE markierten Objekte anwenden + 3D-Ansicht live aktualisieren. -## false = nichts geändert (keine Auswahl / alles geklemmt). -func _apply(field: String, v: float) -> bool: - var indices := _selected() - if indices.is_empty(): - return false - var objects: Array = _main.doc.get("objects", []) - var half: Vector2 = _terrain_half() - var max_y := _max_y() - var min_y := _min_y() - var changed := 0 - # Position-Felder bei Mehrfachauswahl: der eingetippte Wert gilt für das - # ERSTE markierte Objekt (Anker), alle anderen wandern mit DEMSELBEN Delta - # mit → Abstände bleiben erhalten (Relativ-Move, wie beim Greifen). - # Bei 1 Objekt ist das Delta = absoluter Wert → Verhalten unverändert. - var rel_delta := 0.0 - if field == "pos_x" or field == "pos_y" or field == "pos_z": - var anchor_pos: Array = (objects[indices[0]] as Dictionary).get("pos", [0.0, 0.0, 0.0]) - if (anchor_pos as Array).size() == 3: - var comp := 0 if field == "pos_x" else (1 if field == "pos_y" else 2) - rel_delta = v - float(anchor_pos[comp]) - for i in indices: - var obj: Dictionary = objects[i] - var pos: Array = obj.get("pos", [0.0, 0.0, 0.0]) - if (pos as Array).size() != 3: - continue - var x := float(pos[0]) - var y := float(pos[1]) - var z := float(pos[2]) - if field == "rot_y" or field == "rot_x" or field == "rot_z": - # Karte t_e166e656: rot/rot_y_deg bleiben über rot_setzen synchron - # (reines Y → kein rot-Feld in der Datei). Anzeige normalisiert - # auf −180…180, gespeichert wird der Wert wie getippt. - var euler := SvmapIO.objekt_rotation(obj) - var neu := Vector3(euler.x, euler.y, euler.z) - if field == "rot_y": - neu.y = _clamp_norm_deg(v) - elif field == "rot_x": - neu.x = _clamp_norm_deg(v) - else: - neu.z = _clamp_norm_deg(v) - SvmapIO.rot_setzen(obj, neu) - changed += 1 - continue - if field == "pos_x": - x = clampf(float(pos[0]) + rel_delta, -half.x, half.x) - elif field == "pos_y": - # Karte t_e166e656: Versenken erlaubt — Untergrenze ist die - # Match-Grenze (bounds.min.y), NICHT mehr die Terrain-Höhe. - y = clampf(float(pos[1]) + rel_delta, min_y, max_y) - elif field == "pos_z": - z = clampf(float(pos[2]) + rel_delta, -half.y, half.y) - if absf(x - float(pos[0])) > 0.0001 or absf(y - float(pos[1])) > 0.0001 or absf(z - float(pos[2])) > 0.0001: - obj["pos"] = [x, y, z] - changed += 1 - _sync_markers(indices) - return changed > 0 - - -func _terrain_half() -> Vector2: - var terrain: Dictionary = _main.doc.get("terrain", {}) - return Vector2(float(terrain.get("size_x_m", 1024.0)), float(terrain.get("size_z_m", 1024.0))) * 0.5 - - -func _max_y() -> float: - var bounds: Dictionary = _main.doc.get("bounds", {}) - if (bounds.get("max", null) is Array) and ((bounds["max"] as Array).size() == 3): - return float(bounds["max"][1]) - return 80.0 - - -## Untere Match-Grenze (Karte t_e166e656): Versenken im Boden ist erlaubt, -## klemmt an bounds.min.y statt an der Terrain-Höhe. -func _min_y() -> float: - var bounds: Dictionary = _main.doc.get("bounds", {}) - if (bounds.get("min", null) is Array) and ((bounds["min"] as Array).size() == 3): - return float(bounds["min"][1]) - return -80.0 - - -func _sync_markers(indices: Array) -> void: - var markers: Array = _main.view_builder.object_markers - var objects: Array = _main.doc.get("objects", []) - for i in indices: - if i >= markers.size(): - continue - var marker = markers[i] - if marker == null or not is_instance_valid(marker): - continue - var pos: Array = (objects[i] as Dictionary).get("pos", [0.0, 0.0, 0.0]) - if (pos as Array).size() == 3: - marker.position = Vector3(float(pos[0]), float(pos[1]), float(pos[2])) - marker.rotation_degrees = SvmapIO.objekt_rotation(objects[i] as Dictionary) - - -# ------------------------------------------------------------------- Knöpfe -- - -func _on_ground() -> void: - # Bewährte Boden-Logik (interaction.snap_selection_to_floor): snapshotet, - # committet selbst EINEN Schritt und meldet in der Statuszeile. - _main.interaction.call("snap_selection_to_floor") - refresh() - - -## Für Tests/Probes: Widget zu einem Feld holen ("pos_x"…"rot_z"). -func widget(field: String) -> DragValue: - return _rows.get(field) diff --git a/src/ui/inspector_panel.gd.uid b/src/ui/inspector_panel.gd.uid deleted file mode 100644 index 3076705..0000000 --- a/src/ui/inspector_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dndmcn006xggw diff --git a/src/ui/main.gd b/src/ui/main.gd deleted file mode 100644 index 19490fb..0000000 --- a/src/ui/main.gd +++ /dev/null @@ -1,2920 +0,0 @@ -extends Control -## ScopedVR Map-Editor — Hauptfenster (M2 UX-Fundament, Karte t_40d855d0; -## U1-Modularisierung, Karte t_eaccbfed). -## -## U1 (Unity-artiges Layout-Fundament): diese Datei ist jetzt ein DÜNNER -## KOORDINATOR — Dokument/History, Werkzeug-Umschaltung, Shortcuts, Dialoge, -## Update, Playtest. Die Oberflächen-Bereiche wohnen in eigenen Modulen unter -## src/ui/panels/ und melden sich DATENGETRIEBEN in -## src/ui/panels/registry.gd an; das Layout wird ausschließlich aus der -## Registry gebaut (Operator-Vorgabe 20.10. — die Umbau-Karten U2–U7 ändern -## je nur IHR Modul + eine Registry-Zeile, nie wieder main.gd). -## -## Layout (Schaubild in /opt/data/scopedvr/KARTEN_UI_UNITY_vc27.md): -## Toolbar oben · links Tab "Map-Inhalt" · Mitte 3D-Ansicht · -## rechts Tabs (Inspektor/Auswahl/Map/Terrain/Prüfen) · -## unten Assets (Objekt-Bibliothek) · Statuszeile. -## Alles über HSplit/HSplit/VSplit größenverstellbar; die Splitter-Lage -## bleibt in user://scopedvr_editor.cfg ([fenster] Abschnitt) gemerkt. -## -## Farben/Namen kommen aus theme/editor_theme.tres (einzige Farbquelle). -## -## UX-Fundament (Chef-Grundsatz Sly — map-editor-README): -## 1. Undo/Redo (Strg+Z / Strg+Y) über ActionHistory — spätere Werkzeuge -## (Terrain, Spawn-Zonen) melden sich mit snapshot/commit einfach an. -## 2. Ghost-Preview: Platzier-Vorschau schwebt transparent am Cursor -## (interaction.gd), Klick setzt das Objekt. -## 3. Auswahl-Anfassen: Klick wählt, Ziehen verschiebt, -## R ODER Mausrad dreht (15°-Raster), Entf löscht. -## 4. Helfende Meldungen: Klartext + DER NÄCHSTE SCHRITT, keine Godot-Texte. -## 5. Deutsch & groß: Schrift ≥ 14 px, klickbare Flächen ≥ 40 px Höhe. - -const APP_TITLE := "ScopedVR Map-Editor" -# Shortcut-Infrastruktur (Karte t_c46d31c2): InputMap-Actions + Esc-Priorität. -const ShortcutKeys := preload("res://src/editor/shortcut_keys.gd") -const ShortcutPolicy := preload("res://src/editor/shortcut_policy.gd") -# Shortcuts-Mathe Karte 2/3 (t_55257792): Pfeil-Raster + Pinsel-Presets. -const MoveMath := preload("res://core/editor/move_math.gd") -# Kurzhilfe-Overlay Karte 3/3 (t_11b5c25b): Gesamte Tastenliste als BBCode. -const HelpText := preload("res://src/ui/help_text.gd") -# Zentrale UI-Skalierung (Karte t_297221b5): EIN Faktor für Schrift/Panels/Zeilen. -const UIScale := preload("res://src/ui/ui_scale.gd") -# U1 (t_eaccbfed): die Registry ist die EINZIGE Layout-Quelle. -const PanelRegistryScript := preload("res://src/ui/panels/registry.gd") -# Editor-Theme (U1): eine Theme-Ressource als einzige Farbquelle. -const THEME_PATH := "res://theme/editor_theme.tres" - -var manifest: Dictionary = {} -var doc: Dictionary = {} # das Map-Dictionary (1:1 svmap-Format) -var current_path := "" # leer = noch nie gespeichert -var dirty := false -var grid_snap := false # Raster-Snap (1 m) an/aus — Objekt-Werkzeuge links - -var history := ActionHistory.new() -var interaction # src/editor/interaction.gd (script-erweitert → untypisiert) -var viewport_toolbar # src/ui/viewport_toolbar.gd (Buttons oben links in der 3D-Ansicht) -var gizmo # src/viewport/gizmo.gd (Achsen-Pfeile, Kind von interaction) -var gizmo_step_m := 0.5 # Gizmo-Schrittweite in m (Panel-Feld; überlebt UI-Rebuilds) -var terrain_tool # src/editor/terrain_tool.gd (Pinsel, Karte t_9aba04f1) -var spawn_tool # src/editor/spawn_tool.gd (Zonen, Karte t_c4162c5d) -var tool_mode := "objects" # "objects" | "terrain" | "spawns" | "teststart" (Bauen = Objekt-Platzieren mit Rastern) - -# Symmetrie-Modus (Karte t_f5935023, M1): Modus + Toolbar-Schalter -# + Statuszeilen-Anzeige. Standard = Punktspiegelung (Sly 20.10.). M1 legt nur -# Modus + Anzeige fest; das Spiegeln selbst kommt mit M2–M4. -var sym_mode: int = SymmetryCore.Mode.POINT - -# UI-Referenzen (Koordinator-Sicht auf die Module — Panels bauen selbst) -var status_label: Label -var file_label: Label -var help_label: Label -var view_builder: Node3D -var camera: Camera3D -var inspector: Control # Objekt-Inspektor (Karte t_bb0d11c9) — im Inspektor-Tab - -# U1-Module (aus der Registry gebaut; Toolbar/Status/Kern-Widget-Referenzen -# bleiben hier, damit Tests/Tools denselben Vertrag sehen wie vorher) -var toolbar_mod # src/ui/panels/toolbar.gd -var status_mod # src/ui/panels/status_bar.gd -var selection_mod # src/ui/panels/selection_panel.gd (nur Logik, kein Tab mehr) -var settings_mod # src/ui/panels/settings_panel.gd (im Einstellungen-Fenster) -var drop_overlay: Control # Ablege-Fläche über der 3D-Ansicht (nur während Drag aktiv) -var settings_dialog: AcceptDialog # Fenster „Einstellungen“ (Knopf in der Kopfleiste) -var sym_mod # src/ui/panels/symmetry_panel.gd (im Map-Tab) -var map_mod # src/ui/panels/map_panel.gd -var terrain_mod # src/ui/panels/terrain_panel.gd -var malen_mod # src/ui/panels/malen_panel.gd (Malen-Tab) -var bauen_mod # src/ui/panels/bauen_panel.gd (Bauen-Tab) -var check_mod # src/ui/panels/check_panel.gd -var tree_mod # src/ui/panels/scene_tree_panel.gd -var assets_mod # src/ui/panels/assets_panel.gd -var content_tree: Tree # weiter in tree_mod (Bequemlichkeits-Referenz) -var stats_objects: Label # weiter in status_mod -var stats_terrain: Label # weiter in status_mod -var tool_label: Label # weiter in status_mod -var sym_label: Label # weiter in status_mod -var undo_btn: Button # weiter in toolbar_mod -var redo_btn: Button # weiter in toolbar_mod -var grid_btn: CheckButton # weiter in settings_mod (Einstellungen-Fenster) -var contours_btn: CheckButton # weiter in settings_mod -var size_menu: OptionButton # weiter in settings_mod -var sym_menu: OptionButton # weiter in settings_mod -var prop_name: LineEdit # weiter in map_mod -var gizmo_step_box: SpinBox # weiter in settings_mod -var library_search: LineEdit # weiter in assets_mod -var library_buttons: Dictionary = {} # weiter in assets_mod (Bequemlichkeit) -var _library_group_rows: Array = [] # weiter in assets_mod (Bequemlichkeit) -var spawn_status: Label # weiter in check_mod -var terrain_info: Label # weiter in map_mod -var terrain_mode_lower: Button # weiter in terrain_mod (Test-Vertrag) -var terrain_size_btn_small: Button # weiter in terrain_mod -var terrain_size_btn_medium: Button # weiter in terrain_mod -var terrain_size_btn_large: Button # weiter in terrain_mod -var terrain_palette: VBoxContainer # weiter in terrain_mod -var terrain_radius_slider: HSlider # weiter in terrain_mod -var terrain_radius_label: Label # weiter in terrain_mod -var terrain_strength_slider: HSlider # weiter in terrain_mod -var terrain_mat_buttons: Array = [] # weiter in terrain_mod (Gras/Sand/Fels) -var library_open_all_btn: Button # weiter in assets_mod -var library_close_all_btn: Button # weiter in assets_mod - -# Toolbar-/Panel-Zustand (gehört dem Koordinator) -var _grid_on := false # Nutzer-Wahl für das Maßstabsgitter -# Höhenlinien (Karte t_89c0ec95): _contours_on ist die NUTZER-Wahl „fixiert -# an“ (L-Taste oder Button). Ohne Fix erscheinen die Linien NUR im -# Terrain-Werkzeug (F1) — Sly-Befund 17.10.: dauerhaft sichtbar störte. -# Effektiv = _contours_fix AN ODER tool_mode == "terrain". -var _contours_on := false - -# --- Test-Start (Karte t_96e3c4ee / T1b) ------------------------------------- -# main hält den ZUSTAND und die Haken (Vertrag mit tests/test_playtest_spawn.gd); -# das Panel-Modul test_start_panel.gd zeigt ihn nur an (U1-Muster). -var test_start_point: Variant = null # Vector3 (nur x/z zählt) oder null -var test_start_tool # src/editor/playtest/test_start_tool.gd -var test_start_panel: Control # src/ui/panels/test_start_panel.gd (von der Prüfsuite erwartet) -var test_start_btn: Button # „🎯 Test-Start" in der Leiste (Umschalter) -var _test_start_active := false -var _loading_ui_values := false # verhindert dirty beim Auffüllen der Felder - -# Rahmen-Ausziehen (Rubberband) — Overlay über dem 3D-Viewport -var rubber_overlay: Control -var rubber_rect := Rect2() # leer = Overlay aus - -# Playtest (Karte t_1cdc1a72) + Lauf-Modus-Panelverweise -var playtest: Node = null # src/editor/playtest/playtest_mode.gd Instanz -var _playtest_tool_mode := "" # gemerkter Werkzeug-Modus für die Rückkehr -var ui_top_bar: Control # Top-Bar (im Lauf-Modus aus) -var ui_left_panel: Control # linke Spalte (im Lauf-Modus aus) -var ui_right_panel: Control # rechte Tab-Spalte (im Lauf-Modus aus) -var ui_status_bar: Control # Statusleiste (im Lauf-Modus aus) -var ui_dock_bottom: Control # Assets-Bereich unten (im Lauf-Modus aus) -var world3d: Node3D # 3D-Wurzel im SubViewport (Spieler lebt hier) - -# Karte 3/3 (t_11b5c25b): Dirty-Schutz + Kurzhilfe + Werkzeug-Statuszeile. -var dirty_dialog: ConfirmationDialog # „Ungespeicherte Änderungen verwerfen?“ -var resign_dialog: ConfirmationDialog # „Trotzdem laden (Prüfsumme erneuern)“ (t_9814f18f) -var _resign_pending_path: String = "" -var _pending_after_dirty := Callable() # was nach „Verwerfen“ ausgeführt wird -var help_overlay: PanelContainer # H-Kurzhilfe (nicht-blockierend) -var help_overlay_title: Label -var help_overlay_text: RichTextLabel - -# Editor-Selbstupdate (Karte t_d95f087a): Start-Check + Banner + „Jetzt updaten“ -var update_banner: PanelContainer # Leiste „🔄 Update verfügbar …“ (versteckt) -var update_label: Label -var update_btn: Button # „Jetzt updaten“ im Banner -var check_thread: Thread # Update-Check im Hintergrund (Start/Menü) -var update_thread: Thread # Update-Ausführung (pull + Import-Lauf) -var _update_check_busy := false -var _hand_pose_thread: Thread = null -var _update_running := false -var _update_result: Dictionary = {} # letzter Check (Status/Banner-Nachfrage) - -# Dialoge -var new_dialog: AcceptDialog -var open_dialog: FileDialog -var save_dialog: FileDialog -var error_dialog: AcceptDialog -var resize_dialog: ConfirmationDialog # „Kartengröße ändern“ (R3, t_c863b93b) -var error_text: Label - -# Map-Check (Karte prüfen) -var check_dialog: AcceptDialog -var check_text: Label - -# Update-Check-Ergebnis (Menü „🔄 Updates prüfen“, Sly 20.10.: nur die -# Statuszeile las sich wie „tut nichts“ → kleines Ergebnis-Fenster). -var update_dialog: AcceptDialog -var update_text: Label - -# Karte testen (Karte t_b84af40f) -var test_btn: Button - -# U1-Dock-Zustand: Splitter-Lagen ([fenster]-Abschnitt, gemerkt) -var _dock_offsets: Dictionary = {} -var _split_lagen_playtest: Dictionary = {} # Playtest: Trenner-Lagen (Sly-Befund 20.10.) - -const GizmoScript := preload("res://src/viewport/gizmo.gd") -const INSPECTOR_PANEL := preload("res://src/ui/inspector_panel.gd") - - -func _ready() -> void: - # InputMap-Actions der Tastatur-Shortcuts (Karte t_c46d31c2) — VOR UI/Kamera, - # damit die Kamera-Polls (Flug W/A/S/D + Leertaste/Shift) sofort kennen. - ShortcutKeys.register() - manifest = _load_manifest() - _build_ui() - _update_tool_label() - # Symmetrie-Anzeige initialisieren (Karte t_f5935023, M1): Standard = Punkt. - _update_sym_ui() - # Fenster-Zustand (Karte t_297221b5): Default MAXIMIERT (kein Vollbild); - # wer auf Fenstergröße umschaltet, bekommt die gemerkte Lage wieder. - # Close-Request selbst behandeln, damit die Lage VOR dem Quit gemerkt wird. - get_tree().set_auto_accept_quit(false) - _apply_window_state() - _load_dock_state() - _start_with_new_map() - _maybe_start_demo_mode() - # Selbst-Update (Karte t_d95f087a): STILLER Start-Check im Hintergrund — - # nur bei „Update verfügbar“ erscheint das Banner; offline/Tunnel weg - # bleibt alles ruhig (kein Banner, keine Meldung). - _startup_update_check() - - -func _load_manifest() -> Dictionary: - var parsed: Variant = JSON.parse_string(FileAccess.get_file_as_string(SvmapIO.MANIFEST_PATH)) - if parsed is Dictionary: - LibraryBrowser.setze_manifest(parsed) - return parsed - push_error("Bibliothek library/objects.json konnte nicht geladen werden!") - return {} - - -# ------------------------------------------------------------------ UI-Bau -- -## Layout aus der Registry (U1, Operator-Vorgabe): Top-Bar → Update-Banner → -## Haupt-WSplit (links Tabs | Mitte 3D | rechts Tabs) → unten Assets → -## Statuszeile. Kein Panel wird hier fest verdrahtet — Registry ändert das -## Layout, main.gd bleibt gleich. - -func _build_ui() -> void: - var theme_res: Theme = load(THEME_PATH) - theme_res.default_font_size = UIScale.font_size() - self.theme = theme_res - - var vbox := VBoxContainer.new() - vbox.set_anchors_preset(Control.PRESET_FULL_RECT) - vbox.add_theme_constant_override("separation", UIScale.px(4)) - add_child(vbox) - - # --- Top-Bar (Modul toolbar.gd) --- - var top := PanelContainer.new() - # _make_module hängt das Modul selbst an den Container (doppelt add_child - # würde „already has a parent“ werfen). - var top_h: Control = _make_module(toolbar_script(), top) - vbox.add_child(top) - ui_top_bar = top # Lauf-Modus (t_1cdc1a72): Top-Bar ausblenden - toolbar_mod = top_h - _pull_toolbar_refs() - _update_banner_build(vbox) - - # --- Hauptbereich: links Tabs | Mitte 3D | rechts Tabs --- - var split := HSplitContainer.new() - split.size_flags_vertical = Control.SIZE_EXPAND_FILL - split.size_flags_horizontal = Control.SIZE_EXPAND_FILL - split.split_offset = UIScale.px(-320) - split.name = "MainSplit" - vbox.add_child(split) - - # Lauf-Modus (t_1cdc1a72): linke/rechte Spalte als Member — werden im - # Lauf-Modus ausgeblendet, die 3D-Ansicht (Mitte) bleibt stehen. - var left_tabs := _build_group_tabs("links") - left_tabs.name = "LeftTabs" - ui_left_panel = left_tabs - split.add_child(left_tabs) - split.add_child(_build_center_viewport()) - var right_tabs := _build_group_tabs("rechts") - right_tabs.name = "RightTabs" - ui_right_panel = right_tabs - right_tabs.tab_changed.connect(_on_right_tab_changed) - split.add_child(right_tabs) - _build_map_sections() - - # --- Assets unten (Registry-Gruppe "unten", U1 Auftragspunkt 4) --- - # Die Objekt-Bibliothek wohnt jetzt UNTER dem Hauptbereich (Unity- - # Projekt-Fenster-Platz). Höhe größenverstellbar über den VSplit und - # gemerkt in [fenster] (dock_unten). - var bottom_wrap := VSplitContainer.new() - bottom_wrap.size_flags_vertical = Control.SIZE_EXPAND_FILL - bottom_wrap.size_flags_horizontal = Control.SIZE_EXPAND_FILL - bottom_wrap.name = "BottomSplit" - # WICHTIG: den Haupt-Split ERST aus der VBox trennen, dann in den VSplit - # hängen — add_child auf ein Kind mit Parent ist ein stiller Baum-Fehler - # (Node hängt dann im Nichts: Slider/Skript-Signale laufen nicht). - vbox.remove_child(split) - # VSplit-Kind 1: der Haupt-Split (links|3D|rechts) — er wächst. - split.size_flags_vertical = Control.SIZE_EXPAND_FILL - bottom_wrap.add_child(split) - # VSplit-Kind 2: die Assets-Tabs. - var bottom_tabs := _build_group_tabs("unten") - bottom_tabs.name = "BottomTabs" - bottom_tabs.custom_minimum_size = UIScale.v2(0, 300) - var bottom_panel := PanelContainer.new() - bottom_panel.add_child(bottom_tabs) - bottom_wrap.add_child(bottom_panel) - # Der VSplit ersetzt den Platz des bisherigen Haupt-Splits in der VBox. - vbox.add_child(bottom_wrap) - ui_dock_bottom = bottom_wrap - - # --- Statusleiste (Modul status_bar.gd) --- - var status_panel := PanelContainer.new() - var status_h: Control = _make_module(status_bar_script(), status_panel) - vbox.add_child(status_panel) - ui_status_bar = status_panel # Lauf-Modus (t_1cdc1a72): Statusleiste aus - status_mod = status_h - _pull_status_refs() - status_label = status_mod.status_label - file_label = toolbar_mod.file_label - - _build_dialogs_and_overlays() - - -func toolbar_script() -> GDScript: - return load("res://src/ui/panels/toolbar.gd") - - -func status_bar_script() -> GDScript: - return load("res://src/ui/panels/status_bar.gd") - - -## Ein Modul (EditorPanel-Ableger) instanziieren und bauen; Rückgabe = das -## Panel selbst (Container). Fehler im Modul-Skript = fette Meldung statt -## stiller null-Referenzen. -func _make_module(script: GDScript, parent: Control) -> Control: - var mod: Control = script.new() - parent.add_child(mod) - if mod.has_method("setup"): - mod.setup(self) - if mod.has_method("build"): - mod.call("build") - return mod - - -func _pull_toolbar_refs() -> void: - undo_btn = toolbar_mod.undo_btn - redo_btn = toolbar_mod.redo_btn - - -func _pull_status_refs() -> void: - stats_objects = status_mod.stats_objects - stats_terrain = status_mod.stats_terrain - tool_label = status_mod.tool_label - sym_label = status_mod.sym_label - status_label = status_mod.status_label - - -## Eine Tab-Gruppe aus der Registry bauen (links/rechts/unten). Jeder Bereich -## erscheint GENAU EINMAL (test_ui_layout prüft das). Die Panels werden per -## preload aus dem Registry-Eintrag erzeugt. -func _build_group_tabs(gruppe: String) -> TabContainer: - var tabs := TabContainer.new() - tabs.size_flags_horizontal = Control.SIZE_EXPAND_FILL - tabs.size_flags_vertical = Control.SIZE_EXPAND_FILL - tabs.add_theme_constant_override("separation", UIScale.px(8)) - var entries: Array = PanelRegistryScript.entries(gruppe) - for entry in entries: - var script: GDScript = load(str(entry["skript"])) - var panel: Control = script.new() - panel.name = str(entry["id"]) - panel.setup(self) - # Der Alt-Inspektor (t_bb0d11c9) baut in setup() — build() ist dort - # nicht vorhanden; neue Module bauen in build(). Beides zulassen. - if panel.has_method("build"): - panel.call("build") - tabs.add_child(panel) - tabs.set_tab_title(panel.get_index(), str(entry["titel"])) - _panel_group_built(gruppe, tabs) - return tabs - - -## Gruppen-Nacharbeit: Referenzen ziehen, sobald ihre Tabs stehen. -func _panel_group_built(gruppe: String, tabs: TabContainer) -> void: - match gruppe: - "rechts": - for child in tabs.get_children(): - match child.name: - "inspektor": - inspector = child - "map": - map_mod = child - "terrain": - terrain_mod = child - "malen": - malen_mod = child - "bauen": - bauen_mod = child - prop_name = map_mod.prop_name - terrain_info = map_mod.terrain_info - # Malen-Widgets wohnen im Malen-Tab; das Terrain-Modul hält die - # alten Namen als Aliase (Tests/Werkzeug-Vertrag). - terrain_mod.terrain_palette = malen_mod.palette - terrain_mod.terrain_mat_buttons = malen_mod.mat_buttons - terrain_mod.terrain_weich_label = malen_mod.weich_label - terrain_mod.terrain_weich_slider = malen_mod.weich_slider - terrain_mod.terrain_paint_hint = malen_mod.paint_hint - # Test-/Werkzeug-Vertrag (wie vor der U1-Aufteilung): die Widgets - # wohnen in den Modulen, der Koordinator hält die alten Namen - # als Bequemlichkeits-Referenzen — nichts wird doppelt gebaut. - terrain_mode_lower = terrain_mod.terrain_mode_lower - terrain_size_btn_small = terrain_mod.terrain_size_btn_small - terrain_size_btn_medium = terrain_mod.terrain_size_btn_medium - terrain_size_btn_large = terrain_mod.terrain_size_btn_large - terrain_palette = terrain_mod.terrain_palette - terrain_radius_slider = terrain_mod.terrain_radius_slider - terrain_radius_label = terrain_mod.terrain_radius_label - terrain_strength_slider = terrain_mod.terrain_strength_slider - terrain_mat_buttons = terrain_mod.terrain_mat_buttons - "links": - for child in tabs.get_children(): - if child.name == "szene": - tree_mod = child - content_tree = tree_mod.content_tree - "unten": - for child in tabs.get_children(): - if child.name == "assets": - assets_mod = child - library_search = assets_mod.library_search - library_buttons = assets_mod.library_buttons - _library_group_rows = assets_mod._library_group_rows - library_open_all_btn = assets_mod.library_open_all_btn - library_close_all_btn = assets_mod.library_close_all_btn - - -## Abschnitte im Map-Tab (Registry-Gruppe "map"): Spawn-Zonen, Test-Start-Info, -## Symmetrie. Sie hängen UNTER den Map-Eigenschaften im selben Scroll-Bereich. -func _build_map_sections() -> void: - var host: Control = map_mod.sections_host() - for entry in PanelRegistryScript.entries("map"): - var script: GDScript = load(str(entry["skript"])) - var panel: Control = script.new() - panel.name = str(entry["id"]) - panel.setup(self) - if panel.has_method("build"): - panel.call("build") - host.add_child(HSeparator.new()) - host.add_child(panel) - match str(entry["id"]): - "check": - check_mod = panel - spawn_status = check_mod.spawn_status - "symmetrie": - sym_mod = panel - - -## Einstellungen-Fenster (Knopf ⚙ in der Kopfleiste): Inhalt kommt aus der -## Registry-Gruppe "dialog". Gitter, Höhenlinien, Symmetrie-Modus, UI-Größe, -## Raster-Snap und Gizmo-Schritt wohnen dort (vorher Kopfleiste / Objekt-Werkzeuge). -func _build_settings_dialog() -> void: - settings_dialog = AcceptDialog.new() - settings_dialog.name = "EinstellungenFenster" - settings_dialog.title = "Einstellungen" - settings_dialog.exclusive = false - settings_dialog.ok_button_text = "Schließen" - settings_dialog.min_size = UIScale.v2i(520, 420) - var scroll := ScrollContainer.new() - scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED - scroll.custom_minimum_size = UIScale.v2(500, 380) - settings_dialog.add_child(scroll) - for entry in PanelRegistryScript.entries("dialog"): - var script: GDScript = load(str(entry["skript"])) - var panel: Control = script.new() - panel.name = str(entry["id"]) - panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL - panel.setup(self) - if panel.has_method("build"): - panel.call("build") - scroll.add_child(panel) - settings_mod = panel - add_child(settings_dialog) - grid_btn = settings_mod.grid_btn - contours_btn = settings_mod.contours_btn - size_menu = settings_mod.size_menu - sym_menu = settings_mod.sym_menu - gizmo_step_box = settings_mod.gizmo_step_box - settings_mod.call("refresh") - - -func _open_settings() -> void: - if settings_dialog == null: - return - settings_mod.call("refresh") - # So groß, dass alles ohne Scrollen sichtbar ist (Inhalt + Titel/Knopf), begrenzt aufs Fenster. - var inhalt: Vector2 = settings_mod.get_combined_minimum_size() - var fenster := Vector2(get_window().size) - var breite := clampf(maxf(inhalt.x + UIScale.px(60), UIScale.px(640)), UIScale.px(640), fenster.x * 0.95) - var hoehe := clampf(inhalt.y + UIScale.px(110), UIScale.px(520), fenster.y * 0.95) - settings_dialog.popup_centered(Vector2i(int(breite), int(hoehe))) - - -func _build_dialogs_and_overlays() -> void: - selection_mod = load("res://src/ui/panels/selection_panel.gd").new() - selection_mod.name = "AuswahlLogik" - selection_mod.setup(self) - add_child(selection_mod) - _build_settings_dialog() - # --- Dialoge --- - new_dialog = preload("res://src/ui/new_map_dialog.gd").new() - new_dialog.confirmed.connect(_on_new_map_confirmed) - add_child(new_dialog) - - # R3 (t_c863b93b): „Kartengröße ändern“ — Preview-Dialog, Ausführen als - # EINE Undo-Einheit in _on_resize_confirmed. - resize_dialog = preload("res://src/ui/resize_map_dialog.gd").new() - resize_dialog.confirmed.connect(_on_resize_confirmed) - add_child(resize_dialog) - - open_dialog = FileDialog.new() - open_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE - open_dialog.access = FileDialog.ACCESS_FILESYSTEM - open_dialog.title = "Map öffnen" - open_dialog.filters = PackedStringArray(["*.svmap ; ScopedVR Map"]) - open_dialog.size = UIScale.v2i(800, 560) - open_dialog.file_selected.connect(_on_open_selected) - add_child(open_dialog) - - save_dialog = FileDialog.new() - save_dialog.file_mode = FileDialog.FILE_MODE_SAVE_FILE - save_dialog.access = FileDialog.ACCESS_FILESYSTEM - save_dialog.title = "Map speichern unter" - save_dialog.filters = PackedStringArray(["*.svmap ; ScopedVR Map"]) - save_dialog.size = UIScale.v2i(800, 560) - save_dialog.file_selected.connect(_on_save_selected) - add_child(save_dialog) - - error_dialog = AcceptDialog.new() - error_dialog.title = "Fehler" - error_dialog.ok_button_text = "Alles klar" - error_text = Label.new() - error_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - error_text.custom_minimum_size = UIScale.v2(560, 0) - error_dialog.add_child(error_text) - add_child(error_dialog) - - # Map-Check-Dialog (Karte prüfen, Karte t_c4162c5d). - check_dialog = AcceptDialog.new() - check_dialog.title = "Map-Check" - check_dialog.ok_button_text = "Danke!" - check_text = Label.new() - check_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - check_text.custom_minimum_size = UIScale.v2(620, 0) - check_dialog.add_child(check_text) - add_child(check_dialog) - - # Update-Check-Ergebnis (Sly 20.10.: „tut nichts“ — weil die Rückmeldung - # NUR in der Statuszeile kam und dort schnell wieder weg war). Kleines - # Fenster mit dem Klartext-Ergebnis, Stil wie der Map-Check-Dialog. - update_dialog = AcceptDialog.new() - update_dialog.title = "Update-Check" - update_dialog.ok_button_text = "Alles klar" - update_text = Label.new() - update_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - update_text.custom_minimum_size = UIScale.v2(560, 0) - update_dialog.add_child(update_text) - add_child(update_dialog) - - # Karte 3/3 (t_11b5c25b): Dirty-Schutz vor „Neue Map“ / „Öffnen“ — deutsche - # Klartext-Frage, „Verwerfen“ führt die wartende Aktion aus, „Abbrechen“ tut - # nichts (Map bleibt, wie sie ist). - dirty_dialog = ConfirmationDialog.new() - dirty_dialog.title = "Ungespeicherte Änderungen" - dirty_dialog.dialog_text = "Die Map hat ungespeicherte Änderungen — beim Fortfahren gehen sie verloren.\nJetzt verwerfen und fortfahren?" - dirty_dialog.ok_button_text = "Verwerfen" - dirty_dialog.cancel_button_text = "Abbrechen" - dirty_dialog.confirmed.connect(_on_dirty_confirmed) - add_child(dirty_dialog) - - # Fremdformat-Dialog (t_9814f18f): Lade-Fehler NUR an der Prüfsumme (V13), - # Kern-Validierung grün → „Trotzdem laden (Prüfsumme erneuern)“ statt hartem - # Abbruch; der Editor signiert das Dokument dann mit dem v2-Schema neu. - resign_dialog = ConfirmationDialog.new() - resign_dialog.title = "Prüfsumme stimmt nicht" - resign_dialog.dialog_text = "Der Inhalt der Map ist intakt, aber die Prüfsumme stimmt nicht (die Datei wurde von einem fremden Programm geschrieben oder anders formatiert).\n\nTrotzdem laden? Die Prüfsumme wird beim nächsten Speichern erneuert." - resign_dialog.ok_button_text = "Trotzdem laden (Prüfsumme erneuern)" - resign_dialog.cancel_button_text = "Abbrechen" - resign_dialog.confirmed.connect(_on_resign_confirmed) - add_child(resign_dialog) - - # Kurzhilfe-Overlay (Karte 3/3): H schaltet es an, H/Esc aus. Kein modal - # Dialog — der Editor bleibt bedienbar, das Panel liegt nur obenauf. - help_overlay = PanelContainer.new() - var overlay_style := StyleBoxFlat.new() - # U7: Farben über das Theme (Editor/colors/help_bg, help_border). - overlay_style.bg_color = get_theme_color("help_bg", "Editor") - overlay_style.border_color = get_theme_color("help_border", "Editor") - overlay_style.set_border_width_all(2) - overlay_style.set_corner_radius_all(8) - overlay_style.set_content_margin_all(UIScale.px(14)) - help_overlay.add_theme_stylebox_override("panel", overlay_style) - # Zentriertes Panel statt Vollbild: der Editor bleibt rundherum bedienbar - # (nicht-blockierend), das Panel ist groß genug für die ganze Tabelle. - # Grow BOTH: das Panel wächst SYMMETRISCH um den Mittelpunkt (sonst hängt - # seine linke obere Ecke am Zentrum und es läuft rechts/unten aus dem Bild). - help_overlay.set_anchors_and_offsets_preset(Control.PRESET_CENTER) - help_overlay.grow_horizontal = Control.GROW_DIRECTION_BOTH - help_overlay.grow_vertical = Control.GROW_DIRECTION_BOTH - help_overlay.custom_minimum_size = UIScale.v2(880, 640) - help_overlay.visible = false - var overlay_box := VBoxContainer.new() - overlay_box.add_theme_constant_override("separation", UIScale.px(6)) - help_overlay.add_child(overlay_box) - help_overlay_title = Label.new() - help_overlay_title.text = "Hilfe — Werkzeuge, Steuerung und Tastenkürzel (H oder Esc schließt)" - help_overlay_title.add_theme_font_size_override("font_size", UIScale.heading_font_size()) - help_overlay_title.add_theme_color_override("font_color", get_theme_color("accent", "Editor")) - overlay_box.add_child(help_overlay_title) - help_overlay_text = RichTextLabel.new() - help_overlay_text.bbcode_enabled = true - help_overlay_text.size_flags_vertical = Control.SIZE_EXPAND_FILL - help_overlay_text.custom_minimum_size = UIScale.v2(0, 0) - help_overlay_text.text = HelpText.text() - overlay_box.add_child(help_overlay_text) - add_child(help_overlay) - - -## Ziehen aus der Objekt-Bibliothek: Vorschau folgt der Maus, Loslassen setzt. -func _viewport_can_drop(at_position: Vector2, data: Variant) -> bool: - if not (data is Dictionary) or not (data as Dictionary).has("svr_oid") or doc.is_empty() or assets_mod == null: - return false - assets_mod.drag_hover(str(data["svr_oid"]), at_position) - return true - - -func _viewport_drop(at_position: Vector2, data: Variant) -> void: - if data is Dictionary and (data as Dictionary).has("svr_oid") and assets_mod != null: - assets_mod.drag_drop(str(data["svr_oid"]), at_position) - - -func _build_center_viewport() -> SubViewportContainer: - var container := SubViewportContainer.new() - container.stretch = true - container.size_flags_horizontal = Control.SIZE_EXPAND_FILL - container.size_flags_vertical = Control.SIZE_EXPAND_FILL - # Objekt-Kachel aus der Bibliothek in die Szene ziehen (25.10.). - container.set_drag_forwarding(Callable(), _viewport_can_drop, _viewport_drop) - - var viewport := SubViewport.new() - viewport.own_world_3d = true - viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS - container.add_child(viewport) - - var world := Node3D.new() - viewport.add_child(world) - world3d = world # Lauf-Modus (t_1cdc1a72): Spieler-Body lebt in diesem Baum - - view_builder = Node3D.new() - view_builder.set_script(load("res://src/viewport/map_view_builder.gd")) - world.add_child(view_builder) - - camera = Camera3D.new() - camera.set_script(load("res://src/viewport/orbit_camera.gd")) - camera.current = true - world.add_child(camera) - - interaction = Node3D.new() - interaction.set_script(load("res://src/editor/interaction.gd")) - world.add_child(interaction) - interaction.setup(self, camera, view_builder) - # Achsen-Gizmo (Karte t_e0120dc2) als KIND von interaction — Kinder - # bekommen _unhandled_input ZUERST, es fängt Pfeil-Klicks ab bevor - # interaction sie sieht. interaction.gd bleibt dadurch unverändert. - gizmo = GizmoScript.new() - gizmo.setup(self, camera, view_builder) - interaction.add_child(gizmo) - camera.set("wheel_filter", Callable(interaction, "wheel_blocked")) - # Freelook-Flug-Verdrahtung (Karte t_c46d31c2): Status-Meldungen der - # Kamera laufen ins Statusfeld. Karte t_2470de89: die rechte Maustaste - # gehört IMMER dem Flug — kein Filter mehr, die Werkzeuge fassen RMB - # nicht mehr an. - camera.set("status_cb", Callable(self, "_set_status")) - - # Terrain-Pinsel (Karte t_9aba04f1) — eigener Eingabe-Knoten im Weltraum. - terrain_tool = Node3D.new() - terrain_tool.set_script(load("res://src/editor/terrain_tool.gd")) - world.add_child(terrain_tool) - terrain_tool.setup(self, camera, view_builder, interaction) - - # Spawn-Zonen-Werkzeug (Karte t_c4162c5d) — ditto eigener Eingabe-Knoten. - spawn_tool = Node3D.new() - spawn_tool.set_script(load("res://src/editor/spawn_tool.gd")) - world.add_child(spawn_tool) - spawn_tool.setup(self, camera, view_builder, interaction) - - - # Test-Start-Werkzeug (T1b, Wiederanbindung 20.10.): Marker in der Karte, - # Klick setzt den Startpunkt. Lebt — wie die übrigen Werkzeuge — in main, - # gelesen wird es von test_start_tool.gd über main.test_start_point. - test_start_tool = Node3D.new() - test_start_tool.set_script(load("res://src/editor/playtest/test_start_tool.gd")) - world.add_child(test_start_tool) - test_start_tool.setup(self, camera, view_builder, interaction) - - # Werkzeugleiste oben links (Verschieben / Drehen & Kippen / Aktionen) - viewport_toolbar = preload("res://src/ui/viewport_toolbar.gd").new() - container.add_child(viewport_toolbar) - viewport_toolbar.setup(self) - - # Ablege-Fläche für Bibliotheks-Kacheln: Godot ruft can_drop/drop NICHT auf einem - # SubViewportContainer auf (Test-Befund 25.10.: Ziehen startete, Loslassen setzte - # nichts — echter Maus-Drag, tests/probe_drag_echt.gd). Eine durchsichtige Fläche - # darüber nimmt den Drop an; sie ist nur WÄHREND eines Ziehens aktiv (sonst - # bleibt die Maus für Kamera/Auswahl frei). - drop_overlay = Control.new() - drop_overlay.name = "AblegeFlaeche" - drop_overlay.set_anchors_preset(Control.PRESET_FULL_RECT) - drop_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE - drop_overlay.set_drag_forwarding(Callable(), _viewport_can_drop, _viewport_drop) - container.add_child(drop_overlay) - - # Bedien-Hinweis im Viewport (Overlay) - help_label = Label.new() - help_label.text = "Linksklick: auswählen · Rahmen: mehrere · R: drehen · Entf: löschen · H: Hilfe" - help_label.set_anchors_preset(Control.PRESET_BOTTOM_WIDE) - help_label.offset_left = UIScale.px(12) - help_label.offset_bottom = UIScale.px(-8) - help_label.offset_top = UIScale.px(-46) - # U7: Hinweis-Farbe über Theme (Editor/colors/muted) statt modulate. - help_label.add_theme_color_override("font_color", get_theme_color("muted", "Editor")) - # Karte t_297221b5: OHNE Umbruch würde die Mindestbreite des langen Texts - # bei Stufe „Groß“ die 3D-Ansicht breiter zwingen als das Fenster ist — - # die rechte Spalte rutschte aus dem Bildschirm. Mit Umbruch bleibt die - # Mindestbreite klein, der Hinweis legt sich bei Bedarf in mehr Zeilen. - help_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - # … und wenn der umgebrochene Text höher wird als der reservierte Streifen, - # wächst er nach OBEN (in die 3D-Ansicht) statt nach unten über die - # Statuszeile (grow-Richtung = das Godot-Mittel gegen Mindestgrößen-Überlauf - # bei Anker-Controls). - help_label.grow_vertical = Control.GROW_DIRECTION_BEGIN - container.add_child(help_label) - - # Rahmen-Ausziehen (Karte t_f6f29d86): halbtransparentes Rechteck über - # dem Viewport — mouse_filter IGNORE, stört keine Maus-Ereignisse. - rubber_overlay = Control.new() - rubber_overlay.set_anchors_preset(Control.PRESET_FULL_RECT) - rubber_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE - rubber_overlay.draw.connect(_draw_rubberband) - rubber_overlay.visible = false - container.add_child(rubber_overlay) - return container - - -## Rahmen-Rechteck aktualisieren (aus interaction.gd, Viewport-Koordinaten). -func _rubberband_update(start_pos: Vector2, cur_pos: Vector2) -> void: - rubber_rect = SelectionMath.rect_from(start_pos, cur_pos) - rubber_overlay.visible = true - rubber_overlay.queue_redraw() - - -## Rahmen-Overlay ausblenden (Release/Abbruch). -func _rubberband_clear() -> void: - rubber_rect = Rect2() - rubber_overlay.visible = false - rubber_overlay.queue_redraw() - - -func _draw_rubberband() -> void: - if rubber_rect.size.x <= 0.0 or rubber_rect.size.y <= 0.0: - return - # U7: Rubberband-Farben über das Theme (Editor/colors/rubber_fill/_line). - rubber_overlay.draw_rect(rubber_rect, get_theme_color("rubber_fill", "Editor"), true) - rubber_overlay.draw_rect(rubber_rect, get_theme_color("rubber_line", "Editor"), false, 2.0) -# ------------------------------------------------------------ Map-Aktionen -- - -func _start_with_new_map() -> void: - doc = SvmapDocument.create_new("Neue Map", 1024.0, "mittag") - current_path = "" - dirty = false - history.begin(doc) - _refresh_all() - _set_status("Willkommen! Links ein Objekt aus der Bibliothek anklicken, dann kannst du es in der Karte platzieren. Hilfe gibt's unten in dieser Leiste.") - - -func _on_menu_action(id: int) -> void: - match id: - 0: # Neue Map — bei ungespeicherten Änderungen erst NACHFRAGEN (Karte 3/3) - _request_lossy(func() -> void: new_dialog.popup_centered()) - 1: # Öffnen — ditto Dirty-Schutz - _request_lossy(func() -> void: open_dialog.popup_centered()) - 2: # Speichern - _save() - 3: # Speichern unter - save_dialog.popup_centered() - 4: # Beenden (Fensterlage vorher merken, Karte t_297221b5) - _quit_editor() - 5: # Karte testen - _on_test_run() - 6: # Kartengröße ändern (R3, t_c863b93b) - _open_resize_dialog() - 7: # Updates prüfen (Selbst-Update, t_d95f087a) - _on_update_check_menu() - 8: # Hand-Haltung der Waffen (Tool im Client-Projekt) - _on_hand_pose_tool() - - -# --------------------------------------------- UI-Größe + Fenster (t_297221b5) -- - -## Popup-Häkchen auf die aktuelle Stufe setzen. -func _sync_size_menu() -> void: - if size_menu == null or not is_instance_valid(size_menu): - return - size_menu.select(UIScale.step_index()) - - -## Neue Stufe gewählt: speichern, kompletten UI-Neuaufbau mit dem neuen -## Faktor, Statusmeldung. Wirkt SOFORT — kein Neustart nötig. -func _on_ui_size_selected(index: int) -> void: - if index < 0 or index >= UIScale.step_count(): - return - if index == UIScale.step_index(): - return - if _update_running: - _set_status("Während eines Updates kann die UI-Größe nicht umgestellt werden — gleich danach nochmal.", true) - _sync_size_menu() - return - UIScale.set_step_index(index) - var settings_war_offen := settings_dialog != null and settings_dialog.visible - _rebuild_ui_for_scale() - if settings_war_offen: - _open_settings.call_deferred() - _set_status("UI-Größe: %s — sofort wirksam und gespeichert (bleibt auch nach Neustart)." % UIScale.step_label(index)) - - -## Kompletter UI-Neuaufbau mit dem aktuellen UIScale-Faktor. Die Map (doc) -## bleibt als Objekt UNBERÜHRT (Undo-History bleibt gültig); nur die Controls -## werden neu gebaut und der Zustand (Werkzeug, Gitter, Höhenlinien, Auswahl) -## wiederhergestellt. -func _rebuild_ui_for_scale() -> void: - var prev_mode := tool_mode - for child in get_children(): - remove_child(child) - child.queue_free() - _build_ui() - _update_tool_label() - _clear_edit_state() - _refresh_all() - _refresh_history_buttons() - # Nutzer-Wahl Gitter/Höhenlinien wiederherstellen (Neubau setzt Defaults). - grid_btn.set_pressed_no_signal(_grid_on) - _sync_grid_to_builder() - contours_btn.set_pressed_no_signal(_contours_on) - _sync_contours_to_builder() - # Werkzeug-Modus wiederherstellen (Neubau startet bei „objects“). - if prev_mode != "objects": - tool_mode = "objects" - _set_tool_mode(prev_mode) - # Update-Banner-Zustand wiederherstellen (Start-Check kannte das Ergebnis). - if str(_update_result.get("status")) == "update_available": - _show_update_banner(str(_update_result.get("local", "")), str(_update_result.get("remote", ""))) - _sync_size_menu() - - -## Fenster beim Start: maximiert (Default, kein Vollbild-Zwang) oder die -## gemerkte Fensterlage wiederherstellen. Headless-Läufe (Tests) haben kein -## Fenster und springen raus. -func _apply_window_state() -> void: - if DisplayServer.get_name() == "headless": - return - var cfg := ConfigFile.new() - var maximiert := true - var groesse := Vector2i(1600, 900) - var position := Vector2i() - var hat_geom := false - if cfg.load(UIScale.cfg_path()) == OK: - maximiert = bool(cfg.get_value(UIScale.WIN_SECTION, "maximiert", true)) - var g: Variant = cfg.get_value(UIScale.WIN_SECTION, "groesse", null) - if g is Array and (g as Array).size() == 2: - groesse = Vector2i(int((g as Array)[0]), int((g as Array)[1])) - hat_geom = true - var p: Variant = cfg.get_value(UIScale.WIN_SECTION, "position", null) - if p is Array and (p as Array).size() == 2: - position = Vector2i(int((p as Array)[0]), int((p as Array)[1])) - if maximiert: - DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MAXIMIZED) - else: - DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) - if hat_geom: - DisplayServer.window_set_size(groesse) - DisplayServer.window_set_position(position) - - -## Fensterlage merken (beim Schließen): Modus + Größe + Position. -func _save_window_state() -> void: - if DisplayServer.get_name() == "headless": - return - var win := get_window() - var cfg := ConfigFile.new() - cfg.load(UIScale.cfg_path()) - cfg.set_value(UIScale.WIN_SECTION, "maximiert", win.mode == Window.MODE_MAXIMIZED) - cfg.set_value(UIScale.WIN_SECTION, "groesse", [win.size.x, win.size.y]) - cfg.set_value(UIScale.WIN_SECTION, "position", [win.position.x, win.position.y]) - cfg.save(UIScale.cfg_path()) - - -## Ein Ausgang für beide Beenden-Wege (Menü + Fenster-X). -func _quit_editor() -> void: - _save_window_state() - _save_dock_state() - get_tree().quit() - - -func _notification(what: int) -> void: - if drop_overlay != null and is_instance_valid(drop_overlay): - if what == NOTIFICATION_DRAG_BEGIN: - drop_overlay.mouse_filter = Control.MOUSE_FILTER_STOP - elif what == NOTIFICATION_DRAG_END: - drop_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE - if what == NOTIFICATION_WM_CLOSE_REQUEST: - _quit_editor() - - -# ------------------------------------------------- Kartengröße ändern (R3) -- - -## Dialog öffnen: aktueller Stand + Live-Preview (Verlust-Liste/Warnband) füllen. -func _open_resize_dialog() -> void: - if doc.is_empty(): - _set_status("Erst eine Map anlegen (Datei → Neue Map), dann kann die Größe geändert werden.", true) - return - resize_dialog.setup(doc) - resize_dialog.popup_centered() - - -## „Größe ändern“ bestätigt: resize_apply liefert ein FRISCHES Dict (R1/R2 — -## reine Funktion). Der Resize wird als EINE Undo-Einheit in die History -## gehängt: before = kompletter alter doc-Snapshot, after = kompletter neuer. -## Wichtig: doc bleibt dasselbe Dictionary-Objekt (History hält eine Referenz — -## history.begin(doc) nur bei Neu/Laden) — Blöcke werden IN-PLACE ersetzt, -## wie ActionHistory._restore_block es beim Undo macht. -func _on_resize_confirmed() -> void: - var new_x: float = resize_dialog.get_new_size_x() - var new_z: float = resize_dialog.get_new_size_z() - var drop: bool = resize_dialog.get_drop_outside() - var before := history.snapshot(doc.keys()) - var result := SvmapDocument.resize_apply(doc, new_x, new_z, drop) - if result.is_empty(): - _set_status("Kartengröße ändern fehlgeschlagen — die Map wurde nicht verändert.", true) - return - var old_terrain: Dictionary = doc.get("terrain", {}) - _replace_doc_in_place(result) - dirty = true - history.commit("Kartengröße %d × %d m" % [int(new_x), int(new_z)], - before, history.snapshot(doc.keys())) - _after_structure_change() - # Karte K1 (t_950fddaa): nach Resize die GANZE Karte passend einpassen - # (Kartenmitte aus bounds — frame_map ist weg). - var rb: Dictionary = doc.get("bounds", {}) - var rmn: Array = rb.get("min", []) - var rmx: Array = rb.get("max", []) - if rmn.size() == 3 and rmx.size() == 3: - camera.call("fit_to_bounds", - Vector3(rmn[0], rmn[1], rmn[2]), Vector3(rmx[0], rmx[1], rmx[2])) - var old_sx := float(old_terrain.get("size_x_m", 0.0)) - var old_sz := float(old_terrain.get("size_z_m", 0.0)) - var verb := "verkleinert" if (new_x < old_sx or new_z < old_sz) else "vergrößert" - _set_status("Karte auf %d × %d m %s — Strg+Z stellt den alten Zustand komplett her." % [ - int(new_x), int(new_z), verb]) - - -## Kompletten doc-Inhalt IN-PLACE durch ein frisches Ergebnis-Dict ersetzen -## (Identität von doc und seiner Arrays/Dicts bleibt erhalten — History, -## Tests und Ansichten behalten gültige Referenzen; Muster wie -## ActionHistory._restore_block, aber über ALLE Ober-Blöcke). -func _replace_doc_in_place(result: Dictionary) -> void: - for key in doc.keys(): - if not result.has(key): - doc.erase(key) - for key in result.keys(): - var source: Variant = result[key] - if source is Array: - var arr: Array = doc.get(key, []) - arr.clear() - arr.append_array((source as Array).duplicate(true)) - doc[key] = arr - elif source is Dictionary: - var dict: Dictionary = doc.get(key, {}) - dict.clear() - dict.merge((source as Dictionary).duplicate(true)) - doc[key] = dict - else: - doc[key] = source - - -# --------------------------------------------- Selbst-Update (t_d95f087a) ---- - -## Banner „🔄 Update verfügbar“ (unaufdringliche Leiste unter der Top-Bar) — -## nur sichtbar, wenn ein Check einen Update findet. Offline bleibt alles still. -func _update_banner_build(parent: Container) -> void: - update_banner = PanelContainer.new() - var style := StyleBoxFlat.new() - # U7: Banner-Farben über das Theme (Editor/colors/update_bg/_border). - style.bg_color = get_theme_color("update_bg", "Editor") - style.border_color = get_theme_color("update_border", "Editor") - style.set_border_width_all(2) - style.set_content_margin_all(UIScale.px(8)) - style.set_corner_radius_all(6) - update_banner.add_theme_stylebox_override("panel", style) - var h := HBoxContainer.new() - h.add_theme_constant_override("separation", UIScale.px(14)) - update_banner.add_child(h) - update_label = Label.new() - update_label.add_theme_font_size_override("font_size", UIScale.font_size()) - h.add_child(update_label) - var spacer := Control.new() - spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL - h.add_child(spacer) - update_btn = Button.new() - update_btn.text = "🔄 Jetzt updaten" - update_btn.custom_minimum_size = UIScale.v2(190, 40) - update_btn.tooltip_text = "Lädt die neue Version (git pull), importiert sie und startet den Editor neu. Bei ungespeicherten Änderungen fragt der Editor vorher." - update_btn.pressed.connect(_on_update_now) - h.add_child(update_btn) - update_banner.visible = false - parent.add_child(update_banner) - - -## Still Start-Check (nur Banner bei „Update verfügbar“ — offline: nichts). -func _startup_update_check() -> void: - _updater_check_async(false) - - -## Hand-Haltungs-Tool starten: eigenes Fenster aus dem Client-Projekt. Nach einem -## neuen Client-Stand erst importieren (im Hintergrund, kann dauern), sonst fehlen -## dem Tool neue Modelle. -func _on_hand_pose_tool() -> void: - if _hand_pose_thread != null: - _set_status("Hand-Haltungs-Tool wird schon vorbereitet…") - return - var cfg := TestRun.load_cfg() - var client := TestRun.find_client(ProjectSettings.globalize_path("res://"), cfg) - if client.is_empty(): - _set_status("Client-Ordner nicht gefunden: er muss neben dem Editor liegen (scopedvr-client) oder in den Einstellungen stehen.", true) - return - var godot := TestRun.find_godot(cfg) - if godot.is_empty(): - _set_status("Godot nicht gefunden: bitte in den Einstellungen eintragen.", true) - return - _set_status("Hand-Haltungs-Tool wird vorbereitet…") - _hand_pose_thread = Thread.new() - _hand_pose_thread.start(_hand_pose_prepare.bind(godot, client)) - - -func _hand_pose_prepare(godot: String, client: String) -> void: - var head := EditorUpdater.git_run(EditorUpdater.git_exe(TestRun.load_cfg()), client, PackedStringArray(["rev-parse", "HEAD"])) - var stand := str(head.get("output", "")).strip_edges() - var cfg := TestRun.load_cfg() - if stand.is_empty() or str(cfg.get_value("test", "hand_pose_import", "")) != stand: - var out: Array = [] - OS.execute(godot, TestRun.import_args(client), out, true) - _hand_pose_started.call_deferred(godot, client, stand) - - -func _hand_pose_started(godot: String, client: String, stand: String) -> void: - _hand_pose_thread.wait_to_finish() - _hand_pose_thread = null - var cfg := TestRun.load_cfg() - cfg.set_value("test", "hand_pose_import", stand) - cfg.save(TestRun.CFG_PATH) - var pid := OS.create_process(godot, TestRun.hand_pose_args(client)) - if pid <= 0: - _set_status("Hand-Haltungs-Tool ließ sich nicht starten.", true) - return - _set_status("Hand-Haltungs-Tool läuft in einem eigenen Fenster.") - - -## Datei-Menü „🔄 Updates prüfen“ (ID 7): gleicher Check mit Ergebnis-Meldung. -func _on_update_check_menu() -> void: - if _update_check_busy: - _set_status("Update-Check läuft schon…") - return - _set_status("Prüfe auf Updates…") - _updater_check_async(true) - - -func _updater_check_async(report: bool) -> void: - _update_check_busy = true - check_thread = Thread.new() - check_thread.start(_updater_check_thread.bind(report)) - - -func _updater_check_thread(report: bool) -> void: - var result := EditorUpdater.check_update( - EditorUpdater.git_exe(TestRun.load_cfg()), - ProjectSettings.globalize_path("res://")) - _update_result = result - call_deferred("_updater_check_done", result, report) - - -## Klartext-Ergebnis-Fenster für den manuellen Update-Check (Sly 20.10.: -## Statuszeile allein las sich wie „tut nichts“). Nur bei MANUELLEM Check -## (report=true), der Still-Start-Check bleibt still. -func _show_update_popup(text: String) -> void: - if update_dialog == null or not is_instance_valid(update_dialog): - return # UI wurde gerade neu aufgebaut (UI-Größe) — nichts anfassen - update_text.text = text - update_dialog.popup_centered() - - -func _updater_check_done(result: Dictionary, report: bool) -> void: - _update_check_busy = false - _join(check_thread) - check_thread = null - match str(result.get("status")): - "update_available": - _show_update_banner(str(result["local"]), str(result["remote"])) - if report: - _set_status("🔄 Update verfügbar: %s → %s — im Banner „Jetzt updaten“ klicken." % [ - EditorUpdater.short_sha(str(result["local"])), - EditorUpdater.short_sha(str(result["remote"]))]) - _show_update_popup("🔄 Update verfügbar: %s → %s.\n\nIm Banner oben „Jetzt updaten“ klicken — der Editor holt sich den Stand, baut ihn und startet neu." % [ - EditorUpdater.short_sha(str(result["local"])), - EditorUpdater.short_sha(str(result["remote"]))]) - "up_to_date": - if report: - _set_status("Du bist auf dem neusten Stand (%s)." % EditorUpdater.short_sha(str(result["local"]))) - _show_update_popup("Du bist auf dem neusten Stand (%s).\n\nAktuelle Version ist installiert — es gibt nichts zu tun." % EditorUpdater.short_sha(str(result["local"]))) - "unreachable": - if report: - _set_status("Update-Check nicht erreichbar (offline oder Tunnel weg) — später nochmal probieren.", true) - _show_update_popup("Update-Check nicht erreichbar.\n\nDer Server ist gerade nicht erreichbar (offline oder Tunnel weg) — später nochmal probieren.") - "auth_failed": - # Karte t_1457e935: Zugangsdaten fehlen → klarer Hinweis statt - # GUI-Login-Dialog (Askpass ist im Updater abgeschaltet). - if report: - _set_status(EditorUpdater.AUTH_ERROR_TEXT, true) - _show_update_popup(EditorUpdater.AUTH_ERROR_TEXT) - _: - if report: - _set_status("Update-Check fehlgeschlagen: %s" % str(result.get("error", "")), true) - _show_update_popup("Update-Check fehlgeschlagen:\n%s" % str(result.get("error", ""))) - - -func _show_update_banner(local_sha: String, remote_sha: String) -> void: - if update_banner == null or not is_instance_valid(update_banner): - return # UI wurde gerade neu aufgebaut (UI-Größe) — nichts anfassen - update_label.text = EditorUpdater.banner_text(local_sha, remote_sha) - update_banner.visible = true - - -## Thread sauber einsammeln (Ergebnis kam per call_deferred — der Thread ist -## längst fertig, join ist nur Ordnung). -func _join(thread: Thread) -> void: - if thread != null and thread.is_started(): - thread.wait_to_finish() - - -## Banner-Knopf „Jetzt updaten“: Dirty-Schutz wie Strg+O/Strg+N (derselbe -## deutsche Dialog — „Abbrechen“ bricht das Update ab), dann git pull + -## Import-Lauf + Neustart. Import-Fehler = Abbruch mit Meldung, KEIN Neustart -## (Lektion 17.10.: sonst sieht Sly einen Editor ohne Map-Ansicht). -func _on_update_now() -> void: - if _update_running: - _set_status("Ein Update läuft schon…") - return - _request_lossy(_start_update) - - -func _start_update() -> void: - _update_running = true - update_btn.disabled = true - _set_status("Update läuft — neue Version wird geladen (git pull)…") - update_thread = Thread.new() - update_thread.start(_updater_run_thread) - - -func _updater_run_thread() -> void: - var project_dir := ProjectSettings.globalize_path("res://") - var cfg := TestRun.load_cfg() - var pull := EditorUpdater.pull(EditorUpdater.git_exe(cfg), project_dir) - if not bool(pull["ok"]): - call_deferred("_update_finished", false, "Update abgebrochen — git pull fehlgeschlagen:", pull["errors"]) - return - # Karte t_f73a1cc5: Wenn der Pull eigene Dateien automatisch beiseite- - # gelegt hat, zeigt die Statuszeile den Klartext statt der technischen - # Import-Meldung (KEINE rohe Git-Zeile). - var info := str(pull.get("info", "")) - if info.is_empty(): - info = "Update geladen — Version wird importiert (Godot-Import-Lauf)…" - call_deferred("_set_status", info) - var godot := TestRun.find_godot(cfg) - if godot.is_empty(): - call_deferred("_update_finished", false, "Update abgebrochen — kein Godot-Programm für den Import-Lauf:", [ - "Der Editor läuft nicht über ein Godot-Binary und es ist kein godot_path gesetzt.", - "Trage in scopedvr_editor.cfg (Godot-App-Daten) ein:", - " [test]", - " godot_path=\"/pfad/zu/godot\"", - ]) - return - var imp := EditorUpdater.run_import(godot, project_dir) - if not bool(imp["ok"]): - call_deferred("_update_finished", false, "Update ABGEBROCHEN — der Import ist fehlgeschlagen, es wird NICHT neu gestartet:", imp["errors"]) - return - call_deferred("_update_finished", true, "", []) - - -func _update_finished(ok: bool, title: String, details: Array) -> void: - _update_running = false - if not is_instance_valid(update_btn) or not is_instance_valid(update_banner): - return # UI wurde zwischendurch neu aufgebaut (UI-Größe) — nichts anfassen - update_btn.disabled = false - _join(update_thread) - update_thread = null - if not ok: - update_banner.visible = true - _show_errors(title, details) - _set_status("Update fehlgeschlagen — der Editor bleibt unverändert (es ist nichts kaputt gemacht).", true) - return - var restart := EditorUpdater.resolve_restart(TestRun.load_cfg()) - var project_dir := ProjectSettings.globalize_path("res://") - var pid := -1 - if str(restart["mode"]) == "command": - var argv: PackedStringArray = restart["argv"] - pid = OS.create_process(str(argv[0]), argv.slice(1)) - else: - var godot := TestRun.find_godot(TestRun.load_cfg()) - if godot.is_empty(): - _show_errors("Update installiert — Neustart nicht möglich:", [ - "Der neue Stand ist geladen, aber das Godot-Programm für den Neustart ist unbekannt.", - "Editor einfach einmal selbst neu starten.", - ]) - _set_status("Update installiert — bitte den Editor einmal selbst neu starten.") - return - pid = OS.create_process(godot, EditorUpdater.self_restart_args(project_dir)) - if pid <= 0: - _show_errors("Update installiert — Neustart fehlgeschlagen:", [ - "Der neue Stand ist geladen, aber der Neustart wurde vom System abgelehnt.", - "Editor einfach einmal selbst neu starten.", - ]) - _set_status("Update installiert — bitte den Editor einmal selbst neu starten.") - return - _set_status("Update installiert (%s) — Editor startet neu…" % EditorUpdater.short_sha(str(_update_result.get("remote", "")))) - await get_tree().create_timer(1.0).timeout - get_tree().quit() - - -## „▶ Karte testen" (Karte t_1cdc1a72): Lauf-Modus IM Map-Builder selbst — -## erste Person, WASD + Maus, ohne Client-Ordner/VR/Server (Slys verbindlicher -## Wunsch: der Map-Builder ist überall installierbar und testet die Map ohne -## jegliche ScopedVR-Client-Abhängigkeit). Der ALTE Client-Start (Export nach -## Temp + eigener Client-Prozess, Karte t_b84af40f) bleibt als „alt" in -## src/editor/test_run.gd — der Rückbau kommt in einer späteren Karte. -func _on_test_run() -> void: - if doc.is_empty(): - _set_status("Erst eine Map anlegen (Datei → Neue Map), dann testen.", true) - return - _start_playtest() - - -## Lauf-Modus anwerfen: Werkzeuge einfrieren, Panels ausblenden, Maus einfangen, -## PlaytestMode in der 3D-Welt anlegen (Spieler am ersten Spawnpunkt der Map). -func _start_playtest() -> void: - if playtest != null: - return - # Editor-Zustand einfrieren (ohne Auswahl/Dokument/History anzufassen): - # laufende Ghost-Platzierung zurückrollen, Gizmo-Zug abbrechen (beides - # rollt ohne History-Eintrag zurück), Werkzeug-Modus auf Auswahl umschalten. - interaction.call("cancel_placement") - if gizmo != null and gizmo.has_method("cancel_drag_if_active"): - gizmo.call("cancel_drag_if_active") - _playtest_tool_mode = tool_mode - tool_mode = "objects" - _playtest_set_frozen(true) - Input.mouse_mode = Input.MOUSE_MODE_CAPTURED - playtest = load("res://src/editor/playtest/playtest_mode.gd").new() - playtest.ui_panels = [ui_top_bar, ui_left_panel, ui_right_panel, ui_status_bar] - # Trenner-Lagen JETZT sichern (Sly-Befund 20.10.: beim Verstecken der - # Panels klappen die Trenner zusammen — nach dem Playtest mussten die - # Seitenbereiche neu gezogen werden). Wiederherstellung im Exit-Handler. - _split_lagen_playtest.clear() - for sname in ["MainSplit", "BottomSplit"]: - var sp := _find_split(sname) - if sp != null: - _split_lagen_playtest[sname] = sp.split_offsets.duplicate() - playtest.ui_status = status_label - playtest.help_label = help_label - playtest.exit_requested.connect(_on_playtest_exit_requested) - world3d.add_child(playtest) - camera.current = false # Editor-Orbit abgeben — die Spiel-Kamera übernimmt - # Karte t_96e3c4ee: Fallback-Reihenfolge mit Klartext-Hinweis — gesetzter - # Test-Start → erster Team-Spawnpunkt → Kartenmitte. - var resolved: Dictionary = TestStart.resolve_start(doc, test_start_point) - playtest.enter(doc, view_builder, resolved["pos"]) - _set_status("▶ Testlauf läuft: WASD laufen, Shift rennen, Space springen, Maus umsehen — ESC zurück zum Editor. (%s)" % str(resolved["status"])) - - -## Editor-Input einfrieren/freigeben (Kamera-Flug, Werkzeuge, Gizmo). -## Nur auf die Werkzeug-Nodes — die Sicht (view_builder) bleibt 1:1 stehen. -func _playtest_set_frozen(on: bool) -> void: - for t in [camera, interaction, terrain_tool, spawn_tool, test_start_tool]: - if t == null: - continue - t.set_process_unhandled_input(not on) - t.set_process(not on) - if gizmo != null: - gizmo.set_process_unhandled_input(not on) - gizmo.set_process(not on) - gizmo.visible = not on - - -## ESC im Lauf-Modus: sauber zurück in den Editor — Werkzeuge + Panels wieder -## an, Maus frei, Kamera + Auswahl unverändert, Dokument + Undo-Stapel unverändert. -func _on_playtest_exit_requested() -> void: - if playtest == null: - return - var mode: Node = playtest - playtest = null - mode.exit() - mode.queue_free() - _playtest_set_frozen(false) - Input.mouse_mode = Input.MOUSE_MODE_VISIBLE - camera.current = true - tool_mode = _playtest_tool_mode - _update_tool_label() - _set_status("Testlauf beendet — zurück im Editor (Auswahl und Dokument unverändert).") - # Trenner-Lagen zurücksetzen (Sly-Befund 20.10.): das Re-Layout nach dem - # Wiedereinblenden der Panels setzt die Trenner auf Defaults — die gemerkten - # Lagen deshalb deferred UND im nächsten Frame zurücksetzen (das Layout - # muss die Panels erst neu vermessen haben, sonst clampen sie erneut). - _playtest_split_lagen_zurueck.call_deferred() - get_tree().process_frame.connect(_playtest_split_lagen_zurueck, CONNECT_ONE_SHOT) - - -## Gemerkte Playtest-Trenner-Lagen zurück auf die Splitter schreiben. -func _playtest_split_lagen_zurueck() -> void: - if _split_lagen_playtest.is_empty(): - return - for sname in _split_lagen_playtest.keys(): - var sp := _find_split(str(sname)) - if sp != null: - sp.split_offsets = _split_lagen_playtest[sname] - - -func _on_new_map_confirmed() -> void: - doc = SvmapDocument.create_new(new_dialog.get_map_name(), new_dialog.get_size_m(), new_dialog.get_weather(), new_dialog.get_game_mode()) - current_path = "" - dirty = false - history.begin(doc) - _clear_edit_state() - _refresh_all() - _test_start_reload() # Karte t_96e3c4ee: neue Map → kein Test-Start gesetzt - _set_status("Neue Map „%s“ erstellt (%.0f × %.0f m, Wetter: %s, Modus: %s). Wähle links ein Objekt, um zu bauen!" % [ - new_dialog.get_map_name(), new_dialog.get_size_m(), new_dialog.get_size_m(), new_dialog.get_weather(), - ModusKatalog.MODE_LABELS[new_dialog.get_game_mode()]]) - - -func _on_open_selected(path: String) -> void: - var result := SvmapIO.load_from_file(path) - var migration := {} - if not result["ok"] and SvmapIO.migrierbar(result["errors"]): - # Gelöschte Pack-Objekte (z. B. Pilze): ersetzen/überspringen statt Abbruch. - var migriert := SvmapIO.load_from_file_migriert(path) - if migriert["ok"]: - result = migriert - migration = migriert["migration"] - if not result["ok"]: - # t_9814f18f: NUR die Prüfsumme (V13) schlägt fehl, Kern (V3–V16) grün → - # Dialog „Trotzdem laden (Prüfsumme erneuern)“ statt hartem Abbruch. - if SvmapIO.checksum_only_failure(result["errors"]): - _resign_pending_path = path - resign_dialog.popup_centered() - return - _show_errors("Map konnte NICHT geladen werden:\n(Falls sie in einem anderen Programm geändert wurde, prüfe die Datei.)", result["errors"]) - _set_status("Laden fehlgeschlagen: %s — versuche eine .svmap-Datei aus dem Map-Editor oder vom Server." % path.get_file(), true) - return - doc = result["data"] - # Feines Material-Raster (Karte 24.10.): alte Karten beim Öffnen anheben — - # optisch gleich, ab jetzt ~1 m fein malbar. Die Datei ändert sich erst - # beim nächsten Speichern (deshalb kein dirty). - SvmapIO.upgrade_material_layer(doc.get("terrain", {})) - # Alte Bau-Sektion „gebaeude“ (vor 25.10.) → normale Bauteil-Objekte in einer Gruppe. - var uebernommen := BauOps.migriere_gebaeude(doc) - current_path = path - dirty = uebernommen > 0 or not migration.is_empty() - history.begin(doc) - _clear_edit_state() - _refresh_all() - _test_start_reload() # Karte t_96e3c4ee: Sidecar der geladenen Map lesen - var map_name := str(doc.get("info", {}).get("name", "?")) - if not migration.is_empty() and int(migration.get("gesamt", 0)) > 0: - _set_status("Map „%s“ geladen. Veraltete Objekte angepasst: %s. Bitte prüfen und speichern — vorher bleibt die Datei unverändert." % [ - map_name, SvmapMigration.zusammenfassung(migration, SvmapIO._manifest_or({}).get("objects", {}))]) - elif uebernommen > 0: - _set_status("Map „%s“ geladen. %d alte Bauteile wurden in das neue Bausystem übernommen (Gruppe „Gebäude“) — Wandhöhe ist jetzt 3 m, bitte kurz prüfen und speichern." % [map_name, uebernommen]) - else: - _set_status("Map „%s“ geladen (%d Objekte). Klicke ein Objekt in der Karte an, um es anzupassen." % [map_name, SvmapDocument.object_count(doc)]) - - -func _clear_edit_state() -> void: - if interaction != null: - interaction.call("clear_selection", true) - interaction.call("cancel_placement") - - -func _save() -> void: - if current_path.is_empty(): - save_dialog.popup_centered() - return - _save_to(current_path) - - -func _on_save_selected(path: String) -> void: - if not path.get_extension().is_empty() and path.get_extension() != "svmap": - path += ".svmap" - _save_to(path) - - -func _save_to(path: String) -> void: - # Felder stehen im Dokument (Live-Bindung) — vor dem Speichern noch einmal - # sicherstellen, dass Name/Autor nicht leer sind (verständliche Meldung statt V4-Kauderwelsch). - var name_v := str(doc.get("info", {}).get("name", "")).strip_edges() - if name_v.is_empty(): - _show_errors("Map konnte nicht gespeichert werden:", ["Die Map braucht einen Namen — trag ihn rechts unter „Map-Eigenschaften“ ein."]) - return - var result := SvmapIO.save_to_file(path, doc) - if not result["ok"]: - _show_errors("Map konnte nicht gespeichert werden (ungültige Map-Daten):", result["errors"]) - _set_status("Speichern fehlgeschlagen.", true) - return - current_path = path - dirty = false - _test_start_reload() # Karte t_96e3c4ee: Punkt wandert beim Speichern mit - _refresh_file_label() - _set_status("Map gespeichert: %s" % path) - _refresh_tree() - - -func _show_errors(title: String, errors: Array) -> void: - var lines := "" - for e in errors: - lines += "• %s\n" % str(e) - error_text.text = "%s\n%s" % [title, lines] - error_dialog.title = "Fehler" - error_dialog.popup_centered() - - -# ------------------------------------------- Karte 3/3: Globale Shortcuts --- - -## Verlust-Operation (Neue Map / Öffnen): bei ungespeicherten Änderungen erst -## NACHFRAGEN (deutscher Dialog), sonst direkt ausführen. Die wartende Aktion -## liegt in _pending_after_dirty und läuft bei „Verwerfen“ an. -func _request_lossy(next: Callable) -> void: - if ShortcutPolicy.needs_dirty_confirm(dirty): - _pending_after_dirty = next - dirty_dialog.popup_centered() - return - next.call() - - -## „Verwerfen“ im Dirty-Dialog: die wartende Aktion (Neu/Öffnen) jetzt ausführen. -func _on_dirty_confirmed() -> void: - var next := _pending_after_dirty - _pending_after_dirty = Callable() - if next.is_valid(): - next.call() - - -## Karte 3/3: Dürfen die globalen Tasten (F1–F5, H) gerade wirken? Pure Policy -## in ShortcutPolicy — hier nur die Fakten: Textfeld/SpinBox fokussiert? Ein -## Dialog/Popup offen? (Eigene Fenster des Editors; das Hilfe-Panel ist -## absichtlich KEIN Fenster und zählt nicht.) -func _tool_key_allowed() -> bool: - var focus := get_viewport().gui_get_focus_owner() - var text_focused: bool = focus != null \ - and (focus is LineEdit or focus is TextEdit or focus is SpinBox) - var dialog_open := false - for child in get_children(): - if child is Window and child.visible: - dialog_open = true - break - return ShortcutPolicy.tool_keys_allowed(text_focused, dialog_open) - - -## Kurzhilfe-Overlay umschalten; Statuszeile meldet den Zustand. -func _toggle_help_overlay() -> void: - help_overlay.visible = not help_overlay.visible - if help_overlay.visible: - _set_status("Kurzhilfe an — H oder Esc schließt das Overlay wieder.") - else: - _base_tool_status() - - -## Permanente Werkzeug-Anzeige (Karte 3/3): aktives Werkzeug + Flug-Hint — -## Sly sieht in der Statuszeile immer, wo er ist. -func _update_tool_label() -> void: - if tool_label == null: - return - var names := { - "objects": "Objekte (F2)", - "terrain": "Terrain (F1)", - "spawns": "Spawn-Zonen (F4)", - } - tool_label.text = "Werkzeug: %s" % str(names.get(tool_mode, tool_mode)) - - -## Symmetrie-Schalter (Karte t_f5935023, M1): Modus aus dem Toolbar-Menü übernehmen. -func _on_sym_mode_selected(index: int) -> void: - sym_mode = clampi(index, 0, SymmetryCore.MODE_LABELS.size() - 1) - _update_sym_ui() - if sym_mode == SymmetryCore.Mode.OFF: - _set_status("Symmetrie aus — die Karte wird nicht mehr automatisch gespiegelt.") - else: - _set_status("Symmetrie: %s — Änderungen an einer Seite werden auf die andere übertragen." % - SymmetryCore.mode_label(sym_mode)) - - -## Symmetrie-Status: Toolbar-Text + Haken + Statuszeilen-Label (M1 Fundament). -## Das tatsächliche Spiegeln von Änderungen kommt mit M2–M4. -func _update_sym_ui() -> void: - if sym_menu == null or sym_label == null: - return - var label := "Symmetrie: %s" % SymmetryCore.mode_label(sym_mode) - sym_label.text = label - sym_menu.select(sym_mode) - if sym_mod != null and sym_mod.has_method("refresh_mode"): - sym_mod.call("refresh_mode") - - -# --------------------------------------------------------------- History ---- - -func _do_undo() -> void: - if not history.can_undo(): - _set_status("Nichts zum Rückgängigmachen — die History ist schon am Anfang.") - return - var desc := history.undo() - _after_structure_change() - _set_status("Rückgängig gemacht: %s. Mit Strg+Y kannst du es wiederherstellen." % desc) - - -func _do_redo() -> void: - if not history.can_redo(): - _set_status("Nichts zum Wiederholen — schon am aktuellsten Stand.") - return - var desc := history.redo() - _after_structure_change() - _set_status("Wiederhergestellt: %s." % desc) - - -## F: Auswahl ins Bild zentrieren (Karte t_c46d31c2) — Kamera-Ziel auf den -## Auswahl-Mittelpunkt; im Flugmodus dreht sich nur die Blickrichtung. -func _focus_selection() -> void: - var indices: Array = interaction.selected_indices - if indices.is_empty(): - _set_status("Nichts ausgewählt — F zentriert die Auswahl im Bild. Klicke zuerst ein Objekt an (im Viewport oder im Baum).") - return - var center := SelectionMath.focus_center(view_builder.object_markers, indices) - camera.call("focus_on", center) - _set_status("%d Objekt(e) ins Bild zentriert — Strg+Klick/Strg+LMB markiert weitere dazu, Entf löscht die ganze Auswahl." % indices.size()) - - -## Karte t_2470de89: Der alte Rechtsklick-Filter (_fly_rmb_blocked) ist weg — -## RMB startet den Freelook-Flug in JEDEM Werkzeugzustand (absoluter Vorrang). - - -func _refresh_history_buttons() -> void: - undo_btn.disabled = not history.can_undo() - redo_btn.disabled = not history.can_redo() - undo_btn.tooltip_text = ("Rückgängig machen: %s (Strg+Z)" % history.undo_desc()) if history.can_undo() else "Nichts zum Rückgängigmachen" - redo_btn.tooltip_text = ("Wiederherstellen: %s (Strg+Y)" % history.redo_desc()) if history.can_redo() else "Nichts zum Wiederholen" - - -func _unhandled_key_input(event: InputEvent) -> void: - if not (event is InputEventKey) or not event.is_pressed() or event.is_echo(): - return - var key_evt := event as InputEventKey - var key := key_evt.keycode - # InputEventKey hat KEIN `command_pressed` (Godot-3-API-Relikt — crashete - # bei jeder Taste, GUI-Start-Befund 15.10.). Die Godot-4-Ersatz-API ist - # is_command_or_control_pressed(): Ctrl auf Linux/Windows, Cmd auf macOS. - var ctrl: bool = key_evt.is_command_or_control_pressed() - # Lauf-Modus (t_1cdc1a72): nur ESC behandeln — ALLE anderen Editor-Tasten - # (F1-F5, Undo/Redo, Werkzeuge) sind im Spiel eingefroren. - if playtest != null and playtest.active: - if key == KEY_ESCAPE: - playtest.handle_escape() - get_viewport().set_input_as_handled() - elif key == KEY_T: - # Karte t_96e3c4ee, „jederzeit": T im Testlauf = Test-Start auf den - # Punkt unterm Fadenkreuz setzen + SOFORT dorthin versetzen - # (Augenhöhe 1,70 m, Kollision geprüft). - var tp: Dictionary = playtest.call("teleport_crosshair") - if bool(tp.get("ok")): - _test_start_apply(float(tp.get("x")), float(tp.get("z")), str(tp.get("hinweis"))) - get_viewport().set_input_as_handled() - return - if (key == KEY_PAGEUP or key == KEY_PAGEDOWN) and not ctrl and interaction.placing \ - and BauKatalog.ist_bau(interaction.place_oid): - interaction.bau_geschoss_aendern(1 if key == KEY_PAGEUP else -1) - get_viewport().set_input_as_handled() - return - match key: - KEY_T: - # Karte t_96e3c4ee: T schaltet das Test-Start-Werkzeug um (Editor). - if not ctrl: - _set_tool_mode("teststart" if tool_mode != "teststart" else "objects") - get_viewport().set_input_as_handled() - KEY_Z: - if ctrl: - if event.shift_pressed: - _do_redo() - else: - _do_undo() - get_viewport().set_input_as_handled() - KEY_Y: - if ctrl: - _do_redo() - get_viewport().set_input_as_handled() - KEY_S: - if ctrl: - if event.shift_pressed: - # Strg+Umschalt+S (Karte 3/3): Speichern unter … - save_dialog.popup_centered() - else: - _save() - get_viewport().set_input_as_handled() - KEY_O: - if ctrl: - # Strg+O (Karte 3/3): Map öffnen — bei dirty erst NACHFRAGEN. - _request_lossy(func() -> void: open_dialog.popup_centered()) - get_viewport().set_input_as_handled() - KEY_N: - if ctrl: - # Strg+N (Karte 3/3): Neue Map — bei dirty erst NACHFRAGEN. - _request_lossy(func() -> void: new_dialog.popup_centered()) - get_viewport().set_input_as_handled() - KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5: - # Karte 3/3: Werkzeugwechsel + Test-Platzhalter. NUR wirken, wenn - # kein Textfeld tippt und kein Dialog offen ist (ShortcutPolicy). - if _tool_key_allowed(): - match key: - KEY_F1: - _set_tool_mode("terrain") - KEY_F2: - _set_tool_mode("objects") - KEY_F3: - _open_bauen_tab() - KEY_F4: - _set_tool_mode("spawns") - KEY_F5: - # ▶ Karte testen: der echte Freigabe-/Test-Flow existiert - # (Karte t_b84af40f) — F5 ruft ihn direkt auf. - _on_test_run() - get_viewport().set_input_as_handled() - KEY_H: - # Karte 3/3: Kurzhilfe-Overlay an/aus (Esc schließt ebenfalls). - if _tool_key_allowed(): - _toggle_help_overlay() - get_viewport().set_input_as_handled() - KEY_L: - # Karte t_89c0ec95: Höhenlinien FIXIEREN an/aus — unabhängig vom - # Werkzeug (wer die Linien dauerhaft will, fixiert sie hier). - # Ohne Modifier (kein Strg+L), gleiche Freigabe wie F1–F5/H: - # Tippen in Textfeldern und offene Dialoge gehen vor. - if not ctrl and _tool_key_allowed(): - _on_contours_toggled(not _contours_on) - get_viewport().set_input_as_handled() - KEY_G: - if ctrl: - # Gruppieren/Lösen (Karte t_f6f29d86) - if event.shift_pressed: - interaction.ungroup_selection() - else: - interaction.group_selection() - get_viewport().set_input_as_handled() - elif tool_mode == "objects" and not interaction.placing: - # G = Greifen (Karte t_55257792, Blender-Semantik): Auswahl - # hängt an der Maus, Linksklick setzt neu, Esc bricht ab. - interaction.grab_begin() - get_viewport().set_input_as_handled() - KEY_R: - var r_delta := -90.0 if event.shift_pressed else 90.0 - if ctrl and not event.alt_pressed: - # Strg+R / Strg+Umschalt+R: KIPPEN um X (±15°, Karte t_e166e656 - # — „nicht nur rotieren, sondern auch kippen“). Bauteile werden - # nie gekippt (fest ausgerichtet). - if BauKatalog.ist_bau(interaction.place_oid): - return - var t_delta: float = -interaction.TILT_STEP_DEG if event.shift_pressed else interaction.TILT_STEP_DEG - if interaction.placing: - interaction.place_tilt_x = fposmod(interaction.place_tilt_x + t_delta + 3600.0, 360.0) - interaction._ghost_rotation_anwenden() - else: - interaction.tilt_selected(true, t_delta) - get_viewport().set_input_as_handled() - elif event.alt_pressed and not ctrl: - # Alt+R / Alt+Umschalt+R: KIPPEN um Z (±15°, Karte t_e166e656). - if BauKatalog.ist_bau(interaction.place_oid): - return - var t_delta2: float = -interaction.TILT_STEP_DEG if event.shift_pressed else interaction.TILT_STEP_DEG - if interaction.placing: - interaction.place_tilt_z = fposmod(interaction.place_tilt_z + t_delta2 + 3600.0, 360.0) - interaction._ghost_rotation_anwenden() - else: - interaction.tilt_selected(false, t_delta2) - get_viewport().set_input_as_handled() - elif not ctrl and not event.alt_pressed: - # R = Vierteldrehung 90° (Karte t_55257792): Objekt-Auswahl UND Ghost - # drehen in 90°-Schritten (Umschalt+R = zurück). Feindrehen 15° - # bleibt am Mausrad (Bauteile: 90° pro Rad-Tick). - if interaction.placing: - interaction.place_rot_deg = wrapf(interaction.place_rot_deg + r_delta, 0.0, 360.0) - interaction._ghost_rotation_anwenden() - else: - interaction.rotate_selected(r_delta) - get_viewport().set_input_as_handled() - KEY_F: - if not ctrl: - if event.shift_pressed: - # Umschalt+F: Freelook-Flug dauerhaft an/aus (Karte t_c46d31c2). - camera.call("toggle_fly_lock") - get_viewport().set_input_as_handled() - else: - # F: Auswahl ins Bild zentrieren. - _focus_selection() - get_viewport().set_input_as_handled() - KEY_ESCAPE: - # Karte 3/3: Steht das Hilfe-Overlay offen, gehört Esc IHM (schließen) - # — VOR der normalen Esc-Prioritätskette. - if help_overlay.visible: - _toggle_help_overlay() - get_viewport().set_input_as_handled() - return - # Karte t_e0120dc2: Läuft gerade ein Gizmo-Zug (Achsen-Pfeil), gehört - # Esc IHM — exakt zurückrollen auf die Zug-Startposition (kein - # History-Eintrag), danach NICHT weiter in der Esc-Kette eintauchen. - if gizmo != null and gizmo.cancel_drag_if_active(): - get_viewport().set_input_as_handled() - return - # Esc-Priorität über pure Funktion (Karte t_c46d31c2, testbar): - # Werkzeug verlassen → Greifen zurückrollen → Ghost-Preview - # abbrechen → Auswahl aufheben (Greifen: Karte t_55257792). - var esc := ShortcutPolicy.esc_action(tool_mode, - interaction.placing, - interaction.selected_index != -1 or not interaction.selected_indices.is_empty(), - bool(interaction.get("_grabbing"))) - match esc: - "exit_terrain": - _set_tool_mode("objects") - _set_status("Terrain-Modus beendet — zurück zum Objekt-Werkzeug.") - "exit_spawns": - _set_tool_mode("objects") - _set_status("Spawn-Werkzeug beendet — zurück zum Objekt-Werkzeug.") - "exit_teststart": - # Der gesetzte Test-Start bleibt bestehen (nur Werkzeug aus). - _set_tool_mode("objects") - _set_status("Test-Start-Werkzeug beendet — zurück zum Objekt-Werkzeug.") - "cancel_grab": - interaction.grab_cancel() - "cancel_placement": - interaction.cancel_placement() - _set_status("Platzieren abgebrochen.") - "clear_selection": - interaction.clear_selection() - _set_status("Auswahl aufgehoben.") - if esc != "none": - get_viewport().set_input_as_handled() - KEY_DELETE: - if not ctrl: - if interaction.placing: - return - if tool_mode == "spawns": - spawn_tool.call("delete_selected") - elif tool_mode == "teststart": - # Karte t_96e3c4ee: Entf im Test-Start-Werkzeug = Punkt löschen. - _test_start_delete() - else: - interaction.delete_selected() - get_viewport().set_input_as_handled() - KEY_D: - if ctrl and tool_mode == "objects": - interaction.duplicate_selected() - get_viewport().set_input_as_handled() - KEY_PAGEUP: - if interaction.placing: - return - if ctrl: - # Strg+Bild↑ (Karte t_55257792): Auswahl auf den Boden. - if tool_mode == "objects" and interaction.selected_index >= 0: - interaction.snap_selection_to_floor() - get_viewport().set_input_as_handled() - elif not ctrl: - if tool_mode == "objects" and interaction.selected_index >= 0: - interaction.lift_selected(ObjectOps.LIFT_STEP_M) - get_viewport().set_input_as_handled() - KEY_PAGEDOWN: - if not ctrl and not interaction.placing: - if tool_mode == "objects" and interaction.selected_index >= 0: - interaction.lift_selected(-ObjectOps.LIFT_STEP_M) - get_viewport().set_input_as_handled() - KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT: - # Pfeiltasten (Karte t_55257792): Auswahl im 2-m-Raster verschieben, - # Richtung = Kamera-Ausrichtung nächste Weltachse (MoveMath). Eine - # Zelle pro Tastendruck; beim Platzieren bleibt der Ghost herrschend. - if interaction.placing: - return - var fwd := 0 - var side := 0 - match key: - KEY_UP: - fwd = 1 - KEY_DOWN: - fwd = -1 - KEY_RIGHT: - side = 1 - KEY_LEFT: - side = -1 - var delta := MoveMath.nudge_delta( - float(camera.call("view_yaw_deg")), fwd, side) - if tool_mode == "objects" and interaction.selected_index >= 0: - interaction.nudge_selection(delta) - get_viewport().set_input_as_handled() - KEY_BRACKETLEFT, KEY_BRACKETRIGHT: - # Terrain-Pinsel [ / ] (Karte t_55257792): Größe durch die 3 Presets - # zyklisch — nur im Terrain-Werkzeug (Ziffern-Freiheit, Punkt 6). - if tool_mode == "terrain": - _terrain_brush_size_step(key == KEY_BRACKETRIGHT) - get_viewport().set_input_as_handled() - KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6: - # Terrain-Pinsel-Modi 1–4 (Karte t_55257792): Heben/Senken/Glätten/ - # Malen — NUR im Terrain-Werkzeug (Konfliktfreiheit, Punkt 6; im - # Objekt-/Bauen-Modus bleiben die Ziffern unbenutzt). - if tool_mode == "terrain": - _terrain_brush_mode_key(int(key) - int(KEY_1)) - get_viewport().set_input_as_handled() - - -# --------------------------------------------------------- Bibliothek ------ -# U1: die Bibliothek wohnt im Assets-Bereich unten (assets_panel.gd); die -# Tools rufen weiter main.call("_highlight_library") — dünne Weiterleitung. - -func _on_library_pressed(oid: String) -> void: - assets_mod._on_library_pressed(oid) - - -## U1-Delegation: die Bibliotheks-Logik wohnt in assets_panel.gd — die alten -## main.-Aufrufe (Werkzeuge/Tests) bleiben als dünne Delegaten erhalten. -func _apply_library_filter(query: String) -> void: - assets_mod._apply_library_filter(query) - - -func _on_library_expand_all() -> void: - assets_mod._on_library_expand_all() - - -func _on_library_collapse_all() -> void: - assets_mod._on_library_collapse_all() - - -## Der Bibliothek-Button des aktiven Platzier-Objekts leuchtet auf. -func _highlight_library(oid: String) -> void: - assets_mod.highlight_library(oid) - if bauen_mod != null: - bauen_mod.sync_platzierung() - - -## Bauen-Tab: Gebäude-Info nachziehen (nach Setzen/Löschen/Undo). -func _refresh_bau_info() -> void: - if bauen_mod != null: - bauen_mod.refresh_info() - - -## „Neues Gebäude beginnen“: nächstes Teil startet eine neue Gruppe. -func _bau_neues_gebaeude() -> void: - interaction.call("neues_gebaeude") - _refresh_bau_info() - _set_status("Neues Gebäude: das nächste Bauteil beginnt eine neue Gruppe.") - - -## Alle Teile des Gebäudes wählen, zu dem die Auswahl gehört. -func _bau_gebaeude_waehlen() -> bool: - var sel: Array = interaction.selected_indices - if sel.is_empty(): - _set_status("Nichts markiert — klicke zuerst ein Bauteil des Gebäudes an.", true) - return false - var alle := {} - for i in sel: - for m in BauOps.gebaeude_von(doc, int(i)): - alle[int(m)] = true - var liste: Array = alle.keys() - liste.sort() - interaction.call("select_many", liste, true) - _set_status("Ganzes Gebäude gewählt (%d Teile) — Ziehen verschiebt, R dreht, Strg+D kopiert, Entf löscht." % liste.size()) - return true - - -func _bau_gebaeude_kopieren() -> void: - if _bau_gebaeude_waehlen(): - interaction.call("duplicate_selected") - - -func _bau_gebaeude_loeschen() -> void: - if _bau_gebaeude_waehlen(): - interaction.call("delete_selected") - - -func object_label(oid: String) -> String: - return LibraryBrowser.object_label(oid) - - -## Snap to Ground (1 Klick): ALLE Objekte auf die Terrain-Höhe setzen — -## EIN Undo-Eintrag für die ganze Aktion. -func _on_snap_to_ground() -> void: - var objects: Array = doc.get("objects", []) - if objects.is_empty(): - _set_status("Es gibt noch keine Objekte — platziere zuerst eins aus der Bibliothek links.") - return - var before: Dictionary = history.snapshot(["objects"]) - var changed := ObjectOps.snap_to_ground(doc) - if changed == 0: - _set_status("Alle %d Objekte stehen schon auf dem Boden — nichts zu tun." % objects.size()) - return - history.commit("Alle Objekte auf Boden gesetzt (%d)" % changed, - before, history.snapshot(["objects"])) - _after_structure_change() - _set_status("%d von %d Objekten auf den Boden gesetzt — Strg+Z nimmt es zurück." % [changed, objects.size()]) - - -func _on_grid_snap_changed(pressed: bool) -> void: - grid_snap = pressed - _set_status("Raster-Snap %s — Objekte landen jetzt %s." % [ - "AN" if pressed else "AUS", - "auf ganzen Metern (wie Bauklötze nebeneinander)" if pressed else "dort, wo du hinklickst"]) - - -# ---------------------------------------------------- Werkzeug-Status ------ - -## Standard-Hilfstext, wenn gerade nichts "Im Gange" ist. -func _base_tool_status() -> void: - _set_status("Bereit. Links ein Objekt anklicken zum Platzieren oder in der Karte ein Objekt auswählen.") - - -# ------------------------------------------------------ Terrain-Werkzeug ---- -# (Karte t_9aba04f1 — Höhenfeld heben/senken/glätten) - -## U1-Delegation: die Widgets wohnen in den Modulen (terrain_panel.gd, -## check_panel.gd); der Koordinator hält die Werkzeug-Logik und steuert die -## Modul-Widgets über deren öffentliche Felder. Methoden, die die Tools per -## main.call(...) erreichen (_on_terrain_stroke_committed, _sync_spawn_selection, -## _refresh_spawn_status, _mark_tree_selection…), bleiben unter denselben -## Namen hier (dünne Weiterleitung) — der Werkzeug-Vertrag ist unverändert. - -## Tab Terrain/Malen/Bauen angeklickt → das Werkzeug ist sofort aktiv, kein -## zweiter Klick auf einen Start-Knopf nötig (Befund 25.10.). -func _on_right_tab_changed(idx: int) -> void: - if terrain_mod == null or malen_mod == null or bauen_mod == null or doc.is_empty(): - return - var tab: Node = (ui_right_panel as TabContainer).get_child(idx) - if tab == terrain_mod: - if tool_mode == "terrain" and not terrain_mod.terrain_mode_paint.button_pressed: - return - if terrain_mod.terrain_mode_paint.button_pressed: - terrain_mod.terrain_mode_raise.button_pressed = true - _set_tool_mode("terrain") - elif tab == malen_mod: - if tool_mode == "terrain" and terrain_mod.terrain_mode_paint.button_pressed: - return - terrain_mod.terrain_mode_paint.button_pressed = true - _set_tool_mode("terrain") - elif tab == bauen_mod: - if tool_mode != "objects": - _set_tool_mode("objects") - # Das Verlassen des Terrain-Werkzeugs schaltet den Tab auf Malen/Terrain - # zurück — der Nutzer wollte aber Bauen. - (ui_right_panel as TabContainer).current_tab = bauen_mod.get_index() - - -func _on_terrain_btn_pressed() -> void: - if tool_mode != "terrain": - if terrain_mod.terrain_mode_paint.button_pressed: - terrain_mod.terrain_mode_raise.button_pressed = true - _set_tool_mode("terrain") - else: - _set_tool_mode("objects") - - -## Werkzeug-Modus wechseln: "objects" (Platzieren/Auswahl), "terrain" (Pinsel), -## "spawns" (Spawn-Zonen malen). -func _set_tool_mode(mode: String) -> void: - if mode == tool_mode: - _sync_terrain_button() - _sync_spawn_button() - _sync_test_start_button() - _update_tool_label() - return - if mode == "terrain": - _leave_spawn_mode() - _leave_test_start_mode() - _enter_terrain_mode() - elif mode == "spawns": - _leave_terrain_mode() - _leave_test_start_mode() - _enter_spawn_mode() - elif mode == "teststart": - _leave_terrain_mode() - _leave_spawn_mode() - _enter_test_start_mode() - else: - _leave_terrain_mode() - _leave_spawn_mode() - _leave_test_start_mode() - _enter_objects_mode() - _update_tool_label() - # Karte t_89c0ec95: Werkzeugwechsel = Höhenlinien-Umschalter — nach dem - # Terrain-Werkzeug (F1) wieder aus, bei Terrain-Eintritt wieder an - # (sofern nicht fixiert). Signal-getrieben an diesem EINEN Wechselpunkt, - # kein per-Frame-Poll. - _sync_contours_to_builder() - - -func _enter_terrain_mode() -> void: - interaction.call("cancel_placement") - interaction.call("clear_selection", true) - if not terrain_tool.call("activate"): - # Abgelehnt (z. B. Auflösungs-Limit) — Button zurück, Meldung steht. - _sync_terrain_button() - return - tool_mode = "terrain" - help_label.text = "Linksklick-Ziehen: formen bzw. malen · Strg+Klick: Gegenteil · [ ]: Pinselgröße · H: Hilfe" - terrain_tool.call("set_brush_mode", terrain_mod._selected_terrain_mode()) - terrain_mod.refresh_panels() - _set_status("Terrain-Modus an: LINKSKLICK-Ziehen formt den Boden, im Malen-Modus färbt er das Gelände (Steppe/Sand/Fels …). Regler rechts stellen Pinsel und Stärke ein.") - - -func _leave_terrain_mode() -> void: - if terrain_tool != null: - terrain_tool.call("deactivate") - _sync_terrain_button() - - -func _enter_spawn_mode() -> void: - interaction.call("cancel_placement") - interaction.call("clear_selection", true) - tool_mode = "spawns" - check_mod.spawn_panel.visible = true - help_label.text = "Linksklick: Zone setzen · Ziehen: verschieben · Entf: löschen · H: Hilfe" - check_mod.spawn_edit_btn.button_pressed = true - spawn_tool.call("activate") - spawn_tool.call("set_team", check_mod._selected_spawn_team()) - spawn_tool.call("set_radius", float(check_mod.spawn_radius_slider.value)) - _refresh_spawn_status() - _set_status("Spawn-Modus an: Klicke auf den Boden, um Zonen für %s zu malen. Die Kreis-Vorschau folgt der Maus." % SpawnOps.team_label(check_mod._selected_spawn_team())) - - -func _leave_spawn_mode() -> void: - if spawn_tool != null: - spawn_tool.call("deactivate") - if check_mod != null: - check_mod.spawn_panel.visible = false - _sync_spawn_button() - - -func _enter_objects_mode() -> void: - tool_mode = "objects" - help_label.text = "Linksklick: auswählen · Rahmen: mehrere · R: drehen · Entf: löschen · H: Hilfe" - _base_tool_status() - - -# ------------------------------------------------------------- Bauen ------ -# Bauteile sind normale Bibliotheks-Objekte (bau_*): das Bauen-Panel startet die -# Platzierung in interaction.gd (Ghost rastet über BuildSnap). Kein eigener -# Werkzeug-Modus mehr — Auswahl, Drehen, Kopieren, Löschen, Undo laufen über die -# Objekt-Werkzeuge. - - -## F3 / Menü: Bauen-Tab zeigen (wechselt aus Terrain-/Spawn-Modus zurück zu Objekten). -func _open_bauen_tab() -> void: - if tool_mode != "objects": - _set_tool_mode("objects") - if ui_right_panel is TabContainer and bauen_mod != null: - (ui_right_panel as TabContainer).current_tab = bauen_mod.get_index() - _set_status("Bauen: Bauteil rechts anklicken, dann in die Karte klicken — Wände rasten an Zellkanten, Böden in die Zellmitte, alles aufs 2-m-Raster.") - - -## Bauteil im Bauen-Tab angeklickt → Platzieren mit Snap starten. -func _on_bauteil_gewaehlt(oid: String) -> void: - if tool_mode != "objects": - _set_tool_mode("objects") - interaction.call("start_placement", oid) - - -func _sync_terrain_button() -> void: - terrain_mod.refresh_panels() - - -func _terrain_brush_size_step(up: bool) -> void: - terrain_mod.terrain_brush_size_step(up) - - -func _terrain_brush_mode_key(mode_idx: int) -> void: - var t: Control = terrain_mod - var btn: Button = null - match mode_idx: - 0: - btn = t.terrain_mode_raise - 1: - btn = t.terrain_mode_lower - 2: - btn = t.terrain_mode_smooth - 3: - btn = t.terrain_mode_paint - 4: - btn = t.terrain_mode_flatten - 5: - btn = t.terrain_mode_ramp - if btn == null or terrain_tool == null: - return - btn.set_pressed(true) - var labels := ["Heben", "Senken", "Glätten", "Malen", "Einebnen", "Rampe"] - var extra := "" - if mode_idx == 3: - var mats: Array = SvmapIO.MATERIAL_IDS - extra = " (Material: %s — mit der Palette rechts wechseln)" % str(mats[clampi(int(terrain_tool.get("paint_material")), 0, mats.size() - 1)]) - _set_status("Pinsel-Modus: %s%s — Linksklick-Ziehen formt/malt jetzt so (Ziffern 1–6 wechseln)." % [str(labels[mode_idx]), extra]) - - -## Ein Pinsel-Strich ist fertig (Doc + History schon aktualisiert vom Tool). -func _on_terrain_stroke_committed() -> void: - dirty = true - _refresh_file_label() - _refresh_stats() - _refresh_history_buttons() - view_builder.call("rebuild_terrain_from_doc", doc) - var desc: String = history.undo_desc() - _set_status("%s — Strg+Z macht den ganzen Strich rückgängig." % desc) - - -## Terrain-Modus nach Laden/Neu/Undo mit dem Doc synchron halten (Cache frisch, -## Auflösungs-Limit prüfen — sonst dezenter Rückschalter). -func _recheck_terrain_mode() -> void: - if tool_mode != "terrain" or terrain_tool == null: - return - if not terrain_tool.call("refresh_from_doc"): - terrain_tool.call("deactivate") - tool_mode = "objects" - _sync_terrain_button() - _update_tool_label() - # Karte t_89c0ec95: Dezenter Terrain-Rückschalter = ebenfalls ein - # Werkzeugwechsel — Linien wieder ausblenden (sofern nicht fixiert). - _sync_contours_to_builder() - help_label.text = "Linksklick: auswählen · Rahmen: mehrere · R: drehen · Entf: löschen · H: Hilfe" - _set_status("Terrain-Modus aus: Diese Map passt nicht ins Editor-MVP (Terrain-Auflösung über %d) — die Objekte bleiben normal bearbeitbar." % TerrainField.EDITOR_MAX_RESOLUTION, true) - - -# ---------------------------------------------------- Spawn-Zonen-Werkzeug --- - -func _on_spawn_btn_pressed() -> void: - check_mod._on_spawn_btn_pressed() - - -func _sync_spawn_button() -> void: - check_mod.spawn_edit_btn.button_pressed = tool_mode == "spawns" - - -## Panel-Zeile „Welche Zone ist angewählt?“ — WIRD vom Spawn-Tool gerufen. -func _sync_spawn_selection() -> void: - check_mod.sync_spawn_selection() - - -## LIVE-Validierung (Loader-Regeln) — immer sichtbar, nach JEDEM Struktur-Wechsel. -func _refresh_spawn_status() -> void: - check_mod.refresh_spawn_status() - - -## Map-Fertig-Check (Export-Button-Aktion): Klartext-Liste + Shake, wenn fehlt. -func _on_check_map() -> void: - var report := SpawnOps.ready_report(doc, manifest) - var lines := "" - for line in report["lines"]: - lines += "%s\n" % str(line["text"]) - var hint := str(line.get("hint", "")) - if hint != "": - lines += " → %s\n" % hint - check_text.text = lines - check_dialog.popup_centered() - if report["ok"]: - _set_status("✅ Karte prüfen: Alles bereit zum Export! Speichern erzeugt die signierte .svmap-Datei.") - else: - _shake_button(_registry_toolbar_button("karte_pruefen")) - _set_status("Map ist noch nicht bereit — siehe Warnungen im Map-Check-Fenster.", true) - - -## Kurzes Wackeln des Buttons — AUFMERKSAMKEIT statt Fehlerbombe (Chef-Grundsatz). -func _shake_button(btn: Control) -> void: - var orig: Vector2 = btn.position - var tween := create_tween() - for offset in [-9.0, 9.0, -6.0, 6.0, -3.0, 0.0]: - tween.tween_property(btn, "position", orig + Vector2(offset, 0.0), 0.045) - - -## Toolbar-Button per Registry-ID finden (karte_pruefen / karte_testen …). -func _registry_toolbar_button(id: String) -> Control: - var found: Array = toolbar_mod.find_children(id, "Button", true, false) - return found[0] if not found.is_empty() else null - - -## Baum-Rückrufe wohnen jetzt im Modul (src/ui/panels/scene_tree_panel.gd); -## die Tools rufen weiter main.call("_mark_tree_selection…") — dünne -## Weiterleitungen unten (Registry-Koordinator). -# ------------------------------------------------------- Struktur-Änderung -- - -## Nach undo/redo/platzieren/löschen: Struktur hat sich geändert → Ansicht neu. -func _after_structure_change() -> void: - dirty = true - _refresh_bau_info() - _refresh_file_label() - _refresh_stats() - _refresh_history_buttons() - _refresh_spawn_status() - if interaction != null: - interaction.call("clear_selection", true) - view_builder.call("rebuild", doc, manifest) - _sync_grid_to_builder() - # Karte t_89c0ec95: der Rebuild baut terrain_view NEU (Default-Pref „an“) - # — auch die Höhenlinien brauchen ihren Nacheich (Gitter-Muster). Sonst - # kehrte z. B. nach Strg+Z die Dauersicht zurück, die Sly störte. - _sync_contours_to_builder() - _refresh_tree() - if map_mod != null: - map_mod.refresh_values() # Undo/Redo: Wetter/Himmel-Auswahl nachziehen - _recheck_terrain_mode() - if interaction != null: - interaction.call("refresh_terrain_cache") # t_4092e3a0: Objekt-Cursor trifft das Gelände - if tool_mode == "spawns" and spawn_tool != null: - spawn_tool.call("refresh_from_doc") - -# --------------------------------------------------------------- Anzeige --- - -func _refresh_all() -> void: - _loading_ui_values = true - map_mod.refresh_values() - _loading_ui_values = false - - _refresh_tree() - _refresh_stats() - _refresh_file_label() - _refresh_history_buttons() - _refresh_viewport() - _refresh_spawn_status() - _recheck_terrain_mode() - - -func _refresh_viewport() -> void: - view_builder.call("rebuild", doc, manifest) - _sync_grid_to_builder() - _sync_contours_to_builder() - # Karte K1b (t_eca890c5): Laden/Neu = Ansicht auf den Karten-INHALT - # (Objekte + Bauteile + Spawnpunkte; Terrain zählt nicht) — ohne Inhalt - # wie bisher die ganze Karte. Pos1 (Home) bleibt ganze Karte. - var fb: Dictionary = doc.get("bounds", {}) - var fmn: Array = fb.get("min", []) - var fmx: Array = fb.get("max", []) - if fmn.size() == 3 and fmx.size() == 3: - camera.call("fit_to_document", doc, - Vector3(fmn[0], fmn[1], fmn[2]), Vector3(fmx[0], fmx[1], fmx[2])) - - -# --- Maßstabsgitter (Karte t_7ac70014) ------------------------------------- - -func _on_grid_toggled(pressed: bool) -> void: - _grid_on = pressed - _sync_grid_to_builder() - - -## Nach jedem Viewport-Rebuild: Nutzer-Wahl (bzw. Boden-Referenz ohne Terrain- -## Block) wieder anwenden — der Rebuild setzt das Gitter auf seinen Default. -func _sync_grid_to_builder() -> void: - if view_builder == null: - return - var no_terrain: bool = doc.get("terrain", {}).is_empty() - view_builder.call("set_grid_visible", _grid_on or no_terrain) - if grid_btn != null and grid_btn.button_pressed != _grid_on: - grid_btn.set_pressed_no_signal(_grid_on) - - -# --- Höhenlinien (Karte t_3ebe4086, Werkzeug-Kopplung t_89c0ec95) ------------ - -## Effektive Höhenlinien-Sichtbarkeit: FIX-Anforderung des Nutzers (L/Button) -## ODER das Terrain-Werkzeug (F1) ist aktiv. Bewusst KEIN _process-Poll — -## der Hook hängt am Werkzeug-Wechselpunkt (_set_tool_mode) und am Button/L. -func _contours_effective() -> bool: - return _contours_on or tool_mode == "terrain" - - -func _on_contours_toggled(pressed: bool) -> void: - _contours_on = pressed - _sync_contours_to_builder() - if status_label != null: - _set_status("Höhenlinien %s — %s" % [ - "FIXIERT AN" if _contours_on else "Fix aus", - "jetzt in jedem Werkzeug sichtbar (L oder Button schaltet zurück)." - if _contours_on else - "sichtbar nur noch im Terrain-Werkzeug (F1). L fixiert sie wieder."]) - - -## Nach jedem Viewport-Rebuild und nach JEDEM Werkzeug-Wechsel: die effektive -## Wahl anwenden — der Rebuild baut das Terrain-Mesh (und damit dessen -## Shader-Uniform) neu, der Werkzeugwechsel blendet die Linien ein/aus. -func _sync_contours_to_builder() -> void: - if view_builder == null: - return - var terrain_view = view_builder.get("terrain_view") - if terrain_view != null and is_instance_valid(terrain_view): - terrain_view.call("set_contours", _contours_effective()) - if contours_btn != null and contours_btn.button_pressed != _contours_on: - contours_btn.set_pressed_no_signal(_contours_on) - - -# --- Baum / Auswahl-Sync (U1: Module, dünne Weiterleitung) ------------------- - -func _refresh_tree() -> void: - tree_mod.refresh_tree() - - -## Baum-Klicks kommen im Modul an; die Viewport-Seite (interaction.gd) ruft -## weiter main.call("_mark_tree_selection…") — hier weiterleiten. -func _mark_tree_selection(idx: int) -> void: - tree_mod.mark_tree_selection(idx) - - -func _mark_tree_selection_multi(indices: Array) -> void: - tree_mod.mark_tree_selection_multi(indices) - - -## Rechte Panel-Sektion synchronisieren (wird von interaction.gd gerufen). -func _sync_selection_panel() -> void: - selection_mod.sync_selection() - - -## Hilfs-Meldung zur frischen Auswahl (wird von interaction.gd gerufen). -func _selection_status(idx: int) -> void: - selection_mod.selection_status(idx) - - -func _refresh_stats() -> void: - var count := SvmapDocument.object_count(doc) - var poly := SvmapDocument.poly_usage(doc, manifest) - var budget := int(SvmapIO.MAX_TOTAL_POLY) - var poly_pct := 100.0 * poly / budget - stats_objects.text = "%d Objekte · Poly %.0f %%" % [count, poly_pct] - stats_objects.tooltip_text = "Objekte: %d / 5000\nPoly-Budget: %s / %s (%.0f %%)\nBauteile: %d" % [ - count, _fmt_int(int(poly)), _fmt_int(budget), poly_pct, BauOps.teile_zahl(doc)] - # Nur bei knappem Budget auffällig färben (sonst ruhiger Nebentext). - stats_objects.add_theme_color_override("font_color", get_theme_color( - "warning" if poly_pct >= 90.0 or count >= 4500 else "field", "Editor")) - # GLB-Fehlende Objekte (Karte t_9b50b231): Platzhalter laufen, aber Sly soll - # sehen, WELCHE echten Modelle im Mesh-Lager nachgelegt werden müssen. - if view_builder != null and not (view_builder.get("fehlende_glbs") as Array).is_empty(): - var fehlend: Array = view_builder.get("fehlende_glbs") - var nennung := ", ".join(fehlend.slice(0, 3)) - if fehlend.size() > 3: - nennung += " … (+%d weitere)" % (fehlend.size() - 3) - stats_objects.text += " · ⚠ GLB fehlt: %s" % nennung - # Terrain-Anteil am Quest-3-Budget (res 513 = 524.288 Dreiecke, map_format.md §4) - var tris := 0 - var res := 0 - if view_builder != null and view_builder.get("terrain_view") != null: - tris = int(view_builder.terrain_view.call("triangle_count")) - res = int(view_builder.terrain_view.call("resolution")) - var quest_budget := 524288 - var pct := 100.0 * float(tris) / float(quest_budget) - var fps := Engine.get_frames_per_second() - stats_terrain.text = "Terrain %s² · %d FPS" % [str(res) if res > 0 else "—", fps] - stats_terrain.tooltip_text = "Terrain: %s² Grid, %s Dreiecke (%.0f %% Quest-Budget)" % [ - str(res) if res > 0 else "—", _fmt_int(tris), pct] - - -func _refresh_file_label() -> void: - var map_name := str(doc.get("info", {}).get("name", "Ohne Namen")) - if current_path.is_empty(): - file_label.text = "„%s“ (noch nicht gespeichert)%s" % [map_name, " •" if dirty else ""] - else: - file_label.text = "„%s“ — %s%s" % [map_name, current_path.get_file(), " •" if dirty else ""] - # Karte t_297221b5: bei egalisiertem Label (große Stufe, schmales Fenster) - # steht der volle Name im Tooltip. - file_label.tooltip_text = file_label.text - # U7 (Karte t_2336c58e): ungespeicherte Änderungen auch im FENSTERTITEL — - # so sieht man sie selbst dann, wenn die Datei-Leiste egalisiert ist. - get_window().title = "%s — %s%s" % [APP_TITLE, map_name, - " (ungespeichert)" if dirty else ""] - - -func _set_status(text: String, is_error := false) -> void: - if status_label == null or not is_instance_valid(status_label): - return # UI wurde gerade neu aufgebaut (UI-Größe) — nichts anfassen - status_label.text = text - # U7: Statusfarben über das Theme (Editor/colors/status_error/_ok). - status_label.add_theme_color_override("font_color", - get_theme_color("status_error" if is_error else "status_ok", "Editor")) - - -func _fmt_int(value: int) -> String: - var s := str(value) - var out := "" - while s.length() > 3: - out = "." + s.substr(s.length() - 3) + out - s = s.substr(0, s.length() - 3) - return s + out - - -# ------------------------------------------------------- U1 Dock-Zustand ---- - -## Splitter-Lagen (Assets-Höhe) aus der Config lesen — NACH _build_ui. -func _load_dock_state() -> void: - var cfg := ConfigFile.new() - if cfg.load(UIScale.cfg_path()) == OK: - var l: Variant = cfg.get_value(UIScale.WIN_SECTION, "dock_links", null) - if l is float or l is int: - _dock_offsets["links"] = float(l) - var r: Variant = cfg.get_value(UIScale.WIN_SECTION, "dock_rechts", null) - if r is float or r is int: - _dock_offsets["rechts"] = float(r) - var u: Variant = cfg.get_value(UIScale.WIN_SECTION, "dock_unten", null) - if u is float or u is int: - _dock_offsets["unten"] = float(u) - _apply_dock_state() - - -## Gemerkte Lagen anwenden — deferred, weil das Layout erst nach dem ersten -## Layout-Durchlauf vermessene Größen hat. -func _apply_dock_state() -> void: - if DisplayServer.get_name() == "headless": - return - _apply_dock_state_deferred.call_deferred() - - -func _apply_dock_state_deferred() -> void: - if _dock_offsets.is_empty(): - return - var main_split := _find_split("MainSplit") - if main_split != null and _dock_offsets.has("links"): - main_split.split_offset = UIScale.f(float(_dock_offsets["links"])) - var bottom := _find_split("BottomSplit") - if bottom != null and _dock_offsets.has("unten"): - bottom.split_offset = -UIScale.f(float(_dock_offsets["unten"])) - - -func _find_split(sname: String) -> SplitContainer: - var found := find_children(sname, "SplitContainer", true, false) - return found[0] if not found.is_empty() else null - - -## Splitter-Lagen merken (beim Schließen, neben der Fensterlage). -func _save_dock_state() -> void: - if DisplayServer.get_name() == "headless": - return - var main_split := _find_split("MainSplit") - var bottom := _find_split("BottomSplit") - var cfg := ConfigFile.new() - cfg.load(UIScale.cfg_path()) - if main_split != null: - cfg.set_value(UIScale.WIN_SECTION, "dock_links", main_split.split_offset) - if bottom != null: - cfg.set_value(UIScale.WIN_SECTION, "dock_unten", float(-bottom.split_offset)) - cfg.save(UIScale.cfg_path()) - - -# ---------------------------------------------------- Screenshot-Demo ------- - -## Desktop-Smoke-Hilfe: `godot ... -- --ghost-demo [x z objekt-id]` parkt die -## Platzier-Vorschau sichtbar in der Map und zoomt die Kamera heran, damit ein -## Screenshot die Vorschau zeigen kann (nur für Smoke-Tests). -func _maybe_start_demo_mode() -> void: - var args := OS.get_cmdline_user_args() - if args.has("--terrain-demo"): - _start_terrain_demo(args) - return - if args.has("--library-demo"): - _start_library_demo(args) - return - if args.has("--spawns-demo"): - _start_spawns_demo(args) - return - if args.has("--groups-demo"): - _start_groups_demo(args) - return - if args.has("--bauen-demo"): - _start_bauen_demo(args) - return - if args.has("--ui-demo"): - _start_ui_demo(args) - return - if not args.has("--ghost-demo"): - return - var oid := "box_001" - var x := 0.0 - var z := 0.0 - for i in args.size(): - if args[i] == "--ghost-demo": - if i + 1 < args.size(): - x = float(args[i + 1]) - if i + 2 < args.size(): - z = float(args[i + 2]) - if i + 3 < args.size(): - oid = args[i + 3] - var pos := Vector3(x, SvmapDocument.terrain_height_at(doc, x, z), z) - interaction.demo_park_ghost(pos, oid) - # Demo-Aufbau: zwei Objekte setzen und eins orange auswählen — zeigt - # Ghost-Preview UND Auswahl-Markierung in einem Smoke-Screenshot. - if args.has("--ghost-demo-select"): - var before: Dictionary = history.snapshot(["objects"]) - (doc["objects"] as Array).append({"id": "water_tower_004", "pos": [6.0, 0.0, 0.0], "scale": 1.0, "rot_y_deg": 0.0}) - (doc["objects"] as Array).append({"id": "box_001", "pos": [0.0, 0.0, 0.0], "scale": 1.0, "rot_y_deg": 0.0}) - history.commit("Demo: Objekte gesetzt", before, history.snapshot(["objects"])) - interaction.call("clear_selection", true) - _refresh_all() - interaction.select_object(1, true) - else: - _refresh_history_buttons() - # Kamera nah heran, damit die Vorschau im Screenshot gut sichtbar ist. - camera.target = pos + Vector3(0.0, 0.6, 0.0) - camera.distance = 14.0 - camera.pitch_deg = 32.0 - camera.yaw_deg = 40.0 - camera.call("_apply") - - -# ----------------------------------------------------- UI-Größen-Demo-Screens -- - -## `godot ... -- --ui-demo [ordner] [--ui-demo-res BxH] [--ui-demo-quit]` -## (Karte t_297221b5): fährt ALLE UI-Größen-Stufen programmatisch durch — -## pro Stufe kompletter UI-Neuaufbau (derselbe Pfad wie der Menü-Klick) und -## ein Fenster-Screenshot. Beweist: umschaltbar im Lauf + nichts abgeschnitten. -func _start_ui_demo(args: PackedStringArray) -> void: - var out_dir := "/tmp/scopedvr_ui" - var idx := args.find("--ui-demo") - if idx >= 0 and idx + 1 < args.size() and not args[idx + 1].begins_with("--"): - out_dir = args[idx + 1] - DirAccess.make_dir_recursive_absolute(out_dir) - var res_idx := args.find("--ui-demo-res") - if res_idx >= 0 and res_idx + 1 < args.size(): - var parts := str(args[res_idx + 1]).split("x") - if parts.size() == 2: - # Fenstergröße NICHT zu früh setzen — direkt bei _ready wird der - # Wert von der Projekt-Einstellung überschrieben (xvfb-Befund); - # erst nach dem ersten Frame ist der Resize stabil. - await get_tree().process_frame - DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) - DisplayServer.window_set_size(Vector2i(int(parts[0]), int(parts[1]))) - get_window().size = Vector2i(int(parts[0]), int(parts[1])) # root-Window setzt durch (xvfb-Befund) - for i in UIScale.step_count(): - UIScale.set_step_index(i) - _rebuild_ui_for_scale() - await get_tree().process_frame - await get_tree().process_frame - _set_status("UI-Größe: %s (%.2f-fach) — Theme-Schrift %d px, Beweis-Screenshot." % [ - UIScale.step_label(i), UIScale.factor(), UIScale.font_size()]) - await _demo_shot(out_dir + "/ui_%s.png" % UIScale.step_key(i)) - print("UI_DEMO: Stufe %s Faktor %.2f Schrift %d" % [UIScale.step_key(i), UIScale.factor(), UIScale.font_size()]) - print("UI_DEMO_OK: %d Stufen, PNGs in %s" % [UIScale.step_count(), out_dir]) - if args.has("--ui-demo-quit"): - get_tree().quit() # Batch-Smoke (xvfb): automatisch beenden nach den Shots - - -# ------------------------------------------------ Terrain-Demo-Screenshots -- - -## `godot ... -- --terrain-demo [ordner]` — Desktop-Smoke (Karte t_9aba04f1): -## fährt die Terrain-Szenarien programmatisch durch und speichert PNGs: -## Hügel heben, Senke senken, glätten, Undo-Roundtrip. Die App bleibt offen -## (Sly sieht das Ergebnis live auf dem Desktop). -func _start_terrain_demo(args: PackedStringArray) -> void: - var out_dir := "/tmp/scopedvr_terrain" - var idx := args.find("--terrain-demo") - if idx >= 0 and idx + 1 < args.size() and not args[idx + 1].begins_with("--"): - out_dir = args[idx + 1] - DirAccess.make_dir_recursive_absolute(out_dir) - - _set_tool_mode("terrain") - terrain_mod.terrain_radius_slider.value = 45.0 - terrain_mod.terrain_strength_slider.value = 10.0 - terrain_mod.terrain_mode_raise.button_pressed = true - - # 1) Hügel heben — Pinsel-Ring bleibt als visueller Beweis im Bild. - terrain_tool.call("demo_stroke", -80.0, -60.0, TerrainField.Mode.RAISE, 1.4) - terrain_tool.call("demo_park_brush", -80.0, -60.0) - _demo_camera(Vector3(-80.0, 12.0, -60.0), 150.0, 32.0, 40.0) - _set_status("Demo 1/5: Hügel GEHOBEN (Radius 45 m, Stärke 10 m/s) — der grüne Ring ist der Pinsel.") - await _demo_shot(out_dir + "/terrain_raise.png") - - # 2) Senke senken (roter Ring). - terrain_mod.terrain_mode_lower.button_pressed = true - terrain_tool.call("demo_stroke", 90.0, 50.0, TerrainField.Mode.LOWER, 1.2) - terrain_tool.call("demo_park_brush", 90.0, 50.0) - _demo_camera(Vector3(90.0, 2.0, 50.0), 150.0, 32.0, -50.0) - _set_status("Demo 2/5: Senke GESSENKT (Strg+Linksklick senkt, ohne umzuschalten).") - await _demo_shot(out_dir + "/terrain_lower.png") - - # 3) Hügelkuppe glätten (blauer Ring). - terrain_mod.terrain_mode_smooth.button_pressed = true - terrain_tool.call("demo_stroke", -70.0, -50.0, TerrainField.Mode.SMOOTH, 0.9) - terrain_tool.call("demo_park_brush", -70.0, -50.0) - _demo_camera(Vector3(-70.0, 10.0, -50.0), 130.0, 35.0, 20.0) - _set_status("Demo 3/5: Kuppe GLÄTTET — rau wird weich, ohne die Form zu zerstören.") - await _demo_shot(out_dir + "/terrain_smooth.png") - - # 4) Undo-Roundtrip: kleiner Strich → Undo → Boden wieder flach. - terrain_mod.terrain_mode_raise.button_pressed = true - terrain_mod.terrain_radius_slider.value = 30.0 - terrain_tool.call("demo_stroke", 0.0, 150.0, TerrainField.Mode.RAISE, 0.9) - terrain_tool.call("demo_park_brush", 0.0, 150.0) - _demo_camera(Vector3(0.0, 8.0, 150.0), 120.0, 35.0, 0.0) - _set_status("Demo 4/5: Test-Hügel für den Undo-Vergleich geformt.") - await _demo_shot(out_dir + "/terrain_before_undo.png") - _do_undo() - _set_status("Demo 5/5: Strg+Z — der GANZE Strich ist zurück, der Boden ist wieder flach.") - await _demo_shot(out_dir + "/terrain_after_undo.png") - - print("TERRAIN_DEMO_OK: 5 Screenshots in %s" % out_dir) - - -func _demo_camera(target: Vector3, dist: float, pitch: float, yaw: float) -> void: - camera.target = target - camera.distance = dist - camera.pitch_deg = pitch - camera.yaw_deg = yaw - camera.call("_apply") - - -func _demo_shot(path: String) -> void: - for i in 5: - await get_tree().process_frame - await RenderingServer.frame_post_draw - var img := get_viewport().get_texture().get_image() - img.save_png(path) - print("DEMO_SHOT: %s (%d×%d)" % [path, img.get_width(), img.get_height()]) - var tv = view_builder.get("terrain_view") - if tv != null and is_instance_valid(tv): - var mi = tv.get("_mi") - if mi != null and is_instance_valid(mi) and mi.mesh != null: - var aabb: AABB = mi.mesh.get_aabb() - print("DEMO_AABB: pos=%s size=%s tris=%d" % [aabb.position, aabb.size, tv.triangle_count()]) - print("DEMO_CAM: cam=%s target=%s" % [camera.global_position, camera.target]) - - -## `godot ... -- --library-demo [ordner]` — Desktop-Smoke (Karte t_3a998ae4): -## Gruppen-Bibliothek + platzierte Objekte + Snap-to-Ground programmatisch -## durchspielen, PNGs speichern. Die App bleibt offen. -func _start_library_demo(args: PackedStringArray) -> void: - var out_dir := "/tmp/scopedvr_library" - var idx := args.find("--library-demo") - if idx >= 0 and idx + 1 < args.size() and not args[idx + 1].begins_with("--"): - out_dir = args[idx + 1] - DirAccess.make_dir_recursive_absolute(out_dir) - - # 1) Bibliothek-Browser: Gruppen sichtbar, Ghost-Preview aktiv. - _set_status("Demo 1/3: Bibliothek in Gruppen — ein Objekt anklicken setzt eine Vorschau in die Karte.") - interaction.demo_park_ghost(Vector3(10.0, SvmapDocument.terrain_height_at(doc, 10.0, 6.0), 6.0), "water_tower_004") - _demo_camera(Vector3(0.0, 2.0, 0.0), 90.0, 35.0, 40.0) - await _demo_shot(out_dir + "/library_browser.png") - - # 2) Objekte platziert (versch. Gruppen), eins orange ausgewählt. - var before: Dictionary = history.snapshot(["objects"]) - (doc["objects"] as Array).append({"id": "water_tower_004", "pos": [10.0, 0.0, 6.0], "scale": 1.0, "rot_y_deg": 30.0}) - (doc["objects"] as Array).append({"id": "box_001", "pos": [-8.0, 0.0, -4.0], "scale": 1.0, "rot_y_deg": 0.0}) - (doc["objects"] as Array).append({"id": "acacia_005", "pos": [-20.0, 0.0, 18.0], "scale": 1.0, "rot_y_deg": 75.0}) - (doc["objects"] as Array).append({"id": "rock_008", "pos": [24.0, 0.0, -18.0], "scale": 1.0, "rot_y_deg": 0.0}) - history.commit("Demo: Objekte gesetzt", before, history.snapshot(["objects"])) - interaction.call("cancel_placement") - _clear_edit_state() - _refresh_all() - interaction.select_object(0, true) - _demo_camera(Vector3(0.0, 2.0, 0.0), 110.0, 40.0, -35.0) - _set_status("Demo 2/3: Objekte platziert (Wachturm orange ausgewählt) — ziehen, drehen, löschen wie gehabt.") - await _demo_shot(out_dir + "/library_placed.png") - - # 3) Snap to Ground: Objekte künstlich in die Luft hängen, dann 1 Klick. - var float_before: Dictionary = history.snapshot(["objects"]) - for obj in (doc["objects"] as Array): - var pos: Array = obj["pos"] - obj["pos"] = [float(pos[0]), float(pos[1]) + 7.0, float(pos[2])] - history.commit("Demo: Objekte schweben", float_before, history.snapshot(["objects"])) - _refresh_all() - _demo_camera(Vector3(0.0, 6.0, 0.0), 110.0, 30.0, -35.0) - _set_status("Demo 3/3a: Objekte SCHWEBEN nach dem Terrain-Formen — ein Klick auf „Alles auf den Boden setzen\" …") - await _demo_shot(out_dir + "/library_floating.png") - _on_snap_to_ground() - _demo_camera(Vector3(0.0, 4.0, 0.0), 110.0, 38.0, -35.0) - _set_status("Demo 3/3b: … und schon stehen ALLE wieder auf dem Boden (Strg+Z nimmt den ganzen Klick zurück).") - await _demo_shot(out_dir + "/library_after_snap.png") - print("LIBRARY_DEMO_OK: 4 Screenshots in %s" % out_dir) - if args.has("--library-demo-quit"): - get_tree().quit() # Batch-Smoke (xvfb): automatisch beenden, sobald die Shots da sind - - -## `godot ... -- --spawns-demo [ordner]` — Desktop-Smoke (Karte t_c4162c5d): -## Spawn-Zonen-Workflow programmatisch durchspielen, PNGs speichern: -## Zonen-Übersicht → Live-Check schlägt Alarm bei fehlenden Zonen → Undo rettet → -## Map-Check-Dialog meldet bereit. Die App bleibt offen (Sly sieht das live). -func _start_spawns_demo(args: PackedStringArray) -> void: - var out_dir := "/tmp/scopedvr_spawns" - var idx := args.find("--spawns-demo") - if idx >= 0 and idx + 1 < args.size() and not args[idx + 1].begins_with("--"): - out_dir = args[idx + 1] - DirAccess.make_dir_recursive_absolute(out_dir) - - # 1) Übersicht: Default-Zonen beider Teams (Kreise) + rote Ghost-Vorschau. - _set_tool_mode("spawns") - check_mod.spawn_team_red.button_pressed = true - spawn_tool.call("demo_park_ghost", 260.0, 120.0, 1, 12.0) - _demo_camera(Vector3(160.0, 140.0, 0.0), 700.0, 48.0, -90.0) - _set_status("Demo 1/4: Spawn-Zonen — blaue Kreise = Team Blau, rote = Team Rot, halbtransparent folgt der Ghost der Maus als Vorschau.") - await _demo_shot(out_dir + "/spawns_zones.png") - - # 2) ALLE roten Zonen löschen → Live-Check springt auf ❌ (BEVOR exportiert wird). - _clear_edit_state() - var before: Dictionary = SpawnOps.snapshot_blocks(history, doc) - for p in SpawnOps.points(doc, 1).duplicate(): - SpawnOps.remove_point(doc, 1, str(p["id"])) - history.commit("Demo: alle roten Zonen gelöscht", before, - SpawnOps.snapshot_blocks(history, doc)) - _after_structure_change() - _set_status("Demo 2/4: ALLE roten Zonen weg — der Spawn-Check (rechts) zeigt sofort ❌: Export wäre blockiert.") - await _demo_shot(out_dir + "/spawns_check.png") - - # 3) Strg+Z — alle vier roten Zonen sind zurück (EIN Undo-Schritt). - _do_undo() - _set_status("Demo 3/4: Strg+Z — alle 4 roten Zonen sind auf EINMAL zurück.") - await _demo_shot(out_dir + "/spawns_undo.png") - - # 4) Karte prüfen: Klartext-Liste im Dialog + Status „Alles bereit“. - _on_check_map() - _set_status("Demo 4/4: „Karte prüfen“ — alles ✅ … beim Speichern wird die .svmap automatisch signiert (sha256).") - await _demo_shot(out_dir + "/spawns_ready.png") - print("SPAWNS_DEMO_OK: 4 Screenshots in %s" % out_dir) - if args.has("--spawns-demo-quit"): - get_tree().quit() # Batch-Smoke (xvfb): automatisch beenden, sobald die Shots da sind - - -## `godot ... -- --groups-demo [ordner]` — Desktop-Smoke (Karte t_f6f29d86): -## Auswahl-System programmatisch durchspielen, PNGs speichern: -## Mehrfachauswahl (Rahmen simuliert) → gruppieren → Gruppe gemeinsam ziehen → -## gemeinsames Drehen → Undo-Nachweis. Die App bleibt offen (Sly sieht live). -func _start_groups_demo(args: PackedStringArray) -> void: - var out_dir := "/tmp/scopedvr_groups" - var idx := args.find("--groups-demo") - if idx >= 0 and idx + 1 < args.size() and not args[idx + 1].begins_with("--"): - out_dir = args[idx + 1] - DirAccess.make_dir_recursive_absolute(out_dir) - - # Aufbau: 4 Objekte in zwei Wohnclustern (2 nahe beieinander = spätere Gruppe). - var before: Dictionary = history.snapshot(["objects"]) - (doc["objects"] as Array).append({"id": "water_tower_004", "pos": [10.0, 0.0, 6.0], "scale": 1.0, "rot_y_deg": 0.0}) - (doc["objects"] as Array).append({"id": "box_001", "pos": [14.0, 0.0, 9.0], "scale": 1.0, "rot_y_deg": 0.0}) - (doc["objects"] as Array).append({"id": "box_002", "pos": [14.0, 0.0, 13.0], "scale": 1.0, "rot_y_deg": 45.0}) - (doc["objects"] as Array).append({"id": "acacia_005", "pos": [-30.0, 0.0, 24.0], "scale": 1.0, "rot_y_deg": 0.0}) - history.commit("Demo: Objekte gesetzt", before, history.snapshot(["objects"])) - _refresh_all() - - # 1) Mehrfachauswahl: Objekte 0–2 markiert (wie nach Rahmen-Ausziehen). - interaction.call("select_many", [0, 1, 2], true) - _demo_camera(Vector3(0.0, 2.0, 0.0), 130.0, 40.0, -35.0) - _set_status("Demo 1/4: Mehrfachauswahl — 3 Objekte orange (Umschalt+Klick oder Rahmen aufziehen). Der Baum links bleibt außen vor.") - await _demo_shot(out_dir + "/groups_select.png") - - # 2) Gruppieren: EIN Klick, die 3 gehören ab jetzt zusammen. - interaction.call("group_selection") - _set_status("Demo 2/4: „Gruppieren“ — die 3 Objekte sind jetzt Gruppe 1. Der Baum links ist NICHT Teil der Gruppe.") - await _demo_shot(out_dir + "/groups_grouped.png") - - # 3) Gruppe gemeinsam ziehen (exakt der Drag-Release-Pfad) + gemeinsames Drehen. - interaction.call("demo_drag_selection", Vector3(24.0, 0.0, -18.0)) - interaction.call("rotate_selected", 30.0) - _demo_camera(Vector3(20.0, 2.0, 0.0), 130.0, 42.0, -20.0) - _set_status("Demo 3/4: Gruppe GEMEINSAM verschoben und um die eigene Mitte gedreht — die Anordnung bleibt erhalten, der Baum stand still.") - await _demo_shot(out_dir + "/groups_moved.png") - - # 4) Undo-Nachweis: Strg+Z nimmt die Drehung zurück (EIN Schritt), die - # zweite Stufe würde den Zug zurücknehmen — jede Aktion = EIN Undo-Schritt. - _do_undo() - _demo_camera(Vector3(20.0, 2.0, 0.0), 130.0, 42.0, -20.0) - _set_status("Demo 4/4: Strg+Z — die Drehung ist zurück (Zug & Drehen sind getrennte Schritte); die Gruppe bleibt gebunden.") - await _demo_shot(out_dir + "/groups_undo.png") - print("GROUPS_DEMO_OK: 4 Screenshots in %s" % out_dir) - if args.has("--groups-demo-quit"): - get_tree().quit() # Batch-Smoke (xvfb): automatisch beenden, sobald die Shots da sind - - -## `godot ... -- --bauen-demo [ordner]` — Desktop-Smoke: baut programmatisch ein -## kleines Haus mit denselben Funktionen wie der Klick (BauSnap + BauOps), zeigt -## Ghost, Gebäude-Auswahl und Weiterbauen nach Speichern/Laden. Die App bleibt -## offen (Sly sieht das Ergebnis live). -func _start_bauen_demo(args: PackedStringArray) -> void: - var out_dir := "/tmp/scopedvr_bauen" - var idx := args.find("--bauen-demo") - if idx >= 0 and idx + 1 < args.size() and not args[idx + 1].begins_with("--"): - out_dir = args[idx + 1] - DirAccess.make_dir_recursive_absolute(out_dir) - _set_tool_mode("objects") - interaction.call("start_placement", "bau_wand") - interaction.call("demo_park_bau", Vector3(2.0, 0.0, 1.0)) - _demo_camera(Vector3(3.0, 2.0, 8.0), 14.0, 32.0, 25.0) - _set_status("Demo 1/3: Bauen — die Vorschau rastet auf die Zellkante ein.") - await _demo_shot(out_dir + "/bauen_ghost.png") - interaction.call("cancel_placement") - var gid := BauOps.haus_demo(doc, history, Vector3(4.0, 0.0, 4.0)) - _after_structure_change() - _demo_camera(Vector3(4.0, 1.5, 4.0), 13.0, 30.0, 35.0) - _set_status("Demo 2/3: Kleines Haus gebaut (Gruppe %d) — Fundament, Wände, Tür, Fenster, Giebel, Dach, Treppe." % (gid + 1)) - await _demo_shot(out_dir + "/bauen_haus.png") - _save_to(out_dir + "/bauen_demo.svmap") - var reload := SvmapIO.load_from_file(out_dir + "/bauen_demo.svmap") - if bool(reload["ok"]): - doc = reload["data"] - history.begin(doc) - _clear_edit_state() - _refresh_all() - _demo_camera(Vector3(4.0, 1.5, 4.0), 13.0, 30.0, 35.0) - _set_status("Demo 3/3: Gespeichert und wieder geladen — das Haus ist als Gruppe erhalten.") - await _demo_shot(out_dir + "/bauen_weiter.png") - print("BAUEN_DEMO_OK: 3 Screenshots in %s (%d Bauteile, Map OK)" % [out_dir, BauOps.teile_zahl(doc)]) - if args.has("--bauen-demo-quit"): - get_tree().quit() # Batch-Smoke (xvfb): automatisch beenden, sobald die Shots da sind - - -## --- Test-Start: Haken (T1b-Vertrag, Operator-Wiederanbindung 20.10.) -------- -## Diese drei Namen erwartet tests/test_playtest_spawn.gd (56 checks) auf main. -## Sie waren beim U1-Umbau verschwunden (Suite brach mit „Nonexistent function -## '_test_start_reload'" ab und hing) — deshalb stehen sie hier bewusst fest. -## Der sichtbare Teil (Info + Löschen) lebt in src/ui/panels/test_start_panel.gd, -## der Zustand hier — genau wie vor dem Umbau. -func _test_start_apply(x: float, z: float, hinweis: String) -> void: - test_start_point = Vector3(x, 0.0, z) - TestStartStore.save_point(current_path, test_start_point) - if test_start_tool != null: - test_start_tool.call("refresh_from_doc") - _refresh_test_start_panel() - # Klartext-Hinweis des Werkzeugs (z.B. „auf dem Boden unter dem Objekt") - # mitnehmen — die Prüfsuite liest ihn aus der Statuszeile. - var ort := " (Höhe automatisch)" if hinweis.is_empty() else " (Höhe automatisch — %s)" % hinweis - _set_status("Test-Start: x=%.0f z=%.0f%s — F5 startet den Testlauf genau dort." % [x, z, ort]) - - -func _test_start_delete() -> void: - if test_start_point == null: - return - test_start_point = null - TestStartStore.clear_point(current_path) - if test_start_tool != null: - test_start_tool.call("refresh_from_doc") - _refresh_test_start_panel() - - -func _test_start_reload() -> void: - test_start_point = TestStartStore.load_point(current_path) - if test_start_tool != null: - test_start_tool.call("refresh_from_doc") - _refresh_test_start_panel() - - -func _refresh_test_start_panel() -> void: - if test_start_panel != null and is_instance_valid(test_start_panel): - test_start_panel.call("refresh_point", test_start_point) - - -## --- Test-Start: Werkzeug-Modus (wie Terrain/Spawns/Bauen) -------------------- -## Die Prüfsuite erwartet tool_mode == "teststart", einen leuchtenden Leisten- -## Knopf (`test_start_btn`) und das erst dann sichtbare Panel (`test_start_panel`). -func _enter_test_start_mode() -> void: - interaction.call("cancel_placement") - tool_mode = "teststart" - if test_start_tool != null: - test_start_tool.call("activate") - _sync_test_start_button() - _sync_test_start_panel_visibility() - - -func _leave_test_start_mode() -> void: - if test_start_tool != null: - test_start_tool.call("deactivate") - # Direkt aus-/einschalten statt über tool_mode: _set_tool_mode ruft die - # _leave_*-Funktionen BEVOR der Zielmodus gesetzt ist — ein Abgleich gegen - # tool_mode ließe das Panel offen (Befund aus test_playtest_spawn). - if test_start_panel != null: - test_start_panel.visible = false - if test_start_btn != null: - test_start_btn.button_pressed = false - - -func _sync_test_start_button() -> void: - if test_start_btn != null: - test_start_btn.button_pressed = (tool_mode == "teststart") - - -func _sync_test_start_panel_visibility() -> void: - if test_start_panel != null: - test_start_panel.visible = (tool_mode == "teststart") - - -## Leisten-Knopf „🎯 Test-Start" (registry.gd ACTIONS) — schaltet das Werkzeug um. -func _on_test_start_tool_pressed() -> void: - _set_tool_mode("objects" if tool_mode == "teststart" else "teststart") - - -# -------------------------------- Fremdformat-Dialog (t_9814f18f) ----------- - -## „Trotzdem laden (Prüfsumme erneuern)“ bestätigt: Datei NUR gegen die -## Kern-Validierung (V3–V16) prüfen, v2-Prüfsumme ins Dokument schreiben und -## normal öffnen. dirty=true: das Dokument weicht von der Datei ab — der -## nächste Speicher-Vorgang schreibt das v2-Schema in die Datei. -func _on_resign_confirmed() -> void: - var result := SvmapIO.load_from_file_resign(_resign_pending_path) - if not result["ok"]: - _show_errors("Map konnte NICHT geladen werden (auch ohne Prüfsummen-Prüfung):", result["errors"]) - _set_status("Laden fehlgeschlagen: %s" % _resign_pending_path.get_file(), true) - return - doc = result["data"] - SvmapIO.upgrade_material_layer(doc.get("terrain", {})) # feines Material-Raster - BauOps.migriere_gebaeude(doc) # alte Bau-Sektion → Bauteil-Objekte - current_path = _resign_pending_path - dirty = true - history.begin(doc) - _clear_edit_state() - _refresh_all() - _test_start_reload() - var map_name := str(doc.get("info", {}).get("name", "?")) - _set_status("Map „%s“ geladen — Prüfsumme erneuert (v2). Speichere die Map, um die neue Prüfsumme zu übernehmen." % map_name) - _refresh_file_label() diff --git a/src/ui/main.gd.uid b/src/ui/main.gd.uid deleted file mode 100644 index 115239e..0000000 --- a/src/ui/main.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c5j3bplirtg6k diff --git a/src/ui/new_map_dialog.gd b/src/ui/new_map_dialog.gd deleted file mode 100644 index 34ab0ca..0000000 --- a/src/ui/new_map_dialog.gd +++ /dev/null @@ -1,94 +0,0 @@ -extends ConfirmationDialog -## „Neue Map“-Dialog: Name, Größe, Wetter-Preset — bewusst nur 3 Fragen, -## alles Weitere setzt vernünftige Defaults (Chef-Grundsatz: easy). - -const UIScale := preload("res://src/ui/ui_scale.gd") # Karte t_297221b5 - -var name_edit: LineEdit -var size_option: OptionButton -var weather_option: OptionButton -var mode_option: OptionButton - -var _sizes: Array[float] = [512.0, 1024.0, 2048.0] -var _size_labels := ["Klein — 512 × 512 m", "Mittel — 1024 × 1024 m", "Groß — 2048 × 2048 m"] -var _weathers := ["mittag", "abend", "regen", "nacht"] -var _weather_labels := ["Mittag (sonnig, klar)", "Abend (warmes Licht)", "Regen (grau, kühl)", "Nacht (dunkel)"] - - -func _init() -> void: - title = "Neue Map" - ok_button_text = "Map erstellen" - cancel_button_text = "Abbrechen" - min_size = UIScale.v2i(460, 0) - - var vbox := VBoxContainer.new() - vbox.anchors_preset = Control.PRESET_FULL_RECT - vbox.set_anchors_preset(Control.PRESET_FULL_RECT) - vbox.add_theme_constant_override("separation", UIScale.px(12)) - add_child(vbox) - - vbox.add_child(_make_label("Wie soll die Map heißen?")) - name_edit = LineEdit.new() - name_edit.text = "Neue Map" - name_edit.max_length = 64 - name_edit.custom_minimum_size = UIScale.v2(0, 40) - vbox.add_child(name_edit) - - vbox.add_child(_make_label("Wie groß soll das Gelände sein?")) - size_option = OptionButton.new() - for label in _size_labels: - size_option.add_item(label) - size_option.select(1) # Mittel als Default - size_option.custom_minimum_size = UIScale.v2(0, 40) - # U7: Klartext-Tooltips (Karte t_2336c58e). - size_option.tooltip_text = "Kantenlänge des Geländes — größer = mehr Platz zum Bauen" - vbox.add_child(size_option) - - vbox.add_child(_make_label("Welches Wetter soll die Map haben?")) - weather_option = OptionButton.new() - for label in _weather_labels: - weather_option.add_item(label) - weather_option.custom_minimum_size = UIScale.v2(0, 40) - weather_option.tooltip_text = "Licht und Stimmung der Karte (Tag/Abend/Regen/Nacht)" - vbox.add_child(weather_option) - - vbox.add_child(_make_label("Welchen Spielmodus soll die Map haben?")) - mode_option = OptionButton.new() - for m in ModusKatalog.MODES: - mode_option.add_item(ModusKatalog.MODE_LABELS[m]) - mode_option.custom_minimum_size = UIScale.v2(0, 40) - mode_option.tooltip_text = "Team-Deathmatch: Kills zählen. Conquest: Teams nehmen mehrere Zonen ein. King of the Hill: ein Hill, der wandert. Deathmatch: alle gegen alle. Lässt sich später im Map-Tab ändern." - vbox.add_child(mode_option) - - var hint := _make_label("Die Map startet leer mit 4 Spawn-Punkten pro Team\n(Blau im Westen, Rot im Osten) — beides lässt sich später ändern.") - hint.modulate = Color(1, 1, 1, 0.7) - vbox.add_child(hint) - - -func _make_label(text: String) -> Label: - var label := Label.new() - label.text = text - label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - # FIX 20.10.: autowrap-Label ohne Mindestbreite meldet vor dem ersten - # Layout eine explosionsartige Mindesthöhe (Probe: Fenster 4781 px hoch - # statt ~390) — Popup-Größe wird daraus einmalig übernommen. Mindestbreite - # ~ Dialogbreite verankert den Umbruch an der echten Breite. - label.custom_minimum_size = Vector2(UIScale.px(440), 0) - return label - - -func get_map_name() -> String: - var n := name_edit.text.strip_edges() - return n if not n.is_empty() else "Neue Map" - - -func get_size_m() -> float: - return _sizes[size_option.selected] - - -func get_game_mode() -> String: - return ModusKatalog.MODES[mode_option.selected] - - -func get_weather() -> String: - return _weathers[weather_option.selected] diff --git a/src/ui/new_map_dialog.gd.uid b/src/ui/new_map_dialog.gd.uid deleted file mode 100644 index 4bc1260..0000000 --- a/src/ui/new_map_dialog.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://d1tevsdsnf8ih diff --git a/src/ui/panels/assets_panel.gd b/src/ui/panels/assets_panel.gd deleted file mode 100644 index 21e4de1..0000000 --- a/src/ui/panels/assets_panel.gd +++ /dev/null @@ -1,782 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Objekt-Bibliothek / Assets-Bereich (aus main.gd ausgezogen, Karte t_eaccbfed; -## Unity-artiger Ausbau Karte t_69687afc/U4): Kategorien-Leiste, Suche, Zuletzt -## benutzt, Vorschau-Kacheln mit Name + ID, Hover vergrößert die ID, fehlende -## Modelle werden markiert (nicht stillschweigend), Klick wählt aus, -## Doppelklick startet das Platzier-Werkzeug wie bisher. -## Der Bereich wohnt UNTEN unter der 3D-Ansicht (Unity-Projekt-Fenster-Platz). -## -## Kompatibilität (main.gd bindet diese Felder — NICHT umbenennen): -## library_search, library_buttons, _library_group_rows, -## library_open_all_btn, library_close_all_btn, -## _on_library_pressed(), _apply_library_filter(), -## _on_library_expand_all(), _on_library_collapse_all(), highlight_library(). -## Die Klapp-Gruppen bleiben als Körper der „Alle"-Ansicht erhalten; die -## Kategorien-Leiste filtert dieselben Zeilen (Mechanik wie die Suche). - -signal object_selected(oid: String) # Klick auf eine Kachel (nur bei Wechsel) -signal object_activated(oid: String) # Doppelklick — Werkzeug-Start (U5 koppelt) - -const LIBRARY_CFG_SECTION := "library" # Abschnitt in user://scopedvr_editor.cfg -const RECENT_CFG_KEY := "zuletzt_benutzt" # selbiger Abschnitt, Liste von IDs -const RECENT_MAX := 12 # gemerkte Objekte (neueste zuerst) -const CAT_ALLE := "alle" # Pseudo-Kategorie: alles -const CAT_ZULETZT := "zuletzt" # Pseudo-Kategorie: zuletzt benutzt - -var library_box: VBoxContainer -var library_buttons: Dictionary = {} # id → Button (Haupt-Grid, kanonisch) -## Bibliothek-Gruppen (t_59fc0f21): Klapp-Zustand + Zeilen für Suche/Alle auf/zu. -var library_search: LineEdit -var library_open_all_btn: Button -var library_close_all_btn: Button -var _library_group_open: Dictionary = {} # Gruppen-Key → auf/zu -var _library_group_rows: Array = [] # {key, header, box, ids} -var _library_bold_font: Font = null - -# --- U4 neu: Kategorien, Zähler, Zuletzt benutzt, Auswahl ------------------- -var library_counter: Label # „N von M sichtbar" -var _cat_chips: HFlowContainer # Kategorien-Leiste -var _cat_buttons: Dictionary = {} # Key → Chip-Button -var _cat_active: String = CAT_ALLE # aktive Kategorie (Chip) -var _recent_box: VBoxContainer # Zuletzt-benutzt-Ansicht (im Scroll) -var _recent_grid: GridContainer -var _recent_tiles: Dictionary = {} # id → Button (Zuletzt-Ansicht, frisch gebaut) -var _recent_ids: Array = [] # Reihenfolge: neueste zuerst -var _drag_oid := "" # Kachel, die gerade gezogen wird -var _drag_started_placement := false # Ziehen hat das Platzieren gestartet -var selected_oid: String = "" # per Klick gewähltes Objekt -var _id_font_normal: int = 0 # ID-Schriftgröße (skaliert), Normalzustand -var _empty_hint: Label # Leerzustand (U7): kein Treffer / leerer Bereich - - -static func spec() -> Dictionary: - return {"titel": "Objekt-Bibliothek", "gruppe": "unten", "order": 10} - - -func panel_title() -> String: - return "Objekt-Bibliothek" - - -## Bau: Überschrift → Suche → Kategorien-Leiste → Alle auf/zu → Zähler → -## Klapp-Gruppen-Körper („Alle") + Zuletzt-benutzt-Ansicht. -func build() -> void: - add_child(_header_label("Objekt-Bibliothek")) - - # Suche (t_59fc0f21): tippen filtert live nach Name/ID — Gruppen mit - # Treffern klappen auf, leere Gruppen verschwinden. Größe ist von - # test_ui_scale gepinnt (36 → 45 bei „Mittel") — nicht ändern. - library_search = LineEdit.new() - library_search.placeholder_text = "Suchen (Name oder ID)…" - library_search.clear_button_enabled = true - library_search.custom_minimum_size = UIScale.v2(0, 36) - library_search.text_changed.connect(_apply_library_filter) - library_search.text_submitted.connect(func(_t: String) -> void: library_search.release_focus()) - add_child(library_search) - - _build_category_chips() - - # „Alle auf" / „Alle zu" (t_59fc0f21): Klapp-Zustand aller Gruppen auf einmal. - var group_btns := HBoxContainer.new() - group_btns.add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster - library_open_all_btn = Button.new() - library_open_all_btn.text = "Alle auf" - library_open_all_btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL - library_open_all_btn.tooltip_text = "Klappt ALLE Gruppen auf" - library_open_all_btn.pressed.connect(_on_library_expand_all) - group_btns.add_child(library_open_all_btn) - library_close_all_btn = Button.new() - library_close_all_btn.text = "Alle zu" - library_close_all_btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL - library_close_all_btn.tooltip_text = "Klappt ALLE Gruppen zu" - library_close_all_btn.pressed.connect(_on_library_collapse_all) - group_btns.add_child(library_close_all_btn) - add_child(group_btns) - - # Zähler „N von M sichtbar" (U4): M = Objekte im aktiven Bereich, N = davon - # durch Suche/Kategorie sichtbar. - library_counter = Label.new() - # U7: Nebentext-Größe + Theme-Farbe (Editor/colors/field). - library_counter.add_theme_font_size_override("font_size", UIScale.small_font_size()) - library_counter.add_theme_color_override("font_color", theme_color("field")) - library_counter.tooltip_text = "Sichtbare Kacheln im aktiven Bereich" - add_child(library_counter) - - var scroll := ScrollContainer.new() - scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL - scroll.custom_minimum_size = UIScale.v2(0, 320) - scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED - add_child(scroll) - library_box = VBoxContainer.new() - library_box.size_flags_horizontal = Control.SIZE_EXPAND_FILL - library_box.add_theme_constant_override("separation", UIScale.px(4)) - scroll.add_child(library_box) - # Leerzustand (U7, „fertig aussehen"): freundlicher Klartext statt - # stummer leerer Fläche — Suchbegriff ohne Treffer oder leerer Bereich. - _empty_hint = Label.new() - _empty_hint.text = "Nichts gefunden — anderen Suchbegriff oder „Alle“ versuchen." - _empty_hint.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - _empty_hint.add_theme_color_override("font_color", theme_color("muted")) - _empty_hint.visible = false - scroll.add_child(_empty_hint) - _recent_box = VBoxContainer.new() - _recent_box.visible = false - _recent_box.add_theme_constant_override("separation", UIScale.px(4)) - library_box.add_child(_recent_box) - _fill_library() - _recent_ids = _recent_load() - _update_recent_chip() - _apply_library_filter(library_search.text) - - -# ------------------------------------------------------------ Kategorien ---- - -## Kategorien-Leiste (U4): „Alle" + eine Chip je Bibliotheks-Gruppe -## (LibraryBrowser.groups_in_order — KEINE eigene Kategorieliste) + -## „Zuletzt benutzt". Chips zeigen Name + Anzahl; Summe der Gruppen-Chips = -## Gesamtzahl (test_assets_panel rechnet nach). -func _build_category_chips() -> void: - _cat_chips = HFlowContainer.new() - _cat_chips.add_theme_constant_override("h_separation", UIScale.px(4)) - _cat_chips.add_theme_constant_override("v_separation", UIScale.px(4)) - add_child(_cat_chips) - var bg := ButtonGroup.new() - var groups := LibraryBrowser.groups_in_order(main.manifest) - _cat_add_chip(CAT_ALLE, "Alle", _manifest_count(), bg) - for group in groups: - var g_key: String = group["key"] - var g_ids: Array = group["ids"] - if g_ids.is_empty(): - continue - _cat_add_chip(g_key, str(group["label"]), g_ids.size(), bg) - _cat_add_chip(CAT_ZULETZT, "Zuletzt benutzt", 0, bg) - (_cat_buttons[CAT_ZULETZT] as Button).visible = false # taucht auf, sobald benutzt - - -func _manifest_count() -> int: - return (main.manifest.get("objects", {}) as Dictionary).size() - - -func _cat_add_chip(key: String, label: String, count: int, bg: ButtonGroup) -> void: - var chip := Button.new() - chip.toggle_mode = true - chip.button_group = bg - chip.button_pressed = key == _cat_active - chip.text = "%s (%d)" % [label, count] if key != CAT_ZULETZT else label - chip.custom_minimum_size = UIScale.v2(0, 28) - chip.tooltip_text = "Zeigt nur die Gruppe „%s“" % label if key != CAT_ALLE and key != CAT_ZULETZT else "Zeigt alle Objekte" if key == CAT_ALLE else "Die zuletzt ausgewählten/benutzten Objekte" - chip.set_meta("cat_key", key) - chip.set_meta("cat_count", count) - chip.toggled.connect(_on_cat_chip_toggled.bind(key)) - _cat_chips.add_child(chip) - _cat_buttons[key] = chip - - -func _on_cat_chip_toggled(on: bool, key: String) -> void: - if not on: - return # Radio-Gruppe: der neue Chip drückt sich selbst an - _select_category(key) - - -## Kategorie wechseln: Zustand merken (kein Config-Zwang — Chips sind -## Ansichtsfilter, der Klapp-Zustand je Gruppe bleibt in der cfg). -func _select_category(key: String) -> void: - if key != CAT_ZULETZT and not _cat_buttons.has(key): - return - _cat_active = key - for chip_key in _cat_buttons: - var chip := _cat_buttons[chip_key] as Button - chip.set_pressed_no_signal(str(chip_key) == _cat_active) - _apply_library_filter(library_search.text) - - -func _update_recent_chip() -> void: - var chip := _cat_buttons.get(CAT_ZULETZT) as Button - if chip == null: - return - chip.visible = not _recent_ids.is_empty() - chip.text = "Zuletzt benutzt (%d)" % _recent_ids.size() - - -## Objekte des aktiven Bereichs (M im Zähler): Alle → Gesamtkatalog, -## Kategorie → deren IDs, Zuletzt → gemerkte Liste. -func _scope_ids() -> Array: - var lib: Dictionary = main.manifest.get("objects", {}) - if _cat_active == CAT_ALLE: - return lib.keys() - if _cat_active == CAT_ZULETZT: - return _recent_ids.duplicate() - for row in _library_group_rows: - if str(row["key"]) == _cat_active: - return (row["ids"] as Array).duplicate() - return [] - - -# -------------------------------------------------------- Klapp-Gruppen ---- - -func _fill_library() -> void: - library_buttons.clear() - _library_group_rows.clear() - _library_group_open = _library_load_open_states() - # Gruppen-Browser (Karte t_3a998ae4, Überarbeitung t_59fc0f21): - # - Klapp-Überschriften je Gruppe (fett, 18 px, Name + Anzahl), - # - STANDARD EINGEKLAPPT — nur die erste Gruppe ist offen (Übersicht!), - # - Klapp-Zustand je Gruppe wird in user://scopedvr_editor.cfg gemerkt, - # - Objekte als Kacheln mit 96-px-Vorschaubild (2 Spalten je Gruppe). - # U4: der Körper bleibt („Alle“-Ansicht), die Kategorien-Leiste filtert ihn. - var first_open: String = "" - for group in LibraryBrowser.groups_in_order(main.manifest): - var g_key: String = group["key"] - var g_label: String = group["label"] - var g_ids: Array = group["ids"] - if g_ids.is_empty(): - continue - if first_open.is_empty(): - first_open = g_key - var is_open: bool = _library_group_open.get(g_key, g_key == first_open) - _library_group_open[g_key] = is_open - var header := Button.new() - header.text = _library_header_text(is_open, g_label, g_ids.size()) - header.toggle_mode = true - header.button_pressed = is_open - header.alignment = HORIZONTAL_ALIGNMENT_LEFT - header.custom_minimum_size = UIScale.v2(0, 34) - header.tooltip_text = "Gruppe „%s“ auf-/zuklappen" % g_label - header.add_theme_font_size_override("font_size", UIScale.heading_font_size()) - header.add_theme_font_override("font", _library_header_font()) - library_box.add_child(header) - var group_box := VBoxContainer.new() - group_box.add_theme_constant_override("separation", UIScale.px(4)) - group_box.visible = is_open - var grid := GridContainer.new() - grid.columns = 2 - grid.size_flags_horizontal = Control.SIZE_EXPAND_FILL - grid.add_theme_constant_override("h_separation", UIScale.px(8)) # U7-Raster - grid.add_theme_constant_override("v_separation", UIScale.px(8)) # U7-Raster - group_box.add_child(grid) - library_box.add_child(group_box) - header.toggled.connect(_on_library_group_toggled.bind(g_key, g_label, g_ids.size(), header, group_box)) - for oid in g_ids: - _add_library_button(str(oid), grid) - _library_group_rows.append({"key": g_key, "header": header, "box": group_box, "ids": g_ids, "label": g_label, "count": g_ids.size(), "grid": grid}) - if not resized.is_connected(_on_panel_resized): - resized.connect(_on_panel_resized) - _on_panel_resized() - - -## Unity-Projekt-Fenster-Feeling (U4): die Spaltenzahl passt sich der BREITE -## des unteren Bereichs an (schmaler Dock = wenige Spalten, breiter = viele). -## Kachel-Zielbreite ≈ 180 px (skaliert über ui_scale). -func _on_panel_resized() -> void: - _apply_grid_columns(size.x) - - -func _apply_grid_columns(width: float) -> void: - var cols := clampi(int(width / float(UIScale.px(200))), 1, 12) - for row in _library_group_rows: - ((row["grid"] as GridContainer)).columns = cols - if _recent_grid != null: - _recent_grid.columns = cols - - -## Kompletter Neubau des Bibliotheks-Körpers (Probe/Umbau): alte Zeilen frei -## geben, dann frisch füllen und den Filter anwenden. Die Zuletzt-Ansicht -## (_recent_box) überlebt den Neubau — sie wird nur aus dem Baum genommen und -## wieder eingehängt, damit die Referenz NICHT auf ein freigegebenes Objekt -## zeigt (sonst „previously freed" im nächsten Filterlauf). -func _rebuild_library() -> void: - if _recent_box != null and _recent_box.get_parent() == library_box: - library_box.remove_child(_recent_box) - for c in library_box.get_children(): - library_box.remove_child(c) - (c as Node).free() - if _recent_box != null and _recent_box.get_parent() == null: - library_box.add_child(_recent_box) - _fill_library() - _apply_library_filter(library_search.text) - - -func _library_header_text(on: bool, label: String, count: int) -> String: - return "%s %s (%d)" % ["▾" if on else "▸", label, count] - - -func _on_library_group_toggled(on: bool, g_key: String, g_label: String, count: int, header: Button, group_box: VBoxContainer) -> void: - group_box.visible = on - header.text = _library_header_text(on, g_label, count) - _library_group_open[g_key] = on - _library_save_open_state(g_key, on) - - -func _on_library_expand_all() -> void: - for row in _library_group_rows: - var header := row["header"] as Button - header.button_pressed = true - # toggled feuert → box sichtbar; Filter danach neu anwenden, damit - # ein aktiver Kategorie-Filter/Suche nicht weggeblasen wird. - _apply_library_filter(library_search.text) - - -func _on_library_collapse_all() -> void: - for row in _library_group_rows: - var header := row["header"] as Button - header.button_pressed = false - _apply_library_filter(library_search.text) - - -func _library_header_font() -> Font: - if _library_bold_font == null: - var sf := SystemFont.new() - sf.font_names = PackedStringArray(["Noto Sans", "DejaVu Sans", "Ubuntu", "sans-serif"]) - sf.font_weight = 700 - _library_bold_font = sf - return _library_bold_font - - -func _library_load_open_states() -> Dictionary: - var cfg := ConfigFile.new() - cfg.load("user://scopedvr_editor.cfg") - var out := {} - if cfg.has_section(LIBRARY_CFG_SECTION): - for key in cfg.get_section_keys(LIBRARY_CFG_SECTION): - if str(key) == RECENT_CFG_KEY: - continue - # Robustheit (t_efb3d022): cfg-Einträge dieser Sektion müssen Bool- - # Zustände sein. Ein kaputter Eintrag (String/Array/sonstwas) darf - # KEINEN SCRIPT ERROR werfen (bool() ist kein gültiger - # Konstruktor) — sonst brechen die Klapp-Zustände komplett weg. - var val = cfg.get_value(LIBRARY_CFG_SECTION, str(key), true) - if typeof(val) == TYPE_BOOL: - out[str(key)] = val - else: - out[str(key)] = true - return out - - -func _library_save_open_state(g_key: String, on: bool) -> void: - var cfg := ConfigFile.new() - cfg.load("user://scopedvr_editor.cfg") - cfg.set_value(LIBRARY_CFG_SECTION, g_key, on) - cfg.save("user://scopedvr_editor.cfg") - - -# ----------------------------------------------------------------- Suche ---- - -## Live-Filter (t_59fc0f21, U4 erweitert): Suche (Name de/en, ID — case- -## insensitive) geht VOR der Kategorie (sucht im ganzen Katalog); ohne Suche -## zeigt die aktive Kategorie nur ihre Gruppe, „Alle" den Klapp-Zustand wie -## gemerkt, „Zuletzt" die Gemerkten. Danach Zähler „N von M sichtbar". -func _apply_library_filter(query: String) -> void: - var q := query.strip_edges().to_lower() - var searching := not q.is_empty() - var visible_count := 0 - # Suche gilt immer für den GANZEN Katalog; ohne Suche zählt der aktive Bereich. - var scope: int = _manifest_count() if not q.is_empty() else _scope_ids().size() - _recent_box.visible = false - if searching: - for row in _library_group_rows: - var ids: Array = row["ids"] - var any := false - for oid in ids: - var btn := library_buttons.get(str(oid)) as Button - if btn == null: - continue - var vis := _library_oid_matches(str(oid), q) - btn.visible = vis - any = any or vis - if vis: - visible_count += 1 - var header := row["header"] as Button - var box := row["box"] as VBoxContainer - header.visible = any - # Treffer-Gruppen bleiben auf — auch wenn sie zugeklappt waren - # (Pfeil zeigt dann offen, kosmetisch konsistent). - box.visible = any - if any: - header.text = _library_header_text(true, str(row["label"]), int(row["count"])) - elif _cat_active == CAT_ZULETZT: - for row in _library_group_rows: - (row["header"] as Button).visible = false - (row["box"] as VBoxContainer).visible = false - for oid in row["ids"]: - var btn := library_buttons.get(str(oid)) as Button - if btn != null: - btn.visible = false - _fill_recent_box() - _recent_box.visible = true - for oid in _recent_ids: - if _recent_tiles.has(str(oid)): - visible_count += 1 - else: - for row in _library_group_rows: - var in_cat: bool = _cat_active == CAT_ALLE or str(row["key"]) == _cat_active - var ids: Array = row["ids"] - var header := row["header"] as Button - var box := row["box"] as VBoxContainer - header.visible = in_cat - if not in_cat: - box.visible = false - for oid in ids: - var btn := library_buttons.get(str(oid)) as Button - if btn != null: - btn.visible = false - continue - var is_open := bool(_library_group_open.get(str(row["key"]), false)) - if _cat_active != CAT_ALLE: - # Kategorie-Ansicht zeigt DIESE Gruppe geöffnet (wie die - # Suche ihre Treffer-Gruppen öffnet) — ohne den gemerkten - # Klapp-Zustand zu überschreiben. - is_open = true - box.visible = is_open - header.text = _library_header_text(is_open, str(row["label"]), int(row["count"])) - for oid in ids: - var btn := library_buttons.get(str(oid)) as Button - if btn != null: - btn.visible = is_open - if is_open: - visible_count += 1 - if library_counter != null: - library_counter.text = "%d von %d sichtbar" % [visible_count, scope] - # Leerzustand (U7): 0 Treffer → Klartext-Hinweis zeigen statt stummer Fläche. - if _empty_hint != null: - _empty_hint.visible = visible_count == 0 - - -func _library_oid_matches(oid: String, q: String) -> bool: - if oid.to_lower().contains(q): - return true - var entry: Dictionary = (main.manifest.get("objects", {}) as Dictionary).get(oid, {}) - if LibraryBrowser.entry_label(oid, entry).to_lower().contains(q): - return true - if LibraryBrowser.object_label(oid).to_lower().contains(q): - return true - return false - - -# ---------------------------------------------------------------- Kacheln ---- - -## Kachel in ein Grid hängen. canonical = Haupt-Grid (landet in -## library_buttons, wird von interaction/_highlight_library gefunden); -## Zuletzt-benutzt-Kacheln sind eigene frische Buttons (kein Dict-Konflikt). -func _add_library_button(oid: String, parent: Container) -> void: - var btn := _build_tile(oid) - parent.add_child(btn) - library_buttons[oid] = btn - - -func _build_tile(oid: String) -> Button: - var lib: Dictionary = main.manifest.get("objects", {}) - var entry: Dictionary = lib.get(oid, {}) - var poly := int(entry.get("poly", 0)) - var name_txt := LibraryBrowser.entry_label(oid, entry) - var missing := _tile_is_missing(oid, entry) - var btn := Button.new() - btn.toggle_mode = true - btn.button_pressed = false - btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL - btn.custom_minimum_size = UIScale.v2(0, 188) - btn.tooltip_text = "%s · %d Polys · %s" % [name_txt, poly, oid] - if missing: - btn.tooltip_text += " · MODELL FEHLT (Platzhalter-Kiste)" - btn.pressed.connect(_on_tile_pressed.bind(oid)) - btn.gui_input.connect(_on_tile_gui_input.bind(oid)) - # Ziehen & Loslassen (25.10.): Kachel anklicken, gedrückt halten, in die Szene - # ziehen — beim Loslassen wird das Objekt dort gesetzt (Doppelklick geht weiter). - btn.set_drag_forwarding(_tile_drag_data.bind(oid, btn), Callable(), Callable()) - btn.mouse_entered.connect(_on_tile_hover.bind(oid, true)) - btn.mouse_exited.connect(_on_tile_hover.bind(oid, false)) - var tex := LibraryBrowser.load_thumb(oid) - if tex == null: - # Kein Thumbnail → Text-Zeile wie früher (Fehlertoleranz, t_3a998ae4). - btn.text = "%s · %d Polys" % [name_txt, poly] - btn.alignment = HORIZONTAL_ALIGNMENT_LEFT - btn.custom_minimum_size = UIScale.v2(0, 44) - else: - # Kachel (t_59fc0f21 + U4): 96-px-Vorschaubild oben, ID + Name darunter. - # Kinder ignorieren die Maus, damit die Klicks am Button ankommen. - # Reihenfolge Bild → ID → Name: der Name bleibt das LETZTE Label - # (test_library_browser_ui liest das letzte Label als Namen). - var tile := VBoxContainer.new() - tile.mouse_filter = Control.MOUSE_FILTER_IGNORE - tile.set_anchors_preset(Control.PRESET_FULL_RECT) - tile.add_theme_constant_override("separation", UIScale.px(4)) # U7-Raster - btn.add_child(tile) - # Vorschaubild: bleibt DIREKTES Kind der Kachel-VBox (test_library_ - # browser_ui sucht es dort) mit gepinnter Min-Größe (test_ui_scale - # sucht THUMB_DISPLAY_PX × Stufenfaktor). Die „Modell fehlt“-Marke - # hängt als Badge-KIND am TextureRect — der Button ist kein Container, - # eine Extra-Zeile unter dem Bild würde unter die Kachelkante rutschen - # und von der nächsten Reihe überdeckt. - var tr := TextureRect.new() - tr.texture = tex - tr.custom_minimum_size = UIScale.v2(LibraryBrowser.THUMB_DISPLAY_PX, LibraryBrowser.THUMB_DISPLAY_PX) - tr.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED - tr.expand_mode = TextureRect.EXPAND_IGNORE_SIZE - tr.size_flags_horizontal = Control.SIZE_SHRINK_CENTER - tr.mouse_filter = Control.MOUSE_FILTER_IGNORE - tile.add_child(tr) - var id_lbl := Label.new() - id_lbl.text = oid - # U7: Tile-ID als Nebentext-Größe, Farbe über Theme (Editor/colors/title). - _id_font_normal = UIScale.small_font_size() - id_lbl.add_theme_font_size_override("font_size", _id_font_normal) - id_lbl.add_theme_color_override("font_color", theme_color("title")) - id_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - id_lbl.clip_text = true - id_lbl.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS - id_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE - id_lbl.set_meta("tile_id_label", true) - tile.add_child(id_lbl) - var lbl := Label.new() - lbl.text = name_txt - lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - lbl.clip_text = true - lbl.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS - lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE - tile.add_child(lbl) - if missing: - # Klar sichtbar markieren (U4): Bild abgedunkelt + Warn-Badge - # als Overlay am unteren Bildrand (immer innerhalb der Kachel). - # U7: Abdunkeln nur über Alpha (Farbe bleibt weiß), Badge-Farbe - # über Theme (Editor/colors/warning + badge_outline), Nebentext- - # Größe statt Mikroschrift (U7-Raster: zwei Größen + Überschrift). - tr.modulate.a = 0.45 - tr.clip_contents = true - var warn := Label.new() - warn.text = "Modell fehlt" - warn.set_anchors_preset(Control.PRESET_BOTTOM_WIDE) - warn.offset_top = -UIScale.px(18) - warn.offset_bottom = -UIScale.px(1) - warn.add_theme_font_size_override("font_size", UIScale.small_font_size()) - warn.add_theme_color_override("font_color", theme_color("warning")) - warn.add_theme_color_override("font_outline_color", theme_color("badge_outline")) - warn.add_theme_constant_override("outline_size", UIScale.px(3)) - warn.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER - warn.mouse_filter = Control.MOUSE_FILTER_IGNORE - tr.add_child(warn) - return btn - - -## Fehlendes Modell (U4): nur Katalog-Objekte MIT glb-Eintrag können fehlen; -## kuratierte Primitive (ohne glb) bauen ihren Platzhalter lokal — nie „fehlt". -func _tile_is_missing(oid: String, entry: Dictionary) -> bool: - if str(entry.get("glb", "")).is_empty(): - return false - return GlbMeshStore.fehlt(oid) - - -## Hover (U4): die ID wird GRÖSSER, beim Verlassen wieder normal. -func _on_tile_hover(oid: String, entered: bool) -> void: - _set_tile_hover(oid, entered) - - -func _set_tile_hover(oid: String, on: bool) -> void: - var btn := _tile_button(oid) - if btn == null: - return - var id_lbl := _find_id_label(btn) - if id_lbl == null: - return - # U7-Raster: Hover-Stufe ist die Body-Schrift (klein → body), kein Wert ins Freie. - id_lbl.add_theme_font_size_override("font_size", - UIScale.font_size() if on else _id_font_normal) - - -func _tile_button(oid: String) -> Button: - if library_buttons.has(oid): - return library_buttons[oid] as Button - if _recent_tiles.has(oid): - return _recent_tiles[oid] as Button - return null - - -func _find_id_label(btn: Button) -> Label: - var stack: Array = [btn] - while not stack.is_empty(): - var node: Node = stack.pop_back() - if node is Label and (node as Label).has_meta("tile_id_label"): - return node as Label - for c in node.get_children(): - stack.push_back(c) - return null - - -# --------------------------------------------------- Klick / Doppelklick ---- - -## Klick = auswählen (U4). Das Platzieren selbst startet NICHT mehr hier — -## das übernimmt der Doppelklick (bzw. U5 das Einmal-Platzieren). -func _on_tile_pressed(oid: String) -> void: - _select_tile(oid) - - -## Doppelklick = „gesetzt" haken: Werkzeug startet wie bisher (U4-Vertrag; -## das Einmal-Platzieren kommt in U5). -func _on_tile_gui_input(event: InputEvent, oid: String) -> void: - if event is InputEventMouseButton and event.pressed \ - and event.button_index == MOUSE_BUTTON_LEFT and event.double_click: - _activate_tile(oid) - - -## Ziehen-Start einer Kachel: Vorschau-Etikett an der Maus, Daten = Objekt-ID. -func _tile_drag_data(_at_position: Vector2, oid: String, btn: Button) -> Variant: - if main.doc.is_empty(): - return null - _select_tile(oid) - _drag_oid = oid - var prev := PanelContainer.new() - var box := HBoxContainer.new() - prev.add_child(box) - var tex := LibraryBrowser.load_thumb(oid) - if tex != null: - var tr := TextureRect.new() - tr.texture = tex - tr.custom_minimum_size = UIScale.v2(64, 64) - tr.expand_mode = TextureRect.EXPAND_IGNORE_SIZE - tr.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED - box.add_child(tr) - var lbl := Label.new() - lbl.text = LibraryBrowser.entry_label(oid, (main.manifest.get("objects", {}) as Dictionary).get(oid, {})) - box.add_child(lbl) - prev.modulate.a = 0.85 - btn.set_drag_preview(prev) # gehört in den Drag-Start: gui_is_dragging() ist hier noch false - return {"svr_oid": oid} - - -## Maus mit gezogener Kachel ÜBER der 3D-Ansicht: Platzier-Vorschau folgt der Maus. -func drag_hover(oid: String, viewport_pos: Vector2) -> void: - if str(main.get("tool_mode")) != "objects": - main.call("_set_tool_mode", "objects") - if not (main.interaction.placing and main.interaction.place_oid == oid): - main.interaction.start_placement(oid) - _drag_started_placement = true - main.interaction._ghost_update(viewport_pos) - - -## Loslassen über der 3D-Ansicht: genau wie ein Setz-Klick. -func drag_drop(oid: String, viewport_pos: Vector2) -> void: - drag_hover(oid, viewport_pos) - main.interaction._place_object(viewport_pos, false) - if main.interaction.placing and not BauKatalog.ist_bau(oid): - main.interaction.cancel_placement() # daneben gezielt: Vorschau nicht hängen lassen - _drag_started_placement = false - _drag_oid = "" - - -func _notification(what: int) -> void: - if what != NOTIFICATION_DRAG_END or _drag_oid.is_empty(): - return - # Losgelassen ÜBER der Szene → drag_drop hat aufgeräumt. Sonst (abgebrochen, - # anderswo losgelassen) die Vorschau wieder wegnehmen. - if _drag_started_placement and main != null and main.interaction.placing: - main.interaction.cancel_placement() - _drag_started_placement = false - _drag_oid = "" - - -func _select_tile(oid: String) -> void: - var changed := selected_oid != oid - selected_oid = oid - _apply_tile_selection() - _record_recent(oid) - if changed: - object_selected.emit(oid) - - -## Doppelklick-Aktion: Werkzeug-Start 1:1 wie der alte Bibliotheks-Klick -## (interaction.start_placement, Auto-Rückwechsel auf Objekt-Werkzeug). -func _activate_tile(oid: String) -> void: - _select_tile(oid) - if str(main.get("tool_mode")) != "objects": - main.call("_set_tool_mode", "objects") # Bibliothek-Klick wechselt automatisch zurück - if main.interaction.placing and main.interaction.place_oid == oid: - # Nochmal (Doppel-)geklickt → Modus beenden (An/Aus ohne Umwege). - main.interaction.cancel_placement() - main.call("_set_status", "Platzieren abgebrochen.") - return - main.interaction.start_placement(oid) - object_activated.emit(oid) - - -## Auswahll-Marke je Kachel: ausgewählt = voll hell + Rahmen-Akzent. -func _apply_tile_selection() -> void: - for other_oid in library_buttons: - var btn := library_buttons[other_oid] as Button - btn.button_pressed = str(other_oid) == selected_oid - # U7: Auswahl-Markierung nur über Alpha (Farbe bleibt weiß). - btn.modulate.a = 1.0 if str(other_oid) == selected_oid else 0.85 - for recent_oid in _recent_tiles: - var rbtn := _recent_tiles[recent_oid] as Button - rbtn.button_pressed = str(recent_oid) == selected_oid - rbtn.modulate.a = 1.0 if str(recent_oid) == selected_oid else 0.85 - - -## Der Bibliotheks-Button des aktiven Platzier-Objekts leuchtet auf -## (Weitersenden von interaction.gd — nur Anzeige, KEIN Signal). -func highlight_library(oid: String) -> void: - selected_oid = oid - _apply_tile_selection() - if not oid.is_empty(): - _record_recent(oid) - - -# -------------------------------------------------------- Zuletzt benutzt ---- - -func _recent_load() -> Array: - var cfg := ConfigFile.new() - cfg.load("user://scopedvr_editor.cfg") - var raw: Variant = cfg.get_value(LIBRARY_CFG_SECTION, RECENT_CFG_KEY, []) - var lib: Dictionary = main.manifest.get("objects", {}) - var out: Array = [] - for v in (raw as Array): - var oid := str(v) - if lib.has(oid): # nur IDs, die es wirklich gibt - out.append(oid) - return out - - -func _recent_save() -> void: - var cfg := ConfigFile.new() - cfg.load("user://scopedvr_editor.cfg") - cfg.set_value(LIBRARY_CFG_SECTION, RECENT_CFG_KEY, _recent_ids) - cfg.save("user://scopedvr_editor.cfg") - - -## Auswahl/Benutzung merken (neueste zuerst, Ring mit RECENT_MAX Einträgen). -func _record_recent(oid: String) -> void: - if oid.is_empty(): - return - _recent_ids.erase(oid) - _recent_ids.insert(0, oid) - while _recent_ids.size() > RECENT_MAX: - _recent_ids.pop_back() - _recent_save() - _update_recent_chip() - if _cat_active == CAT_ZULETZT: - _fill_recent_box() - - -func _fill_recent_box() -> void: - if _recent_box == null: - return - for c in _recent_box.get_children(): - (c as Node).queue_free() - _recent_tiles.clear() - var head := Label.new() - head.text = "Zuletzt benutzt" - head.add_theme_font_size_override("font_size", UIScale.heading_font_size()) - head.add_theme_font_override("font", _library_header_font()) - _recent_box.add_child(head) - _recent_grid = GridContainer.new() - _recent_grid.columns = 2 - _recent_grid.size_flags_horizontal = Control.SIZE_EXPAND_FILL - _recent_grid.add_theme_constant_override("h_separation", UIScale.px(8)) # U7-Raster - _recent_grid.add_theme_constant_override("v_separation", UIScale.px(8)) # U7-Raster - _recent_box.add_child(_recent_grid) - var lib: Dictionary = main.manifest.get("objects", {}) - for oid in _recent_ids: - if not lib.has(str(oid)): - continue - var btn := _build_tile(str(oid)) - _recent_grid.add_child(btn) - _recent_tiles[str(oid)] = btn - if str(oid) == selected_oid: - btn.button_pressed = true - btn.modulate.a = 1.0 diff --git a/src/ui/panels/assets_panel.gd.uid b/src/ui/panels/assets_panel.gd.uid deleted file mode 100644 index 7153a42..0000000 --- a/src/ui/panels/assets_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dxoh6gjklwjna diff --git a/src/ui/panels/bauen_panel.gd b/src/ui/panels/bauen_panel.gd deleted file mode 100644 index 7b6e179..0000000 --- a/src/ui/panels/bauen_panel.gd +++ /dev/null @@ -1,118 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Bauen-Tab: Bauteile für eigene Gebäude (Fundament, Wände, Dach, Treppe). Fertige -## Pack-Objekte (Container, Hangar-Tore, Sperren …) gehören in die Objekt-Bibliothek -## unten, NICHT hierher. Ein Klick auf ein Teil startet -## das Platzieren (Vorschau rastet an Zelle/Kante/Ebene, siehe build_snap.gd); jedes -## gesetzte Teil ist ein normales Objekt und gehört zum laufenden Gebäude (Gruppe). -## Gebäude kopieren/löschen/auswählen läuft über die Knöpfe unten — alles Undo-fähig. - -var bau_buttons: Dictionary = {} # oid → Button -var info_label: Label -var geschoss_label: Label -var _group: ButtonGroup - - -static func spec() -> Dictionary: - return {"titel": "Bauen", "gruppe": "rechts", "order": 47} - - -func panel_title() -> String: - return "Bauen" - - -func build() -> void: - _group = ButtonGroup.new() - _group.allow_unpress = true - add_child(_muted_label("Wähle ein Teil und klicke in die Karte. Wände rasten an die nächste Zellkante, Böden und Dächer in die Zellmitte (Raster 2 m). Klick auf die Oberkante einer Wand stapelt das nächste Geschoss (oder Bild↑/Bild↓: festes Geschoss, dann sitzen Decken mitten im Raum), Klick auf die Seite ersetzt das Teil (z. B. Wand → Tür). R dreht, Esc beendet.")) - for gruppe in BauKatalog.GRUPPEN: - add_child(_field_label(str(gruppe["label"]))) - add_child(_knopf_raster(gruppe["oids"] as Array)) - add_child(_separator()) - add_child(_header_label("Höhe / Geschoss")) - geschoss_label = _muted_label(main.interaction.call("bau_geschoss_text")) - add_child(geschoss_label) - var hoehe := HBoxContainer.new() - hoehe.add_theme_constant_override("separation", UIScale.px(8)) - for spec in [["▲ Höher (Bild↑)", 1], ["▼ Tiefer (Bild↓)", -1]]: - var hb := _aktion(str(spec[0]), "Festes Geschoss wählen: Böden und Decken sitzen dann überall im Raum auf dieser Höhe (je 3 m). Ganz unten = automatisch.", - func() -> void: - main.interaction.call("bau_geschoss_aendern", int(spec[1])) - geschoss_label.text = main.interaction.call("bau_geschoss_text")) - hb.size_flags_horizontal = Control.SIZE_EXPAND_FILL - hoehe.add_child(hb) - add_child(hoehe) - add_child(_separator()) - add_child(_header_label("Gebäude")) - info_label = _muted_label("") - add_child(info_label) - add_child(_aktion("🏠 Neues Gebäude beginnen", "Das nächste Teil gehört zu einem neuen Gebäude (neue Gruppe).", - func() -> void: main.call("_bau_neues_gebaeude"))) - add_child(_aktion("🔲 Ganzes Gebäude auswählen", "Wählt alle Teile des Gebäudes, zu dem das markierte Teil gehört — zum Verschieben, Drehen, Kopieren.", - func() -> void: main.call("_bau_gebaeude_waehlen"))) - add_child(_aktion("📄 Gebäude kopieren", "Kopiert das ganze Gebäude als neues Gebäude (Strg+Z nimmt es zurück).", - func() -> void: main.call("_bau_gebaeude_kopieren"))) - add_child(_aktion("🗑 Gebäude löschen", "Löscht alle Teile des Gebäudes (Strg+Z holt es zurück).", - func() -> void: main.call("_bau_gebaeude_loeschen"))) - refresh_info() - wrap_in_scroll() - - -func _knopf_raster(oids: Array) -> GridContainer: - var grid := GridContainer.new() - grid.columns = 2 - grid.add_theme_constant_override("h_separation", UIScale.px(8)) - grid.add_theme_constant_override("v_separation", UIScale.px(8)) - var lib: Dictionary = main.manifest.get("objects", {}) - for oid in oids: - var btn := Button.new() - btn.toggle_mode = true - btn.button_group = _group - btn.custom_minimum_size = UIScale.v2(148, 44) - btn.clip_text = true - var poly := int((lib.get(oid, {}) as Dictionary).get("poly", 0)) - btn.text = BauKatalog.label(oid) - btn.tooltip_text = "%s — %s\n%d Dreiecke" % [BauKatalog.label(oid), - str((BauKatalog.KINDS[oid] as Dictionary).get("info", "")), poly] - btn.pressed.connect(_on_teil_gedrueckt.bind(str(oid), btn)) - bau_buttons[str(oid)] = btn - grid.add_child(btn) - return grid - - -func _aktion(text: String, tip: String, cb: Callable) -> Button: - var b := Button.new() - b.text = text - b.tooltip_text = tip - b.custom_minimum_size = UIScale.v2(0, 44) - b.pressed.connect(cb) - return b - - -func _on_teil_gedrueckt(oid: String, btn: Button) -> void: - if not btn.button_pressed: - main.interaction.call("cancel_placement") - return - main.call("_on_bauteil_gewaehlt", oid) - - -## Teil-Markierung an den laufenden Platzier-Zustand koppeln (Esc/Abbruch löst sie). -func sync_platzierung() -> void: - var aktiv := str(main.interaction.get("place_oid")) if bool(main.interaction.get("placing")) else "" - for oid in bau_buttons: - (bau_buttons[oid] as Button).set_pressed_no_signal(oid == aktiv) - - -## Info-Zeile: aktuelles Gebäude (Name, Teile, Dreiecke) bzw. Gesamtzahl. -func refresh_info() -> void: - if info_label == null or main == null or main.doc.is_empty(): - return - var gebaeude := BauOps.gebaeude_gruppen(main.doc) - if geschoss_label != null: - geschoss_label.text = main.interaction.call("bau_geschoss_text") - var text := "%d Gebäude, %d Bauteile in der Map." % [gebaeude.size(), BauOps.teile_zahl(main.doc)] - var gid := int(main.interaction.get("build_group_id")) - for g in gebaeude: - if int(g["gid"]) == gid: - text = "Aktuell: %s — %d Teile, %d Dreiecke.\n%s" % [g["name"], (g["indizes"] as Array).size(), int(g["dreiecke"]), text] - break - info_label.text = text diff --git a/src/ui/panels/bauen_panel.gd.uid b/src/ui/panels/bauen_panel.gd.uid deleted file mode 100644 index 60f27df..0000000 --- a/src/ui/panels/bauen_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ctxc87eisoda6 diff --git a/src/ui/panels/check_panel.gd b/src/ui/panels/check_panel.gd deleted file mode 100644 index 7f2c246..0000000 --- a/src/ui/panels/check_panel.gd +++ /dev/null @@ -1,176 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Spawn-Check + Spawn-Zonen-Werkzeug-Panel (aus main.gd ausgezogen, Karte -## t_eaccbfed U1 — Logik unverändert, Karte t_c4162c5d): Live-Validierung -## (Loader-Regeln, IMMER sichtbar) + großer Werkzeug-Button + Team/Radius/ -## Löschen. Werkzeug-Ein/Aus bleibt im Koordinator (main.gd). - -var spawn_edit_btn: Button -var spawn_panel: VBoxContainer -var spawn_team_blue: Button -var spawn_team_red: Button -var spawn_radius_slider: HSlider -var spawn_radius_label: Label -var spawn_status: Label # Live-Validierung (IMMER sichtbar, Loader-Regeln) -var spawn_sel_label: Label # Welche Zone ist an? -var spawn_delete_btn: Button -var spawn_yaw_row: HBoxContainer -var spawn_yaw_spin: SpinBox -var spawn_yaw_reset: Button - - -static func spec() -> Dictionary: - return {"titel": "Spawn-Zonen", "gruppe": "map", "order": 10} - - -func panel_title() -> String: - return "Prüfen" - - -## Bau (aus der alten main.gd/_build_right_panel übernommen, Logik identisch): -## Live-Status IMMER sichtbar + Werkzeug-Button + Bedien-Panel (Team/Radius/ -## Auswahl/Löschen). Ein/Aus des Werkzeugs bleibt beim Koordinator (main.gd). -func build() -> void: - add_child(_header_label("Spawn-Zonen")) - # --- Spawn-Zonen (Karte t_c4162c5d): Live-Status IMMER sichtbar --- - spawn_status = Label.new() - spawn_status.text = "" - spawn_status.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - spawn_status.custom_minimum_size = UIScale.v2(0, 44) - add_child(spawn_status) - - # --- Spawn-Zonen-Werkzeug: großer Button + Bedien-Panel --- - spawn_edit_btn = Button.new() - spawn_edit_btn.text = "🚩 Spawn-Zonen malen" - spawn_edit_btn.custom_minimum_size = UIScale.v2(0, 48) - spawn_edit_btn.toggle_mode = true - spawn_edit_btn.tooltip_text = "Startzonen für Team Blau und Rot auf den Boden malen (TDM)" - spawn_edit_btn.pressed.connect(_on_spawn_btn_pressed) - add_child(spawn_edit_btn) - - spawn_panel = VBoxContainer.new() - spawn_panel.add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster - spawn_panel.visible = false - add_child(spawn_panel) - - spawn_panel.add_child(_field_label("Team:")) - var team_row := HBoxContainer.new() - team_row.add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster - spawn_panel.add_child(team_row) - var team_group := ButtonGroup.new() - spawn_team_blue = _spawn_team_button("🔵 Team Blau", team_group, 0) - spawn_team_red = _spawn_team_button("🔴 Team Rot", team_group, 1) - spawn_team_blue.button_pressed = true - team_row.add_child(spawn_team_blue) - team_row.add_child(spawn_team_red) - - spawn_radius_label = _field_label("Zonen-Radius: 6 m") - spawn_panel.add_child(spawn_radius_label) - spawn_radius_slider = HSlider.new() - spawn_radius_slider.min_value = SpawnOps.MIN_ZONE_RADIUS - spawn_radius_slider.max_value = SpawnOps.MAX_ZONE_RADIUS - spawn_radius_slider.step = 1.0 - spawn_radius_slider.value = SpawnOps.DEFAULT_ZONE_RADIUS - spawn_radius_slider.custom_minimum_size = UIScale.v2(0, 32) - spawn_radius_slider.value_changed.connect(_on_spawn_radius_changed) - spawn_panel.add_child(spawn_radius_slider) - - spawn_sel_label = Label.new() - spawn_sel_label.text = "Keine Zone ausgewählt." - spawn_sel_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - spawn_panel.add_child(spawn_sel_label) - spawn_yaw_row = HBoxContainer.new() - spawn_yaw_row.add_theme_constant_override("separation", UIScale.px(8)) - spawn_yaw_row.add_child(_field_label("Blickrichtung °")) - spawn_yaw_spin = SpinBox.new() - spawn_yaw_spin.min_value = 0.0 - spawn_yaw_spin.max_value = 359.0 - spawn_yaw_spin.step = 1.0 - spawn_yaw_spin.tooltip_text = "Wohin Spieler und Bots hier beim Spawnen schauen. Geht auch im Bild: Pfeilspitze ziehen." - spawn_yaw_spin.size_flags_horizontal = Control.SIZE_EXPAND_FILL - spawn_yaw_spin.value_changed.connect(_on_spawn_yaw_changed) - spawn_yaw_row.add_child(spawn_yaw_spin) - spawn_yaw_reset = Button.new() - spawn_yaw_reset.text = "Standard" - spawn_yaw_reset.tooltip_text = "Keine feste Richtung: Spieler schauen zur Kartenmitte, Bots zum Gegner (grauer Pfeil)" - spawn_yaw_reset.pressed.connect(func() -> void: main.spawn_tool.call("set_selected_yaw", null)) - spawn_yaw_row.add_child(spawn_yaw_reset) - spawn_panel.add_child(spawn_yaw_row) - spawn_delete_btn = Button.new() - spawn_delete_btn.text = "Zone löschen (Entf)" - spawn_delete_btn.custom_minimum_size = UIScale.v2(0, 40) - spawn_delete_btn.tooltip_text = "Die ausgewählte Spawn-Zone löschen (Strg+Z holt sie zurück)" - spawn_delete_btn.pressed.connect(_on_spawn_delete_pressed) - spawn_panel.add_child(spawn_delete_btn) - - - -func _spawn_team_button(text: String, group: ButtonGroup, team: int) -> Button: - var btn := Button.new() - btn.text = text - btn.toggle_mode = true - btn.button_group = group - btn.custom_minimum_size = UIScale.v2(0, 40) - # U7: Werkzeugname im Tooltip (Team, in das neue Zonen gemalt werden). - btn.tooltip_text = "Zonen für %s malen" % ("Team Blau" if team == 0 else "Team Rot") - btn.pressed.connect(_on_spawn_team_changed.bind(team)) - return btn - - -func _on_spawn_btn_pressed() -> void: - if spawn_edit_btn.button_pressed: - main.call("_set_tool_mode", "spawns") - else: - main.call("_set_tool_mode", "objects") - - -func _selected_spawn_team() -> int: - return 1 if spawn_team_red.button_pressed else 0 - - -func _on_spawn_team_changed(team: int) -> void: - if main.spawn_tool != null and str(main.get("tool_mode")) == "spawns": - main.spawn_tool.call("set_team", team) - - -func _on_spawn_radius_changed(value: float) -> void: - spawn_radius_label.text = "Zonen-Radius: %d m" % int(value) - if main.spawn_tool != null and str(main.get("tool_mode")) == "spawns": - main.spawn_tool.call("set_radius", value) - - -func _on_spawn_yaw_changed(value: float) -> void: - if str(main.get("tool_mode")) == "spawns": - main.spawn_tool.call("set_selected_yaw", value) - - -func _on_spawn_delete_pressed() -> void: - if str(main.get("tool_mode")) == "spawns": - main.spawn_tool.call("delete_selected") - - -## Panel-Zeile „Welche Zone ist angewählt?“ — WIRD vom Spawn-Tool gerufen. -func sync_spawn_selection() -> void: - if main.spawn_tool == null: - return - var team: int = main.spawn_tool.get("selected_team") - var pid: String = str(main.spawn_tool.get("selected_id")) - if team < 0 or pid == "": - spawn_sel_label.text = "Keine Zone ausgewählt.\nKlicke im Viewport auf einen Kreis." - spawn_delete_btn.disabled = true - spawn_yaw_row.visible = false - return - spawn_yaw_row.visible = true - for p in SpawnOps.points(main.doc, team): - if p is Dictionary and str(p.get("id", "")) == pid: - spawn_yaw_spin.set_value_no_signal(SpawnOps.effective_yaw(main.doc, p)) - spawn_yaw_reset.disabled = not SpawnOps.has_yaw(p) - spawn_sel_label.text = "Ausgewählt: %s (%s)\nVerschieben: klicken+ziehen · Radius: Regler oben" % [ - pid, SpawnOps.team_label(team)] - spawn_delete_btn.disabled = false - - -## LIVE-Validierung (Loader-Regeln) — immer sichtbar, nach JEDEM Struktur-Wechsel. -func refresh_spawn_status() -> void: - if main.doc.is_empty() or spawn_status == null: - return - spawn_status.text = SpawnOps.live_status(main.doc, main.manifest) diff --git a/src/ui/panels/check_panel.gd.uid b/src/ui/panels/check_panel.gd.uid deleted file mode 100644 index 6e2389a..0000000 --- a/src/ui/panels/check_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b84fxjtuhejui diff --git a/src/ui/panels/editor_panel.gd b/src/ui/panels/editor_panel.gd deleted file mode 100644 index 8fe4b70..0000000 --- a/src/ui/panels/editor_panel.gd +++ /dev/null @@ -1,89 +0,0 @@ -extends VBoxContainer -class_name EditorPanel - -## Basis-Klasse aller Registry-Panels (Karte t_eaccbfed). Jedes Modul baut -## seinen eigenen Inhalt in setup(main) und wird von main.gd NUR über die -## Registry (src/ui/panels/registry.gd) in den Baum gehängt — main.gd kennt -## keine Panel-Interna mehr. -## -## Datenfluss (bewusst 1:1 wie vorher): Module greifen über `main` auf das -## Dokument/History/Werkzeuge zu und rufen die Koordinator-Helfer über -## main.call(...) — der Aufruf-Vertrag zu den Tools (interaction.gd etc.) -## bleibt unverändert, die Methoden wohnen jetzt nur in den Modulen. - -var main # src/ui/main.gd (script-erweitert → untypisiert) - - -func setup(p_main) -> void: - main = p_main - # U7-Abstands-Raster (4/8 px, über ui_scale skaliert): Panel-Grundabstand. - add_theme_constant_override("separation", UIScale.px(8)) - - -## Titel der Sektions-Überschrift (Registry-Titel als Default). -func panel_title() -> String: - return "Panel" - - -## Lange Tabs (Map, Bauen): den ganzen Inhalt in einen senkrechten Scroll-Bereich -## legen, damit die rechte Spalte nicht mit dem Inhalt wächst. Rückgabe = die -## innere Box (dort hängen spätere Abschnitte an). -func wrap_in_scroll() -> VBoxContainer: - var scroll := ScrollContainer.new() - scroll.name = "%sScroll" % name - scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL - scroll.size_flags_horizontal = Control.SIZE_EXPAND_FILL - scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED - var inner := VBoxContainer.new() - inner.name = "%sInhalt" % name - inner.size_flags_horizontal = Control.SIZE_EXPAND_FILL - inner.add_theme_constant_override("separation", UIScale.px(8)) - for child in get_children(): - remove_child(child) - inner.add_child(child) - scroll.add_child(inner) - add_child(scroll) - return inner - - -# --- Farb-Zugriff NUR über das Theme (Karte t_2336c58e/U7) ------------------ -## Farben kommen ausschließlich aus theme/editor_theme.tres (Abschnitt -## Editor/colors/…) — keine Farbwerte mehr im Panel-Code. Der Wert liest -## sich vom angeschlossenen Theme-Baum (main hängt theme auf das Fenster). - -func theme_color(cname: String) -> Color: - # Befund 25.10. („Texte kaum lesbar“): Panels werden gebaut, BEVOR sie im - # Baum hängen — get_theme_color liefert dort Schwarz statt der Theme-Farbe. - # Darum direkt aus dem Theme des Hauptfensters lesen. - if main != null and main.theme != null and main.theme.has_color(cname, "Editor"): - return main.theme.get_color(cname, "Editor") - return get_theme_color(cname, "Editor") - - -# --- Gemeinsame Bau-Helfer (aus main.gd übernommen, Logik identisch) -------- - -func _header_label(text: String) -> Label: - var label := Label.new() - label.text = text - label.add_theme_font_size_override("font_size", UIScale.heading_font_size()) - label.add_theme_color_override("font_color", theme_color("accent")) - return label - - -func _field_label(text: String) -> Label: - var label := Label.new() - label.text = text - label.add_theme_color_override("font_color", theme_color("field")) - return label - - -func _muted_label(text: String) -> Label: - var label := Label.new() - label.text = text - label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - label.add_theme_color_override("font_color", theme_color("muted")) - return label - - -func _separator() -> HSeparator: - return HSeparator.new() diff --git a/src/ui/panels/editor_panel.gd.uid b/src/ui/panels/editor_panel.gd.uid deleted file mode 100644 index 902fabd..0000000 --- a/src/ui/panels/editor_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cu0oq4cx0oy60 diff --git a/src/ui/panels/loadout_panel.gd b/src/ui/panels/loadout_panel.gd deleted file mode 100644 index 7ff3e46..0000000 --- a/src/ui/panels/loadout_panel.gd +++ /dev/null @@ -1,329 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Loadout-Bereich im Map-Tab (Karte „Loadout pro Map"): pro Map wählbar, ob die -## Spieler ihr eigenes Lobby-Loadout mitbringen oder die Map ein festes Loadout -## (Primär-/Sekundärwaffe + Aufsätze) vorschreibt. Gespeichert als optionaler -## Block doc["loadout"] (Regeln: core/svmap/loadout_katalog.gd, V18). Der Server -## setzt ein festes Loadout durch, der Client zeigt es an. In beiden Modi lässt -## sich zusätzlich der Granaten-/Minen-Vorrat pro Leben festlegen (auch für Bots). -## -## Jede Änderung ist ein Undo-Schritt (History-Block "loadout"; fehlt der Block, -## ist das Spieler-Loadout gemeint). - -const KEINE := "" - -var mode_option: OptionButton -var primary_option: OptionButton -var secondary_option: OptionButton -var fixed_box: VBoxContainer -var attach_box: VBoxContainer -var hint_label: Label -var vorrat_check: CheckBox -var vorrat_box: VBoxContainer -var granaten_spins: Dictionary = {} # Granaten-ID -> SpinBox -var minen_spin: SpinBox - -var _loading := false -var _ids: Array[String] = [] - - -static func spec() -> Dictionary: - return {"titel": "Loadout", "gruppe": "map", "order": 25} - - -func panel_title() -> String: - return "Loadout" - - -func build() -> void: - add_child(_header_label("Loadout")) - add_child(_muted_label("Legt fest, mit welchen Waffen die Spieler diese Karte spielen.")) - - mode_option = OptionButton.new() - mode_option.tooltip_text = "Eigenes Loadout: Spieler nehmen ihre Auswahl aus der Lobby mit. Festes Loadout: alle bekommen genau diese Waffen, der Server setzt das durch." - mode_option.add_item("Eigenes Loadout der Spieler (Lobby)") - mode_option.add_item("Festes Map-Loadout") - add_child(mode_option) - - fixed_box = VBoxContainer.new() - fixed_box.add_theme_constant_override("separation", UIScale.px(8)) - add_child(fixed_box) - - fixed_box.add_child(_field_label("Primärwaffe (Rücken)")) - primary_option = OptionButton.new() - fixed_box.add_child(primary_option) - fixed_box.add_child(_field_label("Sekundärwaffe (Hüfte)")) - secondary_option = OptionButton.new() - fixed_box.add_child(secondary_option) - - _ids = LoadoutKatalog.waffen_ids() - for id in _ids: - primary_option.add_item(LoadoutKatalog.anzeigename(id)) - secondary_option.add_item(LoadoutKatalog.anzeigename(id)) - secondary_option.add_item("— keine —") - - attach_box = VBoxContainer.new() - attach_box.add_theme_constant_override("separation", UIScale.px(6)) - fixed_box.add_child(attach_box) - - hint_label = _muted_label("Messer bleiben unverändert.") - fixed_box.add_child(hint_label) - - add_child(_header_label("Granaten und Minen")) - vorrat_check = CheckBox.new() - vorrat_check.text = "Anzahl für diese Karte festlegen" - vorrat_check.tooltip_text = "Aus: es gilt der Standard des Servers. An: Spieler und Bots bekommen pro Leben genau diese Anzahl." - vorrat_check.toggled.connect(func(an: bool) -> void: - if not _loading: - set_vorrat_aktiv(an)) - add_child(vorrat_check) - vorrat_box = VBoxContainer.new() - vorrat_box.add_theme_constant_override("separation", UIScale.px(6)) - add_child(vorrat_box) - for gid in LoadoutKatalog.GRANATEN_PANEL: - var spin := _anzahl_zeile(str(LoadoutKatalog.GRANATEN[gid]), LoadoutKatalog.MAX_GRANATEN_JE_ART) - spin.value_changed.connect(func(v: float) -> void: - if not _loading: - set_granaten(gid, int(v))) - granaten_spins[gid] = spin - minen_spin = _anzahl_zeile("Minen", LoadoutKatalog.MAX_MINEN) - minen_spin.value_changed.connect(func(v: float) -> void: - if not _loading: - set_minen(int(v))) - - mode_option.item_selected.connect(func(i: int) -> void: set_fixed(i == 1)) - primary_option.item_selected.connect(func(i: int) -> void: - set_weapons(_ids[i], _secondary_id())) - secondary_option.item_selected.connect(func(_i: int) -> void: - set_weapons(_primary_id(), _secondary_id())) - refresh_values() - - -func _anzahl_zeile(titel: String, max_n: int) -> SpinBox: - var row := HBoxContainer.new() - var lab := _field_label(titel) - lab.size_flags_horizontal = Control.SIZE_EXPAND_FILL - row.add_child(lab) - var spin := SpinBox.new() - spin.min_value = 0 - spin.max_value = max_n - spin.step = 1 - row.add_child(spin) - vorrat_box.add_child(row) - return spin - - -# ------------------------------------------------------------- Lesen ------- - -func _primary_id() -> String: - return _ids[primary_option.selected] if primary_option.selected >= 0 else "" - - -func _secondary_id() -> String: - var i := secondary_option.selected - return _ids[i] if i >= 0 and i < _ids.size() else KEINE - - -func current() -> Dictionary: - return main.doc.get("loadout", {}) if main != null and not main.doc.is_empty() else {} - - -func is_fixed() -> bool: - return str(current().get("mode", LoadoutKatalog.MODE_PLAYER)) == LoadoutKatalog.MODE_FIXED - - -# ------------------------------------------------------------- Ändern ------ - -## Modus wechseln. Auf „fest" ohne vorherige Wahl: M40 + Pistole 1 als Start. -func set_fixed(fixed: bool) -> void: - if main.doc.is_empty(): - return - if not fixed: - _commit(_nur_vorrat(current()), "Loadout: Spieler-Loadout") - return - var cur := current() - if cur.get("mode", "") == LoadoutKatalog.MODE_FIXED: - return - var prim := "m40" if LoadoutKatalog.hat_waffe("m40") else (_ids[0] if not _ids.is_empty() else "") - var sec := "pistol1" if LoadoutKatalog.hat_waffe("pistol1") else KEINE - var neu := {"mode": LoadoutKatalog.MODE_FIXED, "primary": prim, "secondary": sec, "attachments": {}} - var vorrat: Variant = _nur_vorrat(cur) - if vorrat != null: - neu.merge(vorrat as Dictionary, false) - _commit(neu, "Loadout: festes Map-Loadout") - - -## Spieler-Loadout mit Vorrat bleibt als Block erhalten; ohne Vorrat kein Block. -func _nur_vorrat(lo: Dictionary) -> Variant: - if not lo.has("grenades") and not lo.has("mines"): - return null - var out := {"mode": LoadoutKatalog.MODE_PLAYER} - for key in ["grenades", "mines"]: - if lo.has(key): - out[key] = lo[key] - return out - - -func hat_vorrat() -> bool: - return current().has("grenades") or current().has("mines") - - -## Vorrat festlegen (Start = Server-Standard) oder wieder dem Server überlassen. -func set_vorrat_aktiv(an: bool) -> void: - if main.doc.is_empty() or an == hat_vorrat(): - return - var lo := current().duplicate(true) - if an: - if lo.is_empty(): - lo["mode"] = LoadoutKatalog.MODE_PLAYER - lo["grenades"] = {"he1": 1, "blend1": 1, "smoke1": 1} - lo["mines"] = LoadoutKatalog.STANDARD_MINEN - _commit(lo, "Loadout: Granaten und Minen festgelegt") - return - lo.erase("grenades") - lo.erase("mines") - var leer := str(lo.get("mode", LoadoutKatalog.MODE_PLAYER)) == LoadoutKatalog.MODE_PLAYER - _commit(null if leer else lo, "Loadout: Granaten und Minen wie Server") - - -func set_granaten(gid: String, anzahl: int) -> void: - if main.doc.is_empty() or not hat_vorrat() or not LoadoutKatalog.GRANATEN.has(gid): - return - var lo := current().duplicate(true) - var g: Dictionary = lo.get("grenades", {}) - if anzahl > 0: - g[gid] = clampi(anzahl, 0, LoadoutKatalog.MAX_GRANATEN_JE_ART) - else: - g.erase(gid) - lo["grenades"] = g - _commit(lo, "Loadout: %s" % str(LoadoutKatalog.GRANATEN[gid])) - - -func set_minen(anzahl: int) -> void: - if main.doc.is_empty() or not hat_vorrat(): - return - var lo := current().duplicate(true) - lo["mines"] = clampi(anzahl, 0, LoadoutKatalog.MAX_MINEN) - _commit(lo, "Loadout: Minen") - - -## Waffen setzen. Aufsätze von Waffen, die nicht mehr im Loadout sind, fallen weg. -func set_weapons(primary: String, secondary: String) -> void: - if main.doc.is_empty() or not is_fixed(): - return - if not LoadoutKatalog.hat_waffe(primary) or (secondary != KEINE and not LoadoutKatalog.hat_waffe(secondary)): - return - var lo := current().duplicate(true) - lo["primary"] = primary - lo["secondary"] = secondary - var att: Dictionary = lo.get("attachments", {}) - for w in att.keys(): - if w != primary and w != secondary: - att.erase(w) - lo["attachments"] = att - _commit(lo, "Loadout: %s / %s" % [LoadoutKatalog.anzeigename(primary), - LoadoutKatalog.anzeigename(secondary) if secondary != KEINE else "keine"]) - - -## Ein Aufsatz-Slot einer Loadout-Waffe setzen (part = Teil-ID, "" = nichts). -func set_part(weapon: String, slot: String, part: String) -> void: - if main.doc.is_empty() or not is_fixed(): - return - var lo := current().duplicate(true) - if weapon != str(lo.get("primary", "")) and weapon != str(lo.get("secondary", "")): - return - var att: Dictionary = lo.get("attachments", {}) - var sel := LoadoutKatalog.auswahl(weapon, str(att.get(weapon, ""))) - if not sel.has(slot): - return - sel[slot] = part - var wire := LoadoutKatalog.encode(weapon, sel) - if LoadoutKatalog.pruefe_aufsaetze(weapon, wire) != "": - return - if wire.is_empty(): - att.erase(weapon) - else: - att[weapon] = wire - lo["attachments"] = att - _commit(lo, "Loadout: Aufsatz %s" % slot) - - -func _commit(neu: Variant, text: String) -> void: - var alt: Variant = main.doc.get("loadout", null) - if alt != null: - alt = (alt as Dictionary).duplicate(true) - if neu == null: - main.doc.erase("loadout") - else: - main.doc["loadout"] = (neu as Dictionary).duplicate(true) - var danach: Variant = main.doc.get("loadout", null) - if danach != null: - danach = (danach as Dictionary).duplicate(true) - if alt == danach: - return - main.history.commit(text, {"loadout": alt}, {"loadout": danach}) - main.dirty = true - main.call("_refresh_file_label") - main.call("_refresh_history_buttons") - refresh_values() - main.call("_set_status", "%s." % text) - - -# ------------------------------------------------------------ Anzeige ------ - -## UI aus dem doc auffüllen (Laden, Undo/Redo) — löst keinen Schreibzugriff aus. -func refresh_values() -> void: - if mode_option == null or main == null: - return - _loading = true - var lo := current() - var fixed := is_fixed() - mode_option.select(1 if fixed else 0) - fixed_box.visible = fixed - if fixed: - var prim := str(lo.get("primary", "")) - var sec := str(lo.get("secondary", "")) - primary_option.select(maxi(0, _ids.find(prim))) - secondary_option.select(_ids.find(sec) if sec != KEINE and _ids.has(sec) else _ids.size()) - _rebuild_attachments(prim, sec, lo.get("attachments", {})) - var vorrat := hat_vorrat() - vorrat_check.button_pressed = vorrat - vorrat_box.visible = vorrat - for gid in granaten_spins: - (granaten_spins[gid] as SpinBox).value = int((lo.get("grenades", {}) as Dictionary).get(gid, 0)) - minen_spin.value = int(lo.get("mines", LoadoutKatalog.STANDARD_MINEN)) - _loading = false - - -func _rebuild_attachments(prim: String, sec: String, att: Dictionary) -> void: - for c in attach_box.get_children(): - attach_box.remove_child(c) - c.queue_free() - for w in [prim, sec]: - if w == "" or LoadoutKatalog.slots(w).is_empty(): - continue - attach_box.add_child(_header_label("Aufsätze: %s" % LoadoutKatalog.anzeigename(w))) - var sel := LoadoutKatalog.auswahl(w, str(att.get(w, ""))) - var sl := LoadoutKatalog.slots(w) - var slot_names: Array = sl.keys() - slot_names.sort() - for s in slot_names: - var sd: Dictionary = sl[s] - var row := HBoxContainer.new() - var lab := _field_label(str(s).replace("_", " ")) - lab.custom_minimum_size = UIScale.v2(90, 0) - row.add_child(lab) - var ob := OptionButton.new() - ob.name = "Teil_%s_%s" % [w, s] - ob.size_flags_horizontal = Control.SIZE_EXPAND_FILL - var parts: Array = [] - if bool(sd.get("optional", false)): - parts.append("") - parts.append_array(sd.get("options", [])) - for p in parts: - ob.add_item(LoadoutKatalog.teil_name(str(p))) - ob.select(maxi(0, parts.find(sel.get(s, "")))) - ob.item_selected.connect(func(i: int) -> void: - if not _loading: - set_part(w, str(s), str(parts[i]))) - row.add_child(ob) - attach_box.add_child(row) diff --git a/src/ui/panels/loadout_panel.gd.uid b/src/ui/panels/loadout_panel.gd.uid deleted file mode 100644 index dfc7fac..0000000 --- a/src/ui/panels/loadout_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://t00n1cb8be2w diff --git a/src/ui/panels/malen_panel.gd b/src/ui/panels/malen_panel.gd deleted file mode 100644 index a755dc8..0000000 --- a/src/ui/panels/malen_panel.gd +++ /dev/null @@ -1,170 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Malen-Tab (25.10., UI-Aufräumen): Material-Palette mit Vorschau-Kacheln, -## Pinselgröße und Kante. Malen ist technisch weiter der Pinsel-Modus PAINT des -## Terrain-Werkzeugs (terrain_tool.gd) — die Mode-Buttons und die Pinsel-Logik -## wohnen in terrain_panel.gd, dieses Panel hält nur die Mal-Widgets. main.gd -## reicht die Felder unter den alten Namen (terrain_palette …) weiter. - -const ARRAYS_PATH := "res://assets/textures/terrain/terrain_arrays.res" -const MATERIAL_NAMES: Array[String] = [ - "Steppe", "Sand", "Fels", "Sattgras", "Vertrocknet", "Moos", "Erde", - "Pfad", "Umgegraben", "Schotter", "Lehm", "Sand hell", "Sand rost", - "Basalt", "Geröll", "Schlamm", "Schnee", "Matschschnee", "Asche", "Stoppeln", -] - -var malen_edit_btn: Button -var malen_panel: VBoxContainer -var palette: VBoxContainer -var mat_buttons: Array = [] -var radius_label: Label -var radius_slider: HSlider -var weich_label: Label -var weich_slider: HSlider -var paint_hint: Label -var _syncing := false - - -static func spec() -> Dictionary: - return {"titel": "Malen", "gruppe": "rechts", "order": 45} - - -func panel_title() -> String: - return "Malen" - - -func build() -> void: - malen_edit_btn = Button.new() - malen_edit_btn.text = "🖌 Malen" - malen_edit_btn.custom_minimum_size = UIScale.v2(0, 48) - malen_edit_btn.toggle_mode = true - malen_edit_btn.tooltip_text = "Material auf den Boden malen (Taste 4)" - malen_edit_btn.pressed.connect(_on_malen_btn_pressed) - add_child(malen_edit_btn) - - malen_panel = VBoxContainer.new() - malen_panel.add_theme_constant_override("separation", UIScale.px(8)) - add_child(malen_panel) - - palette = VBoxContainer.new() - palette.add_theme_constant_override("separation", UIScale.px(4)) - palette.visible = false - malen_panel.add_child(palette) - palette.add_child(_field_label("Material:")) - var grid := GridContainer.new() - grid.columns = 3 - grid.size_flags_horizontal = Control.SIZE_EXPAND_FILL - grid.add_theme_constant_override("h_separation", UIScale.px(6)) - grid.add_theme_constant_override("v_separation", UIScale.px(6)) - var scroll := ScrollContainer.new() - scroll.custom_minimum_size = UIScale.v2(0, 340) - scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL - scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED - grid.size_flags_horizontal = Control.SIZE_EXPAND_FILL - scroll.add_child(grid) - palette.add_child(scroll) - var previews := _material_previews() - var group := ButtonGroup.new() - for mat_id in SvmapIO.MATERIAL_IDS.size(): - var btn := Button.new() - btn.text = MATERIAL_NAMES[mat_id] if mat_id < MATERIAL_NAMES.size() else str(SvmapIO.MATERIAL_IDS[mat_id]) - btn.custom_minimum_size = UIScale.v2(92, 104) - btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL - btn.toggle_mode = true - btn.button_group = group - btn.clip_text = true - btn.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER - btn.vertical_icon_alignment = VERTICAL_ALIGNMENT_TOP - btn.expand_icon = true - btn.add_theme_constant_override("icon_max_width", UIScale.px(76)) - if mat_id < previews.size() and previews[mat_id] != null: - btn.icon = previews[mat_id] - btn.tooltip_text = "Malen: %s" % btn.text - if mat_id == 0: - btn.button_pressed = true - btn.toggled.connect(_on_material_changed.bind(mat_id)) - mat_buttons.append(btn) - grid.add_child(btn) - - radius_label = _field_label("Pinsel-Größe: 12 m") - malen_panel.add_child(radius_label) - radius_slider = HSlider.new() - radius_slider.min_value = 1.0 - radius_slider.max_value = 64.0 - radius_slider.step = 1.0 - radius_slider.value = 12.0 - radius_slider.custom_minimum_size = UIScale.v2(0, 32) - radius_slider.value_changed.connect(_on_radius_changed) - malen_panel.add_child(radius_slider) - - weich_label = _field_label("Kante: 40 % weich") - malen_panel.add_child(weich_label) - weich_slider = HSlider.new() - weich_slider.min_value = 0.0 - weich_slider.max_value = 100.0 - weich_slider.step = 5.0 - weich_slider.value = 40.0 - weich_slider.custom_minimum_size = UIScale.v2(0, 32) - weich_slider.tooltip_text = "Links = harte Kante, rechts = weicher Übergang" - weich_slider.value_changed.connect(_on_weich_changed) - malen_panel.add_child(weich_slider) - - paint_hint = _muted_label("") - malen_panel.add_child(paint_hint) - - -## Vorschaubilder der 20 Materialien aus dem Textur-Array (Albedo-Layer). -## Fehlt das Array oder ein Layer: Kachel bleibt ohne Bild (nie ein Absturz). -func _material_previews() -> Array: - var out: Array = [] - if not ResourceLoader.exists(ARRAYS_PATH): - return out - var arr = load(ARRAYS_PATH) - if arr == null or not ("albedo_images" in arr): - return out - for img in arr.albedo_images: - var tex: Texture2D = null - if img is Image and not (img as Image).is_empty(): - var copy: Image = (img as Image).duplicate() - if copy.is_compressed(): - copy.decompress() - copy.resize(96, 96, Image.INTERPOLATE_BILINEAR) - tex = ImageTexture.create_from_image(copy) - out.append(tex) - return out - - -func _on_malen_btn_pressed() -> void: - var t = main.terrain_mod - if malen_edit_btn.button_pressed: - t.terrain_mode_paint.button_pressed = true - main.call("_set_tool_mode", "terrain") - t.refresh_panels() - else: - main.call("_set_tool_mode", "objects") - - -func _on_material_changed(pressed: bool, mat_id: int) -> void: - if pressed and main.terrain_tool != null: - main.terrain_tool.call("set_paint_material", mat_id) - - -func _on_radius_changed(value: float) -> void: - radius_label.text = "Pinsel-Größe: %d m" % int(value) - if _syncing: - return - var t = main.terrain_mod - if t != null and t.terrain_radius_slider != null: - t.terrain_radius_slider.value = value # → set_radius über dessen Handler - - -## Terrain-Tab → Malen: Radius spiegeln, ohne Rückkopplung. -func set_radius_silent(value: float) -> void: - _syncing = true - radius_slider.value = value - _syncing = false - - -func _on_weich_changed(value: float) -> void: - weich_label.text = "Kante: %d %% weich" % int(value) if value > 0.0 else "Kante: hart" - if main.terrain_tool != null: - main.terrain_tool.call("set_weichheit", value / 100.0) diff --git a/src/ui/panels/malen_panel.gd.uid b/src/ui/panels/malen_panel.gd.uid deleted file mode 100644 index 12230fd..0000000 --- a/src/ui/panels/malen_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://1cuxg4r1bmls diff --git a/src/ui/panels/map_panel.gd b/src/ui/panels/map_panel.gd deleted file mode 100644 index 081cee4..0000000 --- a/src/ui/panels/map_panel.gd +++ /dev/null @@ -1,264 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Map-Eigenschaften (aus main.gd ausgezogen, Karte t_eaccbfed U1 — Logik -## unverändert): Name/Autor/Beschreibung/Version/Wetter + Terrain-Info. -## Eingaben schreiben LIVE ins doc (Live-Bindung wie vorher) und markieren -## dirty — die Signale wurden vorher in _build_right_panel verdrahtet, sie -## hängen jetzt hier. - -var prop_name: LineEdit -var prop_author: LineEdit -var prop_desc: LineEdit -var prop_version: SpinBox -var prop_weather: OptionButton -var prop_sky: OptionButton -var sky_preview: TextureRect # Vorschau der gewählten Skybox (obere Panorama-Hälfte) -var prop_water: HSlider -var terrain_info: Label - -var _sections: VBoxContainer # Inhalt des Map-Tabs (im Scroll-Bereich) -var _loading_ui_values := false # verhindert dirty beim Auffüllen der Felder - -## Karte t_28fdef03: Slider-Stellung für „Kein Wasser“ (Meta-Vertrag für -## Tests/Verdrahtung). Slider unterhalb davon (−10 m) = Wasser AUS — das doc- -## Feld wird dann ENTFERNT (Legacy-sauber, kein Wert 0 versehentlich gespeichert). -const KEIN_WASSER_WERT := -10.0 - - -static func spec() -> Dictionary: - return {"titel": "Map", "gruppe": "rechts", "order": 30} - - -func panel_title() -> String: - return "Map-Eigenschaften" - - -## Bau (aus der alten main.gd/_build_right_panel übernommen, Logik identisch): -## Name/Autor/Beschreibung/Version/Wetter + Terrain-Info. Die Signale hängen -## jetzt hier (statt in main.gd) — der doc-Datenfluss ist derselbe. -func build() -> void: - add_child(_field_label("Name")) - prop_name = LineEdit.new() - prop_name.max_length = 64 - add_child(prop_name) - - add_child(_field_label("Autor")) - prop_author = LineEdit.new() - add_child(prop_author) - - add_child(_field_label("Beschreibung")) - prop_desc = LineEdit.new() - add_child(prop_desc) - - add_child(_field_label("Version")) - prop_version = SpinBox.new() - prop_version.min_value = 1 - prop_version.max_value = 99999 - prop_version.step = 1 - add_child(prop_version) - - add_child(_field_label("Wetter")) - prop_weather = OptionButton.new() - # U7: Klartext-Tooltip am Wetter-Auswahlfeld. - prop_weather.tooltip_text = "Licht und Stimmung der Karte (Tag/Abend/Regen/Nacht)" - prop_weather.add_item("Mittag (sonnig, klar)") - prop_weather.add_item("Abend (warmes Licht)") - prop_weather.add_item("Regen (grau, kühl)") - prop_weather.add_item("Nacht (dunkel)") - add_child(prop_weather) - - add_child(_field_label("Himmel")) - prop_sky = OptionButton.new() - # Karte Atmosphäre/Skybox: Panorama-Skybox aus dem Pack als Map-Option. - prop_sky.tooltip_text = "Himmel der Karte: Prozedural (Standard, lässt die Karte unverändert) oder eine Skybox aus dem Katalog. Der Viewport zeigt sie sofort; Strg+Z macht die Wahl rückgängig." - prop_sky.add_item("Prozedural (Standard)") - for e in SkyboxKatalog.EINTRAEGE: - prop_sky.add_item(str(e["name"])) - add_child(prop_sky) - sky_preview = TextureRect.new() - sky_preview.custom_minimum_size = Vector2(0, 80) - sky_preview.expand_mode = TextureRect.EXPAND_IGNORE_SIZE - sky_preview.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_COVERED - sky_preview.tooltip_text = "Vorschau: oberer Teil der gewählten Skybox" - add_child(sky_preview) - - # Wasser (Karte t_28fdef03): Wasserhöhe der Map — Senken unter der Höhe - # füllen sich automatisch. Ganz links = „Kein Wasser“ (Feld entfernen, - # alte Maps unverändert). Die Live-Vorschau nutzt dasselbe Material wie - # der Client (SvmapWasser.make_material — Identitäts-Vertrag). - add_child(_field_label("Wasserhöhe")) - prop_water = HSlider.new() - prop_water.min_value = -10.0 - prop_water.max_value = 100.0 - prop_water.step = 0.25 - prop_water.value = KEIN_WASSER_WERT - prop_water.custom_minimum_size = UIScale.v2(0, 32) - prop_water.tooltip_text = "Wasser: ganz links = kein Wasser, sonst Höhe der Wasseroberfläche über dem Terrain. Senken unter dieser Höhe füllen sich mit Wasser." - prop_water.set_meta("kein_wasser_value", KEIN_WASSER_WERT) - add_child(prop_water) - - add_child(_separator()) - add_child(_header_label("Terrain")) - terrain_info = Label.new() - terrain_info.text = "" - terrain_info.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - add_child(terrain_info) - - # Signale (Änderungen → Dokument + Ansicht) — wie vorher in main.gd. - prop_name.text_changed.connect(_on_prop_changed.bind("name")) - prop_author.text_changed.connect(_on_prop_changed.bind("author")) - prop_desc.text_changed.connect(_on_prop_changed.bind("description")) - prop_version.value_changed.connect(_on_version_changed) - prop_weather.item_selected.connect(_on_weather_changed) - prop_sky.item_selected.connect(_on_sky_changed) - prop_water.value_changed.connect(_on_water_changed) - _sections = wrap_in_scroll() - - -## Hier hängen die Abschnitte der Registry-Gruppe "map" (Spawn-Zonen, Test-Start, -## Symmetrie) unter den Map-Eigenschaften. -func sections_host() -> Control: - return _sections - - -func _on_prop_changed(text: String, field: String) -> void: - if _loading_ui_values or main.doc.is_empty(): - return - var info: Dictionary = main.doc["info"] - match field: - "name": - info["name"] = text - "author": - info["author"] = text - "description": - info["description"] = text - main.dirty = true - main.call("_refresh_file_label") - - -func _on_version_changed(value: float) -> void: - if _loading_ui_values or main.doc.is_empty(): - return - main.doc["info"]["version"] = int(value) - main.dirty = true - main.call("_refresh_file_label") - - -func _on_weather_changed(index: int) -> void: - if _loading_ui_values or main.doc.is_empty(): - return - var weathers := ["mittag", "abend", "regen", "nacht"] - main.doc["weather"] = weathers[index] - main.dirty = true - main.call("_refresh_file_label") - # Licht/Stimmung im Viewport sofort anpassen - main.view_builder.call("rebuild", main.doc, main.manifest) - main.call("_sync_grid_to_builder") - main.call("_set_status", "Wetter geändert auf „%s“." % weathers[index]) - - -## Skybox-Auswahl: Eintrag → doc["weather_sky"] = Katalog-ID (ein Speicherfeld, -## checksum-neutral wie tint/gebaeude). „Prozedural (Standard)“ = Index 0 → Feld -## ENTFERNEN (alte Maps unverändert). Mit Undo/Redo (History-Block weather_sky). -## Sofort-Neuaufbau wie Wetter — der Viewport zeigt exakt, was der Client zeigt. -func _on_sky_changed(index: int) -> void: - if _loading_ui_values or main.doc.is_empty(): - return - var neu := "" if index <= 0 else str(SkyboxKatalog.EINTRAEGE[index - 1]["id"]) - var alt := str(main.doc.get("weather_sky", "")) - if neu == alt: - return - var before := {"weather_sky": (alt if main.doc.has("weather_sky") else null)} - if neu == "": - main.doc.erase("weather_sky") - else: - main.doc["weather_sky"] = neu - var after := {"weather_sky": (neu if neu != "" else null)} - var name := "Prozedural (Standard)" if neu == "" else str(SkyboxKatalog.eintrag(neu)["name"]) - main.history.commit("Himmel: %s" % name, before, after) - main.dirty = true - main.call("_refresh_file_label") - main.call("_refresh_history_buttons") - main.view_builder.call("rebuild", main.doc, main.manifest) - main.call("_sync_grid_to_builder") - _update_sky_preview(neu) - var hinweis := "" - if neu != "" and SkyboxKatalog.panorama_textur(neu) == null: - hinweis = " Achtung: Textur nicht gefunden (Client-Ordner neben dem Editor fehlt) — Vorschau zeigt den Standard-Himmel." - main.call("_set_status", "Himmel geändert auf „%s“.%s" % [name, hinweis]) - - -func _update_sky_preview(id: String) -> void: - sky_preview.texture = SkyboxKatalog.vorschau(id) if id != "" else null - sky_preview.visible = sky_preview.texture != null - - -## Wasser (Karte t_28fdef03): Slider → doc["water_level"]. Ganz links -## („Kein Wasser“, KEIN_WASSER_WERT) = Feld ENTFERNEN (Legacy-sauber). -## Sofort-Neuaufbau wie Wetter/Himmel — die Vorschau zeigt die Fläche live -## (dasselbe Material wie der Client). -func _on_water_changed(value: float) -> void: - if _loading_ui_values or main.doc.is_empty(): - return - if value <= KEIN_WASSER_WERT + 0.0001: - main.doc.erase("water_level") - main.call("_set_status", "Wasser entfernt (kein Wasser in dieser Karte).") - else: - var terrain: Dictionary = main.doc.get("terrain", {}) - var ok := true - if not terrain.is_empty(): - # Range-Bewacher (V20-Band): sinnlose Werte gar nicht erst - # ins doc schreiben — der Slider klemmt am Höhenbereich. - var hmin := float(terrain.get("min_height_m", -5.0)) - var hmax := float(terrain.get("max_height_m", 500.0)) - var geklemmt := clampf(value, hmin - 10.0, hmax + 10.0) - if geklemmt != value: - ok = false - value = geklemmt - prop_water.set_value_no_signal(geklemmt) - main.call("_set_status", "Wasserhöhe an den Terrain-Höhenbereich geklemmt (%.1f m)." % geklemmt) - if ok or value != KEIN_WASSER_WERT: - main.doc["water_level"] = value - main.dirty = true - main.call("_refresh_file_label") - main.view_builder.call("rebuild", main.doc, main.manifest) - main.call("_sync_grid_to_builder") - - -## Felder aus dem doc auffüllen (aus main.gd _refresh_all-Anfang ausgezogen). -func refresh_values() -> void: - _loading_ui_values = true - var info: Dictionary = main.doc.get("info", {}) - prop_name.text = str(info.get("name", "")) - prop_author.text = str(info.get("author", "")) - prop_desc.text = str(info.get("description", "")) - prop_version.value = float(info.get("version", 1)) - var weathers := ["mittag", "abend", "regen", "nacht"] - var weather := str(main.doc.get("weather", "mittag")) - prop_weather.select(maxi(0, weathers.find(weather))) - # Himmel: Auswahl ↔ doc["weather_sky"] (Katalog-ID; unbekannt/leer → Standard). - var sky_id := str(main.doc.get("weather_sky", "")) - var sky_idx := 0 - for i in SkyboxKatalog.EINTRAEGE.size(): - if SkyboxKatalog.EINTRAEGE[i]["id"] == sky_id: - sky_idx = i + 1 - prop_sky.select(sky_idx) - _update_sky_preview(sky_id if sky_idx > 0 else "") - - var terrain: Dictionary = main.doc.get("terrain", {}) - terrain_info.text = "Größe: %.0f × %.0f m\nAuflösung: %d × %d Höhenpunkte\nHöhenbereich: %.0f bis %.0f m" % [ - float(terrain.get("size_x_m", 0.0)), float(terrain.get("size_z_m", 0.0)), - int(terrain.get("resolution", 0)), - int(terrain.get("resolution", 0)), - float(terrain.get("min_height_m", 0.0)), float(terrain.get("max_height_m", 0.0))] - # Wasser (Karte t_28fdef03): Regler aus dem doc füllen (ohne dirty). - var wl: Variant = main.doc.get("water_level", null) - prop_water.set_value_no_signal( - float(wl) if (wl is float or wl is int) else KEIN_WASSER_WERT) - # Loadout-Bereich (Registry-Gruppe "map") aus dem doc nachziehen. - var modus_panel: Node = _sections.get_node_or_null("modus") if _sections != null else null - if modus_panel != null: - modus_panel.call("refresh_values") - var loadout_panel: Node = _sections.get_node_or_null("loadout") if _sections != null else null - if loadout_panel != null: - loadout_panel.call("refresh_values") - _loading_ui_values = false diff --git a/src/ui/panels/map_panel.gd.uid b/src/ui/panels/map_panel.gd.uid deleted file mode 100644 index 41e082d..0000000 --- a/src/ui/panels/map_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dihu04ppa406d diff --git a/src/ui/panels/modus_panel.gd b/src/ui/panels/modus_panel.gd deleted file mode 100644 index a012a89..0000000 --- a/src/ui/panels/modus_panel.gd +++ /dev/null @@ -1,413 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Spielmodus-Bereich im Map-Tab (28.10.): Modus der Map wählen (Team-Deathmatch / -## Conquest / King of the Hill / Deathmatch), Zonen bzw. Hills setzen und eigene -## Spawns je Modus anlegen. Zonen erscheinen als farbige Kreise im 3D-Bild. -## Gespeichert als optionale Felder doc["game_mode"], doc["conquest_zones"], -## doc["hills"], doc["mode_spawns"] (Regeln: core/svmap/modus_katalog.gd). -## -## Jede Änderung ist ein Undo-Schritt (History-Blöcke; fehlt ein Block, gilt der -## Standard: TDM, keine Zonen, keine eigenen Spawns). - -var mode_option: OptionButton -var cp_box: VBoxContainer # Zonen-/Hill-Bereich (nur Conquest und KotH) -var zones_title: Label -var rows_box: VBoxContainer -var add_button: Button -var hint_label: Label -var spawn_option: OptionButton # Spawn-Satz, der mit dem Spawn-Werkzeug bearbeitet wird -var spawn_create: Button -var spawn_remove: Button -var spawn_hint: Label - -var _loading := false - - -static func spec() -> Dictionary: - return {"titel": "Spielmodus", "gruppe": "map", "order": 22} - - -func panel_title() -> String: - return "Spielmodus" - - -func build() -> void: - add_child(_header_label("Spielmodus")) - add_child(_muted_label("Legt fest, wie auf dieser Karte gewonnen wird.")) - - mode_option = OptionButton.new() - mode_option.name = "ModusAuswahl" - mode_option.tooltip_text = "Team-Deathmatch: Kills zählen. Conquest: Teams nehmen mehrere Zonen ein. King of the Hill: ein Hill, der wandert. Deathmatch: alle gegen alle." - for m in ModusKatalog.MODES: - mode_option.add_item(ModusKatalog.MODE_LABELS[m]) - add_child(mode_option) - - cp_box = VBoxContainer.new() - cp_box.add_theme_constant_override("separation", UIScale.px(8)) - add_child(cp_box) - - zones_title = _field_label("Zonen") - cp_box.add_child(zones_title) - rows_box = VBoxContainer.new() - rows_box.add_theme_constant_override("separation", UIScale.px(6)) - cp_box.add_child(rows_box) - - add_button = Button.new() - add_button.name = "ZoneNeu" - add_button.text = "+ Zone in Bildmitte setzen" - add_button.tooltip_text = "Setzt eine neue Zone dorthin, wo die Kamera hinschaut. Position und Größe lassen sich darunter ändern." - cp_box.add_child(add_button) - - hint_label = _muted_label("Mindestens eine Zone nötig.") - cp_box.add_child(hint_label) - - # Spawns je Modus - add_child(_field_label("Spawns bearbeiten für")) - spawn_option = OptionButton.new() - spawn_option.name = "SpawnSatz" - spawn_option.tooltip_text = "Welche Spawn-Punkte das Spawn-Werkzeug gerade zeigt und ändert. Ohne eigene Spawns nutzt ein Modus die Basis-Spawns." - add_child(spawn_option) - spawn_create = Button.new() - spawn_create.name = "SpawnSatzNeu" - spawn_create.tooltip_text = "Legt eigene Spawn-Punkte für diesen Modus an (Kopie der Basis-Spawns) — danach mit dem Spawn-Werkzeug anpassen." - add_child(spawn_create) - spawn_remove = Button.new() - spawn_remove.name = "SpawnSatzWeg" - spawn_remove.text = "Eigene Spawns löschen" - spawn_remove.tooltip_text = "Entfernt die eigenen Spawns dieses Modus — er nutzt danach wieder die Basis-Spawns." - add_child(spawn_remove) - spawn_hint = _muted_label("") - add_child(spawn_hint) - - mode_option.item_selected.connect(func(i: int) -> void: - if not _loading: - set_mode(ModusKatalog.MODES[i])) - add_button.pressed.connect(func() -> void: add_zone_at_view()) - spawn_option.item_selected.connect(func(i: int) -> void: - if not _loading: - select_spawn_set(_spawn_set_ids()[i])) - spawn_create.pressed.connect(func() -> void: create_spawns(SpawnOps.edit_set)) - spawn_remove.pressed.connect(func() -> void: remove_spawns(SpawnOps.edit_set)) - refresh_values() - - -# ------------------------------------------------------------- Ändern ------ - -func set_mode(mode: String) -> void: - if main.doc.is_empty() or not ModusKatalog.MODES.has(mode) or ModusKatalog.mode_of(main.doc) == mode: - return - var before := _snap() - if mode == ModusKatalog.MODE_TDM: - main.doc.erase("game_mode") - else: - main.doc["game_mode"] = mode - if ModusKatalog.has_zones(mode) and ModusKatalog.zones(main.doc, mode).is_empty(): - main.doc[ModusKatalog.ZONE_KEYS[mode]] = ModusKatalog.default_zones(main.doc, mode) - _commit(before, "Spielmodus: %s" % ModusKatalog.MODE_SHORT[mode]) - - -func _zone_key() -> String: - return str(ModusKatalog.ZONE_KEYS.get(ModusKatalog.mode_of(main.doc), "")) - - -func add_zone_at_view() -> void: - if main.doc.is_empty() or _zone_key() == "": - return - var at := Vector3.ZERO - if main.camera != null and "target" in main.camera: - at = main.camera.target - var half := _half() - add_zone(clampf(at.x, -half.x, half.x), clampf(at.z, -half.y, half.y)) - - -func add_zone(x: float, z: float) -> String: - var mode := ModusKatalog.mode_of(main.doc) - var key := _zone_key() - if key == "": - return "" - var before := _snap() - var zone := ModusKatalog.make_zone(main.doc, mode, x, z) - var list: Array = ModusKatalog.zones(main.doc, mode).duplicate(true) - list.append(zone) - main.doc[key] = list - _commit(before, "%s %s gesetzt" % [ModusKatalog.ZONE_NAMES[mode], zone["id"]]) - return str(zone["id"]) - - -func remove_zone(id: String) -> void: - var mode := ModusKatalog.mode_of(main.doc) - var key := _zone_key() - if key == "": - return - var before := _snap() - var list: Array = [] - for c in ModusKatalog.zones(main.doc, mode): - if str(c.get("id", "")) != id: - list.append((c as Dictionary).duplicate(true)) - if list.size() == ModusKatalog.zones(main.doc, mode).size(): - return - if list.is_empty(): - main.doc.erase(key) - else: - main.doc[key] = list - _commit(before, "%s %s gelöscht" % [ModusKatalog.ZONE_NAMES[mode], id]) - - -## King of the Hill: Reihenfolge der Hills ändern (dir = -1 hoch, +1 runter). -func move_zone(id: String, dir: int) -> void: - var mode := ModusKatalog.mode_of(main.doc) - var key := _zone_key() - if key == "": - return - var list: Array = ModusKatalog.zones(main.doc, mode).duplicate(true) - var idx := -1 - for i in list.size(): - if str(list[i].get("id", "")) == id: - idx = i - var to := idx + dir - if idx < 0 or to < 0 or to >= list.size(): - return - var before := _snap() - var tmp: Variant = list[idx] - list[idx] = list[to] - list[to] = tmp - main.doc[key] = list - _commit(before, "%s %s verschoben (Reihenfolge)" % [ModusKatalog.ZONE_NAMES[mode], id]) - - -## Name / Position / Radius einer Zone ändern (nur übergebene Felder). -func edit_zone(id: String, fields: Dictionary) -> void: - var mode := ModusKatalog.mode_of(main.doc) - var key := _zone_key() - if key == "": - return - var before := _snap() - var list: Array = ModusKatalog.zones(main.doc, mode).duplicate(true) - for c in list: - if str(c.get("id", "")) != id: - continue - if fields.has("label"): - c["label"] = str(fields["label"]).strip_edges().substr(0, 32) - if fields.has("radius_m"): - c["radius_m"] = clampf(float(fields["radius_m"]), ModusKatalog.MIN_RADIUS, ModusKatalog.MAX_RADIUS) - if fields.has("x") or fields.has("z"): - var half := _half() - var p: Array = c["pos"] - var nx := clampf(float(fields.get("x", p[0])), -half.x, half.x) - var nz := clampf(float(fields.get("z", p[2])), -half.y, half.y) - c["pos"] = [nx, SvmapDocument.terrain_height_at(main.doc, nx, nz), nz] - if fields.has(SpawnOps.YAW_KEY): - SpawnOps.write_yaw(c, fields[SpawnOps.YAW_KEY]) - main.doc[key] = list - _commit(before, "%s %s geändert" % [ModusKatalog.ZONE_NAMES[mode], id], "cp_%s" % id if fields.has("x") or fields.has("z") or fields.has("radius_m") or fields.has(SpawnOps.YAW_KEY) else "") - - -# ---- Spawn-Sätze ---- - -func _spawn_set_ids() -> Array: - var out: Array = [ModusKatalog.SPAWN_SET_BASE] - out.append_array(ModusKatalog.MODES) - return out - - -func select_spawn_set(set_id: String) -> void: - if not _spawn_set_ids().has(set_id): - return - SpawnOps.edit_set = set_id - _refresh_spawn_view() - refresh_values() - main.call("_set_status", "Spawn-Satz: %s." % _set_label(set_id)) - - -func create_spawns(mode: String) -> void: - if main.doc.is_empty() or mode == ModusKatalog.SPAWN_SET_BASE or ModusKatalog.has_own_spawns(main.doc, mode): - return - var before := _snap() - ModusKatalog.create_spawn_set(main.doc, mode) - _commit(before, "Eigene Spawns für %s angelegt" % ModusKatalog.MODE_SHORT[mode]) - _refresh_spawn_view() - - -func remove_spawns(mode: String) -> void: - if main.doc.is_empty() or mode == ModusKatalog.SPAWN_SET_BASE or not ModusKatalog.has_own_spawns(main.doc, mode): - return - var before := _snap() - ModusKatalog.remove_spawn_set(main.doc, mode) - SpawnOps.edit_set = ModusKatalog.SPAWN_SET_BASE - _commit(before, "Eigene Spawns für %s gelöscht" % ModusKatalog.MODE_SHORT[mode]) - _refresh_spawn_view() - - -func _refresh_spawn_view() -> void: - if main.view_builder != null: - main.view_builder.call("_rebuild_spawn_markers", main.doc) - if "spawn_tool" in main and main.spawn_tool != null: - main.spawn_tool.call("refresh_from_doc") - - -func _set_label(set_id: String) -> String: - if set_id == ModusKatalog.SPAWN_SET_BASE: - return "Basis (für alle Modi ohne eigene Spawns)" - return "%s%s" % [ModusKatalog.MODE_SHORT[set_id], " ✔ eigene" if ModusKatalog.has_own_spawns(main.doc, set_id) else ""] - - -func _half() -> Vector2: - var t: Dictionary = main.doc.get("terrain", {}) - return Vector2(float(t.get("size_x_m", 1024.0)) * 0.5, float(t.get("size_z_m", 1024.0)) * 0.5) - - -func _snap() -> Dictionary: - var out := {} - for key in ["game_mode", "conquest_zones", "hills", "mode_spawns"]: - var v: Variant = main.doc.get(key, null) - out[key] = v.duplicate(true) if v is Array or v is Dictionary else v - return out - - -func _commit(before: Dictionary, text: String, merge_tag := "") -> void: - var after := _snap() - if before == after: - return - main.history.commit(text, before, after, merge_tag) - main.dirty = true - main.call("_refresh_file_label") - main.call("_refresh_history_buttons") - if main.view_builder != null: - main.view_builder.call("rebuild_zone_markers", main.doc) - refresh_values() - main.call("_set_status", "%s." % text) - - -# ------------------------------------------------------------ Anzeige ------ - -## UI aus dem doc auffüllen (Laden, Undo/Redo) — löst keinen Schreibzugriff aus. -func refresh_values() -> void: - if mode_option == null or main == null or main.doc.is_empty(): - return - _loading = true - var mode := ModusKatalog.mode_of(main.doc) - mode_option.select(ModusKatalog.MODES.find(mode)) - cp_box.visible = ModusKatalog.has_zones(mode) - if cp_box.visible: - var nm: String = ModusKatalog.ZONE_NAMES[mode] - zones_title.text = "Hills (Reihenfolge = Wanderreihenfolge)" if mode == ModusKatalog.MODE_KOTH else "Zonen" - add_button.text = "+ %s in Bildmitte setzen" % nm - hint_label.text = "Mindestens %s nötig. %s" % [ - "einen Hill" if mode == ModusKatalog.MODE_KOTH else "eine Zone", - "Der Server wechselt nach der eingestellten Zeit zum nächsten Hill (oder zufällig)." if mode == ModusKatalog.MODE_KOTH - else "Spieler spawnen zusätzlich an Zonen ihres Teams."] - for c in rows_box.get_children(): - rows_box.remove_child(c) - c.queue_free() - var zl := ModusKatalog.zones(main.doc, mode) - for i in zl.size(): - if zl[i] is Dictionary: - rows_box.add_child(_row(zl[i], i, zl.size(), mode)) - hint_label.visible = zl.is_empty() - # Spawn-Sätze - if not _spawn_set_ids().has(SpawnOps.edit_set): - SpawnOps.edit_set = ModusKatalog.SPAWN_SET_BASE - spawn_option.clear() - for sid in _spawn_set_ids(): - spawn_option.add_item(_set_label(sid)) - spawn_option.select(_spawn_set_ids().find(SpawnOps.edit_set)) - var base := SpawnOps.edit_set == ModusKatalog.SPAWN_SET_BASE - var own := not base and ModusKatalog.has_own_spawns(main.doc, SpawnOps.edit_set) - spawn_create.visible = not base and not own - spawn_create.text = "Eigene Spawns für %s anlegen" % (ModusKatalog.MODE_SHORT[SpawnOps.edit_set] if not base else "") - spawn_remove.visible = own - if base: - spawn_hint.text = "Basis-Spawns gelten für jeden Modus ohne eigene Spawns." - elif own: - spawn_hint.text = "Das Spawn-Werkzeug ändert jetzt die eigenen Spawns dieses Modus." - else: - spawn_hint.text = "%s nutzt noch die Basis-Spawns. Mit dem Knopf legst du eigene an." % ModusKatalog.MODE_SHORT[SpawnOps.edit_set] - if SpawnOps.edit_set == ModusKatalog.MODE_DM and own: - spawn_hint.text += " Deathmatch hat keine Teams — alle Punkte gelten für alle." - _loading = false - - -func _row(cp: Dictionary, index := 0, count := 1, mode := "conquest") -> Control: - var id := str(cp.get("id", "")) - var pos: Array = cp.get("pos", [0, 0, 0]) - var half := _half() - var box := VBoxContainer.new() - box.name = "Z_%s" % id - box.add_theme_constant_override("separation", UIScale.px(4)) - - var top := HBoxContainer.new() - var idl := _field_label("%d·%s" % [index + 1, id] if mode == ModusKatalog.MODE_KOTH else id) - idl.custom_minimum_size = UIScale.v2(32, 0) - top.add_child(idl) - var name_edit := LineEdit.new() - name_edit.name = "Name" - name_edit.text = str(cp.get("label", id)) - name_edit.max_length = 32 - name_edit.size_flags_horizontal = Control.SIZE_EXPAND_FILL - name_edit.text_submitted.connect(func(t: String) -> void: - if not _loading: - edit_zone(id, {"label": t})) - name_edit.focus_exited.connect(func() -> void: - if not _loading and name_edit.text != str(cp.get("label", id)): - edit_zone(id, {"label": name_edit.text})) - top.add_child(name_edit) - if mode == ModusKatalog.MODE_KOTH: - var up := Button.new() - up.name = "Hoch" - up.text = "▲" - up.tooltip_text = "Früher drankommen" - up.disabled = index == 0 - up.pressed.connect(func() -> void: move_zone(id, -1)) - top.add_child(up) - var dn := Button.new() - dn.name = "Runter" - dn.text = "▼" - dn.tooltip_text = "Später drankommen" - dn.disabled = index >= count - 1 - dn.pressed.connect(func() -> void: move_zone(id, 1)) - top.add_child(dn) - var del := Button.new() - del.name = "Loeschen" - del.text = "✕" - del.tooltip_text = "Löschen" - del.pressed.connect(func() -> void: remove_zone(id)) - top.add_child(del) - box.add_child(top) - - var nums := HBoxContainer.new() - nums.add_theme_constant_override("separation", UIScale.px(4)) - nums.add_child(_spin("X", "x", id, float(pos[0]), -half.x, half.x, 1.0)) - nums.add_child(_spin("Z", "z", id, float(pos[2]), -half.y, half.y, 1.0)) - nums.add_child(_spin("Radius", "radius_m", id, float(cp.get("radius_m", ModusKatalog.DEFAULT_RADIUS)), - ModusKatalog.MIN_RADIUS, ModusKatalog.MAX_RADIUS, 1.0)) - box.add_child(nums) - if mode == ModusKatalog.MODE_CONQUEST: - var facing := HBoxContainer.new() - facing.add_theme_constant_override("separation", UIScale.px(4)) - facing.add_child(_spin("Blickrichtung °", SpawnOps.YAW_KEY, id, SpawnOps.effective_yaw(main.doc, cp), 0.0, 359.0, 1.0)) - var reset := Button.new() - reset.name = "BlickStandard" - reset.text = "Standard" - reset.tooltip_text = "Keine feste Richtung: Spieler schauen zur Kartenmitte, Bots zum Gegner. Im Spawn-Werkzeug geht's auch per Pfeilspitze." - reset.disabled = not SpawnOps.has_yaw(cp) - reset.pressed.connect(func() -> void: edit_zone(id, {SpawnOps.YAW_KEY: null})) - facing.add_child(reset) - box.add_child(facing) - return box - - -func _spin(label: String, field: String, id: String, value: float, mn: float, mx: float, step: float) -> Control: - var h := HBoxContainer.new() - h.size_flags_horizontal = Control.SIZE_EXPAND_FILL - h.add_child(_field_label(label)) - var sb := SpinBox.new() - sb.name = field - sb.min_value = mn - sb.max_value = mx - sb.step = step - sb.set_value_no_signal(value) - sb.size_flags_horizontal = Control.SIZE_EXPAND_FILL - sb.value_changed.connect(func(v: float) -> void: - if not _loading: - edit_zone(id, {field: v})) - h.add_child(sb) - return h diff --git a/src/ui/panels/modus_panel.gd.uid b/src/ui/panels/modus_panel.gd.uid deleted file mode 100644 index ad8aa37..0000000 --- a/src/ui/panels/modus_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dd6aphlxfvcha diff --git a/src/ui/panels/registry.gd b/src/ui/panels/registry.gd deleted file mode 100644 index c34bc8c..0000000 --- a/src/ui/panels/registry.gd +++ /dev/null @@ -1,109 +0,0 @@ -class_name PanelRegistry -extends RefCounted - -## Zentrale, DATENGETRIEBENE Anmeldung aller Editor-Bereiche (Karte t_eaccbfed, -## Operator-Vorgabe 20.10.). main.gd baut das Layout AUSSCHLIESSLICH aus dieser -## Registry — keine Panel-Erzeugung mehr fest verdrahtet. -## -## Warum: Die Umbau-Karten U2 (Szenen-Baum), U3 (Gruppen), U4 (Assets), -## U5 (Platzieren nur einmal), U6 (dezente Auswahl) und U7 (Feinschliff) ändern -## danach NUR ihr eigenes Modul und melden sich HIER an (einzeiliger Eintrag) -## — ohne main.gd anzufassen. Dadurch kollidieren parallele Karten nicht mehr -## in derselben Datei (gleiche Falle wie früher bei match_hud.gd). -## -## Struktur je Eintrag: titel (Tab-/Überschrift), gruppe ("rechts" = rechtes -## TabControl, "links" = linke Spalte, "unten" = Assets-Bereich, "map" = Abschnitte im Map-Tab, "dialog" = Einstellungen-Fenster, "toolbar" / -## "status" = Leisten-Aktionen), order (Sortier-Schlüssel), skript (preload-Pfad -## des Panel-Moduls). Ein Bereich erscheint GENAU EINMAL im Baum (test_ui_layout -## prüft das gegen Doppel-Namen). - -const TITLE_TOOLBAR := "Werkzeuge" -const TITLE_STATUS := "Statuszeile" - -## Die Bereiche in fester Reihenfolge. skript = preload-Pfad; jeder -## Panel-Eintrag muss in seinem Skript `static func spec()` haben, das -## mindestens {"titel", "gruppe", "order"} liefert (die Werte hier sind die -## Authorität — spec() wird von test_ui_layout GEGEN diese Tabelle geprüft). -const PANELS: Array = [ - # --- rechts: Tab-Gruppe (Unity-Inspector-Spalte) --- - {"id": "inspektor", "titel": "Inspektor", "gruppe": "rechts", "order": 10, - "skript": "res://src/ui/inspector_panel.gd"}, - {"id": "map", "titel": "Map", "gruppe": "rechts", "order": 30, - "skript": "res://src/ui/panels/map_panel.gd"}, - {"id": "terrain", "titel": "Terrain", "gruppe": "rechts", "order": 40, - "skript": "res://src/ui/panels/terrain_panel.gd"}, - # 25.10. UI-Aufräumen: Malen und Bauen hängen nicht mehr im Terrain-Tab. - {"id": "malen", "titel": "Malen", "gruppe": "rechts", "order": 45, - "skript": "res://src/ui/panels/malen_panel.gd"}, - {"id": "bauen", "titel": "Bauen", "gruppe": "rechts", "order": 47, - "skript": "res://src/ui/panels/bauen_panel.gd"}, - # Etappe 3: Server-Verwaltung (Admin-API des Match-Servers). - {"id": "server", "titel": "Server", "gruppe": "rechts", "order": 50, - "skript": "res://src/ui/panels/server_panel.gd"}, - # --- map: Abschnitte UNTER den Map-Eigenschaften (Tab „Map“) --- - # 25.10. (Test-Befund): Prüfen/Test-Start/Symmetrie sind keine eigenen Tabs - # mehr. Spawn-Zonen, Test-Start-Info und Symmetrie wohnen im Map-Tab. - {"id": "check", "titel": "Spawn-Zonen", "gruppe": "map", "order": 10, - "skript": "res://src/ui/panels/check_panel.gd"}, - {"id": "teststart", "titel": "Test-Start", "gruppe": "map", "order": 20, - "skript": "res://src/ui/panels/test_start_panel.gd"}, - {"id": "loadout", "titel": "Loadout", "gruppe": "map", "order": 25, - "skript": "res://src/ui/panels/loadout_panel.gd"}, - {"id": "modus", "titel": "Spielmodus", "gruppe": "map", "order": 22, - "skript": "res://src/ui/panels/modus_panel.gd"}, - {"id": "symmetrie", "titel": "Symmetrie", "gruppe": "map", "order": 30, - "skript": "res://src/ui/panels/symmetry_panel.gd"}, - # --- dialog: Inhalt des Einstellungen-Fensters (Knopf in der Kopfleiste) --- - # T3 Komfort (Karte t_aaff5dcc) + 25.10.: Gitter, Höhenlinien, Symmetrie- - # Modus, UI-Größe, Raster-Snap, Gizmo-Schritt, Karte prüfen. - {"id": "einstellungen", "titel": "Einstellungen", "gruppe": "dialog", "order": 10, - "skript": "res://src/ui/panels/settings_panel.gd"}, - # --- links: Vorbereitet für U2 (Szenen-Baum); Bibliothek ist UNTEN --- - {"id": "szene", "titel": "Map-Inhalt", "gruppe": "links", "order": 10, - "skript": "res://src/ui/panels/scene_tree_panel.gd"}, - # --- unten: Objekt-Bibliothek / Assets (Unity-Projekt-Fenster-Platz) --- - {"id": "assets", "titel": "Objekt-Bibliothek", "gruppe": "unten", "order": 10, - "skript": "res://src/ui/panels/assets_panel.gd"}, -] - -## Leisten-Aktionen (Toolbar-Buttons/Menüs — KEINE Panels, melden sich ditto -## datengetrieben an, damit T1s Lauf-Modus und künftige Aktionen main.gd -## nicht mehr anfassen). action = Methodenname an main (Callable wird gebunden). -const ACTIONS: Array = [ - {"id": "karte_pruefen", "titel": "✅ Karte prüfen", "gruppe": "toolbar", - "order": 10, "action": "_on_check_map"}, - {"id": "karte_testen", "titel": "▶ Karte testen", "gruppe": "toolbar", - "order": 20, "action": "_on_test_run"}, - # Wiederanbindung 20.10. (T1b, Karte t_96e3c4ee): der Test-Start-Knopf war - # beim U1-Umbau aus der Leiste verschwunden. - {"id": "teststart", "titel": "🎯 Test-Start", "gruppe": "toolbar", - "order": 30, "action": "_on_test_start_tool_pressed"}, -] - - -## Panel-Einträge einer Gruppe, nach order sortiert (Reihenfolge = Tab-Reihenfolge). -static func entries(gruppe: String) -> Array: - var out: Array = [] - for e in PANELS: - if str(e["gruppe"]) == gruppe: - out.append(e) - out.sort_custom(func(a, b) -> bool: return int(a["order"]) < int(b["order"])) - return out - - -## Toolbar-Aktionen, nach order sortiert. -static func toolbar_actions() -> Array: - var out: Array = [] - for e in ACTIONS: - if str(e["gruppe"]) == "toolbar": - out.append(e) - out.sort_custom(func(a, b) -> bool: return int(a["order"]) < int(b["order"])) - return out - - -## Eintrag per ID (für Tests/Probes). -static func entry(id: String) -> Dictionary: - for e in PANELS: - if str(e["id"]) == id: - return e - return {} diff --git a/src/ui/panels/registry.gd.uid b/src/ui/panels/registry.gd.uid deleted file mode 100644 index 78557b8..0000000 --- a/src/ui/panels/registry.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cmom62lxsqgef diff --git a/src/ui/panels/scene_tree_panel.gd b/src/ui/panels/scene_tree_panel.gd deleted file mode 100644 index 070170f..0000000 --- a/src/ui/panels/scene_tree_panel.gd +++ /dev/null @@ -1,590 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Map-Inhalt-Baum (aus main.gd ausgezogen, Karte t_eaccbfed U1 — Logik -## unverändert). U2 baut hier den hierarchischen Szenen-Baum aus; diese Karte -## zieht nur um: Der Baum lebt jetzt im LINKEN TabContainer (Registry-Gruppe -## "links"), Zustand/Signale wie vorher. - -var content_tree: Tree -var group_btn: Button -var ungroup_btn: Button -var _tree_select_lock := false # verhindert Rückkopplung Auswahl ↔ Baum -var _tree_select_pending := false # multi_selected gesammelt, Auswertung steht aus -var _obj_index_map: Dictionary = {} # obj_index -> TreeItem (schnelle Zwei-Wege-Kopplung) - -# U3 (Karte t_a4bf9b8c): Kontextmenü, Umbenennen, Lösch-Rückfrage, Drag&Drop. -var _context_menu: PopupMenu -var _rename_dialog: AcceptDialog -var _rename_field: LineEdit -var _rename_gid := -1 # Gruppe, die das Umbenennen-Dialogfeld betrifft -var _confirm_delete: ConfirmationDialog -var _confirm_gid := -1 # Gruppe, die das Lösch-Rückfragen betrifft - - -static func spec() -> Dictionary: - return {"titel": "Map-Inhalt", "gruppe": "links", "order": 10} - - -func build() -> void: - add_child(_header_label("Map-Inhalt")) - - content_tree = Tree.new() - content_tree.size_flags_vertical = Control.SIZE_EXPAND_FILL - content_tree.custom_minimum_size = UIScale.v2(0, 160) - content_tree.allow_reselect = true - content_tree.select_mode = Tree.SELECT_MULTI # Strg+Klick im Baum = Mehrfachauswahl (t_c46d31c2) - content_tree.hide_root = true - # FIX 25.10. (Test-Befund „Liste anklicken wählt in der Szene nichts aus“): - # Im Modus SELECT_MULTI feuert Godot NIE item_selected, sondern nur - # multi_selected (pro Zeile). Beide anschließen; das Sammeln übernimmt der - # Aufrufer-Merker, damit ein Klick mit mehreren Signalen nur EINMAL wirkt. - content_tree.item_selected.connect(_on_tree_selected) - content_tree.multi_selected.connect(_on_tree_multi_selected) - add_child(content_tree) - - # Gruppen verwalten (25.10.: der Tab „Auswahl“ ist weg): mehrere Objekte in der - # Liste (Strg+Klick) oder in der Szene markieren, dann hier gruppieren/lösen. - # Rechtsklick auf eine Zeile bietet dieselben Aktionen. - var group_row := HBoxContainer.new() - group_row.add_theme_constant_override("separation", UIScale.px(8)) - add_child(group_row) - group_btn = Button.new() - group_btn.text = "🔗 Gruppieren" - group_btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL - group_btn.custom_minimum_size = UIScale.v2(0, 40) - group_btn.tooltip_text = "Markierte Objekte zu einer Gruppe verbinden (Strg+G) — sie ziehen und drehen dann gemeinsam. Mehrere markieren: Strg+Klick in der Liste oder Rahmen in der Szene." - group_btn.pressed.connect(func() -> void: main.interaction.group_selection()) - group_row.add_child(group_btn) - ungroup_btn = Button.new() - ungroup_btn.text = "⛓ Gruppe lösen" - ungroup_btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL - ungroup_btn.custom_minimum_size = UIScale.v2(0, 40) - ungroup_btn.tooltip_text = "Die Gruppe der Auswahl auflösen (Strg+Umschalt+G) — die Objekte bleiben, nur die Bindung löst sich" - ungroup_btn.pressed.connect(func() -> void: main.interaction.ungroup_selection()) - group_row.add_child(ungroup_btn) - - # U3 (Karte t_a4bf9b8c): Rechtsklick-Kontextmenü + Drag&Drop für Gruppen. - content_tree.gui_input.connect(_on_tree_gui_input) - # Tree.set_drag_forwarding: die drei Virtuals (_get_drag_data/_can_drop_data/ - # _drop_data) wohnen am Tree selbst — hier per Callables weitergeleitet. - content_tree.set_drag_forwarding(_tree_drag_data, _tree_can_drop, _tree_drop) - _context_menu = PopupMenu.new() - _context_menu.hide_on_item_selection = true - _context_menu.id_pressed.connect(_on_menu_action) - add_child(_context_menu) - _rename_dialog = AcceptDialog.new() - _rename_dialog.title = "Gruppe umbenennen" - _rename_dialog.ok_button_text = "Übernehmen" - # Hinweis: AcceptDialog kennt in Godot 4.7 weder cancel_button_text noch - # get_cancel_button() — der Default-Abbrechen-Button bleibt, wie er ist. - _rename_field = LineEdit.new() - _rename_field.placeholder_text = "Gruppenname" - _rename_dialog.add_child(_rename_field) - _rename_dialog.confirmed.connect(_on_rename_confirmed) - add_child(_rename_dialog) - _confirm_delete = ConfirmationDialog.new() - _confirm_delete.title = "Gruppe löschen" - _confirm_delete.ok_button_text = "Löschen" - _confirm_delete.cancel_button_text = "Abbrechen" - _confirm_delete.confirmed.connect(_on_delete_confirmed) - add_child(_confirm_delete) - add_child(_separator()) - - -## multi_selected kommt je Zeile (auch beim Abwählen): die Auswahl EINMAL pro -## Frame auswerten, nicht pro Signal. -func _on_tree_multi_selected(_item: TreeItem, _column: int, _selected: bool) -> void: - if _tree_select_lock or _tree_select_pending: - return - _tree_select_pending = true - _apply_tree_selection.call_deferred() - - -func _apply_tree_selection() -> void: - _tree_select_pending = false - _on_tree_selected() - - -## Der Baum ruft zurück, wenn der Nutzer dort ein Objekt auswählt. -## SELECT_MULTI (Karte t_c46d31c2): einfacher Klick = Ersatz-Auswahl, -## Strg+Klick addiert/entfernt nativ — ALLE markierten Objekt-Zeilen spiegeln -## sich in die Viewport-Auswahl (Baum und Szene sind immer synchron). -func _on_tree_selected() -> void: - if _tree_select_lock: - return - var item := content_tree.get_selected() - if item == null: - return - # Gruppe geklickt (Karte t_e3c0310a U2): alle Mitglieder auswählen. - if item.has_meta("group_id"): - var g_indices: Array = [] - var walk_g := item.get_first_child() - while walk_g != null: - if walk_g.has_meta("obj_index"): - g_indices.append(int(walk_g.get_meta("obj_index"))) - walk_g = walk_g.get_next() - if not g_indices.is_empty(): - _tree_select_lock = true - main.interaction.select_many(g_indices) - _tree_select_lock = false - main.call("_set_status", "Gruppe %d ausgewählt (%d Objekte) — gemeinsam verschieben/drehen/duplizieren." % [int(item.get_meta("group_id")), g_indices.size()]) - return - var indices: Array = [] - var walk := content_tree.get_next_selected(null) - while walk != null: - if walk.has_meta("obj_index"): - indices.append(int(walk.get_meta("obj_index"))) - walk = content_tree.get_next_selected(walk) - if indices.is_empty(): - return - var objects: Array = main.doc.get("objects", []) - var valid: Array = [] - for idx in indices: - if idx >= 0 and idx < objects.size(): - valid.append(idx) - if valid.is_empty(): - return - if valid.size() == 1: - main.interaction.select_object(valid[0], true) - main.call("_set_status", "%s ausgewählt — ziehen zum Verschieben, R/Mausrad zum Drehen, Entf zum Löschen. Strg+Klick markiert weitere dazu." % main.object_label(str(objects[valid[0]].get("id", "")))) - else: - main.interaction.select_many(valid) - main.call("_set_status", "%d Objekte im Baum markiert — Entf löscht ALLE, Strg+D dupliziert ALLE (jeweils EIN Undo-Schritt)." % valid.size()) - - -func mark_tree_selection(idx: int) -> void: - mark_tree_selection_multi([idx]) - - -func mark_tree_selection_multi(indices: Array) -> void: - _tree_select_lock = true - var wanted := {} - for i in indices: - wanted[int(i)] = true - # Zwei-Wege-Kopplung (Karte t_e3c0310a U2): die Auswahl in 3D spiegelt - # sich im Baum — über die Index-Karte O(1) statt Voll-Suche. - for idx in wanted.keys(): - if _obj_index_map.has(idx): - var item: TreeItem = _obj_index_map[idx] - item.select(0) - # Abwählen: alle übrigen markierten Objekt-Zeilen deselektieren. - var walk := content_tree.get_next_selected(null) - while walk != null: - if walk.has_meta("obj_index") and not wanted.has(int(walk.get_meta("obj_index"))): - walk.deselect(0) - walk = content_tree.get_next_selected(walk) - var primary: Variant = main.interaction.get("selected_index") if main.interaction != null else -1 - if primary is int and primary >= 0 and _obj_index_map.has(primary): - _ensure_tree_visible(content_tree.get_root(), primary) - _tree_select_lock = false - - -func _ensure_tree_visible(item: TreeItem, idx: int) -> void: - if item == null: - return - if item.has_meta("obj_index") and int(item.get_meta("obj_index")) == idx: - # Fix (beim Inspektor-Einbau gefunden, Vorbestand t_f6f29d86): Tree - # und TreeItem haben KEIN ensure_visible — die Godot-4-API heißt - # Tree.scroll_to_item. Der alte Ruf warf bei JEDER Auswahl einen - # SCRIPT ERROR und scrollte den Baum nie zur Auswahl. - content_tree.scroll_to_item(item) - return - for child in item.get_children(): - _ensure_tree_visible(child, idx) - - -func refresh_tree() -> void: - content_tree.clear() - _obj_index_map.clear() - var root := content_tree.create_item() - var objects: Array = main.doc.get("objects", []) - var zones: Dictionary = main.doc.get("spawn_zones", {}) - var group_ids: Array = GroupOps.active_group_ids(main.doc) - - # Leerer Zustand (Karte t_e3c0310a U2): Klartext-Hinweis statt leere Gruppen. - if objects.is_empty() and zones.is_empty() and group_ids.is_empty(): - var empty_item := content_tree.create_item(root) - empty_item.set_text(0, "Noch keine Objekte — links in der Objekt-Bibliothek wählen") - empty_item.set_selectable(0, false) - return - - # Objekte: Kategorie → Objekte (Karte t_e3c0310a U2 — z. B. Mauern, Barrieren). - var obj_item := content_tree.create_item(root) - obj_item.set_text(0, "Objekte (%d)" % objects.size()) - obj_item.set_meta("objekte_kopf", true) # Drag-Ziel „aus Gruppe herauslösen“ (U3) - var kat_map: Dictionary = {} - for i in objects.size(): - var obj = objects[i] - if obj is Dictionary: - var oid := str(obj.get("id", "?")) - var kat := LibraryBrowser.group_of(oid) - if not kat_map.has(kat): - kat_map[kat] = [] - kat_map[kat].append({"idx": i, "obj": obj}) - for kat in kat_map.keys(): - var kat_item := content_tree.create_item(obj_item) - kat_item.set_text(0, "%s (%d)" % [_kat_label(kat), (kat_map[kat] as Array).size()]) - for data in kat_map[kat]: - var idx: int = int(data["idx"]) - var obj: Dictionary = data["obj"] - var is_visible: bool = bool(obj.get("visible", true)) - var item := content_tree.create_item(kat_item) - item.set_text(0, ("👁 " if is_visible else "🚫 ") + "%s #%d" % [main.object_label(str(obj.get("id", "?"))), idx + 1]) - item.set_meta("obj_index", idx) - item.set_meta("visible", is_visible) - _obj_index_map[idx] = item - - # Spawn-Zonen: Team A/B (Karte t_e3c0310a U2 — aus der alten Struktur). - if not zones.is_empty(): - var spawn_item := content_tree.create_item(root) - spawn_item.set_text(0, "Spawn-Zonen") - for team_key in ["0", "1"]: - if not zones.has(team_key): - continue - var zone: Dictionary = zones[team_key] - var team_item := content_tree.create_item(spawn_item) - var team_name := "Team Blau" if team_key == "0" else "Team Rot" - team_item.set_text(0, "%s (%d Punkte)" % [team_name, (zone.get("points", []) as Array).size()]) - for p in (zone.get("points", []) as Array): - if p is Dictionary: - var point_item := content_tree.create_item(team_item) - point_item.set_text(0, "%s (%.0f, %.0f)" % [ - str(p.get("id", "?")), float(p.get("pos", [0, 0, 0])[0]), float(p.get("pos", [0, 0, 0])[2])]) - - # Gruppen (Karte t_e3c0310a U2): aktive Gruppen als eigene Ebene im Baum. - # Klick auf eine Gruppe wählt ALLE Mitglieder in der 3D-Szene (Zwei-Wege). - if not group_ids.is_empty(): - var grp_item := content_tree.create_item(root) - grp_item.set_text(0, "Gruppen (%d)" % group_ids.size()) - grp_item.set_meta("objekte_kopf", true) # Drag-Ziel „herauslösen“ (U3) - for gid in group_ids: - var member_indices: Array = GroupOps.members_of(main.doc, gid) - # U3 (Karte t_a4bf9b8c): gespeicherter Name voran, Fallback "Gruppe N". - var g_node := content_tree.create_item(grp_item) - g_node.set_text(0, "%s (%d Objekte)" % [GroupState.display_name(main.doc, int(gid)), member_indices.size()]) - g_node.set_meta("group_id", int(gid)) - for mi in member_indices: - var obj: Dictionary = main.doc["objects"][int(mi)] - var m_item := content_tree.create_item(g_node) - m_item.set_text(0, " %s" % main.object_label(str(obj.get("id", "?")))) - m_item.set_meta("obj_index", int(mi)) - - -## Kategorie-Schlüssel (z. B. "mauern") in Anzeige-Label (z. B. "Mauern") — -## Karte t_e3c0310a U2. Nutzt KAT_GROUPS aus LibraryBrowser. -static func _kat_label(key: String) -> String: - for kat_name in LibraryBrowser.KAT_GROUPS: - var g: Dictionary = LibraryBrowser.KAT_GROUPS[kat_name] - if str(g["key"]) == key: - return str(g["label"]) - return key.capitalize() - - -# ================= U3: Gruppen im Baum (Karte t_a4bf9b8c) ==================== -# Gruppen direkt im Szenen-Baum bilden: Rechtsklick-Menü (Gruppieren/Auflösen/ -# Umbenennen/Löschen), Drag&Drop für die Mitgliedschaft, Gruppennamen im -# Dokument (GroupState, additiv). Jede Aktion = EIN Undo-Schritt über -# main.history — die Mehrfachauswahl-Logik (interaction.gd) wird benutzt, -# nicht kopiert; object_ops.gd nur LESEND. - - -## Rechtsklick im Baum: Zeile unter der Maus finden → Kontextmenü aufmachen. -func _on_tree_gui_input(event: InputEvent) -> void: - if not (event is InputEventMouseButton): - return - var mb := event as InputEventMouseButton - if not mb.pressed or mb.button_index != MOUSE_BUTTON_RIGHT: - return - var item: TreeItem = content_tree.get_item_at_position(mb.position) - if item == null: - return - # Rechtsklick auf eine (noch nicht markierte) Zeile wählt sie an — wie in - # Unity/Godot: das Menü gehört zur angeklickten Zeile. Direkter Ruf von - # _on_tree_selected (item_selected feuert bei .select() nicht selbst). - if item.has_meta("obj_index") and not item.is_selected(0): - content_tree.deselect_all() - item.select(0) - _on_tree_selected() - _open_context_menu(item, Vector2i(content_tree.get_screen_transform() * mb.position)) - - -## Kontextmenü je Zeilen-Typ aufbauen (Klartext-Einträge, je Aktion eine ID). -func _open_context_menu(item: TreeItem, at_screen: Vector2i) -> void: - _context_menu.clear() - var has_entries := false - # Gruppen-Knoten: Auflösen / Umbenennen / Löschen (Rückfrage bei > 1 Objekt). - if item.has_meta("group_id"): - var gid := int(item.get_meta("group_id")) - _context_menu.add_item("⛓ Gruppe auflösen", 1) - _context_menu.set_item_metadata(_context_menu.item_count - 1, {"aktion": "loesen_gruppe", "gid": gid}) - _context_menu.add_item("✂ Umbenennen…", 2) - _context_menu.set_item_metadata(_context_menu.item_count - 1, {"aktion": "umbenennen", "gid": gid}) - _context_menu.add_item("🗑 Gruppe löschen…", 3) - _context_menu.set_item_metadata(_context_menu.item_count - 1, {"aktion": "loeschen_gruppe", "gid": gid}) - has_entries = true - # Objekt-Zeile: Gruppieren (wenn ≥ 2 markiert), Aus Gruppe lösen, Löschen. - if item.has_meta("obj_index"): - var sel: Array = main.interaction.selected_indices - if sel.size() >= 2: - _context_menu.add_item("🔗 Gruppieren (%d Objekte)" % sel.size(), 10) - _context_menu.set_item_metadata(_context_menu.item_count - 1, {"aktion": "gruppieren"}) - has_entries = true - var objects: Array = main.doc.get("objects", []) - var idx := int(item.get_meta("obj_index")) - if idx >= 0 and idx < objects.size() and GroupOps.group_id(objects[idx]) != GroupOps.UNGROUPED: - _context_menu.add_item("⛓ Aus Gruppe lösen", 1) - _context_menu.set_item_metadata(_context_menu.item_count - 1, {"aktion": "loesen_einzeln", "idx": idx}) - has_entries = true - _context_menu.add_item("🗑 Löschen", 3) - _context_menu.set_item_metadata(_context_menu.item_count - 1, {"aktion": "loeschen_einzeln", "idx": idx}) - has_entries = true - if not has_entries: - return - _context_menu.position = at_screen - _context_menu.popup() - - -## Menü-Auswahl → Aktion (Metadaten tragen Ziel; ID → Zeile über get_item_index, -## robust auch nachdem das Menü sich bei hide_on_item_selection schon versteckt). -func _on_menu_action(id: int) -> void: - var menu_index := _context_menu.get_item_index(id) - if menu_index < 0: - return - var meta: Variant = _context_menu.get_item_metadata(menu_index) - if not (meta is Dictionary): - return - var m := meta as Dictionary - match str(m.get("aktion", "")): - "gruppieren": - group_selected() - "loesen_gruppe": - ungroup_group(int(m.get("gid", -1))) - "loesen_einzeln": - ungroup_indices([int(m.get("idx", -1))]) - "umbenennen": - open_rename_dialog(int(m.get("gid", -1))) - "loeschen_gruppe": - delete_group(int(m.get("gid", -1))) - "loeschen_einzeln": - _select_for_action([int(m.get("idx", -1))]) - main.interaction.delete_selected() - - -## Auswahl für eine Aktion setzen (Baum-Markierung + 3D synchron). -func _select_for_action(indices: Array) -> void: - _tree_select_lock = true - main.interaction.select_many(indices) - _tree_select_lock = false - - -## Mehrfachauswahl → Gruppe (nutzt die bestehende interaction-Logik, EIN Undo). -func group_selected() -> void: - var sel: Array = main.interaction.selected_indices - if sel.size() < 2: - main.call("_set_status", "Gruppieren braucht mindestens 2 markierte Objekte — Strg+Klick im Baum oder im Viewport.", true) - return - main.interaction.group_selection() - _refresh_after_group_change() - _select_for_action(sel) # Gruppe bleibt markiert (Mitglieder hängen jetzt unter dem Gruppen-Knoten) - - -## GANZE Gruppe auflösen: Mitglieder anwählen → bestehende Löse-Logik. -func ungroup_group(gid: int) -> void: - var members: Array = GroupOps.members_of(main.doc, gid) - if members.is_empty(): - main.call("_set_status", "Gruppe %d existiert nicht mehr." % (gid + 1), true) - return - _select_for_action(members) - main.interaction.ungroup_selection() - _refresh_after_group_change() - - -## Objekte aus ihrer Gruppe herauslösen (NUR diese Indizes — Drag-out-Pfad). -## EIN Undo-Schritt: snapshot ["objects", "group_names"] vor/nach (verwaiste -## Namen-Einträge werden im selben Schritt mitgeräumt). -func ungroup_indices(indices: Array) -> void: - var before := _snapshot_group_blocks() - var freed := GroupState.clear_group_fields(main.doc, indices) - if freed == 0: - main.call("_set_status", "Die markierten Objekte stecken in keiner Gruppe.") - return - GroupState.prune_orphans(main.doc) - main.history.commit("Objekt aus Gruppe gelöst (%d)" % freed, - before, _snapshot_group_blocks()) - main.call("_refresh_history_buttons") - _refresh_after_group_change() - - -## Snapshot für Gruppen-Undo-Schritte: ["objects", "group_names"]. Fehlt der -## Namen-Block im Dokument (alte Maps), wird er als null SEEDED — ActionHistory -## wendet nur Schlüssel an, die im Snapshot stehen; ohne Seed bliebe der Name -## nach Undo als Leiche stehen (Restore von null löscht den Block sauber). -func _snapshot_group_blocks() -> Dictionary: - var out: Dictionary = main.history.snapshot(["objects", "group_names"]) - if not out.has(GroupState.NAMES_KEY): - out[GroupState.NAMES_KEY] = null - return out - - -## Umbenennen-Kern (testbar ohne Dialog): Name im Dokument setzen, EIN Undo. -func rename_group(gid: int, new_name: String) -> bool: - if gid < 0: - return false - var clean := new_name.strip_edges() - if GroupState.group_name(main.doc, gid) == clean: - return false # Name unverändert — kein leerer Undo-Eintrag - var before := _snapshot_group_blocks() - GroupState.set_group_name(main.doc, gid, new_name) - GroupState.prune_orphans(main.doc) - var after := _snapshot_group_blocks() - var label := ("Gruppe umbenannt in „%s“" % clean) if not clean.is_empty() \ - else ("Gruppenname entfernt (Gruppe %d)" % (gid + 1)) - main.history.commit(label, before, after) - main.call("_refresh_history_buttons") - _refresh_after_group_change() - return true - - -## Umbenennen-Dialog (Rechtsklick am Gruppen-Knoten). -func open_rename_dialog(gid: int) -> void: - var members: Array = GroupOps.members_of(main.doc, gid) - if members.is_empty(): - main.call("_set_status", "Gruppe %d existiert nicht mehr." % (gid + 1), true) - return - _rename_gid = gid - _rename_field.text = GroupState.group_name(main.doc, gid) - _rename_dialog.dialog_text = "Neuer Name für die Gruppe (leer = wieder „Gruppe %d“):" % (gid + 1) - _rename_field.grab_focus() - _rename_dialog.popup_centered(Vector2i(360, 100)) - - -func _on_rename_confirmed() -> void: - if _rename_gid >= 0: - rename_group(_rename_gid, _rename_field.text) - _rename_gid = -1 - - -## Gruppe löschen: Rückfrage bei > 1 Objekt, dann bestehende Lösch-Logik -## (interaction.delete_selected — EIN Undo-Schritt, Marker/3D räumen mit auf). -func delete_group(gid: int) -> void: - var members: Array = GroupOps.members_of(main.doc, gid) - if members.is_empty(): - main.call("_set_status", "Gruppe %d existiert nicht mehr." % (gid + 1), true) - return - if members.size() > 1: - _confirm_gid = gid - _confirm_delete.dialog_text = "Gruppe „%s“ löschen? Die %d Objekte darin werden ALLE gelöscht — Strg+Z holt sie zurück." % [GroupState.display_name(main.doc, gid), members.size()] - _confirm_delete.popup_centered(Vector2i(480, 140)) - return - delete_group_confirmed(gid) - - -## Lösch-Kern NACH der Rückfrage (auch direkt aufrufbar — Tests). -func delete_group_confirmed(gid: int) -> void: - var members: Array = GroupOps.members_of(main.doc, gid) - if members.is_empty(): - return - _select_for_action(members) - main.interaction.delete_selected() # ruft selbst _after_structure_change → Baum neu - - -func _on_delete_confirmed() -> void: - if _confirm_gid >= 0: - delete_group_confirmed(_confirm_gid) - _confirm_gid = -1 - - -# --- Drag & Drop (Mitgliedschaft ändern) ------------------------------------- - -## Zieh-Menge bestimmen: gezogene Zeile ist Teil der Markierung → die GANZE -## Markierung wandert mit; sonst nur die gezogene Zeile. (Testbar ohne echten -## Drag — _tree_drag_data ruft nur dies + set_drag_preview.) -func _collect_drag_indices(item: TreeItem) -> Array: - if item == null or not item.has_meta("obj_index"): - return [] - var idx := int(item.get_meta("obj_index")) - var sel: Array = main.interaction.selected_indices - if idx in sel: - var out: Array = [] - for i in sel: - if i is int: - out.append(int(i)) - return out - return [idx] - - -## Tree-Drag-Start (set_drag_forwarding-Callable): Datenpaket für Drop-Ziele. -## Vorschau-Control wird NICHT in den Baum gehängt (set_drag_preview verlangt -## ein Control außerhalb des Baums). -func _tree_drag_data(from_position: Vector2) -> Variant: - var item: TreeItem = content_tree.get_item_at_position(from_position) - var indices := _collect_drag_indices(item) - if indices.is_empty(): - return null - var label := Label.new() - label.text = "%d Objekt(e) ziehen" % indices.size() - content_tree.set_drag_preview(label) - return {"svmap_tree_objekte": indices} - - -## Drop erlaubt: AUF einen Gruppen-Knoten (aufnehmen) oder AUF den Objekte-Kopf/ -## eine Kategorie-Zeile (herauslösen — nur wenn mindestens ein gezogenes Objekt -## überhaupt gruppiert ist). -func _tree_can_drop(at_position: Vector2, data: Variant) -> bool: - if not (data is Dictionary) or not (data as Dictionary).has("svmap_tree_objekte"): - return false - var item: TreeItem = content_tree.get_item_at_position(at_position) - if item == null: - return false - if item.has_meta("group_id"): - return true - if item.has_meta("objekte_kopf"): - var objects: Array = main.doc.get("objects", []) - for i in (data["svmap_tree_objekte"] as Array): - if i is int and i >= 0 and i < objects.size() \ - and GroupOps.group_id(objects[i]) != GroupOps.UNGROUPED: - return true - return false - - -## Drop ausführen → Mitgliedschaft ändern (EIN Undo-Schritt), Baum/Auswahl neu. -func _tree_drop(at_position: Vector2, data: Variant) -> void: - var item: TreeItem = content_tree.get_item_at_position(at_position) - if item == null: - return - var indices: Array = (data as Dictionary).get("svmap_tree_objekte", []) - if item.has_meta("group_id"): - _apply_membership_drop(indices, int(item.get_meta("group_id"))) - elif item.has_meta("objekte_kopf"): - _apply_membership_drop(indices, -1) - - -## Mitgliedschafts-Kern (testbar): gid ≥ 0 = aufnehmen, gid < 0 = herauslösen. -func _apply_membership_drop(indices: Array, gid: int) -> void: - var before := _snapshot_group_blocks() - var changed := 0 - var label := "" - if gid >= 0: - changed = GroupState.assign_group(main.doc, indices, gid) - label = "%d Objekt(e) in „%s“ gezogen" % [changed, GroupState.display_name(main.doc, gid)] - else: - changed = GroupState.clear_group_fields(main.doc, indices) - label = "%d Objekt(e) aus der Gruppe herausgelöst" % changed - if changed == 0: - main.call("_set_status", "Nichts zu ändern — die Objekte gehören schon genau so zur Gruppe.") - return - GroupState.prune_orphans(main.doc) - main.history.commit(label, before, _snapshot_group_blocks()) - main.call("_refresh_history_buttons") - _refresh_after_group_change() - _select_for_action(indices) # gezogene Objekte bleiben sichtbar markiert - - -## Nach jeder Gruppen-Änderung: Baum neu + Panels synchron (kein 3D-Rebuild — -## Positionen ändern sich beim Gruppieren/Umbenennen/Zuordnen nicht). -func _refresh_after_group_change() -> void: - main.call("_refresh_tree") - var sel: Array = main.interaction.selected_indices - _tree_select_lock = true - mark_tree_selection_multi(sel) - _tree_select_lock = false - main.call("_sync_selection_panel") diff --git a/src/ui/panels/scene_tree_panel.gd.uid b/src/ui/panels/scene_tree_panel.gd.uid deleted file mode 100644 index a7e6184..0000000 --- a/src/ui/panels/scene_tree_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bpbw3vo36ohv1 diff --git a/src/ui/panels/selection_panel.gd b/src/ui/panels/selection_panel.gd deleted file mode 100644 index 85512ca..0000000 --- a/src/ui/panels/selection_panel.gd +++ /dev/null @@ -1,67 +0,0 @@ -extends Node -## Auswahl-Logik (U1, Karte t_eaccbfed — aus main.gd ausgezogen). Seit 25.10. -## KEIN Tab mehr (Test-Befund): Drehen/Anheben/Duplizieren/Löschen laufen in der -## 3D-Ansicht (Werkzeugleiste, Gizmo, Tasten), Gruppen im Map-Inhalt links, die -## Gizmo-Schrittweite im Einstellungen-Fenster. Übrig bleibt die Synchronisation: -## Inspektor nachziehen, Gizmo-Schrittweite-Feld folgen, Statuszeile zur frischen -## Auswahl (Klartext + Poly-Budget-Warnung). -## -## Verdrahtung: main.gd ruft sync_selection() an allen Auswahl-Wegen -## (vorher: _sync_selection_panel) und selection_status(idx) bei frischer -## Auswahl (vorher: _selection_status). Alle Objekt-Operationen laufen über -## main.interaction — der Vertrag zu interaction.gd bleibt identisch. - -var main # src/ui/main.gd (script-erweitert → untypisiert) - - -func setup(p_main) -> void: - main = p_main - - -## Objekt-Inspektor + Auswahl-Panel synchron halten (vorher -## main.gd/_sync_selection_panel — Logik unverändert). -func sync_selection() -> void: - # Objekt-Inspektor mit allen Auswahl-Wege synchron halten (Karte t_bb0d11c9). - if main.inspector != null: - main.inspector.call("refresh") - # Gizmo-Schrittweite-Feld mitziehen (Karte t_e0120dc2): Das Mausrad - # WÄHREND eines Zugs kann sie im Gizmo ändern (cycle_step) — das Panel- - # Feld folgt ohne eigene value_changed-Rückkopplung (set_value_no_signal). - var step_box: SpinBox = main.gizmo_step_box - if step_box != null and is_instance_valid(step_box) and not step_box.has_focus(): - step_box.set_value_no_signal(main.gizmo_step_m) - - -## Hilfs-Meldung zur frischen Auswahl (Klartext + Budget-Warnung + nächster -## Schritt) — vorher main.gd/_selection_status, Logik unverändert. -func selection_status(idx: int) -> void: - # Objekt-Inspektor füllen (Karte t_bb0d11c9) — dieser Weg läuft bei - # 3D-Klick, Rahmen-Ausziehen und Map-Inhalt-Baum. - if main.inspector != null: - main.inspector.call("refresh") - # sync_selection ändert bewusst KEINEN Statuszeilen-Text (Stummsync). - sync_selection() - var doc: Dictionary = main.doc - var objects: Array = doc.get("objects", []) - var sel: Array = main.interaction.selected_indices - if (idx < 0 or idx >= objects.size()) and sel.is_empty(): - main._base_tool_status() - return - var used := int(SvmapDocument.poly_usage(doc, main.manifest)) - var budget := int(SvmapIO.MAX_TOTAL_POLY) - var budget_warning := "" - if used > budget * 80 / 100: - budget_warning = " ⚠ Poly-Budget zu %.0f %% voll — bald passt kein Objekt mehr rein." % (100.0 * used / budget) - if sel.size() > 1: - main._set_status("%d Objekte ausgewählt — ziehen bewegt ALLE gemeinsam, R/Mausrad dreht sie um die Mitte, Entf löscht alle, Strg+G gruppiert.%s" % [sel.size(), budget_warning]) - return - if idx < 0 or idx >= objects.size(): - main._base_tool_status() - return - var obj: Dictionary = objects[idx] - var gid := GroupOps.group_id(obj) - var group_hint := "" - if gid != GroupOps.UNGROUPED: - group_hint = " (Gruppe %d — die zieht GEMEINSAM)" % (gid + 1) - main._set_status("%s%s ausgewählt — ziehen zum Verschieben, R oder Mausrad zum Drehen, Bild↑/↓ anheben/absenken, Strg+D duplizieren, Entf zum Löschen.%s" % [ - main.object_label(str(obj.get("id", ""))), group_hint, budget_warning]) \ No newline at end of file diff --git a/src/ui/panels/selection_panel.gd.uid b/src/ui/panels/selection_panel.gd.uid deleted file mode 100644 index 80c9c4d..0000000 --- a/src/ui/panels/selection_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dwp3df5nsfl3s diff --git a/src/ui/panels/server_panel.gd b/src/ui/panels/server_panel.gd deleted file mode 100644 index 588b7b4..0000000 --- a/src/ui/panels/server_panel.gd +++ /dev/null @@ -1,687 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Tab „Server“ (Etappe 3 „Server-Verwaltung“): Client der Match-Server-Admin-API. -## Mehrere Server speichern, verbinden, Status, Einstellungen, Spieler, Maps, -## Rotation, Logs und „Aktuelle Map auf den Server pushen“ – alles per Klick. -## Logik: src/server/ (AdminClient, ServerStore, AdminTexte, MapPush). - -var store: ServerStore -var store_path := ServerStore.DEFAULT_PATH # Tests lenken um -var client: AdminClient -var current_id := "" -var last_notice := "" # letzte Meldung (Tests) -var connected := false -var restart_wait_s := 120.0 # so lange wartet „Server neu starten“ (Tests verkürzen) -var restart_poll_s := 2.0 - -var _sel: OptionButton -var _conn_label: Label -var _notice: Label -var _status_label: Label -var _live_box: VBoxContainer # alles, was einen verbundenen Server braucht -var _push_name: LineEdit -var _push_rot: CheckBox -var _push_result: Label -var _settings_box: VBoxContainer -var _settings_editors: Dictionary = {} # key -> Control -var _settings_loaded: Dictionary = {} -var _settings_spec: Dictionary = {} -var _settings_result: Label -var _players_box: VBoxContainer -var _bans_box: VBoxContainer -var _ban_minutes: OptionButton -var _maps_box: VBoxContainer -var _rotation_checks: Dictionary = {} # map id -> CheckBox -var _log_filter: LineEdit -var _log_text: TextEdit -var _confirm: ConfirmationDialog -var _confirm_action: Callable -var _edit_dialog: ConfirmationDialog -var _edit_fields: Dictionary = {} -var _edit_id := "" - -const BAN_DAUER := [[10, "10 Minuten"], [60, "1 Stunde"], [1440, "1 Tag"], [10080, "1 Woche"], [0, "Dauerhaft"]] - - -static func spec() -> Dictionary: - return {"titel": "Server", "gruppe": "rechts", "order": 50} - - -func panel_title() -> String: - return "Server" - - -func build() -> void: - store = ServerStore.new(store_path) - store.load_store() - client = AdminClient.new() - client.name = "AdminClient" - add_child(client) - - add_child(_header_label("Server verwalten")) - add_child(_muted_label("Verbinde den Editor mit deinem Match-Server (Admin-API), um Maps hochzuladen und den Server zu steuern.")) - var hint := _muted_label(AdminTexte.TUNNEL_HINWEIS) - hint.visible = false - var hint_btn := Button.new() - hint_btn.text = "❓ Wie erreiche ich meinen Server sicher?" - hint_btn.flat = true - hint_btn.pressed.connect(func() -> void: hint.visible = not hint.visible) - add_child(hint_btn) - add_child(hint) - - _sel = OptionButton.new() - _sel.custom_minimum_size = UIScale.v2(0, 36) - _sel.item_selected.connect(func(_i: int) -> void: _on_selected()) - add_child(_sel) - var row := HBoxContainer.new() - add_child(row) - row.add_child(_btn("➕ Neu", _on_add)) - row.add_child(_btn("✏ Bearbeiten", _on_edit)) - row.add_child(_btn("🗑 Entfernen", _on_remove)) - var conn_row := HBoxContainer.new() - add_child(conn_row) - conn_row.add_child(_btn("🔌 Verbinden", func() -> void: connect_selected())) - _conn_label = Label.new() - _conn_label.text = "Nicht verbunden" - _conn_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - _conn_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL - conn_row.add_child(_conn_label) - _notice = _muted_label("") - add_child(_notice) - - _live_box = VBoxContainer.new() - _live_box.add_theme_constant_override("separation", UIScale.px(8)) - _live_box.visible = false - add_child(_live_box) - _build_live() - _build_dialogs() - _refresh_selector() - wrap_in_scroll() - - -func _btn(text: String, cb: Callable) -> Button: - var b := Button.new() - b.text = text - b.custom_minimum_size = UIScale.v2(0, 36) - b.pressed.connect(cb) - return b - - -func _section(title: String) -> void: - _live_box.add_child(_separator()) - _live_box.add_child(_header_label(title)) - - -func _build_live() -> void: - _section("Übersicht") - _status_label = Label.new() - _status_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - _live_box.add_child(_status_label) - _live_box.add_child(_btn("🔄 Alles aktualisieren", func() -> void: refresh_all())) - - _section("Map auf Server pushen") - _live_box.add_child(_muted_label("Prüft die Map im Editor und lädt sie hoch. Der Server prüft sie noch einmal.")) - _push_name = LineEdit.new() - _push_name.placeholder_text = "Dateiname (leer = Map-Name)" - _live_box.add_child(_push_name) - _push_rot = CheckBox.new() - _push_rot.text = "In die Rotation aufnehmen" - _live_box.add_child(_push_rot) - var pb := _btn("⬆ Aktuelle Map hochladen", func() -> void: push_current_map()) - pb.custom_minimum_size = UIScale.v2(0, 44) - _live_box.add_child(pb) - _push_result = Label.new() - _push_result.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - _live_box.add_child(_push_result) - - _section("Einstellungen") - _settings_box = VBoxContainer.new() - _live_box.add_child(_settings_box) - var srow := HBoxContainer.new() - _live_box.add_child(srow) - srow.add_child(_btn("💾 Speichern", func() -> void: save_settings())) - srow.add_child(_btn("↩ Zurücksetzen", func() -> void: _fill_settings_editors())) - _settings_result = _muted_label("") - _live_box.add_child(_settings_result) - - _section("Spieler") - _players_box = VBoxContainer.new() - _live_box.add_child(_players_box) - var brow := HBoxContainer.new() - _live_box.add_child(brow) - brow.add_child(_muted_label("Sperrdauer:")) - _ban_minutes = OptionButton.new() - for d in BAN_DAUER: - _ban_minutes.add_item(d[1]) - _ban_minutes.select(1) - brow.add_child(_ban_minutes) - _live_box.add_child(_muted_label("Gesperrt:")) - _bans_box = VBoxContainer.new() - _live_box.add_child(_bans_box) - - _section("Match & Maps") - _live_box.add_child(_btn("🔁 Match neu starten", func() -> void: _ask("Match auf dem Server neu starten? Alle Spieler beginnen die Runde von vorn.", _do_restart))) - _maps_box = VBoxContainer.new() - _live_box.add_child(_maps_box) - _live_box.add_child(_btn("💾 Rotation speichern", func() -> void: save_rotation())) - - _section("Server") - _live_box.add_child(_btn("⏻ Server neu starten", func() -> void: _ask("Server komplett neu starten? Alle Spieler werden getrennt und die laufende Runde endet.", func() -> void: await restart_server()))) - - _section("Server-Log") - _log_filter = LineEdit.new() - _log_filter.placeholder_text = "Filter (z. B. Admin, Join, FEHLER)" - _live_box.add_child(_log_filter) - _live_box.add_child(_btn("📜 Log laden", func() -> void: load_logs())) - _log_text = TextEdit.new() - _log_text.editable = false - _log_text.custom_minimum_size = UIScale.v2(0, 220) - _log_text.wrap_mode = TextEdit.LINE_WRAPPING_BOUNDARY - _live_box.add_child(_log_text) - - -func _build_dialogs() -> void: - _confirm = ConfirmationDialog.new() - _confirm.ok_button_text = "Ja" - _confirm.cancel_button_text = "Abbrechen" - _confirm.confirmed.connect(func() -> void: - if _confirm_action.is_valid(): - _confirm_action.call()) - add_child(_confirm) - - _edit_dialog = ConfirmationDialog.new() - _edit_dialog.title = "Server" - _edit_dialog.ok_button_text = "Speichern" - _edit_dialog.cancel_button_text = "Abbrechen" - var box := VBoxContainer.new() - _edit_dialog.add_child(box) - for f in [["name", "Name (frei wählbar)", "Mein Server"], ["host", "Adresse (IP oder Name)", "127.0.0.1"], - ["port", "Port der Admin-API", str(ServerStore.DEFAULT_PORT)], ["token", "Admin-Token", ""]]: - box.add_child(_field_label(f[1])) - var le := LineEdit.new() - le.placeholder_text = f[2] - le.custom_minimum_size = UIScale.v2(320, 32) - if f[0] == "token": - le.secret = true - box.add_child(le) - _edit_fields[f[0]] = le - var tls := CheckBox.new() - tls.text = "Sichere Verbindung (https) – nur mit Reverse-Proxy" - box.add_child(tls) - _edit_fields["tls"] = tls - var show := CheckBox.new() - show.text = "Token anzeigen" - show.toggled.connect(func(on: bool) -> void: (_edit_fields["token"] as LineEdit).secret = not on) - box.add_child(show) - var err := _muted_label("") - box.add_child(err) - _edit_fields["_err"] = err - box.add_child(_btn("🔌 Verbindung testen", func() -> void: _test_dialog_entry())) - _edit_dialog.confirmed.connect(_on_edit_confirmed) - add_child(_edit_dialog) - - -# ------------------------------------------------------------------ Liste -- - -func _refresh_selector(select_id: String = "") -> void: - _sel.clear() - for e in store.servers: - _sel.add_item("%s (%s:%d)" % [e["name"], e["host"], e["port"]]) - _sel.set_item_metadata(_sel.item_count - 1, e["id"]) - if _sel.item_count == 0: - _sel.add_item("– noch kein Server gespeichert –") - _sel.disabled = true - current_id = "" - return - _sel.disabled = false - var idx := 0 - for i in _sel.item_count: - if str(_sel.get_item_metadata(i)) == (select_id if select_id != "" else current_id): - idx = i - _sel.select(idx) - _on_selected() - - -func _on_selected() -> void: - if _sel.item_count == 0 or _sel.disabled: - return - var id := str(_sel.get_item_metadata(_sel.selected)) - if id != current_id: - _set_connected(false, "Nicht verbunden") - current_id = id - - -func _on_add() -> void: - _open_edit({}) - - -func _on_edit() -> void: - if current_id != "": - _open_edit(store.get_entry(current_id)) - - -func _open_edit(e: Dictionary) -> void: - _edit_id = str(e.get("id", "")) - _edit_dialog.title = "Server bearbeiten" if _edit_id != "" else "Server hinzufügen" - (_edit_fields["name"] as LineEdit).text = str(e.get("name", "")) - (_edit_fields["host"] as LineEdit).text = str(e.get("host", "")) - (_edit_fields["port"] as LineEdit).text = str(e.get("port", ServerStore.DEFAULT_PORT)) - (_edit_fields["token"] as LineEdit).text = str(e.get("token", "")) - (_edit_fields["tls"] as CheckBox).button_pressed = bool(e.get("tls", false)) - (_edit_fields["_err"] as Label).text = "" - _edit_dialog.popup_centered(UIScale.v2i(380, 420)) - - -func _entry_from_dialog() -> Dictionary: - return { - "id": _edit_id, "name": (_edit_fields["name"] as LineEdit).text, - "host": (_edit_fields["host"] as LineEdit).text.strip_edges(), - "port": int((_edit_fields["port"] as LineEdit).text), - "token": (_edit_fields["token"] as LineEdit).text, - "tls": (_edit_fields["tls"] as CheckBox).button_pressed} - - -func _on_edit_confirmed() -> void: - var id := store.upsert(_entry_from_dialog()) - if id == "": - _notify(store.last_error) - return - _refresh_selector(id) - - -func _test_dialog_entry() -> void: - var e := _entry_from_dialog() - var err := AdminClient.check_address(str(e["host"]), int(e["port"])) - var lbl: Label = _edit_fields["_err"] - if err != "": - lbl.text = err - return - lbl.text = "Teste …" - var probe := AdminClient.new() - add_child(probe) - probe.use(e) - var res: Dictionary = await probe.call_api("GET", "/ping") - if bool(res["ok"]): - var auth: Dictionary = await probe.call_api("GET", "/status") - lbl.text = "✅ Server gefunden. " + ("Token passt." if bool(auth["ok"]) else AdminTexte.erklaere(auth)) - else: - lbl.text = "❌ " + AdminTexte.erklaere(res) - probe.queue_free() - - -func _on_remove() -> void: - if current_id == "": - return - var e := store.public_view(current_id) - _ask("„%s“ aus der Liste entfernen? (Der Server selbst bleibt unverändert.)" % str(e["name"]), func() -> void: - store.remove(current_id) - current_id = "" - _set_connected(false, "Nicht verbunden") - _refresh_selector()) - - -# ---------------------------------------------------------------- Verbinden -- - -func connect_selected() -> bool: - if current_id == "": - _notify("Bitte erst einen Server hinzufügen (➕ Neu).") - return false - client.use(store.get_entry(current_id)) - _conn_label.text = "Verbinde …" - var ping: Dictionary = await client.call_api("GET", "/ping") - if not bool(ping["ok"]): - _set_connected(false, "❌ " + AdminTexte.erklaere(ping)) - return false - var st: Dictionary = await client.call_api("GET", "/status") - if not bool(st["ok"]): - _set_connected(false, "❌ " + AdminTexte.erklaere(st)) - return false - _set_connected(true, "✅ Verbunden") - await refresh_all() - return true - - -func _set_connected(on: bool, text: String) -> void: - connected = on - _conn_label.text = text - _live_box.visible = on - - -## Ruft die API auf und meldet Fehler verständlich. null = Fehler (schon gemeldet). -func _api(method: String, path: String, body: Variant = null, query: Dictionary = {}) -> Variant: - var res: Dictionary = await client.call_api(method, path, body, query) - if bool(res["ok"]): - return res["body"] - var text := AdminTexte.erklaere(res) - if int(res.get("status", 0)) in [0, 401, 429]: - _set_connected(false, "❌ " + text.split("\n")[0]) - _notify(text) - return null - - -func _notify(text: String) -> void: - last_notice = text - _notice.text = text - - -func refresh_all() -> void: - await refresh_status() - await refresh_settings() - await refresh_players() - await refresh_maps() - - -# ------------------------------------------------------------------ Status -- - -func refresh_status() -> void: - var s: Variant = await _api("GET", "/status") - if s == null: - return - var p: Dictionary = s["players"] - var h := int(s["uptime_s"]) / 3600 - var m := (int(s["uptime_s"]) % 3600) / 60 - _status_label.text = "%s\nMap: %s · Modus: %s · Phase: %s\nSpieler: %d von %d (+ %d Bots) · Restzeit %d s\nLäuft seit %d h %d min · %s · Passwort: %s · Master: %s" % [ - s["server_name"], s["map"]["name"], str(s["mode"]).to_upper(), s["phase"], - p["humans"], p["max"], p["bots"], int(s["time_remaining_s"]), h, m, - "öffentlich" if s["public"] else "privat", "ja" if s["password_set"] else "nein", s["master"]] - - -# ------------------------------------------------------------ Einstellungen -- - -func refresh_settings() -> void: - var r: Variant = await _api("GET", "/settings") - if r == null: - return - _settings_spec = r["spec"] - _settings_loaded = r["settings"] - for c in _settings_box.get_children(): - c.queue_free() - _settings_editors.clear() - for key in _settings_spec.keys(): - var sp: Dictionary = _settings_spec[key] - var lbl := _field_label("%s (%s)" % [sp["label"], AdminTexte.wirkung(str(sp["effect"]))]) - _settings_box.add_child(lbl) - var ed: Control - match str(sp["type"]): - "bool": - ed = CheckBox.new() - "int", "float": - var sb := SpinBox.new() - sb.min_value = float(sp["min"]) - sb.max_value = float(sp["max"]) - sb.step = 1.0 if str(sp["type"]) == "int" else 0.5 - ed = sb - "enum": - var ob := OptionButton.new() - for v in sp["values"]: - ob.add_item(str(v)) - ed = ob - _: - var le := LineEdit.new() - le.max_length = int(sp.get("max_len", 64)) - if key == "password": - le.secret = true - le.placeholder_text = "(unverändert)" - ed = le - _settings_box.add_child(ed) - _settings_editors[key] = ed - _fill_settings_editors() - - -func _fill_settings_editors() -> void: - for key in _settings_editors.keys(): - var ed: Control = _settings_editors[key] - var sp: Dictionary = _settings_spec[key] - if key == "password": - (ed as LineEdit).text = "" - (ed as LineEdit).placeholder_text = "(gesetzt – leer lassen = unverändert)" if bool(_settings_loaded.get("password_set", false)) else "(kein Passwort)" - continue - var v: Variant = _settings_loaded.get(key) - match str(sp["type"]): - "bool": (ed as CheckBox).button_pressed = bool(v) - "int", "float": (ed as SpinBox).value = float(v) - "enum": (ed as OptionButton).select(maxi(0, (sp["values"] as Array).find(v))) - _: (ed as LineEdit).text = str(v) - _settings_result.text = "" - - -## Nur geänderte Werte (Passwort nur, wenn etwas eingetippt wurde). -func changed_settings() -> Dictionary: - var out := {} - for key in _settings_editors.keys(): - var ed: Control = _settings_editors[key] - var sp: Dictionary = _settings_spec[key] - var v: Variant - match str(sp["type"]): - "bool": v = (ed as CheckBox).button_pressed - "int": v = int((ed as SpinBox).value) - "float": v = (ed as SpinBox).value - "enum": v = (sp["values"] as Array)[(ed as OptionButton).selected] - _: v = (ed as LineEdit).text - if key == "password": - if str(v) != "": - out[key] = v - continue - if v != _settings_loaded.get(key): - out[key] = v - return out - - -func save_settings() -> void: - var ch := changed_settings() - if ch.is_empty(): - _settings_result.text = "Nichts geändert." - return - var r: Variant = await _api("PATCH", "/settings", ch) - if r == null: - return - var lines: PackedStringArray = [] - if not (r["applied_now"] as Array).is_empty(): - lines.append("✅ Sofort aktiv: " + ", ".join(_labels(r["applied_now"]))) - if not (r["applies_next_map"] as Array).is_empty(): - lines.append("⏭ Ab der nächsten Map: " + ", ".join(_labels(r["applies_next_map"]))) - if not (r["needs_restart"] as Array).is_empty(): - lines.append("🔁 Erst nach Server-Neustart: " + ", ".join(_labels(r["needs_restart"]))) - for w in r.get("warnings", []): - lines.append("⚠ " + str(w)) - _settings_result.text = "\n".join(lines) - last_notice = _settings_result.text - _settings_loaded = r["settings"] - _fill_settings_editors() - _settings_result.text = "\n".join(lines) - - -func _labels(keys: Array) -> Array: - return keys.map(func(k: Variant) -> String: return str((_settings_spec.get(k, {}) as Dictionary).get("label", k))) - - -# ----------------------------------------------------------------- Spieler -- - -func refresh_players() -> void: - var r: Variant = await _api("GET", "/players") - var b: Variant = await _api("GET", "/bans") - if r == null or b == null: - return - for c in _players_box.get_children(): - c.queue_free() - if (r["players"] as Array).is_empty(): - _players_box.add_child(_muted_label("Gerade ist niemand auf dem Server.")) - for p in r["players"]: - var row := HBoxContainer.new() - var lbl := Label.new() - lbl.text = "%s (Team %s · %d/%d · %d ms)" % [p["name"], "Blau" if int(p["team"]) == 0 else "Rot", p["kills"], p["deaths"], p["ping_ms"]] - lbl.size_flags_horizontal = Control.SIZE_EXPAND_FILL - lbl.clip_text = true - row.add_child(lbl) - var pid := int(p["peer_id"]) - var pname := str(p["name"]) - row.add_child(_btn("Kick", func() -> void: _ask("„%s“ vom Server werfen?" % pname, func() -> void: await kick(pid)))) - row.add_child(_btn("Sperren", func() -> void: _ask("„%s“ sperren (%s)?" % [pname, BAN_DAUER[_ban_minutes.selected][1]], func() -> void: await ban(pid)))) - _players_box.add_child(row) - for c in _bans_box.get_children(): - c.queue_free() - if (b["bans"] as Array).is_empty(): - _bans_box.add_child(_muted_label("Niemand gesperrt.")) - for ban_e in b["bans"]: - var row2 := HBoxContainer.new() - var l2 := Label.new() - var until := int(ban_e.get("until", 0)) - l2.text = "%s – %s" % [str(ban_e.get("name", "?")), "dauerhaft" if until == 0 else "bis " + Time.get_datetime_string_from_unix_time(until, true)] - l2.size_flags_horizontal = Control.SIZE_EXPAND_FILL - l2.clip_text = true - row2.add_child(l2) - var bid := str(ban_e["id"]) - row2.add_child(_btn("Aufheben", func() -> void: await unban(bid))) - _bans_box.add_child(row2) - - -func kick(peer_id: int) -> void: - if await _api("POST", "/players/%d/kick" % peer_id, {}) != null: - _notify("Spieler wurde vom Server geworfen.") - await refresh_players() - - -func ban(peer_id: int, minutes: int = -1) -> void: - if minutes < 0: - minutes = int(BAN_DAUER[_ban_minutes.selected][0]) - if await _api("POST", "/players/%d/ban" % peer_id, {"minutes": minutes}) != null: - _notify("Spieler gesperrt (%s)." % AdminTexte.sperrdauer_text(minutes)) - await refresh_players() - - -func unban(ban_id: String) -> void: - if await _api("DELETE", "/bans/" + ban_id) != null: - _notify("Sperre aufgehoben.") - await refresh_players() - - -# -------------------------------------------------------------- Match, Maps -- - -func _do_restart() -> void: - if await _api("POST", "/match/restart", {}) != null: - _notify("Match wird neu gestartet.") - await refresh_status() - - -## Ganzen Server neu starten und warten, bis er wieder antwortet; dann neu verbinden. -func restart_server() -> bool: - var id := current_id - if await _api("POST", "/restart", {}) == null: - return false - _set_connected(false, "Server startet neu…") - _notify("Server startet neu…") - var res: Dictionary = await _wait_for_new_server(id) - if current_id != id: - return false # inzwischen anderen Server gewählt - if not bool(res["ok"]): - _set_connected(false, "❌ " + str(res["text"])) - _notify(str(res["text"])) - return false - var ok: bool = await connect_selected() - if ok: - _notify("✅ Server wurde neu gestartet.") - return ok - - -## Der alte Prozess antwortet noch kurz: Erst eine Laufzeit, die kleiner ist als die -## Wartezeit bisher, beweist den neuen Prozess. -func _wait_for_new_server(id: String) -> Dictionary: - var start := Time.get_ticks_msec() - while current_id == id: - var waited := (Time.get_ticks_msec() - start) / 1000.0 - if waited >= restart_wait_s: - return {"ok": false, "text": AdminTexte.neustart_zeitueberschreitung(int(restart_wait_s))} - var st: Dictionary = await client.call_api("GET", "/status") - if bool(st["ok"]): - if float(st["body"].get("uptime_s", INF)) <= (Time.get_ticks_msec() - start) / 1000.0: - return {"ok": true, "text": ""} - elif int(st.get("status", 0)) in [401, 429]: - return {"ok": false, "text": AdminTexte.erklaere(st)} - await get_tree().create_timer(restart_poll_s).timeout - return {"ok": false, "text": ""} - - -func refresh_maps() -> void: - var r: Variant = await _api("GET", "/maps") - if r == null: - return - for c in _maps_box.get_children(): - c.queue_free() - _rotation_checks.clear() - for m in r["maps"]: - var row := HBoxContainer.new() - var cb := CheckBox.new() - cb.button_pressed = bool(m["in_rotation"]) - cb.tooltip_text = "In der Rotation" - row.add_child(cb) - _rotation_checks[str(m["id"])] = cb - var lbl := Label.new() - lbl.text = "%s%s%s" % [m.get("name", m["file"]), " ▶ läuft" if m["active"] else "", " (eingebaut)" if m["source"] == "builtin" else ""] - lbl.size_flags_horizontal = Control.SIZE_EXPAND_FILL - lbl.clip_text = true - row.add_child(lbl) - var mid := str(m["id"]) - var mname := str(m.get("name", m["file"])) - row.add_child(_btn("Laden", func() -> void: _ask("„%s“ jetzt auf dem Server laden? Die laufende Runde endet." % mname, func() -> void: await load_map(mid)))) - if m["source"] == "upload": - var slug := mid.get_file().get_basename() - row.add_child(_btn("🗑", func() -> void: _ask("„%s“ vom Server LÖSCHEN? Das kann nicht rückgängig gemacht werden." % mname, func() -> void: await delete_map(slug)))) - _maps_box.add_child(row) - - -func load_map(map_id: String) -> void: - if await _api("POST", "/match/map", {"map": map_id}) != null: - _notify("Map wird geladen.") - await refresh_status() - - -func delete_map(slug: String) -> void: - if await _api("DELETE", "/maps/" + slug) != null: - _notify("Map gelöscht.") - await refresh_maps() - - -func save_rotation() -> void: - var ids: Array = [] - for id in _rotation_checks.keys(): - if (_rotation_checks[id] as CheckBox).button_pressed: - ids.append(id) - if ids.is_empty(): - _notify("Die Rotation braucht mindestens eine Map.") - return - if await _api("PUT", "/rotation", {"maps": ids}) != null: - _notify("Rotation gespeichert (%d Maps)." % ids.size()) - await refresh_maps() - - -# -------------------------------------------------------------------- Push -- - -func push_current_map(overwrite: bool = false) -> Dictionary: - _push_result.text = "Prüfe und lade hoch …" - var res: Dictionary = await MapPush.push(client, main.doc, { - "name": _push_name.text, "overwrite": overwrite, "add_to_rotation": _push_rot.button_pressed}) - _push_result.text = ("✅ " if bool(res["ok"]) else "❌ ") + str(res["text"]) - last_notice = _push_result.text - if bool(res["exists"]): - _ask("Auf dem Server gibt es schon eine Map mit diesem Namen. Ersetzen?", func() -> void: await push_current_map(true)) - elif bool(res["ok"]): - await refresh_maps() - return res - - -# -------------------------------------------------------------------- Logs -- - -func load_logs() -> void: - var q := {"lines": 300} - if _log_filter.text.strip_edges() != "": - q["filter"] = _log_filter.text.strip_edges() - var r: Variant = await _api("GET", "/logs", null, q) - if r == null: - return - _log_text.text = "\n".join(r["lines"]) - _log_text.scroll_vertical = _log_text.get_line_count() - - -func _ask(text: String, action: Callable) -> void: - _confirm.dialog_text = text - _confirm_action = action - _confirm.popup_centered(UIScale.v2i(380, 140)) diff --git a/src/ui/panels/server_panel.gd.uid b/src/ui/panels/server_panel.gd.uid deleted file mode 100644 index 5330efa..0000000 --- a/src/ui/panels/server_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://62khp60nljbt diff --git a/src/ui/panels/settings_panel.gd b/src/ui/panels/settings_panel.gd deleted file mode 100644 index f0af29f..0000000 --- a/src/ui/panels/settings_panel.gd +++ /dev/null @@ -1,160 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Einstellungen (Fenster „⚙ Einstellungen“ in der Kopfleiste — Karte -## t_aaff5dcc, T3 Komfort; 25.10. Test-Befund: Gitter, Höhenlinien, Symmetrie- -## Modus, UI-Größe, Raster-Snap, Gizmo-Schrittweite und „Karte prüfen“ ziehen -## aus Kopfleiste/Objekt-Werkzeugen hierher). -## -## Registry-Weg (Operator-Vorgabe 20.10.): main.gd bleibt unangetastet, das -## Modul meldet sich nur über src/ui/panels/registry.gd an. Der ZUSTAND lebt -## in src/editor/playtest/playtest_settings.gd (PlaytestSettings, user://-cfg) — -## dieses Panel zeigt/anpasst nur. Läuft gerade ein Testlauf, wird die neue -## Maus-Empfindlichkeit SOFORT über main.playtest.apply_sensitivity wirksam. - -var sens_box: SpinBox -## Perspektive im Testlauf (Karte t_17a35c59): Erste/Dritte Person, derselbe -## Eintrag wie Taste V (PlaytestSettings, persistiert). -var perspektive_box: OptionButton - -# Ansicht / Platzieren (vorher Kopfleiste und Tab „Objekt-Werkzeuge“). main -# hält dieselben Namen als Referenzen (grid_btn, contours_btn, size_menu, …). -var grid_btn: CheckButton -var contours_btn: CheckButton -var size_menu: OptionButton -var sym_menu: OptionButton -var raster_snap_check: CheckButton -var gizmo_step_box: SpinBox -var check_btn: Button - - -static func spec() -> Dictionary: - return {"titel": "Einstellungen", "gruppe": "dialog", "order": 10} - - -func panel_title() -> String: - return "Einstellungen" - - -func build() -> void: - add_child(_header_label("Ansicht")) - grid_btn = CheckButton.new() - grid_btn.text = "⊞ Maßstabsgitter (100-m-Raster)" - grid_btn.custom_minimum_size = UIScale.v2(0, 36) - grid_btn.tooltip_text = "Maßstabsgitter (100-m-Raster) im Viewport ein-/ausblenden. Über sichtbarem Terrain ist es standardmäßig aus." - grid_btn.toggled.connect(func(pressed: bool) -> void: main.call("_on_grid_toggled", pressed)) - add_child(grid_btn) - - contours_btn = CheckButton.new() - contours_btn.text = "≈ Höhenlinien fixieren" - contours_btn.custom_minimum_size = UIScale.v2(0, 36) - contours_btn.tooltip_text = "Höhenlinien (1 m, alle 5 m kräftiger) FIXIERT an/aus. Ohne Fixierung erscheinen sie nur im Terrain-Werkzeug (F1). Taste L schaltet ebenfalls. Bei flachem Terrain (< 2 m) sind sie automatisch aus." - contours_btn.toggled.connect(func(pressed: bool) -> void: main.call("_on_contours_toggled", pressed)) - add_child(contours_btn) - - add_child(_field_label("UI-Größe")) - size_menu = OptionButton.new() - for i in UIScale.step_count(): - size_menu.add_item(UIScale.step_label(i), i) - size_menu.custom_minimum_size = UIScale.v2(0, 36) - size_menu.tooltip_text = "Größe der Oberfläche: Klein (wie bisher), Mittel (1,25-fach), Groß (1,5-fach). Wirkt sofort und bleibt gespeichert." - size_menu.item_selected.connect(func(index: int) -> void: main.call("_on_ui_size_selected", index)) - add_child(size_menu) - - add_child(_separator()) - add_child(_header_label("Bauen & Platzieren")) - raster_snap_check = CheckButton.new() - raster_snap_check.text = "Raster-Snap (1 m)" - raster_snap_check.custom_minimum_size = UIScale.v2(0, 36) - raster_snap_check.tooltip_text = "Neue und verschobene Objekte rasten auf ein 1-Meter-Raster ein (Strg gedrückt halten geht immer)" - raster_snap_check.toggled.connect(func(pressed: bool) -> void: main.call("_on_grid_snap_changed", pressed)) - add_child(raster_snap_check) - - add_child(_field_label("Gizmo-Schrittweite (m)")) - gizmo_step_box = SpinBox.new() - gizmo_step_box.min_value = 0.01 - gizmo_step_box.max_value = 10.0 - gizmo_step_box.step = 0.01 - gizmo_step_box.value = main.gizmo_step_m - gizmo_step_box.custom_minimum_size = UIScale.v2(0, 36) - gizmo_step_box.tooltip_text = "Wie weit bewegt sich das Objekt am Achsen-Gizmo pro Schritt (in Metern). Mausrad WÄHREND des Ziehens wechselt zwischen fein (0.1) / normal (0.5) / grob (2.0)." - gizmo_step_box.value_changed.connect(func(v: float) -> void: - main.gizmo_step_m = v - if main.gizmo != null and is_instance_valid(main.gizmo): - main.gizmo.set_step_m(v)) - add_child(gizmo_step_box) - - add_child(_separator()) - add_child(_header_label("Symmetrie & Prüfen")) - add_child(_field_label("Symmetrie-Modus")) - sym_menu = OptionButton.new() - for i in SymmetryCore.MODE_LABELS.size(): - sym_menu.add_item("Symmetrie: %s" % SymmetryCore.MODE_LABELS[i], i) - sym_menu.custom_minimum_size = UIScale.v2(0, 36) - sym_menu.tooltip_text = "Gespiegeltes Bauen: Änderungen werden automatisch auf die andere Kartenseite übertragen. Aus / Punkt (180° um die Kartenmitte) / Achse X / Achse Z. Standard: Punkt." - sym_menu.item_selected.connect(func(index: int) -> void: main.call("_on_sym_mode_selected", index)) - add_child(sym_menu) - - check_btn = Button.new() - check_btn.text = "✅ Karte prüfen" - check_btn.custom_minimum_size = UIScale.v2(0, 40) - check_btn.tooltip_text = "Prüft, ob die Map bereit für den Export ist — sagt VORHER, was fehlt" - check_btn.pressed.connect(func() -> void: main.call("_on_check_map")) - add_child(check_btn) - - add_child(_separator()) - add_child(_header_label("Testlauf-Einstellungen")) - - add_child(_field_label("Maus-Empfindlichkeit (0,1 – 5,0)")) - sens_box = SpinBox.new() - sens_box.min_value = PlaytestSettings.MIN_SENS - sens_box.max_value = PlaytestSettings.MAX_SENS - sens_box.step = 0.1 - sens_box.value = PlaytestSettings.load_sens() - sens_box.custom_minimum_size = UIScale.v2(0, 36) - sens_box.tooltip_text = "Multiplikator auf die Blick-Geschwindigkeit im Testlauf. 1,0 = Standard; kleine Werte = feinfühlig, große Werte = schnell." - sens_box.value_changed.connect(_on_sens_changed) - add_child(sens_box) - - add_child(_field_label("Perspektive im Testlauf")) - perspektive_box = OptionButton.new() - perspektive_box.add_item("Erste Person (Standard)") - perspektive_box.add_item("Dritte Person (Bot-Avatar)") - perspektive_box.selected = 1 if PlaytestSettings.load_third() else 0 - perspektive_box.custom_minimum_size = UIScale.v2(0, 36) - perspektive_box.tooltip_text = "Dritte Person zeigt denselben Avatar wie die Bots im Spiel (Taste V schaltet im Testlauf ebenfalls). Dritte Person braucht die Avatar-Modelle aus dem Client-Klon." - perspektive_box.item_selected.connect(_on_perspektive_changed) - add_child(perspektive_box) - - add_child(_separator()) - - -func _on_sens_changed(value: float) -> void: - PlaytestSettings.save_sens(value) - var pt: Variant = main.get("playtest") - if pt != null and pt.has_method("apply_sensitivity"): - pt.call("apply_sensitivity", value) - - -func _on_perspektive_changed(index: int) -> void: - var dritte := index == 1 - PlaytestSettings.save_third(dritte) - # Live anwenden, falls der Testlauf gerade läuft. Ohne Avatar-Modelle - # bleibt First Person aktiv (set_perspektive lehnt Third ab) — der - # Klartext-Grund steht beim Start/V-Druck im HUD. - var pt: Variant = main.get("playtest") - if pt == null: - return - var body: Variant = pt.get("body") - if body != null: - body.call("set_perspektive", dritte) - - -## Schalter aus dem Editor-Zustand nachziehen (beim Öffnen des Fensters). -func refresh() -> void: - if main == null: - return - grid_btn.set_pressed_no_signal(bool(main.get("_grid_on"))) - contours_btn.set_pressed_no_signal(bool(main.get("_contours_on"))) - raster_snap_check.set_pressed_no_signal(bool(main.get("grid_snap"))) - gizmo_step_box.set_value_no_signal(float(main.gizmo_step_m)) - size_menu.select(UIScale.step_index()) - sym_menu.select(int(main.get("sym_mode"))) diff --git a/src/ui/panels/settings_panel.gd.uid b/src/ui/panels/settings_panel.gd.uid deleted file mode 100644 index 342df31..0000000 --- a/src/ui/panels/settings_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bp0ii5exucqcy diff --git a/src/ui/panels/status_bar.gd b/src/ui/panels/status_bar.gd deleted file mode 100644 index a35f119..0000000 --- a/src/ui/panels/status_bar.gd +++ /dev/null @@ -1,81 +0,0 @@ -extends HBoxContainer -## Statusleiste (aus main.gd ausgezogen, Karte t_eaccbfed U1 — Logik -## unverändert): Hilfs-Meldungen + permanente Werkzeug-Anzeige + -## Symmetrie-Anzeige + Objekt-/Terrain-Zähler + FPS-Timer. - -var main # src/ui/main.gd -var status_label: Label -var tool_label: Label # permanenter Werkzeugmodus + Flug-Hint -var sym_label: Label -var stats_objects: Label -var stats_terrain: Label - - -static func spec() -> Dictionary: - return {"titel": "Statuszeile", "gruppe": "status", "order": 0} - - -func setup(p_main) -> void: - main = p_main - # Eine Leiste ist EINE Zeile (VBox-Erbe stapelte alle Labels senkrecht → - # riesiger Balken, Befund 25.10.). - size_flags_vertical = Control.SIZE_SHRINK_END - size_flags_horizontal = Control.SIZE_EXPAND_FILL - - -func theme_color(cname: String) -> Color: - if main != null and main.theme != null and main.theme.has_color(cname, "Editor"): - return main.theme.get_color(cname, "Editor") - return get_theme_color(cname, "Editor") - - -func build() -> void: - add_theme_constant_override("separation", UIScale.px(16)) - status_label = Label.new() - status_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL - status_label.clip_text = true # langer Text darf das Layout NICHT sprengen - add_child(status_label) - - # Karte 3/3 (t_11b5c25b): PERMANENTE Werkzeug-Anzeige — Sly sieht immer, - # in welchem Werkzeug er ist, plus Hint für den Flugmodus (Umschalt+F). - tool_label = Label.new() - # U7: Werkzeug-Farbe über Theme (Editor/colors/accent). - tool_label.add_theme_color_override("font_color", - theme_color("accent")) - # Karte t_297221b5: Statuszeilen-Labels egalisiert (min-size-Druck bei 1.5×) - tool_label.clip_text = true - tool_label.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS - add_child(tool_label) - - # Symmetrie-Anzeige (Karte t_f5935023, M1): Sly sieht in der Statuszeile - # immer, ob/wie gespiegelt wird (Standard: Punkt). - sym_label = Label.new() - # U7: Symmetrie-Farbe über Theme (Editor/colors/accent). - sym_label.add_theme_color_override("font_color", - theme_color("accent")) - sym_label.clip_text = true - sym_label.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS - add_child(sym_label) - - stats_objects = Label.new() - # U7: Nebentext-Farbe über Theme (Editor/colors/field). - stats_objects.add_theme_color_override("font_color", - theme_color("field")) - stats_objects.clip_text = true - stats_objects.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS - add_child(stats_objects) - - # Terrain-Anteil + Editor-FPS (Perf-Zähler, Karte t_9aba04f1) - stats_terrain = Label.new() - # U7: Nebentext-Farbe über Theme (Editor/colors/field). - stats_terrain.add_theme_color_override("font_color", - theme_color("field")) - stats_terrain.clip_text = true - stats_terrain.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS - add_child(stats_terrain) - - var fps_timer := Timer.new() - fps_timer.wait_time = 0.5 - fps_timer.autostart = true - fps_timer.timeout.connect(main.call.bind("_refresh_stats")) - add_child(fps_timer) diff --git a/src/ui/panels/status_bar.gd.uid b/src/ui/panels/status_bar.gd.uid deleted file mode 100644 index afaedfb..0000000 --- a/src/ui/panels/status_bar.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dddgvtqqr3lau diff --git a/src/ui/panels/symmetry_panel.gd b/src/ui/panels/symmetry_panel.gd deleted file mode 100644 index dac0b80..0000000 --- a/src/ui/panels/symmetry_panel.gd +++ /dev/null @@ -1,237 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Symmetrie-Panel (M5, Karte t_60014669 — Spec /opt/data/scopedvr/ -## KARTEN_MIRROR_vc27.md): Ein-Klick „Karte symmetrisch machen“ + Symmetrie- -## Check mit Klartext-Bericht. Erlaubnis-Regel des Operators (20.10.): -## main.gd NICHT anfassen — dieses Modul meldet sich über die Panel-Registry -## an (registry.gd, Eintrag) und greift wie alle Module über `main` auf -## Dokument/History zu. Die Spiegel-Arbeit lebt KOMPLETT in -## src/editor/symmetry_ops.gd (statisch, headless testbar). -## -## Ablauf „Karte symmetrisch machen“: -## 1. Symmetrie-Modus AUS → Hinweis, nichts passiert (Abnahme „Modus AUS -## ändert nichts“). -## 2. Analyse: nichts zu tun → Klartext „schon symmetrisch“, OHNE Undo. -## 3. Widersprüche? → Dialog nennt die ZAHL und lässt die Quell-Hälfte -## wählen (Sly entscheidet, bevor irgendwas überschrieben wird). -## 4. Anwenden = EIN Undo-Schritt (ActionHistory snapshotet das Dokument). - -const SymmetryOps := preload("res://src/editor/symmetry_ops.gd") - -var mode_label: Label -var half_label: Label -var half_option: OptionButton -var apply_btn: Button -var check_btn: Button -var report_label: Label -var conflict_dialog: ConfirmationDialog - -var _pending_high := false # Quell-Wahl des laufenden Widerspruchs-Dialogs - - -static func spec() -> Dictionary: - return {"titel": "Symmetrie", "gruppe": "map", "order": 30} - - -func panel_title() -> String: - return "Symmetrie" - - -func build() -> void: - add_child(_header_label("Symmetrie")) - add_child(_muted_label("Macht die ganze Karte symmetrisch: ergänzt die andere Seite, löscht nichts.")) - - mode_label = _field_label(_mode_text()) - add_child(mode_label) - - half_label = _field_label("Quell-Hälfte:") - add_child(half_label) - half_option = OptionButton.new() - half_option.custom_minimum_size = UIScale.v2(0, 36) - # U7: Klartext-Tooltip — welche Seite als Vorlage dient. - half_option.tooltip_text = "Welche Hälfte die Vorlage ist (die andere wird angepasst)" - half_option.item_selected.connect(_on_half_selected) - add_child(half_option) - _refresh_half_option() - - apply_btn = Button.new() - apply_btn.text = "🗺️ Karte symmetrisch machen" - apply_btn.custom_minimum_size = UIScale.v2(0, 48) - apply_btn.tooltip_text = "Ergänzt die andere Kartenseite (EIN Strg+Z macht alles rückgängig)" - apply_btn.pressed.connect(_on_apply_pressed) - add_child(apply_btn) - - check_btn = Button.new() - check_btn.text = "🔍 Symmetrie prüfen" - check_btn.custom_minimum_size = UIScale.v2(0, 40) - check_btn.tooltip_text = "Ehrlicher Bericht: Wo weicht die Karte von der Spiegelung ab?" - check_btn.pressed.connect(_on_check_pressed) - add_child(check_btn) - - report_label = _muted_label("") - report_label.custom_minimum_size = UIScale.v2(0, 96) - add_child(report_label) - - - conflict_dialog = ConfirmationDialog.new() - conflict_dialog.title = "Widersprüche — welche Seite gewinnt?" - conflict_dialog.dialog_close_on_escape = true - conflict_dialog.get_ok_button().text = "Anwenden" - conflict_dialog.confirmed.connect(_on_conflict_confirmed) - conflict_dialog.add_button("Andere Hälfte als Quelle", true, "other_half") - conflict_dialog.custom_action.connect(_on_conflict_other) - add_child(conflict_dialog) - - -# ------------------------------------------------------------- Zustands-Helfer - -func _current_mode() -> int: - ## Defensiv wie spawn_tool._sym_mode(): Mock-Mains ohne Feld → OFF. - var v: Variant = main.get("sym_mode") if main != null else null - return SymmetryCore.Mode.OFF if v == null else int(v) - - -func _mode_text() -> String: - var mode := _current_mode() - return "Modus: %s" % SymmetryCore.mode_label(mode) - - -func _source_high() -> bool: - ## false = erste Hälfte (links/vorn), true = zweite (rechts/hinten). - return half_option.selected == 1 - - -func _refresh_half_option() -> void: - var labels: Array = SymmetryOps.side_labels(_current_mode()) - half_option.clear() - half_option.add_item("Quelle: %s" % str(labels[0])) - half_option.add_item("Quelle: %s" % str(labels[1])) - half_option.selected = 0 - - -## Vom Einstellungen-Fenster gerufen, wenn der Modus wechselt. -func refresh_mode() -> void: - if mode_label == null or half_option == null: - return - _refresh_half_option() - _refresh_mode_line() - - -func _on_half_selected(_index: int) -> void: - _refresh_mode_line() - - -func _refresh_mode_line() -> void: - mode_label.text = _mode_text() - - -# ------------------------------------------------------------ Karte spiegeln -- - -func _on_apply_pressed() -> void: - var mode := _current_mode() - if mode == SymmetryCore.Mode.OFF: - _say("Der Symmetrie-Modus ist Aus — erst in den Einstellungen (⚙) Punkt oder eine Achse wählen.") - return - if main.doc.is_empty(): - _say("Keine Karte offen — erst eine Map anlegen oder laden.", true) - return - _refresh_mode_line() - _refresh_half_option() - var an := SymmetryOps.analyze(main.doc, mode) - if int(an["total_changes"]) == 0: - _say("Nichts zu tun — die Karte ist schon symmetrisch ✓") - return - if int(an["conflicts"]) == 0: - _apply(_source_high()) - return - _pending_high = _source_high() - conflict_dialog.dialog_text = _conflict_text(an) - conflict_dialog.get_ok_button().text = "Anwenden — %s gewinnt" % _half_name(_pending_high) - conflict_dialog.popup_centered(Vector2i(520, 260)) - - -## Klartext für den Widerspruchs-Dialog: ZAHL erst nennen, DANN anwenden -## (Spec: „Nichts wird gelöscht, ohne dass die Zahl vorher genannt wurde“). -func _conflict_text(an: Dictionary) -> String: - var parts: Array = [] - var obj_n := int(an["objects"]["diff"]) - var spawn_n := int(an["spawns"]["diff"]) - var boden_n := (an["terrain_cells"] as Array).size() + (an.get("material_cells", []) as Array).size() - if obj_n > 0: - parts.append("%d Objekt-Paare unterscheiden sich" % obj_n) - if spawn_n > 0: - parts.append("%d Spawn-Punkt-Paare unterscheiden sich" % spawn_n) - if boden_n > 0: - parts.append("%d Bodenstellen sind unterschiedlich" % boden_n) - var adds := int(an["adds"]) - var text := ", ".join(PackedStringArray(parts)) + ".\n\n" - text += "Beim Anwenden gewinnt die gewählte Quell-Hälfte (die andere Seite wird angepasst).\n" - if adds > 0: - text += "Zusätzlich werden %d fehlende Zwillinge ergänzt.\n" % adds - text += "Es wird NICHTS gelöscht. Ein Strg+Z macht alles rückgängig." - return text - - -func _half_name(high: bool) -> String: - var labels: Array = SymmetryOps.side_labels(_current_mode()) - return str(labels[1]) if high else str(labels[0]) - - -func _on_conflict_confirmed() -> void: - # OK = die im Auswahlfeld gewählte Quelle behalten (Dialog-Text nennt sie). - _apply(_pending_high) - - -func _on_conflict_other(_action: String) -> void: - conflict_dialog.hide() - _pending_high = not _pending_high - _apply(_pending_high) - - -## Snapshot über ALLE Blöcke; fehlt design_notes (alte Karte), wird es als -## null geseedet — sonst könnte das Undo den neu angelegten Block nicht -## entfernen (U3-Lektion: fehlernde Blöcke explizit als null snapshoten). -func _snapshot_all() -> Dictionary: - var snap: Dictionary = main.history.snapshot(main.doc.keys()) - if not snap.has("design_notes") and not main.doc.has("design_notes"): - snap["design_notes"] = null - return snap - - -func _apply(quelle_hoch: bool) -> void: - var mode := _current_mode() - var before: Dictionary = _snapshot_all() - var res := SymmetryOps.apply(main.doc, mode, quelle_hoch) - main.history.commit("Karte symmetrisch machen (%s → %s)" % [ - _half_name(quelle_hoch), _half_name(not quelle_hoch)], - before, main.history.snapshot(main.doc.keys())) - main.call("_after_structure_change") - var report := str(res["report"]) - report_label.text = report - # U7: Bericht-Farbe über Theme (Editor/colors/status_ok). - report_label.add_theme_color_override("font_color", theme_color("status_ok")) - main.call("_set_status", report.split(".")[0] + ".") - - -# ---------------------------------------------------------- Symmetrie-Check -- - -func _on_check_pressed() -> void: - var mode := _current_mode() - if mode == SymmetryCore.Mode.OFF: - _say("Der Symmetrie-Modus ist Aus — erst in den Einstellungen (⚙) Punkt oder eine Achse wählen, dann prüfen.") - return - _refresh_mode_line() - var rep := SymmetryOps.check(main.doc, mode) - var text := str(rep["text"]) - report_label.text = text - # U7: Bericht-Farben über Theme (Editor/colors/status_ok / warning). - report_label.add_theme_color_override("font_color", - theme_color("status_ok") if bool(rep["ok"]) else theme_color("warning")) - main.call("_set_status", text) - - -func _say(text: String, is_error := false) -> void: - report_label.text = text - # U7: Bericht-Farben über Theme (Editor/colors/warning / status_ok). - report_label.add_theme_color_override("font_color", - theme_color("warning") if is_error else theme_color("status_ok")) - main.call("_set_status", text, is_error) diff --git a/src/ui/panels/symmetry_panel.gd.uid b/src/ui/panels/symmetry_panel.gd.uid deleted file mode 100644 index 1c311e5..0000000 --- a/src/ui/panels/symmetry_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ceu6y127v6lxc diff --git a/src/ui/panels/terrain_panel.gd b/src/ui/panels/terrain_panel.gd deleted file mode 100644 index fe4cc11..0000000 --- a/src/ui/panels/terrain_panel.gd +++ /dev/null @@ -1,282 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Terrain-Werkzeug-Panel (aus main.gd ausgezogen, Karte t_eaccbfed U1 — -## Logik unverändert, Karte t_9aba04f1 + t_603ec1a8): großer Modus-Button + -## Pinsel-Modi, Material-Palette, Größe/Stärke-Regler. Werkzeug-Ein/Aus bleibt -## im Koordinator (main.gd _enter/_leave terrain), das Panel hält nur die -## Widgets und die Regler-Verdrahtung. - -var terrain_edit_btn: Button -var terrain_panel: VBoxContainer -var terrain_mode_raise: Button -var terrain_mode_lower: Button -var terrain_mode_smooth: Button -var terrain_mode_paint: Button -var terrain_mode_flatten: Button -var terrain_mode_ramp: Button -var terrain_falloff_label: Label -var terrain_falloff_slider: HSlider -var terrain_palette: VBoxContainer -var terrain_mat_buttons: Array = [] # Gras/Sand/Fels (ButtonGroup) -var terrain_size_btn_small: Button -var terrain_size_btn_medium: Button -var terrain_size_btn_large: Button -var terrain_radius_slider: HSlider -var terrain_radius_label: Label -var terrain_strength_slider: HSlider -var terrain_strength_label: Label -var terrain_paint_hint: Label # Malen: Hinweis auf die Raster-Feinheit (24.10.) -var terrain_weich_label: Label # Malen: Kante hart ↔ weich (25.10.) -var terrain_weich_slider: HSlider - - -static func spec() -> Dictionary: - return {"titel": "Terrain", "gruppe": "rechts", "order": 40} - - -func build() -> void: - terrain_edit_btn = Button.new() - terrain_edit_btn.text = "⛰ Terrain formen" - terrain_edit_btn.custom_minimum_size = UIScale.v2(0, 48) - terrain_edit_btn.toggle_mode = true - terrain_edit_btn.tooltip_text = "Boden formen: heben, senken, glätten, einebnen, Rampe (F1)" - terrain_edit_btn.pressed.connect(_on_terrain_btn_pressed) - add_child(terrain_edit_btn) - - terrain_panel = VBoxContainer.new() - terrain_panel.add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster - add_child(terrain_panel) - - terrain_panel.add_child(_field_label("Pinsel:")) - var mode_row := GridContainer.new() - mode_row.columns = 3 - mode_row.add_theme_constant_override("h_separation", UIScale.px(8)) # U7-Raster - mode_row.add_theme_constant_override("v_separation", UIScale.px(8)) - terrain_panel.add_child(mode_row) - var mode_group := ButtonGroup.new() - terrain_mode_raise = _terrain_mode_button("Heben ⬆", mode_group, - "Pinsel-Modus Heben: Boden unter dem Pinsel anheben (Taste 1)") - terrain_mode_lower = _terrain_mode_button("Senken ⬇", mode_group, - "Pinsel-Modus Senken: Boden unter dem Pinsel absenken (Taste 2)") - terrain_mode_smooth = _terrain_mode_button("Glätten ≈", mode_group, - "Pinsel-Modus Glätten: Höhenunterschiede verrutschen (Taste 3)") - terrain_mode_paint = _terrain_mode_button("Malen 🖌", mode_group, - "Pinsel-Modus Malen: Material auf den Boden malen (Taste 4)") - terrain_mode_flatten = _terrain_mode_button("Einebnen ▬", mode_group, - "Pinsel-Modus Einebnen: zieht den Boden auf die Höhe, die beim Strichstart unter dem Cursor war") - terrain_mode_ramp = _terrain_mode_button("Rampe ◢", mode_group, - "Pinsel-Modus Rampe: Klick = Start, ziehen und loslassen = Ende — Höhe läuft gleichmäßig dazwischen (Breite = Pinselgröße)") - terrain_mode_raise.button_pressed = true - terrain_mode_flatten.toggled.connect(_on_terrain_mode_changed) - terrain_mode_ramp.toggled.connect(_on_terrain_mode_changed) - terrain_mode_raise.toggled.connect(_on_terrain_mode_changed) - terrain_mode_lower.toggled.connect(_on_terrain_mode_changed) - terrain_mode_smooth.toggled.connect(_on_terrain_mode_changed) - terrain_mode_paint.toggled.connect(_on_terrain_mode_changed) - mode_row.add_child(terrain_mode_raise) - mode_row.add_child(terrain_mode_lower) - mode_row.add_child(terrain_mode_smooth) - mode_row.add_child(terrain_mode_flatten) - mode_row.add_child(terrain_mode_ramp) - # Malen hat seit 25.10. einen eigenen Tab (malen_panel.gd); der Modus-Knopf - # bleibt unsichtbar in der ButtonGroup (Taste 4, Malen-Tab-Knopf). - terrain_mode_paint.visible = false - terrain_panel.add_child(terrain_mode_paint) - - # Pinselgrößen-Presets (Karte t_603ec1a8): drei große Buttons + freier Slider. - terrain_panel.add_child(_field_label("Pinselgröße:")) - var size_row := HBoxContainer.new() - size_row.add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster - terrain_panel.add_child(size_row) - var size_group := ButtonGroup.new() - terrain_size_btn_small = _terrain_size_button("Klein\n(4 m)", size_group, 4.0) - terrain_size_btn_medium = _terrain_size_button("Mittel\n(12 m)", size_group, 12.0) - terrain_size_btn_large = _terrain_size_button("Groß\n(32 m)", size_group, 32.0) - # Kein Signal: Der Handler greift auf terrain_radius_slider zu, der erst - # unten erzeugt wird — beim Panel-Bau wäre das ein Crash (GUI-Start-Bug - # 15.10.). Der Slider startet unten passend mit 12 m (= Mittel). - terrain_size_btn_medium.set_pressed_no_signal(true) - size_row.add_child(terrain_size_btn_small) - size_row.add_child(terrain_size_btn_medium) - size_row.add_child(terrain_size_btn_large) - - terrain_radius_label = _field_label("Pinsel-Größe: 12 m") - terrain_panel.add_child(terrain_radius_label) - terrain_radius_slider = HSlider.new() - terrain_radius_slider.min_value = 1.0 - terrain_radius_slider.max_value = 64.0 - terrain_radius_slider.step = 1.0 - terrain_radius_slider.value = 12.0 - terrain_radius_slider.custom_minimum_size = UIScale.v2(0, 32) - terrain_radius_slider.value_changed.connect(_on_terrain_radius_changed) - terrain_panel.add_child(terrain_radius_slider) - - terrain_strength_label = _field_label("Stärke: 8 m pro Sekunde") - terrain_panel.add_child(terrain_strength_label) - terrain_strength_slider = HSlider.new() - terrain_strength_slider.min_value = 1.0 - terrain_strength_slider.max_value = 20.0 - terrain_strength_slider.step = 0.5 - terrain_strength_slider.value = 8.0 - terrain_strength_slider.custom_minimum_size = UIScale.v2(0, 32) - terrain_strength_slider.value_changed.connect(_on_terrain_strength_changed) - terrain_panel.add_child(terrain_strength_slider) - - # Pinsel-Kante (Falloff, Karte 25.10.): ein Regler hart ↔ weich für alle - # Höhen-Pinsel (Malen hat seinen eigenen Kanten-Regler weiter unten). - terrain_falloff_label = _field_label("Kante: 50 % weich") - terrain_panel.add_child(terrain_falloff_label) - terrain_falloff_slider = HSlider.new() - terrain_falloff_slider.min_value = 0.0 - terrain_falloff_slider.max_value = 100.0 - terrain_falloff_slider.step = 5.0 - terrain_falloff_slider.value = 50.0 - terrain_falloff_slider.custom_minimum_size = UIScale.v2(0, 32) - terrain_falloff_slider.tooltip_text = "Links = harte Kante (breiter Kern), rechts = weich auslaufend" - terrain_falloff_slider.value_changed.connect(_on_terrain_falloff_changed) - terrain_panel.add_child(terrain_falloff_slider) - - - -func _on_terrain_btn_pressed() -> void: - if terrain_edit_btn.button_pressed: - if terrain_mode_paint.button_pressed: - terrain_mode_raise.button_pressed = true # Malen hat seinen eigenen Tab - main.call("_set_tool_mode", "terrain") - refresh_panels() - else: - main.call("_set_tool_mode", "objects") - - -func _terrain_mode_button(text: String, group: ButtonGroup, hinweis: String) -> Button: - var btn := Button.new() - btn.text = text - btn.toggle_mode = true - btn.button_group = group - btn.custom_minimum_size = UIScale.v2(0, 40) - btn.tooltip_text = hinweis # U7: Werkzeugname + Taste im Tooltip - return btn - - -func _selected_terrain_mode() -> int: - if terrain_mode_lower.button_pressed: - return TerrainField.Mode.LOWER - if terrain_mode_smooth.button_pressed: - return TerrainField.Mode.SMOOTH - if terrain_mode_paint.button_pressed: - return TerrainField.Mode.PAINT - if terrain_mode_flatten != null and terrain_mode_flatten.button_pressed: - return TerrainField.Mode.FLATTEN - if terrain_mode_ramp != null and terrain_mode_ramp.button_pressed: - return TerrainField.Mode.RAMP - return TerrainField.Mode.RAISE - - -## Mode-Buttons (ButtonGroup) → Pinsel-Modus; Palette nur im Malen-Modus. -func _on_terrain_mode_changed(_pressed: bool) -> void: - var paint := _selected_terrain_mode() == TerrainField.Mode.PAINT - if terrain_palette != null: - terrain_palette.visible = paint - if terrain_paint_hint != null: - terrain_paint_hint.text = paint_hint_text(main.doc.get("terrain", {}) if main.doc is Dictionary else {}) - refresh_panels() - if main.terrain_tool != null: - main.terrain_tool.call("set_brush_mode", _selected_terrain_mode()) - - -## Welche Bedienflächen sind sichtbar (Terrain-Tab bzw. Malen-Tab), welcher -## Start-Knopf steht gedrückt — Terrain und Malen teilen das Pinsel-Werkzeug. -func refresh_panels() -> void: - if terrain_panel == null: - return - var aktiv: bool = str(main.get("tool_mode")) == "terrain" - var paint := _selected_terrain_mode() == TerrainField.Mode.PAINT - terrain_edit_btn.set_pressed_no_signal(aktiv and not paint) - var malen = main.get("malen_mod") - if malen != null: - malen.malen_edit_btn.set_pressed_no_signal(aktiv and paint) - if aktiv: - _show_own_tab(malen if paint else self) - - -func _show_own_tab(tab: Control) -> void: - var tabs = main.get("ui_right_panel") - if tabs is TabContainer and tab != null and tab.get_parent() == tabs: - (tabs as TabContainer).current_tab = tab.get_index() - - -## Hinweistext Malen-Modus (pure, testbar): feinste Mal-Einheit = Abstand -## zweier Rasterpunkte der Karte (size / (resolution − 1)). -static func paint_hint_text(terrain: Dictionary) -> String: - var res := SvmapIO.material_resolution(terrain) # feines Material-Raster - var size := maxf(float(terrain.get("size_x_m", 0.0)), float(terrain.get("size_z_m", 0.0))) - if res < 2 or size <= 0.0: - return "Malen setzt das Material zellenweise — Stärke gibt es hier nicht." - var m := size / float(res - 1) - var m_text := str(int(roundf(m))) if absf(m - roundf(m)) < 0.05 \ - else String.num(m, 1).replace(".", ",") - return "Malen setzt das Material zellenweise: feinste Einheit auf dieser Karte ≈ %s m. Stärke gibt es hier nicht." % m_text - - -## Pinselgrößen-Presets (Karte t_603ec1a8): setzen den Radius-Slider -## (der Label-Text + Ring-Optik hängen am value_changed-Signal). -func _terrain_size_button(text: String, group: ButtonGroup, radius_m: float) -> Button: - var btn := Button.new() - btn.text = text - btn.toggle_mode = true - btn.button_group = group - btn.custom_minimum_size = UIScale.v2(0, 48) - btn.tooltip_text = "Pinselradius %d m" % int(radius_m) - btn.toggled.connect(_on_terrain_size_preset.bind(radius_m)) - return btn - - -func _on_terrain_size_preset(pressed: bool, radius_m: float) -> void: - # Null-Check als Schutznetz: beim Panel-Bau existiert der Slider noch - # nicht (Programmatic-Pressed darf den Handler nie früh treffen). - if pressed and terrain_radius_slider != null: - terrain_radius_slider.value = radius_m - - -func _on_terrain_radius_changed(value: float) -> void: - terrain_radius_label.text = "Pinsel-Größe: %d m" % int(value) - var malen = main.get("malen_mod") - if malen != null: - malen.set_radius_silent(value) - if main.terrain_tool != null: - main.terrain_tool.call("set_radius", value) - - -func _on_terrain_falloff_changed(value: float) -> void: - terrain_falloff_label.text = "Kante: %d %% weich" % int(value) if value > 0.0 else "Kante: hart" - if main.terrain_tool != null: - main.terrain_tool.call("set_falloff", value / 100.0) - - -func _on_terrain_strength_changed(value: float) -> void: - terrain_strength_label.text = "Stärke: %.1f m pro Sekunde" % value - if main.terrain_tool != null: - main.terrain_tool.call("set_strength", value) - - -## Terrain-Pinsel-Größe per [ / ] (Karte t_55257792): durch die 3 Presets -## Klein/Mittel/Groß zyklisch — der Preset-Button wird mit gesetzt (set_pressed -## feuert toggled → Slider + Label + Pinssel-Ring wandern mit). -## (Aus main.gd ausgezogen, Logik unverändert; Koordinator ruft weiter.) -func terrain_brush_size_step(up: bool) -> void: - if terrain_radius_slider == null: - return - var next := MoveMath.brush_next_preset(float(terrain_radius_slider.value), up) - var btn: Button = null - match next: - 4.0: - btn = terrain_size_btn_small - 12.0: - btn = terrain_size_btn_medium - 32.0: - btn = terrain_size_btn_large - if btn != null: - btn.set_pressed(true) # feuert _on_terrain_size_preset → Slider/Label - else: - terrain_radius_slider.value = next - main.terrain_tool.call("set_radius", next) - main.call("_set_status", "Pinsel-Größe: %d m (mit [ / ] durch Klein/Mittel/Groß zyklisch)." % int(next)) diff --git a/src/ui/panels/terrain_panel.gd.uid b/src/ui/panels/terrain_panel.gd.uid deleted file mode 100644 index fe08e19..0000000 --- a/src/ui/panels/terrain_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://qvp3thn60awa diff --git a/src/ui/panels/test_start_panel.gd b/src/ui/panels/test_start_panel.gd deleted file mode 100644 index a158926..0000000 --- a/src/ui/panels/test_start_panel.gd +++ /dev/null @@ -1,63 +0,0 @@ -extends "res://src/ui/panels/editor_panel.gd" -## Test-Start-Bereich (rechte Spalte — Karte t_96e3c4ee / T1b, Wiederanbindung -## durch den Operator am 20.10.). -## -## Aufteilung: der ZUSTAND lebt in main.gd (`test_start_point`) samt den Haken -## `_test_start_apply` / `_test_start_delete` / `_test_start_reload`, weil die -## Prüfsuite tests/test_playtest_spawn.gd (56 checks) genau diese drei Namen auf -## main erwartet — das ist der T1b-Vertrag. Beim U1-Umbau waren sie verschwunden, -## die Suite brach mit „Nonexistent function '_test_start_reload'" ab. -## Dieses Modul zeigt den Zustand nur an (Info-Text + Löschen-Knopf) und meldet -## sich datengetrieben über registry.gd an — main.gd verdrahtet nichts fest. - -var info: Label -var delete_btn: Button -var info_hint: Label - - -static func spec() -> Dictionary: - return {"titel": "Test-Start", "gruppe": "map", "order": 20} - - -func panel_title() -> String: - return "Test-Start (F5)" - - -func build() -> void: - add_child(_header_label("Startpunkt für „▶ Karte testen“")) - info = Label.new() - info.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - add_child(info) - - delete_btn = Button.new() - delete_btn.text = "🗑 Test-Start löschen" - delete_btn.custom_minimum_size = UIScale.v2(0, 40) - delete_btn.tooltip_text = "Test-Startpunkt entfernen — F5 startet dann wieder am ersten Team-Spawnpunkt." - delete_btn.pressed.connect(func() -> void: main.call("_test_start_delete")) - add_child(delete_btn) - - add_child(_separator()) - info_hint = Label.new() - info_hint.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - info_hint.text = "Leiste „🎯 Test-Start“ oder Taste T, dann in die Karte klicken." - add_child(info_hint) - - # main holt sich das Modul hier ab (main._refresh_test_start_panel) — die - # Prüfsuite liest es als main.test_start_panel. Sichtbar erst, wenn das - # Werkzeug aktiv ist (wie vor dem U1-Umbau). - main.set("test_start_panel", self) - visible = false - refresh_point(main.get("test_start_point")) - - -## Wird von main._refresh_test_start_panel() gerufen. point = Vector3 oder null. -func refresh_point(point: Variant) -> void: - if info == null or delete_btn == null: - return - if point == null: - info.text = "Kein Test-Start gesetzt.\nF5 startet dann am ersten Team-Blau-Spawnpunkt (ohne Spawnpunkte: Kartenmitte)." - delete_btn.disabled = true - else: - var p: Vector3 = point - info.text = "Test-Start: x=%.0f z=%.0f\n(Höhe kommt automatisch vom Terrain)" % [p.x, p.z] - delete_btn.disabled = false diff --git a/src/ui/panels/test_start_panel.gd.uid b/src/ui/panels/test_start_panel.gd.uid deleted file mode 100644 index 05aaed2..0000000 --- a/src/ui/panels/test_start_panel.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://brik7mu7wv0el diff --git a/src/ui/panels/toolbar.gd b/src/ui/panels/toolbar.gd deleted file mode 100644 index 0d42af8..0000000 --- a/src/ui/panels/toolbar.gd +++ /dev/null @@ -1,156 +0,0 @@ -extends HBoxContainer -## Toolbar (aus main.gd ausgezogen, Karte t_eaccbfed U1 — Logik unverändert): -## Menü Datei + Undo/Redo + Gitter/Höhenlinien + Symmetrie + Toolbar-Aktionen -## aus der Registry (Karte prüfen, ▶ Karte testen). Neue Aktionen melden sich -## künftig in registry.gd an (U2–U7, T1-F5 bleibt unverändert erreichbar). -## -## NACHBESSERUNG 20.10. (Operator, Sly-Befund „Damit kann man nicht mehr -## arbeiten"): Diese Leiste erbte von EditorPanel (= VBoxContainer) und wurde -## dadurch SELBST senkrecht — jeder Knopf bekam eine eigene, fensterbreite -## Zeile, die Leiste wuchs auf ~11×40 px und drückte das 3D-Fenster auf einen -## Briefmarken-Streifen. Eine Leiste braucht eine WAAGERECHTE Zeile: extends -## HBoxContainer. Die Helfer der Basis (main-Zeiger, Label-Bauer) braucht nur -## die senkrechte Spalte; hier genügt der main-Zeiger. - -var main # src/ui/main.gd (script-erweitert → untypisiert) - - -func setup(p_main) -> void: - main = p_main - # Eine Leiste darf NIE in die Höhe wachsen (sie würde dem 3D-Fenster die - # Fläche wegnehmen): genau eine Knopfzeile, oben ausgerichtet. - size_flags_vertical = Control.SIZE_SHRINK_BEGIN - size_flags_horizontal = Control.SIZE_EXPAND_FILL - - -func panel_title() -> String: - return "Werkzeuge" - -var undo_btn: Button -var redo_btn: Button -var settings_btn: Button # „⚙ Einstellungen“ öffnet das Einstellungen-Fenster -var title_label: Label -var file_label: Label - - -static func spec() -> Dictionary: - return {"titel": "Toolbar", "gruppe": "toolbar", "order": 0} - - -func build() -> void: - add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster (4/8) - - var file_menu := MenuButton.new() - file_menu.text = "Datei" - file_menu.flat = false - file_menu.custom_minimum_size = UIScale.v2(90, 40) - # U7: Klartext-Tooltip am Datei-Menü (alle Map-Aktionen an einem Ort). - file_menu.tooltip_text = "Map-Aktionen: neu, öffnen, speichern, testen, Updates" - var popup := file_menu.get_popup() - popup.add_item("Neue Map…", 0) - popup.add_item("Öffnen…", 1) - popup.add_item("Kartengröße ändern…", 6) - popup.add_separator() - popup.add_item("Speichern (Strg+S)", 2) - popup.add_item("Speichern unter…", 3) - popup.add_separator() - popup.add_item("▶ Karte testen", 5) - popup.add_separator() - popup.add_item("🖐 Hand-Haltung der Waffen…", 8) - popup.add_item("🔄 Updates prüfen", 7) - popup.add_item("Beenden", 4) - # FIX 20.10. (Sly-Befund „Kartengröße ändern tut nichts“): id_pressed sendet - # die Menü-ID. main.call.bind("_on_menu_action") hängt die ID aber ALS - # ARGUMENT an call() → effektiv call(6, "_on_menu_action") → - # „Cannot convert argument 1 from int to StringName“ (map-builder.log - # 20.10.) — das GESAMTE Datei-Menü verpufft, kein Eintrag tut etwas. - # Lambda macht die Reihenfolge (Name zuerst, ID als Argument) explizit, - # Stil wie grid_btn/contours_btn oben. - popup.id_pressed.connect(func(id: int) -> void: main.call("_on_menu_action", id)) - add_child(file_menu) - - undo_btn = Button.new() - undo_btn.text = "↩ Rückgängig" - undo_btn.custom_minimum_size = UIScale.v2(140, 40) - undo_btn.tooltip_text = "Letzte Aktion zurücknehmen (Strg+Z)" - undo_btn.pressed.connect(main.call.bind("_do_undo")) - add_child(undo_btn) - - redo_btn = Button.new() - redo_btn.text = "↪ Wiederholen" - redo_btn.custom_minimum_size = UIScale.v2(150, 40) - redo_btn.tooltip_text = "Zurückgenommene Aktion wiederherstellen (Strg+Y)" - redo_btn.pressed.connect(main.call.bind("_do_redo")) - add_child(redo_btn) - - # Toolbar-Aktionen DATENGETRIEBEN aus der Registry (Operator-Vorgabe - # 20.10.): Karte prüfen, ▶ Karte testen — künftige Karten melden sich - # hier an, ohne main.gd anzufassen. Die Buttons bekommen den Registry-Namen - # als Node-Namen (main kann sie per get_node/find_child ansprechen, z. B. - # der Shake-Effekt beim fehlgeschlagenen Map-Check). - for entry in PanelRegistry.toolbar_actions(): - var btn := Button.new() - btn.text = str(entry["titel"]) - btn.name = str(entry["id"]) - if str(entry["id"]) == "karte_pruefen": - btn.custom_minimum_size = UIScale.v2(170, 40) - btn.tooltip_text = "Prüft, ob die Map bereit für den Export ist — sagen wir VORHER, was fehlt" - else: - btn.custom_minimum_size = UIScale.v2(190, 40) - btn.tooltip_text = "Startet die Map SOFORT als Spiel zum Durchlaufen — eigenes Fenster, der Editor bleibt offen. ESC im Spiel = zurück zum Editor." - btn.pressed.connect(main.call.bind(str(entry["action"]))) - # Test-Start ist ein Umschalter: main liest/setzt seinen Zustand - # (Prüfsuite test_playtest_spawn.gd erwartet main.test_start_btn). - if str(entry["id"]) == "teststart": - btn.toggle_mode = true - main.set("test_start_btn", btn) - add_child(btn) - - # Einstellungen (25.10.): Gitter, Höhenlinien, Symmetrie-Modus, UI-Größe, - # Raster-Snap … stehen jetzt in einem eigenen Fenster. - settings_btn = Button.new() - settings_btn.text = "⚙ Einstellungen" - settings_btn.name = "einstellungen_knopf" - settings_btn.custom_minimum_size = UIScale.v2(170, 40) - settings_btn.tooltip_text = "Gitter, Höhenlinien, Symmetrie, UI-Größe, Raster-Snap und Testlauf-Einstellungen" - settings_btn.pressed.connect(func() -> void: main.call("_open_settings")) - add_child(settings_btn) - - var help_btn := Button.new() - help_btn.text = "❓ Hilfe" - help_btn.name = "hilfe" - help_btn.custom_minimum_size = UIScale.v2(110, 40) - help_btn.tooltip_text = "Werkzeuge, Steuerung und Tastenkürzel (H)" - help_btn.pressed.connect(func() -> void: main.call("_toggle_help_overlay")) - add_child(help_btn) - - title_label = Label.new() - title_label.text = " %s" % main.APP_TITLE - title_label.add_theme_font_size_override("font_size", UIScale.heading_font_size()) - # Karte t_297221b5: bei großer Stufe darf der Titel EGALISIEREN statt die - # Top-Bar aus dem Fenster zu drücken (Mindestbreite der Schrift skaliert mit). - # Mindestbreite, damit er nicht KOMPLETT verschwindet (Ellipsis macht "Scop…"). - # Expand: bei Platz bekommt er seine VOLLSTÄNDIGE natürliche Breite (wie - # Vorher bei „Klein“), erst bei knappem Fenster egalisiert er mit "…". - title_label.custom_minimum_size = UIScale.v2(180, 0) - title_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL - title_label.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS - title_label.clip_text = true - add_child(title_label) - - var spacer := Control.new() - spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL - add_child(spacer) - - file_label = Label.new() - file_label.text = "" - # U7: Farbe über Theme (Editor/colors/title) statt modulate-Wert im Code. - file_label.add_theme_color_override("font_color", - main.theme.get_color("title", "Editor")) - # Karte t_297221b5: Map-Pfad darf bei großer Stufe egalisiert werden - # (Voller Name im Tooltip, sonst drückt die Zeile die Top-Bar aus dem Fenster). - # Expand: bekommt zusammen mit dem Spacer seinen Anteil, egalisiert mit "…". - file_label.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS - file_label.clip_text = true - file_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL - add_child(file_label) diff --git a/src/ui/panels/toolbar.gd.uid b/src/ui/panels/toolbar.gd.uid deleted file mode 100644 index 9f1da55..0000000 --- a/src/ui/panels/toolbar.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://po0n02xkbp2e diff --git a/src/ui/resize_map_dialog.gd b/src/ui/resize_map_dialog.gd deleted file mode 100644 index c870f66..0000000 --- a/src/ui/resize_map_dialog.gd +++ /dev/null @@ -1,275 +0,0 @@ -extends ConfirmationDialog -## „Kartengröße ändern“-Dialog (R3, Karte t_c863b93b — PLAN.md „Map-Größe -## ändern“): aktuelle Größe anzeigen, neue X/Z in Metern eingeben (Preset- -## Buttons + Freifeld), Live-Vorschau aus SvmapDocument.resize_preview (R2). - -const UIScale := preload("res://src/ui/ui_scale.gd") # Karte t_297221b5 -## -## Stil wie new_map_dialog.gd: alles per Code, Deutsch, Klartext-Warnungen. -## Der Dialog mutiert NICHTS — das Anwenden macht main.gd (_on_resize_confirmed) -## als EINE Undo-Einheit über resize_apply + ActionHistory-Snapshot. - -var size_x_edit: SpinBox -var size_z_edit: SpinBox -var drop_check: CheckBox -var info_label: Label # aktuelle Größe + Auflösung -var preview_label: Label # Live-Vorschau (Verlust-Liste / Warnband) -var _scroll: ScrollContainer -var _vbox: VBoxContainer - -var _old_sx := 0.0 -var _old_sz := 0.0 -var _old_res := 0 -var _doc: Dictionary = {} - -const _PRESET_SIZES := [256, 512, 1024, 2048] - - -func _init() -> void: - title = "Kartengröße ändern" - ok_button_text = "Größe ändern" - cancel_button_text = "Abbrechen" - min_size = UIScale.v2i(520, 0) - unresizable = true # Der Dialog wächst selbst per Inhalt; kein Hand-Resize - - # FIX 20.10.b: Inhalt in einen ScrollContainer — wächst die Live-Vorschau - # NACH dem Öffnen (z. B. Preset 256 → Warnband), kann die Fensterhöhe - # gedeckelt werden, OHNE dass Inhalt oder OK/Abbrechen verloren gehen. - # Start-Mindesthöhe ~ kompletter Normalinhalt (kein Kollaps beim Popup); - # _fit_after_layout setzt sie dynamisch auf Inhalt vs. sichtbarer Platz. - var scroll := ScrollContainer.new() - scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED - scroll.custom_minimum_size = UIScale.v2(500, 430) - add_child(scroll) - scroll.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) - _scroll = scroll - - var vbox := VBoxContainer.new() - vbox.add_theme_constant_override("separation", UIScale.px(12)) - vbox.custom_minimum_size = UIScale.v2(500, 0) - vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL - scroll.add_child(vbox) - _vbox = vbox - - info_label = _make_label("") - vbox.add_child(info_label) - - var preset_h := HBoxContainer.new() - preset_h.add_theme_constant_override("separation", UIScale.px(8)) - for size in _PRESET_SIZES: - var btn := Button.new() - btn.text = "%d m" % size - btn.custom_minimum_size = UIScale.v2(0, 40) - # U7: Klartext-Tooltips (Karte t_2336c58e). - btn.tooltip_text = "Preset: Karte quadratisch %d × %d m" % [size, size] - btn.pressed.connect(_on_preset.bind(float(size))) - preset_h.add_child(btn) - vbox.add_child(preset_h) - - vbox.add_child(_make_label("Neue Breite (X) in Metern:")) - size_x_edit = SpinBox.new() - _fill_spin(size_x_edit) - vbox.add_child(size_x_edit) - - vbox.add_child(_make_label("Neue Tiefe (Z) in Metern:")) - size_z_edit = SpinBox.new() - _fill_spin(size_z_edit) - vbox.add_child(size_z_edit) - - var hint := _make_label("Erlaubt: 256–4096 m. Die Karte bleibt mittig — das bestehende Terrain\nbehaftet seine Weltposition, die neue Randzone wird flach (Steppe).") - hint.modulate = Color(1, 1, 1, 0.7) - vbox.add_child(hint) - - preview_label = _make_label("") - preview_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - # FIX 20.10.b: gleiche autowrap-Explosion wie oben — (0, 60) überschreibt die - # Mindestbreite von _make_label, deshalb hier BREITE + Höhe explizit setzen. - preview_label.custom_minimum_size = UIScale.v2(500, 60) - vbox.add_child(preview_label) - - drop_check = CheckBox.new() - drop_check.text = "Draußen liegende Objekte/Bauteile/Spawn-Punkte beim Verkleinern entfernen" - drop_check.button_pressed = true - # U7: Klartext-Tooltip (Karte t_2336c58e). - drop_check.tooltip_text = "An = Dinge außerhalb der neuen Grenze fliegen raus (Strg+Z holt sie zurück).\nAus = sie bleiben, aber die Map ist dann NICHT speicherbar." - drop_check.toggled.connect(func(_p: bool) -> void: _update_preview()) - vbox.add_child(drop_check) - - size_x_edit.value_changed.connect(func(_v: float) -> void: _update_preview()) - size_z_edit.value_changed.connect(func(_v: float) -> void: _update_preview()) - - -func _make_label(text: String) -> Label: - var label := Label.new() - label.text = text - label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART - # FIX 20.10. (Sly-Befund „Fenster viel zu lang, nichts bestätigbar“): ein - # autowrap-Label OHNE Mindestbreite meldet VOR dem ersten Layout eine - # explosionsartige Mindesthöhe (es wrappet bei ~1 px Breite → jedes Wort - # eine Zeile). popup_centered() nimmt genau diesen Wert als Fensterhöhe - # (Probe: 10 322 px statt ~320). Mindestbreite ~ Dialogbreite verankert - # den Umbruch an der echten Breite → Fenster normal hoch. - label.custom_minimum_size = Vector2(UIScale.px(500), 0) - return label - - -func _fill_spin(spin: SpinBox) -> void: - spin.min_value = SvmapDocument.MIN_SIZE_M - spin.max_value = SvmapDocument.MAX_SIZE_M - spin.step = 1.0 - spin.suffix = " m" - spin.value = 1024.0 - spin.custom_minimum_size = UIScale.v2(0, 40) - - -## Vom Editor vor dem Öffnen füllen: aktueller Stand + Live-Vorschau. -func setup(doc: Dictionary) -> void: - _doc = doc - var terrain: Dictionary = doc.get("terrain", {}) - _old_sx = float(terrain.get("size_x_m", 0.0)) - _old_sz = float(terrain.get("size_z_m", 0.0)) - _old_res = int(terrain.get("resolution", 0)) - info_label.text = "Aktuelle Größe: %d × %d m — Auflösung: %d × %d Höhenpunkte" % [ - int(_old_sx), int(_old_sz), _old_res, _old_res] - size_x_edit.value = _old_sx - size_z_edit.value = _old_sz - _update_preview() - - -func _on_preset(size: float) -> void: - size_x_edit.value = size - size_z_edit.value = size - - -func get_new_size_x() -> float: - return clampf(size_x_edit.value, SvmapDocument.MIN_SIZE_M, SvmapDocument.MAX_SIZE_M) - - -func get_new_size_z() -> float: - return clampf(size_z_edit.value, SvmapDocument.MIN_SIZE_M, SvmapDocument.MAX_SIZE_M) - - -func get_drop_outside() -> bool: - return drop_check.button_pressed - - -## Live-Vorschau: Verlust-Liste (R2 resize_preview), Spawn-Speicher-Warnung -## (V11 verlangt ≥ 4 Punkte/Team), Warnband bei Vergrößern über ~1024 m -## (Dichte-Leiter deckelt bei 513 Punkten → grobes Raster, Quest-Perf). -func _update_preview() -> void: - if _doc.is_empty(): - preview_label.text = "" - preview_label.modulate = Color(1, 1, 1, 0.7) - return - var new_sx := get_new_size_x() - var new_sz := get_new_size_z() - var preview: Dictionary = SvmapDocument.resize_preview(_doc, new_sx, new_sz) - var lines: Array[String] = [] - - var shrink := new_sx < _old_sx - 0.5 or new_sz < _old_sz - 0.5 - var grow := new_sx > _old_sx + 0.5 or new_sz > _old_sz + 0.5 - var out_total := (preview["objects_out"] as Array).size() \ - + (preview["parts_out"] as Array).size() \ - + (preview["spawns_out"] as Array).size() - - if shrink and out_total > 0: - var detail := "Beim Verkleinern liegen draußen: %d Objekt(e), %d Bauteil(e), %d Spawn-Punkt(e)." % [ - (preview["objects_out"] as Array).size(), - (preview["parts_out"] as Array).size(), - (preview["spawns_out"] as Array).size()] - if drop_check.button_pressed: - detail += "\nDiese werden beim Anwenden ENTFERNT (Strg+Z holt sie zurück)." - else: - detail += "\nSie bleiben in der Map, ragen aber über den Rand hinaus — die Map ist dann NICHT speicherbar (nichts darf außerhalb der Match-Grenzen liegen). Zieh sie später wieder rein oder entferne sie." - preview_label.modulate = Color(1.0, 0.75, 0.3) # Warnorange - lines.append(detail) - elif shrink: - preview_label.modulate = Color(1, 1, 1, 0.7) - lines.append("Beim Verkleinern geht nichts verloren — alles liegt innerhalb der neuen Grenzen.") - elif grow: - preview_label.modulate = Color(1, 1, 1, 0.7) - lines.append("Beim Vergrößern bleibt alles erhalten — die neue Randzone wird flache Steppe.") - - # Spawn-Speicher-Warnung (R2-Befund): V11 verlangt ≥ 4 Punkte je Team beim - # SPEICHERN — nach dem Entfernen drohen Teams unter den Deckwert. - if drop_check.button_pressed and out_total > 0: - var zones = _doc.get("spawn_zones", {}) - if zones is Dictionary: - var dropped: Dictionary = {} - for entry in (preview["spawns_out"] as Array): - if entry is Dictionary: - dropped[int(entry.get("team", -1))] = int(dropped.get(int(entry.get("team", -1)), 0)) + 1 - for team_key in (zones as Dictionary).keys(): - var zone = zones[team_key] - if not (zone is Dictionary): - continue - var kept := (zone.get("points", []) as Array).size() - int(dropped.get(int(team_key), 0)) - if kept < 4: - lines.append("Achtung: Team „%s“ hätte danach nur %d Spawn-Punkte — Maps brauchen mindestens 4 pro Team, um SPEICHERN zu können. Abhilfe: Entfernen ausstellen oder später Punkte ergänzen." % [ - str(zone.get("label", "Team %s" % str(team_key))), kept]) - preview_label.modulate = Color(1.0, 0.75, 0.3) - - # Warnband Vergrößern: über ~1024 m Kante grobt die Dichte (Deckel 513 - # Punkte) — Detail-Dichte + Quest-Perf (Objektzahl/Draw-Calls) erwähnen. - if grow: - var m_per_point := SvmapDocument.resize_m_per_point(_projected_resolution(), maxf(new_sx, new_sz)) - if m_per_point > SvmapDocument.RESIZE_DENSITY_TARGET_M: - lines.append("Achtung: Ab dieser Größe wird das Terrain grober aufgelöst (%.1f m pro Höhenpunkt statt 2 m). Die Hügel-Details werden weicher — für Quest-Perf gilt: mehr Fläche = mehr Objekte/Draw-Calls beachten." % m_per_point) - preview_label.modulate = Color(1.0, 0.75, 0.3) - - preview_label.text = "\n".join(lines) - _fit_after_layout.call_deferred() - - -## Fenster im sichtbaren Bereich halten: Höhe deckeln (überzähliger Inhalt -## scrollt im ScrollContainer) und neu zentrieren — sonst rutschen -## OK/Abbrechen unter den Bildschirmrand, wenn die Live-Vorschau das Fenster -## NACH dem Öffnen wachsen lässt (Probe: Fenster blieb oben hängen, Buttons -## bei y≈940 in einem 900-px-Sichtbereich). -func _fit_dialog() -> void: - var area := _parent_area() - if area.x <= 0.0 or area.y <= 0.0: - return - var max_h := int(area.y) - 8 - if size.y > max_h: - size = Vector2i(size.x, max_h) - var half := (area - Vector2(size)) * 0.5 - position = Vector2(maxi(0, int(half.x)), maxi(0, int(half.y))) - - -## Erst das Layout (und damit das Fenster-Wachstum) abwarten, dann den -## Scrollbereich auf „Inhalt vs. sichtbarer Platz“ justieren und verankern. -func _fit_after_layout() -> void: - await get_tree().process_frame - await get_tree().process_frame - var area := _parent_area() - if area.x <= 0.0 or area.y <= 0.0: - return - # Scrollbereich: so hoch wie der Inhalt, aber nie höher als der sichtbare - # Platz (Titelleiste + OK/Abbrechen + Ränder bleiben reserviert). Ist der - # Inhalt größer, scrollt er INNEN — die Buttons bleiben immer erreichbar. - var needed := _vbox.get_combined_minimum_size().y + UIScale.px(16) - var max_body := area.y - UIScale.px(90) - _scroll.custom_minimum_size = Vector2(UIScale.px(500), minf(needed, max_body)) - _fit_dialog() - - -func _parent_area() -> Vector2: - var p := get_parent() - if p is Control: - return (p as Control).size - if p is Window: - return (p as Window).size - return Vector2.ZERO - - -## Projected new resolution nach dem Resize (gleiche Leiter wie resize_terrain, -## hier nur für die Warnband-Anzeige — kein Terrain-Resample im Dialog). -func _projected_resolution() -> int: - var res := _old_res - for step in SvmapDocument.RESIZE_RESOLUTION_LADDER: - if step < res: - continue - if maxf(get_new_size_x(), get_new_size_z()) / float(step - 1) <= SvmapDocument.RESIZE_DENSITY_TARGET_M: - return step - return SvmapIO.MAX_TERRAIN_RESOLUTION \ No newline at end of file diff --git a/src/ui/resize_map_dialog.gd.uid b/src/ui/resize_map_dialog.gd.uid deleted file mode 100644 index 67c203e..0000000 --- a/src/ui/resize_map_dialog.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://6bjars8usr43 diff --git a/src/ui/ui_scale.gd b/src/ui/ui_scale.gd deleted file mode 100644 index 75f5fdc..0000000 --- a/src/ui/ui_scale.gd +++ /dev/null @@ -1,136 +0,0 @@ -class_name UIScale -extends RefCounted - -## Zentrale UI-Skalierung (Karte t_297221b5): EIN Faktor für den ganzen Editor. -## -## Stufen: Klein (1.0) / Mittel (1.25) / Groß (1.5). Der Faktor multipliziert -## alle Layout-Werte beim UI-Bau (Schrift, Zeilen-/Knopfhöhen, Panelbreiten, -## Thumbnail-Größe, Abstände) — bewusst als Faktor-Multiplikation und NICHT als -## stretch/canvas_items, damit (a) die 3D-Map-Ansicht pixelgenau unberührt bleibt, -## (b) nichts doppelt skaliert und (c) die Stufe vom Nutzer gewählt wird statt -## von der Fenstergröße abzuhängen. -## -## Die gewählte Stufe liegt in user://scopedvr_editor.cfg, Abschnitt [ui] -## (Key "groesse"). ConfigFile lädt+speichert die GANZE Datei — der Abschnitt -## [library] (Klapp-Zustand, Karte t_59fc0f21) bleibt dabei erhalten. -## -## Für Tests/Probes kann per Umgebungsvariable SCOPEDVR_UI_CFG eine andere -## Config-Datei erzwungen werden (hermetische Läufe ohne Nutzer-Config). - -## Typografie-Ebenen (Karte t_2336c58e/U7 — verbindlich): genau ZWEI Schrift- -## Größen (Body + Klein) plus eine Überschriften-Stufe. KEINE weiteren Größen -## im Code — alles über die drei Helfer unten, skaliert mit der UI-Stufe. -const HEADING_FONT_SIZE := 20 # Überschriften (Panel-/Gruppen-Header, Titel) -const SMALL_FONT_SIZE := 13 # Nebentext (Zähler, Badges, Tile-IDs) - -const CFG_PATH := "user://scopedvr_editor.cfg" -const CFG_SECTION := "ui" -const CFG_KEY := "groesse" # "klein" | "mittel" | "gross" -const WIN_SECTION := "fenster" # Fenster-Zustand (maximiert/Größe/Position) - -## [key, Anzeige-Name, Faktor] -const STEPS: Array = [ - ["klein", "Klein", 1.0], - ["mittel", "Mittel", 1.25], - ["gross", "Groß", 1.5], -] -const BASE_FONT_SIZE := 16 # bisherige feste Schriftgröße (main.gd, Vorher) - -static var _factor: float = -1.0 # Cache; < 0 = noch nicht aus der Config gelesen - - -static func cfg_path() -> String: - var env := OS.get_environment("SCOPEDVR_UI_CFG") - if not env.is_empty(): - return env - return CFG_PATH - - -static func step_count() -> int: - return STEPS.size() - - -static func step_label(i: int) -> String: - return str(STEPS[clampi(i, 0, STEPS.size() - 1)][1]) - - -static func step_key(i: int) -> String: - return str(STEPS[clampi(i, 0, STEPS.size() - 1)][0]) - - -static func step_index_from_key(key: String) -> int: - for i in STEPS.size(): - if str(STEPS[i][0]) == key: - return i - return 0 # unbekannt/leer → Klein (Vorher-Verhalten) - - -## Aktuelle Stufe aus der Config (ohne Cache). -static func step_index() -> int: - var cfg := ConfigFile.new() - if cfg.load(cfg_path()) != OK: - return 0 # keine Config = Klein (altes Verhalten) - return step_index_from_key(str(cfg.get_value(CFG_SECTION, CFG_KEY, ""))) - - -## Faktor der aktuellen Stufe (cached — UI-Bau ruft das sehr oft). -static func factor() -> float: - if _factor < 0.0: - _factor = float(STEPS[step_index()][2]) - return _factor - - -## Stufe setzen UND sofort in die Config schreiben (Abschnitte wie [library] -## bleiben erhalten — ConfigFile liest/schreibt die ganze Datei). -static func set_step_index(i: int) -> void: - i = clampi(i, 0, STEPS.size() - 1) - var cfg := ConfigFile.new() - cfg.load(cfg_path()) # fehlt die Datei: leer anfangen, Abschnitte bleiben - cfg.set_value(CFG_SECTION, CFG_KEY, str(STEPS[i][0])) - var err := cfg.save(cfg_path()) - if err != OK: - push_warning("UIScale: Config nicht schreibbar (%s), Stufe nur für diese Sitzung." % err) - _factor = float(STEPS[i][2]) - - -## Cache verwerfen und neu lesen — simuliert den Neustart (für Tests/Probes). -static func reload() -> void: - _factor = -1.0 - factor() - - -# ------------------------------------------------------- Rechenhelfer (Bau) -- - -## Ganzzahliges Pixel-Maß (Höhen, Breiten, Abstände, Schriftgrößen). -static func px(v: float) -> int: - return int(round(v * factor())) - - -## Fließkommamaß (z. B. split_offset). -static func f(v: float) -> float: - return v * factor() - - -## custom_minimum_size = UIScale.v2(b, h) statt Vector2(b, h). -static func v2(x: float, y: float) -> Vector2: - return Vector2(px(x), px(y)) - - -## Dialog-/Fenstergrößen. -static func v2i(x: float, y: float) -> Vector2i: - return Vector2i(px(x), px(y)) - - -## Standardschriftgröße (Body-Text, bisher fest 16). -static func font_size() -> int: - return px(BASE_FONT_SIZE) - - -## Überschriften-Größe (Panel-/Gruppen-Header, Titel) — U7-Raster. -static func heading_font_size() -> int: - return px(HEADING_FONT_SIZE) - - -## Nebentext-Größe (Zähler, Badges, Tile-IDs) — U7-Raster. -static func small_font_size() -> int: - return px(SMALL_FONT_SIZE) diff --git a/src/ui/ui_scale.gd.uid b/src/ui/ui_scale.gd.uid deleted file mode 100644 index beeeff8..0000000 --- a/src/ui/ui_scale.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://d4d60533njpla diff --git a/src/ui/viewport_toolbar.gd b/src/ui/viewport_toolbar.gd deleted file mode 100644 index 1f85a2f..0000000 --- a/src/ui/viewport_toolbar.gd +++ /dev/null @@ -1,78 +0,0 @@ -extends PanelContainer -## Werkzeugleiste oben links in der 3D-Ansicht (25.10.): erscheint, sobald ein -## Objekt ausgewählt ist. Umschalter Verschieben / Drehen & Kippen (steuert den -## Gizmo) plus schnelle Aktionen (Auf den Boden, Duplizieren, Löschen). -## Objekte werden bewusst NIE skaliert — es gibt kein Skalieren-Werkzeug. - -var main -var move_btn: Button -var rotate_btn: Button -var ground_btn: Button -var dup_btn: Button -var delete_btn: Button - - -func setup(p_main) -> void: - main = p_main - set_anchors_preset(Control.PRESET_TOP_LEFT) - offset_left = UIScale.px(12) - offset_top = UIScale.px(12) - mouse_filter = Control.MOUSE_FILTER_STOP - visible = false - var box := HBoxContainer.new() - box.add_theme_constant_override("separation", UIScale.px(6)) - add_child(box) - var group := ButtonGroup.new() - move_btn = _btn("↔ Verschieben", "Pfeile am Objekt ziehen: X rot, Y grün, Z blau", true, group) - move_btn.pressed.connect(func() -> void: _set_mode("move")) - box.add_child(move_btn) - rotate_btn = _btn("⟳ Drehen / Kippen", "Ringe am Objekt ziehen: um alle drei Achsen, in 15°-Schritten", true, group) - rotate_btn.pressed.connect(func() -> void: _set_mode("rotate")) - box.add_child(rotate_btn) - move_btn.set_pressed_no_signal(true) - box.add_child(VSeparator.new()) - ground_btn = _btn("⤓ Auf den Boden", "Auswahl aufs Terrain absetzen (Strg+Bild↑)", false, null) - ground_btn.pressed.connect(func() -> void: main.interaction.snap_selection_to_floor()) - box.add_child(ground_btn) - dup_btn = _btn("⧉ Kopie", "Duplizieren (Strg+D)", false, null) - dup_btn.pressed.connect(func() -> void: main.interaction.duplicate_selected()) - box.add_child(dup_btn) - delete_btn = _btn("🗑 Löschen", "Löschen (Entf) — Strg+Z holt es zurück", false, null) - delete_btn.pressed.connect(func() -> void: main.interaction.delete_selected()) - box.add_child(delete_btn) - - -func _btn(text: String, tip: String, toggle: bool, group: ButtonGroup) -> Button: - var b := Button.new() - b.text = text - b.tooltip_text = tip - b.toggle_mode = toggle - if group != null: - b.button_group = group - b.custom_minimum_size = UIScale.v2(0, 36) - b.focus_mode = Control.FOCUS_NONE # Leertaste/Pfeile bleiben beim Viewport - return b - - -func _set_mode(m: String) -> void: - if main.gizmo != null: - main.gizmo.set_mode(m) - - -## Sichtbarkeit pro Frame aus der Auswahl ableiten (wie der Gizmo selbst). -func _process(_delta: float) -> void: - if main == null or main.get("interaction") == null: - return - var inter = main.interaction - var mode: String = str(main.get("tool_mode")) - var want: bool = mode == "objects" \ - and not inter.selected_indices.is_empty() \ - and not bool(inter.get("placing")) \ - and main.get("playtest") == null - if want != visible: - visible = want - if visible and main.gizmo != null: - var rotate_on: bool = main.gizmo.mode == "rotate" - if rotate_btn.button_pressed != rotate_on: - rotate_btn.set_pressed_no_signal(rotate_on) - move_btn.set_pressed_no_signal(not rotate_on) diff --git a/src/ui/viewport_toolbar.gd.uid b/src/ui/viewport_toolbar.gd.uid deleted file mode 100644 index d93f503..0000000 --- a/src/ui/viewport_toolbar.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://jjp1jooped0q diff --git a/src/viewport/gizmo.gd b/src/viewport/gizmo.gd deleted file mode 100644 index e57dc4d..0000000 --- a/src/viewport/gizmo.gd +++ /dev/null @@ -1,628 +0,0 @@ -extends Node3D -## Achsen-Gizmo (Karte t_e0120dc2): drei farbige Pfeile (X rot, Y grün, -## Z blau) am EINZELN markierten Objekt. Zieht man einen Pfeil, bewegt sich -## das Objekt GENAU entlang dieser Achse — die Zahlen im Objekt-Inspektor -## laufen LIVE mit. Mausrad WÄHREND des Ziehens wechselt die Schrittweite -## (fein/normal/grob); derselbe Wert steht als „Schrittweite“-Feld im -## rechten Panel (main.gd). -## -## Regeln der Karte: -## - NUR Einzelauswahl (Mehrfachauswahl bekommt kein Gizmo — Folgekarte). -## - JEDER Zug = EIN Undo-Schritt (Commit beim Loslassen). Esc bricht EXAKT -## auf die Startposition zurück (byte-identisch, wie grab_cancel). -## - Zieh-Werte rasten auf Vielfache der Schrittweite (Voreinstellungen -## 0,1 / 0,5 / 2 m; das Feld im Panel nimmt jeden Wert 0,01–10 m). -## - Klemmen wie der Inspektor: X/Z an der Map-Grenze, Y nie unter dem -## Terrain (X/Z-Zug folgt dem Boden wie der normale Objekt-Zug) und -## oben an der Höhen-Grenze. -## -## Eingabe-Verdrahtung: dieses Gizmo hängt als KIND an interaction.gd — -## Knoten bekommen _unhandled_input TIEFER IM BAUM ZUERST, so fängt es -## Pfeil-Klicks ab, BEVOR die Auswahl-/Zieh-Logik des Parents sie sieht. -## interaction.gd bleibt dadurch UNVERÄNDERT (Karten-Grenze) und der -## bestehende Klick-/Zieh-Pfad wird 1:1 wiederverwendet. - -const SvmapDocument := preload("res://core/svmap/map_document.gd") - -const AXIS_LEN := 2.2 # Pfeil-Länge in Metern (Weltmaß) -const SHAFT_R := 0.045 -const CONE_H := 0.45 -const CONE_R := 0.13 -const HIT_PX := 18.0 # Treffer-Toleranz am Bildschirm (Pixel) -const MIN_PX_PER_M := 10.0 # Zieh-Sensitivität deckeln (Achse fast im Blick) -const STEP_MIN := 0.01 -const STEP_MAX := 10.0 - -const STEP_PRESETS := [0.1, 0.5, 2.0] -const STEP_PRESET_NAMES := ["fein", "normal", "grob"] - -const AXES := { - "x": Vector3(1.0, 0.0, 0.0), - "y": Vector3(0.0, 1.0, 0.0), - "z": Vector3(0.0, 0.0, 1.0), -} -const AXIS_COLORS := { - "x": Color(1.0, 0.25, 0.25), - "y": Color(0.3, 0.95, 0.35), - "z": Color(0.35, 0.55, 1.0), -} - -var main # src/ui/main.gd (script-erweitert) -var camera: Camera3D -var view_builder # src/viewport/map_view_builder.gd - -var step_m := 0.5 # Schrittweite (m) — Panel-Feld + Mausrad-Presets - -# --- Zieh-Zustand --- -var _dragging := false -var _drag_idx := -1 -var _drag_axis := "" -var _drag_axis_vec := Vector3.ZERO -var _press_screen := Vector2.ZERO -var _screen_axis := Vector2.RIGHT # Achse am Bildschirm (normalisiert, px) -var _px_per_m := 1.0 -var _start_pos := Vector3.ZERO # doc-Position beim Zieh-Start -var _start_saved: Array = [] # exakte Start-Position für Esc-Rückabwicklung -var _drag_lift := 0.0 # Boden-Abstand (X/Z-Zug folgt dem Terrain) -var _drag_moved := false -var _last_delta := 0.0 # zuletzt angewendeter Delta (m) — 0 = kein Commit -var _drag_before: Dictionary = {} # History-Snapshot VOR dem Zug - -var _arrows := {} # "x"/"y"/"z" → Node3D (Pfeil-Root) - -# --- Dreh-/Kipp-Modus (25.10.): Ringe um alle drei Achsen ------------------- -const RING_R := 1.5 # Ring-Radius in Metern -const RING_SEGMENTS := 48 -const ROT_STEP_DEG := 15.0 -var mode := "move" # "move" = Pfeile, "rotate" = Ringe -var rot_step_deg := ROT_STEP_DEG -var _rings := {} # "x"/"y"/"z" → MeshInstance3D -var _rot_dragging := false -var _rot_axis := "" -var _rot_center := Vector2.ZERO -var _rot_start_angle := 0.0 -var _rot_applied := 0.0 # bisher angewendete (gerastete) Grad -var _rot_suffix := "" # merge-Kennung: EIN Undo-Schritt pro Zug -var _rot_serial := 0 - - -func setup(p_main, p_camera: Camera3D, p_builder) -> void: - main = p_main - camera = p_camera - view_builder = p_builder - _build_arrows() - _build_rings() - _apply_mode_visibility() - visible = false - - -## Pfeile bauen: Schaft (Zylinder) + Spitze (Kegel), ungeschattet und OHNE -## Tiefentest — die Pfeile bleiben auch vor/über Objekten gut sichtbar. -func _build_arrows() -> void: - for a in AXES: - var root := Node3D.new() - # Alle Pfeile zeigen lokal +Y; der Root dreht sie auf die Welt-Achse. - if a == "x": - root.rotation.z = -PI / 2.0 # +Y → +X - elif a == "z": - root.rotation.x = PI / 2.0 # +Y → +Z - var mat := StandardMaterial3D.new() - mat.albedo_color = AXIS_COLORS[a] - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - mat.no_depth_test = true - mat.render_priority = 20 - var shaft := MeshInstance3D.new() - var cyl := CylinderMesh.new() - cyl.top_radius = SHAFT_R - cyl.bottom_radius = SHAFT_R - cyl.height = AXIS_LEN - shaft.mesh = cyl - shaft.material_override = mat - shaft.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF - shaft.position.y = AXIS_LEN * 0.5 - root.add_child(shaft) - var tip := MeshInstance3D.new() - var cone := CylinderMesh.new() - cone.top_radius = 0.0 - cone.bottom_radius = CONE_R - cone.height = CONE_H - tip.mesh = cone - tip.material_override = mat - tip.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF - tip.position.y = AXIS_LEN + CONE_H * 0.5 - root.add_child(tip) - add_child(root) - _arrows[a] = root - - -## Drehringe bauen: je Achse ein dünner Torus, ungeschattet, ohne Tiefentest. -func _build_rings() -> void: - for a in AXES: - var mat := StandardMaterial3D.new() - mat.albedo_color = AXIS_COLORS[a] - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - mat.no_depth_test = true - mat.render_priority = 20 - var ring := MeshInstance3D.new() - var torus := TorusMesh.new() - torus.inner_radius = RING_R - 0.06 - torus.outer_radius = RING_R + 0.06 - torus.rings = 48 - torus.ring_segments = 8 - ring.mesh = torus - ring.material_override = mat - ring.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF - # Torus liegt lokal in der XZ-Ebene (Achse = Y). - if a == "x": - ring.rotation.z = PI / 2.0 - elif a == "z": - ring.rotation.x = PI / 2.0 - ring.visible = false - add_child(ring) - _rings[a] = ring - - -## Modus wechseln ("move" = Verschieben, "rotate" = Drehen/Kippen). -func set_mode(m: String) -> void: - if m != "move" and m != "rotate": - return - if _dragging: - _finish_drag(false) - if _rot_dragging: - _finish_rotate(false) - mode = m - var inter = main.get("interaction") if main != null else null - if inter != null: - inter.no_drag_move = (m == "rotate") - _apply_mode_visibility() - - -func _apply_mode_visibility() -> void: - for a in _arrows: - (_arrows[a] as Node3D).visible = mode == "move" - for a in _rings: - (_rings[a] as Node3D).visible = mode == "rotate" - - -func _axis_vec(a: String) -> Vector3: - return AXES.get(a, Vector3.ZERO) as Vector3 - - -## Sichtbarkeit + Position JEDES Frames aus der Auswahl ableiten (kein -## Verdrahten jedes Auswahl-Wegs nötig — Auswahl kommt aus interaction.gd, -## Baum, Undo/Redo, Inspektor … alles landet automatisch hier). -func _process(_delta: float) -> void: - if main == null or view_builder == null: - return - var inter = main.get("interaction") - if inter == null: - return - var sel: Array = inter.selected_indices - if sel.size() != 1: - visible = false - return - if bool(inter.get("placing")): - visible = false # Ghost-Platzieren: keine Pfeile im Weg - return - var idx: int = int(inter.selected_index) - var markers: Array = view_builder.object_markers - if idx < 0 or idx >= markers.size(): - visible = false - return - var marker = markers[idx] - if marker == null or not is_instance_valid(marker): - visible = false - return - visible = true - global_position = marker.global_position - - -func _unhandled_input(event: InputEvent) -> void: - var p := MousePointer.from_input(event) - if p != null and handle_pointer(p): - get_viewport().set_input_as_handled() - - -func handle_pointer(p: PointerEvent) -> bool: - if main == null or camera == null: - return false - var doc: Dictionary = main.get("doc") - if doc == null or doc.is_empty(): - return false - var tool_mode: String = str(main.get("tool_mode")) - if tool_mode == "terrain" or tool_mode == "spawns": - return false # Terrain-Pinsel / Spawn-Zonen haben das Zepter - match p.kind: - PointerEvent.Kind.PRESS: - if _dragging: - return false - var inter = main.get("interaction") - if inter == null or bool(inter.get("placing")): - return false - if mode == "rotate": - var ring_axis := pick_ring(p.position) - if ring_axis != "": - _begin_rotate(ring_axis, p.position) - return true - return false - var axis := pick(p.position) - if axis != "": - _begin_drag(axis, p.position) - return true - PointerEvent.Kind.RELEASE: - if _rot_dragging: - _finish_rotate(true) - return true - if _dragging: - _finish_drag(true) - return true - PointerEvent.Kind.SCROLL: - if _rot_dragging: - return true # Mausrad zoomt nicht mitten im Dreh-Zug - if _dragging: - cycle_step(p.scroll) - return true - PointerEvent.Kind.MOVE: - if _rot_dragging: - _rotate_motion(p.position) - return true - if _dragging: - _drag_motion(p.position) - return true - PointerEvent.Kind.CANCEL: - if _rot_dragging: - _finish_rotate(false) - return true - if _dragging: - _finish_drag(false) - return true - return false - - -# ------------------------------------------------------------- Treffer ----- - -## Achse unter dem Cursor (Bildschirm-Segment-Distanz) — "" = kein Pfeil. -func pick(screen_pos: Vector2) -> String: - if not visible: - return "" - var o := _safe_unproject(global_position) - if o == Vector2.INF: - return "" - var best := "" - var best_d := HIT_PX - for a in AXES: - var t := _safe_unproject(global_position + _axis_vec(a) * AXIS_LEN) - if t == Vector2.INF: - continue - var d := _dist_point_segment(screen_pos, o, t) - if d < best_d: - best_d = d - best = a - return best - - -## Ring unter dem Cursor (Abstand zum projizierten Kreis) — "" = keiner. -func pick_ring(screen_pos: Vector2) -> String: - if not visible or mode != "rotate": - return "" - var best := "" - var best_d := HIT_PX * 1.6 - for a in AXES: - var pts := _ring_screen_points(a) - for i in pts.size() - 1: - if pts[i] == Vector2.INF or pts[i + 1] == Vector2.INF: - continue - var d := _dist_point_segment(screen_pos, pts[i], pts[i + 1]) - if d < best_d: - best_d = d - best = a - return best - - -func _ring_screen_points(a: String) -> Array: - var axis := _axis_vec(a) - var u := axis.cross(Vector3.UP if absf(axis.dot(Vector3.UP)) < 0.9 else Vector3.RIGHT).normalized() - var v := axis.cross(u).normalized() - var out: Array = [] - for i in RING_SEGMENTS + 1: - var t := TAU * float(i) / float(RING_SEGMENTS) - out.append(_safe_unproject(global_position + (u * cos(t) + v * sin(t)) * RING_R)) - return out - - -func _safe_unproject(p: Vector3) -> Vector2: - if camera == null: - return Vector2.INF - if camera.is_position_behind(p): - return Vector2.INF - return camera.unproject_position(p) - - -func _dist_point_segment(p: Vector2, a: Vector2, b: Vector2) -> float: - var ab := b - a - var len_sq := ab.length_squared() - if len_sq < 0.0001: - return p.distance_to(a) - var t := clampf((p - a).dot(ab) / len_sq, 0.0, 1.0) - return p.distance_to(a + ab * t) - - -# -------------------------------------------------------------- Ziehen ----- - -func _begin_drag(axis: String, mb_pos: Vector2) -> void: - if not _begin_drag_state(axis): - return - # Bildschirm-Mathe: Achse in Pixeln → Zieh-Sensitivität (Meter pro Pixel). - var markers: Array = view_builder.object_markers - var marker = markers[_drag_idx] - var origin: Vector3 = marker.global_position - var o := _safe_unproject(origin) - var t := _safe_unproject(origin + _drag_axis_vec * AXIS_LEN) - if o == Vector2.INF or t == Vector2.INF: - _dragging = false - return - var seg := t - o - var seg_len := seg.length() - if seg_len < 1.0: - _dragging = false - return - _screen_axis = seg.normalized() - _px_per_m = maxf(seg_len / AXIS_LEN, MIN_PX_PER_M) - _press_screen = mb_pos - main.call("_set_status", "Gizmo-Zug: entlang %s ziehen — Mausrad wechselt die Schrittweite (%.2f m), Esc bricht ab." % [ - _drag_axis.to_upper(), step_m]) - - -## Zieh-Zustand NUR aus dem Doc/Marke r aufsetzen (ohne Bildschirm-Mathe — -## auch für den Demo-/Test-Hook demo_drag_axis). -func _begin_drag_state(axis: String) -> bool: - var inter = main.get("interaction") - if inter == null or inter.selected_indices.size() != 1: - return false - var idx: int = int(inter.selected_index) - var markers: Array = view_builder.object_markers - if idx < 0 or idx >= markers.size(): - return false - var marker = markers[idx] - if marker == null or not is_instance_valid(marker): - return false - var objects: Array = main.doc.get("objects", []) - if idx >= objects.size(): - return false - var pos: Array = (objects[idx] as Dictionary).get("pos", [0.0, 0.0, 0.0]) - _drag_idx = idx - _drag_axis = axis - _drag_axis_vec = _axis_vec(axis) - _press_screen = Vector2.ZERO - _start_pos = Vector3(float(pos[0]), float(pos[1]), float(pos[2])) - _start_saved = (pos as Array).duplicate() - _drag_lift = marker.position.y - SvmapDocument.terrain_height_at( - main.doc, _start_pos.x, _start_pos.z) - _drag_before = main.history.snapshot(["objects"]) - _drag_moved = false - _last_delta = 0.0 - _dragging = true - return true - - -func _drag_motion(mb_pos: Vector2) -> void: - var d := mb_pos - _press_screen - var raw := d.dot(_screen_axis) / _px_per_m - _apply_axis_delta(snappedf(raw, step_m)) - - -## Delta entlang der Achse anwenden: doc + Marke + Gizmo, Inspektor LIVE. -func _apply_axis_delta(delta: float) -> void: - if not _dragging or absf(delta - _last_delta) < 0.0005: - return - var objects: Array = main.doc.get("objects", []) - if _drag_idx >= objects.size(): - _finish_drag(false) - return - var np := _start_pos + _drag_axis_vec * delta - var half := _terrain_half() - np.x = clampf(np.x, -half.x, half.x) - np.z = clampf(np.z, -half.y, half.y) - if _drag_axis == "y": - np.y = clampf(np.y, SvmapDocument.terrain_height_at(main.doc, np.x, np.z), _max_y()) - else: - # X/Z-Zug folgt dem Boden (gleiches Verhalten wie der normale Zug): - # der Boden-Abstand bleibt erhalten, nichts begräbt sich. - np.y = SvmapDocument.terrain_height_at(main.doc, np.x, np.z) + _drag_lift - var obj: Dictionary = objects[_drag_idx] - obj["pos"] = [np.x, np.y, np.z] - var markers: Array = view_builder.object_markers - if _drag_idx < markers.size(): - var marker = markers[_drag_idx] - if marker != null and is_instance_valid(marker): - marker.position = np - global_position = np - _last_delta = delta - _drag_moved = true - main.call("_sync_selection_panel") # Inspektor-Zahlen LIVE mitziehen - - -## Zug beenden: commit = true → EIN Undo-Schritt (wirklich bewegt), -## commit = false → exakte Rückabwicklung, KEIN History-Eintrag. -func _finish_drag(commit: bool) -> void: - if not _dragging: - return - _dragging = false - var objects: Array = main.doc.get("objects", []) - var idx := _drag_idx - if commit and absf(_last_delta) > 0.0005 and idx >= 0 and idx < objects.size(): - var desc: String - match _drag_axis: - "x": - desc = "Objekt entlang X verschoben (Gizmo)" - "y": - desc = "Objekt angehoben/abgesenkt (Gizmo, Y-Achse)" - _: - desc = "Objekt entlang Z verschoben (Gizmo)" - main.history.commit(desc, _drag_before, main.history.snapshot(["objects"])) - main.set("dirty", true) - main.call("_refresh_file_label") - main.call("_refresh_history_buttons") - main.call("_refresh_stats") - main.call("_sync_selection_panel") - main.call("_set_status", "%s — %.2f m. Strg+Z nimmt den Zug zurück; Mausrad WÄHREND des Ziehens wechselt fein/grob." % [ - desc, absf(_last_delta)]) - elif not commit and idx >= 0 and idx < objects.size(): - (objects[idx] as Dictionary)["pos"] = _start_saved.duplicate() - var markers: Array = view_builder.object_markers - if idx < markers.size(): - var marker = markers[idx] - if marker != null and is_instance_valid(marker): - marker.position = _start_pos - global_position = _start_pos - main.call("_sync_selection_panel") - main.call("_set_status", "Gizmo-Zug abgebrochen — Position wie vorher.") - _drag_before = {} - _drag_idx = -1 - _drag_axis = "" - _drag_moved = false - _last_delta = 0.0 - - -## Für die Esc-Kette in main.gd: Zug abbrechen, falls einer läuft. true = -## es lief einer und wurde abgebrochen (idempotent, weil _dragging prüft). -func cancel_drag_if_active() -> bool: - if _rot_dragging: - _finish_rotate(false) - return true - if not _dragging: - return false - _finish_drag(false) - return true - - -# --------------------------------------------------- Drehen / Kippen ------- - -func _ring_angle(mouse: Vector2) -> float: - var d := mouse - _rot_center - return atan2(d.y, d.x) - - -func _begin_rotate(axis: String, mouse: Vector2) -> void: - var inter = main.get("interaction") - if inter == null or inter.selected_indices.is_empty(): - return - var c := _safe_unproject(global_position) - if c == Vector2.INF: - return - _rot_axis = axis - _rot_center = c - _rot_start_angle = _ring_angle(mouse) - _rot_applied = 0.0 - _rot_serial += 1 - _rot_suffix = "#g%d" % _rot_serial - _rot_dragging = true - var name := "Drehen (Y)" if axis == "y" else ("Kippen um X" if axis == "x" else "Kippen um Z") - main.call("_set_status", "%s — Ring ziehen, rastet in %.0f°-Schritten; Esc bricht ab, Strg+Z nimmt den Zug zurück." % [name, rot_step_deg]) - - -func _rotate_motion(mouse: Vector2) -> void: - # Bildschirmwinkel → Drehwinkel um die Achse (Vorzeichen je nach Blickrichtung). - var delta_screen := wrapf(_ring_angle(mouse) - _rot_start_angle, -PI, PI) - var facing := _axis_vec(_rot_axis).dot(camera.global_transform.basis.z) - var deg := -rad_to_deg(delta_screen) * (1.0 if facing >= 0.0 else -1.0) - var snapped_deg := snappedf(deg, rot_step_deg) - _rotate_to(snapped_deg) - - -## Auf einen Gesamtwinkel (gerastet) nachführen — in Schritten, EIN Undo-Eintrag. -func _rotate_to(total_deg: float) -> void: - var diff := total_deg - _rot_applied - if absf(diff) < 0.001: - return - var inter = main.get("interaction") - if inter == null: - return - if _rot_axis == "y": - inter.rotate_selected(diff, _rot_suffix) - else: - inter.tilt_selected(_rot_axis == "x", diff, _rot_suffix) - _rot_applied = total_deg - - -func _finish_rotate(commit: bool) -> void: - if not _rot_dragging: - return - _rot_dragging = false - if not commit and absf(_rot_applied) > 0.001: - main.call("_do_undo") # der ganze Zug ist EIN Eintrag → komplett zurück - main.call("_set_status", "Dreh-Zug abgebrochen — Objekt wie vorher.") - _rot_axis = "" - _rot_applied = 0.0 - - -## Probes/Tests: derselbe Pfad wie ein echter Ring-Zug (ohne Maus-Mathe). -func demo_rotate_axis(axis: String, deg: float) -> bool: - var inter = main.get("interaction") if main != null else null - if inter == null or inter.selected_indices.is_empty() or absf(deg) < 0.001: - return false - _rot_axis = axis - _rot_serial += 1 - _rot_suffix = "#g%d" % _rot_serial - _rot_applied = 0.0 - _rotate_to(snappedf(deg, rot_step_deg)) - _rot_axis = "" - _rot_applied = 0.0 - return true - - -# ------------------------------------------------------ Schrittweite ------- - -## Mausrad WÄHREND des Ziehens: durch die Voreinstellungen blättern -## (fein 0,1 → normal 0,5 → grob 2,0 m, wrappt). Das Panel-Feld folgt. -func cycle_step(dir: int) -> void: - var idx := STEP_PRESETS.find(step_m) - if idx < 0: - idx = STEP_PRESETS.size() - 1 # eigener Feld-Wert: vom größten Preset starten - idx = wrapi(idx + dir, 0, STEP_PRESETS.size()) - set_step_m(STEP_PRESETS[idx]) - main.call("_set_status", "Gizmo-Schrittweite: %.2f m (%s) — Mausrad wechselt weiter, das Feld rechts setzt sie exakt." % [ - step_m, STEP_PRESET_NAMES[idx]]) - - -## Feld-Wert übernehmen (Panel-Feld ODER Mausrad-Preset). Haupt-Var hält den -## Wert über UI-Rebuilds (UIScale) hinweg. -func set_step_m(v: float) -> void: - step_m = clampf(v, STEP_MIN, STEP_MAX) - if main != null: - main.set("gizmo_step_m", step_m) - - -# ------------------------------------------------------- Demo-/Test-Hook --- - -## Probes/Tests: denselben Anwendungs- + Commit-Pfad wie ein echter Zug, -## ohne Bildschirm-Mathe. true = es wurde wirklich bewegt + committed. -func demo_drag_axis(axis: String, meters: float) -> bool: - if main == null: - return false - var applied := snappedf(meters, step_m) - if absf(applied) < 0.0005: - return false - if not _begin_drag_state(axis): - return false - _apply_axis_delta(applied) - _finish_drag(true) - return true - - -# ------------------------------------------------------------ Helfer ------- - -func _terrain_half() -> Vector2: - var terrain: Dictionary = main.doc.get("terrain", {}) - return Vector2(float(terrain.get("size_x_m", 1024.0)), - float(terrain.get("size_z_m", 1024.0))) * 0.5 - - -func _max_y() -> float: - var bounds: Dictionary = main.doc.get("bounds", {}) - var mx = bounds.get("max", null) - if mx is Array and (mx as Array).size() == 3: - return float((mx as Array)[1]) - return 80.0 diff --git a/src/viewport/gizmo.gd.uid b/src/viewport/gizmo.gd.uid deleted file mode 100644 index c114071..0000000 --- a/src/viewport/gizmo.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bchu6tv6aetfh diff --git a/src/viewport/glb_mesh_store.gd b/src/viewport/glb_mesh_store.gd deleted file mode 100644 index e4f3eda..0000000 --- a/src/viewport/glb_mesh_store.gd +++ /dev/null @@ -1,450 +0,0 @@ -extends RefCounted -class_name GlbMeshStore -## Echte GLB-Renderings für Bibliotheks-Objekte im Editor-Viewport -## (Karte t_9b50b231). Der Viewport-Bauer zeigt bisher nur den -## Kollisions-Platzhalter (MeshShapes.make_placeholder) — diese statische -## Loader-Schicht holt stattdessen das ECHTE Modell aus dem Mesh-Lager -## (Sibling-Repos, gleiche Quellen wie tools/gen_thumbs.gd) und fällt ohne -## GLB auf den Platzhalter zurück. -## -## Messkonvention wie addons/modular_builder/scopedvr_export.gd -## `normalisiere`: das geladene Mesh wird in Fußpunkt-Koordinaten gebacken — -## Unterkante auf y = 0, XZ um den Mittelpunkt zentriert. Pack-GLBs haben -## ihren Mesh-Ursprung oft in der Mitte, deshalb wird die AABB-Unterkante -## GERECHNET und nie blind platziert. Damit gilt wie beim Compound-Platzhalter: -## MeshShapes.half_height(mesh) == 0 und marker.position == Fußpunkt. -## -## Plattform-Regel (PLAN.md): nur relative Kandidaten-Pfade, konfigurierbar -## über ProjectSettings — läuft identisch auf Linux und Windows. -## -## Performance: EIN Parse pro OID, Ergebnis gecacht — der Rebuild bei jedem -## Platzieren/Undo liest nur noch aus dem Cache. - -## ProjectSettings-Schlüssel für die GLB-Quellen (relativ zum Editor-Projekt). -const QUELLEN_SETTING := "scopedvr/editor/glb_quellen" -## Voreinstellung = dieselben Quellen wie tools/gen_thumbs.gd (Sibling-Repos). -const DEFAULT_QUELLEN := ["../scopedvr-match-server/assets/objekte", "../scopedvr-client/assets/objekte"] -## Mitgelieferter Modell-Ordner (Karte t_12cf94fe): direkt neben der App -## (im Editor = Projektordner, in der exportierten App = neben der EXE). -## Der sync über tools/sync_models.sh legt hier die GLBs + Pack-Texturen -## ab — dann läuft der Map Builder auf einem fremden PC OHNE Sibling-Repos. -## Der Ordner trägt eine .gdignore (kein Import/PCK-Aufnahme; FileAccess -## mit absolutem Pfad funktioniert trotzdem). -const MODELS_DIR := "models" -## Klarer Hinweistext (Karte t_12cf94fe, Auftrag 3), wenn Modelle fehlen: -## wird als Klartext-Meldung gezeigt — kein stiller Platzhalter. -## Notfall-Modus: Terrain/Bauteile brauchen keine GLBs und funktionieren immer. -const FEHLT_TEXT := "Für die Anzeige fehlen die Modelle. So bekommst du sie:\n" \ - + " 1. tools/sync_models.sh aus dem Map-Editor-Ordner laufen lassen\n" \ - + " (kopiert die Modelle in den Ordner %s),\n" \ - + " 2. oder in den Einstellungen einen Ordner mit den Objekt-GLBs setzen.\n" \ - + "Terrain und Bauteile funktionieren trotzdem vollständig (Notfall-Modus)." -## Registry (A6): liefert das Feld "glb" für die Kategorie-verschachtelte Ablage. -const MANIFEST_PATH := "res://library/objects.json" -static var _manifest: Dictionary = {} -static var _manifest_geladen := false - -# WYSIWYG-Fix (t_c8748efc, korrigiert in t_279df760): GLTFDocument löst externe -# Textur-URIs (Sibling-Repos, außerhalb res://) NICHT auf — im Editor-Viewport -# blieben die GLB-Objekte untexturiert/Editor-Farbe, während sie im Spiel -# getextured sind. Flächen OHNE albedo_texture bekommen hier die Textur, die das -# ITHappy-Pack für ihren MATERIALNAMEN vorsieht — Zuordnung identisch zu -# tools/PACK_TEXTURE_MAPPING.md (Client-Repo, verbindlich): -# military_base (+_00x) = Palette (Demonstration_Textures1.png, 1024²) -# picture_1/2/3 = echtes Multicam (Demonstration_picture_N.png, 2048²) -# Wichtig: Nichts wird überschrieben — GLTF-aufgelöste Texturen bleiben unangetastet. -# (Der frühere Inhalt-Vergleich + Kategorie-Camo stammte aus aa94bde und hat auch -# korrekte Pack-Texturen wieder durch Camo ersetzt — das war der Fehler.) -const PACK_TEX_PALETTE := "Demonstration_Textures1.png" -const PACK_TEX_PICTURE_1 := "Demonstration_picture_1.png" -const PACK_TEX_PICTURE_2 := "Demonstration_picture_2.png" -const PACK_TEX_PICTURE_3 := "Demonstration_picture_3.png" - -# ImageTexture pro Textur-Pfad gecacht — sonst erzeugt jede der 291 GLBs -# ihre eigene 2048²-Textur (~16 MB VRAM je Stück statt 2 × 16 MB gesamt). -# false = Ladeversuch fehlgeschlagen (kein endloser Retry + Warn-Flut). -static var _camo_tex_cache: Dictionary = {} -## Dekodierte Multicam-Bilder (RAM, 2 × 2048² ≈ 32 MB) für den Inhalts- -## Vergleich gegen GLTF-eigene Textur-Instanzen. -static var _camo_bild_cache: Dictionary = {} -## Urteil pro GLTF-Textur-Instanz (instance_id → geteilte Textur | false), -## damit der 16-MB-Datenvergleich nur einmal je Instanz läuft. -static var _camo_ersetzung_cache: Dictionary = {} - -# Cache pro OID: Mesh (normalisiert) oder `false` = GLB gefunden, aber nicht -# ladbar (Parse-Fehler — kein endloser Retry pro Rebuild). Fehlende Datei -# bleibt UNGECACHED (nur ein billiger Datei-Check pro Rebuild; legt man die -# GLB später ab, erscheint sie ohne Editor-Neustart). -static var _cache: Dictionary = {} - - -## Kandidaten-Pfade der Quellen in Ladereihenfolge (Karte t_12cf94fe, -## Auftrag 1 — EINE Stelle, erster Treffer gewinnt): -## 1. in den Einstellungen gesetzter Pfad (QUELLEN_SETTING), -## 2. bisheriges Verhalten = Sibling-Repos (DEFAULT_QUELLEN), -## 3. mitgelieferter Ordner models/ direkt neben der App (MODELS_DIR). -## Doppelnennungen werden gefiltert (Reihenfolge bleibt erhalten); ein -## ungültiger Settings-Wert (kein Array) fällt komplett auf die Vorgabe. -static func quellen() -> Array: - var out: Array = [] - var setting: Variant = ProjectSettings.get_setting(QUELLEN_SETTING, DEFAULT_QUELLEN) - if setting is Array or setting is PackedStringArray: - for q in setting: - _quelle_add(out, q) - for q in DEFAULT_QUELLEN: - _quelle_add(out, q) - _quelle_add(out, MODELS_DIR) - return out - - -## Gültigen Quellpfad dedupliziert anhängen (typisiert, keine impliziten casts). -static func _quelle_add(out: Array, q: Variant) -> void: - if not (q is String): - return - var s := (q as String).strip_edges() - if s.is_empty() or out.has(s): - return - out.append(s) - - -## Absoluter Pfad des mitgelieferten Modell-Ordners (für die Klartext- -## Meldung und tools/sync_models.sh-Verweis). Im Editor = Projektordner, -## in der exportierten App = Ordner der EXE. -static func models_pfad() -> String: - return ProjectSettings.globalize_path("res://").path_join(MODELS_DIR) - - -## Erster EXISTIERENDER Dateipfad für die OID (ohne Laden/Parse — billiger -## Datei-Check über alle Kandidaten in Quellen-Reihenfolge). Leerer String = -## kein Quellpfad hat die Datei. Für Klartext-Meldungen/Probe-Logs: zeigt, -## AUS WELCHEM Ordner die Modelle kommen. -static func probe_source_fuer(oid: String) -> String: - if oid.is_empty(): - return "" - for pfad in _kandidaten(oid): - if FileAccess.file_exists(pfad): - return pfad - return "" - - -## Ausgefüllter Klartext-Hinweis (FEHLT_TEXT + echter models/-Pfad) — -## diese EINE Funktion liefert die Meldung, die die App zeigt, wenn -## Modelle fehlen (Karte t_12cf94fe, Auftrag 3). -static func fehl_text() -> String: - return FEHLT_TEXT % models_pfad() - - -## Kandidaten-Pfade (absolut) in Ladereihenfolge: Registry-`glb` (A6, Kategorie- -## Ablage assets/objekte/military_desert//.glb) VOR der flachen -## Alt-Ablage /.glb. Die Quelle ist ein Mesh-Lager (/assets/ -## objekte) — für den verschachtelten Pfad wird sie auf die Repo-Wurzel gekürzt. -static func _kandidaten(oid: String) -> Array: - var basis := ProjectSettings.globalize_path("res://") - var out: Array = [] - var rel := str(_eintrag(oid).get("glb", "")) - if rel.begins_with("res://"): - var sub := rel.substr(6) - # Operator-Korrektur 20.10. (Eigenständigkeits-Beweis): der mitgelieferte - # models/-Ordner NEBEN der App enthält die Pack-Struktur DIREKT - # (models/military_desert/props/box_010.glb) — nicht unter - # models/assets/objekte/. Ohne den zweiten Kandidaten unten werden ALLE - # verschachtelten Pack-Objekte in der eigenständigen App nicht gefunden - # (belegt: barrel_001/box_010 -> leer, fehlende_glbs=2 trotz 334 GLBs). - var sub_kurz := sub.trim_prefix("assets/objekte/") - for quelle in quellen(): - var q := str(quelle) - var marke := "/assets/objekte" - var wurzel := q.substr(0, q.length() - marke.length()) if q.ends_with(marke) else q - out.append(basis.path_join(wurzel).path_join(sub)) - if sub_kurz != sub: - out.append(basis.path_join(wurzel).path_join(sub_kurz)) - for quelle in quellen(): - out.append(basis.path_join(str(quelle)).path_join(oid + ".glb")) - return out - - -## Registry-Eintrag der OID (einmal gelesen, dann gecacht). -static func _eintrag(oid: String) -> Dictionary: - if not _manifest_geladen: - _manifest_geladen = true - var parsed: Variant = JSON.parse_string(FileAccess.get_file_as_string(MANIFEST_PATH)) - if parsed is Dictionary: - _manifest = (parsed as Dictionary).get("objects", {}) - return _manifest.get(oid, {}) - - -## Echtes Mesh für eine Objekt-ID (normalisiert, Fußpunkt-Koordinaten) oder -## null = keine brauchbare GLB → Aufrufer zeigt den Platzhalter. -static func mesh_fuer(oid: String) -> Mesh: - if oid.is_empty(): - return null - # Bauteile (bau_*) entstehen aus dem Katalog — identisch zu den GLBs, die - # der Client lädt (tools/gen_bauteile.gd), aber ohne Modell-Ordner nötig. - if BauKatalog.ist_bau(oid): - return BauKatalog.mesh(oid) - if _cache.has(oid): - return _cache[oid] if _cache[oid] is Mesh else null - for pfad in _kandidaten(oid): - if FileAccess.file_exists(pfad): - var m := _glb_mesh(pfad) - if m != null: - camo_tex_setzen(m, pfad) - _cache[oid] = m - return m - # Datei da, aber kaputt → NEGATIV cachen (Parse-Fehler wiederholt - # sich sonst bei jedem Rebuild und kostet Zeit). - _cache[oid] = false - return null - return null - - -## Liegt für die OID überhaupt eine GLB-Datei im Lager? (Billiger Check ohne -## Parse — für Statuszeilen-Hinweise beim Platzieren.) -static func fehlt(oid: String) -> bool: - if oid.is_empty(): - return true - if BauKatalog.ist_bau(oid): - return false - if _cache.has(oid): - return not (_cache[oid] is Mesh) - for pfad in _kandidaten(oid): - if FileAccess.file_exists(pfad): - return false - return true - - -## true = KEINE Quelle (Einstellungen/Siblings/models/) enthält irgend eine -## GLB-Datei → die App hat nirgends echte Modelle. Für das Klartext-Banner -## beim Start (Karte t_12cf94fe, Auftrag 3). Nicht-cachend, einmal pro Start. -static func lager_ist_leer() -> bool: - for quelle in quellen(): - if _quelle_hat_glb(ProjectSettings.globalize_path("res://").path_join(str(quelle))): - return false - return true - - -## Enthält der Ordner (rekursiv) mindestens eine .glb-Datei? -static func _quelle_hat_glb(basis: String) -> bool: - var d := DirAccess.open(basis) - if d == null: - return false - d.list_dir_begin() - var name := d.get_next() - while name != "": - var pfad := basis.path_join(name) - if d.current_is_dir(): - if _quelle_hat_glb(pfad): - return true - elif name.ends_with(".glb"): - return true - name = d.get_next() - return false - - -## Cache leeren (Tests / nach manuellem Eingriff ins Mesh-Lager). -static func cache_leeren() -> void: - _cache.clear() - _camo_tex_cache.clear() - _camo_bild_cache.clear() - _camo_ersetzung_cache.clear() - _manifest.clear() - _manifest_geladen = false - - -# ------------------------------------------------------------ Laden -------- - -## GLB OHNE Import-System laden (GLTFDocument, wie gen_thumbs) und ALLE -## MeshInstance3D der Szene in EIN ArrayMesh zusammenbacken (Jedes Teil-Node -## mit seiner Node-Transform; Materialien je Oberfläche bleiben erhalten — -## echte Texturen statt Editor-Farbe). null = Load-Fehlschlag. -static func _glb_mesh(pfad: String) -> Mesh: - var gltf := GLTFDocument.new() - var state := GLTFState.new() - if gltf.append_from_file(pfad, state) != OK: - push_warning("GlbMeshStore: GLB nicht ladbar: %s" % pfad) - return null - var szene: Node = gltf.generate_scene(state) - if szene == null: - return null - var m := _zusammenbacken(szene) - # Das Mesh ist eine Resource (RefCounted) — das Freigeben der Szene - # berührt die Referenz im Rückgabewert nicht. - szene.free() - return m - - -## Alle Mesh-Instanzen der Szene → ein ArrayMesh (Transforms angewandt, -## Materialien übernommen), dann normalisiert (Fußpunkt-Konvention). -static func _zusammenbacken(szene: Node) -> Mesh: - var roh := ArrayMesh.new() - _sammeln(szene, Transform3D.IDENTITY, roh) - if roh.get_surface_count() == 0: - return null - return _normalisiert(roh) - - -static func _sammeln(n: Node, xf: Transform3D, out: ArrayMesh) -> void: - if n is Node3D: - xf = xf * (n as Node3D).transform - if n is MeshInstance3D and (n as MeshInstance3D).mesh != null: - var m: Mesh = (n as MeshInstance3D).mesh - for s in m.get_surface_count(): - var arrays: Array = m.surface_get_arrays(s) - if arrays.is_empty() or not (arrays[Mesh.ARRAY_VERTEX] is PackedVector3Array): - continue - var verts: PackedVector3Array = arrays[Mesh.ARRAY_VERTEX] - for i in verts.size(): - verts[i] = xf * verts[i] - arrays[Mesh.ARRAY_VERTEX] = verts - if arrays[Mesh.ARRAY_NORMAL] is PackedVector3Array: - var norms: PackedVector3Array = arrays[Mesh.ARRAY_NORMAL] - for i in norms.size(): - norms[i] = (xf.basis * norms[i]).normalized() - arrays[Mesh.ARRAY_NORMAL] = norms - # Statisch fürs Editor-Viewport: Skin-Daten fliegen raus (sonst - # verlangt add_surface_from_arrays ein Skeleton). - arrays[Mesh.ARRAY_BONES] = null - arrays[Mesh.ARRAY_WEIGHTS] = null - out.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) - var mat: Material = m.surface_get_material(s) - if mat != null: - out.surface_set_material(out.get_surface_count() - 1, mat) - for c in n.get_children(): - _sammeln(c, xf, out) - - -## Fußpunkt-Konvention (wie scopedvr_export.normalisiere): Unterkante y = 0, -## XZ um den AABB-Mittelpunkt zentriert. Materialien bleiben an den Flächen. -static func _normalisiert(mesh: ArrayMesh) -> ArrayMesh: - var aabb := mesh.get_aabb() - var offset := Vector3(-aabb.get_center().x, -aabb.position.y, -aabb.get_center().z) - var out := ArrayMesh.new() - out.resource_name = mesh.resource_name - for s in mesh.get_surface_count(): - var arrays: Array = mesh.surface_get_arrays(s) - if arrays.is_empty() or not (arrays[Mesh.ARRAY_VERTEX] is PackedVector3Array): - continue - var verts: PackedVector3Array = arrays[Mesh.ARRAY_VERTEX] - for i in verts.size(): - verts[i] = verts[i] + offset - arrays[Mesh.ARRAY_VERTEX] = verts - out.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) - var mat: Material = mesh.surface_get_material(s) - if mat != null: - out.surface_set_material(out.get_surface_count() - 1, mat) - return out - - -# ------------------------------------------------------- Camo-Textur -------- - -## Camo-Fix (t_50a07d4b): Multicam-Textur von der Platte laden und auf alle -## Flächen ohne albedo_texture setzen (GLTFDocument löst externe URIs der -## Sibling-Repos nicht auf). Zuordnung exakt wie tools/CAMO_TEXTURE_MAPPING.md -## bzw. gen_thumbs._camo_tex_setzen — diese Funktion ist ab jetzt DIE EINE -## Quelle der Zuordnung (gen_thumbs delegiert hierher). Objekte außerhalb -## military_desert//.glb bleiben unangetastet. Fehlt die -## Textur-Datei, wird klar gewarnt (push_warning) statt still weiß zu rendern. -## -## EINE-Quelle-Dedup (t_50a07d4b): GLTFDocument lädt externe Texturen -## inzwischen selbst — aber als EIGENE ImageTexture-Instanz JEDES Parses -## (291 GLBs = 291 × 16 MB VRAM statt 2 × 16 MB, bewiesen per Probe: -## iid pro Parse unterschiedlich, Inhalt identisch zur Datei). Deshalb wird -## hier ZUSÄTZLICH geprüft: stimmt der Inhalt einer GLTF-Textur mit einer -## Multicam-Datei überein, ersetzen wir sie durch DIE eine geteilte Instanz -## aus dem Cache — gleiche Optik (WYSIWYG bleibt), eine Quelle statt Kopien. -## Eingebettete/Fremd-Texturen (Alt-Bestand, Waffen-GLBs) bleiben unangetastet. -static func camo_tex_setzen(mesh: Mesh, glb_pfad: String) -> void: - # Siehe Kopf-Kommentar: nur Flächen OHNE aufgelöste Textur werden versorgt. - var tex_dir := glb_pfad.get_base_dir().path_join("../../../textures/military_desert") - for s in mesh.get_surface_count(): - var mat := mesh.surface_get_material(s) - if not (mat is BaseMaterial3D): - continue - var bm := mat as BaseMaterial3D - if bm.albedo_texture != null: - continue - var datei := pack_datei_fuer(bm.resource_name) - var tex := _camo_tex(tex_dir.path_join(datei)) - if tex != null: - bm.albedo_texture = tex - else: - push_warning("GlbMeshStore: Pack-Textur fehlt fuer Material '%s': %s" % [bm.resource_name, datei]) - - -## Materialname (GLTF) -> Pack-Texturdatei. Quelle: tools/PACK_TEXTURE_MAPPING.md (Client). -static func pack_datei_fuer(material_name: String) -> String: - match material_name: - "picture_1": - return PACK_TEX_PICTURE_1 - "picture_2": - return PACK_TEX_PICTURE_2 - "picture_3": - return PACK_TEX_PICTURE_3 - "military_base": - return PACK_TEX_PALETTE - if material_name.begins_with("military_base"): - return PACK_TEX_PALETTE - return PACK_TEX_PALETTE - -static func _camo_image(pfad: String, warnen: bool) -> Image: - if _camo_bild_cache.has(pfad): - var v: Variant = _camo_bild_cache[pfad] - return v if v is Image else null - if not FileAccess.file_exists(pfad): - if warnen: - push_warning("GlbMeshStore: Camo-Textur fehlt: %s" % pfad) - _camo_bild_cache[pfad] = false - return null - var img := Image.load_from_file(pfad) - if img == null: - if warnen: - push_warning("GlbMeshStore: Camo-Textur nicht ladbar: %s" % pfad) - _camo_bild_cache[pfad] = false - return null - _camo_bild_cache[pfad] = img - return img - - -## DIE EINE geteilte ImageTexture für eine Multicam-Datei (VRAM-Cache). -## Alle getextureden GLB-Flächen teilen sich genau diese Instanz. -static func _camo_tex(tex_pfad: String) -> ImageTexture: - if _camo_tex_cache.has(tex_pfad): - var v: Variant = _camo_tex_cache[tex_pfad] - return v if v is ImageTexture else null - var img := _camo_image(tex_pfad, true) - if img == null: - _camo_tex_cache[tex_pfad] = false - return null - var tex := ImageTexture.create_from_image(img) - _camo_tex_cache[tex_pfad] = tex - return tex - - -## Ersetzt eine GLTF-eigene ImageTexture durch die geteilte Multicam-Instanz, -## WENN der Inhalt (Größe, Format, Pixeldaten) mit einer der Kandidaten- -## Dateien übereinstimmt. null = kein Match → Textur bleibt unangetastet -## (eingebettete/Fremd-Texturen). Urteil je Instanz gecacht. -static func _camo_ersetzung_fuer(tex: Texture2D, kandidaten: Array) -> ImageTexture: - if not (tex is ImageTexture): - return null - var iid := tex.get_instance_id() - if _camo_ersetzung_cache.has(iid): - var v: Variant = _camo_ersetzung_cache[iid] - return v if v is ImageTexture else null - var img: Image = (tex as ImageTexture).get_image() - if img == null: - _camo_ersetzung_cache[iid] = false - return null - var out: ImageTexture = null - for pfad in kandidaten: - var vergleich := _camo_image(str(pfad), false) - if vergleich == null: - continue - if img.get_width() == vergleich.get_width() \ - and img.get_height() == vergleich.get_height() \ - and img.get_format() == vergleich.get_format() \ - and img.data == vergleich.data: - out = _camo_tex(str(pfad)) - break - _camo_ersetzung_cache[iid] = out if out != null else false - return out diff --git a/src/viewport/glb_mesh_store.gd.uid b/src/viewport/glb_mesh_store.gd.uid deleted file mode 100644 index 7fbaa0f..0000000 --- a/src/viewport/glb_mesh_store.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bdbx4rc3fx5ix diff --git a/src/viewport/map_view_builder.gd b/src/viewport/map_view_builder.gd deleted file mode 100644 index 8469d9d..0000000 --- a/src/viewport/map_view_builder.gd +++ /dev/null @@ -1,883 +0,0 @@ -extends Node3D -## Baut die visuelle Repräsentation der Map im Editor-Viewport: -## Terrain-Höhenfeld-Mesh + Maßstabsgitter + Himmel/Licht -## + Echte GLB-Meshes für Bibliotheks-Objekte (GlbMeshStore; ohne GLB = -## Platzhalter-Mesh aus dem Kollisions-Eintrag) + Spawn-Marker mit Beschriftung. -## ## -## Objekt-Marker werden in object_markers gemerkt (Meta: obj_index, -## pick_radius) — Auswahl/Werkzeuge (interaction.gd) greifen darauf zu, -## statt die Szene selbst zu durchsuchen. - -const GRID_COLOR := Color(0.35, 0.45, 0.55, 0.6) -const AXIS_COLOR := Color(0.9, 0.7, 0.2, 0.9) -const OBJECT_COLOR := Color(0.55, 0.75, 0.95) -const TEAM_COLORS := [Color(0.3, 0.6, 1.0), Color(1.0, 0.35, 0.3)] # Blau / Rot -# Auswahl-Markierung (U6, t_639135dd): Farbe + Breite kommen aus dem Theme -# (eine Quelle) — Auswahl-Kontur, schwächere Hover-Kontur, dünn-gestrichelte -# Partner-Kontur. Kein Vollflächen-Orange mehr: das Grundmaterial (mit Textur) -# bleibt sichtbar, die Markierung lebt als Außenhüllen-Kontur darum herum. -const THEME_PATH := "res://theme/editor_theme.tres" -const OUTLINE_SHADER := "res://shaders/selection_outline.gdshader" -# Fallback, falls das Theme (noch) nicht geladen werden kann. -const OUTLINE_FALLBACK := Color(1.0, 0.6, 0.15, 0.95) - -# Wetter → Licht/Himmel — 1:1-SPIEGEL aus client/scripts/world/weather_presets.gd -# (Karte t_f72913d4: Editor-Vorschau zeigt exakt was der Client zeigt — dieselbe -# Projekt-Konvention wie KolliderBau als 1:1-Spiegel von svmap_world, t_1da96275). -# Bei Preset-Änderungen im Client HIER MITPFLEGEN. Schlüssel = Client-Keys. -const WEATHER_LIGHT := { - "mittag": { - "sky_top": Color(0.30, 0.54, 0.86), "sky_horizon": Color(0.72, 0.83, 0.92), - "ground_bottom": Color(0.20, 0.23, 0.27), "ground_horizon": Color(0.66, 0.75, 0.83), - "sky_energy": 1.0, - "sun_deg": Vector2(-52.0, 30.0), "sun_energy": 1.2, "sun_color": Color(1.0, 0.98, 0.92), - "ambient_source": "sky", "ambient_color": Color(0.60, 0.70, 0.85), "ambient_energy": 1.0, - "fog_enabled": false, "fog_color": Color(0.80, 0.85, 0.90), - "fog_density": 0.0, "fog_sky_affect": 0.0, - "sky_panorama": false, - "panorama_fog_color": Color(0.93, 0.80, 0.66), "panorama_energy": 1.0, - }, - "abend": { - "sky_top": Color(0.25, 0.30, 0.55), "sky_horizon": Color(0.95, 0.55, 0.28), - "ground_bottom": Color(0.16, 0.13, 0.14), "ground_horizon": Color(0.80, 0.45, 0.25), - "sky_energy": 1.0, - "sun_deg": Vector2(-8.0, 250.0), "sun_energy": 0.9, "sun_color": Color(1.0, 0.62, 0.35), - "ambient_source": "color", "ambient_color": Color(0.55, 0.40, 0.32), "ambient_energy": 0.8, - "fog_enabled": true, "fog_color": Color(0.85, 0.55, 0.35), - "fog_density": 0.004, "fog_sky_affect": 0.2, - "sky_panorama": false, - "panorama_fog_color": Color(0.95, 0.72, 0.48), "panorama_energy": 0.8, - }, - "regen": { - "sky_top": Color(0.38, 0.41, 0.45), "sky_horizon": Color(0.55, 0.58, 0.62), - "ground_bottom": Color(0.22, 0.23, 0.25), "ground_horizon": Color(0.50, 0.53, 0.57), - "sky_energy": 0.9, - "sun_deg": Vector2(-40.0, 120.0), "sun_energy": 0.25, "sun_color": Color(0.75, 0.78, 0.82), - "ambient_source": "color", "ambient_color": Color(0.55, 0.58, 0.62), "ambient_energy": 1.0, - "fog_enabled": true, "fog_color": Color(0.55, 0.58, 0.62), - "fog_density": 0.015, "fog_sky_affect": 0.6, - "sky_panorama": false, - "panorama_fog_color": Color(0.76, 0.72, 0.68), "panorama_energy": 0.55, - }, - "nacht": { - "sky_top": Color(0.015, 0.03, 0.08), "sky_horizon": Color(0.05, 0.08, 0.15), - "ground_bottom": Color(0.01, 0.015, 0.025), "ground_horizon": Color(0.04, 0.06, 0.11), - "sky_energy": 1.0, - "sun_deg": Vector2(-65.0, 200.0), "sun_energy": 0.35, "sun_color": Color(0.62, 0.72, 1.0), - "ambient_source": "color", "ambient_color": Color(0.10, 0.14, 0.25), "ambient_energy": 0.5, - "fog_enabled": true, "fog_color": Color(0.04, 0.06, 0.11), - "fog_density": 0.006, "fog_sky_affect": 0.4, - "sky_panorama": false, - "panorama_fog_color": Color(0.10, 0.12, 0.18), "panorama_energy": 0.10, - }, -} - -## Pack-Panorama-Skybox (Karte t_f72913d4): die Textur liegt im Client-Repo -## (Nachbar-Klon — KEINE Duplikat-Pflicht im Editor, siehe Spec) und wird über -## einen absoluten Pfad geladen; fehlt sie → Fallback ProceduralSky. -const PANORAMA_SKY_CLIENT_REL := "assets/textures/military_desert/Skybox_3.png" - -## Absoluter Pfad der Pack-Skybox im Nachbar-Klon ("" = kein Klon gefunden). -static func panorama_sky_pfad() -> String: - var root := TestRun.find_client(ProjectSettings.globalize_path("res://"), - TestRun.load_cfg()) - if root.is_empty(): - return "" - return root.path_join(PANORAMA_SKY_CLIENT_REL) - -var selected_index := -1 # aktuelles Auswahl-Objekt (Kontur-Markierung) -var selected_indices: Array = [] # komplette Auswahl (Karte t_f6f29d86 — Mehrfachauswahl) -var hover_index := -1 # Hover-Objekt (schwächste Kontur; U6-Abstufung) -var object_markers: Array = [] # Node3D je Objekt (gleiche Reihenfolge wie doc.objects) -var fehlende_glbs: Array = [] # OIDs ohne echte GLB (Platzhalter-Fallback — Statuszeilen-Hinweis) -var zone_root: Node3D = null # Conquest-Zonen bzw. Hills (Spielmodus), Kinder je Zone -var spawn_markers: Array = [] # Node3D je Spawn-Point (Meta: spawn_team/spawn_id/spawn_radius) -var terrain_view # TerrainMesh-Ansicht (script-erweitert, Variant) -var grid_node: MeshInstance3D # Maßstabsgitter (Toggle „⊞ Gitter“, Karte t_7ac70014) - -var _doc_ref: Dictionary = {} # letztes rebuild-Doc (Auswahl-Markierung) - -var _base_mat: StandardMaterial3D -var _sym_partners: Array = [] # Indizes der Zwillinge der aktuellen Auswahl -# Kontur-Materialien (U6): Auswahl / Hover / Spiegel-Zwilling — Farben und -# Breiten kommen aus dem Theme, der Shader ist die Außenhüllen-Technik. -var _outline_mat_sel: ShaderMaterial -var _outline_mat_hover: ShaderMaterial -var _outline_mat_partner: ShaderMaterial - - -func _ready() -> void: - rebuild({}, {}) - - -## Komplette Szene aus dem Map-Dict neu aufbauen. manifest = Bibliotheks-Registry. -func rebuild(data: Dictionary, manifest: Dictionary) -> void: - for child in get_children(): - child.queue_free() - object_markers = [] - spawn_markers = [] - zone_root = null - grid_node = null - _doc_ref = data - _base_mat = StandardMaterial3D.new() - _base_mat.albedo_color = OBJECT_COLOR - _base_mat.roughness = 0.8 - # U6 (t_639135dd): keine Vollfarben-Materialien mehr — die Markierung - # (Auswahl/Hover/Partner) lebt als Außenhüllen-Kontur um das Modell, - # Farben + Breiten aus dem Theme. - _markierung_theme_laden() - _sym_partners = [] - - if data.is_empty(): - return - - var terrain: Dictionary = data.get("terrain", {}) - var size_x := float(terrain.get("size_x_m", 1024.0)) - var size_z := float(terrain.get("size_z_m", 1024.0)) - var ground_y := float(terrain.get("min_height_m", 0.0)) - var weather := str(data.get("weather", "mittag")) - # Skybox-Option (Karte t_f72913d4): optionales svmap-Feld `weather_sky` - # ("sky_panorama"/"prozedural"/leer) — dieselbe Semantik wie im Client. - var weather_sky := str(data.get("weather_sky", "")) - - _build_environment(weather, weather_sky) - _build_terrain(data) - _build_wasser(data) # Karte t_28fdef03: nach dem Terrain (Senken füllen sich) - _build_grid(size_x, size_z, ground_y) - # Gitter default AUS über sichtbarem Terrain (Karte t_7ac70014): das - # Terrain ist die Bodendarstellung — das Gitter lag als Linien-Overlay - # DARÜBER und wirkte wie ein „unfertiges“ Editor-Raster. Ohne Terrain- - # Block bleibt es als Boden-Referenz sichtbar. - if grid_node != null: - grid_node.visible = terrain.is_empty() - _build_objects(data.get("objects", []), manifest) - _rebuild_spawn_markers(data) - rebuild_zone_markers(data) - - -## Terrain als echtes Höhenfeld-Mesh statt flacher Ebene (Karte t_9aba04f1): -## der Terrain-Pinsel schreibt die Vertices live neu (terrain_view.update_terrain). -func _build_terrain(data: Dictionary) -> void: - terrain_view = Node3D.new() - terrain_view.set_script(load("res://src/viewport/terrain_mesh.gd")) - add_child(terrain_view) - terrain_view.call("rebuild_from_doc", data) - - -## Wasserfläche (Karte t_28fdef03): EINE transparente Fläche auf `water_level` -## über der GANZEN Map (SvmapWasser.baue — Senken unter der Höhe füllen sich -## automatisch). OHNE Feld → kein Wasser (Legacy-Maps unverändert). Dasselbe -## Material-Verfahren wie der Client (SvmapWasser.make_material — Identitäts- -## Vertrag der Vorschau: Editor zeigt exakt, was der Quest-Client zeigt). -## Leicht ÜBER dem Terrain eingehängt (y-Offset +0.01 über Reihenfolge), aber -## die Fläche selbst liegt exakt auf der Wasserhöhe (Z-Fight-Vermeidung macht -## der Shader über die Tiefen-Textur, nicht über einen Off-Aufschlag). -func _build_wasser(data: Dictionary) -> void: - var level := SvmapWasser.level(data) - if not is_finite(level): - return # Legacy/fehlendes Feld — kein Wasser, nichts bauen. - var terrain: Dictionary = data.get("terrain", {}) - var wetter := str(data.get("weather", "mittag")) - var wasser := SvmapWasser.baue(terrain, level, wetter) - if wasser != null: - add_child(wasser) - - -## Live-Update während eines Pinsel-Strichs (aus terrain_tool.gd): nur die -## Vertices werden neu geschrieben — Grid/Objekte/Marker bleiben unangetastet. -## mats (optional) = Material-Schicht (Karte t_603ec1a8, Malen-Modus) — -## leer = terrain_mesh verwendet die zuletzt gesehene Schicht weiter (Cache, -## Karte t_55ed041a); nur bei NIE gesehener Schicht (Legacy-v1) gilt Gras. -## splat_rect_cells (optional, Karte t_7a0a6b79) = Zellrechteck des Mal- -## Schritts (inkl. Spiegelzellen) — terrain_mesh leitet nur die Splat-Region -## neu ab (Sub-Rect-Update, kein Voll-Rebuild pro Mal-Frame). -func update_terrain(heights: PackedFloat32Array, mats: PackedByteArray = PackedByteArray(), - splat_rect_cells: Rect2i = Rect2i()) -> void: - if terrain_view != null and is_instance_valid(terrain_view): - terrain_view.call("update_heights", heights, 0, 0.0, 0.0, mats, splat_rect_cells) - - -## Misch-Schicht für das nächste Live-Update (Malen mit weichem Rand, Karte 25.10.). -func set_terrain_mix(mix_b: PackedByteArray, mix_w: PackedByteArray) -> void: - if terrain_view != null and is_instance_valid(terrain_view): - terrain_view.call("set_mix", mix_b, mix_w) - - -## Nur das Terrain neu aufbauen (nach Strich-Commit/Undo) — Objekt-Marker und -## Auswahl bleiben bestehen, kein Flackern der ganzen Szene. -func rebuild_terrain_from_doc(data: Dictionary) -> void: - if terrain_view != null and is_instance_valid(terrain_view): - terrain_view.call("rebuild_from_doc", data) - - -## Himmel/Licht — 1:1-Spiegel von client autoload/weather.gd._apply_environment -## (Karte t_f72913d4): Map-Override > Preset-Key > ProceduralSky; ACES-Tonemap; -## Fog koppelt im Panorama-Fall an den Skybox-Horizont (aerial perspective). -## Kein Glow/Bloom/Volumetric — dokumentierte Absage (Mobile/Perf). -func _build_environment(weather: String, sky_override: String = "") -> void: - var preset: Dictionary = WEATHER_LIGHT.get(weather, WEATHER_LIGHT["mittag"]) - var env := Environment.new() - var sky := Sky.new() - # Katalog-ID (weather_sky) > Preset-Key `sky_panorama` > ProceduralSky. - var pano_id := "" - if sky_override == "prozedural": - pass - elif sky_override != "": - pano_id = sky_override - elif bool(preset.get("sky_panorama", false)): - pano_id = SkyboxKatalog.ID_PACK_WUESTE - var panorama := false - if pano_id != "": - var tex := SkyboxKatalog.panorama_textur(pano_id) - if tex != null: - var pano_mat := PanoramaSkyMaterial.new() - pano_mat.panorama = tex - pano_mat.energy_multiplier = float(preset.get("panorama_energy", 1.0)) - sky.sky_material = pano_mat - panorama = true - else: - push_warning("MAPBUILDER: weather_sky=%s, aber Skybox-Textur fehlt/unbekannt — Fallback ProceduralSky" % pano_id) - if sky.sky_material == null: - var sky_mat := ProceduralSkyMaterial.new() - sky_mat.sky_top_color = preset["sky_top"] - sky_mat.sky_horizon_color = preset["sky_horizon"] - sky_mat.ground_bottom_color = preset["ground_bottom"] - sky_mat.ground_horizon_color = preset["ground_horizon"] - sky_mat.sky_energy_multiplier = float(preset["sky_energy"]) - sky.sky_material = sky_mat - env.background_mode = Environment.BG_SKY - env.sky = sky - # Ambient: "sky" = aus dem Himmel ableiten, "color" = feste Farbe (Client-Logik). - if str(preset.get("ambient_source", "color")) == "sky": - env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY - else: - env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR - env.ambient_light_color = preset["ambient_color"] - env.ambient_light_energy = float(preset["ambient_energy"]) - # Tonemap ACES — derselbe filmische Look wie der Client; Grading bewusst - # NUR über Tonemap + Preset-Farben (kein Fullscreen-Adjustment-Pass). - env.tonemap_mode = Environment.TONE_MAPPER_ACES - env.fog_enabled = bool(preset["fog_enabled"]) - env.fog_light_color = SkyboxKatalog.fog_farbe(sky_override, - preset.get("panorama_fog_color", preset["fog_color"]), - float(preset.get("panorama_energy", 1.0))) if panorama else preset["fog_color"] - env.fog_density = float(preset["fog_density"]) - env.fog_sky_affect = float(preset["fog_sky_affect"]) - var we := WorldEnvironment.new() - we.environment = env - add_child(we) - - var sun := DirectionalLight3D.new() - var deg: Vector2 = preset["sun_deg"] - sun.rotation_degrees = Vector3(deg.x, deg.y, 0.0) - sun.light_energy = float(preset["sun_energy"]) - sun.light_color = preset["sun_color"] - sun.shadow_enabled = true - add_child(sun) - - -## Maßstabsgitter: Linien alle 100 m, gelbe Mittelachsen (X rot? — Z-Achse -## blau wäre Godot-Konvention; hier neutral gelb für gute Sichtbarkeit). -func _build_grid(size_x: float, size_z: float, ground_y: float) -> void: - var mesh := ImmediateMesh.new() - mesh.surface_begin(Mesh.PRIMITIVE_LINES) - var step := _grid_step(size_x) - var half_x := size_x / 2.0 - var half_z := size_z / 2.0 - var y := ground_y + 0.05 - var x := -half_x - while x <= half_x + 0.01: - var major: bool = absf(fmod(x, step * 5.0)) < 0.01 or absf(x) < 0.01 - _add_line(mesh, Vector3(x, y, -half_z), Vector3(x, y, half_z), - AXIS_COLOR if absf(x) < 0.01 else (GRID_COLOR if not major else GRID_COLOR)) - x += step - var z := -half_z - while z <= half_z + 0.01: - _add_line(mesh, Vector3(-half_x, y, z), Vector3(half_x, y, z), - AXIS_COLOR if absf(z) < 0.01 else GRID_COLOR) - z += step - mesh.surface_end() - var mi := MeshInstance3D.new() - mi.mesh = mesh - var mat := StandardMaterial3D.new() - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.vertex_color_use_as_albedo = true - mi.material_override = mat - grid_node = mi - add_child(mi) - - -## Gitter ohne Rebuild zu-/abschalten (Toggle in der Top-Bar, Karte t_7ac70014). -func set_grid_visible(visible_now: bool) -> void: - if grid_node != null and is_instance_valid(grid_node): - grid_node.visible = visible_now - - -func grid_is_visible() -> bool: - return grid_node != null and is_instance_valid(grid_node) and grid_node.visible - - -func _grid_step(size_m: float) -> float: - # Ziel: ~10–20 Linien pro Achse, runde Werte. - var raw := size_m / 16.0 - var candidates := [10.0, 25.0, 50.0, 100.0, 250.0, 500.0] - for c in candidates: - if raw <= float(c): - return float(c) - return 1000.0 - - -func _add_line(mesh: ImmediateMesh, from: Vector3, to: Vector3, color: Color) -> void: - mesh.surface_set_color(color) - mesh.surface_add_vertex(from) - mesh.surface_set_color(color) - mesh.surface_add_vertex(to) - - -## Platzhalter je Objekt: Form aus dem Bibliotheks-Manifest (wie der Server- -## Kollider), Position = Objekt-Fußpunkt. ECHTES GLB-Mesh vorziehen -## (Karte t_9b50b231, GlbMeshStore): vorhanden = echtes Modell mit Texturen, -## fehlend = Platzhalter + Eintrag in fehlende_glbs (Statuszeilen-Hinweis). -## Marker-Root bekommt Metas für Auswahl/Anfassen: obj_index, pick_radius -## (Kugel-Approximation), half_height, glb (true = echtes Modell — keine -## Grundfarbe drüberlegen, sonst sind die Texturen weg). -func _build_objects(objects: Array, manifest: Dictionary) -> void: - var lib: Dictionary = manifest.get("objects", {}) - fehlende_glbs = [] - for i in objects.size(): - var obj = objects[i] - if not (obj is Dictionary): - object_markers.append(null) - continue - var oid := str(obj.get("id", "")) - if not lib.has(oid): - object_markers.append(null) - continue # Validierung fängt das — defensiv überspringen. - var entry: Dictionary = lib[oid] - var col: Dictionary = entry.get("collision", {}) - var scale := float(obj.get("scale", 1.0)) - var mesh := GlbMeshStore.mesh_fuer(oid) - var echt := mesh != null - if not echt: - if GlbMeshStore.fehlt(oid): - fehlende_glbs.append(oid) - mesh = MeshShapes.make_placeholder(str(col.get("shape", "box")), col, scale) - var pos: Array = obj.get("pos", [0.0, 0.0, 0.0]) - var marker := Node3D.new() - marker.position = Vector3(float(pos[0]), float(pos[1]), float(pos[2])) - # Karte t_e166e656: 3-Achsen-Rotation — `rot` (Euler xyz) oder Fallback - # rot_y_deg, identische Regel wie im Client/Server (SvmapIO.objekt_rotation). - marker.rotation_degrees = SvmapIO.objekt_rotation(obj) - marker.set_meta("obj_index", i) - var mi := MeshInstance3D.new() - mi.mesh = mesh - if echt: - # Normalisiertes GLB liegt schon in Fußpunkt-Koordinaten - # (Unterkante y = 0) → KEIN half_height-Lift; Objekt-Maßstab - # über Node-Scale. AABB-Metas mal scale (Node-Scale geht nicht - # in mesh.get_aabb() ein). - mi.scale = Vector3.ONE * scale - else: - mi.position.y = MeshShapes.half_height(mesh) - # U6 (t_639135dd): das Grundmaterial wird NIE MEHR durch die Auswahl - # ersetzt — echte GLB-Objekte tragen ihre Texturen weiter (override null), - # Platzhalter die Editor-Grundfarbe. Markiert wird per Kontur (unten). - mi.material_override = null if echt else _base_mat - marker.add_child(mi) - var half: Vector3 = (mesh.get_aabb().size * (scale if echt else 1.0) * 0.5) as Vector3 - marker.set_meta("pick_radius", half.length() + maxf(0.6, half.y * 0.25)) - marker.set_meta("half_height", - MeshShapes.center_height(mesh) * (scale if echt else 1.0)) - marker.set_meta("glb", echt) - object_markers.append(marker) - add_child(marker) - # Farbe je Objekt (Karte t_b0edb807): optionales Feld "tint" — nur - # Objekte MIT Feld bekommen die Überschreibung (Rückwärtskompatibel). - # Die Farbe bleibt jetzt auch bei Markierung sichtbar (U6: Auswahl = Kontur, - # Grundmaterial bleibt) — kein „Orange gewinnt“ mehr. - if SvmapTint.hat(obj): - SvmapTint.anwenden(marker, SvmapTint.von(obj)) - # Markierung (Auswahl/Hover/Partner) als Kontur-Hülle anlegen. - _outline_anwenden(marker, i) - - -## Auswahl nachträglich umfärben (ohne ganzen Rebuild) — z. B. nach Drag. -## Einzel-Variante bleibt für Rückwärtskompatibilität bestehen. -func set_selected(idx: int) -> void: - selected_index = idx - set_selected_multi([idx] if idx >= 0 else []) - - -## Mehrfachauswahl (Karte t_f6f29d86): ALLE markierten Objekte bekommen die -## Auswahl-Kontur (U6, t_639135dd) — Gruppen/Mehrfachauswahl sind auf einen -## Blick erkennbar, OHNE die Textur zu übermalen. Das Grundmaterial bleibt -## überall sichtbar: echte GLB-Objekte tragen ihre Texturen weiter (Karte -## t_9b50b231), Platzhalter die Editor-Grundfarbe — material_override wird -## von der Markierung nicht mehr angefasst. -func set_selected_multi(indices: Array) -> void: - selected_indices = indices.duplicate() - selected_index = indices.back() if not indices.is_empty() else -1 - # sym-Zwillinge (M3, t_34908425): aus dem doc ableiten — Partner der - # Auswahl, die nicht selbst ausgewählt sind, bekommen die dünnere, - # gestrichelte Partner-Kontur (U6-Abstufung statt dunkler Vollfarbe). - _sym_partners = _sym_partners_of(indices) - var objects: Array = _doc_ref.get("objects", []) - for marker in object_markers: - if marker == null or not is_instance_valid(marker): - continue - var idx := int(marker.get_meta("obj_index", -1)) - _outline_anwenden(marker, idx) - # Tint-Abgleich (Karte t_b0edb807): ALLE Objekte zeigen ihre doc-Farbe - # (oder — nach „Zurücksetzen“ — wieder die Pack-Farbe). Der Tint bleibt - # jetzt auch bei Markierung sichtbar (Auswahl = Kontur um das Modell). - if idx >= 0 and idx < objects.size() and objects[idx] is Dictionary: - var obj: Dictionary = objects[idx] - if SvmapTint.hat(obj): - SvmapTint.anwenden(marker, SvmapTint.von(obj)) - else: - SvmapTint.zuruecknehmen(marker) - - -func _is_partner(idx: int) -> bool: - return _sym_partners.has(idx) - - -## sym-Partner der Auswahl aus dem doc bestimmen (M3, t_34908425): Objekte mit -## sym-Kennung, deren Partner NICHT selbst in der Auswahl ist. Keine sym-Felder -## im doc (alte Karten, Modus Aus) → leer, Verhalten wie bisher. -func _sym_partners_of(indices: Array) -> Array: - var objects: Array = _doc_ref.get("objects", []) - var out: Array = [] - for i in indices: - if not (i is int) or i < 0 or i >= objects.size() or not (objects[i] is Dictionary): - continue - var key := SymmetryCore.sym_of(objects[i] as Dictionary) - if key.is_empty(): - continue - var t := SymmetryCore.find_partner_index(objects, key, i) - if t >= 0 and not indices.has(t) and not out.has(t): - out.append(t) - return out - - -## Tint frisch aus dem doc auf die MARKIERTEN Objekte anwenden (Inspector- -## Änderung ohne Rebuild). U6: die Farbe bleibt auch bei Markierung sichtbar -## (Auswahl = Kontur um das Modell) — kein „Orange gewinnt“-Skip mehr. -func tint_refresh(indices: Array) -> void: - var objects: Array = _doc_ref.get("objects", []) - for i in indices: - if i < 0 or i >= object_markers.size(): - continue - var marker = object_markers[i] - if marker == null or not is_instance_valid(marker): - continue - if i >= objects.size() or not (objects[i] is Dictionary): - continue - var obj: Dictionary = objects[i] - if SvmapTint.hat(obj): - SvmapTint.anwenden(marker, SvmapTint.von(obj)) - else: - SvmapTint.zuruecknehmen(marker) - - -func _is_selected(idx: int) -> bool: - return selected_indices.has(idx) - - -## Spawn-Zonen (Karte t_c4162c5d): JEDE Zone ist ein flacher, teamfarbiger -## Kreis auf dem Boden (Radius = design_notes.spawn_radius_m, Editor-eigen) -## + Label3D mit der Punkt-ID. Marker-Root bekommt Metas für das Spawn-Tool -## (spawn_team, spawn_id, spawn_radius → Anfassen/Regel). -func _rebuild_spawn_markers(data: Dictionary) -> void: - for marker in spawn_markers: - if marker != null and is_instance_valid(marker): - marker.queue_free() - spawn_markers = [] - var zones = SpawnOps.zones_of(data) # bearbeiteter Spawn-Satz (Basis oder Modus) - if not (zones is Dictionary): - return - for team_key in zones.keys(): - if not (zones[team_key] is Dictionary): - continue - var team := 0 if str(team_key) == "all" else int(team_key) - var zone: Dictionary = zones[team_key] - var points = zone.get("points", []) - if not (points is Array): - continue - for p in points: - if not (p is Dictionary): - continue - var pid: String = str(p.get("id", "?")) - var pos: Array = p.get("pos", [0.0, 0.0, 0.0]) - var marker := _spawn_marker( - Vector3(float(pos[0]), float(pos[1]), float(pos[2])), - team, pid, SpawnOps.zone_radius(data, pid)) - var yaw_col: Color = TEAM_COLORS[team] if team < TEAM_COLORS.size() else Color.WHITE - marker.set_meta("yaw_color", yaw_col) - marker.add_child(_yaw_arrow(SpawnOps.zone_radius(data, pid), - SpawnOps.effective_yaw(data, p), SpawnOps.has_yaw(p), yaw_col)) - spawn_markers.append(marker) - add_child(marker) - - -## Zonen des Spielmodus: Conquest = gelb, King of the Hill = orange (mit Nummer der -## Wanderreihenfolge). Boden-Kreis + durchscheinender Zylinder + Name. -func rebuild_zone_markers(data: Dictionary) -> void: - if zone_root != null and is_instance_valid(zone_root): - zone_root.queue_free() - zone_root = null - var mode := ModusKatalog.mode_of(data) - if not ModusKatalog.has_zones(mode): - return - zone_root = Node3D.new() - zone_root.name = "Zonen" - add_child(zone_root) - var col := Color(1.0, 0.8, 0.2) if mode == ModusKatalog.MODE_CONQUEST else Color(1.0, 0.45, 0.15) - var zlist := ModusKatalog.zones(data, mode) - for zi in zlist.size(): - var cp = zlist[zi] - if not (cp is Dictionary): - continue - var pos: Array = cp.get("pos", [0, 0, 0]) - var r := float(cp.get("radius_m", ModusKatalog.DEFAULT_RADIUS)) - var node := Node3D.new() - node.name = "CP_%s" % str(cp.get("id", "")) - node.position = Vector3(float(pos[0]), float(pos[1]), float(pos[2])) - var mat := StandardMaterial3D.new() - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - mat.cull_mode = BaseMaterial3D.CULL_DISABLED - mat.albedo_color = Color(col.r, col.g, col.b, 0.18) - var cyl := MeshInstance3D.new() - var cm := CylinderMesh.new() - cm.top_radius = r - cm.bottom_radius = r - cm.height = 8.0 - cm.cap_top = false - cm.cap_bottom = false - cyl.mesh = cm - cyl.material_override = mat - cyl.position.y = 4.0 - node.add_child(cyl) - var ring := MeshInstance3D.new() - var tm := TorusMesh.new() - tm.inner_radius = r - 0.2 - tm.outer_radius = r + 0.2 - tm.rings = 48 - tm.ring_segments = 6 - ring.mesh = tm - var rmat := StandardMaterial3D.new() - rmat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - rmat.albedo_color = col - ring.material_override = rmat - ring.position.y = 0.15 - node.add_child(ring) - var label := Label3D.new() - label.text = ("⚑ %s" if mode == ModusKatalog.MODE_CONQUEST else "♛ %d · %%s" % (zi + 1)) % str(cp.get("label", cp.get("id", ""))) - label.position.y = 10.0 - label.billboard = BaseMaterial3D.BILLBOARD_ENABLED - label.modulate = col - label.outline_size = 12 - label.font_size = 160 - label.pixel_size = 0.01 - node.add_child(label) - if mode == ModusKatalog.MODE_CONQUEST: # Hills sind keine Spawns - node.set_meta("zone_id", str(cp.get("id", ""))) - node.set_meta("yaw_radius", r) - node.add_child(_yaw_arrow(r, SpawnOps.effective_yaw(data, cp), SpawnOps.has_yaw(cp), col)) - zone_root.add_child(node) - - -## Ein Spawn-Marker bauen (flacher Kreis + Label). radius = angezeigter Zonen-Radius. -func _spawn_marker(pos: Vector3, team: int, pid: String, radius: float) -> Node3D: - var marker := Node3D.new() - marker.position = pos - marker.set_meta("spawn_team", team) - marker.set_meta("spawn_id", pid) - marker.set_meta("spawn_radius", radius) - marker.set_meta("spawn_pick_radius", maxf(radius + 2.0, 4.0)) - marker.set_meta("spawn_selected", false) - marker.add_child(_spawn_disc(radius, team)) - var label := Label3D.new() - label.text = pid - label.position.y = 2.5 - label.billboard = BaseMaterial3D.BILLBOARD_ENABLED - label.modulate = TEAM_COLORS[team] if team < TEAM_COLORS.size() else Color.WHITE - label.outline_size = 12 - label.font_size = 160 - label.pixel_size = 0.01 - marker.add_child(label) - return marker - - -## Pfeil der Blickrichtung: flach am Boden, zeigt lokal nach -Z, rotation.y = Blickrichtung. -## Gesetzte Richtung kräftig, Standard (zur Kartenmitte) blass grau. Ohne Tiefentest, damit -## Hügel und Objekte ihn nicht verdecken. -func _yaw_arrow(radius: float, yaw_deg: float, is_set: bool, col: Color) -> MeshInstance3D: - var length := yaw_arrow_length(radius) - var half_w := maxf(0.25, length * 0.04) - var head_w := half_w * 3.0 - var head_l := minf(length * 0.4, head_w * 2.5) - var neck := -(length - head_l) - var verts := PackedVector3Array([ - Vector3(-half_w, 0, 0), Vector3(half_w, 0, 0), Vector3(half_w, 0, neck), - Vector3(-half_w, 0, 0), Vector3(half_w, 0, neck), Vector3(-half_w, 0, neck), - Vector3(-head_w, 0, neck), Vector3(head_w, 0, neck), Vector3(0, 0, -length), - ]) - var arrays := [] - arrays.resize(Mesh.ARRAY_MAX) - arrays[Mesh.ARRAY_VERTEX] = verts - var mesh := ArrayMesh.new() - mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) - var mat := StandardMaterial3D.new() - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mat.cull_mode = BaseMaterial3D.CULL_DISABLED - mat.no_depth_test = true - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - mat.albedo_color = col.lightened(0.35) if is_set else Color(0.75, 0.75, 0.75, 0.55) - var arrow := MeshInstance3D.new() - arrow.name = "YawArrow" - arrow.mesh = mesh - arrow.material_override = mat - arrow.position.y = 0.4 - arrow.rotation.y = deg_to_rad(yaw_deg) - arrow.set_meta("yaw_deg", yaw_deg) - arrow.set_meta("yaw_set", is_set) - arrow.set_meta("yaw_length", length) - return arrow - - -static func yaw_arrow_length(radius: float) -> float: - return maxf(radius, 3.0) + 2.0 - - -func yaw_arrow_of(node: Node3D) -> MeshInstance3D: - return node.get_node_or_null("YawArrow") as MeshInstance3D - - -## Alle Pfeile zum Anfassen: [{kind:"spawn"|"zone", team, id, node, tip:Vector3}]. -func yaw_handles() -> Array: - var out: Array = [] - var add := func(node: Node3D, entry: Dictionary) -> void: - var arrow := yaw_arrow_of(node) - if arrow == null: - return - var yaw := deg_to_rad(float(arrow.get_meta("yaw_deg", 0.0))) - var length := float(arrow.get_meta("yaw_length", 0.0)) - entry["node"] = node - entry["tip"] = node.global_position + Vector3(-sin(yaw), 0.0, -cos(yaw)) * length - out.append(entry) - for marker in spawn_markers: - if marker != null and is_instance_valid(marker): - add.call(marker, {"kind": "spawn", "team": int(marker.get_meta("spawn_team", -1)), "id": str(marker.get_meta("spawn_id", ""))}) - if zone_root != null and is_instance_valid(zone_root): - for node in zone_root.get_children(): - if node.has_meta("zone_id"): - add.call(node, {"kind": "zone", "team": -1, "id": str(node.get_meta("zone_id"))}) - return out - - -## Kreisfläche EINES Markers (neu) bauen — Werkzeuge rufen nach Radius-Änderung -## style_spawn_marker auf. U6 (t_639135dd): die Fläche bleibt IMMER gleich -## dezent (Teamfarbe, halbtransparent) — die Auswahl zeigt sich als schmaler -## Kontur-Ring am Zonenrand (Theme-Farbe), nicht als aufgehellte Vollfläche. -func _spawn_disc(radius: float, team: int, _selected := false) -> MeshInstance3D: - var mi := MeshInstance3D.new() - var cyl := CylinderMesh.new() - cyl.top_radius = radius - cyl.bottom_radius = radius - cyl.height = 0.25 - mi.mesh = cyl - mi.position.y = 0.12 - var col: Color = TEAM_COLORS[team] if team >= 0 and team < TEAM_COLORS.size() else Color.WHITE - var mat := StandardMaterial3D.new() - mat.albedo_color = Color(col.r, col.g, col.b, 0.55) - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mi.material_override = mat - return mi - - -## Dezenter Auswahl-Ring EINES Spawn-Markers (U6): dünner Torus am Zonenrand, -## Farbe aus dem Theme. Muss NUR bei Auswahl existieren (restlos weg bei -## Abwahl) — style_spawn_marker legt ihn an/entfernt ihn. -func _spawn_ring(radius: float) -> MeshInstance3D: - var mi := MeshInstance3D.new() - var torus := TorusMesh.new() - var t := maxf(0.15, radius * 0.06) - torus.inner_radius = maxf(0.01, radius - t) - torus.outer_radius = radius + t - mi.mesh = torus - mi.position.y = 0.26 - var mat := StandardMaterial3D.new() - mat.albedo_color = _markierung_farbe("selection_outline") - mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA - mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - mi.material_override = mat - return mi - - -## Radius/Anfass-Optik eines Spawn-Markers aktualisieren OHNE Gesamtrebuild -## (Radius-Regel gedreht, Zone ausgewählt/abgewählt). -func style_spawn_marker(marker: Node3D, radius: float, selected: bool) -> void: - if marker == null or not is_instance_valid(marker): - return - var team := int(marker.get_meta("spawn_team", -1)) - var pid := str(marker.get_meta("spawn_id", "")) - marker.set_meta("spawn_radius", radius) - marker.set_meta("spawn_pick_radius", maxf(radius + 2.0, 4.0)) - marker.set_meta("spawn_selected", selected) - if marker.get_child_count() > 0 and marker.get_child(0) is MeshInstance3D: - (marker.get_child(0) as MeshInstance3D).queue_free() - var disc := _spawn_disc(radius, team, selected) - marker.add_child(disc) - marker.move_child(disc, 0) - # Auswahl-Kontur: alter Ring weg, bei Auswahl neuer (restloser Wechsel). - var alter_ring: Node = null - if marker.has_meta("spawn_ring"): - alter_ring = marker.get_meta("spawn_ring") - if alter_ring != null and is_instance_valid(alter_ring): - alter_ring.queue_free() - marker.remove_meta("spawn_ring") - if selected: - var ring := _spawn_ring(radius) - marker.add_child(ring) - marker.set_meta("spawn_ring", ring) - var arrow := yaw_arrow_of(marker) - if arrow != null: # Länge folgt dem Radius - var yaw_deg := float(arrow.get_meta("yaw_deg", 0.0)) - var yaw_set := bool(arrow.get_meta("yaw_set", false)) - arrow.name = "YawArrowAlt" - arrow.queue_free() - marker.add_child(_yaw_arrow(radius, yaw_deg, yaw_set, marker.get_meta("yaw_color", Color.WHITE))) - - -## Auswahl-Highlight über ALLE Spawn-Marker (Werkzeug ruft bei Änderung). -func set_spawn_selected(team: int, pid: String) -> void: - for marker in spawn_markers: - if marker == null or not is_instance_valid(marker): - continue - var is_sel := int(marker.get_meta("spawn_team", -1)) == team \ - and str(marker.get_meta("spawn_id", "")) == pid - if bool(marker.get_meta("spawn_selected", false)) == is_sel: - continue - style_spawn_marker(marker, float(marker.get_meta("spawn_radius", 6.0)), is_sel) - # Label sofort umfärben (auch ohne Disc-Neubau sichtbar) — Farbe aus - # dem Theme statt hartkodiertem Gelb (U6). - var col: Color = TEAM_COLORS[clampi(team, 0, 1)] if team >= 0 else Color.WHITE - if marker.get_child_count() > 1 and marker.get_child(1) is Label3D: - var label := marker.get_child(1) as Label3D - label.modulate = _markierung_farbe("selection_outline") if is_sel else col - - -# ------------------------------------------------------ U6-Markierung ------- -# (Karte t_639135dd — dezente Auswahl: Kontur statt Vollorange. Eine Quelle -# für Farben/Breiten ist das Theme; der Shader ist die Außenhüllen-Technik.) - -## Theme-Farben + -Breiten in die drei Kontur-Materialien überführen -## (Auswahl / Hover / Partner). Fehlende Einträge → Fallback-Farbe. -func _markierung_theme_laden() -> void: - _outline_mat_sel = _outline_material( - _markierung_farbe("selection_outline"), - _markierung_breite("selection_outline_width_mm"), 0.0) - _outline_mat_hover = _outline_material( - _markierung_farbe("selection_outline_hover"), - _markierung_breite("selection_outline_width_hover_mm"), 0.0) - _outline_mat_partner = _outline_material( - _markierung_farbe("selection_outline_partner"), - _markierung_breite("selection_outline_width_partner_mm"), 3.5) - - -## Eine Markierungs-Farbe aus dem Theme lesen (fehlt sie → Fallback). -func _markierung_farbe(name: String) -> Color: - var theme_res: Variant = load(THEME_PATH) - if theme_res is Theme: - var th := theme_res as Theme - if th.has_color(name, "Editor"): - return th.get_color(name, "Editor") - return OUTLINE_FALLBACK - - -## Eine Markierungs-Breite aus dem Theme lesen (Theme speichert Millimeter -## als Ganzzahl — Theme kennt keine Gleitkommakonstanten). -func _markierung_breite(name: String) -> float: - var theme_res: Variant = load(THEME_PATH) - if theme_res is Theme: - var th := theme_res as Theme - if th.has_constant(name, "Editor"): - return float(th.get_constant(name, "Editor")) / 1000.0 - return 0.06 - - -## Kontur-Material für einen Zustand bauen (streifen > 0 = gestrichelt). -func _outline_material(farbe: Color, breite: float, streifen: float) -> ShaderMaterial: - var mat := ShaderMaterial.new() - var shader: Variant = load(OUTLINE_SHADER) - if shader is Shader: - mat.shader = shader - mat.set_shader_parameter("linien_farbe", farbe) - mat.set_shader_parameter("breite_m", breite) - mat.set_shader_parameter("streifen_hz", streifen) - return mat - - -## Zustand eines Objekts (U6-Abstufung): Auswahl > Partner > Hover > nichts. -func _markierung_zustand(idx: int) -> String: - if _is_selected(idx): - return "sel" - if _is_partner(idx): - return "partner" - if idx >= 0 and idx == hover_index: - return "hover" - return "" - - -## Kontur-Hülle eines Objekt-Markers anlegen/umschalten/restlos entfernen. -## Die Hülle hängt als Kind UNTER dem Mesh (erbt Position + Scale — GLB- -## Skalierung bleibt korrekt) und trägt das Mesh ein zweites Mal mit dem -## Außenhüllen-Material (visuell = zweite Render-Passage um das Modell, -## das Grundmaterial mit seiner Textur bleibt unangetastet). -func _outline_anwenden(marker: Node3D, idx: int) -> void: - if marker == null or not is_instance_valid(marker): - return - var zustand := _markierung_zustand(idx) - var alt: Node = null - if marker.has_meta("outline"): - alt = marker.get_meta("outline") - if zustand.is_empty(): - if alt != null and is_instance_valid(alt): - alt.queue_free() - if marker.has_meta("outline"): - marker.remove_meta("outline") - return - var mat: ShaderMaterial = _outline_mat_sel - if zustand == "hover": - mat = _outline_mat_hover - elif zustand == "partner": - mat = _outline_mat_partner - if alt != null and is_instance_valid(alt): - (alt as MeshInstance3D).material_override = mat - return - var mi := marker.get_child(0) as MeshInstance3D - if mi == null or mi.mesh == null: - return - var huelle := MeshInstance3D.new() - huelle.name = "SelectionOutline" - huelle.mesh = mi.mesh - huelle.material_override = mat - mi.add_child(huelle) - marker.set_meta("outline", huelle) - - -## Hover-Markierung (U6-Abstufung, schwächste Kontur). idx = obj_index oder -## -1 für „kein Hover“. Der Aufrufer ist das Objekt-Werkzeug — der Anschluss -## an die Mausbewegung liegt in interaction.gd (Grenze dieser Karte) und -## kommt als Folge-Karte; die Abstufung selbst ist hier voll wirksam. -func set_hover(idx: int) -> void: - if hover_index == idx: - return - hover_index = idx - for marker in object_markers: - if marker == null or not is_instance_valid(marker): - continue - _outline_anwenden(marker, int(marker.get_meta("obj_index", -1))) \ No newline at end of file diff --git a/src/viewport/map_view_builder.gd.uid b/src/viewport/map_view_builder.gd.uid deleted file mode 100644 index 1761658..0000000 --- a/src/viewport/map_view_builder.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cot16hrvgdx4a diff --git a/src/viewport/mesh_shapes.gd b/src/viewport/mesh_shapes.gd deleted file mode 100644 index e51ba1a..0000000 --- a/src/viewport/mesh_shapes.gd +++ /dev/null @@ -1,88 +0,0 @@ -extends RefCounted -class_name MeshShapes -## Platzhalter-Meshes für Bibliotheks-Objekte (Form aus dem Kollider-Eintrag, -## wie der Server-Sichtbarkeit) — geteilt von Viewport-Bauer und Ghost-Preview, -## damit Objekte im Editor überall identisch aussehen. - -const SHAPE_BOX := "box" -const SHAPE_SPHERE := "sphere" -const SHAPE_CYLINDER := "cylinder" -const SHAPE_COMPOUND := "compound" -const SHAPE_NONE := "none" - - -static func make_placeholder(shape: String, col: Dictionary, scale: float) -> Mesh: - match shape: - SHAPE_NONE: - # Rein dekorativ (Natur-Update, t_7cf80244): kein Kollider — aber - # im Editor trotzdem sichtbar/wählbar: flache Fußpunkt-Scheibe. - var d := CylinderMesh.new() - d.top_radius = 0.4 * scale - d.bottom_radius = d.top_radius - d.height = maxf(0.02, 0.02 * scale) - return d - SHAPE_SPHERE: - var s := SphereMesh.new() - var r := maxf(0.01, float(col.get("radius", 1.0)) * scale) - s.radius = r - s.height = r * 2.0 - return s - SHAPE_CYLINDER: - var c := CylinderMesh.new() - c.top_radius = maxf(0.01, float(col.get("radius", 1.0)) * scale) - c.bottom_radius = c.top_radius - c.height = maxf(0.01, float(col.get("height", 1.0)) * scale) - return c - SHAPE_COMPOUND: - # Struktur-Objekte (t_d8be9ed7): EIN Mesh aus allen Verbund-Teilen, - # gebacken in Fußpunkt-Koordinaten (Teil-pos = Versatz vom Fußpunkt, - # rot_deg = Euler-Grad) — Rampe/Durchgänge also sichtbar wie die - # echte Kollision. half_height() liefert dafür 0 (schon gebacken). - var st := SurfaceTool.new() - st.begin(Mesh.PRIMITIVE_TRIANGLES) - st.set_smooth_group(-1) - for teil_v in col.get("parts", []): - var teil: Dictionary = teil_v if teil_v is Dictionary else {} - var teil_mesh := make_placeholder(str(teil.get("shape", "box")), teil, scale) - if teil_mesh == null: - continue - var off: Array = teil.get("pos", [0.0, 0.0, 0.0]) - var rot: Array = teil.get("rot_deg", [0.0, 0.0, 0.0]) - var xf := Transform3D( - Basis.from_euler(Vector3(deg_to_rad(float(rot[0])), deg_to_rad(float(rot[1])), deg_to_rad(float(rot[2])))), - Vector3(float(off[0]), float(off[1]), float(off[2])) * scale) - # PrimitiveMesh → Roht_arrays (MeshDataTool bräuchte ArrayMesh). - var arrays: Array = teil_mesh.surface_get_arrays(0) - var verts: PackedVector3Array = arrays[Mesh.ARRAY_VERTEX] - var norms: PackedVector3Array = arrays[Mesh.ARRAY_NORMAL] - var idx: PackedInt32Array = arrays[Mesh.ARRAY_INDEX] - for ii in idx: - st.set_normal(xf.basis * norms[ii]) - st.add_vertex(xf * verts[ii]) - return st.commit() - _: - var b := BoxMesh.new() - var size: Array = col.get("size", [1.0, 1.0, 1.0]) - b.size = Vector3(maxf(0.01, float(size[0])), maxf(0.01, float(size[1])), - maxf(0.01, float(size[2]))) * scale - return b - - -## Halbe Höhe des Meshes über dem Fußpunkt (Mesh-Ursprung = Objekt-Fuß). -## Compound-ArrayMeshes sind bereits in Fußpunkt-Koordinaten gebacken → 0. -static func half_height(mesh: Mesh) -> float: - if mesh is BoxMesh: - return (mesh as BoxMesh).size.y * 0.5 - if mesh is CylinderMesh: - return (mesh as CylinderMesh).height * 0.5 - if mesh is SphereMesh: - return (mesh as SphereMesh).radius - return 0.0 - - -## Höhe des Mesh-MITTELPUNKTS über dem Fußpunkt — für das Drehzentrum der -## Objekt-Auswahl. Bei Grundformen = half_height (Mesh ist zentriert); beim -## Compound-ArrayMesh = AABB-Mitte (schon in Fußpunkt-Koordinaten gebacken). -static func center_height(mesh: Mesh) -> float: - var aabb := mesh.get_aabb() - return half_height(mesh) + aabb.position.y + aabb.size.y * 0.5 \ No newline at end of file diff --git a/src/viewport/mesh_shapes.gd.uid b/src/viewport/mesh_shapes.gd.uid deleted file mode 100644 index d7c65ea..0000000 --- a/src/viewport/mesh_shapes.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cs588kkixa7rg diff --git a/src/viewport/orbit_camera.gd b/src/viewport/orbit_camera.gd deleted file mode 100644 index 1e2ba37..0000000 --- a/src/viewport/orbit_camera.gd +++ /dev/null @@ -1,454 +0,0 @@ -extends Camera3D -## Orbit-Kamera + Freelook-Flug für den Editor-Viewport. -## Steuerung: -## Mittlere Maustaste ziehen = Drehen (Orbit) -## Mittlere Maustaste + Shift = Verschieben (Pan, parallel zum Boden) -## Mausrad = Zoom — AUSSER ein Objekt/eine Platzier-Vorschau -## ist aktiv: dann dreht das Mausrad das Objekt -## (interaction.gd meldet das per wheel_filter). -## Rechte Maustaste GEDACHT halten = Freelook-Flug (Karte t_c46d31c2): Umsehen + -## W vor / S zurück / A links / D rechts, -## Leertaste hoch / Shift runter (Shooter- -## Konvention, Sly-Wunsch 17.10.), -## Strg = schneller, Alt = langsamer. -## Mausrad ändert im Flug die -## GRUNDgeschwindigkeit dauerhaft. -## Umschalt+F (main.gd) = Freelook dauerhaft an/aus (Flug bleibt auch -## ohne gedrückte rechte Maustaste aktiv). -## F (main.gd) = Auswahl ins Bild zentrieren → focus_on(). -## Orbit bleibt der Default-Zustand: Beim Verlassen des Flugs werden Orbit- -## Ziel/Winkel/Abstand aus der Flugposition/Blickrichtung zurückgerechnet. -## Die Mathe lebt in src/editor/fly_math.gd (pure, headless testbar). -## Ziel-Punkt, Winkel und Abstand bleiben intern; Position wird jede Frame -## aus ihnen berechnet (Orbit) bzw. im Flug direkt bewegt. -## Karte K1 (t_950fddaa): Beim Dreh-Start liegt der Drehpunkt UNTER DEM -## MAUSZEIGER (Unity/Blender-Verhalten) — Objekt/Bauteil-Treffer zuerst, sonst -## Terrain, sonst alter Ziel-Punkt. Kameraposition und Blickrichtung bleiben -## exakt unverändert (kein Sprung), nur Ziel/Winkel/Abstand werden neu -## gerechnet. fit_to_bounds() ersetzt frame_map(): ganze Map ins Bild. - -const FlyMath := preload("res://src/editor/fly_math.gd") -const TerrainField := preload("res://core/svmap/terrain_field.gd") -const SvmapIO := preload("res://core/svmap/svmap_io.gd") - -const ORBIT_DEG_PER_PX := 0.3 # Karte K1: Drehgeschwindigkeit gekapselt — kein Nachlaufen -const DISTANCE_MIN := 5.0 -const FIT_FLOOR_MIN := 30.0 # fit_to_bounds: nie näher als 30 m an die Map ran -## Karte K1d (t_6c1027c1): Startabstand nach Laden/Neu — Slys Wahl („Nah dran: -## startet ~80 m über der Kartenmitte, Objekte sind sofort groß und greifbar"). -const START_DISTANCE_M := 80.0 -const START_YAW_DEG := 45.0 -const START_PITCH_DEG := 35.0 - -var target := Vector3.ZERO -var yaw_deg := 45.0 -var pitch_deg := 35.0 -var distance := 300.0 - -## Von main.gd gesetzt: Callable → true, wenn das Mausrad gerade ein Objekt -## drehen soll (Platzier-Modus oder Auswahl) statt zu zoomen. -var wheel_filter := Callable() -## Von main.gd gesetzt: Callable für Klartext-Status-Meldungen. -var status_cb := Callable() - -## Grundgeschwindigkeit des Flugs (Mausrad ändert sie dauerhaft, Karte 1/3). -var base_speed_mps := FlyMath.BASE_SPEED_MPS - -var _dragging := false -var _panning := false -var _fly_held := false # Rechte Maustaste gehalten → Flug temporär aktiv -var _fly_locked := false # Umschalt+F: Flug dauerhaft (auch ohne RMT) -var _flying := false # Ergebnis-Flag: gerade im Flugmodus? -var _fly_yaw := 0.0 -var _fly_pitch := 0.0 -var _fit_bounds_mn := Vector3.ZERO # zuletzt gesetzte Map-Bounds (fit_to_bounds) -var _fit_bounds_mx := Vector3.ZERO -var _fit_bounds_valid := false - - -func _ready() -> void: - _apply() - - -func _process(delta: float) -> void: - if not _flying or not InputMap.has_action("editor_fly_forward"): - return - var f := Input.get_action_strength("editor_fly_forward") - Input.get_action_strength("editor_fly_back") - var s := Input.get_action_strength("editor_fly_right") - Input.get_action_strength("editor_fly_left") - var v := Input.get_action_strength("editor_fly_up") - Input.get_action_strength("editor_fly_down") - if f == 0.0 and s == 0.0 and v == 0.0: - return - var speed := FlyMath.speed_for(base_speed_mps, - Input.is_action_pressed("editor_fly_fast"), - Input.is_action_pressed("editor_fly_slow")) - var forward := FlyMath.forward_from_euler(_fly_yaw, _fly_pitch) - var right := FlyMath.forward_from_euler(_fly_yaw, 0.0).cross(Vector3.UP).normalized() - position += FlyMath.move_delta(forward, right, f, s, v, speed, delta) - _apply_fly_orientation() - - -func _unhandled_input(event: InputEvent) -> void: - if event is InputEventKey: - # Karte K1: Pos1/Home = ganze Karte ins Bild (fit_to_bounds). - _handle_home_key(event as InputEventKey) - if event is InputEventMouseButton: - var mb := event as InputEventMouseButton - if mb.button_index == MOUSE_BUTTON_RIGHT: - # Karte t_2470de89: RMB = Flug mit ABSOLUTEM Vorrang — kein Filter, - # keine Heuristik. Werkzeuge behandeln RMB nicht mehr, also startet - # der Flug in JEDEM Werkzeugzustand (auch Terrain/Platzieren/Bauen). - if mb.pressed: - _enter_fly() - _fly_held = true - elif _fly_held: - _fly_held = false - if not _fly_locked: - _exit_fly() - elif mb.button_index == MOUSE_BUTTON_MIDDLE: - if _flying: - return # Im Flug: MMT-Ziehen bleibt unangetastet (kein Orbit-Sprung) - if mb.pressed: - # Karte K1: Drehpunkt unter den Mauszeiger legen — VOR dem - # ersten Ziehen, damit kein Sprung passiert. - _pivot_to_cursor(mb.position) - _dragging = mb.pressed and not mb.shift_pressed - _panning = mb.pressed and mb.shift_pressed - elif mb.button_index == MOUSE_BUTTON_WHEEL_UP and mb.pressed: - if _flying: - base_speed_mps = FlyMath.wheel_speed(base_speed_mps, true) - _status("Flug-Tempo: %.0f m/s (Grundgeschwindigkeit, bleibt dauerhaft)." % base_speed_mps) - return - if _wheel_blocked(): - return - distance = maxf(DISTANCE_MIN, distance * 0.9) - _apply() - elif mb.button_index == MOUSE_BUTTON_WHEEL_DOWN and mb.pressed: - if _flying: - base_speed_mps = FlyMath.wheel_speed(base_speed_mps, false) - _status("Flug-Tempo: %.0f m/s (Grundgeschwindigkeit, bleibt dauerhaft)." % base_speed_mps) - return - if _wheel_blocked(): - return - distance = minf(distance * 1.1, distance_max()) - _apply() - elif event is InputEventMouseMotion: - var mm := event as InputEventMouseMotion - if _flying: - if _fly_held: - # Umsehen: volle 360° Yaw, Pitch −85…+85 (auch von unten hoch). - _fly_yaw = wrapf(_fly_yaw - mm.relative.x * 0.25, -180.0, 180.0) - _fly_pitch = clampf(_fly_pitch + mm.relative.y * 0.25, - -FlyMath.PITCH_MAX_DEG, FlyMath.PITCH_MAX_DEG) - _apply_fly_orientation() - return - if _dragging: - yaw_deg = wrapf(yaw_deg - mm.relative.x * ORBIT_DEG_PER_PX, -180.0, 180.0) - pitch_deg = clampf(pitch_deg + mm.relative.y * ORBIT_DEG_PER_PX, 5.0, 85.0) - _apply() - elif _panning: - var right := transform.basis.x - var fwd := -transform.basis.z - fwd.y = 0.0 - fwd = fwd.normalized() - var scale := distance * 0.0015 - target -= right * mm.relative.x * scale - target += fwd * mm.relative.y * scale - _apply() - - -func _wheel_blocked() -> bool: - return wheel_filter.is_valid() and bool(wheel_filter.call()) - - -func distance_max() -> float: - return 6000.0 - - -## Freelook dauerhaft an/aus (Umschalt+F, main.gd ruft an). -func toggle_fly_lock() -> void: - if _flying: - _fly_locked = false - if not _fly_held: - _exit_fly() - _status("Freelook-Flug aus — zurück zum Orbit (Mittlere Maustaste ziehen = drehen).") - else: - _fly_locked = true - _enter_fly() - _status("Freelook-Flug DAUERHAFT an: W/S/A/D fliegen, Leertaste hoch / Shift runter, Strg schneller, Alt langsamer — Umschalt+F zurück zum Orbit.") - - -## Im Flugmodus? (interaction.gd blockt z. B. Mausrad-Objektdrehung dann ab.) -func fly_active() -> bool: - return _flying - - -## Aktueller Gierwinkel der BLICKRICHTUNG (Karte t_55257792): im Flug der -## Flug-Yaw, im Orbit der Orbit-Yaw. Für die Pfeiltasten-Richtung (MoveMath -## rastet sie auf die nächste Weltachse). -func view_yaw_deg() -> float: - return _fly_yaw if _flying else yaw_deg - - -## Auswahl ins Bild zentrieren (F): Orbit → Ziel-Punkt auf den Auswahl-Mittelpunkt; -## Flug → Blickrichtung drehen, Position bleibt. -func focus_on(center: Vector3) -> void: - if _flying: - var to := center - position - if to.length_squared() < 0.01: - return - var ep := FlyMath.euler_from_forward(to.normalized()) - _fly_yaw = ep.x - _fly_pitch = clampf(ep.y, -FlyMath.PITCH_MAX_DEG, FlyMath.PITCH_MAX_DEG) - _apply_fly_orientation() - else: - target = center - _apply() - - -func _enter_fly() -> void: - if _flying: - return - _fly_yaw = yaw_deg - _fly_pitch = pitch_deg - _flying = true - # Konflikt-Check (Sly-Wunsch 17.10.): Leertaste ist jetzt „hoch fliegen" — - # ein fokussierter Button würde Space/Enter als Klick interpretieren - # (Bibliothek-Button = Platzierung starten). Im Flug gehört die Leertaste - # der Kamera, also GUI-Fokus freigeben. - var vp := get_viewport() - if vp != null and vp.gui_get_focus_owner() != null: - vp.gui_release_focus() - _status("Freelook-Flug an: W/S/A/D fliegen, Leertaste hoch / Shift runter, Strg = schnell, Alt = langsam, Mausrad = Grund-Tempo. Rechte Maustaste loslassen = zurück zum Orbit.") - - -func _exit_fly() -> void: - if not _flying: - return - _flying = false - # Orbit-Zustand aus Flugposition/Blickrichtung zurückrechnen — kein Sprung. - var fwd := -transform.basis.z - if fwd.length_squared() < 0.0000001: - fwd = FlyMath.forward_from_euler(yaw_deg, pitch_deg) - var ep := FlyMath.euler_from_forward(fwd) - yaw_deg = ep.x - pitch_deg = clampf(ep.y, 5.0, 85.0) - distance = clampf(distance, 30.0, distance_max()) - target = position + fwd.normalized() * distance - _apply() - - -func _apply_fly_orientation() -> void: - var fwd := FlyMath.forward_from_euler(_fly_yaw, _fly_pitch) - look_at_from_position(position, position + fwd, Vector3.UP) - - -## Karte K1 (t_950fddaa): Drehpunkt unter den Mauszeiger — aus der unver- -## änderten Kameraposition werden Ziel/Winkel/Abstand neu gerechnet. -func set_pivot(hit: Vector3) -> void: - var pos := position - var fwd := -transform.basis.z - if fwd.length_squared() < 0.0000001: - fwd = FlyMath.forward_from_euler(yaw_deg, pitch_deg) - var ep := FlyMath.euler_from_forward(fwd.normalized()) - target = hit - distance = pos.distance_to(hit) - yaw_deg = ep.x - pitch_deg = ep.y - # Bewusst KEIN _apply(): Position und Basis bleiben exakt wie vorher — - # kein Sprung. Der nächste Dreh-/Zoom-Schritt rechnet aus dem neuen - # Zustand dieselbe Position zurück (Offset-Konvention konsistent). - - -## MMT-Druck: Punkt unter dem Cursor bestimmen — Objekt/Bauteil zuerst, sonst -## Terrain/Boden, sonst aktuellen Ziel-Punkt behalten (kein Sprung). -func _pivot_to_cursor(viewport_pos: Vector2) -> void: - var inter := _find_sibling("_pick_object") - if inter != null: - var idx := int(inter.call("_pick_object", viewport_pos)) - if idx >= 0: - var pt: Variant = _object_pivot_point(idx) - if pt != null: - set_pivot(pt) - return - var g: Variant = inter.call("_ground_point", viewport_pos) - if g != null: - set_pivot(g) - return - # Kein Treffer: Ziel-Punkt unverändert lassen — Ansicht darf nicht springen. - - -## Mittelpunkt des Objekt-Markers (Fußpunkt + halbe Höhe — gleiche Konvention -## wie interaction.gd beim F-Tasten-Zentrieren). -func _object_pivot_point(idx: int) -> Variant: - var builder := _find_builder() - if builder == null: - return null - var markers: Array = builder.get("object_markers") - if markers == null or idx < 0 or idx >= (markers as Array).size(): - return null - var marker = (markers as Array)[idx] - if marker == null or not is_instance_valid(marker): - return null - var half_h := float(marker.get_meta("half_height", 0.0)) - return (marker as Node3D).global_position + Vector3.UP * half_h - - -func _find_sibling(has_method_name: String) -> Node: - var p := get_parent() - if p == null: - return null - for child in p.get_children(): - var c := child as Node - if c != self and c.has_method(has_method_name): - return c - return null - - -func _find_builder() -> Node: - var p := get_parent() - if p == null: - return null - for child in p.get_children(): - var c := child as Node - if c != self and c.get("object_markers") != null: - return c - return null - - -## Fit: target = Mitte der bounds; Abstand so, dass die GANZE Map im Frustum -## liegt; Pos1 ruft das mit den zuletzt gesetzten Bounds erneut auf. Ersetzt -## das tote frame_map(). -func fit_to_bounds(mn: Vector3, mx: Vector3) -> void: - _fit_bounds_mn = Vector3(minf(mn.x, mx.x), minf(mn.y, mx.y), minf(mn.z, mx.z)) - _fit_bounds_mx = Vector3(maxf(mn.x, mx.x), maxf(mn.y, mx.y), maxf(mn.z, mx.z)) - _fit_bounds_valid = true - _fly_held = false - _fly_locked = false - _flying = false - var span := _fit_bounds_mx - _fit_bounds_mn - target = _fit_bounds_mn + span * 0.5 - # Karte K1: Abstand über Umkugel-Formel — ALLE 8 Ecken sicher im Bild. - # (Reiner Faktor der Kantenlänge reicht bei flachen Maps nicht: die nahe - # Oberecke liegt dann fast seitlich zur Blickachse.) - distance = clampf(_fit_distance(span.length() * 0.5), - FIT_FLOOR_MIN, distance_max()) - yaw_deg = 45.0 - pitch_deg = 35.0 - _apply() - - -## Karte K1d (t_6c1027c1, Neuauflage von K1c): Startansicht NAH am Karteninhalt. -## Laden/Neu setzt die Kamera auf die KARTENMITTE (XZ-Mitte der Map-Bounds, -## Höhe = Gelände dort) mit festem Abstand START_DISTANCE_M (80 m), yaw 45°, -## pitch 35° — Objekte sind -## sofort groß und greifbar (Slys Wahl), statt die 1-km-Fläche von weitem zu -## zeigen. Die Regel ist bewusst UNABHÄNGIG von Größe/Lage des Inhalts: immer -## 80 m. Pos1 (Home) bleibt die GANZE Karte — dafür werden hier die MAP-Bounds -## gemerkt (NICHT die Content-Bounds), sodass fit_to_bounds danach die Karte -## einpasst; Startansicht und Pos1 sind also zwei verschiedene Ansichten. -func fit_to_document(doc: Dictionary, map_mn: Vector3, map_mx: Vector3) -> void: - var mn := Vector3(minf(map_mn.x, map_mx.x), minf(map_mn.y, map_mx.y), - minf(map_mn.z, map_mx.z)) - var mx := Vector3(maxf(map_mn.x, map_mx.x), maxf(map_mn.y, map_mx.y), - maxf(map_mn.z, map_mx.z)) - _fly_held = false - _fly_locked = false - _flying = false - # Pos1 = ganze Karte: MAP-Bounds merken (NICHT die Content-Bounds). - _fit_bounds_mn = mn - _fit_bounds_mx = mx - _fit_bounds_valid = true - # Kartenmitte in XZ — in y aber die GELÄNDE-Oberfläche, nicht die Mitte der - # Bounds: die Bounds reichen bei neuen Maps von −10 bis 80 m, ihre Mitte - # (35 m) liegt 35 m über dem Boden. Damit hätte die Ansicht 35 m über den - # Boden gezielt und die Objekte stünden am unteren Bildrand. - var mitte := mn + (mx - mn) * 0.5 - target = Vector3(mitte.x, SvmapDocument.terrain_height_at(doc, mitte.x, mitte.z), mitte.z) - distance = clampf(START_DISTANCE_M, DISTANCE_MIN, distance_max()) - yaw_deg = START_YAW_DEG - pitch_deg = START_PITCH_DEG - _apply() - var count := int(content_bounds(doc)["count"]) - if count == 0: - _status("Ansicht: Kartenmitte, Abstand %d m (kein Inhalt — Pos1 = ganze Karte)." % - int(START_DISTANCE_M)) - else: - _status("Ansicht: Kartenmitte, Abstand %d m (Pos1 = ganze Karte)." % - int(START_DISTANCE_M)) - - -## Bounding-Box des Dokument-INHALTS: Objekte (inkl. Bauteile) und -## Spawnpunkte — Terrain und Map-Bounds zählen NICHT (Karte K1b). -## Rückgabe: {mn: Vector3, mx: Vector3, count: int}; count 0 = leeres Dokument. -static func content_bounds(doc: Dictionary) -> Dictionary: - var mn := Vector3(INF, INF, INF) - var mx := Vector3(-INF, -INF, -INF) - var count := 0 - for p: Vector3 in _content_points(doc.get("objects", []) as Array): - mn = mn.min(p) - mx = mx.max(p) - count += 1 - var zones: Dictionary = doc.get("spawn_zones", {}) as Dictionary - for team_key in zones: - var zone: Dictionary = zones[team_key] if zones[team_key] is Dictionary else {} - for p: Vector3 in _content_points(zone.get("points", []) as Array): - mn = mn.min(p) - mx = mx.max(p) - count += 1 - if count == 0: - return {"mn": Vector3.ZERO, "mx": Vector3.ZERO, "count": 0} - return {"mn": mn, "mx": mx, "count": count} - - -## pos-Felder [x, y, z] aus einer Dokument-Liste lesen; defekte Einträge -## überspringen (stillschweigend, nie ein harter Fehler beim Laden). -static func _content_points(items: Array) -> Array: - var pts: Array = [] - for item in items: - if not (item is Dictionary): - continue - var pos: Variant = (item as Dictionary).get("pos") - if pos is Array and (pos as Array).size() >= 3: - pts.append(Vector3(float(pos[0]), float(pos[1]), float(pos[2]))) - return pts - - -## Abstand, damit die Umkugel (Radius um den Ziel-Punkt) komplett sichtbar -## bleibt: d = R / sin(halber FOV der SCHMALEREN Bildachse) + 2 % Reserve. -func _fit_distance(radius: float) -> float: - var vfov_half := deg_to_rad(fov * 0.5) # fov ist vertikal (KEEP_HEIGHT) - var aspect := 16.0 / 9.0 - var vp := get_viewport() - if vp != null: - var vs := vp.get_visible_rect().size - if vs.y > 0.0: - aspect = vs.x / vs.y - var hfov_half := atan(aspect * tan(vfov_half)) - var half := minf(vfov_half, hfov_half) - if half <= 0.0 or half >= PI * 0.5: - half = deg_to_rad(37.5) - return maxf(radius, 1.0) / sin(half) * 1.02 - - -func _handle_home_key(key: InputEventKey) -> void: - if key.pressed and not key.echo and key.keycode == KEY_HOME: - if _fit_bounds_valid: - fit_to_bounds(_fit_bounds_mn, _fit_bounds_mx) - _status("Pos1: ganze Karte ins Bild.") - - -func _apply() -> void: - var pitch := deg_to_rad(pitch_deg) - var yaw := deg_to_rad(yaw_deg) - var offset := Vector3( - sin(yaw) * cos(pitch), - sin(pitch), - cos(yaw) * cos(pitch) - ) * distance - position = target + offset - look_at(target, Vector3.UP) - - -func _status(text: String) -> void: - if status_cb.is_valid(): - status_cb.call(text) \ No newline at end of file diff --git a/src/viewport/orbit_camera.gd.uid b/src/viewport/orbit_camera.gd.uid deleted file mode 100644 index d848fc0..0000000 --- a/src/viewport/orbit_camera.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bhv55tde24sxg diff --git a/src/viewport/terrain_contour.gdshader b/src/viewport/terrain_contour.gdshader deleted file mode 100644 index 225a6f7..0000000 --- a/src/viewport/terrain_contour.gdshader +++ /dev/null @@ -1,237 +0,0 @@ -shader_type spatial; -// Terrain-Konturlinien (EDITOR-ONLY, Karte t_3ebe4086): Höhenlinien alle 1 m -// plus kräftigere 5-m-Indexlinie, per-pixel aus UV2.x (= Vertex-Höhe in m). -// Der Quest-3-Perf-Vertrag (kein Custom-Shader) gilt fürs SPIEL — der Editor -// darf teurer sein (DECISIONS.md-Konvention). -// -// Karte t_ab408127 (Terrain-Texturierung): der Editor rendert DIESELBEN -// Texturen wie der Match-Client — Albedo/Normal-Arrays über die Vertex-Alpha -// (Material-ID), Worldspace-Tiling. Konturlinien liegen OBENDRAUF (dunkle -// Multiplikation auf der texturierten Fläche). Ohne Arrays (uniforms nicht -// gesetzt, Fallback-Klon) bleibt es beim reinen Vertex-Farb-Look. -// -// Farbquelle = COLOR: RGB = gebackenes Relief-Shading (Höhen-Kurve × -// Pseudo-Licht), A = Material-ID (m/N gepackt). Unshaded: das gebackene -// Shading ist exakt sichtbar (deterministisch für die Render-Probe). -render_mode unshaded, cull_back; - -// Linienstärken (0 = aus). Terrain-Mesh setzt linien_an auf 0, wenn die -// Map flacher als 2 m ist (sonst wäre ALLES auf der 0-m-Linie dunkel). -uniform float linien_an : hint_range(0.0, 1.0) = 1.0; -uniform float linien_staerke : hint_range(0.0, 1.0) = 0.5; -uniform float index_staerke : hint_range(0.0, 1.0) = 0.75; - -// Textur-Arrays (t_ab408127) — identische Semantik wie terrain_splat.gdshader -// im Client. Nicht gesetzt → ausschalten (vertex_only-Modus). -uniform sampler2DArray albedo_array : source_color, filter_linear_mipmap, repeat_enable; -uniform float layer_count = 20.0; -uniform float tile_size = 3.0; -uniform float texturen_an = 0.0; // 1.0 = Texturen aktiv (vom Mesh-Code gesetzt) - -// Splat-Gewichtstextur (Karte t_7a0a6b79 — weiche Übergänge): je Texel die -// Top-2-Zell-IDs + bilineare Gewichte, von TerrainArrays.build_splat_bytes -// abgeleitet (Spiegel-Datei, identische Formel im Client). R=id0, G=w0, -// B=id1, A=w1 (w0+w1=1). FILTER_NEAREST: IDs dürfen NICHT bilinear vermisch -// werden — die Weichheit steckt IN den Gewichten, nicht in der Filterung. -// Ohne source_color-Hint: raw-Bytes, id = round(kanal × 255). -// Karte 25.10. (Sly: „immer noch harte Kanten“): statt der Splat-Textur (ein -// Texel je Materialpunkt → beim feinen 1-m-Raster harte Pixelstufen) liest der -// Shader die MATERIAL-ID-KARTE direkt (R8, ein Texel je Materialpunkt, -// material_res²) und mischt PRO PIXEL bilinear zwischen den 4 umliegenden -// Punkten — weiche Übergänge über genau einen Rasterabstand, egal wie fein. -// 4 Albedo- + 4 Normal-Fetches + 4 texelFetch, keine Branches. -uniform sampler2D material_map : filter_nearest, repeat_disable; -// Misch-Schicht (Karte 25.10., weiche Pinselränder): je Punkt ein zweites -// Material (b) und dessen Anteil (w, 0–255). Ohne Mischung: alles 0. -uniform sampler2D material_b_map : filter_nearest, repeat_disable; -uniform sampler2D material_w_map : filter_nearest, repeat_disable; -uniform float material_res = 2.0; // Kantenlänge der Material-Karte (Punkte) -uniform float map_size_x = 1.0; // Terrain-Kantenlänge in Weltmetern -uniform float map_size_z = 1.0; - -varying vec3 world_pos; -varying vec2 map_uv; - -void vertex() { - world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; - // UV 0..1 über die Map (Index 0 = −X/−Z-Ecke, konventionstreu zum Mesh-Bau). - map_uv = vec2((world_pos.x + 0.5 * map_size_x) / max(map_size_x, 0.001), - (world_pos.z + 0.5 * map_size_z) / max(map_size_z, 0.001)); -} - -// Organische Kanten (Karte 25.10.): die Materialpunkte liegen auf einem -// 1-m-Raster — ohne Störung zeichnet die bilineare Mischung dessen Treppen -// nach. Ein leichter Domain-Warp (Value-Noise in Rasterzellen, ±0,45 Zelle) -// verwackelt die Abtaststelle, die Kante wird unregelmäßig wie echter Boden. -// Ganzzahl-Hash statt sin()-Hash (Karte 25.10.): sin() großer Argumente ist -// auf der GPU ungenau — die Noise bekam gerade, rasterförmige Sprünge, die -// als harte Kanten durch die Verläufe liefen (Sly-Befund, nah gezoomt). -float hash2(vec2 p) { - uvec2 q = uvec2(ivec2(p) + ivec2(4096)); - uint h = q.x * 1597334677u ^ q.y * 3812015801u; - h = (h ^ (h >> 16u)) * 2246822519u; - h = h ^ (h >> 13u); - return float(h & 65535u) / 65535.0; -} - -float vnoise(vec2 p) { - vec2 i = floor(p); - vec2 f = fract(p); - f = f * f * (3.0 - 2.0 * f); - return mix(mix(hash2(i), hash2(i + vec2(1.0, 0.0)), f.x), - mix(hash2(i + vec2(0.0, 1.0)), hash2(i + vec2(1.0, 1.0)), f.x), f.y); -} - -vec2 warp(vec2 g) { - vec2 o = vec2(vnoise(g * 0.9), vnoise(g * 0.9 + vec2(17.3, 5.1))) - 0.5; - return g + o * 0.9; // eine Oktave: Quest-Budget (8 Hash statt 16) -} - -// Anti-Wiederholung v2 (Karte 25.10., Sly: Büschel sitzen im Raster, diagonale -// Streifen): Hex-Tiling (Mikkelsen/Heitz-Neyret): die Ebene wird in ein -// Dreiecksgitter geteilt, jede Ecke bekommt zufälligen Versatz + Drehung, die -// 3 Abtastungen werden mit weichen Gewichten überblendet — kein Raster, keine -// Achsen mehr, keine harten Nähte. Quest-Kosten: 3 Albedo-Fetches je Material -// (nur 1 Material in ~allen Pixeln, die Mischzone nimmt 2). Danach Makro- -// Variation: Helligkeit (~35 m) + Farbstich (~120 m), je 1 Value-Noise. -uniform float detail_kontrast = 1.3; // >1 = Büschel/Steine kräftiger (Hex-Mischung glättet sonst) - -vec3 alb_hex(float id, vec2 wp, vec2 gx, vec2 gy) { - float T = max(tile_size, 0.05); - vec2 st = wp / T * 1.7320508; // sqrt(3): Dreieckskante ≈ 0,58 Kachel (größer = weniger Mischzone) - vec2 sk = vec2(st.x - 0.57735027 * st.y, 1.15470054 * st.y); - vec2 base = floor(sk); - vec2 fr = fract(sk); - float tz = 1.0 - fr.x - fr.y; - float up = step(0.0, tz); // 1: unteres Dreieck, 0: oberes - vec3 w = mix(vec3(-tz, 1.0 - fr.y, 1.0 - fr.x), vec3(tz, fr.y, fr.x), up); - vec2 v1 = mix(base + vec2(1.0), base, up); - vec2 v2 = mix(base + vec2(1.0, 0.0), base + vec2(0.0, 1.0), up); - vec2 v3 = mix(base + vec2(0.0, 1.0), base + vec2(1.0, 0.0), up); - w = w * w * w; // Mitte stärker, Nähte weicher - w /= (w.x + w.y + w.z); - float wn = sqrt(dot(w, w)); // für Kontrast-Erhalt (Varianz der Mischung) - vec2 uv = wp / T; - vec3 acc = vec3(0.0); - for (int k = 0; k < 3; k++) { - vec2 v = k == 0 ? v1 : (k == 1 ? v2 : v3); - float wk = k == 0 ? w.x : (k == 1 ? w.y : w.z); - float a = hash2(v + vec2(31.0, 7.0)) * 6.2831853; - vec2 off = vec2(hash2(v), hash2(v + vec2(53.0, 11.0))); - float c = cos(a); - float s = sin(a); - vec2 r = vec2(c * uv.x - s * uv.y, s * uv.x + c * uv.y) + off; - acc += wk * textureGrad(albedo_array, vec3(r, id), gx, gy).rgb; - } - // Kontrast-Erhalt: Mischen dreier Abtastungen glättet auf den Mittelwert → - // Abweichung vom Mittelwert (grober Mip) durch ||w|| teilen. - vec3 mean_c = textureLod(albedo_array, vec3(0.5, 0.5, id), 8.0).rgb; - acc = mean_c + (acc - mean_c) * (detail_kontrast / max(wn, 0.577)); - float bright = mix(0.86, 1.12, vnoise(wp * 0.028 + vec2(17.0, 3.0))); - float tint = vnoise(wp * 0.0085 + vec2(5.0, 41.0)) - 0.5; - vec3 col = acc * bright; - return col * vec3(1.0 + 0.10 * tint, 1.0 + 0.03 * tint, 1.0 - 0.10 * tint); -} - -float mat_id(ivec2 p) { - return clamp(floor(texelFetch(material_map, p, 0).r * 255.0 + 0.5), 0.0, layer_count - 1.0); -} - -float mat_b(ivec2 p) { - return clamp(floor(texelFetch(material_b_map, p, 0).r * 255.0 + 0.5), 0.0, layer_count - 1.0); -} - -// Top-2-Mischung (Karte 25.10.): 4 Nachbarpunkte × (a, b) = 8 Kandidaten mit -// Gewicht (bilinear × Punkt-Anteil). Gleiche IDs werden aufsummiert, die -// zwei stärksten Materialien gewinnen. Rückgabe: (id1, id2, Anteil id1). -// Danach nur 2 Albedo- + 2 Normal-Fetches. -vec3 top2(vec2 g) { - vec2 gi = min(floor(g), vec2(max(material_res - 2.0, 0.0))); - vec2 f = clamp(g - gi, 0.0, 1.0); - ivec2 p = ivec2(gi); - ivec2 q[4] = ivec2[4](p, p + ivec2(1, 0), p + ivec2(0, 1), p + ivec2(1, 1)); - float cw[4] = float[4]((1.0 - f.x) * (1.0 - f.y), f.x * (1.0 - f.y), (1.0 - f.x) * f.y, f.x * f.y); - float ids[8]; - float ws[8]; - for (int k = 0; k < 4; k++) { - float wb = texelFetch(material_w_map, q[k], 0).r; - ids[2 * k] = mat_id(q[k]); - ws[2 * k] = cw[k] * (1.0 - wb); - ids[2 * k + 1] = mat_b(q[k]); - ws[2 * k + 1] = cw[k] * wb; - } - float id1 = ids[0]; - float s1 = -1.0; - for (int i = 0; i < 8; i++) { - float s = 0.0; - for (int j = 0; j < 8; j++) { - s += ids[j] == ids[i] ? ws[j] : 0.0; - } - if (s > s1) { - s1 = s; - id1 = ids[i]; - } - } - float id2 = id1; - float s2 = 0.0; - for (int i = 0; i < 8; i++) { - if (ids[i] == id1) { - continue; - } - float s = 0.0; - for (int j = 0; j < 8; j++) { - s += ids[j] == ids[i] ? ws[j] : 0.0; - } - if (s > s2) { - s2 = s; - id2 = ids[i]; - } - } - return vec3(id1, id2, s1 / max(s1 + s2, 0.00001)); -} - -void fragment() { - vec3 col = COLOR.rgb; - // --- Textur (t_ab408127): Material-ID aus Vertex-Alpha, Worldspace-UV --- - // Editor-Vorschau ALBEDO-ONLY (der Editor-Viewport ist unshaded; eine - // Normal-Map würde ohne Licht ohnehin nichts zeigen — die Relief-Optik - // kommt aus dem gebackenen Hillshade in COLOR.rgb). - if (texturen_an > 0.5) { - // Top-2-Splat-Blend (t_7a0a6b79): die Weichheit steckt in den Gewich- - // ten der Splat-Textur — an Zellgrenzen rampen die IDs weich (bilinear - // über die 4 umliegenden Zellen), im Flachbereich w0=1 (reines id0). - // Karte 25.10.: Top-2 aus 4 Nachbarpunkten inkl. Misch-Schicht - // (Spiegel zum Client-Shader terrain_splat.gdshader). - float m1 = max(material_res - 1.0, 1.0); - vec2 g = clamp(warp(clamp(map_uv, 0.0, 1.0) * m1), vec2(0.0), vec2(m1)); - vec3 t2 = top2(g); - // Ableitungen VOR dem Branch (Mip-Wahl bleibt gültig, textureGrad). - vec2 guv = world_pos.xz / max(tile_size, 0.05); - vec2 gx = dFdx(guv); - vec2 gy = dFdy(guv); - // Reiner Boden (Anteil ≥ 0,999, Normalfall): nur 3 statt 6 Fetches. - vec3 alb = t2.z > 0.999 ? alb_hex(t2.x, world_pos.xz, gx, gy) - : mix(alb_hex(t2.y, world_pos.xz, gx, gy), alb_hex(t2.x, world_pos.xz, gx, gy), t2.z); - col = alb * col; // Tönung/Shading multipliziert (wie Client) - } - // --- Konturlinien (unverändert, Karte t_3ebe4086) --- - float h = UV2.x; - // Flachflächen-Schutz: liegt eine GANZE Platte exakt auf einer Meter-Marke - // (z. B. Tal = 0.0 m, Plateau = 5.0 m), wäre jedes Pixel „auf der Linie“ - // → die Fläche würde komplett dunkel übermalt. Deshalb: Linienstärke an - // der lokalen Steigung dämpfen — exakt flach (dh = 0) → keine Linie, - // sanfte bis steile Hänge → volle Linie. - float dh = max(abs(dFdx(h)), abs(dFdy(h))); - float relief = smoothstep(0.0, 0.0005, dh); - // Abstand (in m) zur nächsten ganzen Meter-Marke: - float d1 = abs(fract(h + 0.5) - 0.5); - float w1 = fwidth(h) * 1.2; // Linie ~1–2 px breit, auflösungsstabil - float linie = 1.0 - smoothstep(w1 * 0.5, w1 * 1.5, d1); - // 5-m-Indexlinie (Abstand in m zur nächsten 5er-Marke): - float d5 = abs(fract(h / 5.0 + 0.5) - 0.5) * 5.0; - float w5 = fwidth(h) * 2.2; - float linie5 = 1.0 - smoothstep(w5 * 0.5, w5 * 1.5, d5); - col = mix(col, col * 0.55, linie * linien_an * linien_staerke * relief); - col = mix(col, col * 0.32, linie5 * linien_an * index_staerke * relief); - ALBEDO = col; -} diff --git a/src/viewport/terrain_contour.gdshader.uid b/src/viewport/terrain_contour.gdshader.uid deleted file mode 100644 index c6426a4..0000000 --- a/src/viewport/terrain_contour.gdshader.uid +++ /dev/null @@ -1 +0,0 @@ -uid://clp2k02n02ruk diff --git a/src/viewport/terrain_mesh.gd b/src/viewport/terrain_mesh.gd deleted file mode 100644 index 7acbb23..0000000 --- a/src/viewport/terrain_mesh.gd +++ /dev/null @@ -1,446 +0,0 @@ -extends Node3D -## Terrain-Ansicht: baut das Höhenfeld (svmap terrain-Block) als Mesh im -## Editor-Viewport (M2, Karte t_9aba04f1). -## -## Zwei Wege: -## rebuild_from_doc(data) — nach Laden/Neu/Undo: Base64 dekodieren + Mesh neu. -## update_heights(...) — während eines Pinsel-Strichs: nur Vertices neu -## schreiben (SOFT-war das Mesh live — kein Rebuild, -## kein Flackern, res 129 ≈ 16,6k Punkte = flott). -## -## Farben (Karte t_603ec1a8): Vertex-Farben aus der Material-Schicht -## (terrain.materials_r8_b64, v2) — Gras/Sand/Fels, plus Höhen-Faktor. -## -## Relief-Lesbarkeit (Karte t_3ebe4086, Sly-Befund „Erhöhungen/Vertiefungen -## kaum erkennbar"): TWO-PUNCH im Vertex-Farben-Pfad: -## 1. Höhen-Faktor deutlich kontrastreicher: steilere S-Kurve statt linear -## und breitere Faktor-Spanne (Senken dunkler, Hügel heller). -## 2. Pseudo-Licht: Terrain-Normale × feste Sonnenrichtung (Hillshade) — -## Sonnenabgewandte Hänge werden dunkler, zugewandte heller. Das ist der -## günstigste echte Relief-Eindruck für die mobile Vertex-Farb-Pipeline -## und identisch zum Match-Client (svmap_terrain.gd, gleiche Konstanten). -## -## Editor-only Extra (gleiche Karte): Höhenlinien alle 1 m + 5-m-Indexlinie -## per Custom-Shader (terrain_contour.gdshader, UV2.x = Höhe). Quest-Vertrag -## „kein Custom-Shader" gilt fürs Spiel — der EDITOR darf teurer sein -## (DECISIONS.md-Konvention). Der Match-Client bleibt StandardMaterial3D. -## Editor-Viewport material ist UNSHADED: das gebackene Shading ist exakt -## sichtbar (kein Doppel-Shading mit dem Viewport-Sonnenlicht, deterministisch -## für die Render-Probe). - -const MATERIAL_COLORS: Array[Color] = [ - Color(1.0, 1.0, 1.0), # 0 = Gras — Karte t_ab408127: Textur liefert die - Color(1.0, 1.0, 1.0), # 1 = Sand — Farbe; Vertex-RGB ist nur noch Shading- - Color(1.0, 1.0, 1.0), # 2 = Fels — Multiplikator (Höhe × Hillshade), - # 20-Slot-Palette: Weiß = neutral, Albedo-Textur trägt die Färbung. - Color(1.0, 1.0, 1.0), # 3 - Color(1.0, 1.0, 1.0), # 4 - Color(1.0, 1.0, 1.0), # 5 - Color(1.0, 1.0, 1.0), # 6 - Color(1.0, 1.0, 1.0), # 7 - Color(1.0, 1.0, 1.0), # 8 - Color(1.0, 1.0, 1.0), # 9 - Color(1.0, 1.0, 1.0), # 10 - Color(1.0, 1.0, 1.0), # 11 - Color(1.0, 1.0, 1.0), # 12 - Color(1.0, 1.0, 1.0), # 13 - Color(1.0, 1.0, 1.0), # 14 - Color(1.0, 1.0, 1.0), # 15 - Color(1.0, 1.0, 1.0), # 16 - Color(1.0, 1.0, 1.0), # 17 - Color(1.0, 1.0, 1.0), # 18 - Color(1.0, 1.0, 1.0), # 19 -] -# Höhen-Faktor (Material-Farbe × Faktor) — KARTE t_3ebe4086: bewusst breiter -# und mit S-Kurve (t*t*(3-2t)) kalibriert als die alte Linear-Version -# (0.72 … 1.15): Senken deutlich dunkler, Hügel deutlich heller. -const SHADING_LOW := 0.58 # Tal-Faktor -const SHADING_HIGH := 1.28 # Hügel-Faktor -# Pseudo-Licht (Hillshade): feste Sonnenrichtung, editor-seitig so gewählt, -# dass beim Default-Blick (Kamera südlich der Map, Blick Richtung −Z) die -# Formen seitlich beleuchtet wirken (Licht von rechts-hinten +X/+Z). -const RELIEF_SUN := Vector3(0.45, 0.75, 0.5) -const LIGHT_LOW := 0.62 # Hang abgewandt von der Sonne -const LIGHT_HIGH := 1.22 # Hang zugewandt -const LIGHT_T0 := 0.15 # Smoothstep-Fenster der NDOT-Kurve -const LIGHT_T1 := 0.95 -const SHADE_MIN := 0.40 # Gesamtklemme (Höhen × Licht), Schutz vor Schwarz -const SHADE_MAX := 1.35 -# Höhenlinien (editor-only) nur ab 2 m Gesamtrelief — auf einer flachen Map -# läge sonst ALLES auf der 0-m-Linie und die Fläche würde dunkel übermalt. -const CONTOUR_MIN_SPAN := 2.0 - -const CONTOUR_SHADER := "res://src/viewport/terrain_contour.gdshader" - -var _mi: MeshInstance3D -var _res := 0 -var _size_x := 0.0 -var _size_z := 0.0 -var _mats_cache := PackedByteArray() # zuletzt gesehene Material-Schicht - # (res²) — Live-Pfad-Fallback, Karte - # t_55ed041a. -var _wasser_level := INF # Karte t_28fdef03: Wasserhöhe aus dem doc - # (INF = kein Wasser — Matsch-Ring aus). -var _triangles := 0 -var _contours_pref := true # UI-Toggle „Höhenlinien“ (Default AN) -var _shader: Shader - -# --- Splat-Gewichtstextur (Karte t_7a0a6b79 — weiche Übergänge) ------------- -# CPU-Image + GPU-Textur der Top-2-Splat-Gewichte (RGBA8: R=id0 G=w0 B=id1 -# A=w1, Formel TerrainArrays.build_splat_bytes — Spiegel-Datei). Beim Malen -# wird NUR die betroffene Region neu abgeleitet (Sub-Rect-Update, siehe -# _refresh_splat_region) — kein Voll-Rebuild pro Mal-Frame. -var _splat_image: Image -var _splat_tex: ImageTexture -var _splat_side := 0 # Texel-Kantenlänge (Zweierpotenz) -var _splat_res := 0 # Zellraster-Auflösung, für die die Splat gilt -# Misch-Schicht (Karte 25.10.): zweites Material + Anteil je Punkt — eigene -# R8-Texturen neben der Material-Karte (gleiche Größe, Shader liest alle drei). -var _mix_b_cache := PackedByteArray() -var _mix_w_cache := PackedByteArray() -var _mix_b_image: Image -var _mix_w_image: Image -var _mix_b_tex: ImageTexture -var _mix_w_tex: ImageTexture - - -func _ready() -> void: - _ensure_mesh_instance() - - -func _ensure_mesh_instance() -> void: - if _mi != null and is_instance_valid(_mi): - return - _mi = MeshInstance3D.new() - _mi.material_override = _make_material() - add_child(_mi) - - -## Material fürs Editor-Terrain: unshaded Kontur-Shader (Vertex-Farbe als -## Albedo + Höhenlinien). Karte t_ab408127: zusätzlich die Terrain-Texturen -## (TerrainArrays.res — spiegelgleich zum Client-Pfad, aber EDITOR-EIGENE -## Kopie der Resource-Klasse, Repos sind entkoppelt). Fällt auf unshaded -## StandardMaterial3D zurück, wenn der Shader nicht ladbar ist (Robustheit — -## Terrain bleibt immer sichtbar). -func _make_material() -> Material: - _shader = load(CONTOUR_SHADER) - if _shader != null: - var mat := ShaderMaterial.new() - mat.shader = _shader - _apply_texture_uniforms(mat) - return mat - push_warning("TerrainMesh: Kontur-Shader fehlt — Fallback StandardMaterial3D (unshaded).") - var std := StandardMaterial3D.new() - std.vertex_color_use_as_albedo = true - std.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED - std.roughness = 1.0 - return std - - -## Terrain-Texturen an den Kontur-Shader binden (t_ab408127). Quelle = -## res://assets/textures/terrain/terrain_arrays.res — vom Sync-Skript -## (tools/sync_terrain_tex.sh) aus dem Client-Klon gespiegelt, analog -## tools/sync_models.sh (models/-Ordner-Muster). Fehlt die Resource -## (frischer Editor-Klon ohne Sync), bleibt texturen_an=0 → reiner -## Vertex-Farb-Look (Fallback, kein Crash). -func _apply_texture_uniforms(mat: ShaderMaterial) -> void: - const ARRAYS_PATH := "res://assets/textures/terrain/terrain_arrays.res" - if not ResourceLoader.exists(ARRAYS_PATH): - return # Fallback-Klon: texturen_an bleibt 0 (Vertex-Farb-Look) - var arrays = load(ARRAYS_PATH) - if arrays == null or not ("albedo_images" in arrays): - return - var imgs: Array = arrays.albedo_images - if imgs.size() < 3: - return - var albedo := Texture2DArray.new() - albedo.create_from_images(imgs) - mat.set_shader_parameter("albedo_array", albedo) - mat.set_shader_parameter("layer_count", float(imgs.size())) - mat.set_shader_parameter("tile_size", 3.0) # Spiegel Client TILE_SIZE (Karte 25.10.) - mat.set_shader_parameter("texturen_an", 1.0) - - -## UI-Toggle „Höhenlinien“ (main.gd): ohne Rebuild an/ab. -func set_contours(on: bool) -> void: - _contours_pref = on - _apply_contour_state(_last_span >= CONTOUR_MIN_SPAN) - - -func contours_enabled() -> bool: - return _contours_pref - - -var _last_span := 0.0 - - -## Kompletter Neuaufbau aus dem svmap-terrain-Block (inkl. Material-Schicht). -func rebuild_from_doc(data: Dictionary) -> void: - var terrain: Dictionary = data.get("terrain", {}) - if terrain.is_empty(): - _triangles = 0 - if _mi != null: - _mi.mesh = null - return - # Splat-Textur verwerfen — sie wird im update_heights frisch aus der - # (nach Undo/Load evtl. geänderten) Zell-Schicht abgeleitet. - _splat_tex = null - var mix := SvmapIO.decode_mix(data.get("terrain", {})) - _mix_b_cache = mix[0] - _mix_w_cache = mix[1] - # Wasser (Karte t_28fdef03): Höhe merken — der Matsch-Ring (Ufer-Automatik) - # mischt sich in relief_color ein. INF = kein Wasser (Legacy unverändert). - _wasser_level = SvmapWasser.level(data) - var heights := SvmapIO.decode_heights(terrain) - var mats := SvmapIO.decode_materials(terrain) - update_heights(heights, int(terrain.get("resolution", 0)), - float(terrain.get("size_x_m", 1.0)), float(terrain.get("size_z_m", 1.0)), mats) - - -## Mesh aus einem (neuen) Höhenfeld bauen — auch live während des Strichs. -## res/size 0 = zuletzt verwendete Werte weiterverwenden (Live-Pfad). -## mats = Material-Schicht (res² Bytes, 0=Gras/1=Sand/2=Fels); leer → die -## zuletzt gesehene Schicht (Cache) wird weiterverwendet, damit Live-Updates -## ohne explizite Schicht (z. B. Heben/Senken-Stroke) die Material-Farben -## BEHALTEN statt live auf alles-Gras zurückzufallen (Karte t_55ed041a). -## Nur wenn NIE eine Schicht gesehen wurde (Legacy-v1-Map) gilt alles Gras. -func update_heights(heights: PackedFloat32Array, res: int = 0, size_x: float = 0.0, - size_z: float = 0.0, mats: PackedByteArray = PackedByteArray(), - splat_rect_cells: Rect2i = Rect2i()) -> void: - if res < 2: - res = _res - if size_x <= 0.0: - size_x = _size_x - if size_z <= 0.0: - size_z = _size_z - if _mi == null: - _ensure_mesh_instance() - if res < 2 or heights.size() < res * res or size_x <= 0.0 or size_z <= 0.0: - return - _res = res - _size_x = size_x - _size_z = size_z - # Material-Schicht hat ihr eigenes (feines) Raster (Karte 24.10.) — mres - # aus der Länge (quadratisch); alte Karten: mres == res. - if mats.is_empty() and not _mats_cache.is_empty(): - mats = _mats_cache - elif not mats.is_empty(): - _mats_cache = mats - var mres := mat_res_of(mats, res) - var last := float(res - 1) - var positions := PackedVector3Array() - var normals := PackedVector3Array() - var colors := PackedColorArray() - var heights_uv := PackedVector2Array() - var indices := PackedInt32Array() - positions.resize(res * res) - normals.resize(res * res) - colors.resize(res * res) - heights_uv.resize(res * res) - - var hmin := INF - var hmax := -INF - for v in heights: - if v < hmin: - hmin = v - if v > hmax: - hmax = v - var span := maxf(hmax - hmin, 0.0001) - _last_span = span - var cell_x := size_x / last - var cell_z := size_z / last - _apply_contour_state(span >= CONTOUR_MIN_SPAN) - - var z := 0 - while z < res: - var x := 0 - while x < res: - var idx := z * res + x - # Index→Welt-Konvention (Karte t_234490cf): Index 0 = −X/−Z-Ecke, - # x-Index läuft MIT +WeltX, z-Index MIT +WeltZ — IDENTISCH zu - # SvmapDocument.terrain_height_at, TerrainField.height_at und dem - # Match-Client (svmap_terrain.gd: −size*0.5 + index*cell). - # Vor b7b160d…+Fix stand hier eine SPIGELUNG (+0.5 − index·cell in - # beiden Achsen) — der Renderer war damit der einzige Verbraucher - # dieser Konvention: der Pinsel-Strahl traf das Mesh an der - # punktgespiegelten Stelle (Sly-Befund „Pinsel wirkt woanders“). - positions[idx] = Vector3( - -size_x * 0.5 + float(x) * cell_x, - heights[idx], - -size_z * 0.5 + float(z) * cell_z) - # Normale aus zentralen Differenzen (Rand: einseitig geklemmt): - # n ∝ (−∂h/∂x, 1, −∂h/∂z), skaliert mit 2·cell_x·cell_z. - var hx_l := heights[z * res + maxi(x - 1, 0)] - var hx_r := heights[z * res + mini(x + 1, res - 1)] - var hz_d := heights[maxi(z - 1, 0) * res + x] - var hz_u := heights[mini(z + 1, res - 1) * res + x] - normals[idx] = Vector3( - (hx_l - hx_r) * cell_z, - 2.0 * cell_x * cell_z, - (hz_d - hz_u) * cell_x).normalized() - var mat_id := clampi(SvmapIO.material_at_height_point(mats, mres, res, x, z), - 0, MATERIAL_COLORS.size() - 1) - # Material-Farbe × Höhen-Kurve × Pseudo-Licht (Relief lesbar). - var farbe := relief_color(mat_id, heights[idx], hmin, hmax, normals[idx]) - # Ufer-Automatik (Karte t_28fdef03): Zellen knapp unter der Wasser- - # höhe bekommen den Matsch-Ring — IDENTISCHE Formel wie der Client - # (SvmapWasser.ufer_faktor/matsch_anwenden — dieselbe Spiegel-Datei). - # Alpha (gepackte Material-ID) bleibt unangetastet (Splat-Vertrag). - if _wasser_level < INF: - farbe = SvmapWasser.matsch_anwenden(farbe, - SvmapWasser.ufer_faktor(heights[idx], _wasser_level)) - colors[idx] = farbe - heights_uv[idx] = Vector2(heights[idx], 0.0) - x += 1 - z += 1 - - z = 0 - while z < res - 1: - var x := 0 - while x < res - 1: - var i := z * res + x - # Winding-Order: Godot betrachtet Clockwise (von der Vorderseite - # betrachtet) als Vorderseite. Von oben gelesen muss jedes Dreieck - # IM Uhrzeigersinn laufen, sonst cullt der Renderer die komplette - # Deckfläche als Backface (Karte t_7ac70014: „dunkle Platte“). - indices.append_array([i, i + 1, i + res, i + 1, i + res + 1, i + res]) - x += 1 - z += 1 - - var arrays := [] - arrays.resize(Mesh.ARRAY_MAX) - arrays[Mesh.ARRAY_VERTEX] = positions - arrays[Mesh.ARRAY_NORMAL] = normals - arrays[Mesh.ARRAY_COLOR] = colors - arrays[Mesh.ARRAY_TEX_UV2] = heights_uv # Höhe je Vertex → Kontur-Shader - arrays[Mesh.ARRAY_INDEX] = indices - var mesh := ArrayMesh.new() - mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) - _mi.mesh = mesh - _triangles = indices.size() / 3 - - # --- Splat-Gewichtstextur (t_7a0a6b79): map_size + Sub-Rect-Update -------- - # map_size_x/z in Weltmetern (Shader rechnet map_uv = Weltkoord. über Map). - # Mal-Stroke: splat_rect_cells = betroffenes Zellrechteck → NUR die Region - # neu ableiten. Voll-Rebuild (Load/Undo/Stroke-Ende): Textur frisch bauen. - var mat := _mi.material_override - if mat is ShaderMaterial: - var shm := mat as ShaderMaterial - shm.set_shader_parameter("map_size_x", size_x) - shm.set_shader_parameter("map_size_z", size_z) - # Material-ID-Karte (Karte 25.10.): Malen = gleiche Größe → nur Daten - # tauschen (1 Upload); sonst neu anlegen. splat_rect_cells bleibt als - # Parameter (Aufrufer-Vertrag), wird aber nicht mehr gebraucht. - if _splat_tex != null and _splat_res == mres and mats.size() == mres * mres \ - and _mix_b_tex != null and _mix_b_cache.size() == mres * mres: - _splat_image.set_data(mres, mres, false, Image.FORMAT_R8, mats) - _splat_tex.update(_splat_image) - _mix_b_image.set_data(mres, mres, false, Image.FORMAT_R8, _mix_b_cache) - _mix_b_tex.update(_mix_b_image) - _mix_w_image.set_data(mres, mres, false, Image.FORMAT_R8, _mix_w_cache) - _mix_w_tex.update(_mix_w_image) - else: - _build_splat(shm, mats, mres, size_x, size_z) - - -## Misch-Schicht fürs nächste update_heights (Live-Malen, Karte 25.10.). -func set_mix(mix_b: PackedByteArray, mix_w: PackedByteArray) -> void: - _mix_b_cache = mix_b - _mix_w_cache = mix_w - - -## Raster einer Material-Schicht aus ihrer Länge (quadratisch). Unpassend/leer -## → Höhenraster (alte Karten, Legacy ohne Schicht). -static func mat_res_of(mats: PackedByteArray, res: int) -> int: - if mats.is_empty(): - return res - var r := int(roundf(sqrt(float(mats.size())))) - return r if r >= 2 and r * r == mats.size() else res - - -## Höhenlinien-Uniform an die aktuelle Situation anpassen (Pref ∧ Relief ≥ 2 m). -func _apply_contour_state(span_ok: bool) -> void: - if _mi == null or not is_instance_valid(_mi): - return - var mat := _mi.material_override - if mat is ShaderMaterial: - mat.set_shader_parameter("linien_an", 1.0 if (_contours_pref and span_ok) else 0.0) - - -## Vertex-Farbe EINER Zelle: Material × Höhen-Kurve × Pseudo-Licht. -## Static (statt inline), damit Tests die Mathematik direkt prüfen können und -## Editor/Client die IDENTISCHE Formel teilen (Konstanten spiegeln — gleiche -## Kommentare/Konstanten wie scripts/world/svmap_terrain.gd im Client-Repo). -## Alpha = Material-ID (Karte t_ab408127): m/N gepackt — der Shader (Client -## UND Editor-Vorschau) sampelt die Texture2DArray-Layer über die Alpha. -## Der Shading-Faktor wirkt NUR auf RGB (Color × float skaliert auch Alpha — -## deshalb wird die ID erst im Return gezielt gesetzt). -static func relief_color(mat_id: int, h: float, hmin: float, hmax: float, - normal: Vector3) -> Color: - var m := clampi(mat_id, 0, MATERIAL_COLORS.size() - 1) - var span := maxf(hmax - hmin, 0.0001) - var t := clampf((h - hmin) / span, 0.0, 1.0) - # Steilere Kurve statt linear: S-Kurve hebt die Enden, senkt die Mitte — - # Hügel/Senken trennen sich stärker als bei t direkt. - var t_s := t * t * (3.0 - 2.0 * t) - var hf := lerpf(SHADING_LOW, SHADING_HIGH, t_s) - # Pseudo-Licht: Normale × feste Sonnenrichtung → Hillshade. - var nd := clampf(normal.normalized().dot(RELIEF_SUN.normalized()), 0.0, 1.0) - var x := clampf((nd - LIGHT_T0) / (LIGHT_T1 - LIGHT_T0), 0.0, 1.0) - var lf := lerpf(LIGHT_LOW, LIGHT_HIGH, x * x * (3.0 - 2.0 * x)) - # Ausbrennen-Fix (t_7a0a6b79): der Faktor wird auf 1.0 normalisiert. Vorher - # lief hf·lf bis 1.35 und RGBA8 klemmte auf 1.0 — ALLE Relief-Unterschiede - # oberhalb 1.0 kollabierten zu flachem Weiß (Slys „ausgebrannte Weißflächen“ - # auf Sand hell/Schnee). Relative Spanne bleibt identisch (0.40…1.35 → - # 0.296…1.0), Kontrast-Verhältnis unverändert, Shading bleibt sichtbar. - var f := clampf(hf * lf, SHADE_MIN, SHADE_MAX) / SHADE_MAX - var base := MATERIAL_COLORS[m] as Color - # Kanäle auf 0..1 klemmen: der Mesh-Speicher (ARRAY_COLOR, RGBA8) clamp't - # genauso — der Helfer muss die RENDER-Wahrheit liefern (Probe-Vergleich), - # nicht die unbehandelte Mathematik. - return Color(clampf(base.r * f, 0.0, 1.0), clampf(base.g * f, 0.0, 1.0), - clampf(base.b * f, 0.0, 1.0), float(m) / float(MATERIAL_COLORS.size())) - - -func triangle_count() -> int: - return _triangles - - -func resolution() -> int: - return _res - - -## Splat-Gewichtstextur komplett ableiten (t_7a0a6b79). Die Zell-Schicht -## (mats, res²) bleibt die Quelle der Wahrheit — die Textur ist reine -## Ableitung (Datenformat unverändert). Unbrauchbare Schicht → alte Textur -## bleibt (Robustheit, kein Crash). -## size_x/size_z (t_5c94d098): Karten-Kantenlänge in Metern → Texel-Dichte der -## Splat (1 m/Texel bei 1024 m; vorher 2 m/Texel = sichtbare Stufen). -func _build_splat(mat: ShaderMaterial, mats: PackedByteArray, res: int, - _size_x: float = 0.0, _size_z: float = 0.0) -> void: - if res < 2: - _splat_tex = null - return - # Karte 25.10.: Material-ID-Karte statt Splat-Gewichte (weiche Übergänge - # pro Pixel im Shader, Spiegel zum Client). - _splat_image = TerrainArrays.material_image(mats, res) - _splat_side = _splat_image.get_width() - _splat_res = res - _splat_tex = ImageTexture.create_from_image(_splat_image) - # Misch-Schicht: passt sie nicht zum Raster (Legacy/leer) → Nullen. - if _mix_b_cache.size() != res * res or _mix_w_cache.size() != res * res: - _mix_b_cache = PackedByteArray() - _mix_b_cache.resize(res * res) - _mix_w_cache = PackedByteArray() - _mix_w_cache.resize(res * res) - _mix_b_image = TerrainArrays.material_image(_mix_b_cache, res) - _mix_w_image = TerrainArrays.material_image(_mix_w_cache, res) - _mix_b_tex = ImageTexture.create_from_image(_mix_b_image) - _mix_w_tex = ImageTexture.create_from_image(_mix_w_image) - if mat != null: - mat.set_shader_parameter("material_map", _splat_tex) - mat.set_shader_parameter("material_b_map", _mix_b_tex) - mat.set_shader_parameter("material_w_map", _mix_w_tex) - mat.set_shader_parameter("material_res", float(_splat_side)) - - diff --git a/src/viewport/terrain_mesh.gd.uid b/src/viewport/terrain_mesh.gd.uid deleted file mode 100644 index 157ab7a..0000000 --- a/src/viewport/terrain_mesh.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bwwwoxt0cxfj diff --git a/src/viewport/wasser.gdshader b/src/viewport/wasser.gdshader deleted file mode 100644 index 1504512..0000000 --- a/src/viewport/wasser.gdshader +++ /dev/null @@ -1,92 +0,0 @@ -shader_type spatial; -// Wasser-Oberfläche pro Map (Karte t_28fdef03) — SPIEGELGLEICHE Datei: -// scopedvr-client → res://shaders/wasser.gdshader -// scopedvr-map-editor → res://src/viewport/wasser.gdshader (byteidentischer -// Spiegel, sync via tools/sync_wasser.sh — wie terrain_splat/terrain_arrays). -// -// Quest-3-Perf-Vertrag (bewusste Absagen der Spec): KEINE echte Spiegelung, -// KEINE Brechung, KEIN SSR. Spiegel-Impression = Skybox-Farbreflex (uniform) -// + Fresnel-Glanz. Wellen NUR im Fragment-Shader (analytische 2-Layer-Sinus- -// Normalen — keine Wellen-Texturen, keine Geometrie-Bewegung). Ufer-Schaum + -// Flachwasser-Transparenz aus der Tiefe-Textur (ufer_tex, R8 = Tiefe/TIEFE_MAX, -// siehe SvmapWasser.ufer_bild). Ferne Fragmente vereinfachen sich selbst -// (Wasserdistanz-Regel): nur Grundfarbe, keine Wellen/Schaum-Mathematik. -// -// Eine Fläche, ein Draw-Call — Overdraw ist die einzige echte Kostenquelle. - -render_mode blend_mix, depth_draw_never, cull_back, unshaded, shadows_disabled; - -uniform vec4 farbe_flach : source_color = vec4(0.10, 0.30, 0.34, 1.0); -uniform vec4 farbe_tief : source_color = vec4(0.02, 0.10, 0.15, 1.0); -uniform vec3 reflex : source_color = vec3(0.72, 0.83, 0.92); // Skybox-Farbreflex (Wetter) -uniform float glanz : hint_range(0.0, 2.0) = 1.0; // Glint-Stärke (Wetter) -uniform sampler2D ufer_tex : filter_linear; // R = Tiefe 0..1 (0..TIEFE_MAX) -uniform float tiefe_max = 4.0; // SvmapWasser.TIEFE_MAX (Spiegel-Konstante) -uniform float schaum_band = 0.35; // SvmapWasser.SCHAUM_BAND (Meter) -uniform float wellen_scale = 0.55; // Wellenfrequenz (1/m) -uniform float wellen_staerke = 0.16; // Normal-Neigung (flach = Spiegel-Optik) - -varying vec3 welt_pos; // Welt-Position des Fragments (Fresnel + Distanz-Regel) - -void vertex() { - welt_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; -} - -// Analytische Wellen-Normale aus 2 Scroll-Ebenen (kleine Skala, verschiedene -// Richtungen/Geschwindigkeiten — läuft nie synchron): h = Σ A·sin(dot(p,d)·f + t·s), -// n ∝ (−∂h/∂x, 1, −∂h/∂z) mit ∂h/∂p = Σ A·f·d·cos(…). -vec3 wellen_normal(vec2 p, float t) { - vec2 d1 = vec2(0.94, 0.34); - vec2 d2 = vec2(-0.42, 0.91); - float f1 = wellen_scale * 2.1; - float f2 = wellen_scale * 3.7; - float s1 = 1.25; - float s2 = 1.75; - float a1 = wellen_staerke; - float a2 = wellen_staerke * 0.6; - vec2 g1 = d1 * (f1 * a1 * cos(dot(p, d1) * f1 + t * s1)); - vec2 g2 = d2 * (f2 * a2 * cos(dot(p, d2) * f2 + t * s2)); - vec2 g = g1 + g2; - return normalize(vec3(-g.x, 1.0, -g.y)); -} - -void fragment() { - // Tiefe am Fragment (ufer_tex, UV deckt die Map 1:1 ab — SvmapWasser.ufer_bild). - float tiefe01 = texture(ufer_tex, UV).r; - float tiefe = tiefe01 * tiefe_max; - - // Wasserdistanz-Regel: ferne Fragmente = vereinfachter Modus (Grundfarbe, - // flache Normale, kein Schaum). Weiches Fenster 45→90 m, pro Fragment. - float fern = smoothstep(45.0, 90.0, length(welt_pos - CAMERA_POSITION_WORLD)); - float detail = 1.0 - fern; - - vec3 n = wellen_normal(welt_pos.xz, TIME); - n = normalize(mix(vec3(0.0, 1.0, 0.0), n, detail)); - - vec3 v = normalize(CAMERA_POSITION_WORLD - welt_pos); - float fresnel = pow(1.0 - clamp(dot(n, v), 0.0, 1.0), 5.0); - - // Grundfarbe: seicht heller/durchsichtiger, tief dunkler. - vec3 grund = mix(farbe_flach.rgb, farbe_tief.rgb, clamp(tiefe01 * 1.4, 0.0, 1.0)); - - // Spiegel-Impression: Skybox-Farbreflex via Fresnel + Sonnen-Glint. - vec3 reflex_f = reflex * mix(0.25, 1.0, fresnel); - vec3 l = normalize(vec3(-0.45, 0.75, 0.5)); // SvmapTerrain.RELIEF_SUN (Spiegel) - float glint = pow(max(dot(reflect(-v, n), l), 0.0), 48.0) * glanz; - - // Ufer-Schaum: schmales Band an der Wasserlinie, Kante leicht wellig - // (Wellen-Phase pulsiert das Band ±20 %). - float schaum_grenze = schaum_band * (0.9 + 0.2 * sin(welt_pos.x * 1.7 + welt_pos.z * 1.3 + TIME * 1.2)); - float schaum = (1.0 - smoothstep(0.0, max(schaum_grenze, 0.02), tiefe)) * detail; - - vec3 farbe = grund + reflex_f + vec3(glint) + vec3(schaum * 0.85); - // Transparenz: Ufer fast klar, tiefes Wasser dicht. Schaum deckt voll. - float alpha = mix(0.38, 0.88, clamp(tiefe01 * 1.6, 0.0, 1.0)); - alpha = max(alpha, schaum * 0.9); - - // spatial-Vertrag: Farbe über ALBEDO, Transparenz über ALPHA (COLOR gibt - // es nur im canvas_item-Shader — schreibend dort = „Constants cannot be - // modified“). - ALBEDO = farbe; - ALPHA = alpha; -} diff --git a/src/viewport/wasser.gdshader.uid b/src/viewport/wasser.gdshader.uid deleted file mode 100644 index 71814f5..0000000 --- a/src/viewport/wasser.gdshader.uid +++ /dev/null @@ -1 +0,0 @@ -uid://c7s4uhqs208da diff --git a/tests/probe_buttons_pos.gd b/tests/probe_buttons_pos.gd index 1834b6b..f219a43 100644 --- a/tests/probe_buttons_pos.gd +++ b/tests/probe_buttons_pos.gd @@ -17,7 +17,7 @@ func _rect_chain(n: Node) -> String: return " <- ".join(parts) func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main: Control = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_cache_keys.gd b/tests/probe_cache_keys.gd index fc518ab..44f728b 100644 --- a/tests/probe_cache_keys.gd +++ b/tests/probe_cache_keys.gd @@ -8,14 +8,14 @@ func _initialize() -> void: func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame await process_frame var main_glb: Array = main.get("glb_quellen") print("main.gd glb_quellen=%s" % str(main_glb)) - var store = load("res://src/viewport/glb_mesh_store.gd") + var store = load("res://core/viewport/glb_mesh_store.gd") var cache: Dictionary = store.get("_camo_tex_cache") for k in cache.keys(): print(" CACHE_KEY: '%s'" % str(k)) diff --git a/tests/probe_camo_render.gd b/tests/probe_camo_render.gd index 93fe840..382eb50 100644 --- a/tests/probe_camo_render.gd +++ b/tests/probe_camo_render.gd @@ -22,9 +22,9 @@ func _run() -> void: # GLB-Quelle = Client-Repo (wie im Spiel-Stand, t_c8748efc-Beweis). ProjectSettings.set_setting("scopedvr/editor/glb_quellen", ["../scopedvr-client/assets/objekte"]) - load("res://src/viewport/glb_mesh_store.gd").call("cache_leeren") + load("res://core/viewport/glb_mesh_store.gd").call("cache_leeren") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame @@ -46,7 +46,7 @@ func _run() -> void: # Zahlen-Beweis: JEDE GLB-Fläche trägt die GEMEINSAME Camo-Textur-Instanz. var builder = main.get("view_builder") - var store = load("res://src/viewport/glb_mesh_store.gd") + var store = load("res://core/viewport/glb_mesh_store.gd") var cache: Dictionary = store.get("_camo_tex_cache") print("EINE-QUELLE-CHECK: Cache-Größe=%d (soll 2: Objekt _1 + Boden _2)" % cache.size()) var alle_ok := true diff --git a/tests/probe_d1_walls_render.gd b/tests/probe_d1_walls_render.gd index b6eed6e..e160fa8 100644 --- a/tests/probe_d1_walls_render.gd +++ b/tests/probe_d1_walls_render.gd @@ -38,7 +38,7 @@ func _run() -> void: fehler.append("Editor-Bibliothek hat %d Wände statt 50" % walls) var builder := Node3D.new() - builder.set_script(load("res://src/viewport/map_view_builder.gd")) + builder.set_script(load("res://core/viewport/map_view_builder.gd")) root.add_child(builder) var doc: Dictionary = SvmapDocument.create_new("D1 Waende", 64.0, "mittag") doc["objects"] = PLATZ diff --git a/tests/probe_d2_barriers_render.gd b/tests/probe_d2_barriers_render.gd index d1c6b3d..c0a45ce 100644 --- a/tests/probe_d2_barriers_render.gd +++ b/tests/probe_d2_barriers_render.gd @@ -1,7 +1,7 @@ extends SceneTree ## D2-Renderprobe (Karte t_33250710): Map-Builder-Beweis — drei Absperrungen/ ## Hindernisse aus dem Military-Pack werden über den ECHTEN Editor-Viewport-Bauer -## (src/viewport/map_view_builder.gd) auf flachem Boden platziert, perspektivisch +## (core/viewport/map_view_builder.gd) auf flachem Boden platziert, perspektivisch ## gerendert und als PNG gespeichert (visuelle Prüfung: stehen die Objekte auf ## dem Boden?). Zusätzlich wird je Objekt gemessen: Unterkante vs. Bodenhöhe, ## Mesh-Größe vs. collision.size. @@ -45,7 +45,7 @@ func _run() -> void: root.add_child(vp) var builder := Node3D.new() - builder.set_script(load("res://src/viewport/map_view_builder.gd")) + builder.set_script(load("res://core/viewport/map_view_builder.gd")) vp.add_child(builder) builder.call("rebuild", _doku(), manifest) diff --git a/tests/probe_d3_buildings_render.gd b/tests/probe_d3_buildings_render.gd index ac6cc10..b071947 100644 --- a/tests/probe_d3_buildings_render.gd +++ b/tests/probe_d3_buildings_render.gd @@ -49,7 +49,7 @@ func _run() -> void: doc["objects"] = OBJEKTE builder = Node3D.new() - builder.set_script(load("res://src/viewport/map_view_builder.gd")) + builder.set_script(load("res://core/viewport/map_view_builder.gd")) root.add_child(builder) builder.call("rebuild", doc, manifest) await process_frame diff --git a/tests/probe_d4_mapbuilder.gd b/tests/probe_d4_mapbuilder.gd index 81e62e9..4305462 100644 --- a/tests/probe_d4_mapbuilder.gd +++ b/tests/probe_d4_mapbuilder.gd @@ -21,7 +21,7 @@ func _initialize() -> void: var doc: Dictionary = MapDocument.create_new("D4-Beweis", 256.0, "mittag") doc["objects"] = PLATZ - var bauer: Node3D = load("res://src/viewport/map_view_builder.gd").new() + var bauer: Node3D = load("res://core/viewport/map_view_builder.gd").new() root.add_child(bauer) await process_frame bauer.rebuild(doc, manifest) diff --git a/tests/probe_d6_mapbuilder.gd b/tests/probe_d6_mapbuilder.gd index de6e980..bd7f896 100644 --- a/tests/probe_d6_mapbuilder.gd +++ b/tests/probe_d6_mapbuilder.gd @@ -72,7 +72,7 @@ func _initialize() -> void: FileAccess.get_file_as_string("res://library/objects.json")) var doc: Dictionary = MapDocument.create_new("D6-Beweis", 256.0, "mittag") doc["objects"] = PLATZ - bauer = load("res://src/viewport/map_view_builder.gd").new() + bauer = load("res://core/viewport/map_view_builder.gd").new() vp.add_child(bauer) await process_frame bauer.rebuild(doc, manifest) diff --git a/tests/probe_drag_echt.gd b/tests/probe_drag_echt.gd index 6f3388a..4233a90 100644 --- a/tests/probe_drag_echt.gd +++ b/tests/probe_drag_echt.gd @@ -25,7 +25,7 @@ func _mouse(pos: Vector2, pressed: bool, motion := false) -> void: func _init() -> void: root.size = Vector2i(1600, 900) - var main: Control = (load("res://scenes/main.tscn") as PackedScene).instantiate() + var main: Control = (load("res://core/scenes/main.tscn") as PackedScene).instantiate() root.add_child(main) for i in 10: await process_frame diff --git a/tests/probe_getimg.gd b/tests/probe_getimg.gd index 60647b0..e32b0c4 100644 --- a/tests/probe_getimg.gd +++ b/tests/probe_getimg.gd @@ -12,7 +12,7 @@ func _initialize() -> void: func _run() -> void: - var gltf_mod := load("res://src/viewport/glb_mesh_store.gd") + var gltf_mod := load("res://core/viewport/glb_mesh_store.gd") var res = gltf_mod.call("_glb_mesh", PFAD) if res == null: print("FEHLER: _glb_mesh null") diff --git a/tests/probe_inspector_render.gd b/tests/probe_inspector_render.gd index caa9947..6b9d33b 100644 --- a/tests/probe_inspector_render.gd +++ b/tests/probe_inspector_render.gd @@ -10,7 +10,7 @@ func _initialize() -> void: func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_k1b_render.gd b/tests/probe_k1b_render.gd index 02d9fc5..7e903e4 100644 --- a/tests/probe_k1b_render.gd +++ b/tests/probe_k1b_render.gd @@ -60,7 +60,7 @@ func _in_frustum(p: Vector3) -> bool: return camera.is_position_in_frustum(p) func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_k1d_render.gd b/tests/probe_k1d_render.gd index f6652cc..a095243 100644 --- a/tests/probe_k1d_render.gd +++ b/tests/probe_k1d_render.gd @@ -70,7 +70,7 @@ func _lager_doc() -> Dictionary: func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_m3_partner_render.gd b/tests/probe_m3_partner_render.gd index 6984cce..13aa776 100644 --- a/tests/probe_m3_partner_render.gd +++ b/tests/probe_m3_partner_render.gd @@ -12,7 +12,7 @@ func _initialize() -> void: func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_m4_mirror_render.gd b/tests/probe_m4_mirror_render.gd index 079b7e7..bf246a5 100644 --- a/tests/probe_m4_mirror_render.gd +++ b/tests/probe_m4_mirror_render.gd @@ -11,7 +11,7 @@ extends SceneTree ## Positionen gespiegelt). Nur DER Beweis-Lauf nutzt die echte Code-Kette ## (BuildOps.place_mirrored / SpawnTool.spawn_mirror_add) — genau wie die Suite. -const SpawnTool := preload("res://src/editor/spawn_tool.gd") +const SpawnTool := preload("res://core/editor/spawn_tool.gd") const POINT := SymmetryCore.Mode.POINT @@ -50,7 +50,7 @@ func _initialize() -> void: print("BAU-TEILE: %d | SPAWN-STATUS: %s" % [BuildOps.piece_count(doc), str(spawn_res["status"])]) # --- Render --------------------------------------------------------------- - var bauer: Node3D = load("res://src/viewport/map_view_builder.gd").new() + var bauer: Node3D = load("res://core/viewport/map_view_builder.gd").new() root.add_child(bauer) await process_frame bauer.rebuild(doc, manifest) diff --git a/tests/probe_m5_symmetry_render.gd b/tests/probe_m5_symmetry_render.gd index 51622fc..3de423d 100644 --- a/tests/probe_m5_symmetry_render.gd +++ b/tests/probe_m5_symmetry_render.gd @@ -10,7 +10,7 @@ extends SceneTree ## ## Ausgabe: /tmp/m5_vorher.png, /tmp/m5_nachher.png + Prüfzeilen. -const SpawnToolScript := preload("res://src/editor/spawn_tool.gd") +const SpawnToolScript := preload("res://core/editor/spawn_tool.gd") const POINT := SymmetryCore.Mode.POINT @@ -20,7 +20,7 @@ func _initialize() -> void: _fill_asymmetric(doc) # --- VORHER rendern -------------------------------------------------------- - var bauer: Node3D = load("res://src/viewport/map_view_builder.gd").new() + var bauer: Node3D = load("res://core/viewport/map_view_builder.gd").new() root.add_child(bauer) await process_frame bauer.rebuild(doc, manifest) diff --git a/tests/probe_mal_weich_render.gd b/tests/probe_mal_weich_render.gd index aa9c2de..a26711d 100644 --- a/tests/probe_mal_weich_render.gd +++ b/tests/probe_mal_weich_render.gd @@ -31,7 +31,7 @@ func _run() -> void: TerrainField.apply_material_brush_mix(mats, mb, mw, mres, size, size, -15.0 + 30.0 * t, -10.0 + 8.0 * sin(t * 3.0), radius, 1, weich) var view := Node3D.new() - view.set_script(load("res://src/viewport/terrain_mesh.gd")) + view.set_script(load("res://core/viewport/terrain_mesh.gd")) root.add_child(view) view.call("set_mix", mb, mw) view.call("update_heights", heights, res, size, size, mats) diff --git a/tests/probe_multi_move.gd b/tests/probe_multi_move.gd index c92b7fd..07142d4 100644 --- a/tests/probe_multi_move.gd +++ b/tests/probe_multi_move.gd @@ -22,7 +22,7 @@ func _dist(a: Dictionary, b: Dictionary) -> float: func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_pack_tex_live.gd b/tests/probe_pack_tex_live.gd index 74c5b1b..d39b05a 100644 --- a/tests/probe_pack_tex_live.gd +++ b/tests/probe_pack_tex_live.gd @@ -3,7 +3,7 @@ extends SceneTree ## Erwartung: Palette 1024² fuer military_base, 2048² fuer picture_*. ## Lauf: /opt/data/home/bin/godot4 --headless --path . -s res://tests/probe_pack_tex_live.gd -const GlbMeshStore := preload("res://src/viewport/glb_mesh_store.gd") +const GlbMeshStore := preload("res://core/viewport/glb_mesh_store.gd") func _initialize() -> void: diff --git a/tests/probe_physik_subviewport.gd b/tests/probe_physik_subviewport.gd index 8cbfe9b..ec0f664 100644 --- a/tests/probe_physik_subviewport.gd +++ b/tests/probe_physik_subviewport.gd @@ -31,7 +31,7 @@ func _run() -> void: wand.position = Vector3(0, 1.5, -5) welt.add_child(wand) # PlaytestBody via Autopilot - var body: CharacterBody3D = load("res://src/editor/playtest/playtest_body.gd").new() + var body: CharacterBody3D = load("res://core/editor/playtest/playtest_body.gd").new() welt.add_child(body) body.auto_move_dir = Vector3(0, 0, -1) body.global_position = Vector3(0, 1.2, 5) diff --git a/tests/probe_playtest_comfort.gd b/tests/probe_playtest_comfort.gd index f78b01a..927e348 100644 --- a/tests/probe_playtest_comfort.gd +++ b/tests/probe_playtest_comfort.gd @@ -35,7 +35,7 @@ func _find_subvp(node: Node) -> SubViewport: func _run() -> void: DirAccess.make_dir_recursive_absolute("/opt/data/scopedvr/work/taaff5dcc_beweise") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_playtest_fps.gd b/tests/probe_playtest_fps.gd index cd8a9f5..c572c4c 100644 --- a/tests/probe_playtest_fps.gd +++ b/tests/probe_playtest_fps.gd @@ -19,7 +19,7 @@ func _initialize() -> void: func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame @@ -35,7 +35,7 @@ func _run() -> void: {"id": "tent_001", "pos": [-20.0, 0.0, -10.0], "rot_y_deg": 0.0, "scale": 1.0}, {"id": "box_006", "pos": [6.0, 0.0, 4.0], "rot_y_deg": 0.0, "scale": 1.0}, ] - var build_ops := load("res://src/editor/build_ops.gd") + var build_ops := load("res://core/editor/build_ops.gd") var teile: Array = [] for i in 24: var kind: String = ["wand", "boden", "tuer", "treppe"][i % 4] diff --git a/tests/probe_playtest_render.gd b/tests/probe_playtest_render.gd index 92b5d15..20022c7 100644 --- a/tests/probe_playtest_render.gd +++ b/tests/probe_playtest_render.gd @@ -42,7 +42,7 @@ func _press_key(code: Key) -> InputEventKey: func _run() -> void: DirAccess.make_dir_recursive_absolute("/opt/data/scopedvr/work/t1cdc_beweise") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_resize_shot.gd b/tests/probe_resize_shot.gd index b3ddc94..ec0d921 100644 --- a/tests/probe_resize_shot.gd +++ b/tests/probe_resize_shot.gd @@ -6,7 +6,7 @@ func _initialize() -> void: _run.call_deferred() func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main: Control = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_resize_size.gd b/tests/probe_resize_size.gd index 720e62a..5ae02ff 100644 --- a/tests/probe_resize_size.gd +++ b/tests/probe_resize_size.gd @@ -8,7 +8,7 @@ func _initialize() -> void: _run.call_deferred() func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main: Control = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_skybox_render.gd b/tests/probe_skybox_render.gd index 4b28829..cce15d5 100644 --- a/tests/probe_skybox_render.gd +++ b/tests/probe_skybox_render.gd @@ -26,7 +26,7 @@ func _run() -> void: FileAccess.get_file_as_string(SvmapIO.MANIFEST_PATH)) var builder := Node3D.new() - builder.set_script(load("res://src/viewport/map_view_builder.gd")) + builder.set_script(load("res://core/viewport/map_view_builder.gd")) root.add_child(builder) var bscript: Script = builder.get_script() var sky_pfad: String = bscript.panorama_sky_pfad() diff --git a/tests/probe_steppe_tiling.gd b/tests/probe_steppe_tiling.gd index 124fc96..1a86aa0 100644 --- a/tests/probe_steppe_tiling.gd +++ b/tests/probe_steppe_tiling.gd @@ -27,7 +27,7 @@ func _run() -> void: TerrainField.apply_material_brush_mix(mats, mb, mw, mres, size, size, -25.0 + 50.0 * t, -10.0 + 8.0 * sin(t * 3.0), 3.0, 1, 0.0) var view := Node3D.new() - view.set_script(load("res://src/viewport/terrain_mesh.gd")) + view.set_script(load("res://core/viewport/terrain_mesh.gd")) root.add_child(view) view.call("set_mix", mb, mw) view.call("update_heights", heights, res, size, size, mats) diff --git a/tests/probe_t1b_render.gd b/tests/probe_t1b_render.gd index 002e408..6091160 100644 --- a/tests/probe_t1b_render.gd +++ b/tests/probe_t1b_render.gd @@ -44,7 +44,7 @@ func _press_key(code: Key) -> InputEventKey: func _run() -> void: DirAccess.make_dir_recursive_absolute("/opt/data/scopedvr/work/t96e3_beweise") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_t_efb3d022_repro.gd b/tests/probe_t_efb3d022_repro.gd index 52a1666..3409d6d 100644 --- a/tests/probe_t_efb3d022_repro.gd +++ b/tests/probe_t_efb3d022_repro.gd @@ -23,7 +23,7 @@ func _run() -> void: cfg.set_value("library", "array_gruppe", PackedStringArray(["a", "b"])) cfg.save("user://scopedvr_editor.cfg") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main: Control = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_terrain_mirror_render.gd b/tests/probe_terrain_mirror_render.gd index 9e55f1f..cd28d1b 100644 --- a/tests/probe_terrain_mirror_render.gd +++ b/tests/probe_terrain_mirror_render.gd @@ -48,7 +48,7 @@ func _initialize() -> void: tmain.doc = doc tmain.history.begin(doc) var ttool := Node3D.new() - ttool.set_script(load("res://src/editor/terrain_tool.gd")) + ttool.set_script(load("res://core/editor/terrain_tool.gd")) ttool.setup(tmain, Camera3D.new(), null, null) ttool.call("activate") ttool.call("set_radius", 100.0) @@ -73,7 +73,7 @@ func _initialize() -> void: # --- Draufsicht rendern (unshaded Vertex-Farben + Höhenlinien) --- var view := Node3D.new() - view.set_script(load("res://src/viewport/terrain_mesh.gd")) + view.set_script(load("res://core/viewport/terrain_mesh.gd")) root.add_child(view) view.call("update_heights", heights, RES, SIZE, SIZE, got_mats) var cam := Camera3D.new() diff --git a/tests/probe_terrain_relief_render.gd b/tests/probe_terrain_relief_render.gd index 1f18c18..994d40d 100644 --- a/tests/probe_terrain_relief_render.gd +++ b/tests/probe_terrain_relief_render.gd @@ -108,7 +108,7 @@ func _hill_pit_field(res: int, size: float) -> PackedFloat32Array: func _render_topdown(heights: PackedFloat32Array, res: int, size: float, linien: bool) -> Image: var view := Node3D.new() - view.set_script(load("res://src/viewport/terrain_mesh.gd")) + view.set_script(load("res://core/viewport/terrain_mesh.gd")) root.add_child(view) view.call("update_heights", heights, res, size, size) view.call("set_contours", linien) diff --git a/tests/probe_tint_render.gd b/tests/probe_tint_render.gd index 6a55d33..2073563 100644 --- a/tests/probe_tint_render.gd +++ b/tests/probe_tint_render.gd @@ -30,9 +30,9 @@ func _run() -> void: # unterschiedliche Asset-Stände. ProjectSettings.set_setting("scopedvr/editor/glb_quellen", ["../scopedvr-client/assets/objekte"]) - load("res://src/viewport/glb_mesh_store.gd").call("cache_leeren") + load("res://core/viewport/glb_mesh_store.gd").call("cache_leeren") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_u2_scene_tree_render.gd b/tests/probe_u2_scene_tree_render.gd index 4501a4b..57be295 100644 --- a/tests/probe_u2_scene_tree_render.gd +++ b/tests/probe_u2_scene_tree_render.gd @@ -19,7 +19,7 @@ func _initialize() -> void: await process_frame await process_frame - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_u3_groups_render.gd b/tests/probe_u3_groups_render.gd index 0ed835c..65f9eb5 100644 --- a/tests/probe_u3_groups_render.gd +++ b/tests/probe_u3_groups_render.gd @@ -19,7 +19,7 @@ func _initialize() -> void: await process_frame await process_frame - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_u5_place_once_render.gd b/tests/probe_u5_place_once_render.gd index 71f3a0b..498a474 100644 --- a/tests/probe_u5_place_once_render.gd +++ b/tests/probe_u5_place_once_render.gd @@ -51,7 +51,7 @@ func _dismiss_dialogs() -> void: func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_u6_render.gd b/tests/probe_u6_render.gd index 1472b89..060428c 100644 --- a/tests/probe_u6_render.gd +++ b/tests/probe_u6_render.gd @@ -87,7 +87,7 @@ func _run() -> void: if modus.is_empty(): modus = "nachher" var material := SAND if OS.get_environment("U6_BODEN") != "fels" else FELS - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_u7_theme_render.gd b/tests/probe_u7_theme_render.gd index 859633f..5a54d72 100644 --- a/tests/probe_u7_theme_render.gd +++ b/tests/probe_u7_theme_render.gd @@ -38,7 +38,7 @@ func _run() -> void: dir = "/tmp/u7_beweise" DirAccess.make_dir_recursive_absolute(dir) var name := "u7_ui_%s.png" % str(OS.get_environment("U7_MODUS")) - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/probe_update_check.gd b/tests/probe_update_check.gd index 8b1cffe..a2bc344 100644 --- a/tests/probe_update_check.gd +++ b/tests/probe_update_check.gd @@ -6,7 +6,7 @@ func _initialize() -> void: _run.call_deferred() func _run() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main: Control = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/server_sektion_e2e.gd b/tests/server_sektion_e2e.gd index 12edf14..32c2ba2 100644 --- a/tests/server_sektion_e2e.gd +++ b/tests/server_sektion_e2e.gd @@ -29,7 +29,7 @@ func _initialize() -> void: fake.set_script(load("res://tests/support_fake_main.gd")) fake.doc = good_doc root.add_child(fake) - var panel: Control = load("res://src/ui/panels/server_panel.gd").new() + var panel: Control = load("res://core/ui/panels/server_panel.gd").new() panel.store_path = "user://test_e2e_store.dat" DirAccess.remove_absolute(ProjectSettings.globalize_path(panel.store_path)) panel.setup(fake) diff --git a/tests/test_assets_panel.gd b/tests/test_assets_panel.gd index dd2f356..68cf0e7 100644 --- a/tests/test_assets_panel.gd +++ b/tests/test_assets_panel.gd @@ -23,7 +23,7 @@ const GLB_QUELLEN_SETTING := "scopedvr/editor/glb_quellen" var failures := 0 var checks := 0 var main: Control -var assets # src/ui/panels/assets_panel.gd +var assets # core/ui/panels/assets_panel.gd var selected_count := 0 var activated_count := 0 @@ -34,7 +34,7 @@ func _initialize() -> void: func _run_all() -> void: _clear_library_cfg_section() - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() @@ -349,7 +349,7 @@ func _test_zuletzt_persistenz() -> void: main.queue_free() await process_frame await process_frame - main = (load("res://scenes/main.tscn") as PackedScene).instantiate() + main = (load("res://core/scenes/main.tscn") as PackedScene).instantiate() root.add_child(main) await process_frame await process_frame diff --git a/tests/test_build_spawn_mirror.gd b/tests/test_build_spawn_mirror.gd index d8f326e..c22d1ad 100644 --- a/tests/test_build_spawn_mirror.gd +++ b/tests/test_build_spawn_mirror.gd @@ -25,7 +25,7 @@ const AXIS_X := SymmetryCore.Mode.AXIS_X const AXIS_Z := SymmetryCore.Mode.AXIS_Z # spawn_tool.gd hat bewusst KEINEN class_name (Node-Werkzeug) — Statics via preload. -const SpawnTool := preload("res://src/editor/spawn_tool.gd") +const SpawnTool := preload("res://core/editor/spawn_tool.gd") func _init() -> void: diff --git a/tests/test_drag_bibliothek.gd b/tests/test_drag_bibliothek.gd index 3009cf3..7a0026c 100644 --- a/tests/test_drag_bibliothek.gd +++ b/tests/test_drag_bibliothek.gd @@ -35,7 +35,7 @@ func _mouse(pos: Vector2, pressed: bool, motion := false) -> void: func _init() -> void: - var main: Control = (load("res://scenes/main.tscn") as PackedScene).instantiate() + var main: Control = (load("res://core/scenes/main.tscn") as PackedScene).instantiate() root.add_child(main) await process_frame await process_frame diff --git a/tests/test_glb_view.gd b/tests/test_glb_view.gd index 539ea07..b70de89 100644 --- a/tests/test_glb_view.gd +++ b/tests/test_glb_view.gd @@ -313,7 +313,7 @@ func _proben_doc(oid: String, scale: float) -> Dictionary: func _test_viewport_rebuild_echt() -> void: print("Testgruppe: Viewport-Rebuild — echtes GLB im Editor-Viewport") var builder := Node3D.new() - builder.set_script(load("res://src/viewport/map_view_builder.gd")) + builder.set_script(load("res://core/viewport/map_view_builder.gd")) root.add_child(builder) # pos.y bewusst FALSCH (7 statt Terrainhöhe): der Marker steht am Doc- # Fußpunkt, die Mesh-UNTERKANTE muss trotzdem auf Terrainhöhe hängen. @@ -363,7 +363,7 @@ func _test_viewport_rebuild_fehlend() -> void: (manifest_fb["objects"] as Dictionary)[oid] = {"poly": 12, "collision": {"shape": "box", "size": [2.0, 1.0, 1.0]}} _check(GlbMeshStore.fehlt(oid), "fehlende OID erkannt (fehlt == true)") var builder := Node3D.new() - builder.set_script(load("res://src/viewport/map_view_builder.gd")) + builder.set_script(load("res://core/viewport/map_view_builder.gd")) root.add_child(builder) builder.call("rebuild", _proben_doc(oid, 1.0), manifest_fb) var marker: Node3D = (builder.get("object_markers") as Array)[0] diff --git a/tests/test_gui_smoke.gd b/tests/test_gui_smoke.gd index ca42952..8e7e14b 100644 --- a/tests/test_gui_smoke.gd +++ b/tests/test_gui_smoke.gd @@ -4,7 +4,7 @@ extends SceneTree ## Exit 0 = alles grün. ## ## ANDERS als die übrigen Tests instanziert dieser Test die ECHTE Main-UI -## (scenes/main.tscn → src/ui/main.gd) und deckt damit Runtime-UI-Pfade ab, +## (scenes/main.tscn → core/ui/main.gd) und deckt damit Runtime-UI-Pfade ab, ## die die logik-only-Suite nie sieht (GUI-Start-Befund 15.10.: Terrain-Preset- ## Crash beim Panel-Bau + `command_pressed`-Spam bei jeder Taste — beides ## headless unsichtbar, weil das UI nie instanziert wurde). @@ -26,7 +26,7 @@ func _initialize() -> void: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() diff --git a/tests/test_inspector.gd b/tests/test_inspector.gd index 7830ebf..146fe44 100644 --- a/tests/test_inspector.gd +++ b/tests/test_inspector.gd @@ -42,7 +42,7 @@ func _undo_steps_to_clear() -> int: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() @@ -66,7 +66,7 @@ func _run_all() -> void: main.call("_after_structure_change") main.history.clear() await process_frame - glb_ok = load("res://src/viewport/glb_mesh_store.gd").mesh_fuer("barrel_001") != null + glb_ok = load("res://core/viewport/glb_mesh_store.gd").mesh_fuer("barrel_001") != null # await PFLICHT: T4/T5/T8 enthalten process_frame-Awaits — ohne await # lief _finish() sofort durch und die Mehrfach-Checks liefen NIEMALS diff --git a/tests/test_library.gd b/tests/test_library.gd index 20ae1cb..0c6eaa1 100644 --- a/tests/test_library.gd +++ b/tests/test_library.gd @@ -87,7 +87,7 @@ func _test_manifest_load() -> void: # Thumb) zeigt einen nicht gelaufenen/abgebrochenen Sync. var fehlen_thumb: Array = [] var verwaist_thumb: Array = [] - var tdir := DirAccess.open("res://library/thumbs") + var tdir := DirAccess.open("res://core/thumbs") if tdir != null: var thumbs: Dictionary = {} tdir.list_dir_begin() @@ -538,7 +538,7 @@ func _test_ghost_matches_placement() -> void: cam.current = true cam.look_at_from_position(Vector3(-95.0, 115.0, 135.0), Vector3.ZERO, Vector3.UP) var interaction := Node3D.new() - interaction.set_script(load("res://src/editor/interaction.gd")) + interaction.set_script(load("res://core/editor/interaction.gd")) vp.add_child(interaction) interaction.setup(fake, cam, null) interaction.set("place_oid", "box_001") diff --git a/tests/test_library_browser_ui.gd b/tests/test_library_browser_ui.gd index 717e431..3e93405 100644 --- a/tests/test_library_browser_ui.gd +++ b/tests/test_library_browser_ui.gd @@ -25,7 +25,7 @@ func _initialize() -> void: func _run_all() -> void: _clear_library_cfg_section() - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() @@ -198,7 +198,7 @@ func _test_persistence() -> void: main.queue_free() await process_frame await process_frame - main = (load("res://scenes/main.tscn") as PackedScene).instantiate() + main = (load("res://core/scenes/main.tscn") as PackedScene).instantiate() root.add_child(main) await process_frame await process_frame diff --git a/tests/test_loadout.gd b/tests/test_loadout.gd index cd8644d..c589688 100644 --- a/tests/test_loadout.gd +++ b/tests/test_loadout.gd @@ -65,7 +65,7 @@ func _test_katalog() -> void: func _test_panel() -> void: print("Testgruppe: Panel") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/test_mal_hinweis.gd b/tests/test_mal_hinweis.gd index b9a7d17..ed2f334 100644 --- a/tests/test_mal_hinweis.gd +++ b/tests/test_mal_hinweis.gd @@ -7,7 +7,7 @@ var checks := 0 func _initialize() -> void: - var panel = load("res://src/ui/panels/terrain_panel.gd") + var panel = load("res://core/ui/panels/terrain_panel.gd") _check(panel != null, "terrain_panel.gd lädt ohne Parse-Fehler") var t: String = panel.paint_hint_text({"resolution": 129, "size_x_m": 256.0, "size_z_m": 256.0}) _check(t.contains("2 m"), "256 m / 129 Punkte → feinste Einheit 2 m (%s)" % t) diff --git a/tests/test_map_tint.gd b/tests/test_map_tint.gd index b09d6d2..c84585f 100644 --- a/tests/test_map_tint.gd +++ b/tests/test_map_tint.gd @@ -57,7 +57,7 @@ func _marker_mi(idx: int) -> MeshInstance3D: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() diff --git a/tests/test_modus.gd b/tests/test_modus.gd index 30d4619..561b2fd 100644 --- a/tests/test_modus.gd +++ b/tests/test_modus.gd @@ -66,7 +66,7 @@ func _run_all() -> void: _check(not ModusKatalog.validate(bad, bad["bounds"]).is_empty(), "unbekannter Modus ungültig (V21)") print("Testgruppe: Neu-Dialog") - var dlg: ConfirmationDialog = preload("res://src/ui/new_map_dialog.gd").new() + var dlg: ConfirmationDialog = preload("res://core/ui/new_map_dialog.gd").new() root.add_child(dlg) _check(dlg.get_game_mode() == "tdm", "Dialog-Default TDM") dlg.mode_option.select(1) @@ -77,7 +77,7 @@ func _run_all() -> void: _check(dlg.get_game_mode() == "dm", "Dialog liefert Deathmatch") print("Testgruppe: Panel") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/test_object_mirror.gd b/tests/test_object_mirror.gd index b76e008..6dfb1b0 100644 --- a/tests/test_object_mirror.gd +++ b/tests/test_object_mirror.gd @@ -310,7 +310,7 @@ func _make_interaction(doc: Dictionary, sym_mode: int, vp: SubViewport, var builder := ProbeBuilder.new() builder.sync_markers(doc) var interaction := Node3D.new() - interaction.set_script(load("res://src/editor/interaction.gd")) + interaction.set_script(load("res://core/editor/interaction.gd")) vp.add_child(interaction) interaction.setup(fake, cam, builder) return interaction @@ -514,7 +514,7 @@ func _test_partner_marking() -> void: print("== Partner-Markierung (echter Viewport-Bauer) ==") var doc := _pair_doc(SymmetryCore.Mode.POINT, [100.0, 0.0, 40.0], 30.0) var builder := Node3D.new() - builder.set_script(load("res://src/viewport/map_view_builder.gd")) + builder.set_script(load("res://core/viewport/map_view_builder.gd")) root.add_child(builder) var manifest := {"objects": {"box_001": {"collision": {"shape": "box", "size": [1.2, 1.2, 1.2]}}}} builder.call("rebuild", doc, manifest) diff --git a/tests/test_orbit_camera.gd b/tests/test_orbit_camera.gd index a0f314c..bd68edf 100644 --- a/tests/test_orbit_camera.gd +++ b/tests/test_orbit_camera.gd @@ -40,7 +40,7 @@ func _initialize() -> void: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() diff --git a/tests/test_pinsel_werkzeuge.gd b/tests/test_pinsel_werkzeuge.gd index 5d55cdd..5f68427 100644 --- a/tests/test_pinsel_werkzeuge.gd +++ b/tests/test_pinsel_werkzeuge.gd @@ -63,7 +63,7 @@ func _druck() -> void: _check(is_equal_approx(TerrainField.pressure_of(0.0, 0.6), 0.6), "Trigger") _check(TerrainField.pressure_of(0.001, 0.0) == 0.05 or TerrainField.pressure_of(0.001, 0.0) == 1.0, "Minimum begrenzt") var t := Node3D.new() - t.set_script(load("res://src/editor/terrain_tool.gd")) + t.set_script(load("res://core/editor/terrain_tool.gd")) t.set_pressure(0.5) var a: float = t.call("_step_amount", TerrainField.Mode.RAISE, 1.0) t.set_pressure(1.0) diff --git a/tests/test_place_once.gd b/tests/test_place_once.gd index 24383e3..098ffda 100644 --- a/tests/test_place_once.gd +++ b/tests/test_place_once.gd @@ -34,7 +34,7 @@ func _initialize() -> void: func _run_all() -> void: _clear_library_cfg_section() - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() @@ -352,7 +352,7 @@ func _test_probe_auswahl_stabil() -> void: cam.look_at_from_position(Vector3(-95.0, 115.0, 135.0), Vector3.ZERO, Vector3.UP) var builder := ProbeBuilder.new() var interaction := Node3D.new() - interaction.set_script(load("res://src/editor/interaction.gd")) + interaction.set_script(load("res://core/editor/interaction.gd")) vp.add_child(interaction) interaction.setup(fake, cam, builder) @@ -370,7 +370,7 @@ func _test_probe_auswahl_stabil() -> void: "Probe: letzte Meldung sagt „ausgewählt“ (%s)" % str(fake.statuses.back() if not fake.statuses.is_empty() else "")) # Serienmodus-Gegenprobe: mit Shift bleibt das Werkzeug an. var inter2 := Node3D.new() - inter2.set_script(load("res://src/editor/interaction.gd")) + inter2.set_script(load("res://core/editor/interaction.gd")) vp.add_child(inter2) var doc2 := SvmapDocument.create_new("U5Test2", 1024.0, "mittag") var fake2 := ProbeMain.new() diff --git a/tests/test_playtest.gd b/tests/test_playtest.gd index 2e94dce..23c5c4f 100644 --- a/tests/test_playtest.gd +++ b/tests/test_playtest.gd @@ -31,7 +31,7 @@ func _initialize() -> void: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() diff --git a/tests/test_playtest_avatar.gd b/tests/test_playtest_avatar.gd index c0ce2b1..6f3b850 100644 --- a/tests/test_playtest_avatar.gd +++ b/tests/test_playtest_avatar.gd @@ -265,7 +265,7 @@ func _test_perspektive_und_kamera(avatar: Node3D) -> void: _check(not PlaytestSettings.load_third(), "Default = First Person (persistiert false)") # Leichter Body ohne Avatar (graceful Fallback, kein Crash). - var body_leer: CharacterBody3D = load("res://src/editor/playtest/playtest_body.gd").new() + var body_leer: CharacterBody3D = load("res://core/editor/playtest/playtest_body.gd").new() var boden := StaticBody3D.new() var boden_form := CollisionShape3D.new() var boden_box := BoxShape3D.new() @@ -281,7 +281,7 @@ func _test_perspektive_und_kamera(avatar: Node3D) -> void: _check(not bool(body_leer.get("perspektive_dritte")), "Ohne Avatar: Zustand bleibt First") # Mit Avatar: V schaltet, Third zeigt Körper, SpringArm-Kamera übernimmt. - var body: CharacterBody3D = load("res://src/editor/playtest/playtest_body.gd").new() + var body: CharacterBody3D = load("res://core/editor/playtest/playtest_body.gd").new() root.add_child(body) body.position = Vector3(0.0, 1.0, 0.0) await physics_frame @@ -362,7 +362,7 @@ func _test_perspektive_und_kamera(avatar: Node3D) -> void: func _test_integration_playtest() -> void: print("Testgruppe: Integration — enter() baut Avatar, Gait aus echter Bewegung") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main: Control = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/test_playtest_comfort.gd b/tests/test_playtest_comfort.gd index d7407a5..8501ce2 100644 --- a/tests/test_playtest_comfort.gd +++ b/tests/test_playtest_comfort.gd @@ -28,7 +28,7 @@ func _initialize() -> void: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() @@ -56,7 +56,7 @@ func _run_all() -> void: PlaytestSettings.save_sens(1.0) # Einstellungen-Panel ist über die Registry im Baum (Haupttest der Anbindung). - var registry_script: GDScript = load("res://src/ui/panels/registry.gd") + var registry_script: GDScript = load("res://core/ui/panels/registry.gd") var entry: Dictionary = registry_script.entry("einstellungen") _check(not entry.is_empty(), "Registry: Eintrag 'einstellungen' vorhanden") var panel: Node = main.find_child("einstellungen", true, false) diff --git a/tests/test_playtest_identitaet.gd b/tests/test_playtest_identitaet.gd index b946183..f0464ba 100644 --- a/tests/test_playtest_identitaet.gd +++ b/tests/test_playtest_identitaet.gd @@ -57,7 +57,7 @@ func _run() -> void: var welt := Node3D.new() vp.add_child(welt) welt.add_child(KolliderBau.baue_welt_kollider(doc)) - var body: CharacterBody3D = load("res://src/editor/playtest/playtest_body.gd").new() + var body: CharacterBody3D = load("res://core/editor/playtest/playtest_body.gd").new() welt.add_child(body) body.call("set_terrain", doc) await physics_frame diff --git a/tests/test_playtest_spawn.gd b/tests/test_playtest_spawn.gd index ef709d1..235be21 100644 --- a/tests/test_playtest_spawn.gd +++ b/tests/test_playtest_spawn.gd @@ -27,7 +27,7 @@ func _initialize() -> void: func _run_all() -> void: # Sauberer Sidecar-Start (Suite darf von früheren Läufen nichts erben). TestStartStore.clear_point("") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() diff --git a/tests/test_pointer_router.gd b/tests/test_pointer_router.gd index 9bd315d..355155d 100644 --- a/tests/test_pointer_router.gd +++ b/tests/test_pointer_router.gd @@ -45,7 +45,7 @@ func _run() -> void: func _neu() -> Control: - var main: Control = (load("res://scenes/main.tscn") as PackedScene).instantiate() + var main: Control = (load("res://core/scenes/main.tscn") as PackedScene).instantiate() root.add_child(main) await process_frame await process_frame diff --git a/tests/test_resize_dialog.gd b/tests/test_resize_dialog.gd index beeea68..9f9bb6e 100644 --- a/tests/test_resize_dialog.gd +++ b/tests/test_resize_dialog.gd @@ -50,7 +50,7 @@ func _check(cond: bool, label: String) -> void: # --------------------------------------------------------------- Dialog ----- func _make_dialog() -> ConfirmationDialog: - var dlg: ConfirmationDialog = preload("res://src/ui/resize_map_dialog.gd").new() + var dlg: ConfirmationDialog = preload("res://core/ui/resize_map_dialog.gd").new() return dlg @@ -168,7 +168,7 @@ func _test_preview_texts() -> void: func _test_main_wiring() -> void: print("Testgruppe: main.gd-Verdrahtung + Undo-Roundtrip") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: return diff --git a/tests/test_rmb_vorrang.gd b/tests/test_rmb_vorrang.gd index 13e422f..de7dfac 100644 --- a/tests/test_rmb_vorrang.gd +++ b/tests/test_rmb_vorrang.gd @@ -26,7 +26,7 @@ func _initialize() -> void: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() diff --git a/tests/test_scene_groups.gd b/tests/test_scene_groups.gd index f36be19..4d22208 100644 --- a/tests/test_scene_groups.gd +++ b/tests/test_scene_groups.gd @@ -34,7 +34,7 @@ func _check(cond: bool, what: String) -> void: func _init() -> void: print("Testgruppe: Gruppen im Szenen-Baum (U3)") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/test_scene_tree.gd b/tests/test_scene_tree.gd index 0e9ecff..7407243 100644 --- a/tests/test_scene_tree.gd +++ b/tests/test_scene_tree.gd @@ -29,7 +29,7 @@ func _check(cond: bool, what: String) -> void: func _init() -> void: print("Testgruppe: Szenen-Baum links (U2 Zwei-Wege-Auswahl)") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame diff --git a/tests/test_selection_look.gd b/tests/test_selection_look.gd index 4557210..2ba606b 100644 --- a/tests/test_selection_look.gd +++ b/tests/test_selection_look.gd @@ -53,7 +53,7 @@ func _obj(id: String, pos: Array, rot := 0.0) -> Dictionary: func _build(manifest: Dictionary, doc: Dictionary) -> Node3D: var builder := Node3D.new() - builder.set_script(load("res://src/viewport/map_view_builder.gd")) + builder.set_script(load("res://core/viewport/map_view_builder.gd")) root.add_child(builder) builder.call("rebuild", doc, manifest) return builder @@ -95,7 +95,7 @@ func _restlos(builder: Node3D, label: String) -> void: # ------------------------------------------------------------------ T1 ------ func _test_theme_quelle() -> void: print("== T1 Theme als einzige Quelle ==") - var theme_res: Variant = load("res://theme/editor_theme.tres") + var theme_res: Variant = load("res://core/theme/editor_theme.tres") _check(theme_res is Theme, "Theme lädt") if not (theme_res is Theme): return @@ -250,7 +250,7 @@ func _test_spawn_ring() -> void: if ring is MeshInstance3D: _check((ring as MeshInstance3D).mesh is TorusMesh, "Ring = schmaler Torus am Zonenrand") var rmat := (ring as MeshInstance3D).material_override as StandardMaterial3D - var theme_res: Variant = load("res://theme/editor_theme.tres") + var theme_res: Variant = load("res://core/theme/editor_theme.tres") var soll: Color = (theme_res as Theme).get_color("selection_outline", "Editor") _check(rmat.albedo_color.is_equal_approx(soll), "Ring-Farbe kommt aus dem Theme") var disc1 := marker.get_child(0) as MeshInstance3D diff --git a/tests/test_server_sektion.gd b/tests/test_server_sektion.gd index 5f84e29..a39b524 100644 --- a/tests/test_server_sektion.gd +++ b/tests/test_server_sektion.gd @@ -60,7 +60,7 @@ func _initialize() -> void: _check(AdminTexte.sperrdauer_text(0) == "dauerhaft" and AdminTexte.sperrdauer_text(90) == "1 Stunden" or true, "Sperrdauer-Text") # Panel baut sich (ohne Server) - var panel: Control = load("res://src/ui/panels/server_panel.gd").new() + var panel: Control = load("res://core/ui/panels/server_panel.gd").new() var fake := Control.new() fake.set_script(load("res://tests/support_fake_main.gd")) root.add_child(fake) @@ -71,7 +71,7 @@ func _initialize() -> void: await process_frame _check(panel.find_child("AdminClient", true, false) != null, "Panel baut sich, Client hängt dran") _check(not panel.connected, "anfangs nicht verbunden") - var spec: Dictionary = panel.call("spec") if panel.has_method("spec") else load("res://src/ui/panels/server_panel.gd").spec() + var spec: Dictionary = panel.call("spec") if panel.has_method("spec") else load("res://core/ui/panels/server_panel.gd").spec() _check(spec["titel"] == "Server" and spec["gruppe"] == "rechts", "Registry-spec") # Neustart: Server kommt nicht zurück -> verständliche Meldung statt ewig warten diff --git a/tests/test_shortcuts.gd b/tests/test_shortcuts.gd index 6162d28..abeb617 100644 --- a/tests/test_shortcuts.gd +++ b/tests/test_shortcuts.gd @@ -248,7 +248,7 @@ func _test_fly_key_conflicts() -> void: "heightmap_r16_b64": TerrainField.encode(flat, 0.0, 10.0), }} var ttool := Node3D.new() - ttool.set_script(load("res://src/editor/terrain_tool.gd")) + ttool.set_script(load("res://core/editor/terrain_tool.gd")) root.add_child(ttool) ttool.setup(tfake, Camera3D.new(), ProbeBuilder.new(), null) _check(bool(ttool.call("activate")), "Terrain-Werkzeug aktiviert (Test-Map)") @@ -443,7 +443,7 @@ func _test_multi_delete() -> void: var builder := ProbeBuilder.new() vp.add_child(builder) var interaction := Node3D.new() - interaction.set_script(load("res://src/editor/interaction.gd")) + interaction.set_script(load("res://core/editor/interaction.gd")) vp.add_child(interaction) interaction.setup(fake, cam, builder) @@ -478,7 +478,7 @@ func _test_multi_delete() -> void: # Mausrad-Block im Flugmodus: wheel_blocked meldet Kamera-Vorrang. var orbit := Camera3D.new() - orbit.set_script(load("res://src/viewport/orbit_camera.gd")) + orbit.set_script(load("res://core/viewport/orbit_camera.gd")) vp.add_child(orbit) interaction.set("camera", orbit) _check(not bool(interaction.call("wheel_blocked")), "Orbit + Auswahl: Mausrad dreht Objekt (normal)") @@ -513,7 +513,7 @@ func _test_focus_center() -> void: func _test_camera_fly_roundtrip() -> void: print("Testgruppe: Freelook-Flug an/aus (orbit_camera, kein Positions-Sprung)") var cam := Camera3D.new() - cam.set_script(load("res://src/viewport/orbit_camera.gd")) + cam.set_script(load("res://core/viewport/orbit_camera.gd")) root.add_child(cam) cam.set("target", Vector3.ZERO) cam.set("distance", 100.0) @@ -643,7 +643,7 @@ func _make_interaction(doc: Dictionary, markers: int) -> Array: m.set_meta("half_height", 1.0) builder.object_markers.append(m) var interaction := Node3D.new() - interaction.set_script(load("res://src/editor/interaction.gd")) + interaction.set_script(load("res://core/editor/interaction.gd")) vp.add_child(interaction) interaction.setup(fake, cam, builder) return [fake, interaction, builder] @@ -853,7 +853,7 @@ func _test_grab() -> void: func _test_brush_paint_mode() -> void: print("Testgruppe: Terrain-Pinsel — Modus 3 (Malen) kommt durch set_brush_mode") var tool := Node3D.new() - tool.set_script(load("res://src/editor/terrain_tool.gd")) + tool.set_script(load("res://core/editor/terrain_tool.gd")) root.add_child(tool) tool.call("set_brush_mode", TerrainField.Mode.PAINT) _check(int(tool.get("brush_mode")) == TerrainField.Mode.PAINT, diff --git a/tests/test_skybox.gd b/tests/test_skybox.gd index fab053f..600ad88 100644 --- a/tests/test_skybox.gd +++ b/tests/test_skybox.gd @@ -31,7 +31,7 @@ func _check(cond: bool, label: String) -> void: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() diff --git a/tests/test_spawn_yaw.gd b/tests/test_spawn_yaw.gd index 6a732a3..b5519a1 100644 --- a/tests/test_spawn_yaw.gd +++ b/tests/test_spawn_yaw.gd @@ -41,7 +41,7 @@ func _init() -> void: var doc2 := SvmapDocument.create_new("Blick2", 512.0, "mittag") var a := SpawnOps.add_zone(doc2, 0, -40.0, 10.0) SpawnOps.write_yaw(a, 30.0) - var tool_script := load("res://src/editor/spawn_tool.gd") + var tool_script := load("res://core/editor/spawn_tool.gd") tool_script.spawn_mirror_add(doc2, 0, str(a["id"]), SymmetryCore.Mode.POINT) var twin_id: String = tool_script.spawn_mirror_partner(doc2, str(a["id"])) var twin: Dictionary = tool_script._spawn_point_of(doc2, 1, twin_id) diff --git a/tests/test_symmetry_onclick.gd b/tests/test_symmetry_onclick.gd index cbb249b..e5d75d0 100644 --- a/tests/test_symmetry_onclick.gd +++ b/tests/test_symmetry_onclick.gd @@ -10,7 +10,7 @@ var failures := 0 var checks := 0 ## spawn_tool.gd bewusst OHNE class_name (M4-Entscheidung) → preload. -const SpawnToolScript := preload("res://src/editor/spawn_tool.gd") +const SpawnToolScript := preload("res://core/editor/spawn_tool.gd") func _init() -> void: @@ -323,7 +323,7 @@ func _make_panel(doc: Dictionary, mode: int) -> VBoxContainer: probe.sym_mode = mode probe.history.begin(doc) var panel := VBoxContainer.new() - panel.set_script(load("res://src/ui/panels/symmetry_panel.gd")) + panel.set_script(load("res://core/ui/panels/symmetry_panel.gd")) root.add_child(panel) panel.setup(probe) panel.call("build") diff --git a/tests/test_terrain.gd b/tests/test_terrain.gd index bee84a1..3f0d2d4 100644 --- a/tests/test_terrain.gd +++ b/tests/test_terrain.gd @@ -425,7 +425,7 @@ func _test_live_material_colors() -> void: # --- a) Live-Stroke am Mesh: update_heights OHNE mats (exakter Bug-Pfad) --- var view := Node3D.new() - view.set_script(load("res://src/viewport/terrain_mesh.gd")) + view.set_script(load("res://core/viewport/terrain_mesh.gd")) view.call("update_heights", heights, res, size, size, mats) # Vollrebuild mit Schicht var sand_seen := false for frame in 5: @@ -468,7 +468,7 @@ func _test_live_material_colors() -> void: tmain.doc = doc var builder := ToolBuilder.new() var ttool := Node3D.new() - ttool.set_script(load("res://src/editor/terrain_tool.gd")) + ttool.set_script(load("res://core/editor/terrain_tool.gd")) # Bewusst NICHT in den Baum: sonst feuert Godots automatisches _process # zwischen den manuellen Calls und der Live-Update-Zähler wäre fragil. ttool.setup(tmain, Camera3D.new(), builder, null) @@ -492,7 +492,7 @@ func _test_live_material_colors() -> void: # --- c) Legacy: nie gesehene Schicht → alles Gras (kein Phantom-Cache) --- var view2 := Node3D.new() - view2.set_script(load("res://src/viewport/terrain_mesh.gd")) + view2.set_script(load("res://core/viewport/terrain_mesh.gd")) var flat := PackedFloat32Array() flat.resize(res * res) view2.call("update_heights", flat, res, size, size) # OHNE Schicht, Cache leer @@ -515,7 +515,7 @@ func _test_live_material_colors() -> void: func _test_mesh_winding_live_grid() -> void: print("Testgruppe: Terrain-Mesh (Winding/Normale/Erster Pinselkontakt)") var view := Node3D.new() - view.set_script(load("res://src/viewport/terrain_mesh.gd")) + view.set_script(load("res://core/viewport/terrain_mesh.gd")) var res := 33 var size := 320.0 var heights := PackedFloat32Array() @@ -589,7 +589,7 @@ func _test_mesh_winding_live_grid() -> void: func _test_grid_toggle() -> void: print("Testgruppe: Gitter-Toggle (map_view_builder)") var builder := Node3D.new() - builder.set_script(load("res://src/viewport/map_view_builder.gd")) + builder.set_script(load("res://core/viewport/map_view_builder.gd")) var doc := SvmapDocument.create_new("Gitter", 1024.0, "mittag") builder.call("rebuild", doc, {}) var grid = builder.get("grid_node") @@ -629,7 +629,7 @@ func _test_ray_terrain_mapping() -> void: # --- Mesh-Vertices == Dokument-Konvention (die eigentliche Root-Cause) --- var view := Node3D.new() - view.set_script(load("res://src/viewport/terrain_mesh.gd")) + view.set_script(load("res://core/viewport/terrain_mesh.gd")) view.call("update_heights", heights, res, size, size) var mi = view.get("_mi") var pos: PackedVector3Array = (mi.mesh.surface_get_arrays(0))[Mesh.ARRAY_VERTEX] @@ -804,7 +804,7 @@ func _test_relief_shading() -> void: for i in heights.size(): heights[i] = 10.0 if (i % res) >= res / 2 else 0.0 var view := Node3D.new() - view.set_script(load("res://src/viewport/terrain_mesh.gd")) + view.set_script(load("res://core/viewport/terrain_mesh.gd")) view.call("update_heights", heights, res, 320.0, 320.0) var mi = view.get("_mi") var col: PackedColorArray = (mi.mesh.surface_get_arrays(0))[Mesh.ARRAY_COLOR] @@ -842,7 +842,7 @@ func _test_relief_shading() -> void: var flat := PackedFloat32Array() flat.resize(res * res) var view2 := Node3D.new() - view2.set_script(load("res://src/viewport/terrain_mesh.gd")) + view2.set_script(load("res://core/viewport/terrain_mesh.gd")) view2.call("update_heights", flat, res, 320.0, 320.0) var mat2 = (view2.get("_mi") as MeshInstance3D).material_override _check(mat2 is ShaderMaterial, "Höhenlinien: Kontur-Shader aktiv (Editor-only)") @@ -851,7 +851,7 @@ func _test_relief_shading() -> void: view2.call("set_contours", false) view2.free() var view3 := Node3D.new() - view3.set_script(load("res://src/viewport/terrain_mesh.gd")) + view3.set_script(load("res://core/viewport/terrain_mesh.gd")) view3.call("update_heights", heights, res, 320.0, 320.0) # Stufe = 10 m Relief var mat3 = (view3.get("_mi") as MeshInstance3D).material_override _check(float(mat3.get_shader_parameter("linien_an")) == 1.0, @@ -872,7 +872,7 @@ func _relief_color(mat_id: int, h: float, hmin: float, hmax: float, normal: Vector3) -> Color: if _relief_helper == null or not is_instance_valid(_relief_helper): _relief_helper = Node3D.new() - _relief_helper.set_script(load("res://src/viewport/terrain_mesh.gd")) + _relief_helper.set_script(load("res://core/viewport/terrain_mesh.gd")) return _relief_helper.call("relief_color", mat_id, h, hmin, hmax, normal) diff --git a/tests/test_terrain_mirror.gd b/tests/test_terrain_mirror.gd index c7c54d9..f73f5ad 100644 --- a/tests/test_terrain_mirror.gd +++ b/tests/test_terrain_mirror.gd @@ -123,7 +123,7 @@ func _make_tool(sym: int) -> Array: tmain.history.begin(doc) var builder := ToolBuilder.new() var ttool := Node3D.new() - ttool.set_script(load("res://src/editor/terrain_tool.gd")) + ttool.set_script(load("res://core/editor/terrain_tool.gd")) ttool.setup(tmain, Camera3D.new(), builder, null) var activated: bool = ttool.call("activate") _check(activated, "terrain_tool aktiviert (Sym-Modus %d)" % sym) diff --git a/tests/test_theme.gd b/tests/test_theme.gd index 4e60b70..c1196a1 100644 --- a/tests/test_theme.gd +++ b/tests/test_theme.gd @@ -10,12 +10,12 @@ extends SceneTree ## Splitter-Anfassen (grabber_area), Scrollbars, Tooltip + die Farb-Token ## (accent, status_ok/error, muted, field, title, warning). ## 3. KEINE hartkodierten Farben im Code: Suche nach "Color(" in -## src/ui/panels/*.gd, src/ui/main.gd, src/ui/inspector_panel.gd. +## core/ui/panels/*.gd, core/ui/main.gd, core/ui/inspector_panel.gd. ## 4. Alle Knöpfe (Button/MenuButton/CheckBox) haben einen Tooltip. ## 5. Typografie-Raster: Überschrift > Body > Nebentext, alles über UIScale. ## 6. Fenstertitel zeigt ungespeicherte Änderungen an (U7 Kleinigkeit). -const UIScale := preload("res://src/ui/ui_scale.gd") +const UIScale := preload("res://core/ui/ui_scale.gd") var failures := 0 var checks := 0 @@ -45,7 +45,7 @@ func _finish() -> void: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn laedt") if scene == null: _finish() @@ -72,7 +72,7 @@ func _test_theme_set() -> void: _check(main.theme != null, "main.theme gesetzt") if main.theme == null: return - var theme_file: Theme = load("res://theme/editor_theme.tres") + var theme_file: Theme = load("res://core/theme/editor_theme.tres") _check(main.theme == theme_file, "main nutzt theme/editor_theme.tres (eine Farbquelle)") _check(int(main.theme.default_font_size) == UIScale.font_size(), @@ -113,22 +113,22 @@ func _test_theme_content() -> void: ## 3) Keine Farbwerte mehr im Code — alles kommt aus dem Theme. -## Scan: src/ui/panels/*.gd (verbindlich) + main.gd + inspector_panel.gd. +## Scan: core/ui/panels/*.gd (verbindlich) + main.gd + inspector_panel.gd. ## Achtung: nur "Color(" (Konstruktor) zählt — theme_color()/-> Color: sind ## Schlüsselwörter, keine Farbwerte. func _test_no_hardcoded_colors() -> void: print("Testgruppe: keine hartkodierten Farben im Code") var dateien: Array = [] - var dir := DirAccess.open("res://src/ui/panels") + var dir := DirAccess.open("res://core/ui/panels") if dir != null: dir.list_dir_begin() var fname := dir.get_next() while not fname.is_empty(): if fname.ends_with(".gd"): - dateien.append("res://src/ui/panels/" + fname) + dateien.append("res://core/ui/panels/" + fname) fname = dir.get_next() - dateien.append("res://src/ui/main.gd") - dateien.append("res://src/ui/inspector_panel.gd") + dateien.append("res://core/ui/main.gd") + dateien.append("res://core/ui/inspector_panel.gd") _check(dateien.size() > 5, "Farb-Scan: %d Skripte gefunden" % dateien.size()) var farb_dateien := 0 for pfad in dateien: diff --git a/tests/test_ui_aufraeumen.gd b/tests/test_ui_aufraeumen.gd index 69cde7c..3aa526e 100644 --- a/tests/test_ui_aufraeumen.gd +++ b/tests/test_ui_aufraeumen.gd @@ -13,7 +13,7 @@ func _initialize() -> void: func _run() -> void: - main = (load("res://scenes/main.tscn") as PackedScene).instantiate() + main = (load("res://core/scenes/main.tscn") as PackedScene).instantiate() root.add_child(main) await process_frame await process_frame diff --git a/tests/test_ui_layout.gd b/tests/test_ui_layout.gd index 1bc8b73..e160557 100644 --- a/tests/test_ui_layout.gd +++ b/tests/test_ui_layout.gd @@ -1,6 +1,6 @@ extends SceneTree ## test_ui_layout (Karte t_eaccbfed, U1 UI-Fundament): prüft das Unity-artige -## Layout, das AUSSCHLIESSLICH aus der Registry (src/ui/panels/registry.gd) +## Layout, das AUSSCHLIESSLICH aus der Registry (core/ui/panels/registry.gd) ## gebaut wird. ## ## Geprüft wird: @@ -36,7 +36,7 @@ func _count_named(node: Node, wanted: String) -> int: func _init() -> void: print("Testgruppe: Layout aus der Registry") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") var main: Control = scene.instantiate() root.add_child(main) await process_frame @@ -67,7 +67,7 @@ func _init() -> void: "Mittelbereich hat echte Höhe (%.0f px, min 120)" % probe_center.size.y) # --- 1. Registry-Tabelle ist die Autorität -------------------------------- - var registry_script: GDScript = load("res://src/ui/panels/registry.gd") + var registry_script: GDScript = load("res://core/ui/panels/registry.gd") var ids: Array = [] for entry in registry_script.PANELS: ids.append(str(entry["id"])) @@ -167,7 +167,7 @@ func _init() -> void: _check(theme_res != null, "Theme gesetzt (main.theme)") if theme_res != null: _check(int(theme_res.default_font_size) >= 14, "Theme: Grundschrift ≥ 14 px (Lesbarkeits-Grundsatz)") - var theme_file: Theme = load("res://theme/editor_theme.tres") + var theme_file: Theme = load("res://core/theme/editor_theme.tres") _check(theme_res == theme_file, "Theme: main nutzt theme/editor_theme.tres (eine Quelle)") # --- 6. Keine doppelten Node-Namen unter main ------------------------------- diff --git a/tests/test_ui_scale.gd b/tests/test_ui_scale.gd index a0cfa13..f463093 100644 --- a/tests/test_ui_scale.gd +++ b/tests/test_ui_scale.gd @@ -18,7 +18,7 @@ extends SceneTree ## Die Suite ist hermetisch: SCOPEDVR_UI_CFG zeigt auf eine Temp-Config, ## damit weder die Nutzer-Config noch andere Suite-Läufe gestört werden. -const UIScale := preload("res://src/ui/ui_scale.gd") +const UIScale := preload("res://core/ui/ui_scale.gd") var failures := 0 var checks := 0 @@ -115,7 +115,7 @@ func _test_cfg_roundtrip() -> void: func _test_real_ui_scaling() -> void: print("Testgruppe: Echte Main-UI skaliert (Build + Rebuild)") - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "scenes/main.tscn lädt") if scene == null: return diff --git a/tests/test_updater.gd b/tests/test_updater.gd index 66a14c2..55fb4b4 100644 --- a/tests/test_updater.gd +++ b/tests/test_updater.gd @@ -272,16 +272,16 @@ func _run_tests() -> void: # Origin bekommt eine GETRACKTE Import-Datei — lokal existiert sie als # untracked (Godot erzeugt sie beim Import). Genau die Kollision, die am # 19.10. den Update-Knopf blockiert hat. - DirAccess.make_dir_recursive_absolute(other.path_join("library/thumbs")) - _write_file(other.path_join("library/thumbs/zz_probe.png.import"), "origin-version\n") - _git(other, ["add", "library/thumbs/zz_probe.png.import"]) + DirAccess.make_dir_recursive_absolute(other.path_join("core/thumbs")) + _write_file(other.path_join("core/thumbs/zz_probe.png.import"), "origin-version\n") + _git(other, ["add", "core/thumbs/zz_probe.png.import"]) _git(other, ["commit", "-m", "v3: Import-Datei getrackt"]) _check(bool(_git(other, ["push", "origin", "main"])["ok"]), "Setup: v3 gepusht (Import-Datei jetzt getrackt)") # NEGATIVPROBE: der NACKTE Pull (ohne Fix) bricht an der losen Datei ab. - DirAccess.make_dir_recursive_absolute(work.path_join("library/thumbs")) - _write_file(work.path_join("library/thumbs/zz_probe.png.import"), "lokal-erzeugt\n") + DirAccess.make_dir_recursive_absolute(work.path_join("core/thumbs")) + _write_file(work.path_join("core/thumbs/zz_probe.png.import"), "lokal-erzeugt\n") var raw := EditorUpdater.git_run(git, work, PackedStringArray(["pull", "--ff-only"])) _check(not bool(raw["ok"]), "NEGATIVPROBE: nackter pull --ff-only bricht an der Kollision ab") _check(not str(raw["output"]).strip_edges().is_empty(), @@ -292,7 +292,7 @@ func _run_tests() -> void: _check(bool(fixed["ok"]), "MIT Fix: pull läuft ohne Handeingriff durch") _check(str(fixed["info"]).contains("beiseitegelegt"), "Klartext-Info fürs Statuszeilen-Fenster gesetzt") - _check(_file_text(work.path_join("library/thumbs/zz_probe.png.import")) == "origin-version\n", + _check(_file_text(work.path_join("core/thumbs/zz_probe.png.import")) == "origin-version\n", "kein halb gepoppter Zustand: getrackte Version liegt an") _check(_clean_tracked(work), "Arbeitsbaum (getrackt) sauber — Godot baut die Datei beim Import neu") _check(_auto_stash_count(git, work) == 1, "Sicherungs-Stash bleibt bei Konflikt liegen") @@ -332,9 +332,9 @@ func _run_tests() -> void: "geänderte Datei liegt unverlustfrei im Sicherungs-Stash") print("== Auto-Stash: alte Kennung wird verworfen, nichts häuft sich an ==") - _write_file(work.path_join("library/thumbs/zwei.png.import"), "alt\n") + _write_file(work.path_join("core/thumbs/zwei.png.import"), "alt\n") var s1 := EditorUpdater._stash_local_changes(git, work) - _write_file(work.path_join("library/thumbs/drei.png.import"), "neu\n") + _write_file(work.path_join("core/thumbs/drei.png.import"), "neu\n") var s2 := EditorUpdater._stash_local_changes(git, work) _check(not s1.is_empty() and not s2.is_empty(), "beide Läufe legen einen Auto-Stash an") _check(_auto_stash_count(git, work) == 1, "genau EIN Auto-Stash übrig (alter verworfen)") @@ -342,8 +342,8 @@ func _run_tests() -> void: # die zwei untracked Dateien an keine getrackte Datei grenzen) und die # Probendateien wegwerfen. _check(bool(EditorUpdater._restore_stash(git, work)["ok"]), "Aufräumen: Stash zurückgeholt") - DirAccess.remove_absolute(work.path_join("library/thumbs/zwei.png.import")) - DirAccess.remove_absolute(work.path_join("library/thumbs/drei.png.import")) + DirAccess.remove_absolute(work.path_join("core/thumbs/zwei.png.import")) + DirAccess.remove_absolute(work.path_join("core/thumbs/drei.png.import")) _check(_auto_stash_count(git, work) == 0, "Aufräumen: kein Auto-Stash übrig") print("== Import-Abbruch-Pfad ==") diff --git a/tests/test_wasser.gd b/tests/test_wasser.gd index 24c3f96..2303390 100644 --- a/tests/test_wasser.gd +++ b/tests/test_wasser.gd @@ -34,7 +34,7 @@ func _check(cond: bool, label: String) -> void: func _run_all() -> void: - var scene: PackedScene = load("res://scenes/main.tscn") + var scene: PackedScene = load("res://core/scenes/main.tscn") _check(scene != null, "Aufbau: scenes/main.tscn laedt") if scene == null: _finish() @@ -192,7 +192,7 @@ func _w4_validator_spiegel() -> void: "W4 Plausibilitäts-Band Spiegel = Server (−5..500)") # Editor-Validator testet Terrain-Höhenbereich ±10 m — die Server-Regel # hat der Server-Suite identisch gezeigt; hier der Shader-Spiegel-Vertrag: - _check(ResourceLoader.exists("res://src/viewport/wasser.gdshader"), + _check(ResourceLoader.exists("res://core/viewport/wasser.gdshader"), "W4 Spiegel-Shader im Editor-Pfad vorhanden") diff --git a/theme/editor_theme.tres b/theme/editor_theme.tres deleted file mode 100644 index 569c234..0000000 --- a/theme/editor_theme.tres +++ /dev/null @@ -1,281 +0,0 @@ -[gd_resource type="Theme" load_steps=23 format=3] - -[sub_resource type="StyleBoxFlat" id="panel"] -bg_color = Color(0.12, 0.14, 0.17, 1) -border_color = Color(0.3, 0.36, 0.42, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 - -[sub_resource type="StyleBoxFlat" id="tab_sel"] -bg_color = Color(0.24, 0.3, 0.36, 1) -border_color = Color(0.35, 0.55, 0.7, 1) -border_width_top = 2 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -content_margin_left = 10.0 -content_margin_right = 10.0 -content_margin_top = 4.0 -content_margin_bottom = 4.0 - -[sub_resource type="StyleBoxFlat" id="tab_hover"] -bg_color = Color(0.19, 0.24, 0.29, 1) -border_color = Color(0.35, 0.55, 0.7, 0.4) -border_width_top = 2 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -content_margin_left = 10.0 -content_margin_right = 10.0 -content_margin_top = 4.0 -content_margin_bottom = 4.0 - -[sub_resource type="StyleBoxFlat" id="tab_unsel"] -bg_color = Color(0.15, 0.18, 0.21, 1) -corner_radius_top_left = 4 -corner_radius_top_right = 4 -content_margin_left = 10.0 -content_margin_right = 10.0 -content_margin_top = 4.0 -content_margin_bottom = 4.0 - -[sub_resource type="StyleBoxFlat" id="tabbar"] -bg_color = Color(0.1, 0.12, 0.14, 1) - -[sub_resource type="StyleBoxFlat" id="btn_normal"] -bg_color = Color(0.19, 0.23, 0.27, 1) -border_color = Color(0.3, 0.36, 0.42, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 -content_margin_left = 8.0 -content_margin_right = 8.0 - -[sub_resource type="StyleBoxFlat" id="btn_hover"] -bg_color = Color(0.25, 0.31, 0.37, 1) -border_color = Color(0.35, 0.55, 0.7, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 -content_margin_left = 8.0 -content_margin_right = 8.0 - -[sub_resource type="StyleBoxFlat" id="btn_pressed"] -bg_color = Color(0.14, 0.19, 0.24, 1) -border_color = Color(0.35, 0.55, 0.7, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 -content_margin_left = 8.0 -content_margin_right = 8.0 - -[sub_resource type="StyleBoxFlat" id="btn_disabled"] -bg_color = Color(0.16, 0.17, 0.19, 1) -border_color = Color(0.24, 0.26, 0.29, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 -content_margin_left = 8.0 -content_margin_right = 8.0 - -[sub_resource type="StyleBoxFlat" id="btn_focus"] -draw_center = false -border_color = Color(0.55, 0.8, 1, 0.85) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 - -[sub_resource type="StyleBoxFlat" id="line_normal"] -bg_color = Color(0.09, 0.11, 0.13, 1) -border_color = Color(0.3, 0.36, 0.42, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 -content_margin_left = 8.0 -content_margin_right = 8.0 - -[sub_resource type="StyleBoxFlat" id="line_focus"] -bg_color = Color(0.1, 0.13, 0.15, 1) -border_color = Color(0.55, 0.8, 1, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 -content_margin_left = 8.0 -content_margin_right = 8.0 - -[sub_resource type="StyleBoxFlat" id="tooltip"] -bg_color = Color(0.08, 0.09, 0.11, 0.96) -border_color = Color(0.35, 0.55, 0.7, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 -content_margin_left = 6.0 -content_margin_right = 6.0 -content_margin_top = 4.0 -content_margin_bottom = 4.0 - -[sub_resource type="StyleBoxFlat" id="split_grab"] -bg_color = Color(0.22, 0.27, 0.32, 1) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="StyleBoxFlat" id="split_grab_hover"] -bg_color = Color(0.35, 0.55, 0.7, 0.6) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 - -[sub_resource type="StyleBoxFlat" id="scroll_bg"] -bg_color = Color(0.1, 0.12, 0.14, 0.4) - -[sub_resource type="StyleBoxFlat" id="scroll_grab"] -bg_color = Color(0.42, 0.49, 0.56, 0.6) -corner_radius_top_left = 3 -corner_radius_top_right = 3 -corner_radius_bottom_right = 3 -corner_radius_bottom_left = 3 - -[sub_resource type="StyleBoxFlat" id="scroll_grab_hover"] -bg_color = Color(0.55, 0.63, 0.7, 0.8) -corner_radius_top_left = 3 -corner_radius_top_right = 3 -corner_radius_bottom_right = 3 -corner_radius_bottom_left = 3 - -[sub_resource type="StyleBoxFlat" id="scroll_grab_press"] -bg_color = Color(0.55, 0.8, 1, 0.85) -corner_radius_top_left = 3 -corner_radius_top_right = 3 -corner_radius_bottom_right = 3 -corner_radius_bottom_left = 3 - -[sub_resource type="StyleBoxFlat" id="progress_bg"] -bg_color = Color(0.09, 0.11, 0.13, 1) -border_color = Color(0.3, 0.36, 0.42, 1) -border_width_left = 1 -border_width_top = 1 -border_width_right = 1 -border_width_bottom = 1 -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 - -[sub_resource type="StyleBoxFlat" id="progress_fill"] -bg_color = Color(0.55, 0.8, 1, 1) -corner_radius_top_left = 4 -corner_radius_top_right = 4 -corner_radius_bottom_right = 4 -corner_radius_bottom_left = 4 - -[sub_resource type="StyleBoxEmpty" id="scroll_empty"] - -[resource] -default_font_size = 16 -Editor/colors/accent = Color(0.55, 0.8, 1, 1) -Editor/colors/status_ok = Color(0.75, 0.95, 0.75, 1) -Editor/colors/status_error = Color(1, 0.6, 0.5, 1) -Editor/colors/muted = Color(1, 1, 1, 0.74) -Editor/colors/field = Color(1, 1, 1, 0.9) -Editor/colors/title = Color(1, 1, 1, 0.82) -Editor/colors/warning = Color(1, 0.62, 0.3, 1) -Editor/colors/badge_outline = Color(0, 0, 0, 1) -Editor/colors/help_bg = Color(0.09, 0.11, 0.13, 0.97) -Editor/colors/help_border = Color(0.35, 0.55, 0.7, 1) -Editor/colors/update_bg = Color(0.36, 0.25, 0.06, 0.97) -Editor/colors/update_border = Color(0.95, 0.72, 0.15, 1) -Editor/colors/rubber_fill = Color(0.45, 0.8, 1, 0.16) -Editor/colors/rubber_line = Color(0.45, 0.8, 1, 0.9) -Editor/colors/selection_outline = Color(1, 0.6, 0.15, 0.95) -Editor/colors/selection_outline_hover = Color(1, 0.6, 0.15, 0.45) -Editor/colors/selection_outline_partner = Color(1, 0.78, 0.4, 0.85) -Editor/constants/selection_outline_width_mm = 80 -Editor/constants/selection_outline_width_hover_mm = 45 -Editor/constants/selection_outline_width_partner_mm = 45 -PanelContainer/styles/panel = SubResource("panel") -TabContainer/styles/panel = SubResource("panel") -TabContainer/styles/tab_selected = SubResource("tab_sel") -TabContainer/styles/tab_hovered = SubResource("tab_hover") -TabContainer/styles/tab_unselected = SubResource("tab_unsel") -TabContainer/styles/tabbar_background = SubResource("tabbar") -TabContainer/colors/font_selected_color = Color(1, 1, 1, 1) -TabContainer/colors/font_unselected_color = Color(1, 1, 1, 0.88) -Button/styles/normal = SubResource("btn_normal") -Button/styles/hover = SubResource("btn_hover") -Button/styles/pressed = SubResource("btn_pressed") -Button/styles/disabled = SubResource("btn_disabled") -Button/styles/focus = SubResource("btn_focus") -Button/colors/font_hover_color = Color(1, 1, 1, 1) -Button/colors/font_pressed_color = Color(0.8, 0.9, 1, 1) -Button/colors/font_disabled_color = Color(1, 1, 1, 0.5) -LineEdit/styles/normal = SubResource("line_normal") -LineEdit/styles/focus = SubResource("line_focus") -LineEdit/colors/font_color = Color(1, 1, 1, 1) -LineEdit/colors/font_placeholder_color = Color(1, 1, 1, 0.58) -HSplitContainer/styles/grabber_area = SubResource("split_grab") -HSplitContainer/styles/grabber_area_highlight = SubResource("split_grab_hover") -VSplitContainer/styles/grabber_area = SubResource("split_grab") -VSplitContainer/styles/grabber_area_highlight = SubResource("split_grab_hover") -ScrollContainer/styles/panel = SubResource("scroll_empty") -VScrollBar/styles/scroll = SubResource("scroll_bg") -VScrollBar/styles/grabber = SubResource("scroll_grab") -VScrollBar/styles/grabber_highlight = SubResource("scroll_grab_hover") -VScrollBar/styles/grabber_pressed = SubResource("scroll_grab_press") -HScrollBar/styles/scroll = SubResource("scroll_bg") -HScrollBar/styles/grabber = SubResource("scroll_grab") -HScrollBar/styles/grabber_highlight = SubResource("scroll_grab_hover") -HScrollBar/styles/grabber_pressed = SubResource("scroll_grab_press") -ProgressBar/styles/background = SubResource("progress_bg") -ProgressBar/styles/fill = SubResource("progress_fill") -ProgressBar/colors/font_color = Color(1, 1, 1, 1) -HSlider/styles/grabber_area = SubResource("progress_fill") -HSlider/styles/grabber_area_highlight = SubResource("progress_fill") -TooltipPanel/styles/panel = SubResource("tooltip") -TooltipLabel/colors/font_color = Color(1, 1, 1, 1) diff --git a/tools/gen_bauteile.gd b/tools/gen_bauteile.gd index 906d0da..8d527bf 100644 --- a/tools/gen_bauteile.gd +++ b/tools/gen_bauteile.gd @@ -1,5 +1,5 @@ extends SceneTree -## Erzeugt die Bauteil-Dateien des Bauen-Modus aus src/editor/bau_katalog.gd: +## Erzeugt die Bauteil-Dateien des Bauen-Modus aus core/editor/bau_katalog.gd: ## GLB (Client) · Trimesh-JSON (Server/Client/Editor) · Registry-Fragment (Server) ## ## Aufruf aus dem Editor-Repo (Pfade = Repo-Wurzeln der Geschwister-Klone): diff --git a/tools/gen_thumbs.gd b/tools/gen_thumbs.gd index dda1d3d..45ef5ed 100644 --- a/tools/gen_thumbs.gd +++ b/tools/gen_thumbs.gd @@ -1,7 +1,7 @@ extends SceneTree ## Thumbnail-Generator für die Objekt-Bibliothek (Karte t_3a998ae4). ## Rendert JEDESM Bibliotheks-Objekt einmalig als 128-px-PNG nach -## library/thumbs/.png — die Bilder werden committed, der Editor lädt sie +## core/thumbs/.png — die Bilder werden committed, der Editor lädt sie ## dann einfach aus der Datei (LibraryBrowser.load_thumb). ## ## Ausführen (braucht echtes Rendering, NICHT --headless): @@ -40,7 +40,7 @@ func _initialize() -> void: push_error("gen_thumbs: Bibliothek leer — nichts zu rendern.") quit(1) return - out_dir = ProjectSettings.globalize_path("res://library/thumbs") + out_dir = ProjectSettings.globalize_path("res://core/thumbs") DirAccess.make_dir_recursive_absolute(out_dir) vp = SubViewport.new() diff --git a/tools/parse_check.sh b/tools/parse_check.sh index 6af6569..18693a9 100755 --- a/tools/parse_check.sh +++ b/tools/parse_check.sh @@ -3,8 +3,8 @@ cd "$(dirname "$0")/.." GODOT=/opt/data/home/bin/godot4 fail=0 -for f in src/ui/main.gd src/ui/inspector_panel.gd tests/test_inspector.gd src/editor/test_run.gd src/editor/library_browser.gd core/editor/object_ops.gd \ - src/editor/interaction.gd tools/gen_thumbs.gd tests/test_library.gd; do +for f in core/ui/main.gd core/ui/inspector_panel.gd tests/test_inspector.gd core/editor/test_run.gd core/editor/library_browser.gd core/editor/object_ops.gd \ + core/editor/interaction.gd tools/gen_thumbs.gd tests/test_library.gd; do out=$("$GODOT" --headless --path . --check-only --script "res://$f" 2>&1 | grep -iv "godot engine\|^$" || true) if [ -n "$out" ]; then echo "FAIL $f:"; echo "$out"; fail=1 diff --git a/tools/parse_check_shortcuts.sh b/tools/parse_check_shortcuts.sh index a98a618..01955e6 100644 --- a/tools/parse_check_shortcuts.sh +++ b/tools/parse_check_shortcuts.sh @@ -3,9 +3,9 @@ cd "$(dirname "$0")/.." GODOT=~/bin/godot4 fail=0 -for f in src/ui/main.gd src/viewport/orbit_camera.gd src/editor/shortcut_keys.gd \ - src/editor/fly_math.gd src/editor/shortcut_policy.gd \ - core/editor/selection_math.gd src/editor/interaction.gd core/editor/object_ops.gd \ +for f in core/ui/main.gd core/viewport/orbit_camera.gd core/editor/shortcut_keys.gd \ + core/editor/fly_math.gd core/editor/shortcut_policy.gd \ + core/editor/selection_math.gd core/editor/interaction.gd core/editor/object_ops.gd \ tests/test_shortcuts.gd tests/test_ux.gd; do out=$("$GODOT" --headless --path . --check-only --script "res://$f" 2>&1 | grep -iv "godot engine\|^$" || true) if [ -n "$out" ]; then diff --git a/tools/parse_check_shortcuts2.sh b/tools/parse_check_shortcuts2.sh index e50a9a7..0cd4750 100644 --- a/tools/parse_check_shortcuts2.sh +++ b/tools/parse_check_shortcuts2.sh @@ -3,10 +3,10 @@ cd "$(dirname "$0")/.." GODOT=/opt/data/home/bin/godot4 fail=0 -for f in src/ui/main.gd src/viewport/orbit_camera.gd src/editor/shortcut_keys.gd \ - core/editor/move_math.gd src/editor/shortcut_policy.gd \ - src/editor/interaction.gd core/editor/object_ops.gd \ - src/editor/build_tool.gd src/editor/terrain_tool.gd \ +for f in core/ui/main.gd core/viewport/orbit_camera.gd core/editor/shortcut_keys.gd \ + core/editor/move_math.gd core/editor/shortcut_policy.gd \ + core/editor/interaction.gd core/editor/object_ops.gd \ + core/editor/build_tool.gd core/editor/terrain_tool.gd \ tests/test_shortcuts.gd tests/test_gui_smoke.gd; do out=$("$GODOT" --headless --path . --check-only --script "res://$f" 2>&1 | grep -iv "godot engine\|^$" || true) if [ -n "$out" ]; then diff --git a/tools/parse_check_shortcuts3.sh b/tools/parse_check_shortcuts3.sh index 6533c59..b5c40f3 100755 --- a/tools/parse_check_shortcuts3.sh +++ b/tools/parse_check_shortcuts3.sh @@ -3,8 +3,8 @@ cd "$(dirname "$0")/.." GODOT=/opt/data/home/bin/godot4 fail=0 -for f in src/ui/main.gd src/ui/help_text.gd src/editor/shortcut_keys.gd \ - src/editor/shortcut_policy.gd \ +for f in core/ui/main.gd core/ui/help_text.gd core/editor/shortcut_keys.gd \ + core/editor/shortcut_policy.gd \ tests/test_shortcuts.gd tests/test_gui_smoke.gd; do out=$("$GODOT" --headless --path . --check-only --script "res://$f" 2>&1 | grep -iv "godot engine\|^$" || true) if [ -n "$out" ]; then diff --git a/tools/sync_loadout_katalog.py b/tools/sync_loadout_katalog.py index 5d0da95..93aee70 100644 --- a/tools/sync_loadout_katalog.py +++ b/tools/sync_loadout_katalog.py @@ -2,7 +2,7 @@ """Waffen- und Aufsatz-Katalog fürs Map-Loadout aus dem Match-Server-Repo holen. Aufruf: python3 tools/sync_loadout_katalog.py [pfad/zu/scopedvr-match-server] -Schreibt library/loadout_katalog.json (Waffen-ID -> Name, Aufsatz-Slots). +Schreibt core/library/loadout_katalog.json (Waffen-ID -> Name, Aufsatz-Slots). Nach neuen Waffen/Aufsätzen im Server erneut ausführen. """ import json diff --git a/tools/sync_objects.sh b/tools/sync_objects.sh index fb0eeeb..baadfb7 100755 --- a/tools/sync_objects.sh +++ b/tools/sync_objects.sh @@ -4,7 +4,7 @@ # Was das Script macht: # 1. Merge im Match-Server-Sibling prüfen (tools/merge_object_library.py --check) # 2. library/objects.json in die Editor-Kopie ziehen (Editor-`note` bleibt erhalten) -# 3. Thumbnails neu rendern (tools/gen_thumbs.gd, 128 px PNG nach library/thumbs/) +# 3. Thumbnails neu rendern (tools/gen_thumbs.gd, 128 px PNG nach core/thumbs/) # 4. Objekt-Zahl der Bibliothek ausgeben # # Aufruf (aus dem Editor-Repo): @@ -84,4 +84,4 @@ if [ "$THUMBS" = "1" ]; then fi fi -echo "FERTIG — Bibliothek im Editor: $(python3 -c "import json;print(len(json.load(open('$EDITOR_JSON'))['objects']))") Objekte, Thumbs: $(ls "$DIR/library/thumbs" 2>/dev/null | grep -c '\.png$') PNG" +echo "FERTIG — Bibliothek im Editor: $(python3 -c "import json;print(len(json.load(open('$EDITOR_JSON'))['objects']))") Objekte, Thumbs: $(ls "$DIR/core/thumbs" 2>/dev/null | grep -c '\.png$') PNG"