diff --git a/assets/kenney-fps/fonts/lilita_one_regular.ttf.import b/assets/kenney-fps/fonts/lilita_one_regular.ttf.import deleted file mode 100644 index a43c54c..0000000 --- a/assets/kenney-fps/fonts/lilita_one_regular.ttf.import +++ /dev/null @@ -1,36 +0,0 @@ -[remap] - -importer="font_data_dynamic" -type="FontFile" -uid="uid://biqtga8moh7ah" -path="res://.godot/imported/lilita_one_regular.ttf-68cc4ab6825bdd499d1ad608190f5213.fontdata" - -[deps] - -source_file="res://fonts/lilita_one_regular.ttf" -dest_files=["res://.godot/imported/lilita_one_regular.ttf-68cc4ab6825bdd499d1ad608190f5213.fontdata"] - -[params] - -Rendering=null -antialiasing=1 -generate_mipmaps=false -disable_embedded_bitmaps=true -multichannel_signed_distance_field=false -msdf_pixel_range=8 -msdf_size=48 -allow_system_fallback=true -force_autohinter=false -modulate_color_glyphs=false -hinting=1 -subpixel_positioning=1 -keep_rounding_remainders=true -oversampling=0.0 -Fallbacks=null -fallbacks=[] -Compress=null -compress=true -preload=[] -language_support={} -script_support={} -opentype_features={} diff --git a/assets/kenney-fps/icon.png.import b/assets/kenney-fps/icon.png.import deleted file mode 100644 index 9728dae..0000000 --- a/assets/kenney-fps/icon.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cpxour8a7ihec" -path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://icon.png" -dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/assets/kenney-fps/models/Textures/colormap.png.import b/assets/kenney-fps/models/Textures/colormap.png.import deleted file mode 100644 index e62d53e..0000000 --- a/assets/kenney-fps/models/Textures/colormap.png.import +++ /dev/null @@ -1,41 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b5hxnjwvrxuji" -path.bptc="res://.godot/imported/colormap.png-c1bc3c3aabeec406ff4b53328583776a.bptc.ctex" -metadata={ -"imported_formats": ["s3tc_bptc"], -"vram_texture": true -} - -[deps] - -source_file="res://models/Textures/colormap.png" -dest_files=["res://.godot/imported/colormap.png-c1bc3c3aabeec406ff4b53328583776a.bptc.ctex"] - -[params] - -compress/mode=2 -compress/high_quality=true -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=true -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=0 diff --git a/assets/kenney-fps/models/grass-small.glb.import b/assets/kenney-fps/models/grass-small.glb.import deleted file mode 100644 index a952b5f..0000000 --- a/assets/kenney-fps/models/grass-small.glb.import +++ /dev/null @@ -1,42 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://das5fosq6auoe" -path="res://.godot/imported/grass-small.glb-0be1c06405ef2ce478dc00acb5be5be8.scn" - -[deps] - -source_file="res://models/grass-small.glb" -dest_files=["res://.godot/imported/grass-small.glb-0be1c06405ef2ce478dc00acb5be5be8.scn"] - -[params] - -nodes/root_type="Node3D" -nodes/root_name="Scene Root" -nodes/root_script=null -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_name_suffixes=true -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -materials/extract=0 -materials/extract_format=0 -materials/extract_path="" -_subresources={} -gltf/naming_version=0 -gltf/embedded_image_handling=1 diff --git a/assets/kenney-fps/models/grass.glb.import b/assets/kenney-fps/models/grass.glb.import deleted file mode 100644 index 7e99538..0000000 --- a/assets/kenney-fps/models/grass.glb.import +++ /dev/null @@ -1,42 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://beaer7x07yif6" -path="res://.godot/imported/grass.glb-0ce858eae1c69c894a569863f13e24f1.scn" - -[deps] - -source_file="res://models/grass.glb" -dest_files=["res://.godot/imported/grass.glb-0ce858eae1c69c894a569863f13e24f1.scn"] - -[params] - -nodes/root_type="Node3D" -nodes/root_name="Scene Root" -nodes/root_script=null -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_name_suffixes=true -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -materials/extract=0 -materials/extract_format=0 -materials/extract_path="" -_subresources={} -gltf/naming_version=0 -gltf/embedded_image_handling=1 diff --git a/assets/kenney-fps/models/platform-falling.glb.import b/assets/kenney-fps/models/platform-falling.glb.import deleted file mode 100644 index 5ff9fa9..0000000 --- a/assets/kenney-fps/models/platform-falling.glb.import +++ /dev/null @@ -1,32 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://3403atnv0s14" -path="res://.godot/imported/platform-falling.glb-a1321a8710589d27b2a6e247cfe23359.scn" - -[deps] - -source_file="res://models/platform-falling.glb" -dest_files=["res://.godot/imported/platform-falling.glb-a1321a8710589d27b2a6e247cfe23359.scn"] - -[params] - -nodes/root_type="Node3D" -nodes/root_name="Scene Root" -nodes/apply_root_scale=true -nodes/root_scale=1.0 -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -import_script/path="" -_subresources={} -gltf/embedded_image_handling=1 diff --git a/assets/kenney-fps/models/platform-large-grass.glb.import b/assets/kenney-fps/models/platform-large-grass.glb.import deleted file mode 100644 index 9a97e4c..0000000 --- a/assets/kenney-fps/models/platform-large-grass.glb.import +++ /dev/null @@ -1,42 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://k065rxqtim8f" -path="res://.godot/imported/platform-large-grass.glb-eba1099445789c9c9ba0b37fc57bd13f.scn" - -[deps] - -source_file="res://models/platform-large-grass.glb" -dest_files=["res://.godot/imported/platform-large-grass.glb-eba1099445789c9c9ba0b37fc57bd13f.scn"] - -[params] - -nodes/root_type="Node3D" -nodes/root_name="Scene Root" -nodes/root_script=null -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_name_suffixes=true -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -materials/extract=0 -materials/extract_format=0 -materials/extract_path="" -_subresources={} -gltf/naming_version=0 -gltf/embedded_image_handling=1 diff --git a/assets/kenney-fps/models/platform.glb.import b/assets/kenney-fps/models/platform.glb.import deleted file mode 100644 index da68500..0000000 --- a/assets/kenney-fps/models/platform.glb.import +++ /dev/null @@ -1,42 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://bwgwd5ue8i2bt" -path="res://.godot/imported/platform.glb-3476c7cd272116fb58fd5d0a0eddb703.scn" - -[deps] - -source_file="res://models/platform.glb" -dest_files=["res://.godot/imported/platform.glb-3476c7cd272116fb58fd5d0a0eddb703.scn"] - -[params] - -nodes/root_type="Node3D" -nodes/root_name="Scene Root" -nodes/root_script=null -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_name_suffixes=true -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -materials/extract=0 -materials/extract_format=0 -materials/extract_path="" -_subresources={} -gltf/naming_version=0 -gltf/embedded_image_handling=1 diff --git a/assets/kenney-fps/models/wall-high.glb.import b/assets/kenney-fps/models/wall-high.glb.import deleted file mode 100644 index 985c615..0000000 --- a/assets/kenney-fps/models/wall-high.glb.import +++ /dev/null @@ -1,42 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://c743irj356lax" -path="res://.godot/imported/wall-high.glb-74f2e81af43ef5254fe14637810326a5.scn" - -[deps] - -source_file="res://models/wall-high.glb" -dest_files=["res://.godot/imported/wall-high.glb-74f2e81af43ef5254fe14637810326a5.scn"] - -[params] - -nodes/root_type="Node3D" -nodes/root_name="Scene Root" -nodes/root_script=null -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_name_suffixes=true -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -materials/extract=0 -materials/extract_format=0 -materials/extract_path="" -_subresources={} -gltf/naming_version=0 -gltf/embedded_image_handling=1 diff --git a/assets/kenney-fps/models/wall-low.glb.import b/assets/kenney-fps/models/wall-low.glb.import deleted file mode 100644 index 341edec..0000000 --- a/assets/kenney-fps/models/wall-low.glb.import +++ /dev/null @@ -1,42 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://x08pt5dvke58" -path="res://.godot/imported/wall-low.glb-de080c69f0eef8b51181d363ed18f581.scn" - -[deps] - -source_file="res://models/wall-low.glb" -dest_files=["res://.godot/imported/wall-low.glb-de080c69f0eef8b51181d363ed18f581.scn"] - -[params] - -nodes/root_type="Node3D" -nodes/root_name="Scene Root" -nodes/root_script=null -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_name_suffixes=true -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -materials/extract=0 -materials/extract_format=0 -materials/extract_path="" -_subresources={} -gltf/naming_version=0 -gltf/embedded_image_handling=1 diff --git a/assets/kenney-fps/objects/cloud.tscn b/assets/kenney-fps/objects/cloud.tscn index cc6e923..86fc82a 100644 --- a/assets/kenney-fps/objects/cloud.tscn +++ b/assets/kenney-fps/objects/cloud.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=3 format=3 uid="uid://oqfhfp1a80qd"] -[ext_resource type="PackedScene" uid="uid://g2w2608bc2dy" path="res://models/cloud.glb" id="1_2mo3p"] -[ext_resource type="Script" uid="uid://bfgpo8fvf136p" path="res://objects/cloud.gd" id="2_rmotl"] +[ext_resource type="PackedScene" uid="uid://g2w2608bc2dy" path="res://assets/kenney-fps/models/cloud.glb" id="1_2mo3p"] +[ext_resource type="Script" uid="uid://bfgpo8fvf136p" path="res://assets/kenney-fps/objects/cloud.gd" id="2_rmotl"] [node name="cube2" instance=ExtResource("1_2mo3p")] script = ExtResource("2_rmotl") diff --git a/assets/kenney-fps/objects/enemy.gd b/assets/kenney-fps/objects/enemy.gd index 1350223..f7eca20 100644 --- a/assets/kenney-fps/objects/enemy.gd +++ b/assets/kenney-fps/objects/enemy.gd @@ -28,7 +28,7 @@ func _process(delta): # Take damage from player func damage(amount): - Audio.play("sounds/enemy_hurt.ogg") + Audio.play("assets/kenney-fps/sounds/enemy_hurt.ogg") health -= amount @@ -38,7 +38,7 @@ func damage(amount): # Destroy the enemy when out of health func destroy(): - Audio.play("sounds/enemy_destroy.ogg") + Audio.play("assets/kenney-fps/sounds/enemy_destroy.ogg") destroyed = true queue_free() @@ -63,6 +63,6 @@ func _on_timer_timeout(): muzzle_b.play("default") muzzle_b.rotation_degrees.z = randf_range(-45, 45) - Audio.play("sounds/enemy_attack.ogg") + Audio.play("assets/kenney-fps/sounds/enemy_attack.ogg") collider.damage(5) # Apply damage to player diff --git a/assets/kenney-fps/objects/enemy.tscn b/assets/kenney-fps/objects/enemy.tscn index 064847f..055c8eb 100644 --- a/assets/kenney-fps/objects/enemy.tscn +++ b/assets/kenney-fps/objects/enemy.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=5 format=3 uid="uid://d2g78tpqbyf5g"] -[ext_resource type="PackedScene" uid="uid://lde2xq3vq635" path="res://models/enemy-flying.glb" id="1_3v8nl"] -[ext_resource type="Script" uid="uid://b6udw8uhlp4ei" path="res://objects/enemy.gd" id="1_jg24b"] -[ext_resource type="SpriteFrames" uid="uid://dbv3sy5qjatnl" path="res://sprites/burst_animation.tres" id="3_iblw5"] +[ext_resource type="PackedScene" uid="uid://lde2xq3vq635" path="res://assets/kenney-fps/models/enemy-flying.glb" id="1_3v8nl"] +[ext_resource type="Script" uid="uid://b6udw8uhlp4ei" path="res://assets/kenney-fps/objects/enemy.gd" id="1_jg24b"] +[ext_resource type="SpriteFrames" uid="uid://dbv3sy5qjatnl" path="res://assets/kenney-fps/sprites/burst_animation.tres" id="3_iblw5"] [sub_resource type="SphereShape3D" id="SphereShape3D_iix87"] radius = 0.75 diff --git a/assets/kenney-fps/objects/impact.tscn b/assets/kenney-fps/objects/impact.tscn index ae65850..7fca6b0 100644 --- a/assets/kenney-fps/objects/impact.tscn +++ b/assets/kenney-fps/objects/impact.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=8 format=3 uid="uid://b7070gfoko4mo"] -[ext_resource type="Texture2D" uid="uid://dh0t42ubhuv0" path="res://sprites/hit.png" id="1_mdfft"] -[ext_resource type="Script" uid="uid://bwkexrmt718dx" path="res://objects/impact.gd" id="2_k826h"] +[ext_resource type="Texture2D" uid="uid://dh0t42ubhuv0" path="res://assets/kenney-fps/sprites/hit.png" id="1_mdfft"] +[ext_resource type="Script" uid="uid://bwkexrmt718dx" path="res://assets/kenney-fps/objects/impact.gd" id="2_k826h"] [sub_resource type="AtlasTexture" id="AtlasTexture_8c04i"] atlas = ExtResource("1_mdfft") diff --git a/assets/kenney-fps/objects/platform.tscn b/assets/kenney-fps/objects/platform.tscn index 3fc851d..9c60734 100644 --- a/assets/kenney-fps/objects/platform.tscn +++ b/assets/kenney-fps/objects/platform.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://dpm3l05d7fu35"] -[ext_resource type="PackedScene" uid="uid://bwgwd5ue8i2bt" path="res://models/platform.glb" id="1_0lm70"] +[ext_resource type="PackedScene" uid="uid://bwgwd5ue8i2bt" path="res://assets/kenney-fps/models/platform.glb" id="1_0lm70"] [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_27lc5"] data = PackedVector3Array(-0.9, 0, -0.72, -1, 0.2, -0.8, -1, 0.2, 0.8, -1, 0.2, 0.8, -0.9, 0, 0.72, -0.9, 0, -0.72, -0.95, 0.5, -0.95, -0.95, 0.2, -0.95, -0.8, 0.2, -1, -0.8, 0.2, -1, -0.8, 0.5, -1, -0.95, 0.5, -0.95, -1, 0.2, -0.8, -0.95, 0.2, -0.95, -0.95, 0.5, -0.95, -0.95, 0.5, -0.95, -1, 0.5, -0.8, -1, 0.2, -0.8, -1, 0.2, 0.8, -1, 0.2, -0.8, -1, 0.5, -0.8, -1, 0.5, -0.8, -1, 0.5, 0.8, -1, 0.2, 0.8, 0.8, 0.5, -1, 0.8, 0.2, -1, 0.95, 0.2, -0.95, 0.95, 0.2, -0.95, 0.95, 0.5, -0.95, 0.8, 0.5, -1, -0.8, 0.5, -1, -0.8, 0.2, -1, 0.8, 0.2, -1, 0.8, 0.2, -1, 0.8, 0.5, -1, -0.8, 0.5, -1, 1, 0.5, -0.8, 0.95, 0.5, -0.95, 0.95, 0.2, -0.95, 0.95, 0.2, -0.95, 1, 0.2, -0.8, 1, 0.5, -0.8, -0.8, 0.5, 1, -0.8, 0.2, 1, -0.95, 0.2, 0.95, -0.95, 0.2, 0.95, -0.95, 0.5, 0.95, -0.8, 0.5, 1, -0.95, 0.2, 0.95, -1, 0.2, 0.8, -1, 0.5, 0.8, -1, 0.5, 0.8, -0.95, 0.5, 0.95, -0.95, 0.2, 0.95, -0.8, 0.2, -1, -0.72, 0, -0.9, 0.72, 0, -0.9, 0.72, 0, -0.9, 0.8, 0.2, -1, -0.8, 0.2, -1, 1, 0.2, 0.8, 1, 0.2, -0.8, 0.9, 0, -0.72, 0.9, 0, -0.72, 0.9, 0, 0.72, 1, 0.2, 0.8, -0.95, 0.2, -0.95, -0.855, 0, -0.855, -0.72, 0, -0.9, -0.72, 0, -0.9, -0.8, 0.2, -1, -0.95, 0.2, -0.95, 1, 0.2, 0.8, 0.9, 0, 0.72, 0.855, 0, 0.855, 0.855, 0, 0.855, 0.95, 0.2, 0.95, 1, 0.2, 0.8, -0.855, 0, 0.855, -0.9, 0, 0.72, -1, 0.2, 0.8, -1, 0.2, 0.8, -0.95, 0.2, 0.95, -0.855, 0, 0.855, 0.8, 0.2, 1, 0.72, 0, 0.9, -0.72, 0, 0.9, -0.72, 0, 0.9, -0.8, 0.2, 1, 0.8, 0.2, 1, 0.95, 0.5, 0.95, 1, 0.5, 0.8, 1, 0.2, 0.8, 1, 0.2, 0.8, 0.95, 0.2, 0.95, 0.95, 0.5, 0.95, 1, 0.5, 0.8, 1, 0.5, -0.8, 1, 0.2, -0.8, 1, 0.2, -0.8, 1, 0.2, 0.8, 1, 0.5, 0.8, 1, 0.2, -0.8, 0.95, 0.2, -0.95, 0.855, 0, -0.855, 0.855, 0, -0.855, 0.9, 0, -0.72, 1, 0.2, -0.8, -0.855, 0, -0.855, -0.95, 0.2, -0.95, -1, 0.2, -0.8, -1, 0.2, -0.8, -0.9, 0, -0.72, -0.855, 0, -0.855, 0.8, 0.2, -1, 0.72, 0, -0.9, 0.855, 0, -0.855, 0.855, 0, -0.855, 0.95, 0.2, -0.95, 0.8, 0.2, -1, 0.95, 0.2, 0.95, 0.855, 0, 0.855, 0.72, 0, 0.9, 0.72, 0, 0.9, 0.8, 0.2, 1, 0.95, 0.2, 0.95, 0.855, 0, 0.855, 0.9, 0, 0.72, 0.9, 0, -0.72, 0.9, 0, -0.72, 0.855, 0, -0.855, 0.855, 0, 0.855, 0.855, 0, -0.855, 0.72, 0, 0.9, 0.855, 0, 0.855, 0.855, 0, -0.855, 0.72, 0, -0.9, 0.72, 0, 0.9, 0.72, 0, -0.9, -0.72, 0, 0.9, 0.72, 0, 0.9, 0.72, 0, -0.9, -0.72, 0, -0.9, -0.72, 0, 0.9, -0.72, 0, -0.9, -0.855, 0, -0.855, -0.72, 0, 0.9, -0.855, 0, -0.855, -0.855, 0, 0.855, -0.72, 0, 0.9, -0.855, 0, -0.855, -0.9, 0, -0.72, -0.855, 0, 0.855, -0.9, 0, -0.72, -0.9, 0, 0.72, -0.855, 0, 0.855, -0.8, 0.2, 1, -0.72, 0, 0.9, -0.855, 0, 0.855, -0.855, 0, 0.855, -0.95, 0.2, 0.95, -0.8, 0.2, 1, 0.95, 0.5, 0.95, 0.95, 0.2, 0.95, 0.8, 0.2, 1, 0.8, 0.2, 1, 0.8, 0.5, 1, 0.95, 0.5, 0.95, 0.8, 0.5, 1, 0.8, 0.2, 1, -0.8, 0.2, 1, -0.8, 0.2, 1, -0.8, 0.5, 1, 0.8, 0.5, 1, -0.95, 0.5, 0.95, -1, 0.5, 0.8, -1, 0.5, -0.8, -0.95, 0.5, 0.95, -1, 0.5, -0.8, -0.95, 0.5, -0.95, -0.8, 0.5, 1, -0.95, 0.5, 0.95, -0.95, 0.5, -0.95, -0.8, 0.5, 0.7675, -0.8, 0.5, 1, -0.95, 0.5, -0.95, -0.8, 0.5, -0.7675, -0.8, 0.5, 0.7675, -0.95, 0.5, -0.95, -0.8, 0.5, 1, -0.8, 0.5, 0.7675, -0.7919, 0.5, 0.7919, -0.8, 0.5, 1, -0.7919, 0.5, 0.7919, -0.7675, 0.5, 0.8, -0.8, 0.5, 1, -0.7675, 0.5, 0.8, 0.7675, 0.5, 0.8, -0.8, 0.5, -0.7675, -0.95, 0.5, -0.95, -0.8, 0.5, -1, 0.8, 0.5, 1, -0.8, 0.5, 1, 0.7675, 0.5, 0.8, -0.7919, 0.5, -0.7919, -0.8, 0.5, -0.7675, -0.8, 0.5, -1, -0.7675, 0.5, -0.8, -0.7919, 0.5, -0.7919, -0.8, 0.5, -1, 0.7675, 0.5, -0.8, -0.7675, 0.5, -0.8, -0.8, 0.5, -1, 0.8, 0.5, 1, 0.7675, 0.5, 0.8, 0.7919, 0.5, 0.7919, 0.7675, 0.5, -0.8, -0.8, 0.5, -1, 0.8, 0.5, -1, 0.7919, 0.5, -0.7919, 0.7675, 0.5, -0.8, 0.8, 0.5, -1, 0.8, 0.5, -0.7675, 0.7919, 0.5, -0.7919, 0.8, 0.5, -1, 0.8, 0.5, 0.7675, 0.8, 0.5, -0.7675, 0.8, 0.5, -1, 0.8, 0.5, 1, 0.7919, 0.5, 0.7919, 0.8, 0.5, 0.7675, 0.8, 0.5, -1, 0.95, 0.5, -0.95, 0.8, 0.5, 0.7675, 0.8, 0.5, 1, 0.8, 0.5, 0.7675, 0.95, 0.5, -0.95, 0.95, 0.5, 0.95, 0.8, 0.5, 1, 0.95, 0.5, -0.95, 0.95, 0.5, 0.95, 0.95, 0.5, -0.95, 1, 0.5, -0.8, 1, 0.5, -0.8, 1, 0.5, 0.8, 0.95, 0.5, 0.95, 0.8, 0.5, -0.7675, 0.8, 0.5, 0.7675, 0.7919, 0.5, 0.7919, 0.7919, 0.5, 0.7919, 0.7919, 0.5, -0.7919, 0.8, 0.5, -0.7675, 0.7919, 0.5, 0.7919, 0.7675, 0.5, 0.8, 0.7919, 0.5, -0.7919, 0.7675, 0.5, 0.8, 0.7675, 0.5, -0.8, 0.7919, 0.5, -0.7919, 0.7675, 0.5, 0.8, 0.6, 0.5, -0.6, 0.7675, 0.5, -0.8, 0.6, 0.5, -0.6, -0.7675, 0.5, -0.8, 0.7675, 0.5, -0.8, 0.7675, 0.5, 0.8, 0.6, 0.5, 0.6, 0.6, 0.5, -0.6, 0.6, 0.5, -0.6, -0.6, 0.5, -0.6, -0.7675, 0.5, -0.8, 0.6, 0.5, 0.6, 0.7675, 0.5, 0.8, -0.7675, 0.5, 0.8, -0.6, 0.5, -0.6, -0.6, 0.5, 0.6, -0.7675, 0.5, -0.8, -0.7675, 0.5, 0.8, -0.6, 0.5, 0.6, 0.6, 0.5, 0.6, -0.7675, 0.5, 0.8, -0.7675, 0.5, -0.8, -0.6, 0.5, 0.6, -0.7675, 0.5, 0.8, -0.7919, 0.5, -0.7919, -0.7675, 0.5, -0.8, -0.7675, 0.5, 0.8, -0.7919, 0.5, 0.7919, -0.7919, 0.5, -0.7919, -0.7919, 0.5, 0.7919, -0.8, 0.5, -0.7675, -0.7919, 0.5, -0.7919, -0.7919, 0.5, 0.7919, -0.8, 0.5, 0.7675, -0.8, 0.5, -0.7675, 0.6, 0.5, -0.6, 0.6, 0.5, 0.6, -0.6, 0.5, 0.6, -0.6, 0.5, 0.6, -0.6, 0.5, -0.6, 0.6, 0.5, -0.6, 0.7, 0.4, 0.7, 0.7, 0.2, 0.7, 1.1, 0.2, 0.7, 1.1, 0.2, 0.7, 1.1, 0.4, 0.7, 0.7, 0.4, 0.7, 0.7, 0.4, 0.7, 1.1, 0.4, 0.7, 1.1, 0.4, 0.8162, 1.1, 0.4, 0.8162, 1.0291, 0.4, 1.0291, 0.7, 0.4, 0.7, 1.0291, 0.4, 1.0291, 0.8162, 0.4, 1.1, 0.7, 0.4, 0.7, 0.8162, 0.4, 1.1, 0.7, 0.4, 1.1, 0.7, 0.4, 0.7, 1.1, 0.2, 0.8162, 1.1, 0.2, 0.7, 0.7, 0.2, 0.7, 0.7, 0.2, 0.7, 1.0291, 0.2, 1.0291, 1.1, 0.2, 0.8162, 0.7, 0.2, 0.7, 0.8162, 0.2, 1.1, 1.0291, 0.2, 1.0291, 0.7, 0.2, 0.7, 0.7, 0.2, 1.1, 0.8162, 0.2, 1.1, 1.0291, 0.4, 1.0291, 1.0291, 0.2, 1.0291, 0.8162, 0.2, 1.1, 0.8162, 0.2, 1.1, 0.8162, 0.4, 1.1, 1.0291, 0.4, 1.0291, 1.0291, 0.4, 1.0291, 1.1, 0.4, 0.8162, 1.1, 0.2, 0.8162, 1.1, 0.2, 0.8162, 1.0291, 0.2, 1.0291, 1.0291, 0.4, 1.0291, 1.1, 0.4, 0.8162, 1.1, 0.4, 0.7, 1.1, 0.2, 0.7, 1.1, 0.2, 0.7, 1.1, 0.2, 0.8162, 1.1, 0.4, 0.8162, 0.8162, 0.4, 1.1, 0.8162, 0.2, 1.1, 0.7, 0.2, 1.1, 0.7, 0.2, 1.1, 0.7, 0.4, 1.1, 0.8162, 0.4, 1.1, 0.7, 0.2, 1.1, 0.7, 0.2, 0.7, 0.7, 0.4, 0.7, 0.7, 0.4, 0.7, 0.7, 0.4, 1.1, 0.7, 0.2, 1.1, 1.1, 0.4, -0.7, 1.1, 0.2, -0.7, 0.7, 0.2, -0.7, 0.7, 0.2, -0.7, 0.7, 0.4, -0.7, 1.1, 0.4, -0.7, 1.1, 0.4, -0.8162, 1.1, 0.4, -0.7, 0.7, 0.4, -0.7, 0.7, 0.4, -0.7, 1.0291, 0.4, -1.0291, 1.1, 0.4, -0.8162, 0.7, 0.4, -0.7, 0.8162, 0.4, -1.1, 1.0291, 0.4, -1.0291, 0.7, 0.4, -0.7, 0.7, 0.4, -1.1, 0.8162, 0.4, -1.1, 0.7, 0.2, -0.7, 1.1, 0.2, -0.7, 1.1, 0.2, -0.8162, 1.1, 0.2, -0.8162, 1.0291, 0.2, -1.0291, 0.7, 0.2, -0.7, 1.0291, 0.2, -1.0291, 0.8162, 0.2, -1.1, 0.7, 0.2, -0.7, 0.8162, 0.2, -1.1, 0.7, 0.2, -1.1, 0.7, 0.2, -0.7, 0.7, 0.4, -1.1, 0.7, 0.2, -1.1, 0.8162, 0.2, -1.1, 0.8162, 0.2, -1.1, 0.8162, 0.4, -1.1, 0.7, 0.4, -1.1, 0.7, 0.2, -0.7, 0.7, 0.2, -1.1, 0.7, 0.4, -1.1, 0.7, 0.4, -1.1, 0.7, 0.4, -0.7, 0.7, 0.2, -0.7, 1.1, 0.4, -0.7, 1.1, 0.4, -0.8162, 1.1, 0.2, -0.8162, 1.1, 0.2, -0.8162, 1.1, 0.2, -0.7, 1.1, 0.4, -0.7, 1.1, 0.4, -0.8162, 1.0291, 0.4, -1.0291, 1.0291, 0.2, -1.0291, 1.0291, 0.2, -1.0291, 1.1, 0.2, -0.8162, 1.1, 0.4, -0.8162, 0.8162, 0.4, -1.1, 0.8162, 0.2, -1.1, 1.0291, 0.2, -1.0291, 1.0291, 0.2, -1.0291, 1.0291, 0.4, -1.0291, 0.8162, 0.4, -1.1, -1.1, 0.2, -0.7, -1.1, 0.2, -0.8162, -1.1, 0.4, -0.8162, -1.1, 0.4, -0.8162, -1.1, 0.4, -0.7, -1.1, 0.2, -0.7, -0.8162, 0.4, -1.1, -0.8162, 0.2, -1.1, -0.7, 0.2, -1.1, -0.7, 0.2, -1.1, -0.7, 0.4, -1.1, -0.8162, 0.4, -1.1, -0.8162, 0.4, -1.1, -0.7, 0.4, -1.1, -0.7, 0.4, -0.7, -0.7, 0.4, -0.7, -1.1, 0.4, -0.7, -0.8162, 0.4, -1.1, -1.1, 0.4, -0.7, -1.0291, 0.4, -1.0291, -0.8162, 0.4, -1.1, -1.1, 0.4, -0.7, -1.1, 0.4, -0.8162, -1.0291, 0.4, -1.0291, -0.7, 0.4, -0.7, -0.7, 0.4, -1.1, -0.7, 0.2, -1.1, -0.7, 0.2, -1.1, -0.7, 0.2, -0.7, -0.7, 0.4, -0.7, -0.7, 0.4, -0.7, -0.7, 0.2, -0.7, -1.1, 0.2, -0.7, -1.1, 0.2, -0.7, -1.1, 0.4, -0.7, -0.7, 0.4, -0.7, -1.0291, 0.4, -1.0291, -1.0291, 0.2, -1.0291, -0.8162, 0.2, -1.1, -0.8162, 0.2, -1.1, -0.8162, 0.4, -1.1, -1.0291, 0.4, -1.0291, -1.1, 0.2, -0.8162, -1.0291, 0.2, -1.0291, -1.0291, 0.4, -1.0291, -1.0291, 0.4, -1.0291, -1.1, 0.4, -0.8162, -1.1, 0.2, -0.8162, -0.7, 0.2, -0.7, -0.7, 0.2, -1.1, -0.8162, 0.2, -1.1, -0.8162, 0.2, -1.1, -1.1, 0.2, -0.7, -0.7, 0.2, -0.7, -0.8162, 0.2, -1.1, -1.0291, 0.2, -1.0291, -1.1, 0.2, -0.7, -1.0291, 0.2, -1.0291, -1.1, 0.2, -0.8162, -1.1, 0.2, -0.7, -0.8162, 0.2, 1.1, -0.7, 0.2, 1.1, -0.7, 0.2, 0.7, -0.7, 0.2, 0.7, -1.1, 0.2, 0.7, -0.8162, 0.2, 1.1, -1.1, 0.2, 0.7, -1.0291, 0.2, 1.0291, -0.8162, 0.2, 1.1, -1.1, 0.2, 0.7, -1.1, 0.2, 0.8162, -1.0291, 0.2, 1.0291, -1.1, 0.4, 0.7, -0.7, 0.4, 0.7, -0.7, 0.4, 1.1, -0.7, 0.4, 1.1, -0.8162, 0.4, 1.1, -1.1, 0.4, 0.7, -0.8162, 0.4, 1.1, -1.0291, 0.4, 1.0291, -1.1, 0.4, 0.7, -1.0291, 0.4, 1.0291, -1.1, 0.4, 0.8162, -1.1, 0.4, 0.7, -1.0291, 0.2, 1.0291, -1.1, 0.2, 0.8162, -1.1, 0.4, 0.8162, -1.1, 0.4, 0.8162, -1.0291, 0.4, 1.0291, -1.0291, 0.2, 1.0291, -1.1, 0.2, 0.8162, -1.1, 0.2, 0.7, -1.1, 0.4, 0.7, -1.1, 0.4, 0.7, -1.1, 0.4, 0.8162, -1.1, 0.2, 0.8162, -0.7, 0.4, 1.1, -0.7, 0.4, 0.7, -0.7, 0.2, 0.7, -0.7, 0.2, 0.7, -0.7, 0.2, 1.1, -0.7, 0.4, 1.1, -0.7, 0.4, 1.1, -0.7, 0.2, 1.1, -0.8162, 0.2, 1.1, -0.8162, 0.2, 1.1, -0.8162, 0.4, 1.1, -0.7, 0.4, 1.1, -0.8162, 0.4, 1.1, -0.8162, 0.2, 1.1, -1.0291, 0.2, 1.0291, -1.0291, 0.2, 1.0291, -1.0291, 0.4, 1.0291, -0.8162, 0.4, 1.1, -1.1, 0.4, 0.7, -1.1, 0.2, 0.7, -0.7, 0.2, 0.7, -0.7, 0.2, 0.7, -0.7, 0.4, 0.7, -1.1, 0.4, 0.7) diff --git a/assets/kenney-fps/objects/platform_large_grass.tscn b/assets/kenney-fps/objects/platform_large_grass.tscn index fb6d9e3..ef0b48f 100644 --- a/assets/kenney-fps/objects/platform_large_grass.tscn +++ b/assets/kenney-fps/objects/platform_large_grass.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=5 format=3 uid="uid://bvx5cvigosg0s"] -[ext_resource type="PackedScene" uid="uid://k065rxqtim8f" path="res://models/platform-large-grass.glb" id="1_aqto8"] -[ext_resource type="PackedScene" uid="uid://beaer7x07yif6" path="res://models/grass.glb" id="2_o8lrl"] -[ext_resource type="PackedScene" uid="uid://das5fosq6auoe" path="res://models/grass-small.glb" id="3_m33kb"] +[ext_resource type="PackedScene" uid="uid://k065rxqtim8f" path="res://assets/kenney-fps/models/platform-large-grass.glb" id="1_aqto8"] +[ext_resource type="PackedScene" uid="uid://beaer7x07yif6" path="res://assets/kenney-fps/models/grass.glb" id="2_o8lrl"] +[ext_resource type="PackedScene" uid="uid://das5fosq6auoe" path="res://assets/kenney-fps/models/grass-small.glb" id="3_m33kb"] [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_k56ha"] data = PackedVector3Array(2.5, 0.2, 2.3, 2.4, 0, 2.22, 2.355, 0, 2.355, 2.355, 0, 2.355, 2.45, 0.2, 2.45, 2.5, 0.2, 2.3, 2.45, 0.5, 2.45, 2.5, 0.5, 2.3, 2.5, 0.2, 2.3, 2.5, 0.2, 2.3, 2.45, 0.2, 2.45, 2.45, 0.5, 2.45, 2.45, 0.2, 2.45, 2.355, 0, 2.355, 2.22, 0, 2.4, 2.22, 0, 2.4, 2.3, 0.2, 2.5, 2.45, 0.2, 2.45, 2.45, 0.5, 2.45, 2.45, 0.2, 2.45, 2.3, 0.2, 2.5, 2.3, 0.2, 2.5, 2.3, 0.5, 2.5, 2.45, 0.5, 2.45, 2.3, 0.5, 2.5, 2.3, 0.2, 2.5, -2.3, 0.2, 2.5, -2.3, 0.2, 2.5, -2.3, 0.5, 2.5, 2.3, 0.5, 2.5, -2.45, 0.2, 2.45, -2.5, 0.2, 2.3, -2.5, 0.5, 2.3, -2.5, 0.5, 2.3, -2.45, 0.5, 2.45, -2.45, 0.2, 2.45, -2.3, 0.2, 2.5, -2.22, 0, 2.4, -2.355, 0, 2.355, -2.355, 0, 2.355, -2.45, 0.2, 2.45, -2.3, 0.2, 2.5, -2.3, 0.5, 2.5, -2.3, 0.2, 2.5, -2.45, 0.2, 2.45, -2.45, 0.2, 2.45, -2.45, 0.5, 2.45, -2.3, 0.5, 2.5, 2.3, 0.2, 2.5, 2.22, 0, 2.4, -2.22, 0, 2.4, -2.22, 0, 2.4, -2.3, 0.2, 2.5, 2.3, 0.2, 2.5, -2.355, 0, 2.355, -2.4, 0, 2.22, -2.5, 0.2, 2.3, -2.5, 0.2, 2.3, -2.45, 0.2, 2.45, -2.355, 0, 2.355, -2.45, 0.5, -2.45, -2.45, 0.2, -2.45, -2.3, 0.2, -2.5, -2.3, 0.2, -2.5, -2.3, 0.5, -2.5, -2.45, 0.5, -2.45, 2.355, 0, 2.355, 2.4, 0, 2.22, 2.4, 0, -2.22, 2.4, 0, -2.22, 2.355, 0, -2.355, 2.355, 0, 2.355, 2.355, 0, -2.355, 2.22, 0, 2.4, 2.355, 0, 2.355, 2.355, 0, -2.355, 2.22, 0, -2.4, 2.22, 0, 2.4, 2.22, 0, -2.4, -2.22, 0, 2.4, 2.22, 0, 2.4, 2.22, 0, -2.4, -2.22, 0, -2.4, -2.22, 0, 2.4, -2.22, 0, -2.4, -2.355, 0, -2.355, -2.22, 0, 2.4, -2.355, 0, -2.355, -2.355, 0, 2.355, -2.22, 0, 2.4, -2.355, 0, -2.355, -2.4, 0, -2.22, -2.355, 0, 2.355, -2.4, 0, -2.22, -2.4, 0, 2.22, -2.355, 0, 2.355, -2.355, 0, -2.355, -2.45, 0.2, -2.45, -2.5, 0.2, -2.3, -2.5, 0.2, -2.3, -2.4, 0, -2.22, -2.355, 0, -2.355, 2.5, 0.2, -2.3, 2.45, 0.2, -2.45, 2.355, 0, -2.355, 2.355, 0, -2.355, 2.4, 0, -2.22, 2.5, 0.2, -2.3, -2.3, 0.2, -2.5, -2.22, 0, -2.4, 2.22, 0, -2.4, 2.22, 0, -2.4, 2.3, 0.2, -2.5, -2.3, 0.2, -2.5, 2.5, 0.5, 2.3, 2.5, 0.5, -2.3, 2.5, 0.2, -2.3, 2.5, 0.2, -2.3, 2.5, 0.2, 2.3, 2.5, 0.5, 2.3, 2.5, 0.2, 2.3, 2.5, 0.2, -2.3, 2.4, 0, -2.22, 2.4, 0, -2.22, 2.4, 0, 2.22, 2.5, 0.2, 2.3, 2.3, 0.2, -2.5, 2.22, 0, -2.4, 2.355, 0, -2.355, 2.355, 0, -2.355, 2.45, 0.2, -2.45, 2.3, 0.2, -2.5, -2.5, 0.2, 2.3, -2.5, 0.2, -2.3, -2.5, 0.5, -2.3, -2.5, 0.5, -2.3, -2.5, 0.5, 2.3, -2.5, 0.2, 2.3, -2.5, 0.2, -2.3, -2.45, 0.2, -2.45, -2.45, 0.5, -2.45, -2.45, 0.5, -2.45, -2.5, 0.5, -2.3, -2.5, 0.2, -2.3, 2.3, 0.5, -2.5, 2.3, 0.2, -2.5, 2.45, 0.2, -2.45, 2.45, 0.2, -2.45, 2.45, 0.5, -2.45, 2.3, 0.5, -2.5, 2.5, 0.5, -2.3, 2.45, 0.5, -2.45, 2.45, 0.2, -2.45, 2.45, 0.2, -2.45, 2.5, 0.2, -2.3, 2.5, 0.5, -2.3, -2.45, 0.2, -2.45, -2.355, 0, -2.355, -2.22, 0, -2.4, -2.22, 0, -2.4, -2.3, 0.2, -2.5, -2.45, 0.2, -2.45, -2.4, 0, -2.22, -2.5, 0.2, -2.3, -2.5, 0.2, 2.3, -2.5, 0.2, 2.3, -2.4, 0, 2.22, -2.4, 0, -2.22, -2.3, 0.5, -2.5, -2.3, 0.2, -2.5, 2.3, 0.2, -2.5, 2.3, 0.2, -2.5, 2.3, 0.5, -2.5, -2.3, 0.5, -2.5, 2.5, 0.5, -2.3, 2.5, 0.5, 2.3, 2.45, 0.5, 2.45, 2.45, 0.5, 2.45, 2.45, 0.5, -2.45, 2.5, 0.5, -2.3, 2.45, 0.5, 2.45, 2.3, 0.5, -2.5, 2.45, 0.5, -2.45, 2.45, 0.5, 2.45, 2.3, 0.5, 2.2675, 2.3, 0.5, -2.5, 2.3, 0.5, 2.2675, 2.45, 0.5, 2.45, 2.3, 0.5, 2.5, 2.3, 0.5, 2.5, 2.2919, 0.5, 2.2919, 2.3, 0.5, 2.2675, 2.3, 0.5, 2.5, 2.2675, 0.5, 2.3, 2.2919, 0.5, 2.2919, 2.3, 0.5, 2.2675, 2.3, 0.5, -2.2675, 2.3, 0.5, -2.5, 2.3, 0.5, -2.2675, 2.2919, 0.5, -2.2919, 2.3, 0.5, -2.5, 2.2919, 0.5, -2.2919, 2.2675, 0.5, -2.3, 2.3, 0.5, -2.5, 2.3, 0.5, 2.5, -2.3, 0.5, 2.5, 2.2675, 0.5, 2.3, 2.2675, 0.5, -2.3, -2.3, 0.5, -2.5, 2.3, 0.5, -2.5, -2.3, 0.5, 2.5, -2.2675, 0.5, 2.3, 2.2675, 0.5, 2.3, 2.2675, 0.5, -2.3, -2.2675, 0.5, -2.3, -2.3, 0.5, -2.5, -2.2675, 0.5, -2.3, -2.2919, 0.5, -2.2919, -2.3, 0.5, -2.5, -2.2919, 0.5, -2.2919, -2.3, 0.5, -2.2675, -2.3, 0.5, -2.5, -2.3, 0.5, 2.5, -2.2919, 0.5, 2.2919, -2.2675, 0.5, 2.3, -2.3, 0.5, -2.2675, -2.45, 0.5, -2.45, -2.3, 0.5, -2.5, -2.3, 0.5, 2.5, -2.3, 0.5, 2.2675, -2.2919, 0.5, 2.2919, -2.3, 0.5, -2.2675, -2.3, 0.5, 2.2675, -2.45, 0.5, -2.45, -2.3, 0.5, 2.2675, -2.3, 0.5, 2.5, -2.45, 0.5, -2.45, -2.3, 0.5, 2.5, -2.45, 0.5, 2.45, -2.45, 0.5, -2.45, -2.45, 0.5, 2.45, -2.5, 0.5, -2.3, -2.45, 0.5, -2.45, -2.45, 0.5, 2.45, -2.5, 0.5, 2.3, -2.5, 0.5, -2.3, 2.3, 0.5, -2.2675, 2.3, 0.5, 2.2675, 2.2919, 0.5, 2.2919, 2.2919, 0.5, 2.2919, 2.2919, 0.5, -2.2919, 2.3, 0.5, -2.2675, 2.2919, 0.5, 2.2919, 2.2675, 0.5, 2.3, 2.2919, 0.5, -2.2919, 2.2675, 0.5, 2.3, 2.2675, 0.5, -2.3, 2.2919, 0.5, -2.2919, 2.2675, 0.5, 2.3, 2.1, 0.5, -2.1, 2.2675, 0.5, -2.3, 2.1, 0.5, -2.1, -2.2675, 0.5, -2.3, 2.2675, 0.5, -2.3, 2.1, 0.5, 2.1, 2.1, 0.5, -2.1, 2.2675, 0.5, 2.3, 2.1, 0.5, -2.1, -2.1, 0.5, -2.1, -2.2675, 0.5, -2.3, 2.2675, 0.5, 2.3, -2.2675, 0.5, 2.3, 2.1, 0.5, 2.1, -2.1, 0.5, -2.1, -2.1, 0.5, 2.1, -2.2675, 0.5, -2.3, -2.2675, 0.5, 2.3, -2.1, 0.5, 2.1, 2.1, 0.5, 2.1, -2.2675, 0.5, 2.3, -2.2675, 0.5, -2.3, -2.1, 0.5, 2.1, -2.2675, 0.5, 2.3, -2.2919, 0.5, -2.2919, -2.2675, 0.5, -2.3, -2.2675, 0.5, 2.3, -2.2919, 0.5, 2.2919, -2.2919, 0.5, -2.2919, -2.2919, 0.5, 2.2919, -2.3, 0.5, -2.2675, -2.2919, 0.5, -2.2919, -2.2919, 0.5, 2.2919, -2.3, 0.5, 2.2675, -2.3, 0.5, -2.2675, -2.1, 0.5, -2.1, 2.1, 0.5, -2.1, 2.1, 0.5, 2.1, 2.1, 0.5, 2.1, -2.1, 0.5, 2.1, -2.1, 0.5, -2.1) diff --git a/assets/kenney-fps/objects/player.gd b/assets/kenney-fps/objects/player.gd index 2d06a7b..dd9a240 100644 --- a/assets/kenney-fps/objects/player.gd +++ b/assets/kenney-fps/objects/player.gd @@ -84,7 +84,7 @@ func _process(delta): camera.position.y = lerp(camera.position.y, 0.0, delta * 5) if is_on_floor() and gravity > 1 and !previously_floored: # Landed - Audio.play("sounds/land.ogg") + Audio.play("assets/kenney-fps/sounds/land.ogg") camera.position.y = -0.1 previously_floored = is_on_floor() @@ -102,19 +102,18 @@ func _input(event): handle_rotation(event.relative.x, event.relative.y, false) func handle_controls(delta): - # Mouse capture - if Input.is_action_just_pressed("mouse_capture"): - Input.mouse_mode = Input.MOUSE_MODE_CAPTURED - mouse_captured = true - - if Input.is_action_just_pressed("mouse_capture_exit"): - Input.mouse_mode = Input.MOUSE_MODE_VISIBLE - mouse_captured = false - - input_mouse = Vector2.ZERO + # Mouse capture — Escape toggles + if Input.is_action_just_pressed("escape"): + if mouse_captured: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + mouse_captured = false + input_mouse = Vector2.ZERO + else: + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + mouse_captured = true # Movement - var input := Input.get_vector("move_left", "move_right", "move_forward", "move_back") + var input := Input.get_vector("move_west", "move_east", "move_north", "move_south") movement_velocity = Vector3(input.x, 0, input.y).normalized() * movement_speed # Handle Controller Rotation @@ -165,7 +164,7 @@ func handle_gravity(delta): # Jumping func action_jump(): - Audio.play("sounds/jump_a.ogg, sounds/jump_b.ogg, sounds/jump_c.ogg") + Audio.play("assets/kenney-fps/sounds/jump_a.ogg, assets/kenney-fps/sounds/jump_b.ogg, assets/kenney-fps/sounds/jump_c.ogg") gravity = - jump_strength jumps_remaining -= 1 @@ -206,7 +205,7 @@ func action_shoot(): # Creating an impact animation - var impact = preload("res://objects/impact.tscn") + var impact = preload("res://assets/kenney-fps/objects/impact.tscn") var impact_instance = impact.instantiate() impact_instance.play("shot") @@ -232,7 +231,7 @@ func action_weapon_toggle(): weapon_index = wrap(weapon_index + 1, 0, weapons.size()) initiate_change_weapon(weapon_index) - Audio.play("sounds/weapon_change.ogg") + Audio.play("assets/kenney-fps/sounds/weapon_change.ogg") # Initiates the weapon changing animation (tween) diff --git a/assets/kenney-fps/objects/player.tscn b/assets/kenney-fps/objects/player.tscn index 55db1e1..5d2ac26 100644 --- a/assets/kenney-fps/objects/player.tscn +++ b/assets/kenney-fps/objects/player.tscn @@ -1,12 +1,12 @@ [gd_scene load_steps=9 format=3 uid="uid://dl2ed4gkybggf"] -[ext_resource type="Script" uid="uid://cu47grjp072jk" path="res://objects/player.gd" id="1_ffboj"] -[ext_resource type="Resource" uid="uid://cu2gtxlcmbb34" path="res://weapons/blaster-repeater.tres" id="2_6epbw"] -[ext_resource type="Texture2D" uid="uid://8ggihh27mlrr" path="res://sprites/blob_shadow.png" id="2_b0fo8"] -[ext_resource type="Script" uid="uid://dg01pkkc1c5vd" path="res://scripts/weapon.gd" id="2_i825w"] -[ext_resource type="Resource" uid="uid://c56y8pqoyk15f" path="res://weapons/blaster.tres" id="3_kr4p8"] -[ext_resource type="SpriteFrames" uid="uid://dbv3sy5qjatnl" path="res://sprites/burst_animation.tres" id="4_m6ukc"] -[ext_resource type="AudioStream" uid="uid://cydjn1ct3hps2" path="res://sounds/walking.ogg" id="5_ics1s"] +[ext_resource type="Script" uid="uid://cu47grjp072jk" path="res://assets/kenney-fps/objects/player.gd" id="1_ffboj"] +[ext_resource type="Resource" uid="uid://quaternius_pistol_auto" path="res://assets/quaternius/weapons/pistol.tres" id="2_6epbw"] +[ext_resource type="Texture2D" uid="uid://8ggihh27mlrr" path="res://assets/kenney-fps/sprites/blob_shadow.png" id="2_b0fo8"] +[ext_resource type="Script" uid="uid://dg01pkkc1c5vd" path="res://assets/kenney-fps/scripts/weapon.gd" id="2_i825w"] +[ext_resource type="Resource" uid="uid://quaternius_rifle_auto" path="res://assets/quaternius/weapons/rifle.tres" id="3_kr4p8"] +[ext_resource type="SpriteFrames" uid="uid://dbv3sy5qjatnl" path="res://assets/kenney-fps/sprites/burst_animation.tres" id="4_m6ukc"] +[ext_resource type="AudioStream" uid="uid://cydjn1ct3hps2" path="res://assets/kenney-fps/sounds/walking.ogg" id="5_ics1s"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_gdq8c"] radius = 0.3 diff --git a/assets/kenney-fps/objects/wall_high.tscn b/assets/kenney-fps/objects/wall_high.tscn index a03b970..0abeca7 100644 --- a/assets/kenney-fps/objects/wall_high.tscn +++ b/assets/kenney-fps/objects/wall_high.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://c71evdjblk5wp"] -[ext_resource type="PackedScene" uid="uid://c743irj356lax" path="res://models/wall-high.glb" id="1_uytvm"] +[ext_resource type="PackedScene" uid="uid://c743irj356lax" path="res://assets/kenney-fps/models/wall-high.glb" id="1_uytvm"] [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_uw3vt"] data = PackedVector3Array(-0.0721, 1.65, 0.35, -0.0721, 1.7, 0.3, 0.0279, 1.7, 0.35, -0.1721, 1.7, 0.35, -0.0721, 1.7, 0.3, -0.0721, 1.65, 0.35, 0.2459, 1.7, 0.265, 0.2459, 1.615, 0.35, 0.1354, 1.7, 0.35, 0.2459, 1.7, 0.265, 0.3564, 1.7, 0.35, 0.2459, 1.615, 0.35, 0.3337, 0.2, 0.265, 0.4374, 0.2, 0.35, 0.3337, 0.115, 0.35, 0.3337, 0.2, 0.265, 0.3337, 0.115, 0.35, 0.23, 0.2, 0.35, 0.3103, 1.7, -0.265, 0.3103, 1.615, -0.35, 0.4276, 1.7, -0.35, 0.3103, 1.7, -0.265, 0.193, 1.7, -0.35, 0.3103, 1.615, -0.35, -0.0906, 0.2, -0.265, -0.2606, 0.2, -0.35, -0.0906, 0.115, -0.35, -0.0906, 0.2, -0.265, -0.0906, 0.115, -0.35, 0.0794, 0.2, -0.35, -0.75, 0, 0.3, -0.75, 0, -0.3, -0.75, 0.2, -0.3, -0.75, 0.2, -0.3, -0.75, 0.2, 0.3, -0.75, 0, 0.3, -0.75, 0, -0.3, -0.7, 0, -0.35, -0.7, 0.2, -0.35, -0.7, 0.2, -0.35, -0.75, 0.2, -0.3, -0.75, 0, -0.3, -0.7, 0, 0.35, -0.75, 0, 0.3, -0.75, 0.2, 0.3, -0.75, 0.2, 0.3, -0.7, 0.2, 0.35, -0.7, 0, 0.35, -0.75, 1.5, -0.3, -0.7, 1.5, -0.35, -0.7, 1.7, -0.35, -0.7, 1.7, -0.35, -0.75, 1.7, -0.3, -0.75, 1.5, -0.3, -0.7, 1.5, 0.35, -0.75, 1.5, 0.3, -0.75, 1.7, 0.3, -0.75, 1.7, 0.3, -0.7, 1.7, 0.35, -0.7, 1.5, 0.35, -0.75, 1.5, 0.3, -0.75, 1.5, -0.3, -0.75, 1.7, -0.3, -0.75, 1.7, -0.3, -0.75, 1.7, 0.3, -0.75, 1.5, 0.3, -0.0721, 1.65, 0.35, 0.0279, 1.7, 0.35, 0.1354, 1.7, 0.35, 0.1354, 1.7, 0.35, 0.2459, 1.615, 0.35, -0.0721, 1.65, 0.35, -0.7, 1.7, 0.35, -0.0721, 1.65, 0.35, 0.2459, 1.615, 0.35, -0.7, 1.7, 0.35, -0.1721, 1.7, 0.35, -0.0721, 1.65, 0.35, 0.2459, 1.615, 0.35, -0.7, 1.5, 0.35, -0.7, 1.7, 0.35, 0.7, 1.5, 0.35, -0.7, 1.5, 0.35, 0.2459, 1.615, 0.35, 0.2459, 1.615, 0.35, 0.7, 1.7, 0.35, 0.7, 1.5, 0.35, 0.2459, 1.615, 0.35, 0.3564, 1.7, 0.35, 0.7, 1.7, 0.35, 0.7, 0.2, 0.35, 0.75, 0.2, 0.3, 0.75, 0, 0.3, 0.75, 0, 0.3, 0.7, 0, 0.35, 0.7, 0.2, 0.35, 0.7, 0.2, -0.35, 0.75, 0.2, -0.3, 0.75, 0.2, 0.3, 0.75, 0.2, 0.3, 0.7, 0.2, 0.35, 0.7, 0.2, -0.35, 0.7, 0.2, 0.35, 0.65, 0.2, -0.25, 0.7, 0.2, -0.35, 0.65, 0.2, -0.25, 0.0794, 0.2, -0.35, 0.7, 0.2, -0.35, 0.65, 0.2, -0.25, -0.0906, 0.2, -0.265, 0.0794, 0.2, -0.35, 0.65, 0.2, 0.25, 0.65, 0.2, -0.25, 0.7, 0.2, 0.35, 0.7, 0.2, 0.35, 0.4374, 0.2, 0.35, 0.65, 0.2, 0.25, 0.4374, 0.2, 0.35, 0.3337, 0.2, 0.265, 0.65, 0.2, 0.25, 0.65, 0.2, -0.25, -0.65, 0.2, -0.25, -0.0906, 0.2, -0.265, -0.65, 0.2, -0.25, -0.2606, 0.2, -0.35, -0.0906, 0.2, -0.265, 0.3337, 0.2, 0.265, -0.65, 0.2, 0.25, 0.65, 0.2, 0.25, -0.65, 0.2, -0.25, -0.7, 0.2, -0.35, -0.2606, 0.2, -0.35, -0.65, 0.2, -0.25, -0.65, 0.2, 0.25, -0.7, 0.2, -0.35, 0.3337, 0.2, 0.265, 0.23, 0.2, 0.35, -0.65, 0.2, 0.25, 0.23, 0.2, 0.35, -0.7, 0.2, 0.35, -0.65, 0.2, 0.25, -0.7, 0.2, 0.35, -0.7, 0.2, -0.35, -0.65, 0.2, 0.25, -0.7, 0.2, 0.35, -0.75, 0.2, -0.3, -0.7, 0.2, -0.35, -0.7, 0.2, 0.35, -0.75, 0.2, 0.3, -0.75, 0.2, -0.3, -0.7, 0.2, -0.35, -0.7, 0, -0.35, 0.7, 0, -0.35, 0.7, 0, -0.35, -0.0906, 0.115, -0.35, -0.7, 0.2, -0.35, -0.0906, 0.115, -0.35, -0.2606, 0.2, -0.35, -0.7, 0.2, -0.35, -0.0906, 0.115, -0.35, 0.7, 0, -0.35, 0.7, 0.2, -0.35, 0.7, 0.2, -0.35, 0.0794, 0.2, -0.35, -0.0906, 0.115, -0.35, 0.75, 0.2, 0.3, 0.75, 0.2, -0.3, 0.75, 0, -0.3, 0.75, 0, -0.3, 0.75, 0, 0.3, 0.75, 0.2, 0.3, 0.7, 1.7, 0.35, 0.75, 1.7, 0.3, 0.75, 1.5, 0.3, 0.75, 1.5, 0.3, 0.7, 1.5, 0.35, 0.7, 1.7, 0.35, 0.75, 1.7, 0.3, 0.75, 1.7, -0.3, 0.75, 1.5, -0.3, 0.75, 1.5, -0.3, 0.75, 1.5, 0.3, 0.75, 1.7, 0.3, 0.7, 1.7, -0.35, 0.75, 1.7, -0.3, 0.75, 1.7, 0.3, 0.75, 1.7, 0.3, 0.7, 1.7, 0.35, 0.7, 1.7, -0.35, 0.7, 1.7, 0.35, 0.4276, 1.7, -0.35, 0.7, 1.7, -0.35, 0.7, 1.7, 0.35, 0.3564, 1.7, 0.35, 0.4276, 1.7, -0.35, 0.3564, 1.7, 0.35, 0.3103, 1.7, -0.265, 0.4276, 1.7, -0.35, 0.3564, 1.7, 0.35, 0.2459, 1.7, 0.265, 0.3103, 1.7, -0.265, 0.2459, 1.7, 0.265, 0.193, 1.7, -0.35, 0.3103, 1.7, -0.265, 0.2459, 1.7, 0.265, 0.1354, 1.7, 0.35, 0.193, 1.7, -0.35, 0.1354, 1.7, 0.35, -0.7, 1.7, -0.35, 0.193, 1.7, -0.35, 0.1354, 1.7, 0.35, 0.0279, 1.7, 0.35, -0.7, 1.7, -0.35, 0.0279, 1.7, 0.35, -0.0721, 1.7, 0.3, -0.7, 1.7, -0.35, -0.0721, 1.7, 0.3, -0.1721, 1.7, 0.35, -0.7, 1.7, -0.35, -0.1721, 1.7, 0.35, -0.7, 1.7, 0.35, -0.7, 1.7, -0.35, -0.7, 1.7, 0.35, -0.75, 1.7, -0.3, -0.7, 1.7, -0.35, -0.7, 1.7, 0.35, -0.75, 1.7, 0.3, -0.75, 1.7, -0.3, 0.75, 1.7, -0.3, 0.7, 1.7, -0.35, 0.7, 1.5, -0.35, 0.7, 1.5, -0.35, 0.75, 1.5, -0.3, 0.75, 1.7, -0.3, 0.7, 1.5, 0.35, 0.75, 1.5, 0.3, 0.75, 1.5, -0.3, 0.75, 1.5, -0.3, 0.7, 1.5, -0.35, 0.7, 1.5, 0.35, 0.7, 1.5, -0.35, 0.65, 1.5, 0.25, 0.7, 1.5, 0.35, 0.65, 1.5, 0.25, -0.7, 1.5, 0.35, 0.7, 1.5, 0.35, 0.65, 1.5, -0.25, 0.65, 1.5, 0.25, 0.7, 1.5, -0.35, 0.65, 1.5, 0.25, -0.65, 1.5, 0.25, -0.7, 1.5, 0.35, 0.7, 1.5, -0.35, -0.7, 1.5, -0.35, 0.65, 1.5, -0.25, -0.65, 1.5, 0.25, -0.65, 1.5, -0.25, -0.7, 1.5, 0.35, -0.7, 1.5, -0.35, -0.65, 1.5, -0.25, 0.65, 1.5, -0.25, -0.7, 1.5, -0.35, -0.7, 1.5, 0.35, -0.65, 1.5, -0.25, -0.7, 1.5, -0.35, -0.75, 1.5, 0.3, -0.7, 1.5, 0.35, -0.7, 1.5, -0.35, -0.75, 1.5, -0.3, -0.75, 1.5, 0.3, -0.7, 1.7, -0.35, -0.7, 1.5, -0.35, 0.7, 1.5, -0.35, 0.7, 1.5, -0.35, 0.3103, 1.615, -0.35, -0.7, 1.7, -0.35, 0.3103, 1.615, -0.35, 0.193, 1.7, -0.35, -0.7, 1.7, -0.35, 0.3103, 1.615, -0.35, 0.7, 1.5, -0.35, 0.7, 1.7, -0.35, 0.7, 1.7, -0.35, 0.4276, 1.7, -0.35, 0.3103, 1.615, -0.35, 0.7, 0, 0.35, 0.75, 0, 0.3, 0.75, 0, -0.3, 0.75, 0, -0.3, 0.7, 0, -0.35, 0.7, 0, 0.35, 0.7, 0, -0.35, -0.7, 0, 0.35, 0.7, 0, 0.35, 0.7, 0, -0.35, -0.7, 0, -0.35, -0.7, 0, 0.35, -0.7, 0, -0.35, -0.75, 0, 0.3, -0.7, 0, 0.35, -0.7, 0, -0.35, -0.75, 0, -0.3, -0.75, 0, 0.3, 0.75, 0.2, -0.3, 0.7, 0.2, -0.35, 0.7, 0, -0.35, 0.7, 0, -0.35, 0.75, 0, -0.3, 0.75, 0.2, -0.3, 0.3337, 0.115, 0.35, 0.4374, 0.2, 0.35, 0.7, 0.2, 0.35, 0.3337, 0.115, 0.35, 0.7, 0.2, 0.35, 0.7, 0, 0.35, 0.7, 0, 0.35, -0.7, 0, 0.35, 0.3337, 0.115, 0.35, 0.3337, 0.115, 0.35, -0.7, 0, 0.35, -0.7, 0.2, 0.35, -0.7, 0.2, 0.35, 0.23, 0.2, 0.35, 0.3337, 0.115, 0.35, -0.65, 0.2, 0.25, -0.65, 0.2, -0.25, -0.65, 1.5, -0.25, -0.65, 1.5, -0.25, -0.65, 1.5, 0.25, -0.65, 0.2, 0.25, 0.65, 1.5, 0.25, 0.65, 1.5, -0.25, 0.65, 0.2, -0.25, 0.65, 0.2, -0.25, 0.65, 0.2, 0.25, 0.65, 1.5, 0.25, -0.65, 1.5, -0.25, -0.65, 0.2, -0.25, 0.65, 0.2, -0.25, 0.65, 0.2, -0.25, 0.65, 1.5, -0.25, -0.65, 1.5, -0.25, -0.65, 1.5, -0.25, 0.65, 1.5, -0.25, 0.65, 1.5, 0.25, 0.65, 1.5, 0.25, -0.65, 1.5, 0.25, -0.65, 1.5, -0.25, 0.65, 1.5, 0.25, 0.65, 0.2, 0.25, -0.65, 0.2, 0.25, -0.65, 0.2, 0.25, -0.65, 1.5, 0.25, 0.65, 1.5, 0.25, 0.288, 0.3863, 0.2815, 0.264, 0.3863, 0.25, 0.264, 0.4948, 0.25, 0.264, 0.4948, 0.25, 0.288, 0.4948, 0.2815, 0.288, 0.3863, 0.2815, 0.4181, 0.4948, 0.2815, 0.4181, 0.3863, 0.2815, 0.288, 0.3863, 0.2815, 0.288, 0.3863, 0.2815, 0.288, 0.4948, 0.2815, 0.4181, 0.4948, 0.2815, 0.4181, 0.3863, 0.2815, 0.4421, 0.3863, 0.25, 0.264, 0.3863, 0.25, 0.264, 0.3863, 0.25, 0.288, 0.3863, 0.2815, 0.4181, 0.3863, 0.2815, 0.4181, 0.4948, 0.2815, 0.4421, 0.4948, 0.25, 0.4421, 0.3863, 0.25, 0.4421, 0.3863, 0.25, 0.4181, 0.3863, 0.2815, 0.4181, 0.4948, 0.2815, 0.264, 0.4948, 0.25, 0.4421, 0.4948, 0.25, 0.4181, 0.4948, 0.2815, 0.4181, 0.4948, 0.2815, 0.288, 0.4948, 0.2815, 0.264, 0.4948, 0.25, -0.4779, 0.5479, 0.2815, -0.5018, 0.5479, 0.25, -0.5018, 0.6564, 0.25, -0.5018, 0.6564, 0.25, -0.4779, 0.6564, 0.2815, -0.4779, 0.5479, 0.2815, -0.3477, 0.6564, 0.2815, -0.3477, 0.5479, 0.2815, -0.4779, 0.5479, 0.2815, -0.4779, 0.5479, 0.2815, -0.4779, 0.6564, 0.2815, -0.3477, 0.6564, 0.2815, -0.3477, 0.5479, 0.2815, -0.3238, 0.5479, 0.25, -0.5018, 0.5479, 0.25, -0.5018, 0.5479, 0.25, -0.4779, 0.5479, 0.2815, -0.3477, 0.5479, 0.2815, -0.3477, 0.6564, 0.2815, -0.3238, 0.6564, 0.25, -0.3238, 0.5479, 0.25, -0.3238, 0.5479, 0.25, -0.3477, 0.5479, 0.2815, -0.3477, 0.6564, 0.2815, -0.5018, 0.6564, 0.25, -0.3238, 0.6564, 0.25, -0.3477, 0.6564, 0.2815, -0.3477, 0.6564, 0.2815, -0.4779, 0.6564, 0.2815, -0.5018, 0.6564, 0.25, -0.3579, 0.7066, 0.2815, -0.3819, 0.7066, 0.25, -0.3819, 0.815, 0.25, -0.3819, 0.815, 0.25, -0.3579, 0.815, 0.2815, -0.3579, 0.7066, 0.2815, -0.2278, 0.815, 0.2815, -0.2278, 0.7066, 0.2815, -0.3579, 0.7066, 0.2815, -0.3579, 0.7066, 0.2815, -0.3579, 0.815, 0.2815, -0.2278, 0.815, 0.2815, -0.2278, 0.7066, 0.2815, -0.2039, 0.7066, 0.25, -0.3819, 0.7066, 0.25, -0.3819, 0.7066, 0.25, -0.3579, 0.7066, 0.2815, -0.2278, 0.7066, 0.2815, -0.2278, 0.815, 0.2815, -0.2039, 0.815, 0.25, -0.2039, 0.7066, 0.25, -0.2039, 0.7066, 0.25, -0.2278, 0.7066, 0.2815, -0.2278, 0.815, 0.2815, -0.3819, 0.815, 0.25, -0.2039, 0.815, 0.25, -0.2278, 0.815, 0.2815, -0.2278, 0.815, 0.2815, -0.3579, 0.815, 0.2815, -0.3819, 0.815, 0.25, 0.1283, 1.252, 0.2815, 0.1044, 1.252, 0.25, 0.1044, 1.3605, 0.25, 0.1044, 1.3605, 0.25, 0.1283, 1.3605, 0.2815, 0.1283, 1.252, 0.2815, 0.2585, 1.3605, 0.2815, 0.2585, 1.252, 0.2815, 0.1283, 1.252, 0.2815, 0.1283, 1.252, 0.2815, 0.1283, 1.3605, 0.2815, 0.2585, 1.3605, 0.2815, 0.2585, 1.252, 0.2815, 0.2824, 1.252, 0.25, 0.1044, 1.252, 0.25, 0.1044, 1.252, 0.25, 0.1283, 1.252, 0.2815, 0.2585, 1.252, 0.2815, 0.2585, 1.3605, 0.2815, 0.2824, 1.3605, 0.25, 0.2824, 1.252, 0.25, 0.2824, 1.252, 0.25, 0.2585, 1.252, 0.2815, 0.2585, 1.3605, 0.2815, 0.1044, 1.3605, 0.25, 0.2824, 1.3605, 0.25, 0.2585, 1.3605, 0.2815, 0.2585, 1.3605, 0.2815, 0.1283, 1.3605, 0.2815, 0.1044, 1.3605, 0.25, -0.1236, 0.4737, -0.2815, -0.0996, 0.4737, -0.25, -0.0996, 0.5822, -0.25, -0.0996, 0.5822, -0.25, -0.1236, 0.5822, -0.2815, -0.1236, 0.4737, -0.2815, -0.2537, 0.5822, -0.2815, -0.2537, 0.4737, -0.2815, -0.1236, 0.4737, -0.2815, -0.1236, 0.4737, -0.2815, -0.1236, 0.5822, -0.2815, -0.2537, 0.5822, -0.2815, -0.2537, 0.4737, -0.2815, -0.2776, 0.4737, -0.25, -0.0996, 0.4737, -0.25, -0.0996, 0.4737, -0.25, -0.1236, 0.4737, -0.2815, -0.2537, 0.4737, -0.2815, -0.2537, 0.5822, -0.2815, -0.2776, 0.5822, -0.25, -0.2776, 0.4737, -0.25, -0.2776, 0.4737, -0.25, -0.2537, 0.4737, -0.2815, -0.2537, 0.5822, -0.2815, -0.0996, 0.5822, -0.25, -0.2776, 0.5822, -0.25, -0.2537, 0.5822, -0.2815, -0.2537, 0.5822, -0.2815, -0.1236, 0.5822, -0.2815, -0.0996, 0.5822, -0.25, -0.2435, 0.6338, -0.2815, -0.2196, 0.6338, -0.25, -0.2196, 0.7423, -0.25, -0.2196, 0.7423, -0.25, -0.2435, 0.7423, -0.2815, -0.2435, 0.6338, -0.2815, -0.3737, 0.7423, -0.2815, -0.3737, 0.6338, -0.2815, -0.2435, 0.6338, -0.2815, -0.2435, 0.6338, -0.2815, -0.2435, 0.7423, -0.2815, -0.3737, 0.7423, -0.2815, -0.3737, 0.6338, -0.2815, -0.3976, 0.6338, -0.25, -0.2196, 0.6338, -0.25, -0.2196, 0.6338, -0.25, -0.2435, 0.6338, -0.2815, -0.3737, 0.6338, -0.2815, -0.3737, 0.7423, -0.2815, -0.3976, 0.7423, -0.25, -0.3976, 0.6338, -0.25, -0.3976, 0.6338, -0.25, -0.3737, 0.6338, -0.2815, -0.3737, 0.7423, -0.2815, -0.2196, 0.7423, -0.25, -0.3976, 0.7423, -0.25, -0.3737, 0.7423, -0.2815, -0.3737, 0.7423, -0.2815, -0.2435, 0.7423, -0.2815, -0.2196, 0.7423, -0.25, 0.381, 1.1075, -0.2815, 0.4049, 1.1075, -0.25, 0.4049, 1.216, -0.25, 0.4049, 1.216, -0.25, 0.381, 1.216, -0.2815, 0.381, 1.1075, -0.2815, 0.2508, 1.216, -0.2815, 0.2508, 1.1075, -0.2815, 0.381, 1.1075, -0.2815, 0.381, 1.1075, -0.2815, 0.381, 1.216, -0.2815, 0.2508, 1.216, -0.2815, 0.2508, 1.1075, -0.2815, 0.2269, 1.1075, -0.25, 0.4049, 1.1075, -0.25, 0.4049, 1.1075, -0.25, 0.381, 1.1075, -0.2815, 0.2508, 1.1075, -0.2815, 0.2508, 1.216, -0.2815, 0.2269, 1.216, -0.25, 0.2269, 1.1075, -0.25, 0.2269, 1.1075, -0.25, 0.2508, 1.1075, -0.2815, 0.2508, 1.216, -0.2815, 0.4049, 1.216, -0.25, 0.2269, 1.216, -0.25, 0.2508, 1.216, -0.2815, 0.2508, 1.216, -0.2815, 0.381, 1.216, -0.2815, 0.4049, 1.216, -0.25, 0.6815, 0.5505, 0.0101, 0.65, 0.5505, 0.0341, 0.65, 0.659, 0.0341, 0.65, 0.659, 0.0341, 0.6815, 0.659, 0.0101, 0.6815, 0.5505, 0.0101, 0.6815, 0.659, -0.12, 0.6815, 0.5505, -0.12, 0.6815, 0.5505, 0.0101, 0.6815, 0.5505, 0.0101, 0.6815, 0.659, 0.0101, 0.6815, 0.659, -0.12, 0.6815, 0.5505, -0.12, 0.65, 0.5505, -0.1439, 0.65, 0.5505, 0.0341, 0.65, 0.5505, 0.0341, 0.6815, 0.5505, 0.0101, 0.6815, 0.5505, -0.12, 0.6815, 0.659, -0.12, 0.65, 0.659, -0.1439, 0.65, 0.5505, -0.1439, 0.65, 0.5505, -0.1439, 0.6815, 0.5505, -0.12, 0.6815, 0.659, -0.12, 0.65, 0.659, 0.0341, 0.65, 0.659, -0.1439, 0.6815, 0.659, -0.12, 0.6815, 0.659, -0.12, 0.6815, 0.659, 0.0101, 0.65, 0.659, 0.0341, -0.6815, 1.1149, -0.042, -0.65, 1.1149, -0.0659, -0.65, 1.2233, -0.0659, -0.65, 1.2233, -0.0659, -0.6815, 1.2233, -0.042, -0.6815, 1.1149, -0.042, -0.6815, 1.2233, 0.0882, -0.6815, 1.1149, 0.0882, -0.6815, 1.1149, -0.042, -0.6815, 1.1149, -0.042, -0.6815, 1.2233, -0.042, -0.6815, 1.2233, 0.0882, -0.6815, 1.1149, 0.0882, -0.65, 1.1149, 0.1121, -0.65, 1.1149, -0.0659, -0.65, 1.1149, -0.0659, -0.6815, 1.1149, -0.042, -0.6815, 1.1149, 0.0882, -0.6815, 1.2233, 0.0882, -0.65, 1.2233, 0.1121, -0.65, 1.1149, 0.1121, -0.65, 1.1149, 0.1121, -0.6815, 1.1149, 0.0882, -0.6815, 1.2233, 0.0882, -0.65, 1.2233, -0.0659, -0.65, 1.2233, 0.1121, -0.6815, 1.2233, 0.0882, -0.6815, 1.2233, 0.0882, -0.6815, 1.2233, -0.042, -0.65, 1.2233, -0.0659) diff --git a/assets/kenney-fps/objects/wall_low.tscn b/assets/kenney-fps/objects/wall_low.tscn index 6a8211d..49429b7 100644 --- a/assets/kenney-fps/objects/wall_low.tscn +++ b/assets/kenney-fps/objects/wall_low.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://r7rt7pth4u7o"] -[ext_resource type="PackedScene" uid="uid://x08pt5dvke58" path="res://models/wall-low.glb" id="1_6rbli"] +[ext_resource type="PackedScene" uid="uid://x08pt5dvke58" path="res://assets/kenney-fps/models/wall-low.glb" id="1_6rbli"] [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_rbsb6"] data = PackedVector3Array(-0.4221, 0.85, 0.3502, -0.4221, 0.9, 0.3002, -0.3221, 0.9, 0.3502, -0.5221, 0.9, 0.3502, -0.4221, 0.9, 0.3002, -0.4221, 0.85, 0.3502, -0.1041, 0.9, 0.2652, -0.1041, 0.815, 0.3502, -0.2146, 0.9, 0.3502, -0.1041, 0.9, 0.2652, 0.0064, 0.9, 0.3502, -0.1041, 0.815, 0.3502, 0.6837, 0.2, 0.2652, 0.7874, 0.2, 0.3502, 0.6837, 0.115, 0.3502, 0.6837, 0.2, 0.2652, 0.6837, 0.115, 0.3502, 0.58, 0.2, 0.3502, 0.6603, 0.9, -0.2648, 0.6603, 0.815, -0.3498, 0.7776, 0.9, -0.3498, 0.6603, 0.9, -0.2648, 0.543, 0.9, -0.3498, 0.6603, 0.815, -0.3498, -0.4406, 0.2, -0.2648, -0.6106, 0.2, -0.3498, -0.4406, 0.115, -0.3498, -0.4406, 0.2, -0.2648, -0.4406, 0.115, -0.3498, -0.2706, 0.2, -0.3498, -1.1, 0, 0.3002, -1.1, 0, -0.2998, -1.1, 0.2, -0.2998, -1.1, 0.2, -0.2998, -1.1, 0.2, 0.3002, -1.1, 0, 0.3002, 1.1, 0.2, 0.3002, 1.1, 0.2, -0.2998, 1.1, 0, -0.2998, 1.1, 0, -0.2998, 1.1, 0, 0.3002, 1.1, 0.2, 0.3002, -1.1, 0, -0.2998, -1.05, 0, -0.3498, -1.05, 0.2, -0.3498, -1.05, 0.2, -0.3498, -1.1, 0.2, -0.2998, -1.1, 0, -0.2998, -1.05, 0, 0.3502, -1.1, 0, 0.3002, -1.1, 0.2, 0.3002, -1.1, 0.2, 0.3002, -1.05, 0.2, 0.3502, -1.05, 0, 0.3502, 1.1, 0.2, -0.2998, 1.05, 0.2, -0.3498, 1.05, 0, -0.3498, 1.05, 0, -0.3498, 1.1, 0, -0.2998, 1.1, 0.2, -0.2998, 1.05, 0.2, 0.3502, 1.1, 0.2, 0.3002, 1.1, 0, 0.3002, 1.1, 0, 0.3002, 1.05, 0, 0.3502, 1.05, 0.2, 0.3502, 1.05, 0, 0.3502, 1.1, 0, 0.3002, 1.1, 0, -0.2998, 1.1, 0, -0.2998, 1.05, 0, -0.3498, 1.05, 0, 0.3502, 1.05, 0, -0.3498, -1.05, 0, 0.3502, 1.05, 0, 0.3502, 1.05, 0, -0.3498, -1.05, 0, -0.3498, -1.05, 0, 0.3502, -1.05, 0, -0.3498, -1.1, 0, 0.3002, -1.05, 0, 0.3502, -1.05, 0, -0.3498, -1.1, 0, -0.2998, -1.1, 0, 0.3002, 1.05, 0.9, 0.3502, 1.1, 0.9, 0.3002, 1.1, 0.7, 0.3002, 1.1, 0.7, 0.3002, 1.05, 0.7, 0.3502, 1.05, 0.9, 0.3502, 1.1, 0.9, 0.3002, 1.1, 0.9, -0.2998, 1.1, 0.7, -0.2998, 1.1, 0.7, -0.2998, 1.1, 0.7, 0.3002, 1.1, 0.9, 0.3002, 1.05, 0.9, -0.3498, 1.1, 0.9, -0.2998, 1.1, 0.9, 0.3002, 1.1, 0.9, 0.3002, 1.05, 0.9, 0.3502, 1.05, 0.9, -0.3498, 1.05, 0.9, 0.3502, 0.7776, 0.9, -0.3498, 1.05, 0.9, -0.3498, 1.05, 0.9, 0.3502, 0.0064, 0.9, 0.3502, 0.7776, 0.9, -0.3498, 0.0064, 0.9, 0.3502, 0.6603, 0.9, -0.2648, 0.7776, 0.9, -0.3498, 0.0064, 0.9, 0.3502, 0.543, 0.9, -0.3498, 0.6603, 0.9, -0.2648, 0.0064, 0.9, 0.3502, -0.1041, 0.9, 0.2652, 0.543, 0.9, -0.3498, -0.1041, 0.9, 0.2652, -1.05, 0.9, -0.3498, 0.543, 0.9, -0.3498, -0.1041, 0.9, 0.2652, -0.2146, 0.9, 0.3502, -1.05, 0.9, -0.3498, -0.2146, 0.9, 0.3502, -0.3221, 0.9, 0.3502, -1.05, 0.9, -0.3498, -0.3221, 0.9, 0.3502, -0.4221, 0.9, 0.3002, -1.05, 0.9, -0.3498, -0.4221, 0.9, 0.3002, -0.5221, 0.9, 0.3502, -1.05, 0.9, -0.3498, -0.5221, 0.9, 0.3502, -1.05, 0.9, 0.3502, -1.05, 0.9, -0.3498, -1.05, 0.9, 0.3502, -1.1, 0.9, -0.2998, -1.05, 0.9, -0.3498, -1.05, 0.9, 0.3502, -1.1, 0.9, 0.3002, -1.1, 0.9, -0.2998, -1.1, 0.7, -0.2998, -1.05, 0.7, -0.3498, -1.05, 0.9, -0.3498, -1.05, 0.9, -0.3498, -1.1, 0.9, -0.2998, -1.1, 0.7, -0.2998, 1.1, 0.9, -0.2998, 1.05, 0.9, -0.3498, 1.05, 0.7, -0.3498, 1.05, 0.7, -0.3498, 1.1, 0.7, -0.2998, 1.1, 0.9, -0.2998, 1.05, 0.7, 0.3502, 1.1, 0.7, 0.3002, 1.1, 0.7, -0.2998, 1.1, 0.7, -0.2998, 1.05, 0.7, -0.3498, 1.05, 0.7, 0.3502, 1.05, 0.7, -0.3498, 1, 0.7, 0.2502, 1.05, 0.7, 0.3502, 1, 0.7, 0.2502, -1.05, 0.7, 0.3502, 1.05, 0.7, 0.3502, 1, 0.7, -0.2498, 1, 0.7, 0.2502, 1.05, 0.7, -0.3498, 1, 0.7, 0.2502, -1, 0.7, 0.2502, -1.05, 0.7, 0.3502, 1.05, 0.7, -0.3498, -1.05, 0.7, -0.3498, 1, 0.7, -0.2498, -1, 0.7, 0.2502, -1, 0.7, -0.2498, -1.05, 0.7, 0.3502, -1.05, 0.7, -0.3498, -1, 0.7, -0.2498, 1, 0.7, -0.2498, -1.05, 0.7, -0.3498, -1.05, 0.7, 0.3502, -1, 0.7, -0.2498, -1.05, 0.7, -0.3498, -1.1, 0.7, 0.3002, -1.05, 0.7, 0.3502, -1.05, 0.7, -0.3498, -1.1, 0.7, -0.2998, -1.1, 0.7, 0.3002, -1.05, 0.7, 0.3502, -1.1, 0.7, 0.3002, -1.1, 0.9, 0.3002, -1.1, 0.9, 0.3002, -1.05, 0.9, 0.3502, -1.05, 0.7, 0.3502, -1.1, 0.7, 0.3002, -1.1, 0.7, -0.2998, -1.1, 0.9, -0.2998, -1.1, 0.9, -0.2998, -1.1, 0.9, 0.3002, -1.1, 0.7, 0.3002, -1.05, 0.9, -0.3498, -1.05, 0.7, -0.3498, 1.05, 0.7, -0.3498, 1.05, 0.7, -0.3498, 0.6603, 0.815, -0.3498, -1.05, 0.9, -0.3498, 0.6603, 0.815, -0.3498, 0.543, 0.9, -0.3498, -1.05, 0.9, -0.3498, 0.6603, 0.815, -0.3498, 1.05, 0.7, -0.3498, 1.05, 0.9, -0.3498, 1.05, 0.9, -0.3498, 0.7776, 0.9, -0.3498, 0.6603, 0.815, -0.3498, 1.05, 0.9, 0.3502, 1.05, 0.7, 0.3502, -1.05, 0.7, 0.3502, -1.05, 0.7, 0.3502, -0.1041, 0.815, 0.3502, 1.05, 0.9, 0.3502, -0.1041, 0.815, 0.3502, 0.0064, 0.9, 0.3502, 1.05, 0.9, 0.3502, -0.1041, 0.815, 0.3502, -1.05, 0.7, 0.3502, -1.05, 0.9, 0.3502, -1.05, 0.9, 0.3502, -0.4221, 0.85, 0.3502, -0.1041, 0.815, 0.3502, -1.05, 0.9, 0.3502, -0.5221, 0.9, 0.3502, -0.4221, 0.85, 0.3502, -0.2146, 0.9, 0.3502, -0.1041, 0.815, 0.3502, -0.4221, 0.85, 0.3502, -0.4221, 0.85, 0.3502, -0.3221, 0.9, 0.3502, -0.2146, 0.9, 0.3502, 0.6837, 0.115, 0.3502, 0.7874, 0.2, 0.3502, 1.05, 0.2, 0.3502, 0.6837, 0.115, 0.3502, 1.05, 0.2, 0.3502, 1.05, 0, 0.3502, 1.05, 0, 0.3502, -1.05, 0, 0.3502, 0.6837, 0.115, 0.3502, 0.6837, 0.115, 0.3502, -1.05, 0, 0.3502, -1.05, 0.2, 0.3502, -1.05, 0.2, 0.3502, 0.58, 0.2, 0.3502, 0.6837, 0.115, 0.3502, -0.4406, 0.115, -0.3498, -0.6106, 0.2, -0.3498, -1.05, 0.2, -0.3498, -0.4406, 0.115, -0.3498, -1.05, 0.2, -0.3498, -1.05, 0, -0.3498, -1.05, 0, -0.3498, 1.05, 0, -0.3498, -0.4406, 0.115, -0.3498, -0.4406, 0.115, -0.3498, 1.05, 0, -0.3498, 1.05, 0.2, -0.3498, 1.05, 0.2, -0.3498, -0.2706, 0.2, -0.3498, -0.4406, 0.115, -0.3498, 1.05, 0.2, -0.3498, 1.1, 0.2, -0.2998, 1.1, 0.2, 0.3002, 1.1, 0.2, 0.3002, 1.05, 0.2, 0.3502, 1.05, 0.2, -0.3498, 1.05, 0.2, 0.3502, 1, 0.2, -0.2498, 1.05, 0.2, -0.3498, 1, 0.2, -0.2498, -0.2706, 0.2, -0.3498, 1.05, 0.2, -0.3498, 1, 0.2, -0.2498, -0.4406, 0.2, -0.2648, -0.2706, 0.2, -0.3498, 1, 0.2, 0.2502, 1, 0.2, -0.2498, 1.05, 0.2, 0.3502, 1.05, 0.2, 0.3502, 0.7874, 0.2, 0.3502, 1, 0.2, 0.2502, 0.7874, 0.2, 0.3502, 0.6837, 0.2, 0.2652, 1, 0.2, 0.2502, 1, 0.2, -0.2498, -1, 0.2, -0.2498, -0.4406, 0.2, -0.2648, -1, 0.2, -0.2498, -0.6106, 0.2, -0.3498, -0.4406, 0.2, -0.2648, 0.6837, 0.2, 0.2652, -1, 0.2, 0.2502, 1, 0.2, 0.2502, -1, 0.2, -0.2498, -1.05, 0.2, -0.3498, -0.6106, 0.2, -0.3498, -1, 0.2, -0.2498, -1, 0.2, 0.2502, -1.05, 0.2, -0.3498, 0.6837, 0.2, 0.2652, 0.58, 0.2, 0.3502, -1, 0.2, 0.2502, 0.58, 0.2, 0.3502, -1.05, 0.2, 0.3502, -1, 0.2, 0.2502, -1.05, 0.2, 0.3502, -1.05, 0.2, -0.3498, -1, 0.2, 0.2502, -1.05, 0.2, 0.3502, -1.1, 0.2, -0.2998, -1.05, 0.2, -0.3498, -1.05, 0.2, 0.3502, -1.1, 0.2, 0.3002, -1.1, 0.2, -0.2998, -1, 0.7, -0.2498, 1, 0.7, -0.2498, 1, 0.7, 0.2502, 1, 0.7, 0.2502, -1, 0.7, 0.2502, -1, 0.7, -0.2498, -1, 0.2, 0.2502, -1, 0.2, -0.2498, -1, 0.7, -0.2498, -1, 0.7, -0.2498, -1, 0.7, 0.2502, -1, 0.2, 0.2502, 1, 0.7, 0.2502, 1, 0.7, -0.2498, 1, 0.2, -0.2498, 1, 0.2, -0.2498, 1, 0.2, 0.2502, 1, 0.7, 0.2502, -1, 0.2, -0.2498, 1, 0.2, -0.2498, -0.0568, 0.2737, -0.2498, -0.0568, 0.2737, -0.2498, -1, 0.7, -0.2498, -1, 0.2, -0.2498, 0.1282, 0.2737, -0.2498, -0.0568, 0.2737, -0.2498, 1, 0.2, -0.2498, -0.0568, 0.2737, -0.2498, -0.1123, 0.3292, -0.2498, -1, 0.7, -0.2498, 1, 0.2, -0.2498, 1, 0.7, -0.2498, 0.1282, 0.2737, -0.2498, -0.1123, 0.3292, -0.2498, -0.1123, 0.4402, -0.2498, -1, 0.7, -0.2498, -0.1123, 0.4402, -0.2498, -0.0568, 0.4957, -0.2498, -1, 0.7, -0.2498, -0.0568, 0.4957, -0.2498, 0.1282, 0.4957, -0.2498, -1, 0.7, -0.2498, 1, 0.7, -0.2498, -1, 0.7, -0.2498, 0.1282, 0.4957, -0.2498, 1, 0.7, -0.2498, 0.1837, 0.3292, -0.2498, 0.1282, 0.2737, -0.2498, 1, 0.7, -0.2498, 0.1282, 0.4957, -0.2498, 0.1837, 0.4402, -0.2498, 1, 0.7, -0.2498, 0.1837, 0.4402, -0.2498, 0.1837, 0.3292, -0.2498, -1, 0.7, 0.2502, -0.4665, 0.4698, 0.2502, -0.4665, 0.3588, 0.2502, -1, 0.7, 0.2502, -0.411, 0.5253, 0.2502, -0.4665, 0.4698, 0.2502, -1, 0.7, 0.2502, -0.4665, 0.3588, 0.2502, -0.411, 0.3033, 0.2502, -1, 0.2, 0.2502, -1, 0.7, 0.2502, -0.411, 0.3033, 0.2502, -0.411, 0.3033, 0.2502, -0.226, 0.3033, 0.2502, -1, 0.2, 0.2502, 1, 0.2, 0.2502, -1, 0.2, 0.2502, -0.226, 0.3033, 0.2502, -0.226, 0.3033, 0.2502, 0.1168, 0.3957, 0.2502, 1, 0.2, 0.2502, -0.226, 0.3033, 0.2502, -0.1705, 0.3588, 0.2502, 0.1168, 0.3957, 0.2502, 0.1168, 0.3957, 0.2502, 1, 0.7, 0.2502, 1, 0.2, 0.2502, -0.0682, 0.3957, 0.2502, 0.1168, 0.3957, 0.2502, -0.1705, 0.3588, 0.2502, 0.1168, 0.3957, 0.2502, 0.1723, 0.4512, 0.2502, 1, 0.7, 0.2502, -0.1705, 0.3588, 0.2502, -0.1705, 0.4698, 0.2502, -0.0682, 0.3957, 0.2502, -0.1705, 0.4698, 0.2502, -0.1237, 0.4512, 0.2502, -0.0682, 0.3957, 0.2502, 0.1723, 0.4512, 0.2502, 0.1723, 0.5622, 0.2502, 1, 0.7, 0.2502, 0.1723, 0.5622, 0.2502, 0.1168, 0.6177, 0.2502, 1, 0.7, 0.2502, 0.1168, 0.6177, 0.2502, -0.0682, 0.6177, 0.2502, 1, 0.7, 0.2502, -1, 0.7, 0.2502, 1, 0.7, 0.2502, -0.0682, 0.6177, 0.2502, -0.1705, 0.4698, 0.2502, -0.1237, 0.5622, 0.2502, -0.1237, 0.4512, 0.2502, -1, 0.7, 0.2502, -0.0682, 0.6177, 0.2502, -0.1237, 0.5622, 0.2502, -0.1705, 0.4698, 0.2502, -0.226, 0.5253, 0.2502, -0.1237, 0.5622, 0.2502, -1, 0.7, 0.2502, -0.1237, 0.5622, 0.2502, -0.411, 0.5253, 0.2502, -0.226, 0.5253, 0.2502, -0.411, 0.5253, 0.2502, -0.1237, 0.5622, 0.2502, 0.2365, 0, 0.6875, 0.2758, 0, 0.6195, 0.247, 0, 0.5123, 0.247, 0, 0.5123, 0.1791, 0, 0.4731, 0.2365, 0, 0.6875, 0.1791, 0, 0.4731, 0.0004, 0, 0.521, 0.2365, 0, 0.6875, 0.0004, 0, 0.521, 0.0578, 0, 0.7354, 0.2365, 0, 0.6875, 0.0004, 0, 0.521, -0.0101, 0, 0.6962, 0.0578, 0, 0.7354, 0.0004, 0, 0.521, -0.0389, 0, 0.5889, -0.0101, 0, 0.6962, 0.2758, 0.1, 0.6195, 0.247, 0.1, 0.5123, 0.247, 0, 0.5123, 0.247, 0, 0.5123, 0.2758, 0, 0.6195, 0.2758, 0.1, 0.6195, 0.2365, 0.1, 0.6875, 0.2365, 0, 0.6875, 0.0578, 0, 0.7354, 0.0578, 0, 0.7354, 0.0578, 0.1, 0.7354, 0.2365, 0.1, 0.6875, -0.0101, 0, 0.6962, -0.0389, 0, 0.5889, -0.0389, 0.1, 0.5889, -0.0389, 0.1, 0.5889, -0.0101, 0.1, 0.6962, -0.0101, 0, 0.6962, 0.1791, 0.1, 0.4731, 0.247, 0.1, 0.5123, 0.2758, 0.1, 0.6195, 0.2758, 0.1, 0.6195, 0.2365, 0.1, 0.6875, 0.1791, 0.1, 0.4731, 0.2365, 0.1, 0.6875, 0.0004, 0.1, 0.521, 0.1791, 0.1, 0.4731, 0.2365, 0.1, 0.6875, 0.0578, 0.1, 0.7354, 0.0004, 0.1, 0.521, 0.0578, 0.1, 0.7354, -0.0389, 0.1, 0.5889, 0.0004, 0.1, 0.521, 0.0578, 0.1, 0.7354, -0.0101, 0.1, 0.6962, -0.0389, 0.1, 0.5889, 0.0578, 0, 0.7354, -0.0101, 0, 0.6962, -0.0101, 0.1, 0.6962, -0.0101, 0.1, 0.6962, 0.0578, 0.1, 0.7354, 0.0578, 0, 0.7354, 0.2365, 0.1, 0.6875, 0.2758, 0.1, 0.6195, 0.2758, 0, 0.6195, 0.2758, 0, 0.6195, 0.2365, 0, 0.6875, 0.2365, 0.1, 0.6875, 0.247, 0.1, 0.5123, 0.1791, 0.1, 0.4731, 0.1791, 0, 0.4731, 0.1791, 0, 0.4731, 0.247, 0, 0.5123, 0.247, 0.1, 0.5123, 0.0004, 0.1, 0.521, 0.0004, 0, 0.521, 0.1791, 0, 0.4731, 0.1791, 0, 0.4731, 0.1791, 0.1, 0.4731, 0.0004, 0.1, 0.521, -0.0389, 0, 0.5889, 0.0004, 0, 0.521, 0.0004, 0.1, 0.521, 0.0004, 0.1, 0.521, -0.0389, 0.1, 0.5889, -0.0389, 0, 0.5889, 0.6656, 0.9, -0.1224, 0.6453, 0.9, -0.1983, 0.5491, 0.9, -0.2538, 0.5491, 0.9, -0.2538, 0.4733, 0.9, -0.2334, 0.6656, 0.9, -0.1224, 0.4733, 0.9, -0.2334, 0.3808, 0.9, -0.0732, 0.6656, 0.9, -0.1224, 0.3808, 0.9, -0.0732, 0.5731, 0.9, 0.0378, 0.6656, 0.9, -0.1224, 0.3808, 0.9, -0.0732, 0.4973, 0.9, 0.0581, 0.5731, 0.9, 0.0378, 0.3808, 0.9, -0.0732, 0.4011, 0.9, 0.0026, 0.4973, 0.9, 0.0581, 0.6453, 1, -0.1983, 0.5491, 1, -0.2538, 0.5491, 0.9, -0.2538, 0.5491, 0.9, -0.2538, 0.6453, 0.9, -0.1983, 0.6453, 1, -0.1983, 0.6656, 1, -0.1224, 0.6656, 0.9, -0.1224, 0.5731, 0.9, 0.0378, 0.5731, 0.9, 0.0378, 0.5731, 1, 0.0378, 0.6656, 1, -0.1224, 0.4973, 0.9, 0.0581, 0.4011, 0.9, 0.0026, 0.4011, 1, 0.0026, 0.4011, 1, 0.0026, 0.4973, 1, 0.0581, 0.4973, 0.9, 0.0581, 0.4733, 1, -0.2334, 0.5491, 1, -0.2538, 0.6453, 1, -0.1983, 0.6453, 1, -0.1983, 0.6656, 1, -0.1224, 0.4733, 1, -0.2334, 0.6656, 1, -0.1224, 0.3808, 1, -0.0732, 0.4733, 1, -0.2334, 0.6656, 1, -0.1224, 0.5731, 1, 0.0378, 0.3808, 1, -0.0732, 0.5731, 1, 0.0378, 0.4011, 1, 0.0026, 0.3808, 1, -0.0732, 0.5731, 1, 0.0378, 0.4973, 1, 0.0581, 0.4011, 1, 0.0026, 0.5731, 0.9, 0.0378, 0.4973, 0.9, 0.0581, 0.4973, 1, 0.0581, 0.4973, 1, 0.0581, 0.5731, 1, 0.0378, 0.5731, 0.9, 0.0378, 0.6656, 1, -0.1224, 0.6453, 1, -0.1983, 0.6453, 0.9, -0.1983, 0.6453, 0.9, -0.1983, 0.6656, 0.9, -0.1224, 0.6656, 1, -0.1224, 0.5491, 1, -0.2538, 0.4733, 1, -0.2334, 0.4733, 0.9, -0.2334, 0.4733, 0.9, -0.2334, 0.5491, 0.9, -0.2538, 0.5491, 1, -0.2538, 0.3808, 1, -0.0732, 0.3808, 0.9, -0.0732, 0.4733, 0.9, -0.2334, 0.4733, 0.9, -0.2334, 0.4733, 1, -0.2334, 0.3808, 1, -0.0732, 0.4011, 0.9, 0.0026, 0.3808, 0.9, -0.0732, 0.3808, 1, -0.0732, 0.3808, 1, -0.0732, 0.4011, 1, 0.0026, 0.4011, 0.9, 0.0026, 0.9165, 0.9, -0.1596, 0.8486, 0.9, -0.1988, 0.7413, 0.9, -0.1701, 0.7413, 0.9, -0.1701, 0.7021, 0.9, -0.1021, 0.9165, 0.9, -0.1596, 0.7021, 0.9, -0.1021, 0.75, 0.9, 0.0766, 0.9165, 0.9, -0.1596, 0.75, 0.9, 0.0766, 0.9644, 0.9, 0.0191, 0.9165, 0.9, -0.1596, 0.75, 0.9, 0.0766, 0.9252, 0.9, 0.0871, 0.9644, 0.9, 0.0191, 0.75, 0.9, 0.0766, 0.8179, 0.9, 0.1158, 0.9252, 0.9, 0.0871, 0.8486, 1, -0.1988, 0.7413, 1, -0.1701, 0.7413, 0.9, -0.1701, 0.7413, 0.9, -0.1701, 0.8486, 0.9, -0.1988, 0.8486, 1, -0.1988, 0.9165, 1, -0.1596, 0.9165, 0.9, -0.1596, 0.9644, 0.9, 0.0191, 0.9644, 0.9, 0.0191, 0.9644, 1, 0.0191, 0.9165, 1, -0.1596, 0.9252, 0.9, 0.0871, 0.8179, 0.9, 0.1158, 0.8179, 1, 0.1158, 0.8179, 1, 0.1158, 0.9252, 1, 0.0871, 0.9252, 0.9, 0.0871, 0.7021, 1, -0.1021, 0.7413, 1, -0.1701, 0.8486, 1, -0.1988, 0.8486, 1, -0.1988, 0.9165, 1, -0.1596, 0.7021, 1, -0.1021, 0.9165, 1, -0.1596, 0.75, 1, 0.0766, 0.7021, 1, -0.1021, 0.9165, 1, -0.1596, 0.9644, 1, 0.0191, 0.75, 1, 0.0766, 0.9644, 1, 0.0191, 0.8179, 1, 0.1158, 0.75, 1, 0.0766, 0.9644, 1, 0.0191, 0.9252, 1, 0.0871, 0.8179, 1, 0.1158, 0.9644, 0.9, 0.0191, 0.9252, 0.9, 0.0871, 0.9252, 1, 0.0871, 0.9252, 1, 0.0871, 0.9644, 1, 0.0191, 0.9644, 0.9, 0.0191, 0.9165, 1, -0.1596, 0.8486, 1, -0.1988, 0.8486, 0.9, -0.1988, 0.8486, 0.9, -0.1988, 0.9165, 0.9, -0.1596, 0.9165, 1, -0.1596, 0.7413, 1, -0.1701, 0.7021, 1, -0.1021, 0.7021, 0.9, -0.1021, 0.7021, 0.9, -0.1021, 0.7413, 0.9, -0.1701, 0.7413, 1, -0.1701, 0.75, 1, 0.0766, 0.75, 0.9, 0.0766, 0.7021, 0.9, -0.1021, 0.7021, 0.9, -0.1021, 0.7021, 1, -0.1021, 0.75, 1, 0.0766, 0.8179, 0.9, 0.1158, 0.75, 0.9, 0.0766, 0.75, 1, 0.0766, 0.75, 1, 0.0766, 0.8179, 1, 0.1158, 0.8179, 0.9, 0.1158, -0.226, 0.3033, 0.2502, -0.226, 0.3033, 0.3002, -0.1705, 0.3588, 0.3002, -0.1705, 0.3588, 0.3002, -0.1705, 0.3588, 0.2502, -0.226, 0.3033, 0.2502, -0.4665, 0.3588, 0.3002, -0.4665, 0.4698, 0.3002, -0.411, 0.5253, 0.3002, -0.411, 0.5253, 0.3002, -0.411, 0.3033, 0.3002, -0.4665, 0.3588, 0.3002, -0.411, 0.5253, 0.3002, -0.226, 0.5253, 0.3002, -0.411, 0.3033, 0.3002, -0.226, 0.5253, 0.3002, -0.226, 0.3033, 0.3002, -0.411, 0.3033, 0.3002, -0.226, 0.5253, 0.3002, -0.1705, 0.3588, 0.3002, -0.226, 0.3033, 0.3002, -0.226, 0.5253, 0.3002, -0.1705, 0.4698, 0.3002, -0.1705, 0.3588, 0.3002, -0.226, 0.5253, 0.3002, -0.226, 0.5253, 0.2502, -0.1705, 0.4698, 0.2502, -0.1705, 0.4698, 0.2502, -0.1705, 0.4698, 0.3002, -0.226, 0.5253, 0.3002, -0.4665, 0.4698, 0.3002, -0.4665, 0.3588, 0.3002, -0.4665, 0.3588, 0.2502, -0.4665, 0.3588, 0.2502, -0.4665, 0.4698, 0.2502, -0.4665, 0.4698, 0.3002, -0.411, 0.3033, 0.3002, -0.411, 0.3033, 0.2502, -0.4665, 0.3588, 0.2502, -0.4665, 0.3588, 0.2502, -0.4665, 0.3588, 0.3002, -0.411, 0.3033, 0.3002, -0.226, 0.3033, 0.3002, -0.226, 0.3033, 0.2502, -0.411, 0.3033, 0.2502, -0.411, 0.3033, 0.2502, -0.411, 0.3033, 0.3002, -0.226, 0.3033, 0.3002, -0.411, 0.5253, 0.3002, -0.411, 0.5253, 0.2502, -0.226, 0.5253, 0.2502, -0.226, 0.5253, 0.2502, -0.226, 0.5253, 0.3002, -0.411, 0.5253, 0.3002, -0.1705, 0.3588, 0.2502, -0.1705, 0.3588, 0.3002, -0.1705, 0.4698, 0.3002, -0.1705, 0.4698, 0.3002, -0.1705, 0.4698, 0.2502, -0.1705, 0.3588, 0.2502, -0.4665, 0.3588, 0.2502, -0.4665, 0.4698, 0.2502, -0.411, 0.5253, 0.2502, -0.411, 0.5253, 0.2502, -0.411, 0.3033, 0.2502, -0.4665, 0.3588, 0.2502, -0.411, 0.5253, 0.2502, -0.226, 0.5253, 0.2502, -0.411, 0.3033, 0.2502, -0.226, 0.5253, 0.2502, -0.226, 0.3033, 0.2502, -0.411, 0.3033, 0.2502, -0.226, 0.5253, 0.2502, -0.1705, 0.3588, 0.2502, -0.226, 0.3033, 0.2502, -0.226, 0.5253, 0.2502, -0.1705, 0.4698, 0.2502, -0.1705, 0.3588, 0.2502, -0.411, 0.5253, 0.3002, -0.4665, 0.4698, 0.3002, -0.4665, 0.4698, 0.2502, -0.4665, 0.4698, 0.2502, -0.411, 0.5253, 0.2502, -0.411, 0.5253, 0.3002, -0.1237, 0.5622, 0.3002, -0.1237, 0.4512, 0.3002, -0.1237, 0.4512, 0.2502, -0.1237, 0.4512, 0.2502, -0.1237, 0.5622, 0.2502, -0.1237, 0.5622, 0.3002, -0.0682, 0.3957, 0.3002, -0.0682, 0.3957, 0.2502, -0.1237, 0.4512, 0.2502, -0.1237, 0.4512, 0.2502, -0.1237, 0.4512, 0.3002, -0.0682, 0.3957, 0.3002, -0.1237, 0.4512, 0.2502, -0.1237, 0.5622, 0.2502, -0.0682, 0.6177, 0.2502, -0.0682, 0.6177, 0.2502, -0.0682, 0.3957, 0.2502, -0.1237, 0.4512, 0.2502, -0.0682, 0.6177, 0.2502, 0.1168, 0.6177, 0.2502, -0.0682, 0.3957, 0.2502, 0.1168, 0.6177, 0.2502, 0.1168, 0.3957, 0.2502, -0.0682, 0.3957, 0.2502, 0.1168, 0.6177, 0.2502, 0.1723, 0.4512, 0.2502, 0.1168, 0.3957, 0.2502, 0.1168, 0.6177, 0.2502, 0.1723, 0.5622, 0.2502, 0.1723, 0.4512, 0.2502, 0.1168, 0.3957, 0.3002, 0.1168, 0.3957, 0.2502, -0.0682, 0.3957, 0.2502, -0.0682, 0.3957, 0.2502, -0.0682, 0.3957, 0.3002, 0.1168, 0.3957, 0.3002, 0.1723, 0.4512, 0.2502, 0.1723, 0.4512, 0.3002, 0.1723, 0.5622, 0.3002, 0.1723, 0.5622, 0.3002, 0.1723, 0.5622, 0.2502, 0.1723, 0.4512, 0.2502, -0.0682, 0.6177, 0.3002, -0.1237, 0.5622, 0.3002, -0.1237, 0.5622, 0.2502, -0.1237, 0.5622, 0.2502, -0.0682, 0.6177, 0.2502, -0.0682, 0.6177, 0.3002, 0.1168, 0.6177, 0.3002, 0.1168, 0.6177, 0.2502, 0.1723, 0.5622, 0.2502, 0.1723, 0.5622, 0.2502, 0.1723, 0.5622, 0.3002, 0.1168, 0.6177, 0.3002, -0.1237, 0.4512, 0.3002, -0.1237, 0.5622, 0.3002, -0.0682, 0.6177, 0.3002, -0.0682, 0.6177, 0.3002, -0.0682, 0.3957, 0.3002, -0.1237, 0.4512, 0.3002, -0.0682, 0.6177, 0.3002, 0.1168, 0.6177, 0.3002, -0.0682, 0.3957, 0.3002, 0.1168, 0.6177, 0.3002, 0.1168, 0.3957, 0.3002, -0.0682, 0.3957, 0.3002, 0.1168, 0.6177, 0.3002, 0.1723, 0.4512, 0.3002, 0.1168, 0.3957, 0.3002, 0.1168, 0.6177, 0.3002, 0.1723, 0.5622, 0.3002, 0.1723, 0.4512, 0.3002, -0.0682, 0.6177, 0.3002, -0.0682, 0.6177, 0.2502, 0.1168, 0.6177, 0.2502, 0.1168, 0.6177, 0.2502, 0.1168, 0.6177, 0.3002, -0.0682, 0.6177, 0.3002, 0.1168, 0.3957, 0.2502, 0.1168, 0.3957, 0.3002, 0.1723, 0.4512, 0.3002, 0.1723, 0.4512, 0.3002, 0.1723, 0.4512, 0.2502, 0.1168, 0.3957, 0.2502, 0.1837, 0.4402, -0.2998, 0.1837, 0.3292, -0.2998, 0.1837, 0.3292, -0.2498, 0.1837, 0.3292, -0.2498, 0.1837, 0.4402, -0.2498, 0.1837, 0.4402, -0.2998, 0.1282, 0.2737, -0.2998, 0.1282, 0.2737, -0.2498, 0.1837, 0.3292, -0.2498, 0.1837, 0.3292, -0.2498, 0.1837, 0.3292, -0.2998, 0.1282, 0.2737, -0.2998, 0.1837, 0.3292, -0.2498, 0.1837, 0.4402, -0.2498, 0.1282, 0.4957, -0.2498, 0.1282, 0.4957, -0.2498, 0.1282, 0.2737, -0.2498, 0.1837, 0.3292, -0.2498, 0.1282, 0.4957, -0.2498, -0.0568, 0.4957, -0.2498, 0.1282, 0.2737, -0.2498, -0.0568, 0.4957, -0.2498, -0.0568, 0.2737, -0.2498, 0.1282, 0.2737, -0.2498, -0.0568, 0.4957, -0.2498, -0.1123, 0.3292, -0.2498, -0.0568, 0.2737, -0.2498, -0.0568, 0.4957, -0.2498, -0.1123, 0.4402, -0.2498, -0.1123, 0.3292, -0.2498, -0.0568, 0.2737, -0.2998, -0.0568, 0.2737, -0.2498, 0.1282, 0.2737, -0.2498, 0.1282, 0.2737, -0.2498, 0.1282, 0.2737, -0.2998, -0.0568, 0.2737, -0.2998, -0.1123, 0.3292, -0.2498, -0.1123, 0.3292, -0.2998, -0.1123, 0.4402, -0.2998, -0.1123, 0.4402, -0.2998, -0.1123, 0.4402, -0.2498, -0.1123, 0.3292, -0.2498, 0.1282, 0.4957, -0.2998, 0.1837, 0.4402, -0.2998, 0.1837, 0.4402, -0.2498, 0.1837, 0.4402, -0.2498, 0.1282, 0.4957, -0.2498, 0.1282, 0.4957, -0.2998, -0.0568, 0.4957, -0.2998, -0.0568, 0.4957, -0.2498, -0.1123, 0.4402, -0.2498, -0.1123, 0.4402, -0.2498, -0.1123, 0.4402, -0.2998, -0.0568, 0.4957, -0.2998, 0.1837, 0.3292, -0.2998, 0.1837, 0.4402, -0.2998, 0.1282, 0.4957, -0.2998, 0.1282, 0.4957, -0.2998, 0.1282, 0.2737, -0.2998, 0.1837, 0.3292, -0.2998, 0.1282, 0.4957, -0.2998, -0.0568, 0.4957, -0.2998, 0.1282, 0.2737, -0.2998, -0.0568, 0.4957, -0.2998, -0.0568, 0.2737, -0.2998, 0.1282, 0.2737, -0.2998, -0.0568, 0.4957, -0.2998, -0.1123, 0.3292, -0.2998, -0.0568, 0.2737, -0.2998, -0.0568, 0.4957, -0.2998, -0.1123, 0.4402, -0.2998, -0.1123, 0.3292, -0.2998, 0.1282, 0.4957, -0.2998, 0.1282, 0.4957, -0.2498, -0.0568, 0.4957, -0.2498, -0.0568, 0.4957, -0.2498, -0.0568, 0.4957, -0.2998, 0.1282, 0.4957, -0.2998, -0.0568, 0.2737, -0.2498, -0.0568, 0.2737, -0.2998, -0.1123, 0.3292, -0.2998, -0.1123, 0.3292, -0.2998, -0.1123, 0.3292, -0.2498, -0.0568, 0.2737, -0.2498) diff --git a/assets/kenney-fps/scenes/main.tscn b/assets/kenney-fps/scenes/main.tscn index c2d3650..ec8fc0c 100644 --- a/assets/kenney-fps/scenes/main.tscn +++ b/assets/kenney-fps/scenes/main.tscn @@ -1,15 +1,15 @@ [gd_scene format=3 uid="uid://dxvvlck8lej3f"] -[ext_resource type="Environment" uid="uid://jvmpkdwaeaq" path="res://scenes/main-environment.tres" id="1_q8fpv"] -[ext_resource type="PackedScene" uid="uid://dl2ed4gkybggf" path="res://objects/player.tscn" id="2_elriq"] -[ext_resource type="Script" uid="uid://by0qn28x1i1jj" path="res://scripts/hud.gd" id="3_s8mkj"] -[ext_resource type="FontFile" uid="uid://biqtga8moh7ah" path="res://fonts/lilita_one_regular.ttf" id="3_w27de"] -[ext_resource type="PackedScene" uid="uid://dpm3l05d7fu35" path="res://objects/platform.tscn" id="5_3s40e"] -[ext_resource type="PackedScene" uid="uid://r7rt7pth4u7o" path="res://objects/wall_low.tscn" id="5_6vel1"] -[ext_resource type="PackedScene" uid="uid://c71evdjblk5wp" path="res://objects/wall_high.tscn" id="7_cabne"] -[ext_resource type="PackedScene" uid="uid://bvx5cvigosg0s" path="res://objects/platform_large_grass.tscn" id="7_wggef"] -[ext_resource type="PackedScene" uid="uid://d2g78tpqbyf5g" path="res://objects/enemy.tscn" id="8_7ty2f"] -[ext_resource type="PackedScene" uid="uid://oqfhfp1a80qd" path="res://objects/cloud.tscn" id="10_5ksau"] +[ext_resource type="Environment" uid="uid://jvmpkdwaeaq" path="res://assets/kenney-fps/scenes/main-environment.tres" id="1_q8fpv"] +[ext_resource type="PackedScene" uid="uid://dl2ed4gkybggf" path="res://assets/kenney-fps/objects/player.tscn" id="2_elriq"] +[ext_resource type="Script" uid="uid://by0qn28x1i1jj" path="res://assets/kenney-fps/scripts/hud.gd" id="3_s8mkj"] +[ext_resource type="FontFile" uid="uid://biqtga8moh7ah" path="res://assets/kenney-fps/fonts/lilita_one_regular.ttf" id="3_w27de"] +[ext_resource type="PackedScene" uid="uid://dpm3l05d7fu35" path="res://assets/kenney-fps/objects/platform.tscn" id="5_3s40e"] +[ext_resource type="PackedScene" uid="uid://r7rt7pth4u7o" path="res://assets/kenney-fps/objects/wall_low.tscn" id="5_6vel1"] +[ext_resource type="PackedScene" uid="uid://c71evdjblk5wp" path="res://assets/kenney-fps/objects/wall_high.tscn" id="7_cabne"] +[ext_resource type="PackedScene" uid="uid://bvx5cvigosg0s" path="res://assets/kenney-fps/objects/platform_large_grass.tscn" id="7_wggef"] +[ext_resource type="PackedScene" uid="uid://d2g78tpqbyf5g" path="res://assets/kenney-fps/objects/enemy.tscn" id="8_7ty2f"] +[ext_resource type="PackedScene" uid="uid://oqfhfp1a80qd" path="res://assets/kenney-fps/objects/cloud.tscn" id="10_5ksau"] [sub_resource type="LabelSettings" id="LabelSettings_fpmwk"] font = ExtResource("3_w27de") diff --git a/assets/kenney-fps/sounds/blaster.ogg.import b/assets/kenney-fps/sounds/blaster.ogg.import deleted file mode 100644 index d922369..0000000 --- a/assets/kenney-fps/sounds/blaster.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://dkftljsbdhwng" -path="res://.godot/imported/blaster.ogg-1527ec84d518b60bb9fbaad97656d870.oggvorbisstr" - -[deps] - -source_file="res://sounds/blaster.ogg" -dest_files=["res://.godot/imported/blaster.ogg-1527ec84d518b60bb9fbaad97656d870.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/blaster_repeater.ogg.import b/assets/kenney-fps/sounds/blaster_repeater.ogg.import deleted file mode 100644 index 09c3aaa..0000000 --- a/assets/kenney-fps/sounds/blaster_repeater.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://csdsvg0nh35id" -path="res://.godot/imported/blaster_repeater.ogg-a46ceca73f68a6e3e41e971b07cb8de8.oggvorbisstr" - -[deps] - -source_file="res://sounds/blaster_repeater.ogg" -dest_files=["res://.godot/imported/blaster_repeater.ogg-a46ceca73f68a6e3e41e971b07cb8de8.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/enemy_attack.ogg.import b/assets/kenney-fps/sounds/enemy_attack.ogg.import deleted file mode 100644 index d88c0dc..0000000 --- a/assets/kenney-fps/sounds/enemy_attack.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://blxqudiclpq84" -path="res://.godot/imported/enemy_attack.ogg-ad3c73e6e91698e3fc81bd6423d8fca2.oggvorbisstr" - -[deps] - -source_file="res://sounds/enemy_attack.ogg" -dest_files=["res://.godot/imported/enemy_attack.ogg-ad3c73e6e91698e3fc81bd6423d8fca2.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/enemy_destroy.ogg.import b/assets/kenney-fps/sounds/enemy_destroy.ogg.import deleted file mode 100644 index 2875007..0000000 --- a/assets/kenney-fps/sounds/enemy_destroy.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://br1ov3ld0er6r" -path="res://.godot/imported/enemy_destroy.ogg-feb8f111abab93d5fc30ec838c975232.oggvorbisstr" - -[deps] - -source_file="res://sounds/enemy_destroy.ogg" -dest_files=["res://.godot/imported/enemy_destroy.ogg-feb8f111abab93d5fc30ec838c975232.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/enemy_hurt.ogg.import b/assets/kenney-fps/sounds/enemy_hurt.ogg.import deleted file mode 100644 index 2775ab9..0000000 --- a/assets/kenney-fps/sounds/enemy_hurt.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://cgnbyrnxj12ed" -path="res://.godot/imported/enemy_hurt.ogg-64e07bfa21b7ae57b8a0bf7357a95008.oggvorbisstr" - -[deps] - -source_file="res://sounds/enemy_hurt.ogg" -dest_files=["res://.godot/imported/enemy_hurt.ogg-64e07bfa21b7ae57b8a0bf7357a95008.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/jump_a.ogg.import b/assets/kenney-fps/sounds/jump_a.ogg.import deleted file mode 100644 index a54fae9..0000000 --- a/assets/kenney-fps/sounds/jump_a.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://bvnum0u73y8sv" -path="res://.godot/imported/jump_a.ogg-df3a87b422b8537163b811137ab76d0c.oggvorbisstr" - -[deps] - -source_file="res://sounds/jump_a.ogg" -dest_files=["res://.godot/imported/jump_a.ogg-df3a87b422b8537163b811137ab76d0c.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/jump_b.ogg.import b/assets/kenney-fps/sounds/jump_b.ogg.import deleted file mode 100644 index fff5446..0000000 --- a/assets/kenney-fps/sounds/jump_b.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://5raj3p7xaecq" -path="res://.godot/imported/jump_b.ogg-f0989d7351debef348a67b21be8b7bd0.oggvorbisstr" - -[deps] - -source_file="res://sounds/jump_b.ogg" -dest_files=["res://.godot/imported/jump_b.ogg-f0989d7351debef348a67b21be8b7bd0.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/jump_c.ogg.import b/assets/kenney-fps/sounds/jump_c.ogg.import deleted file mode 100644 index 4b4860a..0000000 --- a/assets/kenney-fps/sounds/jump_c.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://7tnsakv8pwa5" -path="res://.godot/imported/jump_c.ogg-6a4808f519ad4af845e78fe92b3da78c.oggvorbisstr" - -[deps] - -source_file="res://sounds/jump_c.ogg" -dest_files=["res://.godot/imported/jump_c.ogg-6a4808f519ad4af845e78fe92b3da78c.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/land.ogg.import b/assets/kenney-fps/sounds/land.ogg.import deleted file mode 100644 index f653ef6..0000000 --- a/assets/kenney-fps/sounds/land.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://xnxidwkp46un" -path="res://.godot/imported/land.ogg-7222ba872273a4a7535937ef5cfdffd0.oggvorbisstr" - -[deps] - -source_file="res://sounds/land.ogg" -dest_files=["res://.godot/imported/land.ogg-7222ba872273a4a7535937ef5cfdffd0.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/walking.ogg.import b/assets/kenney-fps/sounds/walking.ogg.import deleted file mode 100644 index 23c464b..0000000 --- a/assets/kenney-fps/sounds/walking.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://cydjn1ct3hps2" -path="res://.godot/imported/walking.ogg-bf61e9916135189ff0d5c06a148b02ab.oggvorbisstr" - -[deps] - -source_file="res://sounds/walking.ogg" -dest_files=["res://.godot/imported/walking.ogg-bf61e9916135189ff0d5c06a148b02ab.oggvorbisstr"] - -[params] - -loop=true -loop_offset=0.0 -bpm=0.0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/sounds/weapon_change.ogg.import b/assets/kenney-fps/sounds/weapon_change.ogg.import deleted file mode 100644 index 2fcf792..0000000 --- a/assets/kenney-fps/sounds/weapon_change.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://cmc2ufr6o30gl" -path="res://.godot/imported/weapon_change.ogg-7ebfd5dcd3026b79e24db351d30b1a1b.oggvorbisstr" - -[deps] - -source_file="res://sounds/weapon_change.ogg" -dest_files=["res://.godot/imported/weapon_change.ogg-7ebfd5dcd3026b79e24db351d30b1a1b.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/assets/kenney-fps/splash-screen.png.import b/assets/kenney-fps/splash-screen.png.import deleted file mode 100644 index 80c4cb5..0000000 --- a/assets/kenney-fps/splash-screen.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://biff4dkpfqi47" -path="res://.godot/imported/splash-screen.png-ae6c8b07e185ee8a074576008d9ccc5a.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://splash-screen.png" -dest_files=["res://.godot/imported/splash-screen.png-ae6c8b07e185ee8a074576008d9ccc5a.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/assets/kenney-fps/sprites/blob_shadow.png.import b/assets/kenney-fps/sprites/blob_shadow.png.import deleted file mode 100644 index e2199b6..0000000 --- a/assets/kenney-fps/sprites/blob_shadow.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://8ggihh27mlrr" -path="res://.godot/imported/blob_shadow.png-d19f4ffceb1d99dd3331acec2dc6d7df.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://sprites/blob_shadow.png" -dest_files=["res://.godot/imported/blob_shadow.png-d19f4ffceb1d99dd3331acec2dc6d7df.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/assets/kenney-fps/sprites/burst.png.import b/assets/kenney-fps/sprites/burst.png.import deleted file mode 100644 index 008fc83..0000000 --- a/assets/kenney-fps/sprites/burst.png.import +++ /dev/null @@ -1,40 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cbfhj0tswcksm" -path="res://.godot/imported/burst.png-0ca3a873296b113f4396e0bdead4beff.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://sprites/burst.png" -dest_files=["res://.godot/imported/burst.png-0ca3a873296b113f4396e0bdead4beff.ctex"] - -[params] - -compress/mode=1 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=true -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=false -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=0 diff --git a/assets/kenney-fps/sprites/crosshair-repeater.png.import b/assets/kenney-fps/sprites/crosshair-repeater.png.import index f19e04d..0f4b0a6 100644 --- a/assets/kenney-fps/sprites/crosshair-repeater.png.import +++ b/assets/kenney-fps/sprites/crosshair-repeater.png.import @@ -3,38 +3,29 @@ importer="texture" type="CompressedTexture2D" uid="uid://ce3lgq7foiusl" -path="res://.godot/imported/crosshair-repeater.png-ec408225e689b23875963003728cb016.ctex" -metadata={ -"vram_texture": false -} +path="res://.godot/imported/crosshair-repeater.png-d589090035088acabaed3ef868d992be.ctex" [deps] -source_file="res://sprites/crosshair-repeater.png" -dest_files=["res://.godot/imported/crosshair-repeater.png-ec408225e689b23875963003728cb016.ctex"] +source_file="res://assets/kenney-fps/sprites/crosshair-repeater.png" +dest_files=["res://.godot/imported/crosshair-repeater.png-d589090035088acabaed3ef868d992be.ctex"] [params] compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 -mipmaps/generate=false +mipmaps/generate=true mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 +filter/fix_alpha_border=true +filter/premult=true +filter/repeat=true +filter/filter_clip=false +filter/anisotropic=0 +detect_3d/compress_to=0 +svg/scale=1.0 diff --git a/assets/kenney-fps/sprites/crosshair.png.import b/assets/kenney-fps/sprites/crosshair.png.import index 4a10dac..3f10efc 100644 --- a/assets/kenney-fps/sprites/crosshair.png.import +++ b/assets/kenney-fps/sprites/crosshair.png.import @@ -3,24 +3,18 @@ importer="texture" type="CompressedTexture2D" uid="uid://2jld33y6h5pq" -path.s3tc="res://.godot/imported/crosshair.png-1281ee32d6777347e0f43a202c603c1b.s3tc.ctex" -metadata={ -"imported_formats": ["s3tc_bptc"], -"vram_texture": true -} +path="res://.godot/imported/crosshair.png-1a2174ba945cb2724603c288af43e347.ctex" [deps] -source_file="res://sprites/crosshair.png" -dest_files=["res://.godot/imported/crosshair.png-1281ee32d6777347e0f43a202c603c1b.s3tc.ctex"] +source_file="res://assets/kenney-fps/sprites/crosshair.png" +dest_files=["res://.godot/imported/crosshair.png-1a2174ba945cb2724603c288af43e347.ctex"] [params] -compress/mode=2 +compress/mode=0 compress/high_quality=false compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 @@ -28,14 +22,10 @@ mipmaps/generate=true mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 +filter/fix_alpha_border=true +filter/premult=true +filter/repeat=true +filter/filter_clip=false +filter/anisotropic=0 detect_3d/compress_to=0 +svg/scale=1.0 diff --git a/assets/kenney-fps/sprites/hit.png.import b/assets/kenney-fps/sprites/hit.png.import deleted file mode 100644 index e283a70..0000000 --- a/assets/kenney-fps/sprites/hit.png.import +++ /dev/null @@ -1,41 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dh0t42ubhuv0" -path.s3tc="res://.godot/imported/hit.png-32857f07c817e04581303953f2545db0.s3tc.ctex" -metadata={ -"imported_formats": ["s3tc_bptc"], -"vram_texture": true -} - -[deps] - -source_file="res://sprites/hit.png" -dest_files=["res://.godot/imported/hit.png-32857f07c817e04581303953f2545db0.s3tc.ctex"] - -[params] - -compress/mode=2 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=true -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=0 diff --git a/assets/kenney-fps/sprites/skybox.png.import b/assets/kenney-fps/sprites/skybox.png.import deleted file mode 100644 index 60daeac..0000000 --- a/assets/kenney-fps/sprites/skybox.png.import +++ /dev/null @@ -1,41 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://cb7sdk1i5rx04" -path.bptc="res://.godot/imported/skybox.png-3a75a15c5dbffccdaa926738885bd0eb.bptc.ctex" -metadata={ -"imported_formats": ["s3tc_bptc"], -"vram_texture": true -} - -[deps] - -source_file="res://sprites/skybox.png" -dest_files=["res://.godot/imported/skybox.png-3a75a15c5dbffccdaa926738885bd0eb.bptc.ctex"] - -[params] - -compress/mode=2 -compress/high_quality=true -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=false -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=0 diff --git a/assets/kenney-fps/weapons/blaster-repeater.tres b/assets/kenney-fps/weapons/blaster-repeater.tres index 504cfec..113ee25 100644 --- a/assets/kenney-fps/weapons/blaster-repeater.tres +++ b/assets/kenney-fps/weapons/blaster-repeater.tres @@ -1,8 +1,8 @@ [gd_resource type="Resource" script_class="Weapon" load_steps=4 format=3 uid="uid://cu2gtxlcmbb34"] -[ext_resource type="Texture2D" uid="uid://ce3lgq7foiusl" path="res://sprites/crosshair-repeater.png" id="1_hoqei"] -[ext_resource type="Script" uid="uid://dg01pkkc1c5vd" path="res://scripts/weapon.gd" id="1_l1atd"] -[ext_resource type="PackedScene" uid="uid://dd3oln1ucgqpd" path="res://models/blaster-repeater.glb" id="2_h64nv"] +[ext_resource type="Texture2D" uid="uid://ce3lgq7foiusl" path="res://assets/kenney-fps/sprites/crosshair-repeater.png" id="1_hoqei"] +[ext_resource type="Script" uid="uid://dg01pkkc1c5vd" path="res://assets/kenney-fps/scripts/weapon.gd" id="1_l1atd"] +[ext_resource type="PackedScene" uid="uid://dd3oln1ucgqpd" path="res://assets/kenney-fps/models/blaster-repeater.glb" id="2_h64nv"] [resource] script = ExtResource("1_l1atd") @@ -12,5 +12,5 @@ muzzle_position = Vector3(0.1, -0.4, 1.5) damage = 10.0 spread = 0.5 knockback = 10 -sound_shoot = "sounds/blaster_repeater.ogg" +sound_shoot = "assets/kenney-fps/sounds/blaster_repeater.ogg" crosshair = ExtResource("1_hoqei") diff --git a/assets/kenney-fps/weapons/blaster.tres b/assets/kenney-fps/weapons/blaster.tres index 7ce4df1..f00a77c 100644 --- a/assets/kenney-fps/weapons/blaster.tres +++ b/assets/kenney-fps/weapons/blaster.tres @@ -1,8 +1,8 @@ [gd_resource type="Resource" script_class="Weapon" load_steps=4 format=3 uid="uid://c56y8pqoyk15f"] -[ext_resource type="Texture2D" uid="uid://2jld33y6h5pq" path="res://sprites/crosshair.png" id="1_2onsr"] -[ext_resource type="PackedScene" uid="uid://b2p7bbkuxf7m" path="res://models/blaster.glb" id="1_x0glg"] -[ext_resource type="Script" uid="uid://dg01pkkc1c5vd" path="res://scripts/weapon.gd" id="2_107w7"] +[ext_resource type="Texture2D" uid="uid://2jld33y6h5pq" path="res://assets/kenney-fps/sprites/crosshair.png" id="1_2onsr"] +[ext_resource type="PackedScene" uid="uid://b2p7bbkuxf7m" path="res://assets/kenney-fps/models/blaster.glb" id="1_x0glg"] +[ext_resource type="Script" uid="uid://dg01pkkc1c5vd" path="res://assets/kenney-fps/scripts/weapon.gd" id="2_107w7"] [resource] script = ExtResource("2_107w7") @@ -15,5 +15,5 @@ shot_count = 3 knockback = 40 min_knockback = Vector2(0.025, 0.025) max_knockback = Vector2(0.045, 0.04) -sound_shoot = "sounds/blaster.ogg" +sound_shoot = "assets/kenney-fps/sounds/blaster.ogg" crosshair = ExtResource("1_2onsr") diff --git a/assets/quaternius/models/P90.glb b/assets/quaternius/models/P90.glb new file mode 100644 index 0000000..9fed544 Binary files /dev/null and b/assets/quaternius/models/P90.glb differ diff --git a/assets/kenney-fps/models/cloud.glb.import b/assets/quaternius/models/P90.glb.import similarity index 68% rename from assets/kenney-fps/models/cloud.glb.import rename to assets/quaternius/models/P90.glb.import index 0daeeb6..7ee8994 100644 --- a/assets/kenney-fps/models/cloud.glb.import +++ b/assets/quaternius/models/P90.glb.import @@ -3,19 +3,21 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://g2w2608bc2dy" -path="res://.godot/imported/cloud.glb-53daedc24f8d7f4baa42baf232c66643.scn" +uid="uid://bax08y0t8hkc" +path="res://.godot/imported/P90.glb-c0686bb17e63ef864fe47e2ef85c3e8d.scn" [deps] -source_file="res://models/cloud.glb" -dest_files=["res://.godot/imported/cloud.glb-53daedc24f8d7f4baa42baf232c66643.scn"] +source_file="res://assets/quaternius/models/P90.glb" +dest_files=["res://.godot/imported/P90.glb-c0686bb17e63ef864fe47e2ef85c3e8d.scn"] [params] nodes/root_type="" nodes/root_name="" nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true nodes/apply_root_scale=true nodes/root_scale=1.0 nodes/import_as_skeleton_bones=false @@ -38,5 +40,6 @@ materials/extract=0 materials/extract_format=0 materials/extract_path="" _subresources={} -gltf/naming_version=1 +gltf/naming_version=2 gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/assets/quaternius/models/P90.mtl b/assets/quaternius/models/P90.mtl new file mode 100644 index 0000000..655f1c0 --- /dev/null +++ b/assets/quaternius/models/P90.mtl @@ -0,0 +1,32 @@ +# Blender MTL File: 'P90.blend' +# Material Count: 3 + +newmtl Material.001 +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Material.003 +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Material.004 +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 diff --git a/assets/quaternius/models/P90.obj b/assets/quaternius/models/P90.obj new file mode 100644 index 0000000..baf308c --- /dev/null +++ b/assets/quaternius/models/P90.obj @@ -0,0 +1,1195 @@ +# Blender v2.76 (sub 0) OBJ File: 'P90.blend' +# www.blender.org +mtllib P90.mtl +o P90_Cylinder.001 +v 0.559849 0.254111 1.448544 +v 0.489501 0.669473 1.456098 +v 0.697233 0.254111 1.847772 +v 0.622595 0.669473 1.837714 +v 0.525768 0.254111 2.247000 +v 0.455420 0.669473 2.219331 +v 0.541574 0.254111 1.214073 +v 0.474052 0.669473 1.225893 +v 0.471021 0.669473 -3.326042 +v 0.538403 0.254111 -3.520253 +v 0.559849 0.554702 1.448544 +v 0.697233 0.554702 1.847772 +v 0.525768 0.554702 2.247000 +v 0.541574 0.554702 1.214073 +v 0.538403 0.554702 -3.520253 +v 0.011828 0.254111 1.216263 +v 0.011828 0.669473 1.227987 +v -0.536194 0.254111 1.448544 +v -0.465845 0.669473 1.456098 +v -0.673577 0.254111 1.847772 +v -0.598940 0.669473 1.837714 +v -0.502112 0.254111 2.247000 +v -0.431764 0.669473 2.219331 +v 0.011828 0.254111 2.383290 +v 0.011828 0.669473 2.349608 +v -0.517918 0.254111 1.214073 +v -0.450396 0.669473 1.225893 +v -0.447365 0.669473 -3.326042 +v 0.011828 0.669473 -3.323949 +v 0.011828 0.254111 -3.518063 +v -0.514747 0.254111 -3.520253 +v 0.011828 0.554702 1.354041 +v -0.536194 0.554702 1.448544 +v -0.673577 0.554702 1.847772 +v -0.502112 0.554702 2.247000 +v 0.011828 0.554702 2.383290 +v -0.517918 0.554702 1.214073 +v 0.011828 0.554702 -3.518063 +v -0.514747 0.554702 -3.520253 +v -0.196900 -0.975979 -1.234251 +v -0.196900 -0.387989 -1.234251 +v -0.196900 -0.975979 -1.822241 +v -0.196900 -0.387989 -2.037180 +v 0.191557 -0.975979 -1.234251 +v 0.191557 -0.387989 -1.234251 +v 0.191557 -0.975979 -1.822241 +v 0.191557 -0.387989 -2.037180 +v -0.196900 -0.828982 -1.234251 +v -0.196900 -0.828982 -1.808463 +v 0.191557 -0.828982 -1.808463 +v 0.191557 -0.828982 -1.234251 +v -0.196900 -0.608486 -1.234251 +v -0.196900 -0.575418 -1.866331 +v 0.191557 -0.575418 -1.866331 +v 0.191557 -0.608486 -1.234251 +v -0.196900 -0.702200 -1.812137 +v 0.191557 -0.702200 -1.812137 +v 0.191557 -0.718734 -1.234251 +v -0.196900 -0.718734 -1.234251 +v 0.405012 0.758214 4.678841 +v -0.000000 0.758214 4.678841 +v -0.000000 0.598924 4.829951 +v 0.405012 0.598924 4.829951 +v 0.564524 0.598703 4.670206 +v -0.000000 0.757398 2.453517 +v 0.417383 0.757398 2.453518 +v -0.405012 0.758214 4.678841 +v -0.405012 0.598924 4.829951 +v -0.000000 -0.438536 4.786307 +v 0.405012 -0.438536 4.786307 +v 0.564524 -0.438314 4.626586 +v -0.000000 0.274061 2.446122 +v -0.417383 0.757398 2.453518 +v -0.564524 0.598703 4.670206 +v -0.405012 -0.438536 4.786307 +v -0.000000 -0.521902 4.786307 +v 0.286345 -0.521902 4.786307 +v 0.445857 -0.522124 4.626586 +v 0.564445 0.268024 2.439819 +v 0.564406 0.599308 2.443816 +v -0.564524 -0.438314 4.626586 +v -0.286345 -0.521902 4.786307 +v 0.000000 -1.349401 4.829951 +v 0.286345 -1.349401 4.829951 +v 0.564524 -0.438314 0.708525 +v 0.445857 -0.522124 0.773286 +v -0.000000 0.253466 -3.564641 +v -0.564445 0.268024 2.439819 +v -0.564406 0.599308 2.443816 +v -0.445857 -0.522124 4.626586 +v -0.286345 -1.349401 4.829951 +v 0.445857 -1.349180 4.670206 +v 0.000000 -1.508691 4.678841 +v 0.286345 -1.508691 4.678841 +v -0.000000 -0.522124 0.773286 +v -0.000000 -0.438314 0.708525 +v 0.445857 -1.107394 -1.963539 +v 0.445857 -1.008762 -1.925168 +v 0.445857 -0.863788 -1.868768 +v 0.445857 -0.863788 -1.384881 +v 0.445857 -0.645449 -1.431304 +v 0.445857 -0.522124 -1.642901 +v 0.445857 -0.522124 -0.534386 +v 0.445857 -0.642755 -0.593711 +v 0.445857 -0.886625 -0.553974 +v 0.445857 -1.141366 -0.205801 +v 0.445857 -1.323412 0.288647 +v 0.445857 -1.206539 0.623659 +v 0.445857 -1.119834 0.765241 +v 0.445857 -0.658705 0.849860 +v 0.445857 -1.349180 2.343027 +v 0.445857 -1.391872 2.024004 +v 0.445857 -1.734160 0.942683 +v 0.445857 -1.777849 0.623659 +v 0.445857 -1.705090 -0.205801 +v 0.445857 -1.562095 -0.524824 +v 0.445857 -1.178902 -1.132647 +v 0.445857 -1.107394 -1.451670 +v 0.445857 -1.107394 -1.606144 +v 0.445857 -1.426417 -1.908172 +v 0.445857 -1.426417 -2.851522 +v 0.445857 -1.107394 -3.006489 +v 0.445857 -1.107394 -2.535752 +v 0.445857 -1.213080 -2.238320 +v 0.564524 -0.341855 0.559047 +v 0.564113 0.270750 -3.567939 +v -0.564524 -0.438314 0.708525 +v -0.445857 -0.522124 0.773286 +v -0.445857 -1.349180 4.670206 +v -0.286345 -1.508691 4.678841 +v 0.000000 -1.508691 2.343027 +v 0.286345 -1.508691 2.343027 +v -0.000000 -0.341855 0.559047 +v -0.000000 -0.658705 0.849860 +v 0.000000 -1.213080 -2.238320 +v 0.000000 -1.107394 -1.963539 +v 0.000000 -1.008762 -1.925168 +v 0.000000 -0.863788 -1.868768 +v 0.000000 -0.863788 -1.384881 +v -0.000000 -0.645449 -1.431304 +v 0.564524 -0.438314 -0.493170 +v -0.000000 -0.522124 -0.534386 +v -0.000000 -0.642755 -0.593711 +v -0.000000 -0.886625 -0.553974 +v -0.000000 -1.141366 -0.205801 +v 0.000000 -1.323412 0.288647 +v -0.000000 -1.206539 0.623659 +v -0.000000 -1.119834 0.765241 +v 0.286345 -1.556830 2.031441 +v 0.286345 -1.903827 0.935246 +v 0.286345 -1.938027 0.624270 +v 0.286345 -1.865160 -0.206411 +v 0.286345 -1.766153 -0.500247 +v 0.286345 -1.351973 -1.157224 +v 0.286345 -1.266905 -1.451670 +v 0.286345 -1.266905 -1.606144 +v 0.286345 -1.425410 -1.747761 +v 0.445857 -1.777140 -1.833112 +v 0.445857 -1.717862 -2.668707 +v 0.286345 -1.395609 -3.071771 +v 0.445857 -0.889511 -3.006489 +v 0.445857 -0.729999 -3.325512 +v 0.445857 -0.729999 -3.510210 +v 0.445857 -0.729999 -3.829233 +v 0.445857 -0.729999 -4.113245 +v 0.445857 -0.522124 -4.113245 +v 0.445857 -0.523569 -2.403302 +v 0.445857 -0.741289 -2.606146 +v 0.445857 -0.951230 -2.634243 +v 0.000000 -1.107394 -2.535752 +v 0.564524 -0.381026 -0.205801 +v 0.546611 0.788937 -3.513834 +v -0.000000 0.771653 -3.510536 +v 0.564524 -0.398885 -0.455955 +v -0.564113 0.270750 -3.567939 +v -0.564524 -0.341855 0.559047 +v -0.445857 -1.107394 -1.963539 +v -0.445857 -1.213080 -2.238320 +v -0.445857 -1.107394 -2.535752 +v -0.445857 -1.107394 -3.006489 +v -0.445857 -1.426417 -2.851522 +v -0.445857 -1.426417 -1.908172 +v -0.445857 -1.107394 -1.606144 +v -0.445857 -1.107394 -1.451670 +v -0.445857 -1.178902 -1.132647 +v -0.445857 -1.562095 -0.524824 +v -0.445857 -1.705090 -0.205801 +v -0.445857 -1.777849 0.623659 +v -0.445857 -1.734160 0.942683 +v -0.445857 -1.391872 2.024004 +v -0.445857 -1.349180 2.343027 +v -0.445857 -0.658705 0.849860 +v -0.445857 -1.119834 0.765241 +v -0.445857 -1.206539 0.623659 +v -0.445857 -1.323412 0.288647 +v -0.445857 -1.141366 -0.205801 +v -0.445857 -0.886625 -0.553974 +v -0.445857 -0.642755 -0.593711 +v -0.445857 -0.522124 -0.534386 +v -0.445857 -0.522124 -1.642901 +v -0.445857 -0.645449 -1.431304 +v -0.445857 -0.863788 -1.384881 +v -0.445857 -0.863788 -1.868768 +v -0.445857 -1.008762 -1.925168 +v -0.286345 -1.508691 2.343027 +v 0.000000 -1.556830 2.031441 +v -0.000000 -0.381026 -0.205801 +v -0.000000 -0.523933 -1.651192 +v 0.445857 -0.522124 -2.113175 +v 0.473388 -0.502680 -0.524824 +v -0.000000 -0.502680 -0.524824 +v 0.000000 -1.903827 0.935246 +v 0.000000 -1.938027 0.624270 +v 0.000000 -1.865160 -0.206411 +v 0.000000 -1.766154 -0.500247 +v 0.000000 -1.351973 -1.157224 +v 0.000000 -1.266905 -1.451670 +v 0.000000 -1.266905 -1.606144 +v 0.286345 -1.744116 -2.847179 +v 0.286345 -1.938082 -1.812640 +v 0.286345 -1.107394 -3.166001 +v 0.000000 -0.951230 -2.634243 +v 0.283840 -1.035697 -3.181988 +v 0.283853 -0.908149 -3.309525 +v 0.286359 -0.891622 -3.510210 +v 0.317137 -1.049008 -3.829233 +v 0.317137 -1.049008 -4.113245 +v 0.445557 -0.732735 -4.216948 +v 0.564524 -0.438314 -4.097551 +v -0.000000 -0.523569 -2.403302 +v -0.000000 -0.741289 -2.606146 +v -0.546611 0.788937 -3.513834 +v 0.564102 0.270846 -4.039311 +v 0.546600 0.789033 -4.004236 +v 0.526775 0.796562 -1.895707 +v -0.564524 -0.398885 -0.455955 +v -0.564524 -0.381026 -0.205801 +v -0.445857 -0.951230 -2.634243 +v -0.445857 -0.741289 -2.606146 +v -0.445857 -0.523569 -2.403302 +v -0.445857 -0.522124 -4.113245 +v -0.445857 -0.729999 -4.113245 +v -0.445857 -0.729999 -3.829233 +v -0.445857 -0.729999 -3.510210 +v -0.445857 -0.729999 -3.325512 +v -0.445857 -0.889511 -3.006489 +v -0.286345 -1.395609 -3.071771 +v -0.445857 -1.717862 -2.668707 +v -0.445857 -1.777140 -1.833112 +v -0.286345 -1.425410 -1.747761 +v -0.286345 -1.266905 -1.451670 +v -0.286345 -1.266905 -1.606144 +v -0.286345 -1.351973 -1.157224 +v -0.286345 -1.766153 -0.500247 +v -0.286345 -1.865160 -0.206411 +v -0.286345 -1.938027 0.624270 +v -0.286345 -1.556830 2.031441 +v -0.286345 -1.903827 0.935246 +v -0.564524 -0.438314 -0.493170 +v -0.000000 -0.398885 -0.455955 +v -0.000000 -0.522124 -2.113175 +v -0.000000 -0.438314 -0.493170 +v -0.473388 -0.502680 -0.524824 +v 0.000000 -1.425410 -1.747761 +v 0.286345 -1.788677 -1.671284 +v 0.286345 -1.881920 -2.593698 +v 0.000000 -1.395609 -3.071771 +v 0.000000 -1.107394 -3.166001 +v 0.000000 -1.744116 -2.847179 +v 0.196808 -1.210630 -3.829233 +v 0.196808 -1.210630 -4.113245 +v 0.445557 -0.591705 -4.263079 +v 0.405012 -0.439014 -4.257831 +v -0.526775 0.796562 -1.895707 +v -0.546600 0.789033 -4.004236 +v -0.564102 0.270846 -4.039311 +v 0.444911 0.270932 -4.236072 +v 0.427409 0.789119 -4.200998 +v 0.490423 1.281389 -3.899791 +v -0.000000 0.795982 -1.890158 +v 0.459523 1.660818 -2.576327 +v -0.564524 -0.438314 -4.097551 +v -0.445557 -0.732735 -4.216948 +v -0.317137 -1.049008 -4.113245 +v -0.317137 -1.049008 -3.829233 +v -0.286359 -0.891622 -3.510210 +v -0.283853 -0.908149 -3.309525 +v -0.283840 -1.035697 -3.181988 +v -0.286345 -1.107394 -3.166001 +v -0.286345 -1.744116 -2.847179 +v -0.286345 -1.938082 -1.812640 +v -0.445857 -0.522124 -2.113175 +v 0.000000 -1.788677 -1.671284 +v 0.000000 -1.881920 -2.593698 +v 0.000000 -1.938082 -1.812640 +v 0.000000 -1.039984 -3.181988 +v 0.000000 -0.912436 -3.309525 +v 0.000000 -0.896985 -3.510210 +v 0.157640 -1.051120 -3.669721 +v 0.219490 -1.083571 -4.299738 +v 0.000000 -1.203256 -4.104017 +v 0.286345 -0.522124 -4.272757 +v 0.348196 -0.774714 -4.379634 +v -0.459523 1.660818 -2.576327 +v -0.490423 1.281389 -3.899791 +v -0.427409 0.789119 -4.200998 +v -0.444911 0.270932 -4.236072 +v -0.000000 0.252015 -4.236650 +v -0.000000 0.770202 -4.201578 +v 0.386903 1.303970 -4.069185 +v 0.490433 1.235554 -3.555418 +v 0.529933 0.812236 -1.162442 +v -0.000000 0.811492 -1.160840 +v 0.480212 1.404248 -3.345468 +v 0.464801 1.569411 -2.237094 +v -0.405012 -0.439014 -4.257831 +v -0.445557 -0.591705 -4.263079 +v -0.196808 -1.210630 -4.113245 +v -0.196808 -1.210630 -3.829233 +v -0.286345 -1.881920 -2.593698 +v -0.286345 -1.788677 -1.671284 +v 0.000000 -1.056510 -3.669721 +v 0.000000 -1.088762 -4.298396 +v 0.000000 -1.216008 -3.829233 +v 0.348196 -0.596975 -4.417508 +v -0.000000 -0.522124 -4.272757 +v -0.000000 -0.439014 -4.257831 +v -0.000000 -0.199497 -4.250490 +v 0.003419 -0.200914 -4.250533 +v 0.109502 -0.156972 -4.249187 +v 0.153443 -0.050889 -4.245935 +v 0.109502 0.055194 -4.242683 +v 0.003419 0.099135 -4.241338 +v -0.000000 0.097719 -4.241381 +v -0.529933 0.812236 -1.162442 +v -0.464801 1.569411 -2.237094 +v -0.480212 1.404248 -3.345468 +v -0.490433 1.235554 -3.555418 +v -0.386903 1.303970 -4.069185 +v -0.000000 1.287750 -4.071848 +v 0.486853 1.384361 -3.885376 +v 0.383333 1.401708 -4.054770 +v 0.554448 0.771027 -1.905651 +v 0.535003 0.927651 -1.170873 +v 0.474934 1.652473 -3.282279 +v 0.475022 1.378817 -1.956046 +v -0.000000 1.555461 -2.235664 +v -0.286345 -0.522124 -4.272757 +v -0.348196 -0.774714 -4.379634 +v -0.219490 -1.083571 -4.299738 +v -0.157640 -1.051120 -3.669721 +v 0.000000 -0.779905 -4.378290 +v -0.000000 -0.596975 -4.417508 +v -0.102664 0.055194 -4.242683 +v -0.146605 -0.050889 -4.245935 +v -0.102664 -0.156972 -4.249187 +v -0.535003 0.927651 -1.170873 +v -0.554448 0.771027 -1.905651 +v -0.475022 1.378817 -1.956046 +v -0.474934 1.652473 -3.282279 +v -0.486853 1.384361 -3.885376 +v -0.383333 1.401708 -4.054770 +v -0.000000 1.389247 -4.057433 +v -0.000000 1.388970 -3.345763 +v 0.486863 1.349147 -3.541003 +v 0.564921 0.778709 -1.154154 +v 0.618782 0.854194 -1.918112 +v -0.000000 0.924873 -1.172918 +v -0.000000 1.637336 -3.284120 +v -0.000000 1.646796 -2.576520 +v -0.000000 1.365069 -1.953011 +v 0.516346 0.925587 -1.907866 +v -0.348196 -0.596975 -4.417508 +v -0.564921 0.778709 -1.154154 +v -0.618782 0.854194 -1.918112 +v -0.516346 0.925587 -1.907866 +v -0.486863 1.349147 -3.541003 +v -0.000000 1.220295 -3.554554 +v -0.000000 1.337425 -3.540140 +v 0.553731 0.700325 -1.906446 +v 0.640822 0.717116 -1.918906 +v 0.631112 0.845225 -1.162795 +v -0.000000 0.903141 -1.880688 +v -0.631112 0.845225 -1.162795 +v -0.553731 0.700325 -1.906446 +v -0.640822 0.717116 -1.918906 +v 0.564396 0.698792 -1.154949 +v 0.642575 0.702190 -1.163589 +v -0.564396 0.698792 -1.154949 +v -0.642575 0.702190 -1.163589 +v 0.556345 0.451001 -1.908939 +v 0.567010 0.449469 -1.157442 +v 0.643435 0.467792 -1.921400 +v 0.645189 0.452867 -1.166083 +v -0.567010 0.449469 -1.157442 +v -0.556345 0.451001 -1.908939 +v -0.643435 0.467792 -1.921400 +v -0.645189 0.452867 -1.166083 +v 0.557564 0.380626 -1.898905 +v 0.608296 0.387789 -1.911015 +v 0.608875 0.379127 -1.177056 +v -0.557564 0.380626 -1.898905 +v -0.608296 0.387789 -1.911015 +v -0.608875 0.379127 -1.177056 +v 0.563672 0.379433 -1.168660 +v -0.563672 0.379433 -1.168660 +v 0.559201 0.273989 -1.901043 +v 0.565287 0.272685 -1.170798 +v 0.610055 0.280225 -1.913153 +v 0.610476 0.271554 -1.179194 +v -0.565287 0.272685 -1.170798 +v -0.559201 0.273989 -1.901043 +v -0.610055 0.280225 -1.913153 +v -0.610476 0.271554 -1.179194 +v 0.003419 -0.200914 -4.268863 +v 0.109502 -0.156972 -4.268863 +v -0.102664 -0.156972 -4.268863 +v 0.003419 -0.200914 -4.369526 +v 0.109502 -0.156972 -4.369526 +v 0.153443 -0.050889 -4.268863 +v -0.146605 -0.050889 -4.268863 +v -0.102664 -0.156972 -4.369526 +v 0.153443 -0.050889 -4.369526 +v 0.003419 -0.237359 -4.396092 +v 0.135273 -0.182743 -4.396092 +v 0.109502 0.055194 -4.268863 +v -0.102664 0.055194 -4.268863 +v -0.146605 -0.050889 -4.369526 +v -0.128435 -0.182743 -4.396092 +v 0.109502 0.055194 -4.369526 +v 0.189888 -0.050889 -4.396092 +v 0.003419 -0.237359 -4.656097 +v 0.135273 -0.182743 -4.656097 +v 0.003419 0.099135 -4.268863 +v -0.102664 0.055194 -4.369526 +v -0.183051 -0.050889 -4.396092 +v -0.128435 -0.182743 -4.656097 +v 0.003419 0.099135 -4.369526 +v 0.135273 0.080964 -4.396092 +v 0.189888 -0.050889 -4.656097 +v 0.003419 -0.261613 -4.659142 +v 0.152423 -0.199893 -4.659142 +v -0.128435 0.080964 -4.396092 +v -0.183051 -0.050889 -4.656097 +v -0.145585 -0.199893 -4.659142 +v 0.003419 0.135580 -4.396092 +v 0.135273 0.080965 -4.656097 +v 0.214142 -0.050889 -4.659142 +v 0.003419 -0.261613 -6.253263 +v 0.152423 -0.199893 -6.253263 +v -0.128435 0.080965 -4.656097 +v -0.207305 -0.050889 -4.659142 +v -0.145585 -0.199893 -6.253263 +v 0.003419 0.135580 -4.656097 +v 0.152423 0.098115 -4.659142 +v 0.214142 -0.050889 -6.253263 +v 0.003419 -0.199042 -6.253263 +v 0.108179 -0.155649 -6.253263 +v -0.145585 0.098115 -4.659142 +v -0.207305 -0.050889 -6.253263 +v -0.101341 -0.155649 -6.253263 +v 0.003419 0.159834 -4.659142 +v 0.152423 0.098115 -6.253263 +v 0.151572 -0.050889 -6.253263 +v 0.003419 -0.199042 -4.415716 +v 0.108179 -0.155649 -4.415716 +v -0.145585 0.098115 -6.253263 +v -0.144734 -0.050889 -6.253263 +v -0.101341 -0.155649 -4.415716 +v 0.003419 0.159834 -6.253263 +v 0.108179 0.053871 -6.253263 +v 0.151572 -0.050889 -4.415716 +v -0.144734 -0.050889 -4.415716 +v -0.101341 0.053871 -4.415716 +v 0.003419 0.097264 -4.415716 +v 0.108179 0.053871 -4.415716 +v -0.101341 0.053871 -6.253263 +v 0.003419 0.097264 -6.253263 +vn 0.853300 0.517700 -0.061900 +vn 0.812700 0.510200 -0.281500 +vn 0.771000 0.542000 0.334400 +vn 0.253900 0.321600 0.912200 +vn -0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.002200 0.860700 -0.509100 +vn 1.000000 0.000000 -0.000700 +vn 0.861900 0.507100 -0.000600 +vn -0.004200 0.000000 -1.000000 +vn 0.256300 0.000000 0.966600 +vn 0.918800 0.000000 0.394600 +vn 0.945600 0.000000 -0.325400 +vn 0.997000 0.000000 -0.077700 +vn -0.853300 0.517700 -0.061900 +vn -0.812700 0.510200 -0.281500 +vn -0.771000 0.542000 0.334400 +vn -0.253900 0.321600 0.912200 +vn 0.002200 0.860700 -0.509100 +vn -1.000000 0.000000 -0.000700 +vn 1.000000 -0.000000 0.000000 +vn -0.861900 0.507100 -0.000600 +vn 0.004200 0.000000 -1.000000 +vn -0.256300 0.000000 0.966600 +vn -0.918800 0.000000 0.394600 +vn -0.945600 0.000000 -0.325400 +vn -0.997000 0.000000 -0.077700 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.093300 -0.995600 +vn 0.000000 0.000000 1.000000 +vn 0.000000 -0.029000 -0.999600 +vn 0.000000 -0.673700 -0.739000 +vn 0.000000 -0.393100 -0.919500 +vn 0.000000 0.688200 0.725500 +vn 0.588300 0.556500 0.586700 +vn 0.000000 1.000000 -0.000400 +vn 0.000000 -0.042000 0.999100 +vn 0.707300 -0.029700 0.706300 +vn 0.719600 0.694400 0.001900 +vn -0.010600 0.019900 -0.999700 +vn -0.588300 0.556500 0.586700 +vn 0.499200 -0.708700 0.498500 +vn 1.000000 0.000300 -0.000000 +vn 0.010600 0.019900 -0.999700 +vn -0.719600 0.694400 0.001900 +vn -0.707300 -0.029700 0.706300 +vn 0.000000 0.052700 0.998600 +vn 0.576900 -0.816800 -0.000000 +vn -0.499200 -0.708700 0.498500 +vn 0.707100 0.037200 0.706100 +vn 0.000000 -0.688200 0.725500 +vn 0.000000 -0.611400 -0.791300 +vn -0.010000 0.999900 -0.001500 +vn 0.010000 0.999900 -0.001500 +vn -1.000000 0.000300 -0.000000 +vn -0.576900 -0.816800 -0.000000 +vn -0.707100 0.037200 0.706100 +vn 0.588300 -0.556500 0.586700 +vn 0.000000 -0.840200 -0.542200 +vn 0.000000 -0.489000 -0.872300 +vn 0.000000 0.933300 -0.359000 +vn 0.000000 0.362600 -0.932000 +vn 0.000000 -0.208000 -0.978100 +vn 0.006400 -0.869700 -0.493500 +vn 0.000000 -0.441300 0.897400 +vn 0.000000 0.160800 0.987000 +vn 0.000000 0.807100 0.590500 +vn 0.000000 0.938400 0.345500 +vn 0.000000 0.944200 -0.329400 +vn 0.000000 0.852800 -0.522300 +vn 0.000000 0.180500 -0.983600 +vn 0.707100 -0.707100 0.000000 +vn 0.710600 -0.696400 0.100300 +vn 0.707100 -0.674100 0.213400 +vn 0.715300 -0.693600 0.085700 +vn 0.707100 -0.704400 -0.061800 +vn 0.718800 -0.646600 -0.255300 +vn 0.707100 -0.598200 -0.377100 +vn 0.717200 -0.675200 -0.172300 +vn 0.577000 -0.555900 0.598300 +vn 0.728900 -0.259900 -0.633400 +vn 0.000000 0.942300 0.334800 +vn 0.009100 -0.103700 0.994600 +vn -0.588300 -0.556500 0.586700 +vn 0.000000 -0.988300 0.152700 +vn 0.000000 -0.998700 0.051100 +vn 0.000000 -0.953400 0.301800 +vn 0.000000 -0.996200 -0.087400 +vn 0.000000 -0.845900 -0.533300 +vn 0.723000 -0.371000 -0.582700 +vn 0.000000 0.533500 0.845800 +vn 0.927400 -0.374200 0.000000 +vn 0.000000 -0.681700 0.731700 +vn 0.000000 -0.132600 0.991200 +vn -0.009100 -0.103700 0.994600 +vn 0.999400 0.033800 -0.000000 +vn -0.707100 -0.707100 0.000000 +vn -0.707100 -0.598200 -0.377100 +vn -0.707100 -0.704400 -0.061800 +vn -0.707100 -0.674100 0.213400 +vn -0.006400 -0.869700 -0.493500 +vn 0.000000 -0.997500 0.071200 +vn 0.002000 -1.000000 -0.001900 +vn 0.000000 -0.994000 0.109300 +vn 0.000000 -0.947700 -0.319300 +vn 0.000000 -0.960700 -0.277600 +vn 0.000000 -0.666300 0.745700 +vn 0.700400 0.148200 0.698200 +vn 0.561700 -0.726800 -0.395100 +vn 0.705300 -0.707100 -0.050500 +vn 0.618300 -0.540200 0.570900 +vn 0.000000 -0.310800 -0.950500 +vn 0.000000 -0.541700 -0.840600 +vn 0.728000 -0.031500 -0.684900 +vn 0.742400 -0.563500 -0.362200 +vn 0.725600 -0.687700 -0.024800 +vn 0.769700 -0.592700 0.237400 +vn 0.927300 -0.374200 0.007200 +vn 0.802100 -0.597200 0.000000 +vn 1.000000 -0.000300 -0.002300 +vn 0.578700 -0.815500 -0.000000 +vn 0.532600 -0.660000 -0.529800 +vn 0.000000 -1.000000 0.005000 +vn -0.016700 -0.999800 0.010000 +vn -0.999400 0.033800 -0.000000 +vn 0.853600 0.063800 -0.517000 +vn 0.992900 0.118400 0.006500 +vn 0.016700 -0.999800 0.010000 +vn 0.996200 0.087100 0.006400 +vn 0.000000 -0.686400 0.727200 +vn -1.000000 -0.000300 -0.002300 +vn -0.927400 -0.374200 0.000000 +vn -0.769700 -0.592700 0.237400 +vn -0.725600 -0.687700 -0.024800 +vn -0.742400 -0.563600 -0.362200 +vn -0.728000 -0.031500 -0.684900 +vn -0.728900 -0.259900 -0.633400 +vn -0.723000 -0.371000 -0.582700 +vn -0.705300 -0.707100 -0.050500 +vn -0.700400 0.148200 0.698200 +vn -0.577000 -0.555900 0.598300 +vn -0.717200 -0.675200 -0.172300 +vn -0.718800 -0.646600 -0.255300 +vn -0.715300 -0.693600 0.085700 +vn -0.710600 -0.696400 0.100300 +vn -0.578700 -0.815500 -0.000000 +vn -0.002000 -1.000000 -0.001900 +vn 0.000000 0.206000 0.978600 +vn 0.000000 -0.878600 -0.477600 +vn 0.000000 -0.997400 -0.071700 +vn 0.000000 -0.687300 0.726400 +vn 0.001700 -0.224000 -0.974600 +vn 0.010700 -0.707000 -0.707100 +vn 0.016900 -0.996700 -0.079300 +vn 0.820400 -0.443500 -0.361000 +vn 0.766300 -0.570500 -0.295500 +vn 0.628100 -0.467700 0.621900 +vn -0.005600 -0.999700 -0.022800 +vn 0.394200 0.855100 -0.336900 +vn 0.853300 -0.132900 -0.504200 +vn 0.788200 0.012800 -0.615300 +vn -0.996200 0.087100 0.006400 +vn -0.992900 0.118400 0.006500 +vn -0.853600 0.063800 -0.517000 +vn -0.001600 0.067500 -0.997700 +vn 0.842800 0.198300 -0.500400 +vn 0.001400 -0.999800 0.021300 +vn -0.532600 -0.660000 -0.529800 +vn -0.927300 -0.374200 0.007200 +vn -0.802100 -0.597200 0.000000 +vn -0.561700 -0.726800 -0.395100 +vn -0.618300 -0.540200 0.570900 +vn -0.001700 -0.224000 -0.974600 +vn -0.010700 -0.707000 -0.707100 +vn 0.017200 -0.710500 0.703500 +vn -0.018000 -0.843900 -0.536300 +vn 0.021400 -0.705600 0.708200 +vn -0.000000 0.176800 -0.984300 +vn 0.000000 0.030600 -0.999500 +vn -0.001400 -0.999800 0.021300 +vn -0.788200 0.012800 -0.615300 +vn -0.842800 0.198300 -0.500400 +vn 0.001600 0.067500 -0.997700 +vn -0.006700 0.245300 -0.969400 +vn 0.999500 0.032400 0.003800 +vn 0.854100 0.103600 -0.509700 +vn -0.685500 -0.727800 0.017700 +vn -0.000700 0.089300 0.996000 +vn -0.028900 0.965300 0.259600 +vn -0.394200 0.855100 -0.336900 +vn -0.853300 -0.132900 -0.504200 +vn -0.820400 -0.443500 -0.361000 +vn -0.766300 -0.570500 -0.295500 +vn 0.005600 -0.999700 -0.022800 +vn -0.628100 -0.467700 0.621900 +vn -0.016900 -0.996700 -0.079300 +vn -0.017200 -0.710500 0.703500 +vn -0.000000 -0.250400 -0.968100 +vn 0.018000 -0.843900 -0.536300 +vn 0.000000 0.888300 -0.459300 +vn -0.000300 -0.209000 -0.977900 +vn 0.000700 0.089300 0.996000 +vn 0.685500 -0.727800 0.017700 +vn 0.028900 0.965300 0.259600 +vn -0.999500 0.032400 0.003800 +vn -0.854100 0.103600 -0.509700 +vn 0.006700 0.245300 -0.969400 +vn 0.001500 0.143200 -0.989700 +vn -0.024800 0.778200 -0.627600 +vn -0.198700 -0.063000 -0.978000 +vn -0.030900 0.105400 0.994000 +vn -0.005600 0.243700 -0.969800 +vn -0.031200 0.999400 -0.012900 +vn -0.021700 0.828100 0.560100 +vn -0.021400 -0.705600 0.708200 +vn 0.030900 0.105400 0.994000 +vn 0.198700 -0.063000 -0.978000 +vn 0.021700 0.828100 0.560100 +vn 0.024800 0.778200 -0.627600 +vn 0.031200 0.999400 -0.012900 +vn 0.005600 0.243700 -0.969800 +vn -0.001500 0.143200 -0.989700 +vn 0.005200 -0.123900 0.992300 +vn -0.025800 0.994300 0.103300 +vn -0.999900 0.008100 0.014000 +vn -0.156900 -0.008600 -0.987600 +vn -0.024400 0.999600 -0.016100 +vn 0.025400 0.131600 0.991000 +vn 0.000300 -0.209000 -0.977900 +vn 0.024400 0.999600 -0.016100 +vn 0.999900 0.008100 0.014000 +vn 0.156900 -0.008600 -0.987600 +vn -0.025400 0.131600 0.991000 +vn -0.005200 -0.123900 0.992300 +vn 0.025800 0.994300 0.103300 +vn 0.612400 0.790500 -0.009100 +vn 0.992900 0.118800 -0.007400 +vn 0.119400 -0.001200 0.992800 +vn -0.612400 0.790500 -0.009100 +vn -0.119400 -0.001200 0.992800 +vn -0.992900 0.118800 -0.007400 +vn -0.999800 -0.010600 0.014200 +vn -0.143200 0.008400 -0.989700 +vn 0.999900 0.010500 -0.002100 +vn 0.999800 -0.010600 0.014200 +vn 0.143200 0.008400 -0.989700 +vn -0.999900 0.010500 -0.002100 +vn 0.110200 -0.008800 0.993900 +vn -0.999800 0.015000 0.011300 +vn -0.158200 -0.097700 -0.982600 +vn 0.906800 -0.421400 -0.008100 +vn -0.110200 -0.008800 0.993900 +vn 0.999800 0.015000 0.011300 +vn 0.158200 -0.097700 -0.982600 +vn -0.906800 -0.421400 -0.008100 +vn 0.139000 -0.188400 0.972200 +vn -0.139000 -0.188400 0.972200 +vn -0.999800 -0.015400 0.008300 +vn -0.233800 0.015700 -0.972100 +vn 0.999900 0.015600 -0.000500 +vn 0.182400 -0.016900 0.983100 +vn 0.999800 -0.015400 0.008300 +vn 0.233800 0.015700 -0.972100 +vn -0.999900 0.015600 -0.000500 +vn -0.182400 -0.016900 0.983100 +vn 0.051600 -0.998600 -0.007000 +vn -0.051600 -0.998600 -0.007000 +vn 0.382700 -0.923900 0.000000 +vn -0.382700 -0.923900 0.000000 +vn 0.923900 -0.382700 0.000000 +vn -0.923900 -0.382700 0.000000 +vn 0.237000 -0.572300 0.785100 +vn 0.923900 0.382700 0.000000 +vn -0.923900 0.382700 0.000000 +vn -0.237000 -0.572300 0.785100 +vn 0.572300 -0.237000 0.785100 +vn 0.382700 0.923900 0.000000 +vn -0.382700 0.923900 -0.000000 +vn -0.572300 -0.237000 0.785100 +vn 0.572300 0.237000 0.785100 +vn 0.051500 -0.124400 0.990900 +vn -0.572300 0.237000 0.785100 +vn -0.051500 -0.124400 0.990900 +vn 0.237000 0.572300 0.785100 +vn 0.124400 -0.051500 0.990900 +vn -0.237000 0.572300 0.785100 +vn -0.124400 -0.051500 0.990900 +vn 0.124400 0.051500 0.990900 +vn 0.000000 0.000000 -1.000000 +vn -0.124400 0.051500 0.990900 +vn 0.051500 0.124400 0.990900 +vn -0.051500 0.124400 0.990900 +usemtl Material.004 +s off +f 14//1 8//1 2//1 11//1 +f 11//2 2//2 4//2 12//2 +f 12//3 4//3 6//3 13//3 +f 13//4 6//4 25//4 36//4 +f 16//5 7//5 1//5 3//5 5//5 24//5 +f 2//6 8//6 17//6 25//6 6//6 4//6 +f 17//6 8//6 9//6 29//6 +f 38//7 29//7 9//7 15//7 +f 14//8 7//8 10//8 15//8 +f 7//5 16//5 30//5 10//5 +f 8//9 14//9 15//9 9//9 +f 30//10 38//10 15//10 10//10 +f 5//11 13//11 36//11 24//11 +f 3//12 12//12 13//12 5//12 +f 1//13 11//13 12//13 3//13 +f 7//14 14//14 11//14 1//14 +f 37//15 33//15 19//15 27//15 +f 33//16 34//16 21//16 19//16 +f 34//17 35//17 23//17 21//17 +f 35//18 36//18 25//18 23//18 +f 16//5 24//5 22//5 20//5 18//5 26//5 +f 19//6 21//6 23//6 25//6 17//6 27//6 +f 17//6 29//6 28//6 27//6 +f 38//19 39//19 28//19 29//19 +f 37//20 39//20 31//20 26//20 +f 26//5 31//5 30//5 16//5 +f 32//21 38//21 29//21 17//21 +f 16//21 30//21 38//21 32//21 +f 27//22 28//22 39//22 37//22 +f 30//23 31//23 39//23 38//23 +f 22//24 24//24 36//24 35//24 +f 20//25 22//25 35//25 34//25 +f 18//26 20//26 34//26 33//26 +f 26//27 18//27 33//27 37//27 +usemtl Material.003 +f 48//28 49//28 42//28 40//28 +f 49//29 50//29 46//29 42//29 +f 50//21 51//21 44//21 46//21 +f 51//30 48//30 40//30 44//30 +f 40//5 42//5 46//5 44//5 +f 45//6 47//6 43//6 41//6 +f 58//30 59//30 48//30 51//30 +f 57//21 58//21 51//21 50//21 +f 56//31 57//31 50//31 49//31 +f 59//28 56//28 49//28 48//28 +f 41//28 43//28 53//28 52//28 +f 43//32 47//32 54//32 53//32 +f 47//21 45//21 55//21 54//21 +f 45//30 41//30 52//30 55//30 +f 52//28 53//28 56//28 59//28 +f 53//33 54//33 57//33 56//33 +f 54//21 55//21 58//21 57//21 +f 55//30 52//30 59//30 58//30 +usemtl Material.001 +f 60//34 61//34 62//34 63//34 +f 64//35 60//35 63//35 +f 65//36 61//36 60//36 66//36 +f 67//34 68//34 62//34 61//34 +f 63//37 62//37 69//37 70//37 +f 63//38 70//38 71//38 64//38 +f 60//39 64//39 80//39 66//39 +f 65//40 66//40 80//40 79//40 72//40 +f 65//36 73//36 67//36 61//36 +f 74//41 68//41 67//41 +f 68//37 75//37 69//37 62//37 +f 76//30 77//30 70//30 69//30 +f 71//42 70//42 77//42 78//42 +f 64//43 71//43 85//43 125//43 171//43 174//43 141//43 229//43 233//43 126//43 79//43 80//43 +f 65//44 72//44 88//44 89//44 73//44 +f 67//45 73//45 89//45 74//45 +f 68//46 74//46 81//46 75//46 +f 76//30 69//30 75//30 82//30 +f 77//47 76//47 83//47 84//47 +f 85//48 71//48 78//48 86//48 +f 81//49 90//49 82//49 75//49 +f 82//47 91//47 83//47 76//47 +f 77//50 84//50 92//50 78//50 +f 93//51 94//51 84//51 83//51 +f 85//52 86//52 95//52 96//52 +f 97//21 98//21 99//21 100//21 101//21 102//21 103//21 104//21 105//21 106//21 107//21 108//21 109//21 110//21 86//21 78//21 92//21 111//21 112//21 113//21 114//21 115//21 116//21 117//21 118//21 119//21 120//21 121//21 122//21 123//21 124//21 +f 126//53 87//53 72//53 79//53 +f 72//54 87//54 175//54 88//54 +f 89//55 88//55 175//55 276//55 282//55 259//55 236//55 237//55 176//55 127//55 81//55 74//55 +f 127//56 128//56 90//56 81//56 +f 82//57 90//57 129//57 91//57 +f 93//51 83//51 91//51 130//51 +f 84//58 94//58 92//58 +f 93//5 131//5 132//5 94//5 +f 125//59 85//59 96//59 133//59 +f 86//60 110//60 134//60 95//60 +f 127//52 96//52 95//52 128//52 +f 97//61 124//61 135//61 136//61 +f 98//62 97//62 136//62 137//62 +f 99//62 98//62 137//62 138//62 +f 99//6 138//6 139//6 100//6 +f 101//63 100//63 139//63 140//63 +f 101//64 140//64 208//64 102//64 +f 104//65 103//65 142//65 143//65 +f 105//66 104//66 143//66 144//66 +f 106//67 105//67 144//67 145//67 +f 107//68 106//68 145//68 146//68 +f 108//69 107//69 146//69 147//69 +f 109//70 108//70 147//70 148//70 +f 110//71 109//71 148//71 134//71 +f 94//72 132//72 111//72 92//72 +f 111//73 132//73 149//73 112//73 +f 149//74 150//74 113//74 112//74 +f 114//75 113//75 150//75 151//75 +f 151//76 152//76 115//76 114//76 +f 115//77 152//77 153//77 116//77 +f 153//78 154//78 117//78 116//78 +f 117//79 154//79 155//79 118//79 +f 155//72 156//72 119//72 118//72 +f 120//80 119//80 156//80 157//80 +f 121//21 120//21 158//21 159//21 +f 121//81 160//81 221//81 122//81 +f 123//21 122//21 161//21 162//21 163//21 164//21 165//21 166//21 167//21 168//21 169//21 +f 124//82 123//82 170//82 135//82 +f 87//83 126//83 172//83 173//83 +f 177//28 178//28 179//28 180//28 181//28 182//28 183//28 184//28 185//28 186//28 187//28 188//28 189//28 190//28 191//28 129//28 90//28 128//28 192//28 193//28 194//28 195//28 196//28 197//28 198//28 199//28 200//28 201//28 202//28 203//28 204//28 +f 91//84 129//84 130//84 +f 93//5 130//5 205//5 131//5 +f 132//85 131//85 206//85 149//85 +f 171//86 125//86 133//86 207//86 +f 176//59 133//59 96//59 127//59 +f 128//60 95//60 134//60 192//60 +f 177//61 136//61 135//61 178//61 +f 204//62 137//62 136//62 177//62 +f 203//62 138//62 137//62 204//62 +f 203//6 202//6 139//6 138//6 +f 201//63 140//63 139//63 202//63 +f 103//65 210//65 211//65 142//65 +f 198//65 143//65 142//65 199//65 +f 197//66 144//66 143//66 198//66 +f 196//67 145//67 144//67 197//67 +f 195//68 146//68 145//68 196//68 +f 194//69 147//69 146//69 195//69 +f 193//70 148//70 147//70 194//70 +f 192//71 134//71 148//71 193//71 +f 149//87 206//87 212//87 150//87 +f 151//88 213//88 214//88 152//88 +f 153//89 215//89 216//89 154//89 +f 155//5 217//5 218//5 156//5 +f 159//90 219//90 160//90 121//90 +f 123//91 169//91 222//91 170//91 +f 165//92 164//92 226//92 227//92 +f 168//93 167//93 230//93 231//93 +f 169//94 168//94 231//94 222//94 +f 178//82 135//82 170//82 179//82 +f 87//95 173//95 232//95 175//95 +f 126//96 233//96 234//96 172//96 +f 179//28 238//28 239//28 240//28 241//28 242//28 243//28 244//28 245//28 246//28 180//28 +f 181//28 248//28 249//28 182//28 +f 251//97 184//97 183//97 252//97 +f 254//98 186//98 185//98 253//98 +f 256//99 188//99 187//99 255//99 +f 257//100 190//100 189//100 258//100 +f 130//97 129//97 191//97 205//97 +f 201//101 200//101 208//101 140//101 +f 205//85 257//85 206//85 131//85 +f 174//102 171//102 207//102 260//102 +f 237//86 207//86 133//86 176//86 +f 208//103 261//103 209//103 102//103 +f 210//65 141//65 262//65 211//65 +f 199//65 142//65 211//65 263//65 +f 257//87 258//87 212//87 206//87 +f 150//104 212//104 213//104 151//104 +f 256//88 255//88 214//88 213//88 +f 152//105 214//105 215//105 153//105 +f 254//89 253//89 216//89 215//89 +f 154//106 216//106 217//106 155//106 +f 251//5 252//5 218//5 217//5 +f 156//107 218//107 264//107 157//107 +f 265//108 158//108 120//108 157//108 +f 219//109 159//109 266//109 +f 266//110 159//110 158//110 220//110 +f 265//111 220//111 158//111 +f 160//112 267//112 268//112 221//112 +f 267//113 160//113 219//113 269//113 +f 179//91 170//91 222//91 238//91 +f 223//114 161//114 122//114 221//114 +f 224//115 162//115 161//115 223//115 +f 225//116 163//116 162//116 224//116 +f 226//117 164//117 163//117 225//117 299//117 +f 165//118 227//118 228//118 +f 227//119 226//119 270//119 271//119 +f 272//120 166//120 165//120 228//120 +f 229//121 141//121 210//121 103//121 102//121 209//121 167//121 166//121 +f 229//122 166//122 302//122 273//122 +f 167//123 209//123 261//123 230//123 +f 239//93 231//93 230//93 240//93 +f 238//94 222//94 231//94 239//94 +f 232//124 173//124 280//124 274//124 +f 175//125 232//125 275//125 276//125 +f 233//126 277//126 278//126 234//126 +f 234//127 279//127 311//127 172//127 +f 280//128 173//128 172//128 235//128 +f 235//129 172//129 311//129 314//129 345//129 281//129 315//129 346//129 372//129 +f 141//130 174//130 260//130 262//130 +f 242//131 241//131 317//131 283//131 +f 242//132 284//132 285//132 243//132 +f 244//133 243//133 285//133 351//133 286//133 +f 245//134 244//134 286//134 287//134 +f 246//135 245//135 287//135 288//135 +f 180//136 246//136 288//136 289//136 +f 289//137 247//137 181//137 180//137 +f 247//138 290//138 248//138 181//138 +f 249//139 248//139 320//139 291//139 +f 182//140 249//140 321//140 250//140 +f 252//141 183//141 182//141 250//141 +f 251//142 253//142 185//142 184//142 +f 254//143 255//143 187//143 186//143 +f 258//144 189//144 188//144 256//144 +f 257//145 205//145 191//145 190//145 +f 263//146 259//146 282//146 241//146 240//146 292//146 200//146 199//146 +f 236//102 260//102 207//102 237//102 +f 208//147 200//147 292//147 261//147 +f 263//65 211//65 262//65 259//65 +f 258//104 256//104 213//104 212//104 +f 255//105 254//105 215//105 214//105 +f 253//106 251//106 217//106 216//106 +f 252//107 250//107 264//107 218//107 +f 157//148 264//148 293//148 265//148 +f 266//149 294//149 269//149 219//149 +f 295//150 294//150 266//150 220//150 +f 265//151 293//151 295//151 220//151 +f 247//112 289//112 268//112 267//112 +f 268//152 296//152 223//152 221//152 +f 267//113 269//113 290//113 247//113 +f 223//153 296//153 297//153 224//153 +f 225//154 224//154 297//154 298//154 +f 227//155 300//155 303//155 228//155 +f 300//156 227//156 271//156 +f 299//157 270//157 226//157 +f 271//158 270//158 324//158 301//158 +f 166//159 272//159 325//159 302//159 +f 228//160 303//160 325//160 272//160 +f 273//161 277//161 233//161 229//161 +f 240//123 230//123 261//123 292//123 +f 336//162 304//162 360//162 337//162 338//162 232//162 274//162 376//162 359//162 +f 275//163 232//163 338//163 305//163 +f 276//164 275//164 306//164 307//164 +f 277//165 308//165 309//165 278//165 +f 278//166 310//166 279//166 234//166 +f 280//167 235//167 312//167 313//167 +f 259//130 262//130 260//130 236//130 +f 282//168 316//168 348//168 241//168 +f 242//169 283//169 284//169 +f 284//170 318//170 319//170 285//170 +f 290//171 320//171 248//171 +f 321//172 249//172 291//172 +f 250//148 321//148 293//148 264//148 +f 320//149 290//149 269//149 294//149 +f 295//150 291//150 320//150 294//150 +f 321//151 291//151 295//151 293//151 +f 268//173 289//173 288//173 296//173 +f 288//174 287//174 297//174 296//174 +f 298//175 322//175 299//175 225//175 +f 300//176 271//176 301//176 323//176 +f 270//177 299//177 322//177 324//177 +f 302//178 326//178 327//178 273//178 +f 327//179 328//179 329//179 330//179 331//179 332//179 333//179 334//179 308//179 277//179 273//179 +f 280//180 313//180 335//180 274//180 +f 276//181 307//181 316//181 282//181 +f 305//182 339//182 306//182 275//182 +f 307//183 306//183 309//183 308//183 +f 310//184 278//184 309//184 340//184 +f 279//185 341//185 365//185 311//185 +f 310//186 342//186 341//186 279//186 +f 235//187 343//187 366//187 312//187 +f 312//188 344//188 368//188 313//188 +f 315//189 281//189 370//189 347//189 +f 241//190 348//190 373//190 317//190 +f 283//191 317//191 373//191 349//191 +f 284//192 283//192 349//192 350//192 +f 350//193 318//193 284//193 +f 318//194 301//194 324//194 319//194 +f 351//195 285//195 319//195 +f 286//196 298//196 297//196 287//196 +f 298//197 286//197 351//197 322//197 +f 300//198 323//198 352//198 303//198 +f 301//199 318//199 350//199 323//199 +f 326//200 302//200 325//200 353//200 +f 325//201 303//201 352//201 353//201 +f 348//178 316//178 327//178 326//178 +f 327//179 316//179 307//179 308//179 334//179 354//179 355//179 356//179 328//179 +f 335//202 313//202 368//202 357//202 +f 274//203 335//203 374//203 358//203 +f 336//204 347//204 370//204 304//204 +f 305//205 338//205 377//205 361//205 +f 339//206 305//206 361//206 362//206 +f 339//207 340//207 309//207 306//207 +f 340//208 363//208 342//208 310//208 +f 314//209 311//209 378//209 364//209 +f 343//210 235//210 372//210 367//210 +f 312//211 366//211 382//211 344//211 +f 345//212 314//212 364//212 369//212 +f 281//213 345//213 369//213 370//213 +f 346//214 315//214 347//214 371//214 +f 319//215 324//215 322//215 351//215 +f 350//198 349//198 352//198 323//198 +f 326//200 353//200 373//200 348//200 +f 335//216 357//216 384//216 374//216 +f 358//217 375//217 376//217 274//217 +f 347//218 336//218 359//218 371//218 +f 337//219 364//219 378//219 338//219 +f 304//220 370//220 369//220 360//220 +f 360//221 369//221 364//221 337//221 +f 362//222 363//222 340//222 339//222 +f 311//223 365//223 379//223 378//223 +f 365//224 341//224 342//224 363//224 379//224 +f 343//225 380//225 387//225 366//225 +f 367//226 381//226 380//226 343//226 +f 344//227 372//227 383//227 368//227 +f 371//228 383//228 372//228 346//228 +f 373//229 353//229 352//229 349//229 +f 357//230 368//230 383//230 376//230 +f 358//231 374//231 389//231 385//231 +f 375//232 358//232 385//232 386//232 +f 376//233 383//233 371//233 359//233 +f 338//234 378//234 379//234 377//234 +f 377//235 379//235 363//235 362//235 361//235 +f 367//236 372//236 344//236 382//236 +f 381//237 367//237 382//237 388//237 +f 366//238 387//238 388//238 382//238 +f 357//239 376//239 375//239 384//239 +f 374//240 384//240 390//240 389//240 +f 386//241 390//241 384//241 375//241 +f 387//242 380//242 391//242 392//242 +f 380//243 381//243 393//243 391//243 +f 381//244 388//244 394//244 393//244 +f 389//245 395//245 396//245 385//245 +f 385//246 396//246 397//246 386//246 +f 386//247 397//247 398//247 390//247 +f 388//248 387//248 392//248 394//248 +f 391//249 399//249 405//249 392//249 +f 393//250 400//250 399//250 391//250 +f 394//251 401//251 400//251 393//251 +f 390//252 398//252 395//252 389//252 +f 396//253 395//253 406//253 402//253 +f 397//254 396//254 402//254 403//254 +f 398//255 397//255 403//255 404//255 +f 392//256 405//256 401//256 394//256 +f 395//257 398//257 404//257 406//257 +f 405//258 399//258 407//258 408//258 +f 400//259 409//259 407//259 399//259 +f 401//260 410//260 409//260 400//260 +f 405//261 408//261 410//261 401//261 +f 406//262 411//262 412//262 402//262 +f 403//263 402//263 412//263 413//263 +f 404//264 403//264 413//264 414//264 +f 406//265 404//265 414//265 411//265 +f 408//266 407//266 409//266 410//266 +f 411//267 414//267 413//267 412//267 +f 329//268 415//268 416//268 330//268 +f 356//269 417//269 415//269 329//269 328//269 +f 416//268 415//268 418//268 419//268 +f 330//270 416//270 420//270 331//270 +f 355//271 421//271 417//271 356//271 +f 415//269 417//269 422//269 418//269 +f 420//270 416//270 419//270 423//270 +f 419//272 418//272 424//272 425//272 +f 331//273 420//273 426//273 332//273 +f 354//274 427//274 421//274 355//274 +f 417//271 421//271 428//271 422//271 +f 418//275 422//275 429//275 424//275 +f 426//273 420//273 423//273 430//273 +f 423//276 419//276 425//276 431//276 +f 425//268 424//268 432//268 433//268 +f 332//277 426//277 434//277 333//277 +f 333//278 434//278 427//278 354//278 334//278 +f 421//274 427//274 435//274 428//274 +f 422//279 428//279 436//279 429//279 +f 424//269 429//269 437//269 432//269 +f 434//277 426//277 430//277 438//277 +f 430//280 423//280 431//280 439//280 +f 431//270 425//270 433//270 440//270 +f 433//281 432//281 441//281 442//281 +f 427//278 434//278 438//278 435//278 +f 428//282 435//282 443//282 436//282 +f 429//271 436//271 444//271 437//271 +f 432//283 437//283 445//283 441//283 +f 438//284 430//284 439//284 446//284 +f 439//273 431//273 440//273 447//273 +f 440//285 433//285 442//285 448//285 +f 442//268 441//268 449//268 450//268 +f 435//286 438//286 446//286 443//286 +f 436//274 443//274 451//274 444//274 +f 437//287 444//287 452//287 445//287 +f 441//269 445//269 453//269 449//269 +f 446//277 439//277 447//277 454//277 +f 447//288 440//288 448//288 455//288 +f 448//270 442//270 450//270 456//270 +f 450//289 449//289 457//289 458//289 +f 443//278 446//278 454//278 451//278 +f 444//290 451//290 459//290 452//290 +f 445//271 452//271 460//271 453//271 +f 449//289 453//289 461//289 457//289 +f 454//291 447//291 455//291 462//291 +f 455//273 448//273 456//273 463//273 +f 456//289 450//289 458//289 464//289 +f 458//278 457//278 465//278 466//278 +f 451//292 454//292 462//292 459//292 +f 452//274 459//274 467//274 460//274 +f 453//289 460//289 468//289 461//289 +f 457//277 461//277 469//277 465//277 +f 462//277 455//277 463//277 470//277 +f 463//289 456//289 464//289 471//289 +f 464//274 458//274 466//274 472//274 +f 466//289 465//289 469//289 473//289 474//289 475//289 476//289 472//289 +f 459//278 462//278 470//278 467//278 +f 460//289 467//289 477//289 468//289 +f 461//273 468//273 473//273 469//273 +f 470//289 463//289 471//289 478//289 +f 471//271 464//271 472//271 476//271 +f 468//270 477//270 474//270 473//270 +f 477//268 478//268 475//268 474//268 +f 478//269 471//269 476//269 475//269 +f 467//289 470//289 478//289 477//289 diff --git a/assets/quaternius/models/P90.obj.import b/assets/quaternius/models/P90.obj.import new file mode 100644 index 0000000..e947d17 --- /dev/null +++ b/assets/quaternius/models/P90.obj.import @@ -0,0 +1,25 @@ +[remap] + +importer="wavefront_obj" +importer_version=1 +type="Mesh" +uid="uid://dib3ephrwejf1" +path="res://.godot/imported/P90.obj-8df31986961b4a8e1ac0386a3807b1da.mesh" + +[deps] + +files=["res://.godot/imported/P90.obj-8df31986961b4a8e1ac0386a3807b1da.mesh"] + +source_file="res://assets/quaternius/models/P90.obj" +dest_files=["res://.godot/imported/P90.obj-8df31986961b4a8e1ac0386a3807b1da.mesh", "res://.godot/imported/P90.obj-8df31986961b4a8e1ac0386a3807b1da.mesh"] + +[params] + +generate_tangents=true +generate_lods=true +generate_shadow_mesh=true +generate_lightmap_uv2=false +generate_lightmap_uv2_texel_size=0.2 +scale_mesh=Vector3(1, 1, 1) +offset_mesh=Vector3(0, 0, 0) +force_disable_mesh_compression=false diff --git a/assets/quaternius/models/Pistol.glb b/assets/quaternius/models/Pistol.glb new file mode 100644 index 0000000..7b3891a Binary files /dev/null and b/assets/quaternius/models/Pistol.glb differ diff --git a/assets/kenney-fps/models/enemy-flying.glb.import b/assets/quaternius/models/Pistol.glb.import similarity index 64% rename from assets/kenney-fps/models/enemy-flying.glb.import rename to assets/quaternius/models/Pistol.glb.import index 3d84b92..9b21860 100644 --- a/assets/kenney-fps/models/enemy-flying.glb.import +++ b/assets/quaternius/models/Pistol.glb.import @@ -3,19 +3,21 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://lde2xq3vq635" -path="res://.godot/imported/enemy-flying.glb-6120572f403485a0abe68ce33d56638b.scn" +uid="uid://dsitqopjjyv0f" +path="res://.godot/imported/Pistol.glb-89dbea87b37e6ee1eb7a927c1a2eeafb.scn" [deps] -source_file="res://models/enemy-flying.glb" -dest_files=["res://.godot/imported/enemy-flying.glb-6120572f403485a0abe68ce33d56638b.scn"] +source_file="res://assets/quaternius/models/Pistol.glb" +dest_files=["res://.godot/imported/Pistol.glb-89dbea87b37e6ee1eb7a927c1a2eeafb.scn"] [params] -nodes/root_type="Node3D" -nodes/root_name="Scene Root" +nodes/root_type="" +nodes/root_name="" nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true nodes/apply_root_scale=true nodes/root_scale=1.0 nodes/import_as_skeleton_bones=false @@ -38,5 +40,6 @@ materials/extract=0 materials/extract_format=0 materials/extract_path="" _subresources={} -gltf/naming_version=0 +gltf/naming_version=2 gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/assets/quaternius/models/Pistol.mtl b/assets/quaternius/models/Pistol.mtl new file mode 100644 index 0000000..10be6b0 --- /dev/null +++ b/assets/quaternius/models/Pistol.mtl @@ -0,0 +1,62 @@ +# Blender MTL File: 'Pistol.blend' +# Material Count: 6 + +newmtl DarkerMetal +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Magazine +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Material.003 +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Metal +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Muzzle +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Wood +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 diff --git a/assets/quaternius/models/Pistol.obj b/assets/quaternius/models/Pistol.obj new file mode 100644 index 0000000..919348c --- /dev/null +++ b/assets/quaternius/models/Pistol.obj @@ -0,0 +1,1785 @@ +# Blender v2.76 (sub 0) OBJ File: 'Pistol.blend' +# www.blender.org +mtllib Pistol.mtl +o Muzzle +v -4.476699 -2.729682 0.281679 +v -2.784325 -3.084115 0.281679 +v -4.476699 -2.729682 -0.281678 +v -2.784325 -3.084115 -0.281678 +v -3.267023 0.938434 0.281679 +v -1.521989 0.636661 0.281679 +v -3.267023 0.938434 -0.281678 +v -1.521989 0.636661 -0.281678 +v -4.649329 -2.729682 0.327933 +v -2.603434 -3.084114 0.327933 +v -4.649329 -2.729682 -0.327932 +v -2.603434 -3.084114 -0.327932 +v -4.690264 -2.934360 0.327933 +v -2.644368 -3.233776 0.327933 +v -4.690264 -2.934360 -0.327932 +v -2.644368 -3.233776 -0.327932 +v -4.798998 -2.581476 0.362281 +v -3.579317 0.473820 0.362282 +v -2.355204 -2.987302 0.362281 +v -1.444532 -0.241017 0.362282 +v -4.222938 -1.236677 0.362282 +v -1.998442 -1.582696 0.362282 +v -1.090580 0.101692 0.362282 +v -3.733734 0.826496 0.362282 +v -0.989683 0.383415 0.362282 +v -3.666064 1.591670 0.362282 +v -4.440645 1.117349 0.152840 +v -4.432783 1.324311 0.152840 +v -4.009551 1.433071 0.194895 +v -4.057285 1.076588 0.194895 +v -3.851285 -0.381428 0.362282 +v -1.754714 -0.911856 0.362282 +v -0.859403 1.757498 0.362282 +v -3.602237 1.769586 0.362282 +v -1.058072 0.727078 0.362282 +v -0.740763 1.124958 0.362281 +v 0.562104 1.760490 0.355657 +v 0.750571 1.125198 0.355657 +v 2.815151 1.811499 0.352552 +v 2.830560 1.166613 0.352552 +v 1.224105 1.141108 0.354104 +v 1.208697 1.785994 0.354105 +v -3.543367 -0.238613 0.617818 +v -3.315637 0.477518 0.617818 +v -2.121719 -1.244479 0.617818 +v -2.506987 -2.420609 0.617818 +v -1.657910 -0.121041 0.617818 +v -4.336923 -2.080794 0.617818 +v -3.444936 0.772827 0.617818 +v -3.854564 -0.954745 0.617818 +v -1.917637 -0.682760 0.617818 +v -1.361532 0.165922 0.617818 +v -1.277048 0.401819 0.617818 +v -3.388275 1.413535 0.617818 +v -3.334830 1.656411 0.617818 +v -3.675889 1.381268 0.450506 +v -4.030276 1.341147 0.277035 +v -4.036859 1.167850 0.277035 +v -3.715859 1.082772 0.450506 +v -1.038153 1.646288 0.617818 +v 0.152128 1.648794 0.612270 +v -1.334311 0.689580 0.617818 +v -0.938811 1.345454 0.617818 +v 0.165030 1.345655 0.612270 +v 2.627126 1.691507 0.609671 +v 2.640028 1.422055 0.609671 +v 0.706446 1.400698 0.610971 +v 0.693544 1.670150 0.610971 +v -4.306217 -2.612876 0.375104 +v -2.865760 -2.844352 0.375104 +v -2.684457 -2.298832 0.616215 +v -3.489255 -0.240016 0.616215 +v -3.252746 0.435687 0.616215 +v -2.277669 -1.189098 0.616215 +v -1.937399 -0.129081 0.616215 +v -4.238012 -2.043105 0.616215 +v -3.158402 0.714326 0.616215 +v -3.782884 -0.915720 0.616215 +v -2.085109 -0.659090 0.616215 +v -1.830828 0.141682 0.616215 +v -1.816016 0.364262 0.616215 +v -2.910228 1.318864 0.616215 +v -2.773263 1.548029 0.616215 +v -1.550943 1.430306 0.616215 +v -1.686155 0.679047 0.616215 +v -1.475239 1.254626 0.616215 +v -2.095214 1.588775 0.616215 +v -4.307481 -2.620646 0.515038 +v -2.867024 -2.852122 0.515038 +v -2.685722 -2.306602 0.756148 +v -3.490520 -0.247786 0.756148 +v -3.254010 0.427918 0.756148 +v -2.278934 -1.196867 0.756148 +v -1.938663 -0.136851 0.756148 +v -4.239276 -2.050875 0.756148 +v -3.159667 0.706556 0.756148 +v -3.784149 -0.923490 0.756148 +v -2.086372 -0.666860 0.756148 +v -1.832092 0.133912 0.756148 +v -1.817281 0.356493 0.756148 +v -2.911492 1.311095 0.756148 +v -2.774528 1.540260 0.756148 +v -2.096478 1.581006 0.756148 +v -1.687419 0.671278 0.756148 +v -1.476503 1.246857 0.756148 +v -1.552208 1.422536 0.756148 +v -4.620386 -2.757102 0.362281 +v -2.583257 -3.109388 0.362281 +v 0.169830 1.125104 0.358236 +v 0.639359 0.808476 0.360184 +v 0.499530 0.808383 0.362764 +v 0.620819 0.367841 0.366194 +v 0.519641 0.396732 0.368774 +v 0.433727 0.092503 0.369846 +v 0.356526 0.163999 0.372426 +v 0.224690 -0.043395 0.373404 +v 0.214296 0.061313 0.375984 +v -0.070517 -0.072659 0.377330 +v -0.064520 0.032393 0.379909 +v -0.639295 -0.082211 0.385008 +v -0.633298 0.053320 0.387588 +v -1.228139 -0.031497 0.362281 +v -4.798998 -2.581476 -0.362281 +v -3.579317 0.473820 -0.362282 +v -2.355204 -2.987302 -0.362281 +v -1.444532 -0.241017 -0.362282 +v -3.579317 0.473820 0.000000 +v -4.798998 -2.581476 0.000000 +v -1.444532 -0.241017 -0.000000 +v -2.355204 -2.987302 -0.000000 +v -4.222938 -1.236677 -0.362282 +v -1.998442 -1.582696 -0.362282 +v -1.998442 -1.582696 -0.000000 +v -4.222938 -1.236677 0.000000 +v -1.090580 0.101692 -0.362282 +v -3.733735 0.826496 -0.362282 +v -3.733735 0.826496 0.000000 +v -0.989683 0.383415 -0.000000 +v -0.989683 0.383415 -0.362282 +v -3.666064 1.591670 -0.362282 +v -3.666064 1.591670 0.000000 +v -4.440645 1.117349 -0.152840 +v -4.440645 1.117349 0.000000 +v -4.432783 1.324311 -0.152840 +v -4.432783 1.324311 0.000000 +v -4.009551 1.433071 -0.194895 +v -4.057285 1.076588 -0.194895 +v -4.057285 1.076588 0.000000 +v -4.009551 1.433071 0.000000 +v -3.851285 -0.381428 -0.362282 +v -1.754714 -0.911856 -0.362282 +v -1.754714 -0.911856 -0.000000 +v -3.851285 -0.381428 0.000000 +v -0.853143 1.770017 -0.000000 +v -0.859403 1.757498 -0.362282 +v -3.602237 1.769586 -0.362282 +v -3.602237 1.769586 0.000000 +v -1.058072 0.727078 -0.362282 +v -1.057932 0.728554 -0.000000 +v -0.741879 1.119604 -0.000000 +v -0.740764 1.124958 -0.362282 +v 0.562104 1.760490 -0.000000 +v 0.562104 1.760490 -0.355657 +v 0.748635 1.120156 -0.000000 +v 0.750571 1.125198 -0.355657 +v 2.815151 1.811499 -0.000000 +v 2.815151 1.811499 -0.352553 +v 2.828624 1.161572 -0.000000 +v 2.830560 1.166613 -0.352553 +v 1.224105 1.141108 -0.354105 +v 1.208697 1.785994 -0.354105 +v 1.208697 1.785994 -0.000000 +v 1.222168 1.136067 -0.000000 +v -3.543369 -0.238613 -0.617818 +v -3.315637 0.477518 -0.617818 +v -2.121719 -1.244479 -0.617818 +v -2.506988 -2.420609 -0.617818 +v -1.657910 -0.121041 -0.617818 +v -4.336923 -2.080794 -0.617818 +v -3.444937 0.772827 -0.617818 +v -3.854564 -0.954745 -0.617818 +v -1.917636 -0.682760 -0.617818 +v -1.361531 0.165922 -0.617818 +v -1.277047 0.401819 -0.617818 +v -3.388275 1.413535 -0.617818 +v -3.334830 1.656411 -0.617818 +v -3.675889 1.381268 -0.450506 +v -4.030276 1.341147 -0.277035 +v -4.036859 1.167850 -0.277035 +v -3.715859 1.082772 -0.450506 +v -1.038153 1.646288 -0.617818 +v 0.152128 1.648794 -0.612271 +v -1.334311 0.689580 -0.617818 +v -0.938811 1.345454 -0.617818 +v 0.165030 1.345655 -0.612271 +v 2.627126 1.691507 -0.609672 +v 2.640028 1.422055 -0.609671 +v 0.706445 1.400698 -0.610971 +v 0.693543 1.670150 -0.610971 +v -4.306217 -2.612876 -0.375104 +v -2.865759 -2.844352 -0.375104 +v -2.684457 -2.298832 -0.616215 +v -3.489256 -0.240016 -0.616215 +v -3.252746 0.435687 -0.616215 +v -2.277670 -1.189098 -0.616215 +v -1.937399 -0.129081 -0.616215 +v -4.238012 -2.043105 -0.616215 +v -3.158402 0.714326 -0.616215 +v -3.782884 -0.915720 -0.616215 +v -2.085108 -0.659090 -0.616215 +v -1.830828 0.141682 -0.616215 +v -1.816016 0.364262 -0.616215 +v -2.910229 1.318864 -0.616215 +v -2.773263 1.548029 -0.616215 +v -1.550943 1.430306 -0.616215 +v -1.686155 0.679047 -0.616215 +v -1.475239 1.254626 -0.616215 +v -2.095215 1.588775 -0.616215 +v -4.307481 -2.620646 -0.515038 +v -2.867024 -2.852122 -0.515038 +v -2.685722 -2.306602 -0.756148 +v -3.490521 -0.247786 -0.756149 +v -3.254010 0.427918 -0.756148 +v -2.278934 -1.196867 -0.756149 +v -1.938663 -0.136851 -0.756149 +v -4.239276 -2.050875 -0.756148 +v -3.159667 0.706556 -0.756148 +v -3.784149 -0.923490 -0.756148 +v -2.086372 -0.666860 -0.756149 +v -1.832092 0.133912 -0.756149 +v -1.817280 0.356493 -0.756149 +v -2.911492 1.311095 -0.756148 +v -2.774529 1.540260 -0.756149 +v -2.096479 1.581006 -0.756149 +v -1.687420 0.671278 -0.756149 +v -1.476503 1.246857 -0.756149 +v -1.552208 1.422536 -0.756149 +v -4.620386 -2.757102 0.000000 +v -4.620386 -2.757102 -0.362281 +v -2.583257 -3.109388 -0.362281 +v -2.583257 -3.109388 -0.000000 +v 0.169829 1.125104 -0.358237 +v 0.145055 1.119932 -0.000000 +v 0.639359 0.808476 -0.360184 +v 0.638893 0.803435 -0.000000 +v 0.499530 0.808383 -0.362764 +v 0.493565 0.803211 -0.000000 +v 0.620819 0.367841 -0.366194 +v 0.619093 0.363091 -0.000000 +v 0.519641 0.396732 -0.368774 +v 0.513901 0.392996 -0.000000 +v 0.433727 0.092503 -0.369846 +v 0.430041 0.089046 -0.000000 +v 0.356526 0.163999 -0.372426 +v 0.349717 0.163261 -0.000000 +v 0.224690 -0.043395 -0.373404 +v 0.219638 -0.043539 -0.000000 +v 0.214296 0.061313 -0.375984 +v 0.208710 0.065274 -0.000000 +v -0.070517 -0.072659 -0.377330 +v -0.075531 -0.072016 -0.000000 +v -0.064521 0.032393 -0.379910 +v -0.069425 0.037174 -0.000000 +v -0.639295 -0.082211 -0.385008 +v -0.644308 -0.081382 -0.000000 +v -0.633298 0.053320 -0.387588 +v -0.638202 0.059489 -0.000000 +v -1.228139 -0.031497 -0.362282 +v -1.229475 -0.032792 -0.000000 +v -4.474338 -2.782359 0.000000 +v -4.474338 -2.782359 0.281679 +v -2.729304 -3.084132 0.281679 +v -2.729304 -3.084132 -0.000000 +v -4.474338 -2.782359 -0.281679 +v -2.729304 -3.084132 -0.281679 +v -3.387533 0.343164 0.000000 +v -3.387533 0.343164 0.281679 +v -1.642499 0.041391 0.281679 +v -1.642499 0.041391 -0.000000 +v -3.387534 0.343164 -0.281679 +v -1.642499 0.041391 -0.281679 +v -2.668813 2.417684 -0.257792 +v 4.936440 2.417684 -0.257792 +v -2.668813 2.251978 -0.197480 +v 4.936440 2.251979 -0.197480 +v -2.668813 2.163808 -0.044765 +v 4.936440 2.163809 -0.044765 +v -2.668813 2.194429 0.128896 +v 4.936440 2.194430 0.128896 +v -2.668813 2.329514 0.242246 +v 4.936440 2.329514 0.242245 +v -2.668813 2.505854 0.242246 +v 4.936440 2.505854 0.242245 +v -2.668813 2.640938 0.128896 +v 4.936440 2.640939 0.128896 +v -2.668813 2.671559 -0.044765 +v 4.936440 2.671560 -0.044765 +v -2.668813 2.583389 -0.197480 +v 4.936440 2.583390 -0.197480 +v 4.936440 2.291502 -0.150378 +v 4.936440 2.417684 -0.196304 +v 4.936440 2.224363 -0.034088 +v 4.936440 2.247680 0.098152 +v 4.936440 2.350544 0.184465 +v 4.936440 2.484824 0.184465 +v 4.936440 2.587688 0.098152 +v 4.936440 2.611006 -0.034088 +v 4.936440 2.543866 -0.150378 +v -2.218233 2.291501 -0.150377 +v -2.218233 2.417683 -0.196303 +v -2.218233 2.224361 -0.034087 +v -2.218233 2.247679 0.098153 +v -2.218233 2.350543 0.184466 +v -2.218233 2.484823 0.184466 +v -2.218233 2.587687 0.098153 +v -2.218233 2.611004 -0.034087 +v -2.218233 2.543864 -0.150377 +v -1.125007 0.027445 0.182643 +v -1.168617 1.161458 0.182643 +v -1.125007 0.027445 -0.195360 +v -1.168618 1.161458 -0.195360 +v -0.414642 0.027445 0.182643 +v -0.458253 1.160420 0.182643 +v -0.414642 0.027445 -0.195360 +v -0.458253 1.160420 -0.195360 +v -1.133708 0.279795 0.182643 +v -1.133708 0.279795 -0.195360 +v -0.535486 0.279795 -0.195360 +v -0.535486 0.279795 0.182643 +v -1.160284 0.919772 0.182643 +v -1.160284 0.919772 -0.195360 +v -0.562061 0.919772 -0.195360 +v -0.562062 0.919772 0.182643 +v -1.146996 0.665200 -0.195360 +v -0.654685 0.665200 -0.195360 +v -0.654685 0.665200 0.182643 +v -1.146996 0.665200 0.182643 +v -1.140352 0.472497 -0.195360 +v -0.638696 0.472497 -0.195360 +v -0.638696 0.472497 0.182643 +v -1.140352 0.472497 0.182643 +v -2.531889 2.825947 0.456793 +v 2.822297 2.844821 0.456793 +v 2.822297 2.844821 -0.000000 +v -2.528444 2.825947 -0.000000 +v -2.628881 2.937348 -0.000000 +v -1.492258 2.714040 0.621866 +v 3.111325 2.847408 0.456793 +v 3.111325 2.847408 -0.000000 +v -2.531889 2.825947 -0.456793 +v 2.822297 2.844821 -0.456793 +v -2.631343 2.937348 0.377462 +v -1.608355 2.713631 0.621866 +v -1.492258 2.707172 0.631675 +v 3.111325 2.847408 -0.456793 +v 2.738271 2.691841 0.667700 +v 3.472527 2.850611 0.456793 +v 3.472527 2.850611 -0.000000 +v -1.492258 2.714040 -0.621866 +v -3.259650 2.825947 0.456793 +v -3.151402 2.937348 0.377462 +v -2.749896 2.937348 0.113256 +v -2.751221 2.937348 0.175914 +v -2.631343 2.937348 -0.377462 +v -1.608354 1.829214 0.621866 +v -1.492258 1.829460 0.621866 +v -1.892259 2.712630 0.621866 +v -1.492258 1.931250 0.667700 +v -1.492258 2.550798 0.667700 +v -1.492258 2.681078 0.667700 +v 3.472527 2.850611 -0.456793 +v 2.738271 2.691841 -0.667700 +v 3.014620 2.693627 0.667700 +v 4.053590 2.855762 0.456793 +v 4.053590 2.855762 0.046751 +v 4.053590 2.855762 -0.000000 +v -1.492258 2.707172 -0.631675 +v -1.608354 2.713631 -0.621866 +v -3.259650 2.825947 -0.000000 +v -3.151402 2.937348 -0.000000 +v -2.808354 2.710791 0.621866 +v -3.030956 2.937348 0.175914 +v -3.030956 2.937348 0.113256 +v -2.749896 3.009885 0.113256 +v -2.751221 3.009885 0.175914 +v -3.259650 2.825947 -0.456793 +v -3.151402 2.937348 -0.377462 +v -2.751221 2.937348 -0.175915 +v -2.749896 2.937348 -0.113256 +v -1.608355 2.703468 0.636381 +v -1.608355 2.680783 0.667700 +v -1.608355 2.567521 0.667700 +v -1.608354 1.931004 0.667700 +v -1.892259 1.828612 0.621866 +v -1.692259 2.713335 0.621866 +v -2.292259 2.711220 0.621866 +v -0.651391 1.736751 0.579318 +v 2.746555 1.940238 0.667700 +v 4.053590 2.855762 -0.046751 +v 4.053590 2.855762 -0.456793 +v 3.014620 2.693627 -0.667700 +v -1.492258 2.681078 -0.667700 +v 3.022904 1.942023 0.667700 +v 3.359975 2.695836 0.667700 +v 4.631854 2.860802 0.456793 +v 4.631854 2.860802 0.047130 +v 4.196826 3.002388 0.046751 +v 4.196826 3.002388 -0.000000 +v -1.492258 1.829460 -0.621866 +v -1.492258 2.550798 -0.667700 +v -1.492258 1.931250 -0.667700 +v -1.608355 1.829214 -0.621866 +v -1.892259 2.712630 -0.621866 +v -2.608355 2.710791 0.621866 +v -3.076865 2.678817 0.667700 +v -3.030956 3.070570 0.175914 +v -3.030956 2.937348 -0.113256 +v -3.030956 3.070570 0.113256 +v -2.808354 2.710791 -0.621866 +v -3.030956 2.937348 -0.175915 +v -2.751221 3.009885 -0.175915 +v -2.749896 3.009885 -0.113256 +v -1.692259 2.700791 0.639782 +v -1.692259 2.680570 0.667700 +v -1.692259 2.579606 0.667700 +v -1.692259 1.930826 0.667700 +v -1.808354 1.828790 0.621866 +v -1.808354 2.712925 0.621866 +v -2.092258 2.711925 0.621866 +v -2.408354 2.710810 0.621866 +v 0.722717 1.736751 0.579318 +v 4.196826 3.002388 -0.046751 +v 4.631854 2.860802 -0.047130 +v 4.631854 2.860802 -0.456793 +v 3.359975 2.695836 -0.667700 +v 3.022904 1.942023 -0.667700 +v 2.746554 1.940238 -0.667700 +v 2.830961 1.755625 0.579318 +v 3.368259 2.089247 0.667700 +v 3.915548 2.699391 0.667700 +v 4.820063 2.775364 0.456793 +v 4.820063 2.775364 0.021671 +v 4.454093 2.983511 0.047130 +v 4.454093 2.983511 -0.000000 +v -0.651391 1.736751 -0.579318 +v -1.892259 1.828612 -0.621866 +v -1.608355 1.931004 -0.667700 +v -1.608354 2.567521 -0.667700 +v -1.608354 2.680783 -0.667700 +v -1.608354 2.703468 -0.636381 +v -1.692258 2.713335 -0.621866 +v -2.292258 2.711220 -0.621866 +v -3.613609 2.383409 0.465826 +v -3.516194 2.524010 -0.000000 +v -3.516194 2.524010 0.000079 +v -3.516194 2.524010 0.149714 +v -3.615434 2.399936 0.145756 +v -3.620815 2.393209 0.145451 +v -2.692258 2.710791 0.621866 +v -2.492259 2.710791 0.621866 +v -2.808354 2.678817 0.667700 +v -3.382849 2.373442 0.675347 +v -3.030956 3.070570 -0.113256 +v -2.608355 2.710791 -0.621866 +v -3.076864 2.678817 -0.667700 +v -3.030956 3.070570 -0.175915 +v -1.692259 1.829036 0.621866 +v -1.972652 1.828442 0.621866 +v -1.892259 1.930402 0.667700 +v -1.808354 2.697088 0.644487 +v -2.208354 2.711515 0.621866 +v -2.008355 2.712220 0.621866 +v -2.408354 2.705466 0.629499 +v -2.408355 1.828442 0.621866 +v -2.292258 1.828442 0.621866 +v -0.651077 1.631627 0.350908 +v 0.723031 1.631627 0.350908 +v 4.454093 2.983511 -0.047131 +v 4.820063 2.775364 -0.021671 +v 4.820063 2.775364 -0.456793 +v 3.915547 2.699391 -0.667700 +v 3.368259 2.089247 -0.667700 +v 2.830961 1.755625 -0.579318 +v 3.119990 1.758212 0.456793 +v 3.923832 2.092802 0.667700 +v 4.511218 2.910254 0.047130 +v 4.468442 2.702869 0.667700 +v 4.631854 2.860802 -0.000000 +v 4.820063 2.775364 -0.000000 +v 4.640518 1.981755 0.456793 +v 4.828727 2.115226 0.456793 +v 4.823622 2.504166 0.237607 +v 0.722717 1.736751 -0.579318 +v -1.808354 1.828790 -0.621866 +v -1.692259 1.930826 -0.667700 +v -1.692258 2.579606 -0.667700 +v -1.692258 2.680570 -0.667700 +v -1.692258 2.700791 -0.639782 +v -1.808354 2.712925 -0.621866 +v -2.092258 2.711925 -0.621866 +v -2.408354 2.710810 -0.621866 +v -3.613609 2.383409 -0.465826 +v -3.620815 2.393209 -0.138530 +v -3.615434 2.399936 -0.138835 +v -3.516194 2.524010 -0.149556 +v -3.602321 2.022458 0.465826 +v -3.614557 2.193099 0.135677 +v -3.614557 2.193099 0.003461 +v -3.614557 2.193099 -0.000000 +v -2.808355 1.828442 0.621866 +v -2.692258 1.828442 0.621866 +v -2.608355 2.678817 0.667700 +v -2.608355 1.828442 0.621866 +v -2.492258 1.828442 0.621866 +v -2.808354 2.362363 0.667700 +v -2.808354 1.928460 0.667700 +v -2.808354 1.886436 0.648777 +v -2.692258 2.710791 -0.621866 +v -2.492258 2.710791 -0.621866 +v -2.808354 2.678817 -0.667700 +v -3.382848 2.373442 -0.675347 +v -2.008354 1.828442 0.621866 +v -3.593386 1.736751 0.579318 +v -1.808354 1.930580 0.667700 +v -1.892259 2.608414 0.667700 +v -1.892259 2.680061 0.667700 +v -1.892259 2.694411 0.647888 +v -1.808354 2.680274 0.667700 +v -1.808354 2.596329 0.667700 +v -2.208354 1.828442 0.621866 +v -2.092258 1.828442 0.621866 +v -2.208354 2.684326 0.660701 +v -2.008355 2.690707 0.652594 +v -2.408354 2.678817 0.667700 +v -2.408354 2.658582 0.667700 +v -2.408355 1.929308 0.667700 +v -2.408355 1.858678 0.635897 +v -2.292258 1.850621 0.632158 +v -2.292258 1.929554 0.667700 +v -2.292259 2.666030 0.667700 +v -2.292259 2.679043 0.667700 +v -2.292259 2.681649 0.664101 +v 2.843441 1.646936 0.348132 +v -3.453837 1.631627 0.350908 +v -0.651077 1.631627 -0.000000 +v 0.723031 1.631627 -0.000000 +v 4.511218 2.910254 -0.047130 +v 4.822625 2.580217 -0.193699 +v 4.828727 2.115226 -0.456793 +v 4.640518 1.981755 -0.456793 +v 4.468442 2.702869 -0.667700 +v 3.923832 2.092802 -0.667700 +v 3.119990 1.758212 -0.456793 +v 2.843784 1.695861 0.348132 +v 3.481191 1.971564 0.456793 +v 4.476727 2.096280 0.667700 +v 4.499004 2.917927 -0.000000 +v 4.821591 2.658957 -0.000000 +v 4.640518 1.981755 -0.000000 +v 4.828727 2.115226 -0.000000 +v 4.821884 2.636664 0.126428 +v -1.972652 1.828442 -0.621866 +v 0.723031 1.631627 -0.350908 +v -0.651077 1.631627 -0.350908 +v -1.692259 1.829036 -0.621866 +v -1.892259 1.930402 -0.667700 +v -1.808354 2.697088 -0.644488 +v -2.008354 2.712220 -0.621866 +v -2.208354 2.711515 -0.621866 +v -2.292259 1.828442 -0.621866 +v -2.408354 1.828442 -0.621866 +v -2.408354 2.705466 -0.629499 +v -3.602320 2.022458 -0.465826 +v -3.614557 2.193099 -0.128755 +v -3.602320 2.022458 -0.000000 +v -2.692258 1.878380 0.645039 +v -2.692258 1.928706 0.667700 +v -2.692258 2.448338 0.667700 +v -2.692258 2.678817 0.667700 +v -2.608355 2.510473 0.667700 +v -2.608355 1.928884 0.667700 +v -2.608355 1.872557 0.642337 +v -2.492258 1.864500 0.638598 +v -2.492258 1.929130 0.667700 +v -2.492259 2.596447 0.667700 +v -2.492259 2.678817 0.667700 +v -3.395959 1.927214 0.667700 +v -2.608355 2.678817 -0.667700 +v -2.692258 1.828442 -0.621866 +v -2.808354 1.828442 -0.621866 +v -2.492259 1.828442 -0.621866 +v -2.608355 1.828442 -0.621866 +v -2.808354 1.886436 -0.648778 +v -2.808354 1.928460 -0.667700 +v -2.808354 2.362363 -0.667700 +v -2.008355 2.679765 0.667700 +v -2.008355 2.625137 0.667700 +v -2.008354 1.930156 0.667700 +v -2.008354 1.830919 0.623016 +v -2.092258 1.836742 0.625717 +v -2.092258 1.929978 0.667700 +v -2.092258 2.637222 0.667700 +v -2.092258 2.679552 0.667700 +v -2.092258 2.688030 0.655995 +v -2.208354 2.679256 0.667700 +v -2.208354 2.653945 0.667700 +v -2.208354 1.929732 0.667700 +v -2.208354 1.844798 0.629456 +v 2.844154 1.646936 -0.000000 +v -3.593386 1.736751 -0.000000 +v -3.453837 1.631627 -0.000000 +v 4.821490 2.666699 -0.043908 +v 4.824758 2.417684 -0.252857 +v 4.476727 2.096280 -0.667700 +v 3.481191 1.971564 -0.456793 +v 2.843784 1.695861 -0.348132 +v 2.843441 1.646936 -0.348132 +v 3.132812 1.698448 0.348132 +v 3.494013 1.911800 0.348132 +v 4.062254 1.976715 0.456793 +v 4.653340 1.921991 0.348132 +v 4.653340 1.921991 -0.000000 +v 4.827631 2.198704 0.126428 +v 4.825893 2.331202 0.237607 +v -3.593385 1.736751 -0.579318 +v -2.008355 1.828442 -0.621866 +v -3.453837 1.631627 -0.350908 +v -1.892259 2.694411 -0.647888 +v -1.892259 2.680061 -0.667700 +v -1.892259 2.608414 -0.667700 +v -1.808354 1.930580 -0.667700 +v -1.808354 2.596329 -0.667700 +v -1.808354 2.680274 -0.667700 +v -2.008354 2.690707 -0.652594 +v -2.092258 1.828442 -0.621866 +v -2.208354 1.828442 -0.621866 +v -2.208354 2.684326 -0.660701 +v -2.292258 2.681649 -0.664102 +v -2.292258 2.679043 -0.667700 +v -2.292258 2.666030 -0.667700 +v -2.292259 1.929554 -0.667700 +v -2.292259 1.850621 -0.632158 +v -2.408354 1.858678 -0.635897 +v -2.408354 1.929308 -0.667700 +v -2.408354 2.658582 -0.667700 +v -2.408354 2.678817 -0.667700 +v -2.608355 1.872557 -0.642337 +v -2.608355 1.928884 -0.667700 +v -2.608355 2.510473 -0.667700 +v -2.692258 2.678817 -0.667700 +v -2.692258 2.448338 -0.667700 +v -2.692258 1.928706 -0.667700 +v -2.692258 1.878380 -0.645039 +v -2.492258 2.678817 -0.667700 +v -2.492258 2.596447 -0.667700 +v -2.492259 1.929130 -0.667700 +v -2.492259 1.864500 -0.638599 +v -3.395959 1.927214 -0.667700 +v 2.816410 1.629348 0.329700 +v 3.139605 1.649524 0.348132 +v 4.826892 2.255151 -0.193700 +v 4.653340 1.921991 -0.348132 +v 4.062254 1.976715 -0.456793 +v 3.494013 1.911800 -0.348132 +v 3.132812 1.698448 -0.348132 +v 4.075078 1.916951 0.348132 +v 3.500805 1.808020 0.348132 +v 4.658651 1.818212 0.348132 +v 4.658650 1.818212 -0.000000 +v 4.827924 2.176411 -0.000000 +v -2.008355 1.830919 -0.623016 +v -2.008355 1.930156 -0.667700 +v -2.008354 2.625137 -0.667700 +v -2.008354 2.679765 -0.667700 +v -2.092258 2.688030 -0.655995 +v -2.092258 2.679552 -0.667700 +v -2.092258 2.637222 -0.667700 +v -2.092258 1.929978 -0.667700 +v -2.092258 1.836742 -0.625718 +v -2.208354 1.844798 -0.629456 +v -2.208354 1.929732 -0.667700 +v -2.208354 2.653945 -0.667700 +v -2.208354 2.679256 -0.667700 +v 2.816409 1.629348 -0.329700 +v 2.817062 1.629348 -0.000000 +v 2.842529 1.516570 0.348132 +v 2.815575 1.510141 0.329700 +v 3.157703 1.519158 0.348132 +v 4.658650 1.818212 -0.348132 +v 4.075078 1.916951 -0.348132 +v 4.828027 2.168669 -0.043908 +v 3.500805 1.808020 -0.348132 +v 3.139604 1.649524 -0.348132 +v 4.081870 1.813172 0.348132 +v 3.518905 1.531486 0.348132 +v 4.672799 1.541678 0.348132 +v 4.672798 1.541678 -0.000000 +v 2.842529 1.516570 -0.348132 +v 2.815575 1.510141 -0.329700 +v 2.845095 1.413342 0.277502 +v 2.817922 1.415750 0.265116 +v 3.172035 1.415930 0.277502 +v 4.672798 1.541678 -0.348132 +v 4.081870 1.813172 -0.348132 +v 3.518904 1.531486 -0.348132 +v 3.157703 1.519158 -0.348132 +v 4.099969 1.536638 0.348132 +v 3.533236 1.428259 0.277502 +v 4.675811 1.438450 0.277502 +v 4.675811 1.438450 -0.000000 +v 2.845095 1.413342 -0.277502 +v 2.817921 1.415750 -0.265117 +v 2.817966 1.510141 -0.000000 +v 2.844241 1.210146 0.141676 +v 2.817140 1.229947 0.140917 +v 4.675811 1.438450 -0.277502 +v 4.099969 1.536638 -0.348132 +v 3.533236 1.428259 -0.277502 +v 3.172035 1.415930 -0.277502 +v 4.114299 1.433410 0.277502 +v 3.180332 1.212734 0.141676 +v 3.541533 1.225062 0.141676 +v 4.642606 1.261664 0.141676 +v 4.642606 1.261664 -0.000000 +v 2.844241 1.210146 -0.141676 +v 2.817140 1.229947 -0.140917 +v 2.844241 1.210146 -0.000000 +v 2.817140 1.229947 -0.000000 +v 2.817922 1.415750 -0.000000 +v 4.642606 1.261664 -0.141676 +v 4.114299 1.433410 -0.277502 +v 3.541533 1.225062 -0.141676 +v 3.180332 1.212734 -0.141676 +v 4.122596 1.230214 0.141676 +v 3.180332 1.212734 -0.000000 +v 3.541533 1.225062 -0.000000 +v 4.122596 1.230214 -0.000000 +v 4.122596 1.230214 -0.141676 +v 2.830961 1.755625 0.579318 +v 2.843784 1.695861 0.348132 +v 2.840755 1.755625 0.349334 +v 2.830961 1.755625 -0.000000 +v 2.843784 1.695861 -0.000000 +v 2.843441 1.646936 0.348132 +v 2.843783 1.695861 -0.348132 +v 2.844154 1.646936 -0.000000 +v 2.843441 1.646936 -0.348132 +v 2.840755 1.755625 -0.349334 +v 2.830961 1.755625 -0.579318 +v -3.620133 2.550195 0.153096 +v -3.620133 2.550195 0.003461 +v -3.916551 2.623163 0.003461 +v -3.916551 2.623163 0.153096 +v -3.905262 2.389306 0.146458 +v -3.620133 2.550195 -0.146174 +v -3.916551 2.623163 -0.146174 +v -4.065006 2.593568 0.003461 +v -4.065006 2.593568 0.153096 +v -4.083622 2.479330 0.153096 +v -3.905262 2.389306 -0.139536 +v -4.065006 2.593568 -0.146174 +v -4.083622 2.479330 0.003461 +v -3.905262 2.389306 0.003461 +v -4.083622 2.479330 -0.146174 +vn 0.000000 -0.342000 -0.939700 +vn 0.000000 -0.866000 -0.500000 +vn 0.000000 -0.984800 0.173600 +vn 0.000000 -0.642800 0.766000 +vn 0.000000 0.000000 1.000000 +vn -0.000000 0.642800 0.766000 +vn -0.000000 0.984800 0.173600 +vn 1.000000 -0.000000 0.000000 +vn -0.000000 0.342000 -0.939700 +vn -0.000000 0.866000 -0.500000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 -0.000000 -1.000000 +vn -0.000000 0.866000 0.500000 +vn 0.000000 -0.342000 0.939700 +vn 0.000000 -0.642800 -0.766000 +vn -0.000000 0.984800 -0.173600 +vn 0.000000 -0.984800 -0.173600 +vn -0.000000 0.642800 -0.766000 +vn 0.000000 0.342000 0.939700 +vn 0.000000 -0.866000 0.500000 +vn -0.000000 1.000000 0.000000 +vn -0.170400 -0.985400 0.000000 +vn -0.980600 0.196100 0.000000 +vn 0.964600 -0.263800 -0.000000 +vn -0.949700 0.313200 0.000000 +vn 0.186300 0.982400 -0.016600 +vn -0.144800 -0.989500 0.000000 +vn 0.186300 0.982400 0.016600 +vn 0.947000 -0.321300 0.000000 +vn 0.969200 -0.246200 0.000000 +vn -0.295200 0.011200 0.955400 +vn -0.916000 -0.401100 0.000000 +vn -0.701100 -0.713000 0.000000 +vn -0.919200 0.393800 0.000000 +vn -0.917100 0.398600 0.000000 +vn -0.008100 0.002800 1.000000 +vn 0.939900 -0.341500 0.000000 +vn -0.105700 -0.994400 0.000000 +vn -0.686400 0.294000 0.665100 +vn 0.980900 0.194600 0.000600 +vn 0.003200 -0.755400 0.655300 +vn -0.999300 0.038000 0.000000 +vn -0.624900 -0.214800 0.750600 +vn -0.248900 0.968500 0.000000 +vn -0.419200 0.907900 0.000000 +vn -0.036100 0.936100 0.349800 +vn -0.611600 -0.791200 0.000000 +vn 0.907700 -0.419700 -0.000000 +vn 0.656400 -0.303500 0.690600 +vn -0.953000 0.303000 0.000000 +vn 0.002100 0.999800 0.017300 +vn 0.004000 0.915900 0.401400 +vn -0.941300 0.337700 0.000000 +vn 0.779800 -0.626000 0.002300 +vn 0.002300 0.999800 0.017500 +vn 0.677400 -0.194800 0.709400 +vn -0.519400 0.351000 0.779200 +vn 0.000300 -0.999900 0.014600 +vn 0.999700 0.022300 -0.002900 +vn -0.015900 0.999900 0.000000 +vn 0.015900 -0.999800 0.014200 +vn 0.033600 -0.999300 0.014000 +vn -0.039400 0.999200 -0.000000 +vn 0.009800 -0.699500 0.714500 +vn -0.000500 -0.012900 0.999900 +vn -0.139400 -0.400700 0.905600 +vn 0.024400 -0.008100 0.999700 +vn -0.003200 0.000700 1.000000 +vn -0.454100 0.044800 0.889800 +vn -0.494500 0.050900 0.867700 +vn -0.007100 0.002600 1.000000 +vn -0.009100 0.003300 1.000000 +vn 0.000700 0.000000 1.000000 +vn 0.004800 0.000900 1.000000 +vn 0.002400 0.000100 1.000000 +vn 0.696700 -0.253100 0.671200 +vn -0.622600 0.173500 0.763100 +vn -0.000100 0.916900 0.399000 +vn 0.049200 -0.674600 0.736500 +vn 0.663400 0.132000 0.736500 +vn -0.681000 0.216600 0.699500 +vn -0.330800 -0.589300 0.737000 +vn -0.314600 0.670900 0.671500 +vn -0.011800 0.914800 0.403600 +vn -0.663800 -0.290600 0.689100 +vn 0.808200 0.025000 0.588400 +vn 0.594700 -0.402300 0.696000 +vn 0.638700 -0.228700 0.734700 +vn -0.687700 0.298800 0.661600 +vn -0.004400 0.003200 1.000000 +vn -0.003600 0.000400 1.000000 +vn 0.002900 -0.001200 1.000000 +vn -0.003800 0.001900 1.000000 +vn 0.009300 0.000600 1.000000 +vn 0.004000 -0.001000 1.000000 +vn -0.002800 -0.001000 1.000000 +vn -0.012800 -0.415600 0.909500 +vn 0.023100 -0.009600 0.999700 +vn 0.029300 -0.012700 0.999500 +vn -0.037700 -0.229600 0.972600 +vn 0.472000 -0.881600 0.000000 +vn -0.682200 -0.730100 0.039600 +vn -0.998700 -0.049000 0.016600 +vn 0.007200 0.016800 0.999800 +vn 0.944200 -0.329300 0.001500 +vn 0.825100 -0.564900 0.000200 +vn 0.023100 0.014100 0.999600 +vn 0.999100 -0.043500 -0.002400 +vn 0.539100 -0.842200 -0.002300 +vn -0.816200 0.577700 0.010300 +vn 0.026700 -0.004000 0.999600 +vn -0.101700 0.994700 0.012900 +vn -0.577900 0.816000 0.013100 +vn 0.030000 -0.014400 0.999400 +vn 0.013300 -0.022100 0.999700 +vn 0.016100 -0.024200 0.999600 +vn 0.097300 -0.995300 -0.002000 +vn 0.016600 -0.999900 -0.002100 +vn 0.038100 0.999200 0.013800 +vn 0.678600 0.734500 0.001600 +vn -0.084300 -0.996400 0.001300 +vn 0.695600 -0.718400 0.000000 +vn 0.512400 -0.529200 0.676300 +vn -0.048700 0.016500 0.998700 +vn -0.295200 0.011200 -0.955400 +vn -0.008100 0.002800 -1.000000 +vn -0.686400 0.294000 -0.665100 +vn 0.980900 0.194600 -0.000600 +vn 0.003200 -0.755400 -0.655300 +vn -0.624900 -0.214800 -0.750600 +vn -0.036100 0.936100 -0.349800 +vn 0.656400 -0.303500 -0.690600 +vn 0.002100 0.999800 -0.017300 +vn 0.004000 0.915900 -0.401400 +vn 0.779800 -0.626000 -0.002300 +vn 0.002300 0.999800 -0.017500 +vn 0.677400 -0.194800 -0.709400 +vn -0.519400 0.351000 -0.779200 +vn 0.000300 -0.999900 -0.014600 +vn 0.999700 0.022300 0.002900 +vn 0.015900 -0.999800 -0.014200 +vn 0.033600 -0.999300 -0.014000 +vn 0.009800 -0.699500 -0.714500 +vn -0.000500 -0.012900 -0.999900 +vn -0.139400 -0.400700 -0.905600 +vn 0.024400 -0.008100 -0.999700 +vn -0.003200 0.000700 -1.000000 +vn -0.454100 0.044800 -0.889800 +vn -0.494500 0.050900 -0.867700 +vn -0.007100 0.002600 -1.000000 +vn -0.009100 0.003300 -1.000000 +vn 0.000700 0.000000 -1.000000 +vn 0.004800 0.000900 -1.000000 +vn 0.002400 0.000100 -1.000000 +vn 0.696700 -0.253100 -0.671200 +vn -0.622600 0.173500 -0.763100 +vn -0.000100 0.916900 -0.399000 +vn 0.049200 -0.674600 -0.736500 +vn 0.663400 0.132000 -0.736500 +vn -0.681000 0.216600 -0.699500 +vn -0.330800 -0.589300 -0.737000 +vn -0.314600 0.670900 -0.671500 +vn -0.011800 0.914800 -0.403600 +vn -0.663800 -0.290600 -0.689100 +vn 0.808200 0.025000 -0.588400 +vn 0.594800 -0.402300 -0.696000 +vn 0.638700 -0.228700 -0.734700 +vn -0.687700 0.298800 -0.661600 +vn -0.004400 0.003200 -1.000000 +vn -0.003600 0.000400 -1.000000 +vn 0.002900 -0.001200 -1.000000 +vn -0.003800 0.001900 -1.000000 +vn 0.009300 0.000600 -1.000000 +vn 0.004000 -0.001000 -1.000000 +vn -0.002800 -0.001000 -1.000000 +vn -0.012800 -0.415600 -0.909500 +vn 0.023100 -0.009600 -0.999700 +vn 0.029300 -0.012700 -0.999500 +vn -0.037700 -0.229600 -0.972600 +vn -0.682200 -0.730100 -0.039600 +vn -0.998700 -0.049000 -0.016600 +vn 0.007200 0.016800 -0.999800 +vn 0.944200 -0.329300 -0.001500 +vn 0.825100 -0.564900 -0.000200 +vn 0.023100 0.014100 -0.999600 +vn 0.999100 -0.043500 0.002400 +vn 0.539100 -0.842200 0.002300 +vn -0.816200 0.577700 -0.010300 +vn 0.026700 -0.004000 -0.999600 +vn -0.101700 0.994700 -0.012900 +vn -0.577900 0.816000 -0.013100 +vn 0.030000 -0.014400 -0.999400 +vn 0.013300 -0.022100 -0.999700 +vn 0.016100 -0.024200 -0.999600 +vn 0.097300 -0.995300 0.002000 +vn 0.016600 -0.999900 0.002100 +vn 0.038100 0.999200 -0.013800 +vn 0.678600 0.734500 -0.001600 +vn -0.084300 -0.996400 -0.001300 +vn 0.512400 -0.529200 -0.676300 +vn -0.048700 0.016500 -0.998700 +vn -0.944500 0.328400 0.000000 +vn 0.944500 -0.328400 -0.000000 +vn -0.158400 -0.985800 -0.056200 +vn 0.917900 0.395600 0.030300 +vn -0.927200 0.374300 0.012400 +vn -0.925000 0.379700 0.012700 +vn 0.279100 0.958600 0.055700 +vn 0.938900 -0.344000 -0.010600 +vn -0.947100 0.320700 0.009200 +vn -0.062500 -0.384300 0.921100 +vn 0.997800 -0.066400 0.005300 +vn 0.939800 -0.341500 -0.010500 +vn -0.992800 0.119800 -0.002300 +vn 0.950100 -0.311900 -0.008700 +vn -0.917100 0.398500 0.013800 +vn -0.943800 0.330400 0.009800 +vn 0.963300 -0.268500 -0.006200 +vn 0.938900 -0.344100 -0.010600 +vn 0.930500 -0.366200 -0.011900 +vn -0.059900 0.996700 0.054800 +vn 0.924300 -0.381300 -0.012800 +vn -0.858200 0.512900 0.020700 +vn -0.158400 -0.985800 0.056200 +vn 0.917900 0.395600 -0.030300 +vn -0.927200 0.374300 -0.012400 +vn -0.925000 0.379700 -0.012700 +vn 0.279100 0.958600 -0.055700 +vn 0.938900 -0.344000 0.010600 +vn -0.947100 0.320700 -0.009200 +vn -0.062500 -0.384300 -0.921100 +vn 0.997800 -0.066400 -0.005300 +vn 0.939800 -0.341500 0.010500 +vn -0.992800 0.119800 0.002300 +vn 0.950100 -0.311900 0.008700 +vn -0.917100 0.398500 -0.013800 +vn -0.943800 0.330400 -0.009800 +vn 0.963300 -0.268500 0.006200 +vn 0.938900 -0.344100 0.010600 +vn 0.930500 -0.366200 0.011900 +vn -0.059900 0.996700 -0.054800 +vn 0.924400 -0.381300 0.012800 +vn -0.858200 0.512900 -0.020700 +vn -0.999400 -0.034500 0.000000 +vn 0.901900 0.431900 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.001500 1.000000 -0.000000 +vn 0.881500 0.472100 0.000000 +vn 0.918200 -0.396100 0.000000 +vn -0.998600 -0.052100 0.000000 +vn 0.939700 -0.341900 0.000000 +vn 0.996600 0.082700 0.000000 +vn -0.003500 1.000000 -0.000000 +vn 0.743400 0.668800 0.005300 +vn -0.002900 0.819200 0.573500 +vn -0.009000 1.000000 0.000000 +vn 0.743400 0.668800 -0.005300 +vn -0.006300 0.810000 0.586400 +vn -0.008900 1.000000 0.000000 +vn -0.000000 0.580100 0.814600 +vn -0.002100 0.809900 0.586600 +vn -0.006300 0.810000 -0.586400 +vn -0.006200 0.808600 0.588400 +vn -0.717200 0.696900 0.000000 +vn 0.999800 0.000000 0.021100 +vn -0.000000 0.580100 -0.814600 +vn -0.006200 0.808600 -0.588400 +vn -0.002100 0.809900 -0.586600 +vn -0.006200 0.806500 0.591200 +vn -0.008700 1.000000 0.000000 +vn -0.715300 0.698800 0.000000 +vn -0.771200 0.636300 0.018300 +vn 0.211500 0.977400 0.002200 +vn 0.999800 0.000000 -0.021100 +vn 0.413400 0.910600 0.000000 +vn 0.073200 0.997300 0.000000 +vn 0.000000 0.820200 -0.572100 +vn 0.211500 0.977400 -0.002200 +vn 0.000000 -0.908400 0.418100 +vn 0.001400 -0.413300 0.910600 +vn -0.001000 -0.000100 -1.000000 +vn -0.006100 0.803900 -0.594700 +vn -0.006200 0.806500 -0.591200 +vn 0.178800 -0.565800 -0.804900 +vn 0.178800 -0.565800 0.804900 +vn 0.344100 -0.674300 0.653300 +vn -0.001000 -0.000100 1.000000 +vn -0.006100 0.803900 0.594700 +vn 0.999900 0.013100 0.000000 +vn 0.804500 0.591300 -0.056100 +vn 0.001400 -0.413300 -0.910600 +vn -0.771300 0.636200 -0.018200 +vn -0.998900 -0.046000 0.013500 +vn -0.528100 0.481600 0.699400 +vn 0.000000 0.820200 0.572100 +vn 0.011000 -0.004700 0.999900 +vn -0.528100 0.481600 -0.699400 +vn 0.007600 -0.906600 0.422000 +vn 0.387500 0.921600 0.024800 +vn 0.578500 -0.815700 0.000000 +vn 0.000000 -0.908400 -0.418100 +vn -0.998900 -0.045700 -0.013400 +vn 0.000900 -0.410600 0.911800 +vn 0.007200 -1.000000 0.000000 +vn -0.601700 -0.798700 0.000000 +vn 0.998300 -0.007000 0.057200 +vn 0.804500 0.591300 0.056100 +vn 0.387500 0.921600 -0.024800 +vn 0.789700 0.009000 -0.613500 +vn 0.006700 -0.872900 -0.487800 +vn 0.344100 -0.674300 -0.653300 +vn 0.079600 -0.938500 -0.336100 +vn 0.007600 -0.906600 -0.422000 +vn 0.079600 -0.938500 0.336100 +vn 0.448700 -0.759600 0.470800 +vn 0.006700 -0.872900 0.487800 +vn 0.006600 -0.875400 0.483300 +vn 0.789700 0.009000 0.613500 +vn 0.977800 0.209800 0.000000 +vn -0.002900 0.819200 -0.573500 +vn -0.671300 0.064000 -0.738400 +vn -0.999500 -0.031300 -0.000000 +vn -0.671300 0.064000 0.738400 +vn -0.000000 -0.420900 0.907100 +vn 0.000000 -0.420900 -0.907100 +vn 0.000900 -0.410600 -0.911800 +vn 0.011000 -0.004700 -0.999900 +vn -0.544700 0.838600 -0.001100 +vn 0.006600 -0.875400 -0.483300 +vn 0.448700 -0.759600 -0.470800 +vn 0.998300 -0.007000 -0.057200 +vn 0.007800 -0.875800 0.482600 +vn 0.007600 -0.875800 0.482600 +vn 0.998700 0.051100 -0.000000 +vn -0.544700 0.838600 0.001100 +vn -0.565100 0.004000 0.825000 +vn 0.007600 -0.875800 -0.482600 +vn 0.007800 -0.875800 -0.482600 +vn -0.565100 0.004000 -0.825000 +vn -1.000000 -0.000300 -0.004600 +vn -0.390800 -0.526400 0.755100 +vn 0.004500 -0.564400 0.825500 +vn 0.019200 -0.562800 0.826400 +vn 0.999600 0.029200 -0.000000 +vn -1.000000 -0.000300 0.004600 +vn -0.390800 -0.526400 -0.755100 +vn -0.393800 -0.509700 0.765000 +vn -0.999900 -0.010800 -0.004000 +vn 0.019200 -0.562800 -0.826400 +vn 0.004500 -0.564400 -0.825500 +vn 0.005000 -0.564200 0.825600 +vn 0.018900 -0.555100 0.831600 +vn 0.005000 -0.564400 0.825500 +vn 0.982800 -0.184600 -0.000000 +vn -0.393800 -0.509700 -0.764900 +vn -0.999900 -0.010800 0.004000 +vn -0.590000 -0.807400 0.000000 +vn 0.004300 -0.555700 0.831400 +vn -1.000000 0.004200 0.000000 +vn 0.005000 -0.564400 -0.825500 +vn 0.005000 -0.564200 -0.825600 +vn 0.018900 -0.555100 -0.831600 +vn 0.004900 -0.555600 0.831400 +vn 0.034100 -0.999400 0.000000 +vn 0.019600 -0.582300 0.812700 +vn 0.060400 -0.998200 0.000000 +vn 0.004300 -0.555700 -0.831400 +vn 0.007700 -1.000000 0.000000 +vn 0.019600 -0.582300 -0.812700 +vn 0.004900 -0.555600 -0.831400 +vn 0.008900 -1.000000 0.000000 +vn 0.239000 0.971000 0.000000 +vn 0.003900 -0.035400 0.999400 +vn 0.244300 0.969700 0.000000 +vn -0.195500 0.980700 0.000000 +vn 0.020400 -0.048100 0.998600 +vn 0.003900 -0.035400 -0.999400 +vn -0.987000 0.160800 0.000000 +vn -0.450600 -0.892700 0.000000 +vn -0.559400 -0.828900 0.000000 +vn -0.045100 -0.050100 -0.997700 +vn 0.997900 0.049700 0.042500 +vn 0.997300 0.073000 -0.007200 +vn 0.997300 0.073000 0.007200 +vn 0.997900 0.049700 -0.042500 +usemtl Muzzle +s off +f 282//1 283//1 285//1 284//1 +f 284//2 285//2 287//2 286//2 +f 286//3 287//3 289//3 288//3 +f 288//4 289//4 291//4 290//4 +f 290//5 291//5 293//5 292//5 +f 292//6 293//6 295//6 294//6 +f 294//7 295//7 297//7 296//7 +f 293//8 291//8 304//8 305//8 +f 298//9 299//9 283//9 282//9 +f 296//10 297//10 299//10 298//10 +f 282//11 284//11 286//11 288//11 290//11 292//11 294//11 296//11 298//11 +f 305//12 304//12 313//12 314//12 +f 291//8 289//8 303//8 304//8 +f 285//8 283//8 301//8 300//8 +f 289//8 287//8 302//8 303//8 +f 287//8 285//8 300//8 302//8 +f 283//8 299//8 308//8 301//8 +f 299//8 297//8 307//8 308//8 +f 297//8 295//8 306//8 307//8 +f 295//8 293//8 305//8 306//8 +f 309//8 310//8 317//8 316//8 315//8 314//8 313//8 312//8 311//8 +f 302//13 300//13 309//13 311//13 +f 301//14 308//14 317//14 310//14 +f 306//15 305//15 314//15 315//15 +f 303//16 302//16 311//16 312//16 +f 307//17 306//17 315//17 316//17 +f 304//18 303//18 312//18 313//18 +f 300//19 301//19 310//19 309//19 +f 308//20 307//20 316//20 317//20 +usemtl Magazine +f 2//5 6//5 5//5 1//5 +f 3//12 7//12 8//12 4//12 +f 2//21 10//21 12//21 4//21 +f 1//21 3//21 11//21 9//21 +f 5//22 7//22 8//22 6//22 +f 9//23 11//23 15//23 13//23 +f 10//24 14//24 16//24 12//24 +f 1//25 5//25 7//25 3//25 +f 10//5 9//5 13//5 14//5 +f 11//12 12//12 16//12 15//12 +f 2//26 1//26 9//26 10//26 +f 13//27 15//27 16//27 14//27 +f 3//28 4//28 12//28 11//28 +f 6//29 2//29 4//29 8//29 +usemtl Metal +f 133//30 22//30 19//30 130//30 +f 28//31 27//31 58//31 57//31 +f 127//32 18//32 24//32 137//32 +f 17//33 128//33 238//33 107//33 +f 21//34 134//34 128//34 17//34 +f 31//35 153//35 134//35 21//35 +f 46//36 45//36 74//36 71//36 +f 152//37 32//37 22//37 133//37 +f 148//38 30//38 27//38 143//38 +f 21//39 17//39 48//39 50//39 +f 25//40 138//40 159//40 35//40 +f 36//41 109//41 38//41 64//41 63//41 +f 143//42 27//42 28//42 145//42 +f 30//43 24//43 49//43 59//43 +f 29//44 149//44 145//44 28//44 +f 26//45 141//45 149//45 29//45 +f 42//46 37//46 61//46 68//46 +f 137//47 24//47 30//47 148//47 +f 129//48 20//48 32//48 152//48 +f 32//49 20//49 47//49 51//49 +f 18//50 127//50 153//50 31//50 +f 33//51 154//51 157//51 34//51 +f 33//52 34//52 55//52 60//52 +f 141//53 26//53 34//53 157//53 +f 35//54 159//54 160//54 36//54 +f 154//55 33//55 37//55 162//55 +f 19//56 22//56 45//56 46//56 +f 26//57 29//57 56//57 54//57 +f 36//58 160//58 243//58 109//58 +f 40//59 168//59 166//59 39//59 +f 172//60 42//60 39//60 166//60 +f 41//61 173//61 168//61 40//61 +f 38//62 164//62 173//62 41//62 +f 162//63 37//63 42//63 172//63 +f 41//64 40//64 66//64 67//64 +f 60//65 55//65 83//65 87//65 84//65 +f 19//66 46//66 71//66 70//66 +f 44//67 43//67 72//67 73//67 +f 52//68 53//68 81//68 80//68 +f 59//69 56//69 57//69 58//69 +f 49//70 54//70 56//70 59//70 +f 51//71 47//71 75//71 79//71 +f 45//72 51//72 79//72 74//72 +f 68//73 67//73 66//73 65//73 +f 60//74 63//74 64//74 61//74 +f 61//75 64//75 67//75 68//75 +f 22//76 32//76 51//76 45//76 +f 34//77 26//77 54//77 55//77 +f 37//78 33//78 60//78 61//78 +f 38//79 41//79 67//79 64//79 +f 25//80 35//80 62//80 53//80 +f 18//81 31//81 43//81 44//81 +f 27//82 30//82 59//82 58//82 +f 29//83 28//83 57//83 56//83 +f 39//84 42//84 68//84 65//84 +f 24//85 18//85 44//85 49//85 +f 40//86 39//86 65//86 66//86 +f 35//87 36//87 63//87 62//87 +f 23//88 25//88 53//88 52//88 +f 31//89 21//89 50//89 43//89 +f 47//90 52//90 80//90 75//90 +f 53//91 62//91 85//91 81//91 +f 55//92 54//92 82//92 83//92 +f 62//93 63//93 86//93 85//93 +f 49//94 44//94 73//94 77//94 +f 54//95 49//95 77//95 82//95 +f 63//96 60//96 84//96 86//96 +f 48//97 17//97 69//97 76//97 +f 50//98 48//98 76//98 78//98 +f 43//99 50//99 78//99 72//99 +f 17//100 19//100 70//100 69//100 +f 240//22 241//22 273//22 275//22 +f 130//101 19//101 108//101 241//101 +f 19//5 17//5 107//5 108//5 +f 109//102 243//102 247//102 111//102 +f 111//103 247//103 251//103 113//103 +f 38//104 109//104 111//104 110//104 +f 164//105 38//105 110//105 245//105 +f 249//106 112//106 114//106 253//106 +f 110//107 111//107 113//107 112//107 +f 245//108 110//108 112//108 249//108 +f 253//109 114//109 116//109 257//109 +f 113//110 251//110 255//110 115//110 +f 112//111 113//111 115//111 114//111 +f 117//112 259//112 263//112 119//112 +f 115//113 255//113 259//113 117//113 +f 114//114 115//114 117//114 116//114 +f 118//115 119//115 121//115 120//115 +f 116//116 117//116 119//116 118//116 +f 257//117 116//117 118//117 261//117 +f 261//118 118//118 120//118 265//118 +f 119//119 263//119 267//119 121//119 +f 121//120 267//120 138//120 25//120 +f 265//121 120//121 122//121 269//121 +f 20//122 129//122 269//122 122//122 +f 20//123 122//123 23//123 52//123 47//123 +f 120//124 121//124 25//124 23//124 122//124 +f 133//30 130//30 125//30 132//30 +f 144//125 188//125 189//125 142//125 +f 127//32 137//32 136//32 124//32 +f 123//33 239//33 238//33 128//33 +f 131//34 123//34 128//34 134//34 +f 150//35 131//35 134//35 153//35 +f 177//126 202//126 205//126 176//126 +f 152//37 133//37 132//37 151//37 +f 148//38 143//38 142//38 147//38 +f 131//127 181//127 179//127 123//127 +f 139//128 158//128 159//128 138//128 +f 161//129 194//129 195//129 165//129 242//129 +f 143//42 145//42 144//42 142//42 +f 147//130 190//130 180//130 136//130 +f 146//44 144//44 145//44 149//44 +f 140//45 146//45 149//45 141//45 +f 171//131 199//131 192//131 163//131 +f 137//47 148//47 147//47 136//47 +f 129//48 152//48 151//48 126//48 +f 151//132 182//132 178//132 126//132 +f 124//50 150//50 153//50 127//50 +f 155//133 156//133 157//133 154//133 +f 155//134 191//134 186//134 156//134 +f 141//53 157//53 156//53 140//53 +f 158//135 161//135 160//135 159//135 +f 154//136 162//136 163//136 155//136 +f 125//137 177//137 176//137 132//137 +f 140//138 185//138 187//138 146//138 +f 161//139 242//139 243//139 160//139 +f 169//140 167//140 166//140 168//140 +f 172//60 166//60 167//60 171//60 +f 170//141 169//141 168//141 173//141 +f 165//142 170//142 173//142 164//142 +f 162//63 172//63 171//63 163//63 +f 170//143 198//143 197//143 169//143 +f 191//144 215//144 218//144 214//144 186//144 +f 125//145 201//145 202//145 177//145 +f 175//146 204//146 203//146 174//146 +f 183//147 211//147 212//147 184//147 +f 190//148 189//148 188//148 187//148 +f 180//149 190//149 187//149 185//149 +f 182//150 210//150 206//150 178//150 +f 176//151 205//151 210//151 182//151 +f 199//152 196//152 197//152 198//152 +f 191//153 192//153 195//153 194//153 +f 192//154 199//154 198//154 195//154 +f 132//155 176//155 182//155 151//155 +f 156//156 186//156 185//156 140//156 +f 163//157 192//157 191//157 155//157 +f 165//158 195//158 198//158 170//158 +f 139//159 184//159 193//159 158//159 +f 124//160 175//160 174//160 150//160 +f 142//161 189//161 190//161 147//161 +f 146//162 187//162 188//162 144//162 +f 167//163 196//163 199//163 171//163 +f 136//164 180//164 175//164 124//164 +f 169//165 197//165 196//165 167//165 +f 158//166 193//166 194//166 161//166 +f 135//167 183//167 184//167 139//167 +f 150//168 174//168 181//168 131//168 +f 178//169 206//169 211//169 183//169 +f 184//170 212//170 216//170 193//170 +f 186//171 214//171 213//171 185//171 +f 193//172 216//172 217//172 194//172 +f 180//173 208//173 204//173 175//173 +f 185//174 213//174 208//174 180//174 +f 194//175 217//175 215//175 191//175 +f 179//176 207//176 200//176 123//176 +f 181//177 209//177 207//177 179//177 +f 174//178 203//178 209//178 181//178 +f 123//179 200//179 201//179 125//179 +f 107//22 238//22 270//22 271//22 +f 130//101 241//101 240//101 125//101 +f 125//12 240//12 239//12 123//12 +f 242//180 246//180 247//180 243//180 +f 246//181 250//181 251//181 247//181 +f 165//182 244//182 246//182 242//182 +f 164//183 245//183 244//183 165//183 +f 249//184 253//184 252//184 248//184 +f 244//185 248//185 250//185 246//185 +f 245//186 249//186 248//186 244//186 +f 253//187 257//187 256//187 252//187 +f 250//188 254//188 255//188 251//188 +f 248//189 252//189 254//189 250//189 +f 258//190 262//190 263//190 259//190 +f 254//191 258//191 259//191 255//191 +f 252//192 256//192 258//192 254//192 +f 260//193 264//193 266//193 262//193 +f 256//194 260//194 262//194 258//194 +f 257//195 261//195 260//195 256//195 +f 261//196 265//196 264//196 260//196 +f 262//197 266//197 267//197 263//197 +f 266//198 139//198 138//198 267//198 +f 265//199 269//199 268//199 264//199 +f 126//122 268//122 269//122 129//122 +f 126//200 178//200 183//200 135//200 268//200 +f 264//201 268//201 135//201 139//201 266//201 +f 272//12 271//12 277//12 278//12 +f 274//5 275//5 281//5 280//5 +f 238//22 239//22 274//22 270//22 +f 108//22 107//22 271//22 272//22 +f 239//22 240//22 275//22 274//22 +f 241//22 108//22 272//22 273//22 +f 277//22 276//22 279//22 278//22 +f 280//22 281//22 279//22 276//22 +f 275//202 273//202 279//202 281//202 +f 270//203 274//203 280//203 276//203 +f 273//202 272//202 278//202 279//202 +f 271//203 270//203 276//203 277//203 +usemtl Wood +f 69//204 70//204 89//204 88//204 +f 86//205 84//205 106//205 105//205 +f 78//206 76//206 95//206 97//206 +f 82//207 77//207 96//207 101//207 +f 84//208 87//208 103//208 106//208 +f 85//209 86//209 105//209 104//209 +f 77//210 73//210 92//210 96//210 +f 88//211 89//211 90//211 95//211 +f 93//5 97//5 95//5 90//5 +f 98//5 91//5 97//5 93//5 +f 92//5 94//5 99//5 96//5 +f 96//5 99//5 100//5 101//5 +f 94//5 92//5 91//5 98//5 +f 101//5 100//5 104//5 105//5 106//5 103//5 102//5 +f 80//212 81//212 100//212 99//212 +f 74//213 79//213 98//213 93//213 +f 76//214 69//214 88//214 95//214 +f 70//215 71//215 90//215 89//215 +f 72//216 78//216 97//216 91//216 +f 73//217 72//217 91//217 92//217 +f 79//218 75//218 94//218 98//218 +f 71//219 74//219 93//219 90//219 +f 75//220 80//220 99//220 94//220 +f 87//221 83//221 102//221 103//221 +f 81//222 85//222 104//222 100//222 +f 83//223 82//223 101//223 102//223 +f 200//224 219//224 220//224 201//224 +f 217//225 236//225 237//225 215//225 +f 209//226 228//226 226//226 207//226 +f 213//227 232//227 227//227 208//227 +f 215//228 237//228 234//228 218//228 +f 216//229 235//229 236//229 217//229 +f 208//230 227//230 223//230 204//230 +f 219//231 226//231 221//231 220//231 +f 224//12 221//12 226//12 228//12 +f 229//12 224//12 228//12 222//12 +f 223//12 227//12 230//12 225//12 +f 227//12 232//12 231//12 230//12 +f 225//12 229//12 222//12 223//12 +f 232//12 233//12 234//12 237//12 236//12 235//12 231//12 +f 211//232 230//232 231//232 212//232 +f 205//233 224//233 229//233 210//233 +f 207//234 226//234 219//234 200//234 +f 201//235 220//235 221//235 202//235 +f 203//236 222//236 228//236 209//236 +f 204//237 223//237 222//237 203//237 +f 210//238 229//238 225//238 206//238 +f 202//239 221//239 224//239 205//239 +f 206//240 225//240 230//240 211//240 +f 218//241 234//241 233//241 214//241 +f 212//242 231//242 235//242 216//242 +f 214//243 233//243 232//243 213//243 +usemtl Material.003 +f 326//244 327//244 320//244 318//244 +f 327//12 328//12 324//12 320//12 +f 328//245 329//245 322//245 324//245 +f 329//5 326//5 318//5 322//5 +f 318//246 320//246 324//246 322//246 +f 323//247 325//247 321//247 319//247 +f 340//5 341//5 326//5 329//5 +f 339//248 340//248 329//248 328//248 +f 338//12 339//12 328//12 327//12 +f 341//244 338//244 327//244 326//244 +f 319//244 321//244 331//244 330//244 +f 321//12 325//12 332//12 331//12 +f 325//249 323//249 333//249 332//249 +f 323//5 319//5 330//5 333//5 +f 330//250 331//250 334//250 337//250 +f 331//12 332//12 335//12 334//12 +f 332//251 333//251 336//251 335//251 +f 333//5 330//5 337//5 336//5 +f 337//244 334//244 338//244 341//244 +f 334//12 335//12 339//12 338//12 +f 335//252 336//252 340//252 339//252 +f 336//5 337//5 341//5 340//5 +usemtl DarkerMetal +f 342//253 343//253 344//253 345//253 +f 345//254 346//254 352//254 342//254 +f 343//255 342//255 473//255 430//255 396//255 542//255 532//255 471//255 429//255 604//255 533//255 472//255 367//255 527//255 470//255 428//255 395//255 423//255 390//255 353//255 347//255 354//255 +f 344//256 343//256 348//256 349//256 +f 350//253 345//253 344//253 351//253 +f 345//257 350//257 364//257 346//257 +f 344//256 349//256 355//256 351//256 +f 343//258 356//258 373//258 348//258 +f 349//259 348//259 357//259 358//259 +f 360//260 342//260 352//260 361//260 +f 352//21 346//21 362//21 363//21 +f 347//5 353//5 365//5 366//5 +f 366//11 368//11 369//11 370//11 354//11 347//11 +f 343//261 354//261 370//261 356//261 +f 349//259 358//259 371//259 355//259 +f 351//262 355//262 401//262 372//262 +f 348//263 373//263 404//263 357//263 +f 358//259 357//259 374//259 375//259 376//259 +f 379//264 360//264 361//264 380//264 +f 361//21 352//21 363//21 382//21 +f 346//21 380//21 383//21 362//21 +f 363//265 362//265 384//265 385//265 +f 386//266 387//266 364//266 350//266 +f 364//21 388//21 389//21 346//21 +f 353//8 390//8 391//8 392//8 393//8 365//8 +f 368//5 398//5 369//5 +f 398//5 356//5 370//5 369//5 +f 358//259 376//259 399//259 400//259 371//259 +f 355//267 371//267 435//267 401//267 +f 351//268 372//268 402//268 377//268 +f 356//5 398//5 403//5 373//5 +f 357//269 404//269 440//269 374//269 +f 375//270 374//270 405//270 406//270 +f 376//271 375//271 407//271 408//271 +f 409//11 359//11 377//11 402//11 410//11 411//11 +f 359//12 409//12 412//12 378//12 +f 379//264 380//264 387//264 386//264 +f 379//272 454//272 455//272 456//272 457//272 458//272 453//272 360//272 +f 380//21 361//21 382//21 383//21 +f 382//5 363//5 385//5 416//5 +f 346//21 389//21 417//21 380//21 +f 362//12 383//12 418//12 384//12 +f 384//273 418//273 416//273 385//273 +f 387//21 420//21 388//21 364//21 +f 388//274 421//274 422//274 389//274 +f 390//261 423//261 424//261 391//261 +f 391//5 424//5 425//5 392//5 +f 426//5 393//5 392//5 425//5 +f 376//271 408//271 432//271 399//271 +f 399//270 433//270 434//270 400//270 +f 372//12 401//12 436//12 437//12 +f 437//12 410//12 402//12 372//12 +f 373//5 403//5 439//5 404//5 +f 406//275 405//275 441//275 442//275 +f 408//276 407//276 443//276 444//276 +f 411//12 410//12 437//12 +f 378//8 412//8 447//8 448//8 449//8 450//8 +f 380//21 417//21 420//21 387//21 +f 383//11 382//11 416//11 418//11 +f 389//5 422//5 463//5 417//5 +f 465//277 386//277 350//277 572//277 646//277 654//277 519//277 464//277 588//277 650//277 518//277 419//277 520//277 +f 420//12 466//12 421//12 388//12 +f 422//278 421//278 466//278 463//278 +f 467//11 426//11 425//11 424//11 423//11 395//11 +f 395//5 428//5 427//5 467//5 +f 396//5 430//5 474//5 475//5 +f 431//279 397//279 476//279 477//279 +f 438//280 398//280 368//280 366//280 365//280 393//280 426//280 467//280 427//280 524//280 469//280 394//280 468//280 397//280 431//280 +f 408//276 444//276 478//276 432//276 +f 399//281 432//281 478//281 547//281 433//281 +f 433//275 479//275 480//275 434//275 +f 400//282 434//282 551//282 481//282 +f 481//283 435//283 371//283 400//283 +f 401//12 435//12 482//12 436//12 +f 437//284 436//284 553//284 483//284 +f 484//285 403//285 398//285 438//285 +f 403//286 484//286 555//286 439//286 +f 404//5 439//5 485//5 440//5 +f 406//287 486//287 443//287 407//287 375//287 +f 487//288 405//288 374//288 440//288 +f 488//275 406//275 442//275 489//275 +f 405//5 490//5 491//5 441//5 +f 561//289 558//289 489//289 442//289 441//289 491//289 560//289 670//289 623//289 624//289 492//289 +f 443//290 486//290 557//290 444//290 +f 562//291 446//291 566//291 631//291 494//291 565//291 495//291 447//291 412//291 409//291 411//291 437//291 483//291 493//291 445//291 +f 495//12 496//12 448//12 447//12 +f 449//12 448//12 496//12 497//12 +f 450//268 449//268 497//268 498//268 +f 502//292 503//292 504//292 505//292 454//292 379//292 386//292 +f 417//11 463//11 466//11 420//11 +f 453//293 458//293 507//293 508//293 509//293 575//293 506//293 +f 453//294 462//294 415//294 360//294 +f 459//5 381//5 510//5 511//5 +f 512//295 414//295 460//295 586//295 534//295 473//295 342//295 360//295 415//295 461//295 381//295 459//295 579//295 +f 460//5 414//5 513//5 514//5 +f 461//296 415//296 462//296 587//296 515//296 +f 381//8 461//8 515//8 516//8 517//8 510//8 +f 465//297 521//297 502//297 386//297 +f 367//5 472//5 522//5 468//5 394//5 +f 394//11 469//11 525//11 526//11 527//11 367//11 +f 428//8 470//8 528//8 529//8 524//8 427//8 +f 429//5 471//5 530//5 531//5 +f 430//8 473//8 534//8 535//8 536//8 537//8 474//8 +f 475//11 538//11 539//11 540//11 541//11 542//11 396//11 +f 477//298 543//298 438//298 431//298 +f 397//279 523//279 544//279 476//279 +f 476//246 545//246 546//246 477//246 +f 488//275 489//275 479//275 433//275 +f 434//12 480//12 549//12 550//12 +f 435//12 481//12 552//12 482//12 +f 440//5 485//5 556//5 487//5 +f 486//299 406//299 488//299 557//299 +f 490//300 559//300 560//300 491//300 +f 493//301 563//301 564//301 445//301 +f 565//11 451//11 498//11 497//11 496//11 495//11 +f 451//12 565//12 494//12 499//12 +f 452//12 570//12 571//12 501//12 +f 509//302 574//302 503//302 502//302 573//302 575//302 +f 511//11 576//11 577//11 578//11 579//11 459//11 +f 414//8 512//8 580//8 581//8 582//8 513//8 +f 514//11 583//11 584//11 585//11 586//11 460//11 +f 587//5 516//5 515//5 +f 516//303 587//303 517//303 +f 518//12 589//12 590//12 419//12 +f 519//12 591//12 592//12 464//12 +f 419//8 590//8 593//8 594//8 595//8 520//8 +f 472//8 533//8 596//8 597//8 598//8 599//8 522//8 +f 469//5 524//5 529//5 525//5 +f 528//5 526//5 525//5 529//5 +f 470//261 527//261 526//261 528//261 +f 531//11 600//11 601//11 602//11 603//11 604//11 429//11 +f 471//8 532//8 605//8 606//8 607//8 608//8 530//8 +f 585//5 535//5 534//5 586//5 +f 584//5 536//5 535//5 585//5 +f 536//303 584//303 583//303 537//303 +f 607//303 539//303 538//303 608//303 +f 539//5 607//5 606//5 540//5 +f 605//5 541//5 540//5 606//5 +f 532//261 542//261 541//261 605//261 +f 477//304 546//304 609//304 543//304 +f 523//305 610//305 611//305 544//305 +f 544//246 611//246 545//246 476//246 +f 564//246 563//246 546//246 545//246 +f 438//306 543//306 554//306 +f 557//307 547//307 478//307 444//307 +f 547//308 557//308 488//308 433//308 +f 479//289 489//289 558//289 612//289 548//289 613//289 661//289 691//289 670//289 560//289 549//289 480//289 +f 434//309 550//309 614//309 551//309 +f 550//300 549//300 560//300 559//300 +f 481//12 551//12 614//12 552//12 +f 482//310 552//310 663//310 615//310 +f 615//311 553//311 436//311 482//311 +f 483//312 553//312 665//312 616//312 +f 483//313 617//313 563//313 493//313 +f 618//314 484//314 438//314 554//314 +f 555//315 484//315 618//315 619//315 +f 620//316 485//316 439//316 555//316 +f 485//317 620//317 490//317 556//317 +f 556//318 490//318 405//318 487//318 +f 559//319 490//319 621//319 622//319 +f 413//12 446//12 562//12 626//12 568//12 +f 445//301 564//301 627//301 625//301 +f 446//11 413//11 628//11 629//11 630//11 566//11 +f 499//8 494//8 631//8 632//8 633//8 567//8 +f 500//12 635//12 636//12 569//12 +f 638//320 452//320 501//320 572//320 350//320 351//320 377//320 359//320 378//320 450//320 498//320 451//320 499//320 567//320 628//320 413//320 568//320 634//320 675//320 500//320 569//320 637//320 +f 570//11 452//11 638//11 639//11 640//11 641//11 642//11 +f 501//8 571//8 643//8 644//8 645//8 646//8 572//8 +f 502//321 521//321 658//321 625//321 573//321 +f 506//322 575//322 610//322 523//322 +f 587//323 462//323 453//323 506//323 523//323 +f 581//303 577//303 576//303 582//303 +f 577//5 581//5 580//5 578//5 +f 578//5 580//5 512//5 579//5 +f 475//324 474//324 537//324 583//324 514//324 513//324 582//324 576//324 511//324 510//324 517//324 587//324 523//324 397//324 468//324 522//324 599//324 600//324 531//324 530//324 608//324 538//324 +f 464//8 592//8 647//8 648//8 649//8 588//8 +f 589//11 518//11 650//11 651//11 652//11 653//11 +f 591//11 519//11 654//11 655//11 656//11 657//11 +f 643//325 571//325 570//325 642//325 680//325 636//325 635//325 679//325 671//325 626//325 562//325 445//325 625//325 658//325 593//325 590//325 589//325 653//325 647//325 592//325 591//325 657//325 +f 594//326 593//326 658//326 +f 658//12 595//12 594//12 +f 658//327 521//327 465//327 520//327 595//327 +f 533//261 604//261 603//261 596//261 +f 596//5 603//5 602//5 597//5 +f 601//5 598//5 597//5 602//5 +f 598//303 601//303 600//303 599//303 +f 563//304 617//304 609//304 546//304 +f 543//328 609//328 685//328 659//328 +f 625//305 627//305 611//305 610//305 +f 627//246 564//246 545//246 611//246 +f 618//5 554//5 543//5 660//5 +f 559//319 622//319 662//319 550//319 +f 552//329 614//329 550//329 663//329 +f 615//330 664//330 665//330 553//330 +f 483//331 616//331 617//331 +f 620//332 555//332 619//332 666//332 +f 619//5 618//5 660//5 667//5 +f 490//333 620//333 666//333 621//333 +f 622//334 621//334 668//334 669//334 +f 568//8 626//8 671//8 672//8 673//8 674//8 634//8 +f 567//268 633//268 629//268 628//268 +f 633//12 632//12 630//12 629//12 +f 566//12 630//12 632//12 631//12 +f 635//11 500//11 675//11 676//11 677//11 678//11 679//11 +f 569//8 636//8 680//8 681//8 682//8 683//8 637//8 +f 637//268 683//268 639//268 638//268 +f 683//12 682//12 640//12 639//12 +f 641//12 640//12 682//12 681//12 +f 681//326 680//326 642//326 641//326 +f 644//326 643//326 657//326 656//326 +f 656//12 655//12 645//12 644//12 +f 655//12 654//12 646//12 645//12 +f 573//322 625//322 610//322 575//322 +f 648//326 647//326 653//326 652//326 +f 652//12 651//12 649//12 648//12 +f 651//12 650//12 588//12 649//12 +f 617//335 684//335 685//335 609//335 +f 686//336 543//336 659//336 687//336 +f 660//5 543//5 686//5 688//5 +f 622//334 669//334 689//334 662//334 +f 550//337 662//337 690//337 663//337 +f 663//338 690//338 664//338 615//338 +f 664//12 692//12 693//12 665//12 +f 665//12 693//12 617//12 616//12 +f 666//5 619//5 667//5 694//5 +f 667//5 660//5 688//5 695//5 +f 621//5 666//5 694//5 668//5 +f 669//334 668//334 696//334 697//334 +f 672//326 671//326 679//326 678//326 +f 678//12 677//12 673//12 672//12 +f 674//12 673//12 677//12 676//12 +f 634//268 674//268 676//268 675//268 +f 698//339 699//339 684//339 617//339 +f 659//340 685//340 713//340 687//340 +f 700//341 686//341 687//341 701//341 +f 688//342 686//342 700//342 702//342 +f 669//334 697//334 703//334 689//334 +f 662//12 689//12 704//12 690//12 +f 690//12 704//12 692//12 664//12 +f 692//12 705//12 706//12 693//12 +f 693//12 706//12 698//12 617//12 +f 694//5 667//5 695//5 707//5 +f 695//343 688//343 702//343 708//343 +f 668//5 694//5 707//5 696//5 +f 697//344 696//344 709//344 710//344 +f 684//345 699//345 713//345 685//345 +f 711//346 712//346 699//346 698//346 +f 714//347 700//347 701//347 715//347 +f 687//348 713//348 729//348 701//348 +f 697//344 710//344 716//344 703//344 +f 689//12 703//12 717//12 704//12 +f 704//12 717//12 705//12 692//12 +f 705//349 718//349 719//349 706//349 +f 706//350 719//350 711//350 698//350 +f 707//351 695//351 708//351 720//351 +f 708//352 702//352 721//352 722//352 +f 696//353 707//353 720//353 709//353 +f 710//354 709//354 723//354 724//354 +f 725//355 726//355 712//355 711//355 +f 699//356 712//356 729//356 713//356 +f 727//357 714//357 715//357 728//357 +f 702//358 700//358 714//358 721//358 +f 701//359 729//359 728//359 715//359 +f 710//354 724//354 730//354 716//354 +f 703//360 716//360 731//360 717//360 +f 717//361 731//361 718//361 705//361 +f 718//362 732//362 733//362 719//362 +f 720//363 708//363 722//363 734//363 +f 721//364 735//364 736//364 722//364 +f 720//365 734//365 723//365 709//365 +f 734//366 737//366 724//366 723//366 +f 719//367 733//367 725//367 711//367 +f 727//357 728//357 726//357 725//357 +f 712//359 726//359 728//359 729//359 +f 714//368 727//368 735//368 721//368 +f 738//366 730//366 724//366 737//366 +f 730//369 738//369 731//369 716//369 +f 731//370 738//370 732//370 718//370 +f 733//364 732//364 736//364 735//364 +f 722//371 736//371 737//371 734//371 +f 725//368 733//368 735//368 727//368 +f 732//371 738//371 737//371 736//371 +f 750//372 751//372 752//372 753//372 +f 750//373 753//373 758//373 759//373 754//373 507//373 458//373 457//373 +f 455//374 751//374 750//374 456//374 +f 755//372 756//372 752//372 751//372 +f 753//375 752//375 757//375 758//375 +f 755//374 751//374 455//374 454//374 505//374 +f 456//376 750//376 457//376 +f 574//377 760//377 764//377 761//377 756//377 755//377 504//377 503//377 +f 756//375 761//375 757//375 752//375 +f 758//378 757//378 762//378 759//378 +f 763//379 754//379 759//379 762//379 +f 507//380 754//380 763//380 508//380 +f 504//381 755//381 505//381 +f 761//378 764//378 762//378 757//378 +f 763//379 762//379 764//379 760//379 +f 508//380 763//380 760//380 574//380 509//380 +f 739//382 740//382 741//382 +f 741//383 740//383 744//383 746//383 743//383 742//383 +f 747//384 745//384 748//384 742//384 743//384 746//384 +f 749//385 748//385 745//385 diff --git a/assets/quaternius/models/Pistol.obj.import b/assets/quaternius/models/Pistol.obj.import new file mode 100644 index 0000000..e70f465 --- /dev/null +++ b/assets/quaternius/models/Pistol.obj.import @@ -0,0 +1,25 @@ +[remap] + +importer="wavefront_obj" +importer_version=1 +type="Mesh" +uid="uid://cpt164o0tk18a" +path="res://.godot/imported/Pistol.obj-14b0d39d64d4f9501f6e7999f30e6929.mesh" + +[deps] + +files=["res://.godot/imported/Pistol.obj-14b0d39d64d4f9501f6e7999f30e6929.mesh"] + +source_file="res://assets/quaternius/models/Pistol.obj" +dest_files=["res://.godot/imported/Pistol.obj-14b0d39d64d4f9501f6e7999f30e6929.mesh", "res://.godot/imported/Pistol.obj-14b0d39d64d4f9501f6e7999f30e6929.mesh"] + +[params] + +generate_tangents=true +generate_lods=true +generate_shadow_mesh=true +generate_lightmap_uv2=false +generate_lightmap_uv2_texel_size=0.2 +scale_mesh=Vector3(1, 1, 1) +offset_mesh=Vector3(0, 0, 0) +force_disable_mesh_compression=false diff --git a/assets/quaternius/models/Revolver.glb b/assets/quaternius/models/Revolver.glb new file mode 100644 index 0000000..d07c9a1 Binary files /dev/null and b/assets/quaternius/models/Revolver.glb differ diff --git a/assets/quaternius/models/Revolver.glb.import b/assets/quaternius/models/Revolver.glb.import new file mode 100644 index 0000000..092b87b --- /dev/null +++ b/assets/quaternius/models/Revolver.glb.import @@ -0,0 +1,45 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://dsie0nqm2cynl" +path="res://.godot/imported/Revolver.glb-b3a8e05b70649269c157ffc7301e7705.scn" + +[deps] + +source_file="res://assets/quaternius/models/Revolver.glb" +dest_files=["res://.godot/imported/Revolver.glb-b3a8e05b70649269c157ffc7301e7705.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/assets/quaternius/models/Revolver.mtl b/assets/quaternius/models/Revolver.mtl new file mode 100644 index 0000000..fdbec97 --- /dev/null +++ b/assets/quaternius/models/Revolver.mtl @@ -0,0 +1,52 @@ +# Blender MTL File: 'Revolver.blend' +# Material Count: 5 + +newmtl Black +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl BulletTip +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl BulletYellow +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Metal +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Wood +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 diff --git a/assets/quaternius/models/Revolver.obj b/assets/quaternius/models/Revolver.obj new file mode 100644 index 0000000..6492456 --- /dev/null +++ b/assets/quaternius/models/Revolver.obj @@ -0,0 +1,3321 @@ +# Blender v2.76 (sub 0) OBJ File: 'Revolver.blend' +# www.blender.org +mtllib Revolver.mtl +o Bullets_Cylinder.022 +v 2.126255 -417.796844 2.181988 +v 2.060856 -418.354309 2.181988 +v 2.123431 -417.797668 1.687716 +v 2.058325 -418.352997 1.687714 +v 1.779100 -417.355804 2.181988 +v 1.777637 -417.358276 1.687714 +v 2.088629 -417.807465 1.678792 +v 2.090237 -417.809540 1.679282 +v 2.078181 -417.905853 1.679079 +v 2.001549 -417.965424 1.660611 +v 1.921623 -417.955444 1.639105 +v 1.899352 -418.145416 1.639105 +v 1.978579 -418.155304 1.660422 +v 2.038161 -418.231934 1.678604 +v 2.026106 -418.328247 1.678401 +v 2.021139 -418.332092 1.677204 +v 1.620298 -418.698395 1.687714 +v 1.621066 -418.701111 2.181987 +v 1.222895 -417.290070 2.181987 +v 1.223664 -417.292786 1.687714 +v 1.757416 -417.394501 1.677488 +v 1.764499 -417.395386 1.678828 +v 1.824077 -417.472015 1.678676 +v 1.812016 -417.568329 1.660241 +v 1.749523 -417.616943 1.639105 +v 1.870432 -417.770569 1.639105 +v 1.934344 -417.720856 1.660721 +v 2.030659 -417.732910 1.678940 +v 1.949480 -418.387817 1.677038 +v 1.853164 -418.375763 1.658617 +v 1.808226 -418.317993 1.639105 +v 1.650040 -418.442719 1.639105 +v 1.702101 -418.509674 1.661711 +v 1.690051 -418.605957 1.679880 +v 1.613425 -418.665558 1.679703 +v 1.610941 -418.665222 1.679228 +v 1.793581 -418.299164 1.639105 +v 1.805636 -418.202850 1.639105 +v 1.882262 -418.143280 1.639105 +v 1.905233 -417.953400 1.639105 +v 1.888651 -417.932068 1.639105 +v 1.611015 -418.429108 1.639105 +v 1.642517 -418.433044 1.639105 +v 1.066323 -418.632904 1.687714 +v 1.064861 -418.635376 2.181987 +v 0.783105 -417.636871 2.181987 +v 0.785636 -417.638184 1.687714 +v 1.234039 -417.329559 1.678305 +v 1.328614 -417.341400 1.678130 +v 1.388186 -417.418030 1.659706 +v 1.378583 -417.494720 1.639105 +v 1.582060 -417.518768 1.639105 +v 1.591557 -417.442932 1.659479 +v 1.668189 -417.383331 1.677652 +v 1.735383 -417.627930 1.639105 +v 1.639073 -417.615875 1.639105 +v 1.579496 -417.539246 1.639105 +v 1.376125 -417.514343 1.639105 +v 1.358303 -417.528198 1.639105 +v 1.854440 -417.806580 1.639105 +v 1.857711 -417.780457 1.639105 +v 1.517114 -418.653503 1.679055 +v 1.457532 -418.576874 1.660636 +v 1.467558 -418.496735 1.639105 +v 1.260317 -418.472229 1.639105 +v 1.251228 -418.544891 1.658622 +v 1.174607 -418.604431 1.676790 +v 1.088239 -418.593628 1.676631 +v 0.995544 -418.187958 1.639105 +v 1.489467 -418.465118 1.639105 +v 1.546207 -418.420990 1.639105 +v 1.845656 -417.876770 1.639105 +v 1.845750 -417.876007 1.639105 +v 1.004892 -418.113281 1.639105 +v 0.720529 -418.193512 1.687715 +v 0.717706 -418.194336 2.181988 +v 0.823681 -417.659576 1.676961 +v 0.898640 -417.601288 1.676788 +v 0.994944 -417.613342 1.658365 +v 1.039284 -417.670380 1.639105 +v 1.193199 -417.549011 1.639105 +v 1.143617 -417.485229 1.660642 +v 1.155678 -417.388916 1.678814 +v 1.232304 -417.329346 1.678637 +v 1.299499 -417.573914 1.639105 +v 1.231106 -417.565369 1.639105 +v 0.958717 -418.053009 1.639105 +v 1.004987 -418.112518 1.639105 +v 1.078297 -418.592377 1.678512 +v 1.018720 -418.515778 1.678359 +v 1.030770 -418.419464 1.659929 +v 1.092349 -418.371582 1.639105 +v 0.975143 -418.222656 1.639105 +v 0.916312 -418.268402 1.659000 +v 0.820007 -418.256348 1.677215 +v 0.762060 -418.181793 1.677066 +v 1.107390 -418.359894 1.639105 +v 1.203700 -418.371948 1.639105 +v 1.263278 -418.448578 1.639105 +v 1.469580 -418.480560 1.639105 +v 0.992932 -418.208832 1.639105 +v 0.760430 -418.179718 1.677564 +v 0.772485 -418.083405 1.677361 +v 0.849105 -418.023834 1.658895 +v 0.922653 -418.033051 1.639105 +v 0.944905 -417.843262 1.639105 +v 0.869530 -417.833801 1.659386 +v 0.809958 -417.757172 1.677566 +v 0.822014 -417.660858 1.677363 +v 1.054516 -417.689972 1.639105 +v 1.042460 -417.786285 1.639105 +v 0.965834 -417.845886 1.639105 +v 0.945410 -418.035889 1.639105 +v 1.203188 -417.561859 1.639105 +v 2.088629 -417.807465 2.151330 +v 2.090236 -417.809540 2.151821 +v 2.078181 -417.905853 2.151618 +v 2.001549 -417.965424 2.133149 +v 1.921623 -417.955444 2.111644 +v 1.899352 -418.145416 2.111643 +v 1.978579 -418.155304 2.132961 +v 2.038162 -418.231934 2.151143 +v 2.026106 -418.328247 2.150940 +v 2.021139 -418.332092 2.149743 +v 1.757416 -417.394501 2.150027 +v 1.764499 -417.395386 2.151367 +v 1.824076 -417.472015 2.151214 +v 1.812016 -417.568329 2.132779 +v 1.749523 -417.616943 2.111643 +v 1.870432 -417.770569 2.111644 +v 1.934344 -417.720856 2.133259 +v 2.030659 -417.732910 2.151479 +v 1.949480 -418.387817 2.149577 +v 1.853163 -418.375763 2.131156 +v 1.808226 -418.317993 2.111643 +v 1.650040 -418.442719 2.111643 +v 1.702101 -418.509674 2.134249 +v 1.690051 -418.605957 2.152419 +v 1.613425 -418.665558 2.152242 +v 1.610941 -418.665222 2.151767 +v 1.793581 -418.299164 2.111643 +v 1.805636 -418.202850 2.111643 +v 1.882262 -418.143280 2.111643 +v 1.905233 -417.953400 2.111644 +v 1.888651 -417.932068 2.111644 +v 1.611015 -418.429108 2.111643 +v 1.642517 -418.433044 2.111643 +v 1.234039 -417.329559 2.150843 +v 1.328614 -417.341400 2.150669 +v 1.388186 -417.418030 2.132245 +v 1.378583 -417.494720 2.111643 +v 1.582060 -417.518768 2.111643 +v 1.591557 -417.442932 2.132018 +v 1.668188 -417.383331 2.150191 +v 1.735383 -417.627930 2.111643 +v 1.639073 -417.615875 2.111643 +v 1.579496 -417.539246 2.111643 +v 1.376125 -417.514343 2.111643 +v 1.358303 -417.528198 2.111643 +v 1.854440 -417.806580 2.111644 +v 1.857711 -417.780457 2.111644 +v 1.517114 -418.653503 2.151594 +v 1.457532 -418.576874 2.133175 +v 1.467558 -418.496735 2.111643 +v 1.260317 -418.472229 2.111643 +v 1.251228 -418.544891 2.131161 +v 1.174607 -418.604431 2.149329 +v 1.088239 -418.593628 2.149170 +v 0.995544 -418.187958 2.111644 +v 1.489467 -418.465118 2.111643 +v 1.546206 -418.420990 2.111643 +v 1.845656 -417.876770 2.111644 +v 1.845750 -417.876007 2.111644 +v 1.004892 -418.113281 2.111644 +v 0.823681 -417.659576 2.149500 +v 0.898639 -417.601288 2.149326 +v 0.994944 -417.613342 2.130904 +v 1.039284 -417.670380 2.111643 +v 1.193198 -417.549011 2.111643 +v 1.143617 -417.485229 2.133181 +v 1.155678 -417.388916 2.151352 +v 1.232304 -417.329346 2.151175 +v 1.299499 -417.573914 2.111643 +v 1.231106 -417.565369 2.111643 +v 0.958717 -418.053009 2.111644 +v 1.004987 -418.112518 2.111644 +v 1.078297 -418.592377 2.151050 +v 1.018720 -418.515778 2.150898 +v 1.030770 -418.419464 2.132468 +v 1.092349 -418.371582 2.111643 +v 0.975143 -418.222656 2.111644 +v 0.916312 -418.268402 2.131539 +v 0.820007 -418.256348 2.149753 +v 0.762060 -418.181793 2.149605 +v 1.107390 -418.359894 2.111643 +v 1.203700 -418.371948 2.111643 +v 1.263278 -418.448578 2.111643 +v 1.469580 -418.480560 2.111643 +v 0.992932 -418.208832 2.111644 +v 0.760430 -418.179718 2.150102 +v 0.772485 -418.083405 2.149900 +v 0.849105 -418.023834 2.131433 +v 0.922653 -418.033051 2.111644 +v 0.944905 -417.843262 2.111643 +v 0.869530 -417.833801 2.131925 +v 0.809958 -417.757172 2.150105 +v 0.822014 -417.660858 2.149902 +v 1.054516 -417.689972 2.111643 +v 1.042460 -417.786285 2.111643 +v 0.965834 -417.845886 2.111643 +v 0.945410 -418.035889 2.111644 +v 1.203188 -417.561859 2.111643 +v 1.579916 -417.951019 2.181988 +v 1.565251 -418.076050 2.181987 +v 1.502066 -417.852112 2.181987 +v 1.466626 -418.153809 2.181988 +v 1.377335 -417.837372 2.181988 +v 1.341895 -418.139069 2.181988 +v 1.278710 -417.915131 2.181988 +v 1.264044 -418.040161 2.181988 +v 1.579916 -417.951019 2.472713 +v 1.565250 -418.076050 2.472713 +v 1.502066 -417.852112 2.472713 +v 1.466626 -418.153809 2.472713 +v 1.377335 -417.837372 2.472713 +v 1.341895 -418.139069 2.472713 +v 1.278710 -417.915131 2.472713 +v 1.264044 -418.040161 2.472713 +v 1.579916 -417.951019 2.670889 +v 1.565250 -418.076050 2.670889 +v 1.502066 -417.852112 2.670889 +v 1.466626 -418.153809 2.670889 +v 1.377335 -417.837372 2.670889 +v 1.341895 -418.139069 2.670889 +v 1.278710 -417.915131 2.670889 +v 1.264044 -418.040161 2.670889 +v 1.729800 -417.909576 2.478335 +v 1.701216 -418.150848 2.478335 +v 1.578068 -417.718719 2.478335 +v 1.508995 -418.300934 2.478335 +v 1.334965 -417.690247 2.478335 +v 1.265893 -418.272461 2.478335 +v 1.142745 -417.840332 2.478335 +v 1.114160 -418.081604 2.478335 +v 1.729800 -417.909576 2.665266 +v 1.701216 -418.150848 2.665266 +v 1.578068 -417.718719 2.665266 +v 1.508995 -418.300934 2.665266 +v 1.334965 -417.690247 2.665266 +v 1.265893 -418.272461 2.665267 +v 1.142745 -417.840332 2.665266 +v 1.114160 -418.081604 2.665266 +v 0.819952 -418.256439 1.954883 +v 0.820142 -418.256104 1.308908 +v 0.916262 -418.268494 1.954939 +v 0.916453 -418.268158 1.308965 +v 0.992888 -418.208923 1.955075 +v 0.993078 -418.208588 1.309101 +v 1.004944 -418.112610 1.955211 +v 1.005134 -418.112274 1.309237 +v 0.945366 -418.035980 1.955268 +v 0.945557 -418.035645 1.309293 +v 0.849056 -418.023926 1.955211 +v 0.849246 -418.023590 1.309237 +v 0.772430 -418.083496 1.955076 +v 0.772620 -418.083160 1.309101 +v 0.760375 -418.179810 1.954939 +v 0.760565 -418.179474 1.308965 +v 0.914653 -418.260895 1.190695 +v 0.823881 -418.249512 1.190642 +v 0.986873 -418.204742 1.190824 +v 0.998235 -418.113953 1.190952 +v 0.942084 -418.041748 1.191005 +v 0.851312 -418.030396 1.190952 +v 0.779092 -418.086517 1.190824 +v 0.767730 -418.177307 1.190695 +v 0.906944 -418.232635 1.138962 +v 0.838378 -418.224030 1.138922 +v 0.961497 -418.190216 1.139059 +v 0.970079 -418.121643 1.139156 +v 0.927664 -418.067078 1.139196 +v 0.859098 -418.058502 1.139156 +v 0.804546 -418.100922 1.139059 +v 0.795964 -418.169495 1.138962 +v 0.895652 -418.191376 1.102039 +v 0.859531 -418.186859 1.102018 +v 0.924390 -418.169037 1.102090 +v 0.928911 -418.132904 1.102141 +v 0.906567 -418.104187 1.102162 +v 0.870446 -418.099640 1.102141 +v 0.841708 -418.122009 1.102090 +v 0.837187 -418.158112 1.102039 +v 1.078243 -418.592499 1.954883 +v 1.078433 -418.592163 1.308908 +v 1.174553 -418.604553 1.954939 +v 1.174743 -418.604218 1.308965 +v 1.251179 -418.544952 1.955075 +v 1.251369 -418.544617 1.309101 +v 1.263234 -418.448639 1.955211 +v 1.263424 -418.448334 1.309237 +v 1.203657 -418.372040 1.955268 +v 1.203847 -418.371704 1.309293 +v 1.107347 -418.359985 1.955211 +v 1.107537 -418.359650 1.309237 +v 1.030721 -418.419556 1.955075 +v 1.030911 -418.419220 1.309101 +v 1.018665 -418.515869 1.954939 +v 1.018856 -418.515533 1.308965 +v 1.172944 -418.596954 1.190695 +v 1.082172 -418.585571 1.190642 +v 1.245164 -418.540802 1.190824 +v 1.256526 -418.450012 1.190952 +v 1.200374 -418.377808 1.191005 +v 1.109602 -418.366425 1.190952 +v 1.037382 -418.422577 1.190824 +v 1.026020 -418.513367 1.190695 +v 1.165235 -418.568665 1.138962 +v 1.096669 -418.560089 1.138922 +v 1.219787 -418.526276 1.139059 +v 1.228370 -418.457703 1.139156 +v 1.185955 -418.403137 1.139196 +v 1.117389 -418.394562 1.139156 +v 1.062837 -418.436981 1.139059 +v 1.054254 -418.505554 1.138962 +v 1.153942 -418.527435 1.102039 +v 1.117822 -418.522919 1.102018 +v 1.182680 -418.505096 1.102090 +v 1.187201 -418.468964 1.102141 +v 1.164857 -418.440216 1.102162 +v 1.128737 -418.435699 1.102141 +v 1.099999 -418.458069 1.102090 +v 1.095478 -418.494171 1.102039 +v 1.517059 -418.653595 1.954883 +v 1.517249 -418.653259 1.308908 +v 1.613369 -418.665649 1.954939 +v 1.613559 -418.665314 1.308965 +v 1.689995 -418.606079 1.955075 +v 1.690186 -418.605743 1.309101 +v 1.702051 -418.509766 1.955211 +v 1.702241 -418.509430 1.309237 +v 1.642473 -418.433136 1.955268 +v 1.642663 -418.432800 1.309293 +v 1.546163 -418.421082 1.955211 +v 1.546353 -418.420746 1.309237 +v 1.469537 -418.480652 1.955075 +v 1.469727 -418.480316 1.309101 +v 1.457482 -418.576965 1.954939 +v 1.457672 -418.576630 1.308965 +v 1.611760 -418.658051 1.190695 +v 1.520988 -418.646667 1.190642 +v 1.683980 -418.601898 1.190824 +v 1.695342 -418.511108 1.190952 +v 1.639191 -418.438904 1.191005 +v 1.548419 -418.427551 1.190952 +v 1.476199 -418.483673 1.190824 +v 1.464836 -418.574463 1.190695 +v 1.604051 -418.629791 1.138962 +v 1.535485 -418.621185 1.138922 +v 1.658603 -418.587372 1.139059 +v 1.667186 -418.518799 1.139156 +v 1.624771 -418.464233 1.139196 +v 1.556205 -418.455658 1.139156 +v 1.501653 -418.498077 1.139059 +v 1.493070 -418.566650 1.138962 +v 1.592759 -418.588531 1.102039 +v 1.556638 -418.584015 1.102018 +v 1.621497 -418.566193 1.102090 +v 1.626018 -418.530060 1.102141 +v 1.603674 -418.501343 1.102162 +v 1.567553 -418.496826 1.102141 +v 1.538815 -418.519165 1.102090 +v 1.534294 -418.555267 1.102039 +v 1.853115 -418.375854 1.954883 +v 1.853305 -418.375519 1.308908 +v 1.949425 -418.387909 1.954939 +v 1.949615 -418.387573 1.308965 +v 2.026051 -418.328339 1.955075 +v 2.026241 -418.328003 1.309101 +v 2.038106 -418.232025 1.955211 +v 2.038296 -418.231689 1.309237 +v 1.978529 -418.155396 1.955268 +v 1.978719 -418.155060 1.309293 +v 1.882219 -418.143341 1.955211 +v 1.882409 -418.143005 1.309237 +v 1.805593 -418.202911 1.955075 +v 1.805783 -418.202576 1.309101 +v 1.793537 -418.299225 1.954939 +v 1.793727 -418.298889 1.308965 +v 1.947816 -418.380310 1.190695 +v 1.857044 -418.368958 1.190642 +v 2.020036 -418.324158 1.190824 +v 2.031398 -418.233398 1.190952 +v 1.975246 -418.161163 1.191005 +v 1.884474 -418.149811 1.190952 +v 1.812254 -418.205963 1.190824 +v 1.800892 -418.296722 1.190695 +v 1.940107 -418.352051 1.138962 +v 1.871541 -418.343475 1.138922 +v 1.994659 -418.309631 1.139059 +v 2.003242 -418.241058 1.139156 +v 1.960827 -418.186523 1.139196 +v 1.892261 -418.177917 1.139156 +v 1.837708 -418.220337 1.139059 +v 1.829126 -418.288910 1.138962 +v 1.928814 -418.310791 1.102039 +v 1.892694 -418.306274 1.102018 +v 1.957552 -418.288452 1.102090 +v 1.962073 -418.252350 1.102141 +v 1.939729 -418.223602 1.102162 +v 1.903609 -418.219086 1.102141 +v 1.874871 -418.241425 1.102090 +v 1.870349 -418.277557 1.102039 +v 0.869481 -417.833893 1.954883 +v 0.869671 -417.833557 1.308908 +v 0.965791 -417.845947 1.954939 +v 0.965981 -417.845612 1.308965 +v 1.042417 -417.786377 1.955075 +v 1.042607 -417.786041 1.309101 +v 1.054472 -417.690063 1.955211 +v 1.054663 -417.689728 1.309237 +v 0.994895 -417.613434 1.955268 +v 0.995085 -417.613098 1.309293 +v 0.898585 -417.601379 1.955211 +v 0.898775 -417.601044 1.309237 +v 0.821959 -417.660950 1.955075 +v 0.822149 -417.660614 1.309101 +v 0.809904 -417.757263 1.954939 +v 0.810094 -417.756927 1.308965 +v 0.964182 -417.838348 1.190695 +v 0.873410 -417.826996 1.190642 +v 1.036402 -417.782196 1.190824 +v 1.047764 -417.691437 1.190952 +v 0.991613 -417.619202 1.191005 +v 0.900840 -417.607849 1.190952 +v 0.828620 -417.664001 1.190824 +v 0.817258 -417.754761 1.190695 +v 0.956473 -417.810089 1.138962 +v 0.887907 -417.801514 1.138922 +v 1.011025 -417.767670 1.139059 +v 1.019608 -417.699097 1.139156 +v 0.977193 -417.644562 1.139196 +v 0.908627 -417.635956 1.139156 +v 0.854075 -417.678375 1.139059 +v 0.845492 -417.746948 1.138962 +v 0.945180 -417.768829 1.102039 +v 0.909060 -417.764313 1.102018 +v 0.973918 -417.746490 1.102090 +v 0.978440 -417.710388 1.102141 +v 0.956096 -417.681641 1.102162 +v 0.919975 -417.677124 1.102141 +v 0.891237 -417.699463 1.102090 +v 0.886716 -417.735596 1.102039 +v 1.203145 -417.561951 1.954883 +v 1.203335 -417.561615 1.308908 +v 1.299455 -417.574005 1.954939 +v 1.299645 -417.573669 1.308965 +v 1.376081 -417.514435 1.955076 +v 1.376271 -417.514099 1.309101 +v 1.388136 -417.418121 1.955211 +v 1.388327 -417.417786 1.309237 +v 1.328559 -417.341492 1.955268 +v 1.328749 -417.341156 1.309293 +v 1.232249 -417.329437 1.955211 +v 1.232439 -417.329102 1.309237 +v 1.155623 -417.389008 1.955075 +v 1.155813 -417.388672 1.309101 +v 1.143568 -417.485321 1.954939 +v 1.143758 -417.484985 1.308965 +v 1.297846 -417.566406 1.190696 +v 1.207074 -417.555054 1.190642 +v 1.370066 -417.510254 1.190824 +v 1.381428 -417.419464 1.190952 +v 1.325277 -417.347260 1.191005 +v 1.234504 -417.335907 1.190952 +v 1.162284 -417.392059 1.190824 +v 1.150922 -417.482819 1.190696 +v 1.290137 -417.538147 1.138962 +v 1.221571 -417.529541 1.138922 +v 1.344689 -417.495728 1.139059 +v 1.353272 -417.427155 1.139156 +v 1.310857 -417.372620 1.139196 +v 1.242291 -417.364014 1.139156 +v 1.187739 -417.406433 1.139059 +v 1.179156 -417.475006 1.138962 +v 1.278844 -417.496887 1.102039 +v 1.242724 -417.492371 1.102018 +v 1.307582 -417.474548 1.102090 +v 1.312104 -417.438416 1.102141 +v 1.289760 -417.409698 1.102162 +v 1.253639 -417.405182 1.102141 +v 1.224901 -417.427521 1.102090 +v 1.220380 -417.463623 1.102039 +v 1.905190 -417.953461 1.954883 +v 1.905380 -417.953125 1.308908 +v 2.001500 -417.965515 1.954939 +v 2.001690 -417.965179 1.308965 +v 2.078126 -417.905945 1.955076 +v 2.078316 -417.905609 1.309101 +v 2.090181 -417.809631 1.955211 +v 2.090371 -417.809296 1.309237 +v 2.030604 -417.733002 1.955268 +v 2.030794 -417.732666 1.309293 +v 1.934294 -417.720947 1.955211 +v 1.934484 -417.720612 1.309237 +v 1.857667 -417.780548 1.955075 +v 1.857857 -417.780212 1.309101 +v 1.845612 -417.876831 1.954939 +v 1.845802 -417.876526 1.308965 +v 1.999891 -417.957916 1.190695 +v 1.909118 -417.946564 1.190642 +v 2.072111 -417.901764 1.190824 +v 2.083473 -417.811005 1.190952 +v 2.027321 -417.738770 1.191005 +v 1.936549 -417.727417 1.190952 +v 1.864329 -417.783569 1.190824 +v 1.852967 -417.874359 1.190695 +v 1.992182 -417.929657 1.138962 +v 1.923616 -417.921082 1.138922 +v 2.046734 -417.887238 1.139059 +v 2.055316 -417.818695 1.139156 +v 2.012902 -417.764130 1.139196 +v 1.944335 -417.755554 1.139156 +v 1.889783 -417.797974 1.139059 +v 1.881201 -417.866516 1.138962 +v 1.980889 -417.888428 1.102039 +v 1.944768 -417.883911 1.102018 +v 2.009627 -417.866089 1.102090 +v 2.014148 -417.829956 1.102141 +v 1.991804 -417.801208 1.102162 +v 1.955684 -417.796692 1.102141 +v 1.926946 -417.819031 1.102090 +v 1.922424 -417.855164 1.102039 +v 1.639030 -417.615936 1.954883 +v 1.639220 -417.615601 1.308908 +v 1.735340 -417.627991 1.954939 +v 1.735530 -417.627686 1.308965 +v 1.811966 -417.568420 1.955075 +v 1.812156 -417.568085 1.309101 +v 1.824021 -417.472107 1.955211 +v 1.824211 -417.471771 1.309237 +v 1.764444 -417.395477 1.955268 +v 1.764634 -417.395172 1.309293 +v 1.668134 -417.383423 1.955211 +v 1.668324 -417.383087 1.309237 +v 1.591508 -417.443024 1.955075 +v 1.591698 -417.442688 1.309101 +v 1.579452 -417.539337 1.954939 +v 1.579643 -417.539001 1.308965 +v 1.733731 -417.620392 1.190695 +v 1.642958 -417.609039 1.190642 +v 1.805951 -417.564240 1.190824 +v 1.817313 -417.473480 1.190952 +v 1.761161 -417.401276 1.191005 +v 1.670389 -417.389893 1.190952 +v 1.598169 -417.446045 1.190824 +v 1.586807 -417.536835 1.190695 +v 1.726022 -417.592133 1.138962 +v 1.657456 -417.583557 1.138922 +v 1.780574 -417.549713 1.139059 +v 1.789156 -417.481171 1.139156 +v 1.746742 -417.426605 1.139196 +v 1.678176 -417.418030 1.139156 +v 1.623623 -417.460449 1.139059 +v 1.615041 -417.529022 1.138962 +v 1.714729 -417.550903 1.102039 +v 1.678609 -417.546387 1.102018 +v 1.743467 -417.528564 1.102090 +v 1.747988 -417.492432 1.102141 +v 1.725644 -417.463684 1.102162 +v 1.689524 -417.459167 1.102141 +v 1.660786 -417.481506 1.102090 +v 1.656265 -417.517639 1.102039 +v -0.207699 1.575944 2.276923 +v -0.207699 1.377246 2.201197 +v -0.207699 2.066770 2.023149 +v -0.207699 2.067397 1.765164 +v 0.214448 1.575944 2.276923 +v 0.214448 1.377246 2.201197 +v 0.214448 2.066770 2.023149 +v 0.214448 2.067398 1.765164 +v -0.168019 2.051357 2.179056 +v -0.168019 1.786627 2.268374 +v 0.174768 2.051357 2.179055 +v 0.174768 1.786627 2.268374 +v -0.096670 2.118635 2.263391 +v -0.096670 1.968073 2.380735 +v 0.103419 2.118635 2.263391 +v 0.103419 1.968074 2.380735 +v -0.096670 2.182016 2.453872 +v -0.096670 2.074292 2.501152 +v 0.103419 2.182016 2.453872 +v 0.103418 2.074292 2.501152 +v -0.077948 2.212064 2.671061 +v -0.077948 2.111795 2.625241 +v 0.084697 2.212064 2.671061 +v 0.084697 2.111795 2.625241 +v -0.207699 1.275600 2.102187 +v -0.207699 1.654069 1.442971 +v 0.214448 1.654069 1.442971 +v 0.214448 1.275600 2.102187 +v -0.154561 0.049668 1.627178 +v -0.154561 0.518361 1.627178 +v -0.154561 0.049668 0.996165 +v -0.154561 0.518361 0.810161 +v 0.161309 0.049668 1.627178 +v 0.161309 0.518361 1.627178 +v 0.161309 0.049668 0.996165 +v 0.161309 0.518361 0.810161 +v -0.124871 -0.099135 1.078007 +v -0.124871 -0.099135 1.284931 +v 0.131619 -0.099135 1.078007 +v 0.131619 -0.099135 1.284931 +v -0.071484 -0.285139 1.092887 +v -0.071484 -0.344660 1.210530 +v 0.078232 -0.285139 1.092887 +v 0.078232 -0.344660 1.210530 +v -0.071484 -0.486693 1.011302 +v -0.071484 -0.544873 1.113551 +v 0.078232 -0.486693 1.011302 +v 0.078232 -0.544873 1.113551 +v -0.057475 -0.600966 0.864162 +v -0.057475 -0.715705 0.890141 +v 0.064223 -0.600966 0.864162 +v 0.064223 -0.715705 0.890141 +v -0.057475 -0.659991 0.701108 +v -0.057475 -0.730516 0.727087 +v 0.064223 -0.659991 0.701108 +v 0.064223 -0.730516 0.727087 +v 0.327798 -2.208930 4.754399 +v 0.327798 -0.716681 4.391720 +v 0.346943 -2.233109 3.141257 +v 0.346944 -0.958467 2.839025 +v 0.307796 -2.474473 4.613307 +v 0.307796 -2.498651 3.338665 +v 0.346944 -0.578481 2.564628 +v 0.327798 0.376574 3.754644 +v 0.390975 -0.470463 2.293747 +v 0.461002 0.950702 3.564065 +v 0.390975 0.290471 2.334551 +v 0.390975 0.823812 2.784925 +v 0.524178 1.065577 3.302306 +v 0.391189 1.231892 3.414718 +v 0.391189 1.154141 3.565106 +v 0.392289 -0.166541 1.791495 +v 0.394361 0.033233 1.611265 +v 0.392503 1.370408 2.761702 +v 0.394575 1.579904 2.447618 +v 0.396902 0.129975 1.472794 +v 0.397116 2.345484 1.641503 +v 0.407129 0.138360 -0.846234 +v 0.407343 2.278266 -0.827582 +v 0.398307 2.048724 1.379464 +v 0.398144 0.591875 1.328338 +v 0.405938 0.603870 -0.416180 +v 0.406101 2.044246 -0.398157 +v 0.400450 2.376793 0.539767 +v 0.397297 2.464155 1.485852 +v 0.400631 2.457479 0.731364 +v 0.408242 1.050728 -1.058142 +v 0.408456 2.279828 -1.039490 +v 0.426697 1.095856 -4.574149 +v 0.426911 2.324956 -4.555498 +v 0.086946 2.713566 -3.793732 +v 0.288234 1.528182 -4.853699 +v 0.288448 2.220798 -4.835049 +v 0.420357 2.308929 -3.306850 +v 0.420143 1.079830 -3.325501 +v 0.086946 2.536002 -4.604102 +v 0.086946 2.519001 -3.712513 +v 0.086946 2.729592 -4.565253 +v 0.384992 2.521843 -4.600842 +v 0.378438 2.505816 -3.684169 +v 0.310892 -0.493544 2.037120 +v 0.312206 -0.374907 1.850693 +v 0.274445 -0.655319 1.891294 +v 0.275759 -0.604058 1.793298 +v 0.274445 -0.894987 1.729578 +v 0.275759 -0.817614 1.650557 +v 0.274445 -1.029853 1.435535 +v 0.275759 -0.925006 1.400350 +v 0.274445 -1.023998 0.930551 +v 0.275759 -0.919626 0.967119 +v 0.274445 -0.886209 0.409688 +v 0.275759 -0.793265 0.469624 +v 0.274445 -0.682159 0.094696 +v 0.275759 -0.600533 0.169317 +v 0.274445 -0.360679 -0.039406 +v 0.275759 -0.352339 0.070873 +v 0.310892 -0.199671 -0.051582 +v 0.312206 -0.191330 0.058696 +v 0.390975 0.007782 -0.231501 +v 0.392289 0.016123 0.215658 +v 0.405546 0.139784 -0.501530 +v 0.401145 0.143744 0.456716 +v 0.553461 -0.917234 2.963436 +v 0.553461 -2.061486 3.247707 +v 0.553461 -0.662863 4.253574 +v 0.553461 -2.002257 4.593763 +v 0.553461 -2.325967 4.501239 +v 0.553461 -2.377350 3.437765 +v 0.553461 -0.580390 2.724838 +v 0.553461 0.309799 3.694322 +v 0.553461 -0.408506 2.495996 +v 0.553461 0.921622 3.299428 +v 0.553461 0.823934 3.520827 +v 0.553461 0.199115 2.510977 +v 0.553461 0.691268 2.873578 +v 0.553461 -1.068700 3.110918 +v 0.553461 -2.004948 3.324914 +v 0.553461 -0.860569 4.166533 +v 0.553461 -1.956487 4.463483 +v 0.553461 -2.260805 4.353958 +v 0.553461 -2.302846 3.483804 +v 0.553461 -0.613285 2.872293 +v 0.553461 -0.089519 3.708943 +v 0.553461 -0.216486 3.199586 +v 0.616597 -1.068700 3.110918 +v 0.616597 -2.004948 3.324914 +v 0.616597 -0.860569 4.166533 +v 0.616597 -1.956486 4.463483 +v 0.616597 -2.260805 4.353958 +v 0.616597 -2.302846 3.483804 +v 0.616597 -0.216486 3.199586 +v 0.616597 -0.089519 3.708943 +v 0.616597 -0.613285 2.872292 +v 0.553461 -0.072575 3.474638 +v 0.616597 -0.071885 3.477406 +v 0.616597 -0.432995 2.949241 +v 0.553461 -0.444036 2.940134 +v 0.463133 -0.030825 1.718573 +v 0.463322 1.329667 2.577390 +v 0.491646 1.515110 2.303495 +v 0.496734 0.139450 1.570141 +v 0.499172 2.192795 1.585802 +v 0.498983 0.229629 1.447062 +v 0.508225 2.183270 -0.599809 +v 0.508035 0.277059 -0.660639 +v 0.509210 2.134677 -0.787387 +v 0.502124 2.228142 0.610555 +v 0.499497 2.095359 1.437874 +v 0.499321 0.531138 1.380567 +v 0.507711 0.542508 -0.454876 +v 0.507886 2.088999 -0.435325 +v 0.509021 1.046690 -0.734252 +v 0.502738 0.275494 0.537040 +v 0.506634 0.240331 -0.311189 +v 0.399127 0.211062 0.939993 +v 0.500238 0.506193 1.171448 +v 0.398906 0.568644 1.150162 +v 0.499349 0.788084 1.433965 +v 0.398167 0.808099 1.379500 +v 0.499475 1.955023 1.466469 +v 0.398289 1.947401 1.410191 +v 0.500599 2.120420 1.205646 +v 0.399225 2.072451 1.193758 +v 0.496862 1.130362 2.175035 +v 0.499030 0.718880 1.481638 +v 0.496848 0.918637 2.075178 +v 0.498128 0.731128 1.727061 +v 0.497912 1.915694 1.980421 +v 0.396325 2.223080 1.903162 +v 0.507735 0.759755 -0.489189 +v 0.405955 0.761960 -0.451159 +v 0.405075 0.575647 -0.328302 +v 0.506844 0.513860 -0.336452 +v 0.406081 1.927327 -0.439212 +v 0.507864 1.923738 -0.475699 +v 0.506891 2.117700 -0.229250 +v 0.405148 2.069939 -0.222753 +v 0.407815 0.700769 -0.860784 +v 0.408057 0.931032 -0.920025 +v 0.562712 1.986673 -1.037983 +v 0.562498 1.437475 -1.056635 +v 0.574613 1.999677 -3.305343 +v 0.581167 2.006838 -4.553992 +v 0.580953 1.457640 -4.572642 +v 0.574399 1.450479 -3.323994 +v 0.443766 1.967718 -4.833541 +v 0.443552 1.740314 -4.852193 +v 0.509084 1.410384 -0.752014 +v 0.509184 1.986889 -0.780169 +v 0.145497 1.685500 -4.849789 +v 0.145617 2.056011 -4.839358 +v 0.235251 1.780435 -4.848947 +v 0.235370 1.939171 -4.838516 +v 0.131902 1.652315 -1.479100 +v 0.132022 2.022826 -1.468670 +v 0.221656 1.747250 -1.478259 +v 0.221776 1.905986 -1.467828 +v -0.327807 -2.208930 4.754399 +v -0.327806 -0.716681 4.391720 +v -0.346952 -2.233109 3.141257 +v -0.346952 -0.958467 2.839025 +v -0.000004 -0.958467 2.839025 +v -0.000004 -2.233109 3.141257 +v -0.000004 -0.716681 4.391720 +v -0.000004 -2.208931 4.754399 +v -0.307804 -2.474473 4.613307 +v -0.307804 -2.498652 3.338666 +v -0.000004 -2.474473 4.613307 +v -0.000004 -2.498652 3.338666 +v -0.000004 -0.578481 2.564628 +v -0.346952 -0.578481 2.564628 +v -0.327806 0.376574 3.754644 +v -0.000004 0.376574 3.754645 +v -0.000004 -0.470463 2.293747 +v -0.390983 -0.470463 2.293747 +v -0.461009 0.950702 3.564065 +v -0.000004 0.950702 3.564065 +v -0.390983 0.290471 2.334551 +v -0.390983 0.823812 2.784925 +v -0.524186 1.065577 3.302307 +v -0.391196 1.231892 3.414718 +v -0.391196 1.154141 3.565106 +v -0.000004 1.154141 3.565106 +v -0.000004 1.234869 3.409686 +v -0.000004 -0.166541 1.791495 +v -0.392297 -0.166541 1.791495 +v -0.394369 0.033233 1.611265 +v -0.000004 0.033233 1.611265 +v -0.000004 1.373384 2.756670 +v -0.392510 1.370408 2.761702 +v -0.000004 1.582880 2.442587 +v -0.394582 1.579904 2.447618 +v -0.000004 0.129975 1.472794 +v -0.396910 0.129975 1.472794 +v -0.397124 2.345484 1.641503 +v -0.000004 2.346644 1.635773 +v -0.000004 0.138360 -0.846234 +v -0.407136 0.138360 -0.846234 +v -0.407350 2.278265 -0.827583 +v -0.000004 2.279397 -0.833318 +v -0.398314 2.048724 1.379464 +v -0.398152 0.591875 1.328338 +v -0.405945 0.603870 -0.416180 +v -0.406108 2.044246 -0.398157 +v -0.000004 2.048884 1.376907 +v -0.000004 0.592035 1.325781 +v -0.000004 0.603934 -0.418741 +v -0.000004 2.044310 -0.400719 +v -0.000004 2.377788 0.516571 +v -0.400458 2.376792 0.539766 +v -0.000004 2.465315 1.480121 +v -0.397304 2.464155 1.485852 +v -0.400639 2.457479 0.731364 +v -0.000004 2.458475 0.708169 +v -0.000004 1.050728 -1.058142 +v -0.408249 1.050728 -1.058141 +v -0.408463 2.279828 -1.039490 +v -0.000004 2.280960 -1.045226 +v -0.000004 1.095856 -4.574149 +v -0.426704 1.095856 -4.574149 +v -0.426918 2.324956 -4.555498 +v -0.086953 2.713566 -3.793731 +v -0.000004 1.447318 -4.853699 +v -0.288241 1.528182 -4.853700 +v -0.288455 2.220798 -4.835048 +v -0.000004 2.294426 -4.840782 +v -0.420364 2.308929 -3.306850 +v -0.000004 1.079830 -3.325501 +v -0.420151 1.079830 -3.325501 +v -0.000004 2.310061 -3.312585 +v -0.000004 2.537133 -4.609838 +v -0.086953 2.536002 -4.604102 +v -0.086953 2.519001 -3.712513 +v -0.000003 2.730724 -4.570990 +v -0.086953 2.729592 -4.565253 +v -0.000004 2.521107 -3.717038 +v -0.000003 2.714698 -3.799466 +v -0.385000 2.521843 -4.600842 +v -0.378446 2.505816 -3.684168 +v -0.000004 -0.493544 2.037120 +v -0.310900 -0.493544 2.037121 +v -0.000004 -0.374907 1.850693 +v -0.312214 -0.374907 1.850694 +v -0.000004 -0.655319 1.891294 +v -0.274453 -0.655319 1.891294 +v -0.000004 -0.604058 1.793298 +v -0.275767 -0.604058 1.793298 +v -0.000004 -0.894987 1.729578 +v -0.274453 -0.894987 1.729578 +v -0.000004 -0.817614 1.650557 +v -0.275767 -0.817614 1.650557 +v -0.000004 -1.029853 1.435535 +v -0.274453 -1.029853 1.435535 +v -0.000004 -0.925006 1.400350 +v -0.275767 -0.925006 1.400350 +v -0.000004 -1.023998 0.930551 +v -0.274453 -1.023998 0.930551 +v -0.000004 -0.919626 0.967119 +v -0.275767 -0.919626 0.967119 +v -0.000004 -0.886209 0.409688 +v -0.274453 -0.886209 0.409688 +v -0.000004 -0.793265 0.469624 +v -0.275767 -0.793265 0.469624 +v -0.000004 -0.682159 0.094696 +v -0.274453 -0.682159 0.094696 +v -0.000004 -0.600533 0.169317 +v -0.275767 -0.600533 0.169317 +v -0.000004 -0.360679 -0.039405 +v -0.274453 -0.360679 -0.039405 +v -0.000004 -0.352339 0.070873 +v -0.275767 -0.352339 0.070873 +v -0.000004 -0.199671 -0.051582 +v -0.310900 -0.199671 -0.051582 +v -0.000004 -0.191330 0.058696 +v -0.312214 -0.191330 0.058696 +v -0.000004 0.007782 -0.231501 +v -0.390983 0.007782 -0.231501 +v -0.000004 0.016123 0.215658 +v -0.392297 0.016123 0.215658 +v -0.000004 0.139812 -0.494788 +v -0.405553 0.139784 -0.501530 +v -0.000004 0.143715 0.449643 +v -0.401152 0.143744 0.456717 +v -0.553469 -0.917234 2.963436 +v -0.553469 -2.061486 3.247707 +v -0.553469 -0.662863 4.253574 +v -0.553469 -2.002257 4.593763 +v -0.553469 -2.325967 4.501239 +v -0.553469 -2.377350 3.437765 +v -0.553469 -0.580391 2.724838 +v -0.553469 0.309799 3.694322 +v -0.553469 -0.408506 2.495996 +v -0.553469 0.921623 3.299428 +v -0.553469 0.823934 3.520827 +v -0.553469 0.199115 2.510977 +v -0.553469 0.691268 2.873578 +v -0.553469 -1.068700 3.110918 +v -0.553469 -2.004948 3.324914 +v -0.553469 -0.860569 4.166533 +v -0.553469 -1.956486 4.463484 +v -0.553469 -2.260805 4.353959 +v -0.553469 -2.302846 3.483804 +v -0.553469 -0.613285 2.872293 +v -0.553469 -0.089519 3.708943 +v -0.553469 -0.216486 3.199586 +v -0.616606 -1.068700 3.110918 +v -0.616605 -2.004948 3.324914 +v -0.616605 -0.860569 4.166533 +v -0.616606 -1.956487 4.463483 +v -0.616606 -2.260805 4.353959 +v -0.616606 -2.302847 3.483804 +v -0.616605 -0.216486 3.199586 +v -0.616605 -0.089519 3.708943 +v -0.616605 -0.613285 2.872293 +v -0.553469 -0.072575 3.474638 +v -0.616605 -0.071885 3.477406 +v -0.616605 -0.432995 2.949242 +v -0.553469 -0.444036 2.940135 +v -0.463141 -0.030825 1.718573 +v -0.463330 1.329667 2.577390 +v -0.491654 1.515110 2.303495 +v -0.496741 0.139450 1.570141 +v -0.499180 2.192795 1.585802 +v -0.498991 0.229629 1.447062 +v -0.508232 2.183270 -0.599809 +v -0.508043 0.277059 -0.660638 +v -0.509218 2.134677 -0.787387 +v -0.502131 2.228142 0.610555 +v -0.499504 2.095358 1.437874 +v -0.499329 0.531138 1.380567 +v -0.507719 0.542508 -0.454876 +v -0.507894 2.089000 -0.435325 +v -0.509028 1.046690 -0.734252 +v -0.502746 0.275494 0.537040 +v -0.506642 0.240331 -0.311189 +v -0.399135 0.211062 0.939993 +v -0.000004 0.210765 0.957244 +v -0.500245 0.506193 1.171448 +v -0.000004 0.568480 1.152056 +v -0.398914 0.568644 1.150162 +v -0.499357 0.788084 1.433965 +v -0.000004 0.815310 1.374564 +v -0.398175 0.808099 1.379500 +v -0.000004 1.947883 1.409432 +v -0.499482 1.955023 1.466469 +v -0.398297 1.947401 1.410191 +v -0.500607 2.120420 1.205646 +v -0.000004 2.072877 1.196720 +v -0.399232 2.072451 1.193759 +v -0.496870 1.130362 2.175036 +v -0.499038 0.718880 1.481638 +v -0.496856 0.918637 2.075178 +v -0.498136 0.731128 1.727061 +v -0.497920 1.915694 1.980421 +v -0.396332 2.223080 1.903162 +v -0.000004 2.224877 1.897575 +v -0.000004 0.762842 -0.455298 +v -0.507742 0.759755 -0.489189 +v -0.405962 0.761960 -0.451159 +v -0.405082 0.575647 -0.328302 +v -0.000004 0.577274 -0.340096 +v -0.506851 0.513860 -0.336452 +v -0.000004 1.936799 -0.441149 +v -0.406088 1.927327 -0.439212 +v -0.507871 1.923738 -0.475699 +v -0.000004 2.068799 -0.231182 +v -0.506898 2.117700 -0.229250 +v -0.405155 2.069939 -0.222753 +v -0.000004 0.685554 -0.857250 +v -0.407822 0.700769 -0.860783 +v -0.000004 0.909250 -0.910134 +v -0.408065 0.931031 -0.920025 +v -0.562719 1.986673 -1.037984 +v -0.562505 1.437475 -1.056635 +v -0.574620 1.999677 -3.305343 +v -0.581174 2.006838 -4.553991 +v -0.580960 1.457640 -4.572643 +v -0.574406 1.450479 -3.323994 +v -0.443773 1.967718 -4.833541 +v -0.443559 1.740314 -4.852192 +v -0.509092 1.410385 -0.752014 +v -0.509192 1.986889 -0.780169 +v -0.000004 1.642242 -4.849789 +v -0.145504 1.685500 -4.849789 +v -0.145624 2.056011 -4.839358 +v -0.000003 2.095398 -4.842566 +v -0.235258 1.780435 -4.848948 +v -0.235377 1.939171 -4.838517 +v -0.000004 1.609057 -1.479100 +v -0.131910 1.652315 -1.479100 +v -0.132029 2.022826 -1.468669 +v -0.000004 2.062213 -1.471878 +v -0.221663 1.747250 -1.478258 +v -0.221783 1.905986 -1.467827 +v 0.126086 2.001926 0.879574 +v 0.137201 1.997183 0.914388 +v 0.174789 1.876642 0.914066 +v 0.165534 1.867546 0.879214 +v 0.000865 2.053442 1.003767 +v 0.201886 1.903474 0.941709 +v 0.126086 2.005370 -0.407826 +v 0.165534 1.870990 -0.408186 +v 0.280723 1.832324 0.913947 +v 0.280677 1.819375 0.879086 +v 0.169747 1.983493 0.941923 +v 0.000865 2.057218 -0.407688 +v 0.280858 1.870436 0.941621 +v 0.135036 1.905481 -0.408093 +v 0.100130 1.990601 -0.407866 +v 0.002022 2.031646 -0.407756 +v 0.280677 1.822819 -0.408315 +v 0.392948 1.890188 0.914102 +v 0.217623 1.963401 0.965074 +v -0.124718 2.002813 0.879576 +v 0.230551 1.931876 0.964990 +v 0.281001 1.910770 0.964933 +v 0.360401 1.903730 0.941710 +v 0.131654 1.871109 -0.408185 +v 0.140480 1.892206 -0.408129 +v 0.287370 1.799656 -0.408377 +v 0.254844 1.721910 -0.408585 +v 0.077832 1.785240 -0.408415 +v 0.099435 1.794099 -0.408391 +v 0.404063 1.885631 0.879262 +v 0.404063 1.889074 -0.408138 +v 0.249057 1.950239 0.969596 +v -0.135867 1.998148 0.914391 +v -0.124718 2.006257 -0.407824 +v 0.281093 1.936836 0.969560 +v 0.288537 1.802446 -0.408369 +v 0.029157 1.765280 -0.408469 +v 0.394284 1.860367 -0.408214 +v 0.518848 1.841053 -0.408266 +v 0.518848 1.837277 1.003189 +v -0.168508 1.984689 0.941927 +v -0.165116 1.868715 0.879218 +v -0.165116 1.872159 -0.408183 +v 0.312526 1.923697 0.964968 +v -0.096373 1.991296 -0.407864 +v 0.295888 1.820018 -0.408322 +v 0.295193 1.623516 -0.408848 +v 0.393301 1.582471 -0.408958 +v 0.424537 1.324938 -0.409647 +v 0.464887 1.226543 -0.409909 +v 0.384741 1.059173 -0.410357 +v 0.293064 1.021579 -0.410458 +v 0.252020 0.923471 -0.410720 +v 0.292369 0.825076 -0.411012 +v 0.274404 0.828754 -0.410974 +v 0.158924 0.781398 -0.411100 +v 0.136495 0.765580 -0.411184 +v 0.096145 0.863975 -0.410879 +v -0.001962 0.905019 -0.410770 +v -0.298100 1.025570 -0.410447 +v -0.396208 1.066615 -0.410337 +v -0.457912 1.251323 -0.409843 +v -0.427444 1.324149 -0.409648 +v -0.467794 1.422543 -0.409385 +v -0.565901 1.463588 -0.409277 +v -0.536230 1.485766 -0.409216 +v -0.488058 1.600908 -0.408908 +v -0.492474 1.628202 -0.408886 +v -0.394367 1.587158 -0.408945 +v -0.295972 1.627507 -0.408837 +v -0.254926 1.725615 -0.408575 +v -0.073822 1.785069 -0.408416 +v 0.001040 1.753750 -0.408499 +v 0.492391 1.819323 -0.408324 +v 0.000855 2.049644 1.327071 +v 0.516874 1.834345 1.326496 +v -0.216524 1.964937 0.965078 +v -0.201212 1.904900 0.941713 +v -0.174306 1.877877 0.914069 +v -0.137417 1.893189 -0.408126 +v -0.280596 1.824804 -0.408309 +v -0.280596 1.821360 0.879091 +v 0.562995 1.185498 -0.410087 +v 0.535157 1.163218 -0.410079 +v 0.486985 1.048076 -0.410387 +v 0.489567 1.020884 -0.410514 +v 0.391460 1.061928 -0.410350 +v 0.274404 0.825310 0.876427 +v 0.158924 0.777955 0.876300 +v -0.100357 0.864670 -0.410877 +v -0.257750 0.927175 -0.410710 +v -0.494603 1.026265 -0.410495 +v -0.492381 1.051540 -0.410378 +v -0.539736 1.167020 -0.410069 +v -0.566884 1.185692 -0.410020 +v -0.468489 1.226042 -0.409911 +v -0.536230 1.482323 0.878185 +v -0.488058 1.597465 0.878492 +v -0.295277 1.824009 -0.408338 +v 0.566224 1.722079 0.878825 +v 0.566224 1.725523 -0.408575 +v -0.518633 1.840947 1.003199 +v -0.516674 1.838000 1.326506 +v 0.000727 2.013459 1.335898 +v 0.003156 2.014437 1.335410 +v 0.092439 1.976363 1.335511 +v 0.128657 1.886251 1.353739 +v 0.097071 1.812096 1.375046 +v 0.273583 1.738451 1.374850 +v 0.304891 1.811956 1.353729 +v 0.394938 1.848222 1.335644 +v 0.484221 1.810148 1.335745 +v 0.486569 1.804307 1.336926 +v 0.728523 1.318226 1.325116 +v 0.731349 1.319081 1.001804 +v -0.248050 1.951997 0.969601 +v -0.229675 1.933503 0.964994 +v -0.280550 1.834309 0.913953 +v -0.097067 1.794794 -0.408390 +v -0.403512 1.891931 -0.408130 +v -0.403512 1.888487 0.879270 +v 0.465582 1.423044 -0.409384 +v 0.535157 1.159774 0.877321 +v 0.486985 1.044632 0.877014 +v 0.398649 0.758385 -0.411162 +v 0.398649 0.754941 0.876239 +v 0.168114 0.768607 0.911102 +v 0.274357 0.812175 0.911219 +v 0.119855 0.640615 0.875933 +v 0.119855 0.644059 -0.411468 +v -0.492381 1.048096 0.877023 +v -0.539736 1.163576 0.877332 +v -0.683122 1.451552 -0.409308 +v -0.683122 1.448109 0.878093 +v -0.545419 1.491484 0.913036 +v -0.501100 1.597418 0.913319 +v -0.566826 1.726086 0.878836 +v -0.566826 1.729530 -0.408564 +v 0.532741 1.720928 -0.408587 +v 0.570796 1.710838 0.913622 +v -0.734794 1.324265 1.001818 +v -0.731969 1.323391 1.325129 +v -0.487396 1.808567 1.336653 +v -0.484596 1.815137 1.335331 +v -0.394542 1.851347 1.335580 +v -0.305251 1.813216 1.353913 +v -0.275714 1.739714 1.374853 +v -0.094757 1.813716 1.375051 +v -0.124964 1.888887 1.353636 +v -0.086898 1.978226 1.335655 +v 0.520432 1.720090 1.336867 +v 0.482366 1.630750 1.355048 +v 0.414456 1.603381 1.374488 +v 0.490890 1.416993 1.373990 +v 0.569563 1.448701 1.351468 +v 0.658838 1.410684 1.333197 +v 0.695049 1.320629 1.333133 +v 0.694067 1.318325 1.333602 +v 0.392319 1.594480 1.374464 +v 0.303037 1.632553 1.374566 +v 0.266827 1.722608 1.374807 +v 0.090592 1.796903 1.375006 +v 0.065528 1.786824 1.374979 +v 0.467065 1.383218 1.373899 +v 0.479518 1.412421 1.373977 +v 0.627844 1.571567 0.971149 +v 0.513229 0.803616 1.323739 +v 0.515188 0.802399 1.000422 +v -0.280415 1.872421 0.941627 +v -0.280272 1.912755 0.964939 +v -0.393384 1.865054 -0.408297 +v -0.518634 1.844723 -0.408747 +v 0.562694 1.185624 -0.410088 +v 0.650636 1.210574 -0.409952 +v 0.650636 1.207130 0.877448 +v 0.500027 1.044493 0.911840 +v 0.544346 1.150427 0.912124 +v 0.534341 0.929153 0.876705 +v 0.534341 0.932597 -0.410696 +v 0.529917 0.922489 -0.410782 +v 0.390477 0.784032 -0.411184 +v 0.515188 0.806175 -0.411034 +v 0.274222 0.773916 0.938689 +v 0.195019 0.741436 0.938602 +v 0.131004 0.645094 0.910772 +v -0.004311 0.593681 -0.412093 +v 0.095450 0.667473 -0.411544 +v -0.122028 0.812871 -0.411016 +v -0.298735 0.829214 -0.411008 +v -0.569348 0.924590 -0.410717 +v -0.569348 0.921146 0.876683 +v -0.548990 1.154293 0.912134 +v -0.505423 1.048049 0.911850 +v -0.683675 1.199938 0.877429 +v -0.683675 1.203382 -0.409972 +v -0.734794 1.328041 -0.409650 +v -0.572325 1.518507 0.940681 +v -0.539286 1.597479 0.940891 +v -0.571476 1.714877 0.913633 +v -0.532824 1.726598 -0.408705 +v 0.491696 1.622821 -0.408850 +v 0.584182 1.678122 0.941107 +v 0.499591 1.593879 0.913309 +v 0.486550 1.594018 0.878483 +v 0.486550 1.597461 -0.408917 +v -0.280180 1.938821 0.969565 +v -0.629507 1.576014 0.971161 +v -0.522294 0.806068 1.000432 +v -0.520320 0.807271 1.323749 +v -0.693764 1.323231 1.334539 +v -0.656376 1.410904 1.334947 +v -0.566314 1.447057 1.353469 +v -0.495228 1.416683 1.373989 +v -0.416150 1.605701 1.374495 +v -0.486452 1.635741 1.354200 +v -0.522670 1.725851 1.336268 +v -0.269033 1.723096 1.374808 +v -0.307106 1.633814 1.374570 +v -0.397161 1.597604 1.374473 +v -0.477022 1.408920 1.373968 +v -0.468601 1.387975 1.373912 +v -0.064518 1.788435 1.374983 +v -0.088745 1.798766 1.375011 +v 0.656975 1.231345 1.333542 +v 0.566928 1.195077 1.351864 +v 0.492630 1.226698 1.373481 +v 0.412088 1.034183 1.372966 +v 0.479437 1.005520 1.353371 +v 0.515640 0.915522 1.334962 +v 0.481497 0.835456 1.334907 +v 0.065978 0.857783 1.372493 +v 0.468257 1.256455 1.373560 +v 0.441444 1.323138 1.373739 +v 0.000537 1.760692 1.374909 +v -0.000166 1.760992 1.374909 +v -0.003256 0.887306 1.372572 +v 0.618932 1.593302 0.971207 +v 0.648049 1.522315 0.963895 +v 0.626202 1.067836 0.969247 +v -0.004301 0.591972 1.323172 +v -0.004311 0.589904 0.999853 +v -0.359722 1.906277 0.941717 +v -0.392364 1.892965 0.914109 +v -0.491779 1.824705 -0.408713 +v 0.533905 1.481982 -0.409226 +v 0.563977 1.463394 -0.409326 +v 0.679349 1.198562 -0.409984 +v 0.679349 1.195118 0.877416 +v 0.650590 1.193995 0.912240 +v 0.571252 1.123256 0.939623 +v 0.538213 1.044285 0.939412 +v 0.543596 0.938249 0.911556 +v 0.563053 0.917141 0.876672 +v 0.563053 0.920585 -0.410728 +v 0.488872 0.824382 -0.411394 +v 0.515188 0.806176 -0.411525 +v 0.387500 0.750277 0.911053 +v 0.274080 0.733458 0.961784 +v 0.223482 0.712709 0.961729 +v 0.163645 0.658405 0.938380 +v -0.002945 0.627124 -0.411916 +v -0.281356 0.830719 -0.410968 +v -0.522294 0.809845 -0.411515 +v -0.543608 1.048110 0.939422 +v -0.576088 1.127313 0.939634 +v -0.679104 1.188697 0.912226 +v -0.664297 1.423238 -0.409387 +v -0.705341 1.325132 -0.409656 +v -0.678471 1.459131 0.912950 +v -0.664855 1.491603 0.940609 +v -0.600788 1.547111 0.963961 +v -0.579682 1.597560 0.964096 +v 0.598726 1.642592 0.964216 +v 0.537777 1.593670 0.940881 +v 0.533905 1.478538 0.878175 +v -0.311706 1.925905 0.964974 +v -0.650059 1.526906 0.963907 +v -0.620440 1.597685 0.971218 +v -0.631428 1.072284 0.969260 +v -0.489314 0.837945 1.334584 +v -0.524736 0.926039 1.334993 +v -0.486655 1.015264 1.353654 +v -0.419617 1.042157 1.372987 +v -0.493986 1.223512 1.373472 +v -0.568950 1.193440 1.351854 +v -0.658240 1.231570 1.333784 +v -0.694450 1.321624 1.334203 +v -0.440812 1.318866 1.373727 +v -0.467850 1.255464 1.373557 +v -0.073902 0.859485 1.372498 +v -0.003962 0.887607 1.372573 +v 0.477565 0.826245 1.333002 +v 0.387511 0.790035 1.333058 +v 0.298236 0.828051 1.351589 +v 0.269142 0.900364 1.372607 +v 0.093727 0.828628 1.372415 +v 0.121523 0.759542 1.352335 +v 0.083441 0.670316 1.333882 +v -0.004148 0.635096 1.333937 +v 0.262034 0.918041 1.372655 +v 0.300108 1.007323 1.372894 +v 0.390163 1.043533 1.372991 +v 0.477655 1.233084 1.373498 +v 0.085321 0.849534 1.372471 +v 0.598922 1.542868 0.963950 +v 0.578173 1.593465 0.964085 +v 0.662594 1.486909 0.940596 +v 0.645157 1.113163 0.962800 +v 0.616200 1.043929 0.969184 +v 0.244530 0.691498 0.966892 +v 0.661389 1.225848 -0.409979 +v 0.731349 1.322856 -0.409652 +v 0.674698 1.183909 0.912213 +v 0.650455 1.155735 0.939710 +v 0.599715 1.094528 0.962750 +v 0.578609 1.044080 0.962615 +v 0.570693 0.965081 0.939200 +v 0.567703 0.928163 0.911529 +v 0.354859 0.736818 0.938589 +v 0.273974 0.703573 0.966924 +v -0.128117 0.641492 0.875935 +v -0.141402 0.766563 -0.411181 +v -0.166214 0.782548 -0.411097 +v -0.298795 0.829068 -0.411008 +v -0.535648 0.928159 -0.410840 +v -0.495298 0.829764 -0.411375 +v -0.573919 0.932201 0.911540 +v -0.587305 0.964768 0.939199 +v -0.584004 1.048191 0.962626 +v -0.604753 1.098788 0.962762 +v -0.664991 1.226737 -0.409912 +v -0.585093 1.682257 0.941118 +v -0.599887 1.646831 0.964228 +v 0.543159 1.487634 0.913026 +v 0.570256 1.514466 0.940670 +v 0.680551 1.443286 0.878080 +v 0.680551 1.446729 -0.409321 +v -0.621595 1.048307 0.969195 +v -0.650063 1.117744 0.962812 +v -0.252427 0.693256 0.966897 +v -0.006614 0.634107 1.333436 +v -0.095896 0.672180 1.333741 +v -0.132098 0.762177 1.352448 +v -0.103013 0.830301 1.372420 +v -0.279374 0.903884 1.372617 +v -0.309182 0.834067 1.352149 +v -0.399244 0.797914 1.333872 +v -0.488527 0.835987 1.334177 +v -0.396592 1.051414 1.373012 +v -0.307310 1.013341 1.372910 +v -0.271100 0.923287 1.372669 +v -0.094016 0.851397 1.372476 +v -0.478886 1.229584 1.373488 +v 0.675979 1.454341 0.912937 +v 0.650348 1.125588 0.956920 +v 0.597244 0.998638 0.962494 +v 0.208419 0.676704 0.961632 +v 0.662084 1.422350 -0.409513 +v 0.702434 1.323956 -0.410068 +v 0.731349 1.322858 -0.410143 +v 0.661082 1.151289 0.939698 +v 0.581319 0.960635 0.939188 +v 0.310085 0.718394 0.961744 +v -0.139233 0.646050 0.910774 +v -0.128117 0.644936 -0.411465 +v -0.101052 0.668168 -0.411553 +v -0.166214 0.779104 0.876303 +v -0.281356 0.827276 0.876432 +v -0.397191 0.788719 -0.411178 +v -0.406096 0.757787 0.876246 +v -0.665717 1.155982 0.939711 +v -0.602960 1.002882 0.962505 +v -0.216423 0.678207 0.961637 +v -0.281786 0.705538 0.966930 +v 0.592052 0.986245 0.956547 +v -0.171780 0.659592 0.938383 +v -0.175468 0.769822 0.911106 +v -0.281402 0.814141 0.911224 +v -0.406096 0.761231 -0.411154 +v -0.394980 0.753044 0.911061 +v -0.231231 0.714317 0.961733 +v -0.281680 0.735423 0.961790 +v -0.317791 0.720615 0.961750 +v -0.202565 0.742842 0.938605 +v -0.281537 0.775881 0.938694 +v -0.362434 0.739354 0.938596 +vn -0.124200 -0.992300 -0.000500 +vn 0.613800 -0.789500 -0.000200 +vn 0.992300 -0.124200 0.000200 +vn 0.789500 0.613800 0.000500 +vn 0.124200 0.992300 0.000600 +vn -0.613800 0.789500 0.000200 +vn -0.789500 -0.613800 -0.000600 +vn -0.992300 0.124200 -0.000200 +vn -0.000700 -0.001300 1.000000 +vn 0.614000 -0.789300 -0.000300 +vn 0.789400 0.613900 0.000500 +vn -0.613800 0.789500 0.000300 +vn -0.124200 -0.992300 -0.000600 +vn 0.789500 0.613800 0.000600 +vn 0.124200 0.992300 0.000500 +vn -0.789500 -0.613800 -0.000500 +vn -0.614000 0.789300 0.000200 +vn -0.789400 -0.613900 -0.000500 +vn -0.124300 -0.992200 -0.000500 +vn 0.613900 -0.789400 -0.000200 +vn 0.124300 0.992200 0.000600 +vn 0.788200 0.613000 -0.054500 +vn -0.110000 -0.878900 -0.464100 +vn -0.990600 0.124100 -0.057700 +vn 0.612800 -0.788100 -0.057600 +vn 0.124000 0.990800 -0.054700 +vn -0.788100 -0.612700 -0.058900 +vn -0.124100 -0.990500 -0.059100 +vn 0.990700 -0.123900 -0.056000 +vn -0.612700 0.788400 -0.055900 +vn -0.677500 0.085800 -0.730500 +vn -0.699600 -0.543700 -0.463600 +vn -0.543800 0.700700 -0.461900 +vn 0.700200 0.544800 -0.461400 +vn 0.544500 -0.699200 -0.463300 +vn -0.879300 0.110700 -0.463300 +vn 0.110400 0.880300 -0.461400 +vn 0.880000 -0.109500 -0.462200 +vn 0.000700 0.001300 -1.000000 +vn 0.085500 0.679000 -0.729100 +vn 0.678900 -0.083900 -0.729500 +vn -0.084500 -0.677500 -0.730600 +vn -0.539100 -0.418700 -0.730800 +vn -0.419200 0.540600 -0.729400 +vn 0.540000 0.420400 -0.729200 +vn 0.420100 -0.538600 -0.730300 +vn -0.109900 -0.879300 -0.463500 +vn 0.612900 -0.788000 -0.057500 +vn 0.124200 0.990700 -0.055000 +vn -0.788100 -0.612700 -0.059100 +vn -0.612800 0.788300 -0.055800 +vn -0.543800 0.700500 -0.462200 +vn 0.700100 0.544700 -0.461700 +vn 0.544500 -0.699400 -0.463100 +vn 0.110600 0.880500 -0.461000 +vn 0.880000 -0.109500 -0.462100 +vn 0.085400 0.679500 -0.728700 +vn 0.678800 -0.083900 -0.729500 +vn -0.084300 -0.677200 -0.731000 +vn -0.419300 0.540700 -0.729200 +vn 0.540600 0.420800 -0.728500 +vn 0.419900 -0.538700 -0.730400 +vn 0.788200 0.612900 -0.054700 +vn -0.110000 -0.879100 -0.463800 +vn 0.612800 -0.788100 -0.057700 +vn -0.124100 -0.990500 -0.059400 +vn -0.612700 0.788400 -0.056000 +vn -0.677700 0.085900 -0.730300 +vn 0.700400 0.544900 -0.461100 +vn -0.879300 0.110700 -0.463200 +vn 0.110400 0.880500 -0.461100 +vn 0.085300 0.679000 -0.729200 +vn 0.678600 -0.083900 -0.729700 +vn -0.084500 -0.677400 -0.730800 +vn -0.539000 -0.418600 -0.731000 +vn -0.419100 0.540600 -0.729500 +vn 0.540400 0.420700 -0.728700 +vn 0.420300 -0.538900 -0.730000 +vn 0.788300 0.612900 -0.054800 +vn -0.109700 -0.879400 -0.463200 +vn 0.124000 0.990800 -0.055000 +vn -0.788100 -0.612700 -0.059300 +vn -0.123900 -0.990500 -0.059100 +vn -0.612800 0.788300 -0.056200 +vn -0.699800 -0.543600 -0.463500 +vn -0.543900 0.700600 -0.461800 +vn 0.678700 -0.083900 -0.729600 +vn -0.084200 -0.676900 -0.731300 +vn -0.539200 -0.418800 -0.730700 +vn -0.418800 0.540400 -0.729800 +vn 0.540200 0.420600 -0.728900 +vn 0.788300 0.612900 -0.054600 +vn -0.109700 -0.879100 -0.463800 +vn -0.990600 0.124100 -0.057800 +vn 0.612800 -0.788100 -0.057900 +vn -0.612800 0.788300 -0.056000 +vn -0.677600 0.085800 -0.730400 +vn -0.699500 -0.543400 -0.464100 +vn 0.544600 -0.699300 -0.463000 +vn -0.879400 0.110700 -0.463100 +vn 0.110500 0.880300 -0.461400 +vn 0.085600 0.679300 -0.728800 +vn -0.084300 -0.677400 -0.730800 +vn -0.538800 -0.418500 -0.731100 +vn -0.419200 0.540800 -0.729300 +vn 0.788200 0.612900 -0.055000 +vn -0.109800 -0.878900 -0.464100 +vn -0.678100 0.085900 -0.730000 +vn -0.699600 -0.543600 -0.463800 +vn 0.700200 0.544900 -0.461400 +vn 0.085600 0.679200 -0.729000 +vn 0.679100 -0.084000 -0.729200 +vn -0.419000 0.540500 -0.729600 +vn 0.540000 0.420600 -0.729100 +vn -0.788000 -0.612800 -0.058900 +vn -0.612900 0.788200 -0.055800 +vn -0.677900 0.085900 -0.730200 +vn 0.700200 0.544600 -0.461600 +vn 0.679200 -0.084000 -0.729200 +vn -0.084300 -0.677900 -0.730300 +vn -0.539000 -0.418400 -0.731000 +vn 0.540100 0.420400 -0.729100 +vn 0.788200 0.613000 -0.054800 +vn -0.109700 -0.878900 -0.464100 +vn 0.612900 -0.788000 -0.057900 +vn 0.124300 0.990700 -0.054700 +vn -0.788000 -0.612800 -0.058800 +vn -0.678000 0.085900 -0.730000 +vn -0.699500 -0.543600 -0.463900 +vn 0.110500 0.880100 -0.461700 +vn 0.880100 -0.109500 -0.462000 +vn -0.084300 -0.677500 -0.730600 +vn 0.540400 0.420600 -0.728800 +vn 0.420200 -0.538800 -0.730200 +vn 0.993200 -0.116500 -0.005400 +vn 0.785800 0.618500 -0.005500 +vn 0.256200 -0.030000 -0.966200 +vn 0.619200 -0.785200 -0.005200 +vn 0.117400 0.993100 -0.005300 +vn 0.202700 0.159600 -0.966100 +vn 0.159400 -0.202200 -0.966300 +vn -0.000000 0.000000 -1.000000 +vn -0.117400 -0.993100 -0.005300 +vn -0.619200 0.785200 -0.005200 +vn 0.030200 0.255800 -0.966300 +vn -0.030200 -0.255800 -0.966200 +vn -0.785800 -0.618500 -0.005500 +vn -0.993200 0.116500 -0.005400 +vn -0.159500 0.202300 -0.966300 +vn -0.202700 -0.159500 -0.966200 +vn -0.256200 0.030000 -0.966200 +vn 0.000000 0.000000 1.000000 +vn -0.789400 -0.613900 0.000000 +vn -0.613600 0.789600 0.000000 +vn -0.613600 0.789700 0.000000 +vn 0.789400 0.613800 0.000000 +vn -0.124000 -0.992300 -0.000000 +vn -0.992300 0.124100 0.000000 +vn -0.614000 0.789300 0.000000 +vn -0.613800 0.789500 0.000000 +vn -0.124300 -0.992200 -0.000100 +vn -0.992300 0.124200 0.000000 +vn 0.992200 -0.124300 -0.000000 +vn 0.124200 0.992300 0.000000 +vn -0.992300 0.124000 -0.000000 +vn 0.992300 -0.124200 0.000000 +vn 0.992300 -0.124300 0.000000 +vn 0.789400 0.613900 0.000000 +vn -0.789400 -0.613800 0.000000 +vn -0.992300 0.124300 -0.000000 +vn -0.992200 0.124300 0.000000 +vn 0.789300 0.614000 0.000000 +vn 0.124900 0.992200 0.000000 +vn 0.613900 -0.789400 0.000000 +vn -0.613900 0.789400 0.000000 +vn 0.124100 0.992300 0.000000 +vn -0.789500 -0.613800 0.000000 +vn -0.612100 0.790700 0.000000 +vn 0.613800 -0.789500 0.000000 +vn -0.124200 -0.992300 -0.000100 +vn -0.124200 -0.992300 0.000000 +vn 0.992300 -0.124100 0.000000 +vn -0.122200 -0.992500 0.000000 +vn 0.123800 0.992300 0.000000 +vn -0.123800 -0.992300 0.000000 +vn 0.123900 0.992300 0.000000 +vn 0.613600 -0.789600 -0.000100 +vn 0.786300 0.617900 0.000000 +vn 0.124500 0.992200 0.000000 +vn 0.613800 -0.789400 0.000000 +vn 0.789500 0.613700 0.000000 +vn 0.124400 0.992200 0.000000 +vn -0.613700 0.789500 0.000000 +vn 0.789500 0.613800 0.000000 +vn -0.124300 -0.992200 0.000000 +vn 0.133900 0.991000 0.000000 +vn 0.992400 -0.123200 0.000000 +vn 0.614000 -0.789300 0.000000 +vn 0.609500 -0.792800 0.000000 +vn 0.992300 -0.124000 0.000000 +vn -0.789500 -0.613700 0.000000 +vn 0.613700 -0.789500 0.000000 +vn -0.790500 -0.612400 0.000000 +vn 0.124700 0.992200 0.000000 +vn 0.613300 -0.789800 0.000000 +vn 0.789600 0.613700 0.000000 +vn 0.124000 0.992300 0.000000 +vn -0.613800 0.789400 0.000000 +vn 0.164000 -0.085100 -0.982800 +vn -0.176000 -0.048200 -0.983200 +vn -0.096100 -0.156700 -0.983000 +vn 0.054600 -0.183200 -0.981500 +vn -0.159900 0.086700 -0.983300 +vn -0.052900 0.179600 -0.982300 +vn 0.182700 0.050100 -0.981900 +vn 0.095300 0.159800 -0.982500 +vn -0.993200 0.116500 0.000000 +vn 0.030800 0.024400 0.999200 +vn -0.619100 0.785300 0.000000 +vn 0.117400 0.993100 -0.000000 +vn 0.785800 0.618500 0.000000 +vn -0.785800 -0.618500 0.000000 +vn -0.117400 -0.993100 0.000000 +vn 0.619100 -0.785300 0.000000 +vn 0.993200 -0.116500 -0.000000 +vn 0.024300 -0.031100 -0.999200 +vn 0.038800 -0.004600 0.999200 +vn 0.030800 0.024400 -0.999200 +vn -0.038800 0.004600 0.999200 +vn 0.038800 -0.004600 -0.999200 +vn -0.030800 -0.024400 0.999200 +vn -0.038800 0.004600 -0.999200 +vn -0.116300 -0.993200 0.000000 +vn 0.615400 -0.788200 0.000000 +vn 0.993100 -0.117600 0.000000 +vn -0.993100 0.117700 0.000000 +vn -0.615400 0.788200 0.000000 +vn 0.116300 0.993200 0.000100 +vn 0.782800 0.622300 0.000000 +vn -0.782800 -0.622300 0.000000 +vn 0.004600 0.039500 -0.999200 +vn 0.024300 -0.031100 0.999200 +vn -0.004600 -0.039500 -0.999200 +vn 0.004600 0.039500 0.999200 +vn -0.024300 0.031100 -0.999200 +vn -0.004600 -0.039500 0.999200 +vn -0.030800 -0.024400 -0.999200 +vn -0.024300 0.031100 0.999200 +vn -1.000000 0.000000 -0.000000 +vn -0.000000 1.000000 0.002400 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 -0.356100 0.934400 +vn 0.000000 0.040500 0.999200 +vn 0.895400 0.198400 0.398700 +vn 0.938100 0.143200 0.315400 +vn -0.938100 0.143200 0.315400 +vn 0.000000 0.995100 0.098400 +vn -0.895400 0.198400 0.398700 +vn 0.000000 -0.526500 0.850200 +vn 0.000000 0.781700 -0.623600 +vn 0.000000 -0.957200 0.289300 +vn 0.000000 -0.749900 0.661500 +vn 0.000000 0.948900 -0.315700 +vn -0.000000 0.990600 -0.137000 +vn 0.994100 0.000800 0.108900 +vn -0.994100 0.000800 0.108900 +vn 0.000000 -0.415600 0.909500 +vn 0.000000 -0.867200 -0.497900 +vn 0.000000 -0.697800 0.716300 +vn -0.000000 0.614800 -0.788700 +vn 0.000000 -0.368900 -0.929500 +vn 0.000000 -0.917100 0.398700 +vn 0.000000 1.000000 0.000000 +vn 0.971200 -0.234400 -0.043000 +vn 0.980700 -0.195700 0.000000 +vn -0.980700 -0.195700 -0.000000 +vn -0.000000 -0.481900 -0.876200 +vn -0.971200 -0.234400 -0.043000 +vn 0.000000 -0.290000 0.957000 +vn -0.000000 -0.079700 -0.996800 +vn 0.000000 -0.794400 0.607400 +vn 0.000000 -0.435900 0.900000 +vn 0.000000 0.375200 -0.926900 +vn -0.000000 0.940300 -0.340400 +vn 0.000000 0.789800 -0.613400 +vn 0.998200 -0.035600 -0.048100 +vn -0.998200 -0.035600 -0.048100 +vn -0.000000 -0.345700 -0.938400 +vn 0.000000 -0.995900 0.090500 +vn 0.537400 -0.690800 -0.483800 +vn 0.882300 -0.402700 -0.243700 +vn 0.004800 0.978200 0.207500 +vn 0.000000 -0.669900 -0.742500 +vn -0.000800 0.831900 0.554900 +vn -0.000000 -0.819800 -0.572700 +vn 0.827800 0.560700 0.020500 +vn -0.003900 -0.023000 -0.999700 +vn 0.024800 0.921300 -0.388000 +vn 0.822200 0.565800 -0.062300 +vn -0.007800 0.220100 0.975400 +vn 1.000000 -0.003300 0.007000 +vn 0.007400 0.028800 -0.999600 +vn -0.000800 -0.991600 -0.129300 +vn 0.000100 0.991300 -0.131800 +vn 0.005200 0.997400 -0.072300 +vn 0.003000 1.000000 -0.008800 +vn -0.006400 0.795200 0.606300 +vn 1.000000 -0.002500 0.003600 +vn 0.000000 -0.999900 -0.012800 +vn 0.002700 1.000000 0.007400 +vn 0.021900 0.008200 -0.999700 +vn 0.067100 0.196300 -0.978200 +vn 0.006200 0.075100 -0.997200 +vn 0.064700 -0.571900 -0.817800 +vn 0.897300 0.441300 0.008800 +vn 0.002600 0.999900 0.012800 +vn 0.612500 -0.326600 -0.719900 +vn 0.045300 0.998800 0.018400 +vn -0.047100 0.388100 0.920400 +vn 0.881000 0.080200 -0.466200 +vn 0.011600 0.999700 0.020800 +vn 0.976000 0.217600 0.009100 +vn -0.004100 0.886500 0.462600 +vn 0.100400 0.638000 -0.763500 +vn 0.000000 -0.669500 0.742800 +vn 0.000000 -0.996000 0.089600 +vn 0.000000 -0.273300 -0.961900 +vn 0.999900 -0.006700 0.010000 +vn 0.000000 0.243000 -0.970000 +vn 0.986600 -0.144000 -0.076900 +vn 0.999900 -0.011300 0.005000 +vn 0.000000 -0.559300 0.828900 +vn 0.000000 0.555700 -0.831400 +vn -0.000000 0.999900 0.012400 +vn 0.000000 -0.909000 0.416900 +vn -0.000000 0.918900 -0.394400 +vn -0.000000 0.969200 0.246200 +vn 0.999900 -0.012600 -0.000200 +vn 0.000000 -0.999900 -0.011600 +vn 0.000000 0.841600 0.540100 +vn 0.999900 -0.011800 -0.003100 +vn -0.000000 -0.966700 -0.255700 +vn 0.999900 -0.004800 -0.011900 +vn 0.999900 -0.010100 -0.006500 +vn -0.000000 -0.839300 -0.543700 +vn 0.975400 -0.220400 0.005000 +vn -0.000000 -0.385000 -0.922900 +vn 0.000000 0.368700 0.929600 +vn 0.933000 -0.359800 0.006400 +vn -0.000000 -0.075400 -0.997200 +vn 0.000000 0.075400 0.997200 +vn -0.004200 -0.880900 0.473300 +vn 0.000000 -0.655200 -0.755500 +vn 0.000000 -0.603400 0.797500 +vn 0.996000 -0.089500 0.003000 +vn -0.003800 -0.896100 -0.443800 +vn -0.002900 -0.988300 -0.152600 +vn 0.000000 -1.000000 0.004100 +vn 0.989800 -0.070100 0.123800 +vn 0.851200 0.379100 0.363100 +vn 1.000000 -0.000800 0.004400 +vn 1.000000 -0.000300 0.003800 +vn 1.000000 -0.000200 0.002200 +vn 1.000000 0.006400 0.004200 +vn 1.000000 -0.000100 0.007100 +vn 0.605400 -0.795600 -0.022100 +vn 0.785100 -0.618700 -0.028100 +vn 0.481000 0.024000 -0.876400 +vn 0.862100 0.398900 0.312500 +vn 0.543600 0.833200 -0.101300 +vn 0.743000 -0.669100 0.017900 +vn 0.879000 -0.080900 -0.469900 +vn 0.991700 -0.096700 0.084300 +vn 0.393000 0.166900 0.904300 +vn 0.786600 0.616700 -0.030300 +vn 0.437800 -0.620300 -0.650800 +vn 0.449700 -0.887400 -0.101400 +vn -0.002700 0.906300 0.422700 +vn 0.002100 -0.990900 0.134400 +vn 0.001800 1.000000 0.005300 +vn 0.521500 0.853200 0.006400 +vn 0.011200 0.221700 -0.975000 +vn 0.515100 0.184900 -0.837000 +vn 0.003700 -0.298400 -0.954400 +vn 0.523400 -0.203200 -0.827500 +vn 0.433200 -0.892000 0.129400 +vn -0.000600 -0.989600 0.144000 +vn 1.000000 0.000100 0.005800 +vn 0.742400 0.655100 0.140400 +vn 0.743200 -0.573300 -0.345000 +vn -0.006300 0.646600 0.762800 +vn -0.007600 -0.011200 0.999900 +vn 0.343500 -0.010300 0.939100 +vn -0.003600 0.949700 0.313000 +vn 0.541900 0.809100 0.227600 +vn -0.009200 -0.341300 0.939900 +vn 0.374300 -0.257100 0.890900 +vn 0.426200 -0.904600 0.003500 +vn 0.000900 -1.000000 0.002300 +vn -0.005100 -0.239800 -0.970800 +vn 0.011500 -0.738500 -0.674100 +vn 0.816500 0.561100 0.135900 +vn 1.000000 -0.000600 0.005200 +vn 0.900700 0.020300 -0.433900 +vn 0.769500 0.414500 -0.485900 +vn 0.890000 0.455800 0.008900 +vn 0.921600 -0.388200 0.001200 +vn 0.926100 -0.377200 0.001400 +vn 0.943900 0.330300 0.006500 +vn 0.982400 0.001300 0.186900 +vn 0.975700 -0.202500 -0.083600 +vn -0.726700 0.687000 0.003800 +vn -0.793000 -0.609200 -0.009200 +vn 0.022600 0.007900 -0.999700 +vn -0.005700 0.019900 -0.999800 +vn -0.011100 0.016500 -0.999800 +vn 0.014200 0.039400 -0.999100 +vn 0.011800 0.021400 -0.999700 +vn -0.272700 -0.962000 -0.010000 +vn -0.297700 0.954600 0.008800 +vn -1.000000 0.001000 -0.004000 +vn -0.537400 -0.690800 -0.483800 +vn -0.882300 -0.402700 -0.243700 +vn -0.004800 0.978200 0.207500 +vn 0.000800 0.831900 0.554900 +vn -0.827800 0.560700 0.020500 +vn 0.003900 -0.023000 -0.999700 +vn -0.024800 0.921300 -0.388000 +vn -0.822200 0.565800 -0.062300 +vn 0.007800 0.220100 0.975400 +vn -1.000000 -0.003300 0.007000 +vn -0.007400 0.028800 -0.999600 +vn 0.000800 -0.991600 -0.129300 +vn -0.000100 0.991300 -0.131800 +vn -0.005200 0.997400 -0.072300 +vn -0.003000 1.000000 -0.008800 +vn 0.006400 0.795200 0.606300 +vn -1.000000 -0.002500 0.003600 +vn -0.002700 1.000000 0.007400 +vn -0.021900 0.008200 -0.999700 +vn -0.067100 0.196300 -0.978200 +vn -0.006200 0.075100 -0.997200 +vn -0.064700 -0.571900 -0.817800 +vn -0.897300 0.441300 0.008800 +vn -0.002600 0.999900 0.012800 +vn -0.612500 -0.326600 -0.719900 +vn -0.045300 0.998800 0.018400 +vn 0.047100 0.388100 0.920400 +vn -0.881000 0.080200 -0.466300 +vn -0.011600 0.999700 0.020800 +vn -0.976000 0.217600 0.009100 +vn 0.004100 0.886500 0.462600 +vn -0.100400 0.638000 -0.763500 +vn -0.999900 -0.006700 0.010000 +vn -0.986600 -0.144000 -0.076900 +vn -0.999900 -0.011300 0.005000 +vn -0.999900 -0.012600 -0.000200 +vn -0.999900 -0.011800 -0.003100 +vn -0.999900 -0.004800 -0.011900 +vn -0.999900 -0.010100 -0.006500 +vn -0.975400 -0.220400 0.005000 +vn 0.000000 0.368700 0.929500 +vn -0.933000 -0.359800 0.006400 +vn 0.004200 -0.880900 0.473300 +vn -0.996000 -0.089500 0.003000 +vn 0.003800 -0.896100 -0.443800 +vn 0.002900 -0.988300 -0.152600 +vn -0.989800 -0.070100 0.123800 +vn -0.851200 0.379100 0.363100 +vn -1.000000 -0.000800 0.004400 +vn -1.000000 -0.000300 0.003800 +vn -1.000000 -0.000200 0.002200 +vn -1.000000 0.006400 0.004200 +vn -1.000000 -0.000100 0.007100 +vn -0.605400 -0.795600 -0.022100 +vn -0.785100 -0.618700 -0.028100 +vn -0.481000 0.024000 -0.876400 +vn -0.862100 0.398900 0.312500 +vn -0.543600 0.833200 -0.101300 +vn -0.743000 -0.669100 0.017900 +vn -0.879000 -0.080900 -0.469900 +vn -0.991700 -0.096700 0.084300 +vn -0.393000 0.166900 0.904300 +vn -0.786600 0.616700 -0.030300 +vn -0.437800 -0.620300 -0.650800 +vn -0.449600 -0.887400 -0.101400 +vn 0.002700 0.906300 0.422700 +vn -0.002100 -0.990900 0.134400 +vn -0.001800 1.000000 0.005300 +vn -0.521500 0.853200 0.006400 +vn -0.011200 0.221700 -0.975000 +vn -0.515100 0.184900 -0.837000 +vn -0.003700 -0.298400 -0.954400 +vn -0.523400 -0.203200 -0.827500 +vn -0.433200 -0.892000 0.129400 +vn 0.000600 -0.989600 0.144000 +vn -1.000000 0.000100 0.005800 +vn -0.742400 0.655100 0.140400 +vn -0.743200 -0.573300 -0.345000 +vn 0.006300 0.646600 0.762800 +vn 0.007600 -0.011200 0.999900 +vn -0.343500 -0.010300 0.939100 +vn 0.003600 0.949700 0.313000 +vn -0.541900 0.809100 0.227600 +vn 0.009200 -0.341300 0.939900 +vn -0.374400 -0.257100 0.890900 +vn -0.426200 -0.904600 0.003500 +vn -0.000900 -1.000000 0.002300 +vn 0.005100 -0.239800 -0.970800 +vn -0.011500 -0.738500 -0.674100 +vn -0.816500 0.561100 0.135900 +vn -1.000000 -0.000600 0.005200 +vn -0.900700 0.020300 -0.433900 +vn -0.769500 0.414500 -0.485900 +vn -0.890000 0.455800 0.008900 +vn -0.921600 -0.388200 0.001200 +vn -0.926100 -0.377200 0.001400 +vn -0.943900 0.330300 0.006500 +vn -0.982400 0.001300 0.186900 +vn -0.975700 -0.202500 -0.083600 +vn 0.726700 0.687000 0.003800 +vn 0.793000 -0.609200 -0.009200 +vn -0.022600 0.007900 -0.999700 +vn 0.005700 0.019900 -0.999800 +vn 0.011100 0.016500 -0.999800 +vn -0.014200 0.039400 -0.999100 +vn -0.011800 0.021400 -0.999700 +vn 0.272700 -0.962000 -0.010000 +vn 0.297700 0.954600 0.008800 +vn 1.000000 0.001000 -0.004000 +vn 0.917200 0.277900 -0.285500 +vn 0.384300 0.923200 0.002700 +vn 0.635100 0.222800 -0.739600 +vn 0.959500 0.281700 0.000800 +vn 0.364700 0.872700 -0.324600 +vn 0.237700 0.570200 -0.786400 +vn -0.000000 0.002700 -1.000000 +vn 0.385900 0.922500 0.002500 +vn -0.446600 0.848500 -0.284000 +vn -0.377700 0.925900 0.002800 +vn 0.492000 0.201000 -0.847100 +vn 0.203800 0.489400 -0.847900 +vn -0.288700 0.609300 -0.738500 +vn 0.376400 -0.926400 -0.009200 +vn -0.389000 -0.921200 -0.009000 +vn -0.473100 0.881000 0.002400 +vn 0.071700 0.174100 -0.982100 +vn -0.203900 0.492200 -0.846300 +vn -0.921500 0.388300 -0.005000 +vn -0.376400 0.926500 -0.003500 +vn 0.926400 0.376400 -0.006200 +vn 0.389000 0.921200 -0.003700 +vn 0.388900 0.921200 -0.006200 +vn 0.171900 0.073100 -0.982400 +vn -0.915200 0.284400 -0.285500 +vn -0.957500 0.288500 0.000800 +vn -0.070500 0.174600 -0.982100 +vn 0.385100 0.922800 0.010800 +vn -0.633600 0.227300 -0.739600 +vn 0.921000 -0.389400 -0.007700 +vn -0.379400 0.925200 0.002500 +vn -0.389000 -0.921200 -0.006500 +vn -0.377200 0.926100 -0.006300 +vn 0.388100 0.921600 -0.006000 +vn -0.000100 0.002700 -1.000000 +vn 0.921200 -0.388900 -0.006600 +vn 0.375800 -0.926700 -0.008700 +vn 0.379400 -0.925200 -0.002500 +vn -0.389000 -0.921200 -0.009600 +vn 0.376400 -0.926400 -0.008400 +vn 0.000100 0.002700 -1.000000 +vn 0.002600 -0.000300 -1.000000 +vn -0.000000 0.002800 -1.000000 +vn -0.926400 -0.376400 -0.007900 +vn -0.922500 0.386000 0.001000 +vn 0.376400 -0.926400 -0.006800 +vn 0.376100 -0.926600 -0.006400 +vn 0.925200 0.379400 0.001000 +vn -0.378500 0.925500 0.010800 +vn 0.099300 0.235500 0.966800 +vn 0.925200 0.379400 0.009100 +vn -0.490600 0.204500 -0.847000 +vn -0.358600 0.875300 -0.324600 +vn 0.479300 0.877600 0.002300 +vn -0.926400 -0.376400 -0.006500 +vn 0.922500 -0.386000 -0.001000 +vn 0.921200 -0.388900 -0.009300 +vn 0.376400 -0.926400 -0.009100 +vn -0.492800 -0.870100 -0.002300 +vn 0.358600 -0.873500 -0.329300 +vn 0.961800 -0.273600 -0.000700 +vn 0.926300 0.376800 -0.003900 +vn -0.000900 0.003900 -1.000000 +vn -0.375700 0.926700 -0.005100 +vn -0.925200 -0.379400 -0.001000 +vn 0.376800 -0.926300 -0.007600 +vn 0.921400 -0.388500 -0.006400 +vn -0.226800 0.973900 0.002600 +vn -0.871800 0.365600 -0.326000 +vn -0.852800 -0.522200 -0.001400 +vn 0.921200 -0.389000 -0.005700 +vn -0.921500 0.388300 -0.006500 +vn -0.922500 0.385900 0.009100 +vn -0.097600 0.236200 0.966800 +vn 0.238300 0.095100 0.966500 +vn -0.000000 -0.002700 1.000000 +vn 0.922500 -0.386000 0.007000 +vn -0.171400 0.074400 -0.982400 +vn -0.233600 0.571800 -0.786400 +vn -0.200300 0.490800 -0.847900 +vn 0.452600 0.845300 -0.284000 +vn 0.921000 -0.389400 -0.006300 +vn -0.926200 -0.377000 -0.007700 +vn 0.871800 -0.363900 -0.327900 +vn -0.926700 -0.375700 -0.008800 +vn -0.376400 0.926500 -0.003600 +vn -0.000800 -0.001100 -1.000000 +vn 0.377700 -0.925900 -0.002200 +vn -0.466300 -0.836100 -0.288800 +vn 0.233600 -0.567600 -0.789400 +vn 0.919600 -0.267800 -0.287300 +vn -0.002700 -0.000300 -1.000000 +vn 0.388900 0.921300 -0.003100 +vn -0.855100 0.518400 0.001400 +vn -0.874400 -0.357700 -0.327900 +vn -0.244900 -0.969500 -0.002600 +vn 0.926400 0.376400 -0.004800 +vn -0.221600 0.932700 -0.284500 +vn -0.568100 0.239800 -0.787300 +vn -0.819200 -0.495700 -0.288300 +vn -0.922500 0.385900 0.001000 +vn -0.921200 0.389000 -0.005900 +vn -0.921200 0.389000 -0.006900 +vn -0.002700 -0.000000 -1.000000 +vn 0.926600 0.375900 -0.005000 +vn -0.376400 0.926500 -0.005800 +vn 0.815700 -0.501500 -0.288300 +vn 0.849100 -0.528300 -0.001400 +vn -0.925200 -0.379400 0.007100 +vn -0.237600 0.096800 0.966500 +vn 0.237600 -0.102000 0.966000 +vn 0.378500 -0.925600 0.005800 +vn 0.293000 0.607200 -0.738500 +vn 0.207300 0.490700 -0.846300 +vn -0.926500 -0.376400 -0.004400 +vn -0.385900 -0.922500 -0.002500 +vn 0.568100 -0.235600 -0.788600 +vn 0.874400 0.359400 -0.326000 +vn 0.386000 0.922500 0.002500 +vn -0.305500 -0.596100 -0.742500 +vn 0.200300 -0.486200 -0.850500 +vn 0.637500 -0.209400 -0.741500 +vn -0.821800 0.493100 -0.285600 +vn -0.569700 -0.231500 -0.788500 +vn -0.239500 -0.926800 -0.289400 +vn -0.581100 -0.331900 -0.743100 +vn -0.170300 0.650200 -0.740400 +vn -0.487100 0.206000 -0.848700 +vn 0.389700 0.920900 -0.005000 +vn 0.578800 -0.336000 -0.743100 +vn -0.385100 -0.922900 0.005800 +vn -0.238300 -0.100300 0.966000 +vn 0.097600 -0.241300 0.965500 +vn -0.921300 0.389000 -0.003400 +vn -0.364700 -0.870900 -0.329300 +vn 0.487100 -0.201500 -0.849800 +vn 0.569700 0.235700 -0.787300 +vn 0.002000 0.006200 -1.000000 +vn 0.070500 -0.169300 -0.983000 +vn -0.926700 -0.375600 -0.008900 +vn -0.376400 0.926500 -0.004300 +vn -0.488500 -0.198100 -0.849800 +vn -0.002700 0.005400 -1.000000 +vn -0.000000 0.002600 -1.000000 +vn 0.519100 -0.258000 -0.814900 +vn 0.233700 0.972300 0.002600 +vn -0.099300 -0.240700 0.965500 +vn 0.171400 -0.069100 -0.982800 +vn 0.488500 0.202600 -0.848700 +vn 0.186900 0.551900 -0.812700 +vn -0.389300 -0.921100 -0.006700 +vn 0.926400 0.376400 -0.008200 +vn -0.377000 0.926200 -0.004000 +vn 0.922500 -0.385900 -0.001000 +vn -0.237700 -0.566000 -0.789400 +vn -0.002000 0.002800 1.000000 +vn -0.389600 -0.920900 -0.010000 +vn -0.221200 -0.492400 -0.841800 +vn -0.071700 -0.168800 -0.983000 +vn 0.171500 -0.069100 -0.982800 +vn 0.504800 -0.194700 -0.841000 +vn -0.920900 0.389700 -0.006700 +vn -0.384300 -0.923200 -0.002200 +vn 0.388500 0.921400 -0.002700 +vn 0.921400 -0.388600 -0.006000 +vn 0.389000 0.921200 -0.004600 +vn 0.926400 0.376400 -0.005100 +vn -0.926400 -0.376400 -0.007600 +vn -0.584200 0.331000 -0.741000 +vn -0.185000 -0.642500 -0.743600 +vn -0.511000 0.251100 -0.822100 +vn -0.189200 -0.533800 -0.824200 +vn -0.172000 -0.067900 -0.982800 +vn 0.389500 0.921000 -0.003800 +vn -0.375700 0.926700 -0.004300 +vn -0.920900 0.389700 -0.006300 +vn -0.520900 -0.254300 -0.814800 +vn -0.183100 0.553200 -0.812700 +vn -0.171900 -0.067900 -0.982800 +vn 0.228200 0.931100 -0.284500 +vn 0.174900 0.649000 -0.740400 +vn 0.000200 0.006500 -1.000000 +vn 0.172000 0.073100 -0.982400 +vn -0.203800 -0.484800 -0.850500 +vn -0.921500 -0.261300 -0.287300 +vn -0.963800 -0.266800 -0.000700 +vn 0.486700 -0.873600 -0.002300 +vn -0.389000 -0.921200 -0.008100 +vn -0.171500 0.074400 -0.982400 +vn -0.638900 -0.204900 -0.741500 +vn 0.460400 -0.839400 -0.288800 +vn -0.506200 -0.191100 -0.841000 +vn 0.301300 -0.598200 -0.742500 +vn 0.217700 -0.494000 -0.841800 +vn -0.921200 0.389000 -0.006200 +vn -0.926200 -0.376900 -0.007300 +vn 0.926700 0.375800 -0.005400 +vn -0.388500 -0.921400 -0.007700 +vn 0.002600 0.005600 -1.000000 +vn 0.921200 -0.388900 -0.006700 +vn 0.376800 -0.926200 -0.008400 +vn -0.388400 -0.921500 -0.008900 +vn 0.926300 0.376800 -0.003800 +vn 0.003400 0.002500 -1.000000 +vn -0.003400 0.002600 -1.000000 +vn -0.000000 -0.230700 -0.973000 +vn 0.505800 -0.770900 -0.387200 +vn 0.000000 -0.469200 0.883100 +vn 0.000000 -0.585400 -0.810700 +vn 0.000000 0.236200 0.971700 +vn 0.000000 -0.999800 0.019000 +vn -0.000000 -0.596600 -0.802500 +vn 0.729700 0.424800 -0.535800 +vn 0.893900 0.355400 0.273200 +vn 0.000000 0.503500 0.864000 +vn 0.481700 -0.875900 0.028300 +vn -0.000000 0.315000 0.949100 +vn 0.000000 -0.928900 -0.370400 +vn 0.870200 0.381600 0.311700 +vn 0.000400 0.887900 0.460100 +vn 0.000000 -0.005100 1.000000 +vn 0.817900 0.460000 -0.345700 +vn 0.429000 0.238900 0.871200 +vn 0.553500 -0.196200 -0.809400 +vn 0.637800 -0.302500 0.708300 +vn 0.524300 -0.495500 -0.692500 +vn 0.599400 -0.471400 -0.646800 +vn 0.367300 0.466100 0.804900 +vn 0.449700 0.215200 0.866900 +vn 0.759600 0.026500 -0.649800 +vn -0.505800 -0.770900 -0.387200 +vn -0.729700 0.424800 -0.535800 +vn -0.893900 0.355400 0.273200 +vn -0.481700 -0.875900 0.028300 +vn -0.870200 0.381600 0.311700 +vn -0.000400 0.887900 0.460100 +vn -0.817900 0.460000 -0.345700 +vn -0.429000 0.238900 0.871200 +vn -0.553500 -0.196200 -0.809400 +vn -0.637800 -0.302500 0.708300 +vn -0.524300 -0.495500 -0.692500 +vn -0.599400 -0.471400 -0.646800 +vn -0.367300 0.466100 0.804900 +vn -0.449700 0.215200 0.866900 +vn -0.759600 0.026500 -0.649800 +vn 0.000000 0.261500 0.965200 +vn 0.000000 -0.338600 0.940900 +vn 0.000000 -0.464100 -0.885800 +vn 0.000000 0.510400 0.860000 +vn -0.018600 0.753900 -0.656700 +vn -0.000000 -0.470600 -0.882300 +vn 0.000000 -0.222800 -0.974900 +vn -0.007100 0.997200 0.074000 +vn 0.000000 -0.998800 0.048300 +vn 0.005300 0.886500 -0.462600 +vn 0.033100 0.382500 -0.923400 +vn 0.018600 0.753900 -0.656700 +vn 0.007100 0.997200 0.074000 +vn -0.005300 0.886500 -0.462600 +vn -0.033200 0.382500 -0.923400 +usemtl BulletYellow +s off +f 253//1 254//1 256//1 255//1 +f 255//2 256//2 258//2 257//2 +f 257//3 258//3 260//3 259//3 +f 259//4 260//4 262//4 261//4 +f 261//5 262//5 264//5 263//5 +f 263//6 264//6 266//6 265//6 +f 267//7 268//7 254//7 253//7 +f 265//8 266//8 268//8 267//8 +f 253//9 255//9 257//9 259//9 261//9 263//9 265//9 267//9 +f 293//1 294//1 296//1 295//1 +f 295//10 296//10 298//10 297//10 +f 297//3 298//3 300//3 299//3 +f 299//11 300//11 302//11 301//11 +f 301//5 302//5 304//5 303//5 +f 303//6 304//6 306//6 305//6 +f 307//7 308//7 294//7 293//7 +f 305//8 306//8 308//8 307//8 +f 293//9 295//9 297//9 299//9 301//9 303//9 305//9 307//9 +f 333//1 334//1 336//1 335//1 +f 335//2 336//2 338//2 337//2 +f 337//3 338//3 340//3 339//3 +f 339//4 340//4 342//4 341//4 +f 341//5 342//5 344//5 343//5 +f 343//12 344//12 346//12 345//12 +f 347//7 348//7 334//7 333//7 +f 345//8 346//8 348//8 347//8 +f 333//9 335//9 337//9 339//9 341//9 343//9 345//9 347//9 +f 373//13 374//13 376//13 375//13 +f 375//2 376//2 378//2 377//2 +f 377//3 378//3 380//3 379//3 +f 379//14 380//14 382//14 381//14 +f 381//15 382//15 384//15 383//15 +f 383//12 384//12 386//12 385//12 +f 387//16 388//16 374//16 373//16 +f 385//8 386//8 388//8 387//8 +f 373//9 375//9 377//9 379//9 381//9 383//9 385//9 387//9 +f 413//1 414//1 416//1 415//1 +f 415//2 416//2 418//2 417//2 +f 417//3 418//3 420//3 419//3 +f 419//4 420//4 422//4 421//4 +f 421//5 422//5 424//5 423//5 +f 423//6 424//6 426//6 425//6 +f 427//7 428//7 414//7 413//7 +f 425//8 426//8 428//8 427//8 +f 413//9 415//9 417//9 419//9 421//9 423//9 425//9 427//9 +f 453//13 454//13 456//13 455//13 +f 455//2 456//2 458//2 457//2 +f 457//3 458//3 460//3 459//3 +f 459//14 460//14 462//14 461//14 +f 461//15 462//15 464//15 463//15 +f 463//6 464//6 466//6 465//6 +f 467//16 468//16 454//16 453//16 +f 465//8 466//8 468//8 467//8 +f 453//9 455//9 457//9 459//9 461//9 463//9 465//9 467//9 +f 493//1 494//1 496//1 495//1 +f 495//2 496//2 498//2 497//2 +f 497//3 498//3 500//3 499//3 +f 499//4 500//4 502//4 501//4 +f 501//5 502//5 504//5 503//5 +f 503//17 504//17 506//17 505//17 +f 507//18 508//18 494//18 493//18 +f 505//8 506//8 508//8 507//8 +f 493//9 495//9 497//9 499//9 501//9 503//9 505//9 507//9 +f 533//19 534//19 536//19 535//19 +f 535//20 536//20 538//20 537//20 +f 537//3 538//3 540//3 539//3 +f 539//11 540//11 542//11 541//11 +f 541//21 542//21 544//21 543//21 +f 543//17 544//17 546//17 545//17 +f 547//18 548//18 534//18 533//18 +f 545//8 546//8 548//8 547//8 +f 533//9 535//9 537//9 539//9 541//9 543//9 545//9 547//9 +usemtl BulletTip +f 262//22 260//22 272//22 273//22 +f 269//23 270//23 278//23 277//23 +f 268//24 266//24 275//24 276//24 +f 258//25 256//25 269//25 271//25 +f 264//26 262//26 273//26 274//26 +f 254//27 268//27 276//27 270//27 +f 256//28 254//28 270//28 269//28 +f 260//29 258//29 271//29 272//29 +f 266//30 264//30 274//30 275//30 +f 284//31 283//31 291//31 292//31 +f 270//32 276//32 284//32 278//32 +f 275//33 274//33 282//33 283//33 +f 273//34 272//34 280//34 281//34 +f 271//35 269//35 277//35 279//35 +f 276//36 275//36 283//36 284//36 +f 274//37 273//37 281//37 282//37 +f 272//38 271//38 279//38 280//38 +f 285//39 286//39 292//39 291//39 290//39 289//39 288//39 287//39 +f 282//40 281//40 289//40 290//40 +f 280//41 279//41 287//41 288//41 +f 277//42 278//42 286//42 285//42 +f 278//43 284//43 292//43 286//43 +f 283//44 282//44 290//44 291//44 +f 281//45 280//45 288//45 289//45 +f 279//46 277//46 285//46 287//46 +f 302//22 300//22 312//22 313//22 +f 309//47 310//47 318//47 317//47 +f 308//24 306//24 315//24 316//24 +f 298//48 296//48 309//48 311//48 +f 304//49 302//49 313//49 314//49 +f 294//50 308//50 316//50 310//50 +f 296//28 294//28 310//28 309//28 +f 300//29 298//29 311//29 312//29 +f 306//51 304//51 314//51 315//51 +f 324//31 323//31 331//31 332//31 +f 310//32 316//32 324//32 318//32 +f 315//52 314//52 322//52 323//52 +f 313//53 312//53 320//53 321//53 +f 311//54 309//54 317//54 319//54 +f 316//36 315//36 323//36 324//36 +f 314//55 313//55 321//55 322//55 +f 312//56 311//56 319//56 320//56 +f 325//39 326//39 332//39 331//39 330//39 329//39 328//39 327//39 +f 322//57 321//57 329//57 330//57 +f 320//58 319//58 327//58 328//58 +f 317//59 318//59 326//59 325//59 +f 318//43 324//43 332//43 326//43 +f 323//60 322//60 330//60 331//60 +f 321//61 320//61 328//61 329//61 +f 319//62 317//62 325//62 327//62 +f 342//63 340//63 352//63 353//63 +f 349//64 350//64 358//64 357//64 +f 348//24 346//24 355//24 356//24 +f 338//65 336//65 349//65 351//65 +f 344//26 342//26 353//26 354//26 +f 334//50 348//50 356//50 350//50 +f 336//66 334//66 350//66 349//66 +f 340//29 338//29 351//29 352//29 +f 346//67 344//67 354//67 355//67 +f 364//68 363//68 371//68 372//68 +f 350//32 356//32 364//32 358//32 +f 355//33 354//33 362//33 363//33 +f 353//69 352//69 360//69 361//69 +f 351//35 349//35 357//35 359//35 +f 356//70 355//70 363//70 364//70 +f 354//71 353//71 361//71 362//71 +f 352//38 351//38 359//38 360//38 +f 365//39 366//39 372//39 371//39 370//39 369//39 368//39 367//39 +f 362//72 361//72 369//72 370//72 +f 360//73 359//73 367//73 368//73 +f 357//74 358//74 366//74 365//74 +f 358//75 364//75 372//75 366//75 +f 363//76 362//76 370//76 371//76 +f 361//77 360//77 368//77 369//77 +f 359//78 357//78 365//78 367//78 +f 382//79 380//79 392//79 393//79 +f 389//80 390//80 398//80 397//80 +f 388//24 386//24 395//24 396//24 +f 378//65 376//65 389//65 391//65 +f 384//81 382//81 393//81 394//81 +f 374//82 388//82 396//82 390//82 +f 376//83 374//83 390//83 389//83 +f 380//29 378//29 391//29 392//29 +f 386//84 384//84 394//84 395//84 +f 404//31 403//31 411//31 412//31 +f 390//85 396//85 404//85 398//85 +f 395//86 394//86 402//86 403//86 +f 393//53 392//53 400//53 401//53 +f 391//35 389//35 397//35 399//35 +f 396//70 395//70 403//70 404//70 +f 394//55 393//55 401//55 402//55 +f 392//38 391//38 399//38 400//38 +f 405//39 406//39 412//39 411//39 410//39 409//39 408//39 407//39 +f 402//40 401//40 409//40 410//40 +f 400//87 399//87 407//87 408//87 +f 397//88 398//88 406//88 405//88 +f 398//89 404//89 412//89 406//89 +f 403//90 402//90 410//90 411//90 +f 401//91 400//91 408//91 409//91 +f 399//46 397//46 405//46 407//46 +f 422//92 420//92 432//92 433//92 +f 429//93 430//93 438//93 437//93 +f 428//94 426//94 435//94 436//94 +f 418//95 416//95 429//95 431//95 +f 424//26 422//26 433//26 434//26 +f 414//27 428//27 436//27 430//27 +f 416//83 414//83 430//83 429//83 +f 420//29 418//29 431//29 432//29 +f 426//96 424//96 434//96 435//96 +f 444//97 443//97 451//97 452//97 +f 430//98 436//98 444//98 438//98 +f 435//52 434//52 442//52 443//52 +f 433//69 432//69 440//69 441//69 +f 431//99 429//99 437//99 439//99 +f 436//100 435//100 443//100 444//100 +f 434//101 433//101 441//101 442//101 +f 432//38 431//38 439//38 440//38 +f 445//39 446//39 452//39 451//39 450//39 449//39 448//39 447//39 +f 442//102 441//102 449//102 450//102 +f 440//87 439//87 447//87 448//87 +f 437//103 438//103 446//103 445//103 +f 438//104 444//104 452//104 446//104 +f 443//105 442//105 450//105 451//105 +f 441//45 440//45 448//45 449//45 +f 439//46 437//46 445//46 447//46 +f 462//106 460//106 472//106 473//106 +f 469//107 470//107 478//107 477//107 +f 468//24 466//24 475//24 476//24 +f 458//25 456//25 469//25 471//25 +f 464//26 462//26 473//26 474//26 +f 454//82 468//82 476//82 470//82 +f 456//83 454//83 470//83 469//83 +f 460//29 458//29 471//29 472//29 +f 466//96 464//96 474//96 475//96 +f 484//108 483//108 491//108 492//108 +f 470//109 476//109 484//109 478//109 +f 475//52 474//52 482//52 483//52 +f 473//110 472//110 480//110 481//110 +f 471//35 469//35 477//35 479//35 +f 476//70 475//70 483//70 484//70 +f 474//101 473//101 481//101 482//101 +f 472//56 471//56 479//56 480//56 +f 485//39 486//39 492//39 491//39 490//39 489//39 488//39 487//39 +f 482//111 481//111 489//111 490//111 +f 480//112 479//112 487//112 488//112 +f 477//42 478//42 486//42 485//42 +f 478//89 484//89 492//89 486//89 +f 483//113 482//113 490//113 491//113 +f 481//114 480//114 488//114 489//114 +f 479//46 477//46 485//46 487//46 +f 502//79 500//79 512//79 513//79 +f 509//93 510//93 518//93 517//93 +f 508//94 506//94 515//94 516//94 +f 498//25 496//25 509//25 511//25 +f 504//81 502//81 513//81 514//81 +f 494//115 508//115 516//115 510//115 +f 496//83 494//83 510//83 509//83 +f 500//29 498//29 511//29 512//29 +f 506//116 504//116 514//116 515//116 +f 524//117 523//117 531//117 532//117 +f 510//109 516//109 524//109 518//109 +f 515//86 514//86 522//86 523//86 +f 513//118 512//118 520//118 521//118 +f 511//99 509//99 517//99 519//99 +f 516//70 515//70 523//70 524//70 +f 514//37 513//37 521//37 522//37 +f 512//56 511//56 519//56 520//56 +f 525//39 526//39 532//39 531//39 530//39 529//39 528//39 527//39 +f 522//57 521//57 529//57 530//57 +f 520//119 519//119 527//119 528//119 +f 517//120 518//120 526//120 525//120 +f 518//121 524//121 532//121 526//121 +f 523//76 522//76 530//76 531//76 +f 521//122 520//122 528//122 529//122 +f 519//46 517//46 525//46 527//46 +f 542//123 540//123 552//123 553//123 +f 549//124 550//124 558//124 557//124 +f 548//94 546//94 555//94 556//94 +f 538//125 536//125 549//125 551//125 +f 544//126 542//126 553//126 554//126 +f 534//127 548//127 556//127 550//127 +f 536//28 534//28 550//28 549//28 +f 540//29 538//29 551//29 552//29 +f 546//116 544//116 554//116 555//116 +f 564//128 563//128 571//128 572//128 +f 550//129 556//129 564//129 558//129 +f 555//52 554//52 562//52 563//52 +f 553//69 552//69 560//69 561//69 +f 551//35 549//35 557//35 559//35 +f 556//70 555//70 563//70 564//70 +f 554//130 553//130 561//130 562//130 +f 552//131 551//131 559//131 560//131 +f 565//39 566//39 572//39 571//39 570//39 569//39 568//39 567//39 +f 562//72 561//72 569//72 570//72 +f 560//58 559//58 567//58 568//58 +f 557//132 558//132 566//132 565//132 +f 558//104 564//104 572//104 566//104 +f 563//105 562//105 570//105 571//105 +f 561//133 560//133 568//133 569//133 +f 559//134 557//134 565//134 567//134 +usemtl Metal +f 1//135 2//135 4//135 3//135 +f 5//136 1//136 3//136 6//136 +f 4//137 16//137 15//137 14//137 13//137 12//137 11//137 10//137 9//137 8//137 7//137 3//137 +f 2//138 18//138 17//138 4//138 +f 19//139 5//139 6//139 20//139 +f 3//140 7//140 28//140 27//140 26//140 25//140 24//140 23//140 22//140 21//140 6//140 +f 17//141 36//141 35//141 34//141 33//141 32//141 31//141 30//141 29//141 16//141 4//141 +f 32//142 43//142 42//142 41//142 40//142 11//142 12//142 39//142 38//142 37//142 31//142 +f 18//143 45//143 44//143 17//143 +f 46//144 19//144 20//144 47//144 +f 6//145 21//145 54//145 53//145 52//145 51//145 50//145 49//145 48//145 20//145 +f 26//142 61//142 60//142 59//142 58//142 51//142 52//142 57//142 56//142 55//142 25//142 +f 44//146 68//146 67//146 66//146 65//146 64//146 63//146 62//146 36//146 17//146 +f 69//142 74//142 73//142 72//142 41//142 42//142 71//142 70//142 +f 45//147 76//147 75//147 44//147 +f 76//148 46//148 47//148 75//148 +f 20//149 48//149 84//149 83//149 82//149 81//149 80//149 79//149 78//149 77//149 47//149 +f 74//142 88//142 87//142 86//142 85//142 59//142 60//142 73//142 +f 75//150 96//150 95//150 94//150 93//150 92//150 91//150 90//150 89//150 68//150 44//150 +f 93//142 101//142 69//142 70//142 100//142 64//142 65//142 99//142 98//142 97//142 92//142 +f 47//151 77//151 109//151 108//151 107//151 106//151 105//151 104//151 103//151 102//151 96//151 75//151 +f 81//142 114//142 86//142 87//142 113//142 105//142 106//142 112//142 111//142 110//142 80//142 +f 76//152 220//152 219//152 46//152 +f 32//153 136//153 147//153 43//153 +f 93//154 191//154 199//154 101//154 +f 55//155 155//155 129//155 25//155 +f 81//156 179//156 212//156 114//156 +f 43//157 147//157 146//157 42//157 +f 101//158 199//158 169//158 69//158 +f 25//159 129//159 128//159 24//159 +f 85//160 183//160 159//160 59//160 +f 42//161 146//161 171//161 71//161 +f 69//162 169//162 174//162 74//162 +f 53//163 153//163 152//163 52//163 +f 59//160 159//160 158//160 58//160 +f 30//164 134//164 133//164 29//164 +f 74//165 174//165 186//165 88//165 +f 52//166 152//166 157//166 57//166 +f 83//167 181//167 180//167 82//167 +f 37//168 141//168 135//168 31//168 +f 88//169 186//169 185//169 87//169 +f 24//170 128//170 127//170 23//170 +f 58//171 158//171 151//171 51//171 +f 31//172 135//172 134//172 30//172 +f 89//173 187//173 168//173 68//173 +f 54//174 154//174 153//174 53//174 +f 51//162 151//162 150//162 50//162 +f 29//175 133//175 124//175 16//175 +f 68//176 168//176 167//176 67//176 +f 23//177 127//177 126//177 22//177 +f 16//178 124//178 123//178 15//178 +f 84//179 182//179 181//179 83//179 +f 38//166 142//166 141//166 37//166 +f 90//168 188//168 187//168 89//168 +f 22//157 126//157 125//157 21//157 +f 50//177 150//177 149//177 49//177 +f 15//162 123//162 122//162 14//162 +f 67//154 167//154 166//154 66//154 +f 21//180 125//180 154//180 54//180 +f 49//181 149//181 148//181 48//181 +f 39//179 143//179 142//179 38//179 +f 91//182 189//182 188//182 90//182 +f 48//183 148//183 182//183 84//183 +f 14//169 122//169 121//169 13//169 +f 66//158 166//158 165//158 65//158 +f 40//184 144//184 119//184 11//184 +f 13//185 121//185 120//185 12//185 +f 65//162 165//162 197//162 99//162 +f 11//186 119//186 118//186 10//186 +f 12//157 120//157 143//157 39//157 +f 97//187 195//187 190//187 92//187 +f 102//188 200//188 194//188 96//188 +f 72//156 172//156 145//156 41//156 +f 107//189 205//189 204//189 106//189 +f 92//190 190//190 189//190 91//190 +f 103//166 201//166 200//166 102//166 +f 41//191 145//191 144//191 40//191 +f 106//192 204//192 210//192 112//192 +f 99//177 197//177 196//177 98//177 +f 104//179 202//179 201//179 103//179 +f 10//193 118//193 117//193 9//193 +f 108//194 206//194 205//194 107//194 +f 98//181 196//181 195//181 97//181 +f 105//195 203//195 202//195 104//195 +f 61//166 161//166 160//166 60//166 +f 112//159 210//159 209//159 111//159 +f 62//186 162//186 140//186 36//186 +f 60//166 160//166 173//166 73//166 +f 109//166 207//166 206//166 108//166 +f 36//196 140//196 139//196 35//196 +f 73//197 173//197 172//197 72//197 +f 111//162 209//162 208//162 110//162 +f 63//156 163//156 162//156 62//156 +f 9//162 117//162 116//162 8//162 +f 78//174 176//174 175//174 77//174 +f 35//159 139//159 138//159 34//159 +f 113//185 211//185 203//185 105//185 +f 27//198 131//198 130//198 26//198 +f 77//199 175//199 207//199 109//199 +f 100//200 198//200 164//200 64//200 +f 87//201 185//201 211//201 113//201 +f 26//202 130//202 161//202 61//202 +f 110//177 208//177 178//177 80//177 +f 64//182 164//182 163//182 63//182 +f 8//203 116//203 115//203 7//203 +f 80//201 178//201 177//201 79//201 +f 34//162 138//162 137//162 33//162 +f 7//169 115//169 132//169 28//169 +f 79//181 177//181 176//181 78//181 +f 71//174 171//174 170//174 70//174 +f 95//164 193//164 192//164 94//164 +f 28//181 132//181 131//181 27//181 +f 114//204 212//204 184//204 86//204 +f 70//205 170//205 198//205 100//205 +f 96//206 194//206 193//206 95//206 +f 56//164 156//164 155//164 55//164 +f 86//207 184//207 183//207 85//207 +f 33//169 137//169 136//169 32//169 +f 94//208 192//208 191//208 93//208 +f 57//194 157//194 156//194 56//194 +f 82//191 180//191 179//191 81//191 +f 124//209 133//209 134//209 135//209 141//209 142//209 143//209 120//209 121//209 122//209 123//209 +f 200//210 201//210 202//210 203//210 211//210 185//210 186//210 174//210 169//210 199//210 191//210 192//210 193//210 194//210 +f 187//211 188//211 189//211 190//211 195//211 196//211 197//211 165//211 166//211 167//211 168//211 +f 162//212 163//212 164//212 198//212 170//212 171//212 146//212 147//212 136//212 137//212 138//212 139//212 140//212 +f 205//213 206//213 207//213 175//213 176//213 177//213 178//213 208//213 209//213 210//213 204//213 +f 212//214 179//214 180//214 181//214 182//214 148//214 149//214 150//214 151//214 158//214 159//214 183//214 184//214 +f 144//215 145//215 172//215 173//215 160//215 161//215 130//215 131//215 132//215 115//215 116//215 117//215 118//215 119//215 +f 156//216 157//216 152//216 153//216 154//216 125//216 126//216 127//216 128//216 129//216 155//216 +f 220//217 228//217 227//217 219//217 +f 46//152 219//152 217//152 19//152 +f 19//152 217//152 215//152 5//152 +f 5//152 215//152 213//152 1//152 +f 45//152 218//152 220//152 76//152 +f 18//152 216//152 218//152 45//152 +f 2//152 214//152 216//152 18//152 +f 1//152 213//152 214//152 2//152 +f 229//218 245//218 247//218 231//218 +f 219//219 227//219 225//219 217//219 +f 217//220 225//220 223//220 215//220 +f 215//221 223//221 221//221 213//221 +f 218//222 226//222 228//222 220//222 +f 216//223 224//223 226//223 218//223 +f 214//224 222//224 224//224 216//224 +f 213//225 221//225 222//225 214//225 +f 229//152 231//152 233//152 235//152 236//152 234//152 232//152 230//152 +f 222//226 238//226 240//226 224//226 +f 230//227 246//227 245//227 229//227 +f 223//228 239//228 237//228 221//228 +f 235//229 251//229 252//229 236//229 +f 221//230 237//230 238//230 222//230 +f 236//231 252//231 250//231 234//231 +f 228//232 244//232 243//232 227//232 +f 240//233 248//233 250//233 242//233 +f 238//234 246//234 248//234 240//234 +f 237//235 245//235 246//235 238//235 +f 244//236 252//236 251//236 243//236 +f 243//237 251//237 249//237 241//237 +f 241//238 249//238 247//238 239//238 +f 239//239 247//239 245//239 237//239 +f 242//240 250//240 252//240 244//240 +f 225//241 241//241 239//241 223//241 +f 232//242 248//242 246//242 230//242 +f 224//243 240//243 242//243 226//243 +f 231//244 247//244 249//244 233//244 +f 227//245 243//245 241//245 225//245 +f 234//246 250//246 248//246 232//246 +f 226//247 242//247 244//247 228//247 +f 233//248 249//248 251//248 235//248 +f 574//249 573//249 575//249 576//249 +f 576//250 575//250 579//250 580//250 +f 580//251 579//251 577//251 578//251 +f 578//252 577//252 573//252 574//252 +f 577//253 584//253 582//253 573//253 +f 580//251 578//251 600//251 599//251 +f 583//254 587//254 588//254 584//254 +f 579//255 583//255 584//255 577//255 +f 573//256 582//256 581//256 575//256 +f 575//257 581//257 583//257 579//257 +f 587//251 591//251 592//251 588//251 +f 582//258 586//258 585//258 581//258 +f 584//259 588//259 586//259 582//259 +f 581//260 585//260 587//260 583//260 +f 592//261 596//261 594//261 590//261 +f 586//249 590//249 589//249 585//249 +f 588//262 592//262 590//262 586//262 +f 585//263 589//263 591//263 587//263 +f 589//264 593//264 595//264 591//264 +f 591//265 595//265 596//265 592//265 +f 590//266 594//266 593//266 589//266 +f 593//267 594//267 596//267 595//267 +f 600//268 597//268 598//268 599//268 +f 574//249 576//249 598//249 597//249 +f 578//269 574//269 597//269 600//269 +f 576//270 580//270 599//270 598//270 +f 602//249 604//249 603//249 601//249 +f 604//271 608//271 607//271 603//271 +f 608//251 606//251 605//251 607//251 +f 606//152 602//152 601//152 605//152 +f 605//272 601//272 610//272 612//272 +f 606//273 608//273 604//273 602//273 +f 611//274 612//274 616//274 615//274 +f 607//275 605//275 612//275 611//275 +f 601//276 603//276 609//276 610//276 +f 603//277 607//277 611//277 609//277 +f 615//251 616//251 620//251 619//251 +f 610//278 609//278 613//278 614//278 +f 612//279 610//279 614//279 616//279 +f 609//280 611//280 615//280 613//280 +f 620//281 618//281 622//281 624//281 +f 614//249 613//249 617//249 618//249 +f 616//282 614//282 618//282 620//282 +f 613//283 615//283 619//283 617//283 +f 621//284 623//284 627//284 625//284 +f 617//285 619//285 623//285 621//285 +f 619//286 620//286 624//286 623//286 +f 618//287 617//287 621//287 622//287 +f 626//288 625//288 627//288 628//288 +f 623//251 624//251 628//251 627//251 +f 622//249 621//249 625//249 626//249 +f 624//289 622//289 626//289 628//289 +f 645//290 648//290 735//290 733//290 +f 644//291 637//291 673//291 674//291 +f 816//292 642//292 646//292 821//292 +f 644//293 817//293 820//293 645//293 +f 821//294 646//294 647//294 823//294 +f 645//295 820//295 825//295 648//295 +f 656//296 649//296 734//296 739//296 +f 650//297 829//297 1001//297 770//297 +f 656//298 841//298 846//298 658//298 +f 660//299 651//299 736//299 738//299 +f 654//300 763//300 989//300 839//300 +f 757//301 759//301 758//301 733//301 735//301 +f 753//302 751//302 974//302 976//302 +f 755//303 652//303 837//303 980//303 +f 653//304 749//304 971//304 838//304 +f 841//305 656//305 651//305 832//305 +f 843//306 657//306 658//306 846//306 +f 828//307 649//307 657//307 843//307 +f 649//308 656//308 658//308 657//308 +f 667//309 860//309 851//309 661//309 +f 832//310 651//310 660//310 850//310 +f 665//311 778//311 785//311 783//311 +f 668//312 863//312 866//312 670//312 +f 778//313 779//313 784//313 785//313 +f 661//314 851//314 855//314 664//314 +f 662//315 666//315 774//315 775//315 +f 850//316 660//316 666//316 862//316 +f 661//317 664//317 779//317 776//317 +f 659//309 847//309 860//309 667//309 +f 669//251 668//251 670//251 663//251 +f 672//318 671//318 668//318 669//318 +f 868//319 669//319 663//319 869//319 +f 662//320 665//320 671//320 +f 869//321 663//321 670//321 866//321 +f 666//322 662//322 671//322 672//322 +f 862//323 666//323 672//323 669//323 868//323 +f 668//324 671//324 665//324 858//324 863//324 +f 673//325 872//325 876//325 675//325 +f 637//326 806//326 872//326 673//326 +f 817//327 644//327 674//327 874//327 +f 676//328 675//328 677//328 678//328 +f 874//329 674//329 676//329 878//329 +f 674//330 673//330 675//330 676//330 +f 678//331 677//331 679//331 680//331 +f 675//332 876//332 880//332 677//332 +f 878//333 676//333 678//333 882//333 +f 886//334 680//334 682//334 890//334 +f 677//335 880//335 884//335 679//335 +f 882//336 678//336 680//336 886//336 +f 890//337 682//337 684//337 894//337 +f 680//338 679//338 681//338 682//338 +f 679//339 884//339 888//339 681//339 +f 894//340 684//340 686//340 898//340 +f 682//341 681//341 683//341 684//341 +f 681//342 888//342 892//342 683//342 +f 686//343 685//343 687//343 688//343 +f 684//344 683//344 685//344 686//344 +f 683//345 892//345 896//345 685//345 +f 688//346 687//346 689//346 690//346 +f 685//347 896//347 900//347 687//347 +f 898//348 686//348 688//348 902//348 +f 690//349 689//349 691//349 692//349 +f 687//350 900//350 904//350 689//350 +f 902//351 688//351 690//351 906//351 +f 910//352 692//352 694//352 914//352 +f 689//353 904//353 908//353 691//353 +f 906//354 690//354 692//354 910//354 +f 692//355 691//355 693//355 694//355 +f 691//356 908//356 912//356 693//356 +f 648//357 825//357 969//357 747//357 +f 693//358 912//358 829//358 650//358 +f 731//359 730//359 733//359 758//359 756//359 732//359 +f 649//360 761//360 647//360 732//360 760//360 734//360 +f 735//361 745//361 746//361 737//361 742//361 765//361 748//361 741//361 +f 734//362 757//362 735//362 741//362 750//362 752//362 740//362 +f 737//363 736//363 743//363 767//363 762//363 742//363 +f 736//364 739//364 734//364 740//364 754//364 768//364 743//364 +f 736//365 737//365 744//365 780//365 781//365 738//365 +f 648//366 747//366 694//366 745//366 735//366 +f 693//367 650//367 737//367 746//367 +f 751//368 753//368 752//368 750//368 +f 647//369 646//369 731//369 732//369 +f 749//370 653//370 741//370 748//370 +f 694//371 693//371 746//371 745//371 +f 650//372 770//372 771//372 659//372 744//372 737//372 +f 641//373 640//373 639//373 637//373 730//373 731//373 +f 763//374 654//374 742//374 762//374 +f 651//375 656//375 739//375 736//375 +f 644//376 645//376 733//376 730//376 +f 652//377 755//377 754//377 740//377 +f 988//378 761//378 649//378 828//378 +f 747//379 969//379 914//379 694//379 +f 749//380 764//380 993//380 971//380 +f 764//381 749//381 748//381 765//381 +f 751//382 653//382 838//382 974//382 +f 653//383 751//383 750//383 741//383 +f 652//384 753//384 976//384 837//384 +f 753//385 652//385 740//385 752//385 +f 769//386 655//386 743//386 768//386 +f 655//387 769//387 998//387 840//387 +f 732//388 756//388 758//388 759//388 757//388 734//388 760//388 +f 646//389 642//389 731//389 +f 637//390 644//390 730//390 +f 823//391 647//391 761//391 988//391 +f 763//392 766//392 995//392 989//392 +f 766//393 763//393 762//393 767//393 +f 764//394 654//394 839//394 993//394 +f 654//395 764//395 765//395 742//395 +f 766//396 655//396 840//396 995//396 +f 655//397 766//397 767//397 743//397 +f 755//398 769//398 768//398 754//398 +f 769//399 755//399 980//399 998//399 +f 770//400 1001//400 1003//400 771//400 +f 771//401 1003//401 847//401 659//401 +f 642//402 641//402 731//402 +f 774//403 777//403 776//403 775//403 +f 775//404 776//404 779//404 778//404 +f 772//403 773//403 777//403 774//403 +f 665//405 662//405 775//405 778//405 +f 666//406 660//406 772//406 774//406 +f 667//407 661//407 776//407 777//407 +f 659//408 667//408 777//408 773//408 +f 738//409 781//409 772//409 660//409 +f 773//410 772//410 781//410 780//410 +f 780//411 744//411 659//411 773//411 +f 784//412 782//412 786//412 788//412 +f 783//413 785//413 789//413 787//413 +f 858//414 665//414 783//414 1018//414 +f 664//415 855//415 1015//415 782//415 +f 779//416 664//416 782//416 784//416 +f 786//417 787//417 789//417 788//417 +f 786//418 1021//418 1024//418 787//418 +f 1018//419 783//419 787//419 1024//419 +f 782//420 1015//420 1021//420 786//420 +f 785//421 784//421 788//421 789//421 +f 819//422 954//422 956//422 826//422 +f 818//423 875//423 873//423 807//423 +f 816//424 821//424 822//424 813//424 +f 818//293 819//293 820//293 817//293 +f 821//425 823//425 824//425 822//425 +f 819//295 826//295 825//295 820//295 +f 842//426 960//426 955//426 827//426 +f 830//427 1002//427 1001//427 829//427 +f 842//428 845//428 846//428 841//428 +f 849//429 959//429 957//429 831//429 +f 835//430 839//430 989//430 991//430 +f 983//431 956//431 954//431 984//431 985//431 +f 978//432 976//432 974//432 975//432 +f 981//433 980//433 837//433 833//433 +f 834//434 838//434 971//434 972//434 +f 841//435 832//435 831//435 842//435 +f 843//436 846//436 845//436 844//436 +f 828//437 843//437 844//437 827//437 +f 827//438 844//438 845//438 842//438 +f 861//309 852//309 851//309 860//309 +f 832//439 850//439 849//439 831//439 +f 857//440 1017//440 1020//440 1011//440 +f 864//441 867//441 866//441 863//441 +f 1011//442 1020//442 1019//442 1012//442 +f 852//443 856//443 855//443 851//443 +f 853//444 1008//444 1007//444 859//444 +f 850//445 862//445 859//445 849//445 +f 852//446 1009//446 1012//446 856//446 +f 848//309 861//309 860//309 847//309 +f 865//249 854//249 867//249 864//249 +f 871//447 865//447 864//447 870//447 +f 868//448 869//448 854//448 865//448 +f 853//449 870//449 857//449 +f 869//450 866//450 867//450 854//450 +f 859//451 871//451 870//451 853//451 +f 862//452 868//452 865//452 871//452 859//452 +f 864//453 863//453 858//453 857//453 870//453 +f 873//325 877//325 876//325 872//325 +f 807//326 873//326 872//326 806//326 +f 817//327 874//327 875//327 818//327 +f 879//454 883//454 881//454 877//454 +f 874//329 878//329 879//329 875//329 +f 875//455 879//455 877//455 873//455 +f 883//456 887//456 885//456 881//456 +f 877//332 881//332 880//332 876//332 +f 878//333 882//333 883//333 879//333 +f 886//334 890//334 891//334 887//334 +f 881//335 885//335 884//335 880//335 +f 882//336 886//336 887//336 883//336 +f 890//337 894//337 895//337 891//337 +f 887//457 891//457 889//457 885//457 +f 885//339 889//339 888//339 884//339 +f 894//340 898//340 899//340 895//340 +f 891//458 895//458 893//458 889//458 +f 889//342 893//342 892//342 888//342 +f 899//459 903//459 901//459 897//459 +f 895//460 899//460 897//460 893//460 +f 893//345 897//345 896//345 892//345 +f 903//461 907//461 905//461 901//461 +f 897//347 901//347 900//347 896//347 +f 898//462 902//462 903//462 899//462 +f 907//463 911//463 909//463 905//463 +f 901//350 905//350 904//350 900//350 +f 902//351 906//351 907//351 903//351 +f 910//464 914//464 915//464 911//464 +f 905//353 909//353 908//353 904//353 +f 906//354 910//354 911//354 907//354 +f 911//465 915//465 913//465 909//465 +f 909//466 913//466 912//466 908//466 +f 826//467 968//467 969//467 825//467 +f 913//358 830//358 829//358 912//358 +f 952//468 953//468 982//468 984//468 954//468 951//468 +f 827//469 955//469 986//469 953//469 824//469 987//469 +f 956//470 962//470 970//470 994//470 963//470 958//470 967//470 966//470 +f 955//471 961//471 977//471 973//471 962//471 956//471 983//471 +f 958//472 963//472 990//472 997//472 964//472 957//472 +f 957//473 964//473 999//473 979//473 961//473 955//473 960//473 +f 957//474 959//474 1014//474 1013//474 965//474 958//474 +f 826//475 956//475 966//475 915//475 968//475 +f 913//476 967//476 958//476 830//476 +f 975//477 973//477 977//477 978//477 +f 824//478 953//478 952//478 822//478 +f 972//479 970//479 962//479 834//479 +f 915//480 966//480 967//480 913//480 +f 830//481 958//481 965//481 848//481 1004//481 1002//481 +f 812//482 952//482 951//482 807//482 810//482 811//482 +f 991//483 990//483 963//483 835//483 +f 831//484 957//484 960//484 842//484 +f 818//485 951//485 954//485 819//485 +f 833//486 961//486 979//486 981//486 +f 988//487 828//487 827//487 987//487 +f 968//488 915//488 914//488 969//488 +f 972//489 971//489 993//489 992//489 +f 992//490 994//490 970//490 972//490 +f 975//491 974//491 838//491 834//491 +f 834//492 962//492 973//492 975//492 +f 833//493 837//493 976//493 978//493 +f 978//494 977//494 961//494 833//494 +f 1000//495 999//495 964//495 836//495 +f 836//496 840//496 998//496 1000//496 +f 953//497 986//497 955//497 983//497 985//497 984//497 982//497 +f 822//498 952//498 813//498 +f 807//499 951//499 818//499 +f 823//500 988//500 987//500 824//500 +f 991//501 989//501 995//501 996//501 +f 996//502 997//502 990//502 991//502 +f 992//503 993//503 839//503 835//503 +f 835//504 963//504 994//504 992//504 +f 996//505 995//505 840//505 836//505 +f 836//506 964//506 997//506 996//506 +f 981//507 979//507 999//507 1000//507 +f 1000//508 998//508 980//508 981//508 +f 1002//509 1004//509 1003//509 1001//509 +f 1004//510 848//510 847//510 1003//510 +f 813//511 952//511 812//511 +f 1007//512 1008//512 1009//512 1010//512 +f 1008//513 1011//513 1012//513 1009//513 +f 1005//512 1007//512 1010//512 1006//512 +f 857//514 1011//514 1008//514 853//514 +f 859//515 1007//515 1005//515 849//515 +f 861//516 1010//516 1009//516 852//516 +f 848//517 1006//517 1010//517 861//517 +f 959//518 849//518 1005//518 1014//518 +f 1006//519 1013//519 1014//519 1005//519 +f 1013//520 1006//520 848//520 965//520 +f 1019//521 1025//521 1022//521 1016//521 +f 1017//522 1023//522 1026//522 1020//522 +f 858//523 1018//523 1017//523 857//523 +f 856//524 1016//524 1015//524 855//524 +f 1012//525 1019//525 1016//525 856//525 +f 1022//526 1025//526 1026//526 1023//526 +f 1022//527 1023//527 1024//527 1021//527 +f 1018//528 1024//528 1023//528 1017//528 +f 1016//529 1022//529 1021//529 1015//529 +f 1020//530 1026//530 1025//530 1019//530 +f 1028//531 1029//531 1030//531 1027//531 +f 1038//532 1031//532 1066//532 1065//532 1057//532 1056//532 1044//532 1049//532 1070//532 1061//532 1058//532 1045//532 1037//532 1028//532 1027//532 1033//532 +f 1029//533 1028//533 1037//533 1032//533 +f 1033//534 1027//534 1030//534 1034//534 +f 1030//535 1029//535 1035//535 1036//535 +f 1029//536 1032//536 1039//536 1035//536 +f 1038//537 1033//537 1034//537 1040//537 1041//537 1042//537 +f 1034//538 1030//538 1036//538 1043//538 +f 1035//539 1044//539 1056//539 1036//539 +f 1059//540 1067//540 1103//540 1142//540 1232//540 1302//540 1268//540 1269//540 1147//540 1146//540 1198//540 1128//540 1031//540 1038//540 1060//540 1046//540 +f 1032//541 1037//541 1045//541 1047//541 +f 1032//542 1047//542 1048//542 1039//542 +f 1039//543 1049//543 1044//543 1035//543 +f 1131//544 1130//544 1176//544 1071//544 1042//544 +f 1040//537 1034//537 1050//537 1051//537 +f 1132//545 1131//545 1042//545 1041//545 +f 1069//537 1060//537 1038//537 1042//537 1071//537 1106//537 +f 1052//537 1053//537 1054//537 1055//537 1050//537 1034//537 1043//537 +f 1043//546 1036//546 1056//546 1057//546 +f 1058//547 1061//547 1048//547 1047//547 +f 1039//548 1048//548 1070//548 1049//548 +f 1188//549 1134//549 1133//549 1051//549 1050//549 1055//549 +f 1260//550 1189//550 1188//550 1055//550 1054//550 1063//550 1099//550 +f 1052//537 1043//537 1062//537 +f 1187//551 1186//551 1073//551 1053//551 +f 1054//537 1053//537 1063//537 +f 1249//552 1248//552 1261//552 1260//552 1099//552 1098//552 1145//552 +f 1186//553 1185//553 1074//553 1073//553 +f 1045//554 1058//554 1047//554 +f 1046//555 1068//555 1105//555 1059//555 +f 1069//556 1068//556 1046//556 1060//556 +f 1061//557 1070//557 1048//557 +f 1031//558 1101//558 1102//558 1066//558 +f 1067//559 1059//559 1105//559 1104//559 +f 1176//560 1175//560 1106//560 1071//560 +f 1107//561 1108//561 1068//561 1069//561 +f 1138//562 1137//562 1064//562 1100//562 +f 1185//563 1179//563 1178//563 1227//563 1074//563 +f 1329//564 1252//564 1251//564 1109//564 1076//564 +f 1077//565 1076//565 1109//565 1110//565 1111//565 1112//565 1113//565 +f 1327//566 1326//566 1079//566 1078//566 +f 1181//567 1180//567 1191//567 1148//567 1272//567 +f 1081//568 1114//568 1115//568 1082//568 +f 1330//569 1257//569 1262//569 1317//569 1085//569 1084//569 +f 1317//570 1316//570 1378//570 1116//570 1085//570 +f 1116//571 1214//571 1288//571 1215//571 1117//571 1086//571 1085//571 +f 1289//572 1352//572 1395//572 1350//572 1215//572 1288//572 1405//572 +f 1118//573 1119//573 1120//573 1121//573 1122//573 1088//573 1087//573 +f 1314//574 1247//574 1246//574 1090//574 1089//574 +f 1092//575 1123//575 1124//575 1093//575 +f 1171//576 1170//576 1270//576 1197//576 +f 1137//577 1136//577 1072//577 1064//577 +f 1065//578 1066//578 1141//578 1338//578 1386//578 1363//578 1362//578 1380//578 1333//578 1264//578 1192//578 1263//578 1299//578 1228//578 1166//578 1126//578 1127//578 +f 1128//579 1129//579 1101//579 1031//579 +f 1102//580 1101//580 1130//580 1131//580 1132//580 1133//580 1134//580 1135//580 1136//580 1137//580 1138//580 1139//580 +f 1066//581 1102//581 1140//581 1141//581 +f 1103//582 1067//582 1104//582 1143//582 +f 1108//583 1144//583 1105//583 1068//583 +f 1146//584 1147//584 1108//584 1107//584 +f 1177//585 1139//585 1138//585 1100//585 1165//585 +f 1110//586 1149//586 1150//586 1111//586 +f 1191//587 1190//587 1259//587 1075//587 1148//587 +f 1328//588 1327//588 1078//588 1077//588 1113//588 +f 1151//589 1152//589 1114//589 1081//589 +f 1153//590 1115//590 1114//590 1154//590 +f 1082//591 1115//591 1155//591 1156//591 +f 1326//592 1321//592 1320//592 1080//592 1079//592 +f 1348//593 1349//593 1214//593 +f 1373//594 1372//594 1350//594 1395//594 +f 1119//595 1157//595 1158//595 1120//595 +f 1375//596 1309//596 1308//596 1118//596 1087//596 +f 1308//597 1307//597 1351//597 1118//597 +f 1159//598 1160//598 1123//598 1092//598 +f 1123//599 1161//599 1162//599 1124//599 +f 1093//600 1124//600 1163//600 1164//600 +f 1170//601 1169//601 1242//601 1226//601 1270//601 +f 1178//602 1177//602 1165//602 1227//602 +f 1167//603 1168//603 1129//603 1128//603 +f 1101//604 1129//604 1169//604 1170//604 1171//604 1172//604 1173//604 1174//604 1175//604 1176//604 1130//604 +f 1140//605 1102//605 1139//605 1177//605 1178//605 1179//605 1180//605 1181//605 1182//605 1183//605 1184//605 +f 1180//606 1179//606 1185//606 1186//606 1187//606 1135//606 1134//606 1188//606 1189//606 1190//606 1191//606 +f 1141//607 1140//607 1193//607 1194//607 +f 1103//608 1143//608 1142//608 +f 1105//609 1144//609 1195//609 1104//609 +f 1104//610 1195//610 1196//610 1143//610 +f 1108//611 1147//611 1269//611 1144//611 +f 1136//612 1135//612 1187//612 1053//612 1052//612 1062//612 1072//612 +f 1243//613 1173//613 1172//613 1125//613 1097//613 +f 1100//537 1064//537 1072//537 1062//537 1043//537 1057//537 1065//537 1127//537 1231//537 1271//537 1272//537 1148//537 1075//537 1074//537 1227//537 1165//537 +f 1200//568 1201//568 1149//568 1110//568 +f 1202//614 1150//614 1149//614 1203//614 +f 1111//578 1150//578 1204//578 1205//578 +f 1255//615 1254//615 1112//615 1206//615 +f 1319//616 1318//616 1281//616 1207//616 +f 1337//617 1385//617 1386//617 1273//617 1200//617 1110//617 1199//617 1109//617 +f 1208//618 1194//618 1267//618 1212//618 1156//618 1155//618 1211//618 1286//618 1383//618 1336//618 1346//618 1389//618 1345//618 1283//618 1152//618 1151//618 1282//618 +f 1114//619 1152//619 1283//619 1154//619 +f 1154//620 1209//620 1210//620 1153//620 +f 1153//621 1211//621 1155//621 1115//621 +f 1080//622 1207//622 1281//622 1282//622 1151//622 1081//622 +f 1368//623 1367//623 1287//623 1392//623 +f 1216//624 1217//624 1157//624 1119//624 +f 1218//625 1158//625 1157//625 1219//625 +f 1120//626 1158//626 1220//626 1221//626 +f 1313//627 1312//627 1357//627 1294//627 +f 1123//628 1160//628 1295//628 1161//628 +f 1162//629 1161//629 1223//629 1224//629 +f 1162//630 1225//630 1163//630 1124//630 +f 1164//631 1163//631 1225//631 1358//631 1359//631 1304//631 1233//631 1303//631 1296//631 1295//631 1160//631 1159//631 1222//631 1167//631 1128//631 1198//631 +f 1379//632 1315//632 1314//632 1089//632 1088//632 1122//632 +f 1244//633 1243//633 1097//633 1096//633 +f 1198//634 1270//634 1226//634 1094//634 1093//634 1164//634 +f 1242//635 1241//635 1094//635 1226//635 +f 1245//636 1244//636 1096//636 1095//636 +f 1166//637 1229//637 1230//637 1126//637 +f 1127//638 1126//638 1230//638 1231//638 +f 1234//639 1235//639 1168//639 1167//639 +f 1129//640 1168//640 1236//640 1237//640 1238//640 1239//640 1240//640 1241//640 1242//640 1169//640 +f 1174//606 1173//606 1243//606 1244//606 1245//606 1240//606 1239//606 1246//606 1247//606 1248//606 1249//606 +f 1193//641 1140//641 1184//641 1250//641 1251//641 1252//641 1253//641 1254//641 1255//641 1256//641 +f 1257//606 1258//606 1259//606 1190//606 1189//606 1260//606 1261//606 1262//606 +f 1194//642 1193//642 1266//642 1267//642 +f 1142//557 1143//557 1196//557 1232//557 +f 1195//643 1144//643 1269//643 1268//643 +f 1195//644 1268//644 1302//644 1196//644 +f 1183//645 1182//645 1384//645 1385//645 +f 1273//646 1274//646 1201//646 1200//646 +f 1203//590 1149//590 1201//590 1275//590 +f 1203//647 1276//647 1277//647 1202//647 +f 1150//648 1202//648 1278//648 1204//648 +f 1205//649 1204//649 1279//649 1280//649 +f 1154//650 1283//650 1345//650 1209//650 +f 1209//651 1284//651 1285//651 1210//651 +f 1210//652 1286//652 1211//652 1153//652 +f 1157//653 1217//653 1353//653 1219//653 +f 1218//654 1219//654 1290//654 1291//654 +f 1218//655 1292//655 1220//655 1158//655 +f 1364//595 1398//595 1354//595 1353//595 1217//595 1216//595 1289//595 1234//595 1167//595 1222//595 1221//595 1220//595 1292//595 1397//595 1365//595 1305//595 +f 1162//656 1224//656 1358//656 1225//656 +f 1223//657 1161//657 1295//657 1296//657 +f 1224//658 1223//658 1297//658 1298//658 +f 1241//659 1240//659 1245//659 1095//659 1094//659 +f 1228//660 1300//660 1229//660 1166//660 +f 1231//578 1230//578 1301//578 1271//578 +f 1267//661 1266//661 1235//661 1234//661 +f 1168//662 1235//662 1306//662 1307//662 1308//662 1309//662 1310//662 1311//662 1312//662 1313//662 1236//662 +f 1262//606 1261//606 1248//606 1247//606 1314//606 1315//606 1316//606 1317//606 +f 1266//663 1193//663 1256//663 1318//663 1319//663 1320//663 1321//663 1322//663 1323//663 1324//663 1325//663 +f 1322//606 1321//606 1326//606 1327//606 1328//606 1253//606 1252//606 1329//606 1258//606 1257//606 1330//606 +f 1263//554 1192//554 1331//554 1332//554 +f 1192//547 1264//547 1331//547 +f 1232//547 1196//547 1302//547 +f 1250//664 1184//664 1183//664 1385//664 1337//664 +f 1275//665 1201//665 1274//665 1339//665 +f 1275//620 1340//620 1276//620 1203//620 +f 1276//666 1341//666 1342//666 1277//666 +f 1202//667 1277//667 1343//667 1278//667 +f 1344//535 1279//535 1204//535 1278//535 +f 1111//668 1205//668 1280//668 1282//668 1281//668 1206//668 1112//668 +f 1346//669 1336//669 1285//669 1284//669 +f 1323//670 1322//670 1330//670 1084//670 1083//670 +f 1367//671 1325//671 1324//671 1213//671 1287//671 +f 1291//672 1290//672 1355//672 1356//672 +f 1119//673 1118//673 1351//673 1352//673 1289//673 1216//673 +f 1294//674 1357//674 1121//674 1120//674 1221//674 1222//674 +f 1304//608 1298//608 1297//608 1233//608 +f 1299//675 1332//675 1300//675 1228//675 +f 1230//648 1229//648 1360//648 1301//648 +f 1229//667 1300//667 1361//667 1360//667 +f 1271//676 1301//676 1362//676 1363//676 +f 1233//557 1297//557 1303//557 +f 1235//677 1266//677 1325//677 1367//677 1368//677 1369//677 1370//677 1371//677 1372//677 1373//677 1374//677 1306//677 +f 1310//606 1309//606 1375//606 1376//606 1377//606 1371//606 1370//606 1378//606 1316//606 1315//606 1379//606 +f 1299//678 1263//678 1332//678 +f 1300//679 1332//679 1331//679 1361//679 +f 1333//680 1361//680 1331//680 1264//680 +f 1334//669 1265//669 1341//669 +f 1265//678 1335//678 1342//678 1341//678 +f 1182//681 1181//681 1272//681 1384//681 +f 1259//682 1258//682 1329//682 1076//682 1075//682 +f 1251//683 1250//683 1337//683 1109//683 +f 1141//684 1194//684 1208//684 1282//684 1280//684 1279//684 1344//684 1388//684 1401//684 1382//684 1335//684 1265//684 1334//684 1381//684 1387//684 1339//684 1274//684 1273//684 1386//684 1338//684 +f 1339//685 1387//685 1340//685 1275//685 +f 1276//651 1340//651 1381//651 1334//651 1341//651 +f 1342//679 1382//679 1401//679 1343//679 1277//679 +f 1388//536 1344//536 1278//536 1343//536 +f 1199//686 1110//686 1109//686 +f 1254//687 1253//687 1328//687 1113//687 1112//687 +f 1389//688 1284//688 1209//688 1345//688 +f 1389//689 1346//689 1284//689 +f 1336//690 1383//690 1285//690 +f 1383//691 1286//691 1210//691 1285//691 +f 1324//692 1323//692 1083//692 1213//692 +f 1390//693 1347//693 1391//693 1212//693 1267//693 1234//693 1289//693 1405//693 1396//693 1406//693 1412//693 1409//693 1400//693 1366//693 1399//693 1402//693 +f 1214//537 1349//537 1288//537 +f 1320//694 1319//694 1207//694 1080//694 +f 1378//695 1370//695 1369//695 1348//695 1214//695 1116//695 +f 1349//646 1393//646 1394//646 1288//646 +f 1374//696 1373//696 1395//696 1352//696 +f 1307//697 1306//697 1374//697 1352//697 1351//697 +f 1377//698 1376//698 1086//698 1117//698 +f 1353//699 1354//699 1290//699 1219//699 +f 1397//700 1292//700 1218//700 1291//700 +f 1354//701 1398//701 1355//701 1290//701 +f 1291//702 1356//702 1365//702 1397//702 +f 1305//703 1356//703 1355//703 1364//703 +f 1312//704 1311//704 1121//704 1357//704 +f 1311//705 1310//705 1379//705 1122//705 1121//705 +f 1372//706 1371//706 1377//706 1117//706 1215//706 1350//706 +f 1358//707 1224//707 1298//707 1359//707 +f 1303//708 1297//708 1223//708 1296//708 +f 1359//709 1298//709 1304//709 +f 1360//710 1380//710 1362//710 1301//710 +f 1361//711 1333//711 1380//711 1360//711 +f 1384//712 1272//712 1271//712 1363//712 1386//712 1385//712 +f 1365//689 1356//689 1305//689 +f 1335//713 1382//713 1342//713 +f 1387//714 1381//714 1340//714 +f 1401//542 1388//542 1343//542 +f 1390//715 1403//715 1393//715 1347//715 +f 1391//716 1347//716 1393//716 1349//716 +f 1404//665 1394//665 1393//665 1403//665 +f 1288//717 1394//717 1396//717 1405//717 +f 1376//718 1375//718 1087//718 1086//718 +f 1364//719 1355//719 1398//719 +f 1366//703 1407//703 1399//703 +f 1400//689 1408//689 1407//689 1366//689 +f 1390//720 1402//720 1410//720 1403//720 +f 1404//685 1403//685 1410//685 1411//685 +f 1404//721 1406//721 1396//721 1394//721 +f 1399//722 1407//722 1410//722 1402//722 +f 1409//669 1408//669 1400//669 +f 1411//714 1410//714 1407//714 1408//714 +f 1404//723 1411//723 1412//723 1406//723 +f 1409//724 1412//724 1411//724 1408//724 +f 1318//725 1256//725 1255//725 1206//725 1281//725 +f 1133//726 1132//726 1041//726 1040//726 1051//726 +f 1107//537 1069//537 1106//537 1145//537 1098//537 +f 1175//727 1174//727 1249//727 1145//727 1106//727 +f 1125//571 1107//571 1098//571 1097//571 +f 1172//728 1171//728 1197//728 1125//728 +f 1197//729 1270//729 1198//729 1146//729 1107//729 1125//729 +f 1237//730 1236//730 1313//730 1294//730 1293//730 +f 1053//537 1073//537 1074//537 1075//537 1076//537 1077//537 1078//537 1079//537 1080//537 1081//537 1082//537 1083//537 1084//537 1085//537 1086//537 1087//537 1088//537 1089//537 1090//537 1091//537 1092//537 1093//537 1094//537 1095//537 1096//537 1097//537 1098//537 1099//537 1063//537 +f 1091//573 1293//573 1294//573 1222//573 1159//573 1092//573 +f 1238//731 1237//731 1293//731 1091//731 +f 1246//732 1239//732 1238//732 1091//732 1090//732 +f 1369//733 1368//733 1392//733 1348//733 +f 1082//734 1156//734 1212//734 1287//734 1213//734 1083//734 +f 1212//735 1391//735 1349//735 1348//735 1392//735 1287//735 +usemtl Black +f 794//736 632//736 631//736 795//736 +f 635//737 637//737 703//737 701//737 +f 629//738 797//738 800//738 633//738 +f 632//739 794//739 802//739 635//739 +f 630//740 796//740 797//740 629//740 +f 800//741 801//741 634//741 633//741 +f 795//742 631//742 634//742 801//742 +f 639//743 640//743 707//743 706//743 +f 641//744 638//744 705//744 704//744 +f 796//745 630//745 636//745 805//745 +f 633//746 634//746 700//746 699//746 +f 805//747 636//747 638//747 809//747 +f 635//748 802//748 806//748 637//748 +f 638//749 641//749 642//749 643//749 +f 643//750 642//750 816//750 815//750 +f 809//751 638//751 643//751 815//751 +f 700//251 696//251 709//251 713//251 +f 702//251 697//251 710//251 715//251 +f 702//251 701//251 703//251 706//251 707//251 704//251 705//251 +f 698//251 699//251 712//251 711//251 +f 640//752 641//752 704//752 707//752 +f 638//753 636//753 702//753 705//753 +f 631//754 632//754 695//754 696//754 +f 629//755 633//755 699//755 698//755 +f 632//756 635//756 701//756 695//756 +f 634//757 631//757 696//757 700//757 +f 636//758 630//758 697//758 702//758 +f 630//759 629//759 698//759 697//759 +f 637//760 639//760 706//760 703//760 +f 699//251 700//251 713//251 712//251 +f 697//251 698//251 711//251 710//251 +f 696//251 695//251 708//251 709//251 +f 695//251 701//251 714//251 708//251 +f 701//251 702//251 715//251 726//251 716//251 729//251 714//251 +f 794//736 795//736 792//736 793//736 +f 803//761 922//761 924//761 807//761 +f 790//738 798//738 800//738 797//738 +f 793//739 803//739 802//739 794//739 +f 791//740 790//740 797//740 796//740 +f 800//741 798//741 799//741 801//741 +f 795//742 801//742 799//742 792//742 +f 810//762 927//762 928//762 811//762 +f 812//763 925//763 926//763 808//763 +f 796//745 805//745 804//745 791//745 +f 798//764 920//764 921//764 799//764 +f 805//747 809//747 808//747 804//747 +f 803//748 807//748 806//748 802//748 +f 808//765 814//765 813//765 812//765 +f 814//766 815//766 816//766 813//766 +f 809//751 815//751 814//751 808//751 +f 921//249 934//249 930//249 917//249 +f 923//249 936//249 931//249 918//249 +f 923//249 926//249 925//249 928//249 927//249 924//249 922//249 +f 919//249 932//249 933//249 920//249 +f 811//767 928//767 925//767 812//767 +f 808//768 926//768 923//768 804//768 +f 792//769 917//769 916//769 793//769 +f 790//770 919//770 920//770 798//770 +f 793//771 916//771 922//771 803//771 +f 799//772 921//772 917//772 792//772 +f 804//773 923//773 918//773 791//773 +f 791//774 918//774 919//774 790//774 +f 807//775 924//775 927//775 810//775 +f 920//249 933//249 934//249 921//249 +f 918//249 931//249 932//249 919//249 +f 917//249 930//249 929//249 916//249 +f 916//249 929//249 935//249 922//249 +f 922//249 935//249 950//249 937//249 947//249 936//249 923//249 +usemtl Wood +f 710//776 711//776 720//776 719//776 +f 711//777 712//777 721//777 720//777 +f 708//778 714//778 725//778 717//778 +f 717//251 719//251 720//251 718//251 +f 718//251 720//251 721//251 722//251 +f 719//251 717//251 725//251 728//251 723//251 727//251 724//251 +f 715//779 710//779 719//779 724//779 +f 729//780 716//780 723//780 728//780 +f 713//781 709//781 718//781 722//781 +f 709//782 708//782 717//782 718//782 +f 726//783 715//783 724//783 727//783 +f 712//784 713//784 722//784 721//784 +f 716//785 726//785 727//785 723//785 +f 714//786 729//786 728//786 725//786 +f 931//776 940//776 941//776 932//776 +f 932//777 941//777 942//777 933//777 +f 929//778 938//778 946//778 935//778 +f 938//249 939//249 941//249 940//249 +f 939//249 943//249 942//249 941//249 +f 940//249 945//249 948//249 944//249 949//249 946//249 938//249 +f 936//779 945//779 940//779 931//779 +f 950//787 949//787 944//787 937//787 +f 934//781 943//781 939//781 930//781 +f 930//782 939//782 938//782 929//782 +f 947//788 948//788 945//788 936//788 +f 933//784 942//784 943//784 934//784 +f 937//789 944//789 948//789 947//789 +f 935//790 946//790 949//790 950//790 diff --git a/assets/quaternius/models/Revolver.obj.import b/assets/quaternius/models/Revolver.obj.import new file mode 100644 index 0000000..4d833b2 --- /dev/null +++ b/assets/quaternius/models/Revolver.obj.import @@ -0,0 +1,25 @@ +[remap] + +importer="wavefront_obj" +importer_version=1 +type="Mesh" +uid="uid://daivcihpvdn5q" +path="res://.godot/imported/Revolver.obj-d2a80e1f299a317971f481f2a64d6638.mesh" + +[deps] + +files=["res://.godot/imported/Revolver.obj-d2a80e1f299a317971f481f2a64d6638.mesh"] + +source_file="res://assets/quaternius/models/Revolver.obj" +dest_files=["res://.godot/imported/Revolver.obj-d2a80e1f299a317971f481f2a64d6638.mesh", "res://.godot/imported/Revolver.obj-d2a80e1f299a317971f481f2a64d6638.mesh"] + +[params] + +generate_tangents=true +generate_lods=true +generate_shadow_mesh=true +generate_lightmap_uv2=false +generate_lightmap_uv2_texel_size=0.2 +scale_mesh=Vector3(1, 1, 1) +offset_mesh=Vector3(0, 0, 0) +force_disable_mesh_compression=false diff --git a/assets/quaternius/models/Rifle.glb b/assets/quaternius/models/Rifle.glb new file mode 100644 index 0000000..075e362 Binary files /dev/null and b/assets/quaternius/models/Rifle.glb differ diff --git a/assets/kenney-fps/models/blaster.glb.import b/assets/quaternius/models/Rifle.glb.import similarity index 64% rename from assets/kenney-fps/models/blaster.glb.import rename to assets/quaternius/models/Rifle.glb.import index a1b627c..07e1a9e 100644 --- a/assets/kenney-fps/models/blaster.glb.import +++ b/assets/quaternius/models/Rifle.glb.import @@ -3,19 +3,21 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://b2p7bbkuxf7m" -path="res://.godot/imported/blaster.glb-865d95bc6d15a20a70b45829eaeb4dc5.scn" +uid="uid://dq6hh5r08lg30" +path="res://.godot/imported/Rifle.glb-8f0d9d0b7acc6e4bd68aa2695c1cdf0b.scn" [deps] -source_file="res://models/blaster.glb" -dest_files=["res://.godot/imported/blaster.glb-865d95bc6d15a20a70b45829eaeb4dc5.scn"] +source_file="res://assets/quaternius/models/Rifle.glb" +dest_files=["res://.godot/imported/Rifle.glb-8f0d9d0b7acc6e4bd68aa2695c1cdf0b.scn"] [params] -nodes/root_type="Node3D" -nodes/root_name="Scene Root" +nodes/root_type="" +nodes/root_name="" nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true nodes/apply_root_scale=true nodes/root_scale=1.0 nodes/import_as_skeleton_bones=false @@ -38,5 +40,6 @@ materials/extract=0 materials/extract_format=0 materials/extract_path="" _subresources={} -gltf/naming_version=0 +gltf/naming_version=2 gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/assets/quaternius/models/Rifle.mtl b/assets/quaternius/models/Rifle.mtl new file mode 100644 index 0000000..d430f88 --- /dev/null +++ b/assets/quaternius/models/Rifle.mtl @@ -0,0 +1,72 @@ +# Blender MTL File: 'Rifle.blend' +# Material Count: 7 + +newmtl Barrels +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Black +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl BulletOrange +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl BulletYellow +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl DarkWood +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl LightWood +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Metal +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 diff --git a/assets/quaternius/models/Rifle.obj b/assets/quaternius/models/Rifle.obj new file mode 100644 index 0000000..1f2ea13 --- /dev/null +++ b/assets/quaternius/models/Rifle.obj @@ -0,0 +1,2235 @@ +# Blender v2.76 (sub 0) OBJ File: 'Rifle.blend' +# www.blender.org +mtllib Rifle.mtl +o Rifle +v -0.140135 0.346864 2.318867 +v -0.140135 0.346864 2.119779 +v -0.140135 -0.021472 2.318867 +v -0.140135 -0.021472 2.119779 +v 0.055533 0.346864 2.318867 +v 0.055533 0.346864 2.119779 +v 0.055533 -0.021472 2.318867 +v 0.055533 -0.021472 2.119779 +v 0.044267 -0.021472 2.119779 +v 0.044267 -0.021472 2.318867 +v 0.044267 0.346864 2.119779 +v 0.044267 0.346864 2.318867 +v -0.124742 -0.021472 2.318867 +v -0.124742 0.346864 2.119779 +v -0.124742 -0.021472 2.119779 +v -0.124742 0.346864 2.318867 +v 0.044267 0.339199 2.119779 +v 0.044267 0.339199 2.318867 +v -0.124742 0.339199 2.318867 +v -0.124742 0.339199 2.119779 +v -0.140135 0.339199 2.119779 +v -0.140135 0.339199 2.318867 +v 0.055533 0.339199 2.119779 +v 0.055533 0.339199 2.318867 +v 0.001362 0.343587 1.997540 +v -0.002200 0.346342 2.319592 +v -0.031063 0.330151 1.997540 +v -0.035530 0.332532 2.319592 +v -0.044495 0.297715 1.997540 +v -0.049335 0.299191 2.319592 +v -0.031063 0.265279 1.997540 +v -0.035530 0.265851 2.319592 +v 0.001362 0.251843 1.997540 +v -0.002200 0.252041 2.319592 +v 0.033788 0.265279 1.997540 +v 0.031129 0.265851 2.319592 +v 0.047219 0.297715 1.997540 +v 0.044935 0.299191 2.319592 +v 0.033788 0.330151 1.997540 +v 0.031129 0.332532 2.319592 +v 0.001362 0.332307 1.969923 +v -0.023090 0.322175 1.969923 +v -0.033218 0.297715 1.969923 +v -0.023090 0.273255 1.969923 +v 0.001362 0.263124 1.969923 +v 0.025814 0.273255 1.969923 +v 0.035942 0.297715 1.969923 +v 0.025814 0.322175 1.969923 +v 0.001362 0.332306 1.884088 +v -0.023090 0.322175 1.884088 +v -0.033218 0.297715 1.884088 +v -0.023090 0.273255 1.884088 +v 0.001362 0.263124 1.884088 +v 0.025814 0.273255 1.884088 +v 0.035942 0.297715 1.884088 +v 0.025814 0.322175 1.884088 +v 0.001362 0.324811 1.884088 +v -0.017792 0.316875 1.884088 +v -0.025725 0.297715 1.884088 +v -0.017792 0.278555 1.884088 +v 0.001362 0.270619 1.884088 +v 0.020516 0.278555 1.884088 +v 0.028449 0.297715 1.884088 +v 0.020516 0.316875 1.884088 +v 0.001362 0.318688 1.814492 +v -0.013463 0.312545 1.814492 +v -0.019604 0.297715 1.814492 +v -0.013463 0.282885 1.814492 +v 0.001362 0.276743 1.814492 +v 0.016187 0.282885 1.814492 +v 0.022328 0.297715 1.814492 +v 0.016187 0.312545 1.814492 +v 0.001362 0.297715 1.749314 +v 0.001362 0.251688 1.997540 +v -0.002200 0.254444 2.319592 +v -0.031063 0.238253 1.997540 +v -0.035530 0.240633 2.319592 +v -0.044495 0.205817 1.997540 +v -0.049335 0.207293 2.319592 +v -0.031063 0.173381 1.997540 +v -0.035530 0.173952 2.319592 +v 0.001362 0.159945 1.997540 +v -0.002200 0.160142 2.319592 +v 0.033788 0.173381 1.997540 +v 0.031129 0.173952 2.319592 +v 0.047219 0.205817 1.997540 +v 0.044935 0.207293 2.319592 +v 0.033788 0.238253 1.997540 +v 0.031129 0.240633 2.319592 +v 0.001362 0.240408 1.969923 +v -0.023090 0.230277 1.969923 +v -0.033218 0.205817 1.969923 +v -0.023090 0.181357 1.969923 +v 0.001362 0.171226 1.969923 +v 0.025814 0.181357 1.969923 +v 0.035942 0.205817 1.969923 +v 0.025814 0.230277 1.969923 +v 0.001362 0.240408 1.884088 +v -0.023090 0.230277 1.884088 +v -0.033218 0.205817 1.884088 +v -0.023090 0.181357 1.884088 +v 0.001362 0.171225 1.884088 +v 0.025814 0.181357 1.884088 +v 0.035942 0.205817 1.884088 +v 0.025814 0.230277 1.884088 +v 0.001362 0.232913 1.884088 +v -0.017792 0.224977 1.884088 +v -0.025725 0.205817 1.884088 +v -0.017792 0.186657 1.884088 +v 0.001362 0.178721 1.884088 +v 0.020516 0.186657 1.884088 +v 0.028449 0.205817 1.884088 +v 0.020516 0.224977 1.884088 +v 0.001362 0.226789 1.814492 +v -0.013463 0.220647 1.814492 +v -0.019604 0.205817 1.814492 +v -0.013463 0.190987 1.814492 +v 0.001362 0.184844 1.814492 +v 0.016187 0.190987 1.814492 +v 0.022328 0.205817 1.814492 +v 0.016187 0.220647 1.814492 +v 0.001362 0.205817 1.749314 +v 0.001362 0.158734 1.997540 +v -0.002200 0.161489 2.319592 +v -0.031063 0.145298 1.997540 +v -0.035530 0.147679 2.319592 +v -0.044495 0.112862 1.997540 +v -0.049335 0.114338 2.319592 +v -0.031063 0.080426 1.997540 +v -0.035530 0.080998 2.319592 +v 0.001362 0.066991 1.997540 +v -0.002200 0.067188 2.319592 +v 0.033788 0.080426 1.997540 +v 0.031129 0.080998 2.319592 +v 0.047219 0.112862 1.997540 +v 0.044935 0.114338 2.319592 +v 0.033788 0.145298 1.997540 +v 0.031129 0.147679 2.319592 +v 0.001362 0.147454 1.969923 +v -0.023090 0.137322 1.969923 +v -0.033218 0.112862 1.969923 +v -0.023090 0.088403 1.969923 +v 0.001362 0.078271 1.969923 +v 0.025814 0.088403 1.969923 +v 0.035942 0.112862 1.969923 +v 0.025814 0.137322 1.969923 +v 0.001362 0.147454 1.884088 +v -0.023090 0.137322 1.884088 +v -0.033218 0.112862 1.884088 +v -0.023090 0.088402 1.884088 +v 0.001362 0.078271 1.884088 +v 0.025814 0.088402 1.884088 +v 0.035942 0.112862 1.884088 +v 0.025814 0.137322 1.884088 +v 0.001362 0.139959 1.884088 +v -0.017792 0.132022 1.884088 +v -0.025725 0.112862 1.884088 +v -0.017792 0.093702 1.884088 +v 0.001362 0.085766 1.884088 +v 0.020516 0.093702 1.884088 +v 0.028449 0.112862 1.884088 +v 0.020516 0.132022 1.884088 +v 0.001362 0.133835 1.814492 +v -0.013463 0.127692 1.814492 +v -0.019604 0.112862 1.814492 +v -0.013463 0.098033 1.814492 +v 0.001362 0.091890 1.814492 +v 0.016187 0.098033 1.814492 +v 0.022328 0.112862 1.814492 +v 0.016187 0.127692 1.814492 +v 0.001362 0.112862 1.749314 +v 0.001362 0.067892 1.997540 +v -0.002200 0.070647 2.319592 +v -0.031063 0.054456 1.997540 +v -0.035530 0.056837 2.319592 +v -0.044495 0.022020 1.997540 +v -0.049335 0.023496 2.319592 +v -0.031063 -0.010416 1.997540 +v -0.035530 -0.009844 2.319592 +v 0.001362 -0.023851 1.997540 +v -0.002200 -0.023654 2.319592 +v 0.033788 -0.010416 1.997540 +v 0.031129 -0.009844 2.319592 +v 0.047219 0.022020 1.997540 +v 0.044935 0.023496 2.319592 +v 0.033788 0.054456 1.997540 +v 0.031129 0.056837 2.319592 +v 0.001362 0.056612 1.969923 +v -0.023090 0.046480 1.969923 +v -0.033218 0.022020 1.969923 +v -0.023090 -0.002440 1.969923 +v 0.001362 -0.012571 1.969923 +v 0.025814 -0.002440 1.969923 +v 0.035942 0.022020 1.969923 +v 0.025814 0.046480 1.969923 +v 0.001362 0.056612 1.884088 +v -0.023090 0.046480 1.884088 +v -0.033218 0.022020 1.884088 +v -0.023090 -0.002440 1.884088 +v 0.001362 -0.012571 1.884088 +v 0.025814 -0.002440 1.884088 +v 0.035942 0.022020 1.884088 +v 0.025814 0.046480 1.884088 +v 0.001362 0.049117 1.884088 +v -0.017792 0.041180 1.884088 +v -0.025725 0.022020 1.884088 +v -0.017792 0.002860 1.884088 +v 0.001362 -0.005076 1.884088 +v 0.020516 0.002860 1.884088 +v 0.028449 0.022020 1.884088 +v 0.020516 0.041180 1.884088 +v 0.001362 0.042993 1.814492 +v -0.013463 0.036850 1.814492 +v -0.019604 0.022020 1.814492 +v -0.013463 0.007190 1.814492 +v 0.001362 0.001048 1.814492 +v 0.016187 0.007190 1.814492 +v 0.022328 0.022020 1.814492 +v 0.016187 0.036850 1.814492 +v 0.001362 0.022020 1.749314 +v -0.089450 0.067892 1.997540 +v -0.093012 0.070647 2.319592 +v -0.121876 0.054456 1.997540 +v -0.126342 0.056837 2.319592 +v -0.135307 0.022020 1.997540 +v -0.140148 0.023496 2.319592 +v -0.121876 -0.010416 1.997540 +v -0.126342 -0.009844 2.319592 +v -0.089450 -0.023851 1.997540 +v -0.093012 -0.023654 2.319592 +v -0.057025 -0.010416 1.997540 +v -0.059683 -0.009844 2.319592 +v -0.043594 0.022020 1.997540 +v -0.045877 0.023496 2.319592 +v -0.057025 0.054456 1.997540 +v -0.059683 0.056837 2.319592 +v -0.089450 0.056612 1.969923 +v -0.113902 0.046480 1.969923 +v -0.124030 0.022020 1.969923 +v -0.113902 -0.002440 1.969923 +v -0.089450 -0.012571 1.969923 +v -0.064998 -0.002440 1.969923 +v -0.054870 0.022020 1.969923 +v -0.064998 0.046480 1.969923 +v -0.089450 0.056612 1.884088 +v -0.113902 0.046480 1.884088 +v -0.124030 0.022020 1.884088 +v -0.113902 -0.002440 1.884088 +v -0.089450 -0.012571 1.884088 +v -0.064998 -0.002440 1.884088 +v -0.054870 0.022020 1.884088 +v -0.064998 0.046480 1.884088 +v -0.089450 0.049117 1.884088 +v -0.108604 0.041180 1.884088 +v -0.116538 0.022020 1.884088 +v -0.108604 0.002860 1.884088 +v -0.089450 -0.005076 1.884088 +v -0.070297 0.002860 1.884088 +v -0.062363 0.022020 1.884088 +v -0.070297 0.041180 1.884088 +v -0.089450 0.042993 1.814492 +v -0.104275 0.036850 1.814492 +v -0.110416 0.022020 1.814492 +v -0.104275 0.007190 1.814492 +v -0.089450 0.001048 1.814492 +v -0.074625 0.007190 1.814492 +v -0.068485 0.022020 1.814492 +v -0.074625 0.036850 1.814492 +v -0.089450 0.022020 1.749314 +v -0.089450 0.158734 1.997540 +v -0.093012 0.161489 2.319592 +v -0.121876 0.145298 1.997540 +v -0.126342 0.147679 2.319592 +v -0.135307 0.112862 1.997540 +v -0.140148 0.114338 2.319592 +v -0.121876 0.080426 1.997540 +v -0.126342 0.080998 2.319592 +v -0.089450 0.066991 1.997540 +v -0.093012 0.067188 2.319592 +v -0.057025 0.080426 1.997540 +v -0.059683 0.080998 2.319592 +v -0.043594 0.112862 1.997540 +v -0.045877 0.114338 2.319592 +v -0.057025 0.145298 1.997540 +v -0.059683 0.147679 2.319592 +v -0.089450 0.147454 1.969923 +v -0.113902 0.137322 1.969923 +v -0.124030 0.112862 1.969923 +v -0.113902 0.088403 1.969923 +v -0.089450 0.078271 1.969923 +v -0.064998 0.088403 1.969923 +v -0.054870 0.112862 1.969923 +v -0.064998 0.137322 1.969923 +v -0.089450 0.147454 1.884088 +v -0.113902 0.137322 1.884088 +v -0.124030 0.112862 1.884088 +v -0.113902 0.088402 1.884088 +v -0.089450 0.078271 1.884088 +v -0.064998 0.088402 1.884088 +v -0.054870 0.112862 1.884088 +v -0.064998 0.137322 1.884088 +v -0.089450 0.139959 1.884088 +v -0.108604 0.132022 1.884088 +v -0.116538 0.112862 1.884088 +v -0.108604 0.093702 1.884088 +v -0.089450 0.085766 1.884088 +v -0.070297 0.093702 1.884088 +v -0.062363 0.112862 1.884088 +v -0.070297 0.132022 1.884088 +v -0.089450 0.133835 1.814492 +v -0.104275 0.127692 1.814492 +v -0.110416 0.112862 1.814492 +v -0.104275 0.098033 1.814492 +v -0.089450 0.091890 1.814492 +v -0.074625 0.098033 1.814492 +v -0.068485 0.112862 1.814492 +v -0.074625 0.127692 1.814492 +v -0.089450 0.112862 1.749314 +v -0.089450 0.251688 1.997540 +v -0.093012 0.254444 2.319592 +v -0.121876 0.238253 1.997540 +v -0.126342 0.240633 2.319592 +v -0.135307 0.205817 1.997540 +v -0.140148 0.207293 2.319592 +v -0.121876 0.173381 1.997540 +v -0.126342 0.173952 2.319592 +v -0.089450 0.159945 1.997540 +v -0.093012 0.160142 2.319592 +v -0.057025 0.173381 1.997540 +v -0.059683 0.173952 2.319592 +v -0.043594 0.205817 1.997540 +v -0.045877 0.207293 2.319592 +v -0.057025 0.238253 1.997540 +v -0.059683 0.240633 2.319592 +v -0.089450 0.240408 1.969923 +v -0.113902 0.230277 1.969923 +v -0.124030 0.205817 1.969923 +v -0.113902 0.181357 1.969923 +v -0.089450 0.171226 1.969923 +v -0.064998 0.181357 1.969923 +v -0.054870 0.205817 1.969923 +v -0.064998 0.230277 1.969923 +v -0.089450 0.240408 1.884088 +v -0.113902 0.230277 1.884088 +v -0.124030 0.205817 1.884088 +v -0.113902 0.181357 1.884088 +v -0.089450 0.171225 1.884088 +v -0.064998 0.181357 1.884088 +v -0.054870 0.205817 1.884088 +v -0.064998 0.230277 1.884088 +v -0.089450 0.232913 1.884088 +v -0.108604 0.224977 1.884088 +v -0.116538 0.205817 1.884088 +v -0.108604 0.186657 1.884088 +v -0.089450 0.178721 1.884088 +v -0.070297 0.186657 1.884088 +v -0.062363 0.205817 1.884088 +v -0.070297 0.224977 1.884088 +v -0.089450 0.226789 1.814492 +v -0.104275 0.220647 1.814492 +v -0.110416 0.205817 1.814492 +v -0.104275 0.190987 1.814492 +v -0.089450 0.184844 1.814492 +v -0.074625 0.190987 1.814492 +v -0.068485 0.205817 1.814492 +v -0.074625 0.220647 1.814492 +v -0.089450 0.205817 1.749314 +v -0.089450 0.343587 1.997540 +v -0.093012 0.346342 2.319592 +v -0.121876 0.330151 1.997540 +v -0.126342 0.332532 2.319592 +v -0.135307 0.297715 1.997540 +v -0.140148 0.299191 2.319592 +v -0.121876 0.265279 1.997540 +v -0.126342 0.265851 2.319592 +v -0.089450 0.251843 1.997540 +v -0.093012 0.252041 2.319592 +v -0.057025 0.265279 1.997540 +v -0.059683 0.265851 2.319592 +v -0.043594 0.297715 1.997540 +v -0.045877 0.299191 2.319592 +v -0.057025 0.330151 1.997540 +v -0.059683 0.332532 2.319592 +v -0.089450 0.332307 1.969923 +v -0.113902 0.322175 1.969923 +v -0.124030 0.297715 1.969923 +v -0.113902 0.273255 1.969923 +v -0.089450 0.263124 1.969923 +v -0.064998 0.273255 1.969923 +v -0.054870 0.297715 1.969923 +v -0.064998 0.322175 1.969923 +v -0.089450 0.332306 1.884088 +v -0.113902 0.322175 1.884088 +v -0.124030 0.297715 1.884088 +v -0.113902 0.273255 1.884088 +v -0.089450 0.263124 1.884088 +v -0.064998 0.273255 1.884088 +v -0.054870 0.297715 1.884088 +v -0.064998 0.322175 1.884088 +v -0.089450 0.324811 1.884088 +v -0.108604 0.316875 1.884088 +v -0.116538 0.297715 1.884088 +v -0.108604 0.278555 1.884088 +v -0.089450 0.270619 1.884088 +v -0.070297 0.278555 1.884088 +v -0.062363 0.297715 1.884088 +v -0.070297 0.316875 1.884088 +v -0.089450 0.318688 1.814492 +v -0.104275 0.312545 1.814492 +v -0.110416 0.297715 1.814492 +v -0.104275 0.282885 1.814492 +v -0.089450 0.276743 1.814492 +v -0.074625 0.282885 1.814492 +v -0.068485 0.297715 1.814492 +v -0.074625 0.312545 1.814492 +v -0.089450 0.297715 1.749314 +v 0.007506 0.525184 0.787648 +v 0.003944 0.527939 1.109699 +v -0.024919 0.511749 0.787648 +v -0.029385 0.514129 1.109700 +v -0.038350 0.479313 0.787648 +v -0.043191 0.480789 1.109700 +v -0.024919 0.446876 0.787648 +v -0.029385 0.447448 1.109700 +v 0.007506 0.433441 0.787648 +v 0.003944 0.433638 1.109700 +v 0.039932 0.446876 0.787648 +v 0.037274 0.447448 1.109700 +v 0.053363 0.479313 0.787648 +v 0.051079 0.480789 1.109700 +v 0.039932 0.511749 0.787648 +v 0.037274 0.514129 1.109700 +v 0.007506 0.513904 0.760031 +v -0.016945 0.503772 0.760031 +v -0.027074 0.479313 0.760031 +v -0.016945 0.454853 0.760031 +v 0.007506 0.444721 0.760031 +v 0.031958 0.454853 0.760031 +v 0.042086 0.479313 0.760031 +v 0.031958 0.503772 0.760031 +v 0.007506 0.513904 0.674196 +v -0.016945 0.503772 0.674196 +v -0.027074 0.479312 0.674196 +v -0.016945 0.454853 0.674196 +v 0.007506 0.444721 0.674196 +v 0.031958 0.454853 0.674196 +v 0.042086 0.479312 0.674196 +v 0.031958 0.503772 0.674196 +v 0.007506 0.506409 0.674196 +v -0.011647 0.498472 0.674196 +v -0.019581 0.479312 0.674196 +v -0.011647 0.460152 0.674196 +v 0.007506 0.452216 0.674196 +v 0.026660 0.460152 0.674196 +v 0.034594 0.479312 0.674196 +v 0.026660 0.498472 0.674196 +v 0.007506 0.500285 0.604599 +v -0.007319 0.494143 0.604599 +v -0.013459 0.479313 0.604599 +v -0.007319 0.464483 0.604600 +v 0.007506 0.458340 0.604599 +v 0.022331 0.464483 0.604600 +v 0.028472 0.479313 0.604599 +v 0.022331 0.494143 0.604599 +v 0.007506 0.479313 0.539422 +v 0.015505 -0.031506 1.939847 +v 0.015505 -0.072701 1.984877 +v 0.015505 -0.011846 1.984639 +v 0.015505 -0.060235 2.008895 +v -0.015505 -0.031506 1.939847 +v -0.015505 -0.072701 1.984877 +v -0.015505 -0.011846 1.984639 +v -0.015505 -0.060235 2.008895 +v 0.015505 -0.122692 2.004661 +v 0.015505 -0.126931 2.024789 +v -0.015505 -0.126931 2.024789 +v -0.015505 -0.122692 2.004661 +v 0.015505 -0.189169 1.986354 +v 0.015505 -0.200296 2.003653 +v -0.015505 -0.200296 2.003653 +v -0.015505 -0.189169 1.986354 +v 0.015505 0.051990 1.935233 +v 0.015505 0.032330 1.890441 +v -0.015505 0.051990 1.935233 +v -0.015505 0.032330 1.890441 +v 0.049520 -0.077240 2.116743 +v 0.049520 -0.096304 2.153611 +v 0.049520 -0.180646 2.128016 +v 0.049520 -0.159277 2.092434 +v 0.000000 -0.077240 2.116743 +v -0.000000 -0.159277 2.092434 +v 0.049520 -0.045128 2.131890 +v 0.049520 -0.046301 2.173356 +v 0.000000 -0.096304 2.153611 +v -0.000000 -0.180646 2.128016 +v 0.049520 -0.250508 2.040991 +v 0.049520 -0.209134 2.037693 +v -0.049520 -0.159277 2.092434 +v -0.049520 -0.077240 2.116743 +v 0.000000 -0.045128 2.131890 +v -0.000000 -0.209134 2.037693 +v 0.110500 -0.048925 2.266099 +v 0.000000 -0.046301 2.173356 +v -0.049520 -0.096304 2.153611 +v -0.049520 -0.180646 2.128016 +v -0.000000 -0.250508 2.040991 +v 0.049520 -0.260810 1.903656 +v 0.049520 -0.219909 1.910713 +v -0.049520 -0.045128 2.131890 +v -0.049520 -0.209134 2.037693 +v 0.049520 -0.034623 1.760623 +v -0.000000 -0.219909 1.910713 +v 0.000000 -0.048925 2.266099 +v -0.049520 -0.046301 2.173356 +v -0.049520 -0.250508 2.040991 +v -0.000000 -0.260810 1.903656 +v 0.049520 -0.190545 1.799874 +v 0.049520 -0.162098 1.830096 +v -0.049520 -0.034623 1.760623 +v -0.049520 -0.219909 1.910713 +v -0.000000 -0.034623 1.760623 +v -0.000000 -0.162098 1.830096 +v 0.110500 -0.029425 1.576915 +v 0.110500 -0.104749 2.422791 +v 0.000000 -0.104749 2.422791 +v -0.049520 -0.260810 1.903656 +v -0.000000 -0.190545 1.799874 +v 0.049520 -0.094841 1.766408 +v 0.049520 -0.077844 1.804273 +v -0.110500 -0.048925 2.266099 +v -0.049520 -0.162098 1.830096 +v -0.000000 -0.077844 1.804273 +v 0.049520 -0.032923 1.700556 +v 0.198887 0.059440 1.552513 +v 0.198887 0.039452 2.256126 +v 0.198887 -0.003232 2.438565 +v 0.110500 -0.360172 2.733244 +v 0.000000 -0.360172 2.733244 +v -0.110500 -0.104749 2.422791 +v -0.049520 -0.190545 1.799874 +v -0.000000 -0.094841 1.766408 +v -0.110500 -0.029425 1.576915 +v -0.049520 -0.077844 1.804273 +v -0.000000 -0.030088 1.600334 +v 0.097926 -0.025968 1.493944 +v 0.166196 0.042673 1.475096 +v 0.198887 0.071382 2.252693 +v 0.198887 0.079934 0.831113 +v 0.198887 0.128690 0.828304 +v 0.198887 -0.247231 2.735132 +v 0.110500 -0.407341 2.889477 +v 0.000000 -0.407341 2.889477 +v -0.110500 -0.360172 2.733244 +v -0.198887 -0.003232 2.438565 +v -0.049520 -0.094841 1.766408 +v -0.000000 -0.032923 1.700556 +v -0.049520 -0.032923 1.700556 +v -0.198887 0.039452 2.256126 +v -0.198887 0.059440 1.552513 +v -0.000000 -0.026479 1.512033 +v 0.198887 0.011371 2.436995 +v 0.166196 0.058502 0.917880 +v 0.095326 -0.003874 1.479608 +v 0.159973 0.061122 1.461761 +v 0.198887 0.386769 0.813768 +v 0.198887 0.374542 2.234114 +v 0.198887 0.108939 0.652317 +v 0.198887 0.145552 0.650206 +v 0.198887 -0.137574 2.749936 +v 0.110500 -0.384125 3.116249 +v 0.000000 -0.384125 3.116249 +v -0.110500 -0.407341 2.889477 +v -0.198887 -0.247231 2.735132 +v -0.198887 0.071382 2.252693 +v -0.198887 0.128690 0.828304 +v -0.198887 0.079934 0.831113 +v -0.166196 0.042673 1.475096 +v -0.097926 -0.025968 1.493944 +v 0.198887 0.264824 2.414252 +v 0.110500 -0.008463 0.836081 +v 0.097926 -0.009776 0.921716 +v 0.159973 0.076111 0.934126 +v -0.000000 -0.004359 1.496737 +v 0.095326 0.011458 0.937759 +v 0.198887 0.396383 0.636014 +v 0.173569 0.383597 0.810490 +v 0.110500 0.014519 0.662384 +v 0.198887 0.135815 0.554088 +v 0.198887 0.167898 0.546275 +v 0.198887 -0.316961 2.904156 +v 0.198887 0.120048 2.763535 +v 0.198887 -0.171860 2.923743 +v 0.198887 -0.293500 3.133307 +v 0.110500 -0.404518 3.287590 +v 0.000000 -0.404518 3.287590 +v -0.110500 -0.384125 3.116249 +v -0.198887 -0.137574 2.749936 +v -0.198887 0.011371 2.436995 +v -0.198887 0.374542 2.234114 +v -0.198887 0.386769 0.813768 +v -0.198887 0.145552 0.650206 +v -0.198887 0.108939 0.652317 +v -0.166196 0.058502 0.917880 +v -0.159973 0.061122 1.461761 +v -0.095326 -0.003874 1.479608 +v 0.110500 0.366869 2.398969 +v -0.000000 -0.008463 0.836081 +v -0.000000 -0.009776 0.921716 +v -0.000000 0.011458 0.937759 +v 0.173569 0.393210 0.632737 +v 0.198887 0.425424 0.513730 +v 0.173569 0.371370 2.193345 +v 0.110500 0.040948 0.565787 +v 0.198887 0.156778 0.366984 +v 0.198887 0.197704 0.357019 +v 0.198887 0.099924 2.939869 +v 0.110500 0.212268 2.771955 +v 0.198887 -0.165474 3.164960 +v 0.198887 -0.318423 3.309301 +v -0.000000 -0.896613 4.683361 +v 0.110500 -0.896613 4.683361 +v -0.110500 -0.404518 3.287590 +v -0.198887 -0.293500 3.133307 +v -0.198887 -0.316961 2.904156 +v -0.198887 -0.171860 2.923743 +v -0.198887 0.120048 2.763535 +v -0.198887 0.264824 2.414252 +v -0.173569 0.383597 0.810490 +v -0.198887 0.396383 0.636014 +v -0.198887 0.167898 0.546275 +v -0.198887 0.135815 0.554088 +v -0.110500 0.014519 0.662384 +v -0.110500 -0.008463 0.836081 +v -0.097926 -0.009776 0.921716 +v -0.159973 0.076111 0.934126 +v -0.095326 0.011458 0.937759 +v 0.085182 0.363697 2.358200 +v -0.000000 0.014519 0.662384 +v 0.173569 0.422252 0.510453 +v 0.173569 0.566586 0.634948 +v 0.173569 0.491946 0.798666 +v 0.198887 0.437377 0.336693 +v 0.173569 0.483730 2.139065 +v 0.110500 0.067414 0.392146 +v 0.000000 0.040948 0.565787 +v 0.198887 0.157684 0.332414 +v 0.198887 0.198471 0.322341 +v 0.110500 0.189191 2.941389 +v 0.198887 0.122827 3.126351 +v 0.000000 0.212268 2.771955 +v 0.000000 0.366869 2.398969 +v 0.198887 -0.177828 3.344062 +v 0.198887 -0.806961 4.694987 +v 0.110500 -0.838547 4.779691 +v -0.000000 -0.838547 4.779691 +v -0.110500 -0.896613 4.683361 +v -0.198887 -0.318423 3.309301 +v -0.198887 -0.165474 3.164960 +v -0.198887 0.099924 2.939869 +v -0.110500 0.366869 2.398969 +v -0.110500 0.212268 2.771955 +v -0.173569 0.371370 2.193345 +v -0.173569 0.393210 0.632737 +v -0.198887 0.425424 0.513730 +v -0.198887 0.156778 0.366984 +v -0.198887 0.197704 0.357019 +v -0.110500 0.040948 0.565787 +v 0.000000 0.363697 2.358200 +v 0.173569 0.434205 0.333415 +v 0.173569 0.579971 0.515133 +v 0.085182 0.655083 0.639141 +v 0.198887 0.437917 0.302206 +v 0.099881 0.539483 1.175539 +v 0.099881 0.535889 1.761836 +v 0.000000 0.067414 0.392146 +v 0.110500 0.068317 0.357699 +v 0.198887 0.207615 -1.570960 +v 0.198887 0.240735 -1.587018 +v 0.110500 0.208862 3.101560 +v 0.198887 0.124563 3.310656 +v 0.000000 0.189191 2.941389 +v 0.198887 -0.467526 4.745223 +v -0.110500 -0.838547 4.779691 +v 0.110500 -0.485315 4.831969 +v -0.000000 -0.485315 4.831969 +v -0.198887 -0.806961 4.694987 +v -0.198887 -0.177828 3.344062 +v -0.198887 0.122827 3.126351 +v -0.110500 0.189191 2.941389 +v -0.085182 0.363697 2.358200 +v -0.173569 0.483730 2.139065 +v -0.173569 0.491946 0.798666 +v -0.173569 0.566586 0.634948 +v -0.173569 0.422252 0.510453 +v -0.198887 0.437377 0.336693 +v -0.198887 0.198471 0.322341 +v -0.198887 0.157684 0.332414 +v -0.110500 0.067414 0.392146 +v 0.085182 0.499263 2.236111 +v 0.000000 0.499263 2.236111 +v 0.198887 0.593861 0.341883 +v 0.173569 0.590689 0.338605 +v 0.085182 0.580328 0.802605 +v 0.198887 0.467655 -1.596682 +v 0.198887 0.594153 0.307256 +v 0.085182 0.572556 2.134495 +v 0.061221 0.574742 1.759838 +v 0.061221 0.578142 1.177262 +v 0.099881 0.459930 1.175075 +v 0.099881 0.456336 1.761372 +v 0.000000 0.068317 0.357699 +v 0.110500 0.118008 -1.538934 +v 0.110500 0.200699 -1.622802 +v 0.110500 0.254111 -1.648698 +v 0.110500 0.214886 3.277604 +v -0.000000 0.208862 3.101560 +v 0.198887 0.046554 4.759627 +v -0.110500 -0.485315 4.831969 +v 0.110500 0.041893 4.848012 +v -0.000000 0.041893 4.848012 +v -0.198887 -0.467526 4.745223 +v -0.198887 0.124563 3.310656 +v -0.110500 0.208862 3.101560 +v -0.099881 0.535889 1.761836 +v -0.099881 0.539483 1.175539 +v -0.173569 0.579971 0.515133 +v -0.085182 0.655083 0.639141 +v -0.173569 0.434205 0.333415 +v -0.198887 0.437917 0.302206 +v -0.198887 0.240735 -1.587018 +v -0.198887 0.207615 -1.570960 +v -0.110500 0.068317 0.357699 +v -0.085182 0.499263 2.236111 +v 0.000000 0.572556 2.134495 +v 0.110500 0.682246 0.345938 +v 0.085182 0.668719 0.342659 +v 0.085182 0.658157 0.518941 +v 0.000000 0.580328 0.802605 +v 0.000000 0.655083 0.639141 +v 0.198887 0.391079 -1.668945 +v 0.194402 0.436736 0.287077 +v 0.194402 0.583216 0.292048 +v 0.110500 0.682539 0.311221 +v 0.000000 0.574742 1.759838 +v 0.061221 0.495189 1.759373 +v 0.000000 0.578142 1.177262 +v 0.061221 0.498589 1.176798 +v 0.099881 0.330815 1.174322 +v 0.099881 0.327221 1.760618 +v 0.000000 0.118008 -1.538934 +v 0.110500 0.275613 -1.664316 +v 0.000000 0.254111 -1.648698 +v 0.000000 0.200699 -1.622802 +v -0.000000 0.214886 3.277604 +v 0.110500 0.135059 4.760348 +v -0.110500 0.041893 4.848012 +v -0.000000 0.135059 4.760348 +v -0.198887 0.046554 4.759627 +v -0.110500 0.214886 3.277604 +v -0.085182 0.572556 2.134495 +v -0.061221 0.574742 1.759838 +v -0.099881 0.456336 1.761372 +v -0.099881 0.459930 1.175075 +v -0.061221 0.578142 1.177262 +v -0.085182 0.580328 0.802605 +v -0.173569 0.590689 0.338605 +v -0.198887 0.593861 0.341883 +v -0.198887 0.594153 0.307256 +v -0.198887 0.467655 -1.596682 +v -0.110500 0.254111 -1.648698 +v -0.110500 0.200699 -1.622802 +v -0.110500 0.118008 -1.538934 +v 0.000000 0.658157 0.518941 +v 0.198887 0.610232 -1.599246 +v 0.198887 0.609899 -1.671499 +v 0.194402 0.464617 -1.581501 +v 0.111535 0.666082 0.295948 +v -0.000000 0.682246 0.345938 +v -0.000000 0.682539 0.311221 +v 0.000000 0.495189 1.759373 +v 0.061221 0.313900 1.758620 +v 0.000000 0.498589 1.176798 +v 0.061221 0.317299 1.176045 +v 0.000000 0.275613 -1.664316 +v -0.110500 0.135059 4.760348 +v -0.061221 0.495189 1.759373 +v -0.099881 0.327221 1.760618 +v -0.099881 0.330815 1.174322 +v -0.061221 0.498589 1.176798 +v -0.085182 0.658157 0.518941 +v -0.085182 0.668719 0.342659 +v -0.110500 0.682246 0.345938 +v -0.110500 0.682539 0.311221 +v -0.194402 0.583216 0.292048 +v -0.194402 0.436736 0.287077 +v -0.198887 0.391079 -1.668945 +v -0.110500 0.275613 -1.664316 +v -0.000000 0.668719 0.342659 +v 0.110500 0.297629 -3.324020 +v 0.110500 0.682187 -1.597274 +v 0.198887 0.404090 -3.323432 +v 0.198887 0.622922 -3.321880 +v 0.194402 0.598290 -1.584024 +v 0.111535 0.681196 -1.585031 +v -0.000000 0.666082 0.295948 +v 0.000000 0.306446 1.758620 +v -0.000000 0.309846 1.176044 +v 0.000000 0.297629 -3.324020 +v -0.061221 0.313900 1.758620 +v -0.061221 0.317299 1.176045 +v -0.111535 0.666082 0.295948 +v -0.194402 0.464617 -1.581501 +v -0.198887 0.610232 -1.599246 +v -0.198887 0.609899 -1.671499 +v 0.110500 0.663866 -1.672506 +v 0.142355 0.636496 -3.409850 +v 0.000000 0.681196 -1.585031 +v -0.110500 0.297629 -3.324020 +v 0.000000 0.323577 -3.412289 +v 0.142355 0.323577 -3.412289 +v -0.194402 0.598290 -1.584024 +v -0.111535 0.681196 -1.585031 +v -0.110500 0.682187 -1.597274 +v -0.198887 0.622922 -3.321880 +v -0.198887 0.404090 -3.323432 +v 0.000000 0.682187 -1.597274 +v 0.000000 0.663866 -1.672506 +v 0.110500 0.661204 -3.321232 +v -0.142355 0.323577 -3.412289 +v 0.000000 0.340647 -3.412156 +v 0.047525 0.360339 -3.412003 +v 0.067425 0.408395 -3.411628 +v 0.047525 0.456453 -3.411252 +v 0.044831 0.457569 -3.411244 +v 0.003035 0.474887 -3.411109 +v 0.000428 0.475967 -3.411100 +v 0.003034 0.477047 -3.411092 +v 0.044838 0.494368 -3.410958 +v 0.047525 0.495482 -3.410948 +v 0.067425 0.543539 -3.410574 +v 0.047525 0.591595 -3.410200 +v 0.000000 0.611287 -3.410046 +v 0.000000 0.636496 -3.409850 +v -0.110500 0.663866 -1.672506 +v -0.142355 0.636496 -3.409850 +v 0.000000 0.661204 -3.321232 +v -0.000516 0.611501 -3.410045 +v -0.048557 0.591595 -3.410200 +v -0.068456 0.543539 -3.410574 +v -0.048557 0.495482 -3.410948 +v -0.045869 0.494368 -3.410958 +v -0.004066 0.477047 -3.411092 +v -0.001459 0.475967 -3.411100 +v -0.004066 0.474887 -3.411109 +v -0.045862 0.457569 -3.411244 +v -0.048557 0.456453 -3.411252 +v -0.068456 0.408395 -3.411628 +v -0.048557 0.360339 -3.412003 +v -0.000516 0.340433 -3.412158 +v -0.110500 0.661204 -3.321232 +v 0.000000 0.511249 -3.410826 +v 0.000000 0.575827 -3.410323 +v 0.022461 0.566521 -3.410395 +v 0.031979 0.543539 -3.410574 +v 0.022461 0.520555 -3.410753 +v -0.000516 0.511035 -3.410828 +v -0.023493 0.520555 -3.410753 +v -0.033010 0.543539 -3.410574 +v -0.023493 0.566521 -3.410395 +v -0.000516 0.576042 -3.410321 +v 0.049520 0.001902 2.176001 +v 0.049520 0.001902 2.134496 +v 0.000000 0.001902 2.134496 +v 0.000000 0.001902 2.176001 +v -0.049520 0.001902 2.176001 +v -0.049520 0.001902 2.134496 +v 0.023599 0.485568 -4.302999 +v 0.000428 0.475967 -4.303505 +v 0.047525 0.495481 -4.303505 +v 0.023599 0.466367 -4.302999 +v 0.046772 0.475967 -4.302999 +v 0.023599 0.485568 -4.303505 +v 0.067425 0.543538 -4.303505 +v 0.061102 0.481904 -4.303000 +v 0.086624 0.543539 -4.302999 +v 0.047525 0.591595 -4.303505 +v 0.047525 0.456452 -4.303505 +v 0.023599 0.466366 -4.303505 +v 0.046771 0.475967 -4.597024 +v 0.061101 0.481905 -4.597023 +v 0.061102 0.605173 -4.302999 +v 0.086624 0.543539 -4.597024 +v -0.000516 0.611501 -4.303505 +v 0.067425 0.408396 -4.303505 +v 0.061102 0.470030 -4.302999 +v 0.061101 0.470030 -4.597024 +v -0.000516 0.495559 -4.597024 +v -0.000516 0.496341 -4.597024 +v 0.032848 0.510165 -4.597024 +v -0.000516 0.630703 -4.302999 +v 0.061101 0.605173 -4.597024 +v 0.046668 0.543539 -4.597024 +v -0.048557 0.591595 -4.303505 +v 0.047525 0.360339 -4.303504 +v 0.086624 0.408396 -4.302999 +v 0.086624 0.408396 -4.597024 +v -0.062133 0.346761 -4.597024 +v -0.087656 0.408396 -4.597024 +v -0.062133 0.470030 -4.597024 +v -0.047803 0.475967 -4.597024 +v -0.000516 0.456375 -4.597024 +v 0.061101 0.346761 -4.597024 +v -0.000516 0.321231 -4.597024 +v -0.062133 0.481905 -4.597023 +v -0.033880 0.510165 -4.597024 +v -0.000516 0.496342 -4.749331 +v 0.032848 0.510166 -4.749331 +v -0.062133 0.605173 -4.302999 +v 0.037477 0.615358 -4.316436 +v -0.000516 0.631099 -4.316436 +v 0.037476 0.615358 -4.497726 +v 0.032848 0.576912 -4.597024 +v 0.046668 0.543539 -4.749331 +v -0.068456 0.543538 -4.303505 +v -0.000516 0.340433 -4.303505 +v 0.061102 0.346761 -4.302999 +v -0.000516 0.321232 -4.302999 +v -0.062133 0.346761 -4.302999 +v -0.087655 0.408396 -4.302999 +v -0.062133 0.470030 -4.302999 +v -0.047803 0.475967 -4.302999 +v -0.062133 0.481904 -4.303000 +v -0.087656 0.543539 -4.597024 +v -0.047700 0.543539 -4.597024 +v -0.033880 0.510166 -4.749331 +v -0.000516 0.511035 -4.749331 +v 0.022461 0.520555 -4.749331 +v -0.087655 0.543539 -4.302999 +v -0.038508 0.615358 -4.316436 +v 0.037477 0.728881 -4.316436 +v -0.000516 0.728932 -4.316436 +v -0.000516 0.630702 -4.597024 +v -0.000516 0.631099 -4.497726 +v 0.037476 0.728880 -4.497726 +v -0.000516 0.590735 -4.597024 +v 0.032848 0.576912 -4.749331 +v 0.031979 0.543539 -4.749331 +v -0.048557 0.495481 -4.303505 +v -0.048557 0.360339 -4.303504 +v -0.068456 0.408396 -4.303505 +v -0.048557 0.456452 -4.303505 +v -0.024630 0.466366 -4.303505 +v -0.024630 0.485568 -4.303505 +v -0.062133 0.605173 -4.597024 +v -0.033880 0.576911 -4.597024 +v -0.047700 0.543539 -4.749331 +v -0.023493 0.520555 -4.749331 +v -0.038508 0.615358 -4.497726 +v -0.038508 0.728881 -4.316436 +v 0.037477 0.762107 -4.331735 +v -0.000516 0.728932 -4.497726 +v 0.037476 0.762107 -4.482427 +v -0.000516 0.590735 -4.749331 +v 0.022461 0.566522 -4.749331 +v -0.024630 0.485568 -4.302999 +v -0.024630 0.466367 -4.302999 +v -0.033880 0.576912 -4.749331 +v -0.033010 0.543539 -4.749331 +v -0.038508 0.728880 -4.497726 +v -0.000516 0.761550 -4.331735 +v -0.000516 0.761550 -4.482427 +v 0.037476 0.784719 -4.450743 +v 0.037477 0.784719 -4.363420 +v -0.000516 0.576042 -4.749331 +v -0.001459 0.475967 -4.303505 +v -0.023493 0.566522 -4.749331 +v -0.038508 0.762107 -4.331735 +v -0.038508 0.762107 -4.482427 +v -0.000516 0.763188 -4.450743 +v -0.000516 0.763187 -4.363420 +v -0.038508 0.784719 -4.363420 +v -0.038508 0.784719 -4.450743 +vn -0.000000 -0.999600 -0.028300 +vn 0.000000 -0.942000 -0.335600 +vn 0.705900 -0.708000 -0.020100 +vn 0.721100 -0.665400 -0.193300 +vn -0.000000 -0.772200 -0.635300 +vn 0.684100 -0.717100 -0.133600 +vn 1.000000 -0.000000 0.000000 +vn 0.707200 -0.546000 -0.449200 +vn 0.000000 -0.957300 -0.289000 +vn -0.721100 -0.665400 -0.193300 +vn -0.705900 -0.708000 -0.020100 +vn -0.002500 -0.999200 -0.041000 +vn 0.501700 -0.864700 -0.024600 +vn 0.276200 -0.500100 -0.820800 +vn 0.744200 -0.628600 -0.225900 +vn 0.000000 -0.994800 0.101800 +vn -0.707200 -0.546000 -0.449200 +vn -1.000000 -0.000000 0.000000 +vn -0.684100 -0.717100 -0.133600 +vn 0.002500 -0.999200 -0.041000 +vn 0.706700 -0.701400 0.093000 +vn -0.945500 -0.325600 -0.009300 +vn -0.146200 -0.556700 -0.817800 +vn -0.131700 0.991300 0.008600 +vn 0.710900 -0.695800 -0.102600 +vn 0.707200 -0.703300 0.072000 +vn 0.000000 -0.993000 -0.118200 +vn -0.744200 -0.628600 -0.225900 +vn -0.501700 -0.864700 -0.024600 +vn -0.276200 -0.500100 -0.820800 +vn 0.667400 0.636100 0.387400 +vn 0.000000 -0.999900 -0.015300 +vn 0.515600 -0.475400 0.712800 +vn 0.146200 -0.556700 -0.817800 +vn -0.131000 0.989900 0.053500 +vn 0.707200 -0.681900 -0.186600 +vn 0.707200 0.653100 0.270700 +vn 0.714000 -0.694300 -0.090600 +vn 0.000000 -0.943100 -0.332500 +vn -0.707200 -0.703300 0.072000 +vn 0.131700 0.991300 0.008600 +vn -0.710900 -0.695800 -0.102600 +vn -0.706700 -0.701400 0.093000 +vn 0.945500 -0.325600 -0.009300 +vn -0.106800 0.994200 -0.011000 +vn 0.000000 -0.991400 -0.131200 +vn 0.000000 -0.602800 0.797900 +vn -0.150100 0.961900 0.228400 +vn 0.709300 -0.698900 -0.091900 +vn 0.000000 -0.964500 -0.263900 +vn 0.716000 0.692700 0.086500 +vn -0.000000 0.923800 0.382900 +vn 0.707200 -0.666800 -0.235100 +vn -0.714000 -0.694300 -0.090600 +vn -0.707200 0.653100 0.270700 +vn -0.667400 0.636100 0.387400 +vn 0.131000 0.989900 0.053500 +vn -0.707200 -0.681900 -0.186600 +vn -0.515600 -0.475400 0.712800 +vn -0.000000 0.997000 -0.077600 +vn -0.132600 0.988900 0.066800 +vn 0.000000 -0.988600 -0.150700 +vn 0.708300 -0.705700 -0.018500 +vn 0.707200 0.701700 -0.086200 +vn 0.000000 0.990900 0.135000 +vn -0.707200 -0.666800 -0.235100 +vn -0.716000 0.692700 0.086500 +vn 0.106800 0.994200 -0.011000 +vn 0.150100 0.961900 0.228400 +vn -0.709300 -0.698900 -0.091900 +vn -0.124300 -0.032900 0.991700 +vn 0.000000 -0.999700 -0.026200 +vn 0.708400 -0.705600 -0.018500 +vn 0.708700 0.705400 -0.015200 +vn 0.000000 0.992500 -0.121900 +vn -0.707200 0.701700 -0.086200 +vn 0.132600 0.988900 0.066800 +vn -0.708300 -0.705700 -0.018500 +vn 0.707200 0.707000 0.006000 +vn 0.000000 0.999400 -0.034200 +vn 0.707200 0.706000 0.038000 +vn -0.708700 0.705400 -0.015200 +vn 0.124300 -0.032900 0.991700 +vn -0.708400 -0.705600 -0.018500 +vn -0.082900 -0.136200 0.987200 +vn -0.425500 0.904800 0.013800 +vn 0.957900 0.009500 -0.287000 +vn 0.557900 0.584900 -0.588800 +vn 0.000000 1.000000 0.008400 +vn 0.000000 0.998600 0.053800 +vn -0.707200 0.706000 0.038000 +vn 0.082900 -0.136200 0.987200 +vn -0.707200 0.707000 0.006000 +vn -0.957900 0.009500 -0.287000 +vn 0.425500 0.904800 0.013800 +vn 0.000000 -0.235600 0.971900 +vn 0.782100 -0.623100 -0.006600 +vn 0.000000 0.680300 -0.733000 +vn 0.000000 -0.999900 -0.013300 +vn -0.557900 0.584900 -0.588800 +vn 0.462600 0.886500 0.002800 +vn -0.782100 -0.623100 -0.006600 +vn -0.462600 0.886500 0.002800 +vn 0.000000 1.000000 -0.001600 +vn 0.000000 1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.706300 -0.707700 -0.020100 +vn -0.706300 -0.707700 -0.020100 +vn 0.000000 -0.856400 0.516200 +vn 0.625100 -0.668500 0.403000 +vn 0.000000 -0.146400 0.989200 +vn 0.489900 -0.380300 -0.784500 +vn 0.707200 -0.103500 0.699400 +vn -0.625100 -0.668500 0.403000 +vn 0.000000 -0.030400 0.999500 +vn 0.057500 0.005800 -0.998300 +vn 0.038700 -0.005800 0.999200 +vn 0.423500 -0.645100 -0.636000 +vn 0.000000 -0.436300 -0.899800 +vn 0.705000 -0.020700 0.708900 +vn -0.707200 -0.103500 0.699400 +vn 0.000000 0.685300 0.728300 +vn -0.489900 -0.380300 -0.784500 +vn 0.839800 -0.268000 -0.472100 +vn 0.000000 0.005800 -1.000000 +vn 0.053200 0.004800 -0.998600 +vn 0.000000 -0.005800 1.000000 +vn 0.043000 -0.004800 0.999100 +vn -0.327900 0.944700 0.005700 +vn 0.000000 -0.712100 -0.702100 +vn 0.000000 -0.587700 -0.809100 +vn 0.569100 0.563500 0.598800 +vn -0.705000 -0.020700 0.708900 +vn -0.057500 0.005800 -0.998300 +vn -0.038700 -0.005800 0.999200 +vn -0.839800 -0.268000 -0.472100 +vn -0.423500 -0.645100 -0.636000 +vn 0.576800 0.810500 -0.102500 +vn 0.958400 0.005300 0.285300 +vn -0.000200 0.004100 -1.000000 +vn 0.000200 -0.004100 1.000000 +vn -0.569100 0.563500 0.598800 +vn -0.053200 0.004800 -0.998600 +vn 0.327900 0.944700 0.005700 +vn -0.043000 -0.004800 0.999100 +vn 0.616700 0.679500 0.397400 +vn 0.841800 0.004100 -0.539800 +vn 0.000200 0.004100 -1.000000 +vn -0.120900 0.992700 0.005800 +vn -0.000200 -0.004100 1.000000 +vn 0.000000 -0.959400 -0.282000 +vn -0.958400 0.005300 0.285400 +vn -0.576800 0.810500 -0.102500 +vn 0.766100 -0.636500 0.089400 +vn 0.000000 0.971600 -0.236600 +vn 0.394200 0.912100 -0.112600 +vn 0.000000 0.996700 0.080700 +vn 0.120900 0.992700 0.005800 +vn -0.000000 0.007800 -1.000000 +vn -0.616700 0.679500 0.397400 +vn -0.841800 0.004100 -0.539800 +vn 0.000000 0.963300 -0.268600 +vn -0.766100 -0.636500 0.089400 +vn -0.394200 0.912100 -0.112600 +vn 0.000000 0.448100 0.894000 +vn 0.000000 -0.737800 -0.675000 +vn 0.000000 0.612100 0.790800 +vn 0.000000 -0.368000 -0.929800 +vn 0.000000 0.231800 0.972800 +vn 0.000000 -0.841000 -0.541000 +vn 0.000000 0.265500 -0.964100 +vn 0.000000 -0.276800 0.960900 +vn 0.000000 0.915700 -0.401900 +vn 0.000000 -0.612100 -0.790800 +vn 0.000000 0.284100 -0.958800 +vn 0.000000 -0.290400 0.956900 +vn 0.000000 0.426600 -0.904400 +vn 0.000000 0.739300 -0.673400 +vn 0.000000 -0.367300 0.930100 +vn 0.000000 -0.779800 0.626000 +vn 0.000000 0.996400 -0.084500 +vn 0.000000 -0.997200 0.074800 +vn 0.000000 0.812600 0.582800 +vn 0.000000 -0.828100 -0.560600 +vn 0.000000 0.710600 0.703600 +vn 0.000000 0.293000 0.956100 +vn 0.000000 -0.330100 -0.944000 +vn 0.000000 -0.728500 -0.685000 +vn 0.776700 0.365100 0.513300 +vn 0.680700 0.666300 0.304300 +vn 0.560300 0.828300 0.005100 +vn 0.000000 0.669200 0.743100 +vn 0.686400 0.725500 0.049800 +vn 0.709300 0.703700 -0.041300 +vn 0.707300 0.705200 0.049400 +vn -0.776700 0.365100 0.513300 +vn -0.560300 0.828300 0.005100 +vn 0.000000 0.811000 0.585000 +vn 0.617400 0.638000 0.460200 +vn 0.000000 0.909400 0.415900 +vn 0.000000 1.000000 0.005800 +vn -0.709300 0.703700 -0.041300 +vn -0.707300 0.705200 0.049400 +vn -0.680700 0.666300 0.304300 +vn 0.662600 0.747600 0.045100 +vn 0.000000 0.999700 0.025600 +vn -0.617400 0.638000 0.460200 +vn -0.686400 0.725500 0.049800 +vn -0.662600 0.747600 0.045100 +vn 0.000000 0.998200 0.059800 +vn 0.707200 0.707000 0.005700 +vn 0.000000 1.000000 0.008000 +vn -0.707200 0.707000 0.005700 +vn 0.382800 -0.923800 -0.000000 +vn 0.382800 0.923800 -0.000000 +vn -0.010900 -0.026400 0.999600 +vn 0.923900 -0.382600 0.000000 +vn -0.010900 0.026300 0.999600 +vn 0.383000 0.923700 -0.000900 +vn -0.026300 0.010900 0.999600 +vn 0.923900 0.382600 -0.000000 +vn 0.383000 -0.923700 0.001300 +vn -0.026300 -0.010900 0.999600 +vn -0.010900 -0.026300 0.999600 +vn -0.382800 0.923800 0.000000 +vn 0.010900 -0.026300 0.999600 +vn 0.382600 0.923500 0.027300 +vn 0.395900 0.918300 -0.000000 +vn -0.923900 0.382600 -0.000000 +vn -0.382800 -0.923800 0.000000 +vn -0.923900 -0.382600 0.000000 +vn 0.026300 -0.010900 0.999600 +vn -0.382600 0.923500 0.027300 +vn 0.382800 0.923800 -0.003700 +vn 0.010900 0.026300 0.999600 +vn 0.026300 0.010900 0.999600 +vn -0.395900 0.918300 -0.000000 +vn -0.002800 0.421400 0.906900 +vn -0.382800 0.923800 -0.003700 +vn -0.383100 -0.923700 0.001300 +vn -0.382900 0.923800 -0.000900 +vn 0.002800 0.421400 0.906900 +vn -0.002800 0.421400 -0.906900 +vn 0.010900 -0.026400 0.999600 +vn -0.262000 0.901300 0.344900 +vn 0.002800 0.421400 -0.906900 +vn -0.262000 0.901300 -0.344900 +vn -0.493100 0.870000 0.000000 +vn 0.262000 0.901300 0.344900 +vn 0.262000 0.901300 -0.344900 +vn 0.493100 0.870000 0.000000 +vn -0.382800 0.923800 -0.012100 +vn -0.923800 0.382500 -0.015600 +vn -0.923900 -0.382500 -0.012100 +vn -0.382800 -0.923800 -0.003700 +vn 0.382800 -0.923800 0.004800 +vn 0.923900 -0.382600 0.008300 +vn 0.923900 0.382600 0.004800 +vn -0.864500 -0.358000 -0.353000 +vn 0.864500 -0.358000 -0.353000 +vn -0.358100 -0.864300 -0.353000 +vn 0.864500 0.358000 -0.353000 +vn -0.864500 0.358000 -0.353000 +vn 0.358100 -0.864300 -0.353000 +vn 0.358100 0.864300 -0.353000 +vn -0.358100 0.864300 -0.353000 +vn -0.358100 -0.864400 -0.353000 +vn 0.358100 -0.864400 -0.353000 +vn 0.358100 0.864400 -0.353000 +vn 0.920900 0.381300 -0.081000 +vn 0.381500 -0.920800 -0.081000 +vn -0.920900 -0.381300 -0.081000 +vn -0.381500 0.920800 -0.081000 +vn 0.381500 0.920800 -0.081000 +vn 0.920900 -0.381300 -0.081000 +vn -0.381500 -0.920800 -0.081000 +vn -0.920900 0.381300 -0.081000 +vn -0.885600 0.366700 -0.284900 +vn 0.885600 0.366700 -0.284900 +vn 0.366900 -0.885500 -0.284900 +vn -0.885600 -0.366700 -0.284900 +vn -0.366900 0.885500 -0.284900 +vn 0.366900 0.885500 -0.284900 +vn 0.885600 -0.366700 -0.284900 +vn -0.366900 -0.885500 -0.284900 +usemtl LightWood +s off +f 503//1 493//1 492//1 500//1 521//1 511//1 533//1 556//1 544//1 523//1 502//1 513//1 +f 513//1 530//1 542//1 544//1 556//1 557//1 519//1 521//1 500//1 509//1 514//1 503//1 +f 524//2 525//2 513//2 502//2 +f 502//3 523//3 534//3 535//3 +f 524//4 502//4 535//4 536//4 +f 537//5 538//5 525//5 524//5 +f 539//2 530//2 513//2 525//2 +f 534//6 523//6 545//6 546//6 +f 547//7 535//7 534//7 548//7 549//7 +f 537//8 524//8 536//8 550//8 +f 551//9 552//9 538//9 537//9 +f 553//5 539//5 525//5 538//5 +f 539//10 554//10 558//10 530//10 +f 530//11 558//11 559//11 542//11 +f 544//12 560//12 545//12 523//12 +f 561//7 536//7 535//7 547//7 +f 548//13 534//13 546//13 562//13 +f 546//14 545//14 563//14 564//14 +f 547//7 549//7 565//7 566//7 +f 549//7 548//7 567//7 568//7 +f 537//15 550//15 590//15 551//15 +f 569//7 550//7 536//7 561//7 +f 570//16 571//16 552//16 551//16 +f 572//9 553//9 538//9 552//9 +f 553//17 573//17 554//17 539//17 +f 574//18 575//18 576//18 559//18 558//18 +f 559//19 577//19 578//19 542//19 +f 544//20 542//20 578//20 560//20 +f 579//7 561//7 547//7 566//7 +f 580//21 548//21 562//21 581//21 +f 562//22 546//22 564//22 582//22 +f 560//23 583//23 563//23 545//23 +f 565//7 549//7 568//7 585//7 +f 565//24 586//24 612//24 566//24 +f 567//25 548//25 580//25 587//25 +f 568//7 567//7 588//7 589//7 +f 569//7 561//7 579//7 591//7 +f 592//7 590//7 550//7 569//7 +f 570//26 551//26 590//26 593//26 +f 594//27 595//27 571//27 570//27 +f 596//16 572//16 552//16 571//16 +f 553//28 572//28 624//28 573//28 +f 597//18 598//18 554//18 573//18 +f 598//18 574//18 558//18 554//18 +f 574//18 599//18 600//18 575//18 +f 575//18 601//18 602//18 576//18 +f 576//29 603//29 577//29 559//29 +f 577//30 604//30 605//30 578//30 +f 606//31 579//31 566//31 +f 607//32 580//32 581//32 608//32 +f 581//33 562//33 582//33 584//33 +f 560//34 578//34 605//34 583//34 +f 565//35 585//35 610//35 586//35 +f 568//7 589//7 611//7 585//7 +f 588//36 567//36 587//36 613//36 +f 614//7 615//7 589//7 588//7 +f 616//7 592//7 569//7 591//7 +f 606//37 617//37 591//37 579//37 +f 618//7 593//7 590//7 592//7 +f 594//38 570//38 593//38 619//38 +f 620//39 595//39 594//39 621//39 +f 622//27 596//27 571//27 595//27 +f 596//40 623//40 624//40 572//40 +f 625//18 597//18 573//18 624//18 +f 597//18 626//18 627//18 598//18 +f 627//18 599//18 574//18 598//18 +f 600//41 599//41 662//41 628//41 +f 600//18 629//18 601//18 575//18 +f 601//18 630//18 631//18 602//18 +f 602//42 632//42 633//42 576//42 +f 633//43 634//43 603//43 576//43 +f 603//44 635//44 604//44 577//44 +f 606//45 566//45 612//45 637//45 +f 607//32 608//32 634//32 633//32 +f 580//46 607//46 638//46 587//46 +f 608//47 581//47 584//47 609//47 +f 585//48 611//48 639//48 610//48 +f 615//7 642//7 611//7 589//7 +f 613//49 644//49 614//49 588//49 +f 587//50 638//50 645//50 613//50 +f 615//7 614//7 646//7 647//7 +f 616//51 591//51 617//51 648//51 +f 618//7 592//7 616//7 649//7 +f 650//52 617//52 606//52 651//52 +f 652//7 619//7 593//7 618//7 +f 621//53 594//53 619//53 653//53 +f 620//39 656//39 622//39 595//39 +f 623//54 596//54 622//54 657//54 +f 658//18 625//18 624//18 623//18 +f 659//18 626//18 597//18 625//18 +f 660//55 627//55 626//55 661//55 +f 660//56 599//56 627//56 +f 600//57 628//57 663//57 629//57 +f 601//18 629//18 664//18 630//18 +f 665//18 631//18 630//18 666//18 +f 631//58 667//58 632//58 602//58 +f 634//59 636//59 635//59 603//59 +f 651//60 606//60 637//60 668//60 +f 633//46 632//46 638//46 607//46 +f 608//47 609//47 636//47 634//47 +f 611//61 642//61 669//61 639//61 +f 615//7 647//7 672//7 642//7 +f 675//62 644//62 613//62 645//62 +f 632//50 667//50 645//50 638//50 +f 646//63 614//63 644//63 676//63 +f 647//7 646//7 677//7 678//7 +f 649//64 616//64 648//64 679//64 +f 680//7 652//7 618//7 649//7 +f 650//52 651//52 660//52 661//52 +f 681//65 648//65 617//65 650//65 +f 652//7 682//7 653//7 619//7 +f 656//66 686//66 657//66 622//66 +f 687//18 658//18 623//18 657//18 +f 658//18 688//18 659//18 625//18 +f 659//67 689//67 661//67 626//67 +f 660//68 690//68 662//68 599//68 +f 629//69 663//69 694//69 664//69 +f 666//18 630//18 664//18 695//18 +f 666//18 696//18 697//18 665//18 +f 667//70 631//70 665//70 698//70 +f 651//60 668//60 690//60 660//60 +f 642//71 701//71 702//71 669//71 +f 647//7 678//7 704//7 672//7 +f 642//7 672//7 705//7 701//7 +f 675//62 645//62 667//62 698//62 +f 644//72 675//72 711//72 676//72 +f 677//73 646//73 676//73 712//73 +f 679//74 715//74 680//74 649//74 +f 716//75 679//75 648//75 681//75 +f 682//7 652//7 680//7 717//7 +f 681//65 650//65 661//65 689//65 +f 687//18 657//18 686//18 721//18 +f 722//18 688//18 658//18 687//18 +f 688//76 723//76 689//76 659//76 +f 664//77 694//77 728//77 695//77 +f 666//18 695//18 729//18 696//18 +f 696//18 730//18 731//18 697//18 +f 697//78 732//78 698//78 665//78 +f 743//79 735//79 701//79 705//79 +f 698//72 732//72 711//72 675//72 +f 676//72 711//72 750//72 712//72 +f 754//80 715//80 679//80 716//80 +f 716//75 681//75 689//75 723//75 +f 715//81 755//81 717//81 680//81 +f 721//18 758//18 722//18 687//18 +f 722//82 759//82 723//82 688//82 +f 695//83 728//83 766//83 767//83 +f 695//18 767//18 768//18 729//18 +f 696//18 729//18 769//18 730//18 +f 731//84 772//84 732//84 697//84 +f 736//85 702//85 701//85 735//85 +f 776//86 741//86 672//86 704//86 +f 741//87 742//87 705//87 672//87 +f 742//88 777//88 743//88 705//88 +f 778//89 735//89 743//89 779//89 +f 732//72 772//72 750//72 711//72 +f 754//80 716//80 723//80 759//80 +f 755//90 715//90 754//90 757//90 +f 759//91 722//91 758//91 785//91 +f 767//92 766//92 791//92 792//92 +f 793//93 768//93 767//93 792//93 +f 768//94 794//94 795//94 729//94 +f 729//95 795//95 812//95 769//95 +f 735//96 778//96 798//96 736//96 +f 751//97 799//97 801//97 740//97 +f 740//7 801//7 802//7 775//7 +f 779//98 743//98 777//98 805//98 +f 778//89 779//89 793//89 792//89 +f 784//99 808//99 799//99 751//99 +f 785//90 757//90 754//90 759//90 +f 793//100 811//100 794//100 768//100 +f 792//96 791//96 798//96 778//96 +f 775//101 802//101 828//101 815//101 +f 779//98 805//98 811//98 793//98 +f 784//99 797//99 818//99 808//99 +f 796//18 814//18 824//18 825//18 +f 797//102 796//102 825//102 818//102 +f 814//103 844//103 860//103 824//103 +f 815//104 828//104 846//104 827//104 +f 844//104 827//104 846//104 860//104 +f 871//105 872//105 873//105 874//105 +f 875//105 874//105 873//105 876//105 +usemtl Black +f 21//18 4//18 3//18 22//18 +f 9//106 8//106 7//106 10//106 +f 23//7 6//7 5//7 24//7 +f 14//105 2//105 1//105 16//105 +f 6//105 11//105 12//105 5//105 +f 17//18 9//18 10//18 18//18 +f 4//106 15//106 13//106 3//106 +f 1//107 22//107 19//107 16//107 +f 20//106 17//106 18//106 19//106 +f 12//107 18//107 24//107 5//107 +f 15//7 20//7 19//7 13//7 +f 6//108 23//108 17//108 11//108 +f 23//108 8//108 9//108 17//108 +f 14//108 20//108 21//108 2//108 +f 18//107 10//107 7//107 24//107 +f 22//107 3//107 13//107 19//107 +f 8//7 23//7 24//7 7//7 +f 2//18 21//18 22//18 1//18 +f 20//108 15//108 4//108 21//108 +f 16//107 19//107 18//107 12//107 +f 11//108 17//108 20//108 14//108 +f 11//105 14//105 16//105 12//105 +f 563//109 584//109 582//109 564//109 +f 563//1 583//1 609//1 584//1 +f 605//110 604//110 635//110 636//110 +f 605//1 636//1 609//1 583//1 +f 620//111 621//111 654//111 655//111 +f 654//112 621//112 653//112 +f 620//111 655//111 683//111 656//111 +f 684//113 685//113 655//113 654//113 +f 674//18 673//18 709//18 710//18 +f 678//114 677//114 713//114 714//114 +f 684//115 654//115 653//115 682//115 +f 718//113 683//113 655//113 685//113 +f 683//116 686//116 656//116 +f 685//117 684//117 719//117 720//117 +f 707//118 674//118 710//118 745//118 +f 673//119 708//119 747//119 709//119 +f 710//18 709//18 748//18 749//18 +f 677//120 712//120 713//120 +f 752//121 714//121 713//121 753//121 +f 682//122 717//122 719//122 684//122 +f 685//117 720//117 756//117 718//117 +f 718//123 721//123 686//123 683//123 +f 755//124 757//124 720//124 719//124 +f 724//7 762//7 763//7 725//7 +f 730//125 770//125 771//125 731//125 +f 751//126 740//126 704//126 678//126 714//126 +f 774//7 704//7 740//7 775//7 +f 744//127 707//127 745//127 780//127 +f 745//128 710//128 749//128 781//128 +f 708//129 746//129 782//129 747//129 +f 709//130 747//130 783//130 748//130 +f 748//131 783//131 781//131 749//131 +f 712//132 750//132 753//132 713//132 +f 714//133 752//133 784//133 751//133 +f 752//121 753//121 771//121 770//121 +f 717//134 755//134 719//134 +f 785//124 756//124 720//124 757//124 +f 756//135 758//135 721//135 718//135 +f 761//136 786//136 762//136 724//136 +f 762//7 787//7 788//7 763//7 +f 725//137 763//137 789//137 764//137 +f 769//138 796//138 797//138 770//138 730//138 +f 731//139 771//139 772//139 +f 774//140 775//140 815//140 800//140 +f 704//141 774//141 803//141 776//141 +f 744//127 780//127 786//127 761//127 +f 780//142 745//142 781//142 806//142 +f 764//129 789//129 782//129 746//129 +f 747//143 782//143 807//143 783//143 +f 772//132 771//132 753//132 750//132 +f 770//133 797//133 784//133 752//133 +f 758//144 756//144 785//144 +f 786//145 809//145 787//145 762//145 +f 788//146 787//146 809//146 810//146 +f 763//147 788//147 810//147 789//147 +f 813//18 814//18 796//18 769//18 +f 774//148 800//148 804//148 803//148 +f 802//149 801//149 820//149 816//149 +f 780//150 806//150 809//150 786//150 +f 806//151 781//151 783//151 807//151 +f 789//152 810//152 807//152 782//152 +f 799//153 808//153 819//153 820//153 +f 769//154 812//154 821//154 813//154 +f 813//155 823//155 844//155 814//155 +f 801//156 799//156 820//156 +f 826//157 800//157 815//157 827//157 +f 816//158 828//158 802//158 +f 800//159 826//159 817//159 804//159 +f 806//160 807//160 810//160 809//160 +f 818//153 829//153 819//153 808//153 +f 820//161 819//161 830//161 831//161 832//161 833//161 834//161 835//161 836//161 837//161 838//161 839//161 840//161 841//161 842//161 843//161 816//161 +f 813//162 821//162 822//162 823//162 +f 824//163 845//163 829//163 825//163 +f 826//157 827//157 844//157 823//157 +f 846//164 828//164 816//164 843//164 +f 823//159 822//159 817//159 826//159 +f 825//165 829//165 818//165 +f 829//161 845//161 843//161 842//161 847//161 848//161 849//161 850//161 851//161 852//161 853//161 854//161 855//161 856//161 857//161 858//161 859//161 830//161 819//161 +f 845//166 824//166 860//166 +f 846//164 843//164 845//164 860//164 +f 861//161 862//161 863//161 864//161 865//161 +f 862//161 861//161 866//161 867//161 868//161 869//161 870//161 +usemtl Metal +f 467//7 466//7 468//7 469//7 +f 469//167 468//167 472//167 473//167 +f 473//18 472//18 470//18 471//18 +f 471//168 470//168 466//168 467//168 +f 468//169 482//169 484//169 472//169 +f 471//18 477//18 476//18 473//18 +f 477//18 481//18 480//18 476//18 +f 469//7 475//7 474//7 467//7 +f 467//170 474//170 477//170 471//170 +f 473//171 476//171 475//171 469//171 +f 481//172 478//172 479//172 480//172 +f 475//7 479//7 478//7 474//7 +f 474//173 478//173 481//173 477//173 +f 476//174 480//174 479//174 475//174 +f 483//175 485//175 484//175 482//175 +f 470//176 485//176 483//176 466//176 +f 472//18 484//18 485//18 470//18 +f 466//7 483//7 482//7 468//7 +f 486//7 487//7 488//7 489//7 +f 490//177 486//177 489//177 491//177 +f 492//7 493//7 487//7 486//7 +f 487//178 494//178 495//178 488//178 +f 489//7 488//7 496//7 497//7 +f 490//177 491//177 498//177 499//177 +f 500//179 492//179 486//179 490//179 +f 491//180 489//180 497//180 501//180 +f 493//181 503//181 494//181 487//181 +f 504//178 505//178 495//178 494//178 +f 488//182 495//182 506//182 496//182 +f 497//7 496//7 507//7 508//7 +f 500//179 490//179 499//179 509//179 +f 491//180 501//180 510//180 498//180 +f 499//18 498//18 505//18 504//18 +f 501//183 497//183 508//183 512//183 +f 514//181 504//181 494//181 503//181 +f 505//182 515//182 506//182 495//182 +f 496//184 506//184 516//184 507//184 +f 508//7 507//7 517//7 518//7 +f 509//18 499//18 504//18 514//18 +f 501//183 512//183 520//183 510//183 +f 498//18 510//18 515//18 505//18 +f 512//185 508//185 518//185 522//185 +f 515//184 526//184 516//184 506//184 +f 507//186 516//186 527//186 517//186 +f 518//7 517//7 528//7 529//7 +f 512//185 522//185 531//185 520//185 +f 510//18 520//18 526//18 515//18 +f 532//187 529//187 511//187 521//187 +f 522//188 518//188 529//188 532//188 +f 526//186 540//186 527//186 516//186 +f 517//189 527//189 541//189 528//189 +f 529//7 528//7 533//7 511//7 +f 532//187 521//187 519//187 543//187 +f 522//188 532//188 543//188 531//188 +f 520//18 531//18 540//18 526//18 +f 540//189 555//189 541//189 527//189 +f 528//190 541//190 556//190 533//190 +f 543//18 519//18 557//18 555//18 +f 531//18 543//18 555//18 540//18 +f 555//190 557//190 556//190 541//190 +f 610//7 640//7 641//7 586//7 +f 612//7 586//7 641//7 643//7 +f 612//191 643//191 699//191 637//191 +f 610//7 639//7 670//7 640//7 +f 640//192 671//192 703//192 641//192 +f 643//193 641//193 673//193 674//193 +f 662//18 691//18 692//18 628//18 +f 663//18 628//18 692//18 693//18 +f 668//194 637//194 699//194 700//194 +f 669//7 702//7 670//7 639//7 +f 640//195 670//195 737//195 671//195 +f 706//196 643//196 674//196 707//196 +f 641//197 703//197 708//197 673//197 +f 662//198 690//198 733//198 691//198 +f 691//199 724//199 725//199 692//199 +f 663//18 693//18 726//18 694//18 +f 668//194 700//194 733//194 690//194 +f 700//200 699//200 706//200 734//200 +f 643//201 706//201 699//201 +f 738//202 703//202 671//202 739//202 +f 734//203 706//203 707//203 744//203 +f 703//203 738//203 746//203 708//203 +f 760//204 761//204 724//204 691//204 +f 692//205 725//205 764//205 765//205 +f 728//18 694//18 726//18 766//18 +f 765//206 727//206 693//206 692//206 +f 700//200 734//200 760//200 733//200 +f 737//207 670//207 702//207 736//207 +f 739//208 671//208 737//208 773//208 +f 738//202 739//202 727//202 765//202 +f 734//203 744//203 761//203 760//203 +f 765//203 764//203 746//203 738//203 +f 691//209 733//209 760//209 +f 790//210 726//210 693//210 727//210 +f 766//211 726//211 790//211 791//211 +f 736//212 798//212 773//212 737//212 +f 739//208 773//208 790//208 727//208 +f 791//212 790//212 773//212 798//212 +usemtl DarkWood +f 741//7 776//7 803//7 742//7 +f 804//213 777//213 742//213 803//213 +f 805//214 777//214 804//214 817//214 +f 795//18 794//18 821//18 812//18 +f 822//215 821//215 794//215 811//215 +f 805//214 817//214 822//214 811//214 +usemtl Barrels +f 837//216 877//216 838//216 +f 836//216 878//216 877//216 837//216 +f 838//216 877//216 882//216 879//216 839//216 +f 835//217 880//217 878//217 836//217 +f 878//218 881//218 877//218 +f 839//219 879//219 883//219 840//219 +f 834//217 880//217 835//217 +f 878//220 880//220 881//220 +f 877//221 881//221 882//221 +f 879//220 882//220 881//220 884//220 +f 883//222 879//222 884//222 885//222 +f 840//223 883//223 886//223 841//223 +f 833//217 887//217 888//217 880//217 834//217 +f 881//224 880//224 888//224 +f 884//216 881//216 889//216 890//216 +f 886//225 883//225 885//225 891//225 +f 885//219 884//219 890//219 892//219 +f 841//217 886//217 893//217 847//217 842//217 +f 832//223 894//223 887//223 833//223 +f 888//226 887//226 895//226 881//226 +f 881//217 895//217 896//217 889//217 +f 897//108 898//108 899//108 890//108 889//108 +f 893//226 886//226 891//226 900//226 +f 891//223 885//223 892//223 901//223 +f 892//108 890//108 899//108 902//108 +f 847//227 893//227 903//227 848//227 +f 831//219 904//219 894//219 832//219 +f 887//225 894//225 905//225 895//225 +f 895//223 905//223 906//223 896//223 +f 907//108 908//108 909//108 910//108 911//108 889//108 896//108 906//108 912//108 913//108 +f 889//108 911//108 897//108 +f 910//108 914//108 915//108 898//108 897//108 +f 899//216 898//216 916//216 917//216 +f 903//228 893//228 900//228 918//228 +f 900//229 891//229 919//229 920//229 +f 891//230 901//230 921//230 919//230 +f 901//108 892//108 902//108 922//108 +f 902//219 899//219 917//219 923//219 +f 848//231 903//231 924//231 849//231 +f 859//216 925//216 904//216 831//216 830//216 +f 894//222 904//222 926//222 905//222 +f 905//219 926//219 912//219 906//219 +f 927//232 928//232 907//232 913//232 +f 928//233 929//233 908//233 907//233 +f 929//231 930//231 909//231 908//231 +f 930//227 931//227 910//227 909//227 +f 897//108 911//108 910//108 +f 926//216 927//216 913//216 912//216 +f 931//232 932//232 914//232 910//232 +f 914//108 933//108 934//108 915//108 +f 898//232 915//232 935//232 916//232 +f 917//108 916//108 936//108 937//108 +f 924//234 903//234 918//234 938//234 +f 918//235 900//235 920//235 939//235 +f 920//107 919//107 940//107 941//107 +f 901//236 942//236 943//236 921//236 +f 919//7 921//7 944//7 940//7 +f 942//108 901//108 922//108 945//108 +f 922//223 902//223 923//223 946//223 +f 923//108 917//108 937//108 947//108 +f 849//233 924//233 948//233 850//233 +f 858//232 949//232 925//232 859//232 +f 904//220 925//220 927//220 926//220 +f 925//237 949//237 928//237 927//237 +f 949//238 950//238 929//238 928//238 +f 950//234 951//234 930//234 929//234 +f 951//228 952//228 931//228 930//228 +f 953//237 948//237 932//237 931//237 +f 932//233 938//233 933//233 914//233 +f 933//108 954//108 955//108 934//108 +f 915//233 934//233 956//233 935//233 +f 916//108 935//108 957//108 936//108 +f 937//227 936//227 866//227 861//227 865//227 +f 948//238 924//238 938//238 932//238 +f 938//231 918//231 954//231 933//231 +f 954//239 918//239 939//239 958//239 +f 939//107 920//107 941//107 959//107 +f 940//240 960//240 970//240 941//240 +f 942//241 954//241 958//241 943//241 +f 921//108 943//108 961//108 944//108 +f 940//7 944//7 962//7 960//7 +f 954//108 942//108 945//108 955//108 +f 945//217 922//217 946//217 963//217 +f 946//108 923//108 947//108 964//108 +f 864//231 947//231 937//231 865//231 +f 850//232 948//232 953//232 965//232 851//232 +f 857//233 950//233 949//233 858//233 +f 856//231 951//231 950//231 857//231 +f 952//227 951//227 856//227 855//227 966//227 +f 966//242 931//242 952//242 +f 931//243 965//243 953//243 +f 934//231 955//231 967//231 956//231 +f 935//108 956//108 968//108 957//108 +f 866//217 936//217 957//217 867//217 +f 958//18 939//18 959//18 969//18 +f 941//244 970//244 977//244 959//244 +f 943//108 958//108 969//108 961//108 +f 961//245 971//245 962//245 944//245 +f 960//7 962//7 972//7 973//7 +f 955//227 945//227 963//227 967//227 +f 963//108 946//108 964//108 974//108 +f 863//233 964//233 947//233 864//233 +f 851//232 965//232 852//232 +f 975//237 931//237 966//237 +f 975//246 965//246 931//246 +f 956//108 967//108 976//108 968//108 +f 867//223 957//223 968//223 868//223 +f 969//18 959//18 977//18 978//18 +f 960//247 973//247 980//247 970//247 +f 969//248 978//248 971//248 961//248 +f 971//249 979//249 972//249 962//249 +f 980//250 973//250 972//250 979//250 +f 967//108 963//108 974//108 976//108 +f 974//232 964//232 863//232 862//232 870//232 +f 852//232 965//232 975//232 853//232 +f 854//227 966//227 855//227 +f 853//227 975//227 966//227 854//227 +f 868//219 968//219 976//219 869//219 +f 978//18 977//18 981//18 982//18 +f 970//251 980//251 981//251 977//251 +f 978//252 982//252 979//252 971//252 +f 981//253 980//253 979//253 982//253 +f 869//216 976//216 974//216 870//216 +usemtl BulletYellow +f 25//254 27//254 28//254 26//254 +f 27//255 29//255 30//255 28//255 +f 29//256 31//256 32//256 30//256 +f 31//257 33//257 34//257 32//257 +f 33//258 35//258 36//258 34//258 +f 35//259 37//259 38//259 36//259 +f 28//107 30//107 32//107 34//107 36//107 38//107 40//107 26//107 +f 39//236 25//236 26//236 40//236 +f 37//260 39//260 40//260 38//260 +f 29//261 43//261 44//261 31//261 +f 46//219 54//219 55//219 47//219 +f 35//262 46//262 47//262 37//262 +f 31//263 44//263 45//263 33//263 +f 37//264 47//264 48//264 39//264 +f 27//265 42//265 43//265 29//265 +f 33//266 45//266 46//266 35//266 +f 39//267 48//267 41//267 25//267 +f 25//268 41//268 42//268 27//268 +f 49//108 57//108 58//108 50//108 +f 44//232 52//232 53//232 45//232 +f 42//231 50//231 51//231 43//231 +f 47//223 55//223 56//223 48//223 +f 45//216 53//216 54//216 46//216 +f 43//233 51//233 52//233 44//233 +f 41//227 49//227 50//227 42//227 +f 48//217 56//217 49//217 41//217 +f 56//108 64//108 57//108 49//108 +f 54//108 62//108 63//108 55//108 +f 52//108 60//108 61//108 53//108 +f 50//108 58//108 59//108 51//108 +f 55//108 63//108 64//108 56//108 +f 53//108 61//108 62//108 54//108 +f 51//108 59//108 60//108 52//108 +f 74//254 76//254 77//254 75//254 +f 76//255 78//255 79//255 77//255 +f 78//256 80//256 81//256 79//256 +f 80//257 82//257 83//257 81//257 +f 82//258 84//258 85//258 83//258 +f 84//259 86//259 87//259 85//259 +f 77//107 79//107 81//107 83//107 85//107 87//107 89//107 75//107 +f 88//236 74//236 75//236 89//236 +f 86//260 88//260 89//260 87//260 +f 78//261 92//261 93//261 80//261 +f 95//219 103//219 104//219 96//219 +f 84//262 95//262 96//262 86//262 +f 80//263 93//263 94//263 82//263 +f 86//264 96//264 97//264 88//264 +f 76//265 91//265 92//265 78//265 +f 82//266 94//266 95//266 84//266 +f 88//267 97//267 90//267 74//267 +f 74//268 90//268 91//268 76//268 +f 98//108 106//108 107//108 99//108 +f 93//232 101//232 102//232 94//232 +f 91//231 99//231 100//231 92//231 +f 96//223 104//223 105//223 97//223 +f 94//216 102//216 103//216 95//216 +f 92//233 100//233 101//233 93//233 +f 90//227 98//227 99//227 91//227 +f 97//217 105//217 98//217 90//217 +f 105//108 113//108 106//108 98//108 +f 103//108 111//108 112//108 104//108 +f 101//108 109//108 110//108 102//108 +f 99//108 107//108 108//108 100//108 +f 104//108 112//108 113//108 105//108 +f 102//108 110//108 111//108 103//108 +f 100//108 108//108 109//108 101//108 +f 123//254 125//254 126//254 124//254 +f 125//255 127//255 128//255 126//255 +f 127//256 129//256 130//256 128//256 +f 129//257 131//257 132//257 130//257 +f 131//258 133//258 134//258 132//258 +f 133//259 135//259 136//259 134//259 +f 126//107 128//107 130//107 132//107 134//107 136//107 138//107 124//107 +f 137//236 123//236 124//236 138//236 +f 135//260 137//260 138//260 136//260 +f 127//261 141//261 142//261 129//261 +f 144//219 152//219 153//219 145//219 +f 133//262 144//262 145//262 135//262 +f 129//263 142//263 143//263 131//263 +f 135//264 145//264 146//264 137//264 +f 125//265 140//265 141//265 127//265 +f 131//266 143//266 144//266 133//266 +f 137//267 146//267 139//267 123//267 +f 123//268 139//268 140//268 125//268 +f 147//108 155//108 156//108 148//108 +f 142//232 150//232 151//232 143//232 +f 140//231 148//231 149//231 141//231 +f 145//223 153//223 154//223 146//223 +f 143//216 151//216 152//216 144//216 +f 141//233 149//233 150//233 142//233 +f 139//227 147//227 148//227 140//227 +f 146//217 154//217 147//217 139//217 +f 154//108 162//108 155//108 147//108 +f 152//108 160//108 161//108 153//108 +f 150//108 158//108 159//108 151//108 +f 148//108 156//108 157//108 149//108 +f 153//108 161//108 162//108 154//108 +f 151//108 159//108 160//108 152//108 +f 149//108 157//108 158//108 150//108 +f 172//254 174//254 175//254 173//254 +f 174//255 176//255 177//255 175//255 +f 176//256 178//256 179//256 177//256 +f 178//257 180//257 181//257 179//257 +f 180//258 182//258 183//258 181//258 +f 182//259 184//259 185//259 183//259 +f 175//107 177//107 179//107 181//107 183//107 185//107 187//107 173//107 +f 186//236 172//236 173//236 187//236 +f 184//260 186//260 187//260 185//260 +f 176//261 190//261 191//261 178//261 +f 193//219 201//219 202//219 194//219 +f 182//262 193//262 194//262 184//262 +f 178//269 191//269 192//269 180//269 +f 184//264 194//264 195//264 186//264 +f 174//265 189//265 190//265 176//265 +f 180//270 192//270 193//270 182//270 +f 186//271 195//271 188//271 172//271 +f 172//268 188//268 189//268 174//268 +f 196//108 204//108 205//108 197//108 +f 191//232 199//232 200//232 192//232 +f 189//231 197//231 198//231 190//231 +f 194//223 202//223 203//223 195//223 +f 192//216 200//216 201//216 193//216 +f 190//233 198//233 199//233 191//233 +f 188//227 196//227 197//227 189//227 +f 195//217 203//217 196//217 188//217 +f 203//108 211//108 204//108 196//108 +f 201//108 209//108 210//108 202//108 +f 199//108 207//108 208//108 200//108 +f 197//108 205//108 206//108 198//108 +f 202//108 210//108 211//108 203//108 +f 200//108 208//108 209//108 201//108 +f 198//108 206//108 207//108 199//108 +f 221//254 223//254 224//254 222//254 +f 223//255 225//255 226//255 224//255 +f 225//256 227//256 228//256 226//256 +f 227//257 229//257 230//257 228//257 +f 229//258 231//258 232//258 230//258 +f 231//259 233//259 234//259 232//259 +f 224//107 226//107 228//107 230//107 232//107 234//107 236//107 222//107 +f 235//236 221//236 222//236 236//236 +f 233//260 235//260 236//260 234//260 +f 225//261 239//261 240//261 227//261 +f 242//219 250//219 251//219 243//219 +f 231//262 242//262 243//262 233//262 +f 227//269 240//269 241//269 229//269 +f 233//264 243//264 244//264 235//264 +f 223//265 238//265 239//265 225//265 +f 229//270 241//270 242//270 231//270 +f 235//267 244//267 237//267 221//267 +f 221//268 237//268 238//268 223//268 +f 245//108 253//108 254//108 246//108 +f 240//232 248//232 249//232 241//232 +f 238//231 246//231 247//231 239//231 +f 243//223 251//223 252//223 244//223 +f 241//216 249//216 250//216 242//216 +f 239//233 247//233 248//233 240//233 +f 237//227 245//227 246//227 238//227 +f 244//217 252//217 245//217 237//217 +f 252//108 260//108 253//108 245//108 +f 250//108 258//108 259//108 251//108 +f 248//108 256//108 257//108 249//108 +f 246//108 254//108 255//108 247//108 +f 251//108 259//108 260//108 252//108 +f 249//108 257//108 258//108 250//108 +f 247//108 255//108 256//108 248//108 +f 270//254 272//254 273//254 271//254 +f 272//255 274//255 275//255 273//255 +f 274//256 276//256 277//256 275//256 +f 276//257 278//257 279//257 277//257 +f 278//258 280//258 281//258 279//258 +f 280//259 282//259 283//259 281//259 +f 273//107 275//107 277//107 279//107 281//107 283//107 285//107 271//107 +f 284//236 270//236 271//236 285//236 +f 282//260 284//260 285//260 283//260 +f 274//261 288//261 289//261 276//261 +f 291//219 299//219 300//219 292//219 +f 280//262 291//262 292//262 282//262 +f 276//263 289//263 290//263 278//263 +f 282//264 292//264 293//264 284//264 +f 272//265 287//265 288//265 274//265 +f 278//266 290//266 291//266 280//266 +f 284//267 293//267 286//267 270//267 +f 270//268 286//268 287//268 272//268 +f 294//108 302//108 303//108 295//108 +f 289//232 297//232 298//232 290//232 +f 287//231 295//231 296//231 288//231 +f 292//223 300//223 301//223 293//223 +f 290//216 298//216 299//216 291//216 +f 288//233 296//233 297//233 289//233 +f 286//227 294//227 295//227 287//227 +f 293//217 301//217 294//217 286//217 +f 301//108 309//108 302//108 294//108 +f 299//108 307//108 308//108 300//108 +f 297//108 305//108 306//108 298//108 +f 295//108 303//108 304//108 296//108 +f 300//108 308//108 309//108 301//108 +f 298//108 306//108 307//108 299//108 +f 296//108 304//108 305//108 297//108 +f 319//254 321//254 322//254 320//254 +f 321//255 323//255 324//255 322//255 +f 323//256 325//256 326//256 324//256 +f 325//257 327//257 328//257 326//257 +f 327//258 329//258 330//258 328//258 +f 329//259 331//259 332//259 330//259 +f 322//107 324//107 326//107 328//107 330//107 332//107 334//107 320//107 +f 333//236 319//236 320//236 334//236 +f 331//260 333//260 334//260 332//260 +f 323//261 337//261 338//261 325//261 +f 340//219 348//219 349//219 341//219 +f 329//262 340//262 341//262 331//262 +f 325//263 338//263 339//263 327//263 +f 331//264 341//264 342//264 333//264 +f 321//265 336//265 337//265 323//265 +f 327//266 339//266 340//266 329//266 +f 333//267 342//267 335//267 319//267 +f 319//268 335//268 336//268 321//268 +f 343//108 351//108 352//108 344//108 +f 338//232 346//232 347//232 339//232 +f 336//231 344//231 345//231 337//231 +f 341//223 349//223 350//223 342//223 +f 339//216 347//216 348//216 340//216 +f 337//233 345//233 346//233 338//233 +f 335//227 343//227 344//227 336//227 +f 342//217 350//217 343//217 335//217 +f 350//108 358//108 351//108 343//108 +f 348//108 356//108 357//108 349//108 +f 346//108 354//108 355//108 347//108 +f 344//108 352//108 353//108 345//108 +f 349//108 357//108 358//108 350//108 +f 347//108 355//108 356//108 348//108 +f 345//108 353//108 354//108 346//108 +f 368//254 370//254 371//254 369//254 +f 370//255 372//255 373//255 371//255 +f 372//256 374//256 375//256 373//256 +f 374//257 376//257 377//257 375//257 +f 376//258 378//258 379//258 377//258 +f 378//259 380//259 381//259 379//259 +f 371//107 373//107 375//107 377//107 379//107 381//107 383//107 369//107 +f 382//236 368//236 369//236 383//236 +f 380//260 382//260 383//260 381//260 +f 372//261 386//261 387//261 374//261 +f 389//219 397//219 398//219 390//219 +f 378//262 389//262 390//262 380//262 +f 374//263 387//263 388//263 376//263 +f 380//264 390//264 391//264 382//264 +f 370//265 385//265 386//265 372//265 +f 376//266 388//266 389//266 378//266 +f 382//267 391//267 384//267 368//267 +f 368//268 384//268 385//268 370//268 +f 392//108 400//108 401//108 393//108 +f 387//232 395//232 396//232 388//232 +f 385//231 393//231 394//231 386//231 +f 390//223 398//223 399//223 391//223 +f 388//216 396//216 397//216 389//216 +f 386//233 394//233 395//233 387//233 +f 384//227 392//227 393//227 385//227 +f 391//217 399//217 392//217 384//217 +f 399//108 407//108 400//108 392//108 +f 397//108 405//108 406//108 398//108 +f 395//108 403//108 404//108 396//108 +f 393//108 401//108 402//108 394//108 +f 398//108 406//108 407//108 399//108 +f 396//108 404//108 405//108 397//108 +f 394//108 402//108 403//108 395//108 +f 417//254 419//254 420//254 418//254 +f 419//255 421//255 422//255 420//255 +f 421//256 423//256 424//256 422//256 +f 423//257 425//257 426//257 424//257 +f 425//258 427//258 428//258 426//258 +f 427//259 429//259 430//259 428//259 +f 420//107 422//107 424//107 426//107 428//107 430//107 432//107 418//107 +f 431//236 417//236 418//236 432//236 +f 429//260 431//260 432//260 430//260 +f 421//261 435//261 436//261 423//261 +f 438//219 446//219 447//219 439//219 +f 427//262 438//262 439//262 429//262 +f 423//263 436//263 437//263 425//263 +f 429//264 439//264 440//264 431//264 +f 419//265 434//265 435//265 421//265 +f 425//266 437//266 438//266 427//266 +f 431//267 440//267 433//267 417//267 +f 417//268 433//268 434//268 419//268 +f 441//108 449//108 450//108 442//108 +f 436//232 444//232 445//232 437//232 +f 434//231 442//231 443//231 435//231 +f 439//223 447//223 448//223 440//223 +f 437//216 445//216 446//216 438//216 +f 435//233 443//233 444//233 436//233 +f 433//227 441//227 442//227 434//227 +f 440//217 448//217 441//217 433//217 +f 448//108 456//108 449//108 441//108 +f 446//108 454//108 455//108 447//108 +f 444//108 452//108 453//108 445//108 +f 442//108 450//108 451//108 443//108 +f 447//108 455//108 456//108 448//108 +f 445//108 453//108 454//108 446//108 +f 443//108 451//108 452//108 444//108 +usemtl BulletOrange +f 63//272 71//272 72//272 64//272 +f 61//273 69//273 70//273 62//273 +f 59//274 67//274 68//274 60//274 +f 57//275 65//275 66//275 58//275 +f 64//276 72//276 65//276 57//276 +f 62//277 70//277 71//277 63//277 +f 60//278 68//278 69//278 61//278 +f 58//279 66//279 67//279 59//279 +f 66//280 73//280 67//280 +f 71//281 73//281 72//281 +f 69//282 73//282 70//282 +f 67//283 73//283 68//283 +f 65//284 73//284 66//284 +f 72//285 73//285 65//285 +f 70//286 73//286 71//286 +f 68//287 73//287 69//287 +f 112//272 120//272 121//272 113//272 +f 110//273 118//273 119//273 111//273 +f 108//274 116//274 117//274 109//274 +f 106//275 114//275 115//275 107//275 +f 113//276 121//276 114//276 106//276 +f 111//277 119//277 120//277 112//277 +f 109//278 117//278 118//278 110//278 +f 107//279 115//279 116//279 108//279 +f 115//280 122//280 116//280 +f 120//281 122//281 121//281 +f 118//282 122//282 119//282 +f 116//283 122//283 117//283 +f 114//284 122//284 115//284 +f 121//285 122//285 114//285 +f 119//286 122//286 120//286 +f 117//287 122//287 118//287 +f 161//272 169//272 170//272 162//272 +f 159//273 167//273 168//273 160//273 +f 157//274 165//274 166//274 158//274 +f 155//275 163//275 164//275 156//275 +f 162//276 170//276 163//276 155//276 +f 160//277 168//277 169//277 161//277 +f 158//278 166//278 167//278 159//278 +f 156//279 164//279 165//279 157//279 +f 164//280 171//280 165//280 +f 169//281 171//281 170//281 +f 167//282 171//282 168//282 +f 165//283 171//283 166//283 +f 163//284 171//284 164//284 +f 170//285 171//285 163//285 +f 168//286 171//286 169//286 +f 166//287 171//287 167//287 +f 210//272 218//272 219//272 211//272 +f 208//273 216//273 217//273 209//273 +f 206//274 214//274 215//274 207//274 +f 204//275 212//275 213//275 205//275 +f 211//276 219//276 212//276 204//276 +f 209//277 217//277 218//277 210//277 +f 207//278 215//278 216//278 208//278 +f 205//279 213//279 214//279 206//279 +f 213//280 220//280 214//280 +f 218//281 220//281 219//281 +f 216//282 220//282 217//282 +f 214//283 220//283 215//283 +f 212//284 220//284 213//284 +f 219//285 220//285 212//285 +f 217//286 220//286 218//286 +f 215//287 220//287 216//287 +f 259//272 267//272 268//272 260//272 +f 257//273 265//273 266//273 258//273 +f 255//274 263//274 264//274 256//274 +f 253//275 261//275 262//275 254//275 +f 260//276 268//276 261//276 253//276 +f 258//277 266//277 267//277 259//277 +f 256//278 264//278 265//278 257//278 +f 254//279 262//279 263//279 255//279 +f 262//280 269//280 263//280 +f 267//281 269//281 268//281 +f 265//282 269//282 266//282 +f 263//283 269//283 264//283 +f 261//284 269//284 262//284 +f 268//285 269//285 261//285 +f 266//286 269//286 267//286 +f 264//287 269//287 265//287 +f 308//272 316//272 317//272 309//272 +f 306//273 314//273 315//273 307//273 +f 304//274 312//274 313//274 305//274 +f 302//275 310//275 311//275 303//275 +f 309//276 317//276 310//276 302//276 +f 307//277 315//277 316//277 308//277 +f 305//278 313//278 314//278 306//278 +f 303//279 311//279 312//279 304//279 +f 311//280 318//280 312//280 +f 316//281 318//281 317//281 +f 314//282 318//282 315//282 +f 312//283 318//283 313//283 +f 310//284 318//284 311//284 +f 317//285 318//285 310//285 +f 315//286 318//286 316//286 +f 313//287 318//287 314//287 +f 357//272 365//272 366//272 358//272 +f 355//273 363//273 364//273 356//273 +f 353//274 361//274 362//274 354//274 +f 351//275 359//275 360//275 352//275 +f 358//276 366//276 359//276 351//276 +f 356//277 364//277 365//277 357//277 +f 354//278 362//278 363//278 355//278 +f 352//279 360//279 361//279 353//279 +f 360//280 367//280 361//280 +f 365//281 367//281 366//281 +f 363//282 367//282 364//282 +f 361//283 367//283 362//283 +f 359//284 367//284 360//284 +f 366//285 367//285 359//285 +f 364//286 367//286 365//286 +f 362//287 367//287 363//287 +f 406//272 414//272 415//272 407//272 +f 404//273 412//273 413//273 405//273 +f 402//274 410//274 411//274 403//274 +f 400//275 408//275 409//275 401//275 +f 407//276 415//276 408//276 400//276 +f 405//277 413//277 414//277 406//277 +f 403//278 411//278 412//278 404//278 +f 401//279 409//279 410//279 402//279 +f 409//280 416//280 410//280 +f 414//281 416//281 415//281 +f 412//282 416//282 413//282 +f 410//283 416//283 411//283 +f 408//284 416//284 409//284 +f 415//285 416//285 408//285 +f 413//286 416//286 414//286 +f 411//287 416//287 412//287 +f 455//272 463//272 464//272 456//272 +f 453//273 461//273 462//273 454//273 +f 451//274 459//274 460//274 452//274 +f 449//275 457//275 458//275 450//275 +f 456//276 464//276 457//276 449//276 +f 454//277 462//277 463//277 455//277 +f 452//278 460//278 461//278 453//278 +f 450//279 458//279 459//279 451//279 +f 458//280 465//280 459//280 +f 463//281 465//281 464//281 +f 461//282 465//282 462//282 +f 459//283 465//283 460//283 +f 457//284 465//284 458//284 +f 464//285 465//285 457//285 +f 462//286 465//286 463//286 +f 460//287 465//287 461//287 diff --git a/assets/quaternius/models/Rifle.obj.import b/assets/quaternius/models/Rifle.obj.import new file mode 100644 index 0000000..53fd75c --- /dev/null +++ b/assets/quaternius/models/Rifle.obj.import @@ -0,0 +1,25 @@ +[remap] + +importer="wavefront_obj" +importer_version=1 +type="Mesh" +uid="uid://cjej2m67fp777" +path="res://.godot/imported/Rifle.obj-e07611af2416a9a8a736e6c4a5299fc0.mesh" + +[deps] + +files=["res://.godot/imported/Rifle.obj-e07611af2416a9a8a736e6c4a5299fc0.mesh"] + +source_file="res://assets/quaternius/models/Rifle.obj" +dest_files=["res://.godot/imported/Rifle.obj-e07611af2416a9a8a736e6c4a5299fc0.mesh", "res://.godot/imported/Rifle.obj-e07611af2416a9a8a736e6c4a5299fc0.mesh"] + +[params] + +generate_tangents=true +generate_lods=true +generate_shadow_mesh=true +generate_lightmap_uv2=false +generate_lightmap_uv2_texel_size=0.2 +scale_mesh=Vector3(1, 1, 1) +offset_mesh=Vector3(0, 0, 0) +force_disable_mesh_compression=false diff --git a/assets/quaternius/models/Shotgun.glb b/assets/quaternius/models/Shotgun.glb new file mode 100644 index 0000000..85a9939 Binary files /dev/null and b/assets/quaternius/models/Shotgun.glb differ diff --git a/assets/kenney-fps/models/blaster-repeater.glb.import b/assets/quaternius/models/Shotgun.glb.import similarity index 64% rename from assets/kenney-fps/models/blaster-repeater.glb.import rename to assets/quaternius/models/Shotgun.glb.import index bdb3374..223f5d6 100644 --- a/assets/kenney-fps/models/blaster-repeater.glb.import +++ b/assets/quaternius/models/Shotgun.glb.import @@ -3,19 +3,21 @@ importer="scene" importer_version=1 type="PackedScene" -uid="uid://dd3oln1ucgqpd" -path="res://.godot/imported/blaster-repeater.glb-5f1125651aecb8bf54890e793b8c6da4.scn" +uid="uid://bfofgtyblb50p" +path="res://.godot/imported/Shotgun.glb-a190f57e8908ce676f957c7ad67f3129.scn" [deps] -source_file="res://models/blaster-repeater.glb" -dest_files=["res://.godot/imported/blaster-repeater.glb-5f1125651aecb8bf54890e793b8c6da4.scn"] +source_file="res://assets/quaternius/models/Shotgun.glb" +dest_files=["res://.godot/imported/Shotgun.glb-a190f57e8908ce676f957c7ad67f3129.scn"] [params] -nodes/root_type="Node3D" -nodes/root_name="Scene Root" +nodes/root_type="" +nodes/root_name="" nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true nodes/apply_root_scale=true nodes/root_scale=1.0 nodes/import_as_skeleton_bones=false @@ -38,5 +40,6 @@ materials/extract=0 materials/extract_format=0 materials/extract_path="" _subresources={} -gltf/naming_version=0 +gltf/naming_version=2 gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/assets/quaternius/models/Shotgun.mtl b/assets/quaternius/models/Shotgun.mtl new file mode 100644 index 0000000..70137a7 --- /dev/null +++ b/assets/quaternius/models/Shotgun.mtl @@ -0,0 +1,62 @@ +# Blender MTL File: 'Shotgun.blend' +# Material Count: 6 + +newmtl Barrels +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Black +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl BulletRed +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl BulletYellow +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl DarkMetal +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Trigger +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 diff --git a/assets/quaternius/models/Shotgun.obj b/assets/quaternius/models/Shotgun.obj new file mode 100644 index 0000000..fd3cefa --- /dev/null +++ b/assets/quaternius/models/Shotgun.obj @@ -0,0 +1,1281 @@ +# Blender v2.76 (sub 0) OBJ File: 'Shotgun.blend' +# www.blender.org +mtllib Shotgun.mtl +o Shotgun_Cylinder +v -0.092066 0.290536 -2.036970 +v -0.092066 0.290536 -2.270715 +v -0.051154 0.307483 -2.036970 +v -0.051154 0.307483 -2.270715 +v -0.034207 0.348395 -2.036970 +v -0.034207 0.348395 -2.270715 +v -0.051154 0.389308 -2.036970 +v -0.051154 0.389308 -2.270715 +v -0.092066 0.406254 -2.036970 +v -0.092066 0.406254 -2.270715 +v -0.132979 0.389308 -2.036970 +v -0.132979 0.389308 -2.270715 +v -0.149925 0.348395 -2.036970 +v -0.149925 0.348395 -2.270715 +v -0.132979 0.307483 -2.036970 +v -0.132979 0.307483 -2.270715 +v -0.060758 0.317087 -2.270715 +v -0.092066 0.304118 -2.270715 +v -0.047790 0.348395 -2.270715 +v -0.060758 0.379704 -2.270715 +v -0.092066 0.392672 -2.270715 +v -0.123375 0.379704 -2.270715 +v -0.136343 0.348395 -2.270715 +v -0.123375 0.317087 -2.270715 +v -0.060758 0.317087 -2.259676 +v -0.092066 0.304118 -2.259676 +v -0.047790 0.348395 -2.259676 +v -0.060758 0.379704 -2.259676 +v -0.092066 0.392672 -2.259676 +v -0.123375 0.379704 -2.259676 +v -0.136343 0.348395 -2.259676 +v -0.123375 0.317087 -2.259676 +v -0.092066 0.286980 -2.035834 +v -0.048640 0.304968 -2.035834 +v -0.030652 0.348395 -2.035834 +v -0.048640 0.391822 -2.035834 +v -0.092066 0.409810 -2.035834 +v -0.135493 0.391822 -2.035834 +v -0.153481 0.348395 -2.035834 +v -0.135493 0.304968 -2.035834 +v -0.092066 0.286980 -1.956658 +v -0.048640 0.304968 -1.956658 +v -0.030652 0.348395 -1.956658 +v -0.048640 0.391822 -1.956658 +v -0.092066 0.409810 -1.956658 +v -0.135493 0.391822 -1.956658 +v -0.153481 0.348395 -1.956658 +v -0.135493 0.304968 -1.956658 +v -0.092066 0.330352 -1.956658 +v -0.079308 0.335637 -1.956658 +v -0.074023 0.348395 -1.956658 +v -0.079308 0.361154 -1.956658 +v -0.092066 0.366438 -1.956658 +v -0.104825 0.361154 -1.956658 +v -0.110110 0.348395 -1.956658 +v -0.104825 0.335637 -1.956658 +v -0.014667 -0.015708 -1.202048 +v -0.014667 0.044867 -1.202048 +v -0.014667 -0.015708 -1.335920 +v -0.014667 0.044867 -1.335920 +v 0.014667 -0.015708 -1.202048 +v 0.014667 0.044867 -1.202048 +v 0.014667 -0.015708 -1.335921 +v 0.014667 0.044867 -1.335921 +v -0.014667 -0.046161 -1.280533 +v -0.014667 -0.046161 -1.229929 +v 0.014667 -0.046161 -1.280533 +v 0.014667 -0.046161 -1.229929 +v -0.014667 -0.095809 -1.253702 +v -0.014667 -0.104572 -1.229254 +v 0.014667 -0.095809 -1.253702 +v 0.014667 -0.104572 -1.229254 +v -0.014667 -0.151800 -1.271254 +v -0.014667 -0.160563 -1.259702 +v 0.014667 -0.151800 -1.271254 +v 0.014667 -0.160563 -1.259702 +v 0.047097 -0.010389 -3.179550 +v -0.006741 0.026739 -3.121388 +v -0.060579 -0.010389 -3.179549 +v -0.006741 0.048126 -4.626300 +v 0.047082 0.007363 -4.568043 +v -0.060564 0.007363 -4.568043 +v 0.074306 0.060310 -3.121389 +v 0.065056 -0.002950 -3.179550 +v 0.141226 0.073268 -3.179630 +v 0.065071 0.014814 -4.568043 +v 0.076492 0.082602 -4.626300 +v 0.144914 0.089233 -4.568043 +v 0.117172 0.133312 -3.156363 +v 0.148640 0.087534 -3.179646 +v 0.148640 0.195180 -3.218268 +v 0.144914 0.089233 -4.568043 +v 0.109814 0.140860 -4.605620 +v 0.148640 0.195180 -4.548994 +v 0.072335 0.227217 -3.181755 +v 0.141189 0.213169 -3.228603 +v 0.065071 0.289286 -3.275983 +v 0.141189 0.213169 -4.543411 +v 0.073639 0.224032 -4.594682 +v 0.065071 0.289286 -4.516867 +v -0.006741 0.269921 -3.196279 +v 0.047082 0.296737 -3.282874 +v -0.060564 0.296737 -3.282873 +v 0.047082 0.296737 -4.513144 +v -0.006741 0.261598 -4.590007 +v -0.060564 0.296737 -4.513144 +v -0.085817 0.227216 -3.181754 +v -0.078553 0.289286 -3.275983 +v -0.154670 0.213169 -3.228603 +v -0.078553 0.289286 -4.516866 +v -0.087121 0.224032 -4.594682 +v -0.154670 0.213169 -4.543411 +v -0.130654 0.133312 -3.156363 +v -0.162122 0.195179 -3.218267 +v -0.162122 0.087533 -3.179646 +v -0.162122 0.195179 -4.548993 +v -0.123296 0.140860 -4.605619 +v -0.158396 0.089232 -4.568043 +v -0.087788 0.060310 -3.121388 +v -0.154707 0.073268 -3.179629 +v -0.078538 -0.002950 -3.179549 +v -0.158396 0.089232 -4.568043 +v -0.089973 0.082602 -4.626300 +v -0.078553 0.014814 -4.568043 +v 0.047082 0.007363 -3.522402 +v 0.047097 0.003740 -3.405983 +v -0.060579 0.003740 -3.405983 +v -0.060564 0.007363 -3.522402 +v 0.065056 0.011179 -3.405983 +v 0.065071 0.014814 -3.522402 +v 0.144914 0.089232 -3.522402 +v 0.144955 0.085680 -3.405910 +v 0.144914 0.089233 -3.405887 +v 0.144914 0.089233 -3.522402 +v 0.148640 0.195180 -3.522402 +v 0.148640 0.195180 -3.405887 +v 0.141189 0.213169 -3.405887 +v 0.141189 0.213169 -3.522402 +v 0.065071 0.289286 -3.522402 +v 0.065071 0.289286 -3.405887 +v 0.047082 0.296737 -3.405887 +v 0.047082 0.296737 -3.522402 +v -0.060564 0.296737 -3.522402 +v -0.060564 0.296737 -3.405887 +v -0.078553 0.289286 -3.405887 +v -0.078553 0.289286 -3.522402 +v -0.154670 0.213169 -3.522402 +v -0.154670 0.213169 -3.405886 +v -0.162122 0.195179 -3.405886 +v -0.162122 0.195179 -3.522402 +v -0.158396 0.089232 -3.522402 +v -0.158396 0.089232 -3.405886 +v -0.078538 0.011179 -3.405983 +v -0.158436 0.085680 -3.405909 +v -0.158396 0.089232 -3.522402 +v -0.078553 0.014814 -3.522402 +v 0.103614 0.024004 -1.049154 +v 0.103614 0.024004 -1.049154 +v 0.103614 0.022727 -1.093526 +v 0.103614 0.022727 -1.093526 +v 0.207229 0.126334 -1.095276 +v 0.207229 0.128429 -1.022471 +v 0.118888 -0.012794 -1.049589 +v 0.118888 -0.012794 -1.049589 +v 0.068690 0.022727 -1.093526 +v 0.068690 0.024004 -1.049153 +v 0.103614 0.019857 -1.300711 +v 0.103615 0.019857 -1.300711 +v 0.237776 0.107025 -1.018975 +v 0.207229 0.123473 -1.302486 +v 0.207229 0.303976 -0.967700 +v 0.207229 0.358242 -1.099210 +v 0.068690 0.005399 -1.049374 +v 0.118888 -0.056828 -0.821744 +v 0.118888 -0.056828 -0.821744 +v 0.068690 0.011733 -1.049299 +v 0.068690 -0.017823 -1.204339 +v 0.068690 0.021442 -1.186279 +v 0.103614 0.021202 -2.561068 +v 0.103616 0.021202 -2.561068 +v 0.237776 0.308448 -0.956129 +v 0.237776 0.057052 -0.785486 +v 0.207230 0.124817 -2.561295 +v 0.207229 0.410402 -1.307353 +v 0.103614 0.474661 -1.109704 +v 0.103614 0.403123 -0.936337 +v -0.068541 0.005399 -1.049374 +v 0.118888 -0.129702 -0.654350 +v -0.118888 -0.056828 -0.821744 +v -0.118888 -0.012794 -1.049589 +v 0.068690 -0.098482 -1.136426 +v 0.068690 -0.098482 -1.168216 +v 0.068690 0.007077 -1.365206 +v 0.068690 0.019927 -1.366359 +v 0.068690 0.019857 -1.300711 +v -0.103614 0.019857 -1.300711 +v -0.103614 0.021202 -2.561067 +v 0.068690 0.020012 -1.445996 +v 0.068690 0.020337 -1.750953 +v 0.068690 0.020421 -1.829668 +v -0.068541 0.020421 -1.829668 +v -0.068541 0.020337 -1.750953 +v -0.068541 0.020012 -1.445995 +v -0.068541 0.019927 -1.366358 +v -0.068541 0.019857 -1.300711 +v 0.118888 0.422211 -0.920142 +v 0.237776 0.203351 -0.739839 +v 0.207230 0.408335 -2.561919 +v 0.103614 0.403123 -0.936337 +v 0.103614 0.474661 -1.109704 +v -0.068541 -0.098482 -1.136426 +v 0.237776 -0.024648 -0.597817 +v 0.118888 -0.129702 -0.654350 +v -0.118888 -0.129702 -0.654349 +v -0.118888 -0.012794 -1.049589 +v 0.068690 -0.177053 -1.175361 +v 0.068690 -0.151188 -1.193842 +v -0.068541 -0.017823 -1.204339 +v -0.068541 -0.098482 -1.168215 +v -0.068541 0.007077 -1.365206 +v 0.068690 0.008216 -1.445088 +v -0.068541 0.021442 -1.186279 +v -0.103615 0.019857 -1.300711 +v -0.103616 0.021202 -2.561067 +v 0.068690 0.012573 -1.750735 +v 0.068690 0.013696 -1.829565 +v -0.068541 0.013696 -1.829564 +v -0.068541 0.012573 -1.750735 +v -0.068541 0.008215 -1.445088 +v 0.003189 0.274357 -2.561624 +v 0.084748 0.068761 -2.561172 +v 0.111401 0.133109 -2.561314 +v 0.079707 0.209627 -2.561481 +v 0.018871 0.234826 -2.561537 +v 0.118888 0.422211 -0.920142 +v 0.118888 0.320132 -0.705763 +v 0.237776 0.091880 -0.534544 +v 0.103616 0.511949 -2.562147 +v 0.103615 0.514013 -1.309099 +v 0.079707 0.306051 -2.561694 +v -0.103614 0.474661 -1.109704 +v -0.103614 0.403123 -0.936336 +v 0.103614 0.514013 -1.309099 +v -0.103614 0.024004 -1.049153 +v -0.068541 0.011733 -1.049299 +v -0.068541 -0.177053 -1.175361 +v 0.237776 -0.256749 -0.401053 +v 0.118888 -0.292025 -0.514688 +v -0.118888 -0.292025 -0.514687 +v 0.118888 -0.292025 -0.514688 +v -0.118888 -0.129702 -0.654349 +v -0.118888 -0.056828 -0.821744 +v -0.103614 0.024004 -1.049153 +v -0.068541 -0.151188 -1.193842 +v 0.068690 -0.218027 -1.269475 +v 0.068690 -0.186312 -1.271641 +v -0.103614 0.022727 -1.093525 +v -0.103614 0.022727 -1.093525 +v -0.207229 0.123473 -1.302485 +v -0.207230 0.124817 -2.561294 +v -0.080937 0.074958 -2.561185 +v -0.073329 0.056591 -2.561145 +v 0.003189 0.024896 -2.561076 +v 0.079707 0.056591 -2.561145 +v 0.068460 -0.049283 -1.511661 +v -0.068312 -0.068783 -1.578367 +v -0.068541 0.024004 -1.049153 +v -0.068541 0.022727 -1.093525 +v -0.013700 0.234326 -2.561536 +v 0.003189 0.241321 -2.561551 +v -0.118888 0.422211 -0.920142 +v 0.118888 0.320132 -0.705763 +v 0.118888 0.196360 -0.477814 +v 0.237776 0.044646 -0.289625 +v 0.237776 0.023384 -0.301170 +v 0.111401 0.382569 -2.561862 +v 0.103614 0.511949 -2.562147 +v -0.103614 0.514013 -1.309098 +v -0.103614 0.474661 -1.109704 +v -0.068541 -0.218027 -1.269475 +v -0.118888 -0.335492 -0.503087 +v 0.118888 -0.335492 -0.503087 +v -0.118888 -0.292025 -0.514687 +v -0.237776 0.057052 -0.785485 +v -0.207229 0.128429 -1.022471 +v -0.237776 0.107024 -1.018973 +v -0.068541 -0.186312 -1.271641 +v 0.068690 -0.204259 -1.390773 +v 0.068690 -0.172903 -1.385545 +v -0.068312 -0.049283 -1.511661 +v -0.207229 0.126334 -1.095275 +v -0.073329 0.209627 -2.561481 +v -0.105024 0.133109 -2.561313 +v -0.207229 0.410401 -1.307353 +v -0.207230 0.408335 -2.561918 +v 0.068460 -0.068783 -1.578367 +v 0.003189 0.274357 -4.891192 +v 0.009311 0.276893 -4.891192 +v 0.009311 0.276893 -5.122174 +v 0.003189 0.274357 -5.122678 +v 0.003189 0.274357 -6.420291 +v 0.079707 0.306051 -6.420291 +v -0.118888 0.422211 -0.920142 +v -0.118888 0.320132 -0.705763 +v 0.118888 0.196360 -0.477814 +v 0.118888 0.182778 -0.262553 +v 0.237776 0.067736 -0.230342 +v 0.237776 0.045778 -0.229244 +v 0.079707 0.459087 -2.562031 +v -0.103614 0.511949 -2.562147 +v 0.019653 0.483962 -2.562085 +v 0.111401 0.382569 -6.420291 +v -0.103615 0.514013 -1.309098 +v -0.103614 0.403123 -0.936336 +v -0.068541 -0.204259 -1.390773 +v 0.237776 -0.190936 -0.189673 +v 0.118888 -0.335492 -0.503087 +v 0.237776 -0.324646 -0.382933 +v 0.118888 -0.441732 -0.353857 +v -0.118888 -0.441732 -0.353856 +v -0.237776 -0.024648 -0.597816 +v -0.207229 0.303976 -0.967699 +v -0.237776 0.308448 -0.956128 +v -0.068541 -0.172903 -1.385544 +v 0.068690 -0.142449 -1.524097 +v 0.068690 -0.120806 -1.500813 +v -0.068541 -0.120806 -1.500812 +v -0.207229 0.358242 -1.099209 +v -0.064609 0.302439 -2.561686 +v -0.103616 0.511949 -2.562147 +v -0.073329 0.306051 -2.561693 +v -0.068541 -0.142449 -1.524097 +v -0.073329 0.306051 -6.420291 +v -0.002934 0.276893 -5.122174 +v -0.002934 0.276893 -4.891192 +v 0.003189 0.274357 -6.532399 +v 0.079707 0.306051 -6.532399 +v -0.118888 0.320132 -0.705763 +v -0.118888 0.196360 -0.477813 +v 0.118888 0.182778 -0.262553 +v 0.118888 0.195216 -0.230619 +v 0.237776 0.099835 0.006126 +v 0.237776 0.049985 0.008619 +v 0.079707 0.459087 -6.420291 +v 0.065797 0.464849 -2.562043 +v 0.003189 0.490781 -2.562100 +v 0.111401 0.382569 -6.532399 +v 0.237776 -0.213381 0.061785 +v 0.237776 -0.308369 -0.159225 +v 0.118888 -0.441732 -0.353857 +v -0.118888 -0.425221 -0.126920 +v 0.118888 -0.425221 -0.126920 +v -0.118888 -0.335492 -0.503086 +v -0.237776 -0.256750 -0.401052 +v -0.237776 0.091880 -0.534544 +v -0.237776 0.203351 -0.739838 +v -0.076269 0.451988 -2.562015 +v -0.105024 0.382569 -2.561862 +v -0.105024 0.382569 -6.420290 +v -0.073329 0.306051 -6.532399 +v 0.003189 0.274357 -6.644507 +v 0.079707 0.306051 -6.644507 +v -0.118888 0.182778 -0.262552 +v 0.118888 0.195216 -0.230619 +v 0.118888 0.221196 -0.002196 +v 0.237776 -0.147745 1.702607 +v 0.237776 -0.446216 1.701369 +v 0.079707 0.459087 -6.532399 +v 0.003189 0.490781 -6.420291 +v -0.073329 0.459087 -2.562030 +v 0.111401 0.382569 -6.644507 +v 0.237776 -0.690056 1.687923 +v 0.237776 -0.330203 0.092074 +v 0.118888 -0.425221 -0.126920 +v 0.118888 -0.463287 0.100989 +v -0.118888 -0.463287 0.100989 +v -0.118888 -0.425221 -0.126920 +v -0.118888 -0.441732 -0.353856 +v -0.237776 -0.324646 -0.382932 +v -0.237776 0.023383 -0.301169 +v -0.237776 0.044646 -0.289624 +v -0.118888 0.196360 -0.477813 +v -0.073329 0.459087 -6.420291 +v -0.105024 0.382569 -6.532398 +v -0.073329 0.306051 -6.644507 +v 0.003189 0.274357 -6.714530 +v 0.079707 0.306051 -6.714530 +v -0.118888 0.182778 -0.262552 +v -0.118888 0.195216 -0.230618 +v 0.118888 0.221196 -0.002196 +v 0.118888 -0.027842 1.704281 +v 0.118888 -0.163897 1.821429 +v 0.118888 -0.485877 1.820093 +v 0.079707 0.459087 -6.644507 +v 0.026482 0.526673 -6.420291 +v 0.003189 0.526924 -6.420291 +v 0.111401 0.382569 -6.714530 +v 0.118888 -0.722553 1.803470 +v 0.237776 -0.993968 1.646306 +v 0.118888 -0.463287 0.100989 +v -0.118888 -1.117824 1.633614 +v 0.118888 -1.117824 1.633614 +v -0.237776 -0.308369 -0.159224 +v -0.237776 -0.190936 -0.189672 +v -0.237776 0.045778 -0.229243 +v -0.237776 0.067736 -0.230341 +v -0.073329 0.459087 -6.532399 +v -0.105024 0.382569 -6.644506 +v -0.073329 0.306051 -6.714530 +v -0.105024 0.382569 -6.714530 +v -0.073329 0.459087 -6.714530 +v 0.003189 0.490781 -6.714530 +v 0.079707 0.459087 -6.714530 +v -0.118888 0.195216 -0.230618 +v -0.118888 0.221196 -0.002195 +v 0.118888 -0.027842 1.704281 +v 0.118888 -0.163897 1.821429 +v 0.118888 -0.485877 1.820093 +v 0.026482 0.571301 -6.644507 +v 0.026482 0.571301 -6.532399 +v -0.020104 0.526673 -6.420291 +v 0.003189 0.571553 -6.532399 +v 0.118888 -1.046729 1.759079 +v 0.118888 -1.117824 1.633614 +v 0.118888 -1.046729 1.759079 +v -0.118888 -1.046729 1.759079 +v -0.118888 -0.463287 0.100989 +v -0.237776 -0.330203 0.092075 +v -0.237776 -0.213381 0.061786 +v -0.237776 0.049984 0.008620 +v -0.237776 0.099835 0.006127 +v -0.020104 0.571301 -6.532399 +v -0.073329 0.459087 -6.644507 +v 0.003189 0.490781 -6.644507 +v -0.118888 0.221196 -0.002195 +v -0.118888 -0.027842 1.704281 +v 0.118888 -0.722553 1.803470 +v -0.118888 -0.163897 1.821429 +v -0.118888 -0.485877 1.820094 +v 0.003189 0.571553 -6.644507 +v -0.118888 -0.722553 1.803470 +v -0.118888 -1.117824 1.633614 +v -0.118888 -1.046729 1.759079 +v -0.237776 -0.993969 1.646307 +v -0.237776 -0.690056 1.687923 +v -0.237776 -0.446216 1.701370 +v -0.237776 -0.147745 1.702609 +v -0.020104 0.571301 -6.644507 +v -0.118888 -0.485877 1.820094 +v -0.118888 -0.722553 1.803470 +v -0.118888 -0.163897 1.821429 +v -0.118888 -0.027842 1.704281 +v -0.105024 0.133109 -4.891191 +v -0.073329 0.056591 -4.891192 +v -0.073329 0.209627 -4.891192 +v -0.143131 0.133109 -4.891191 +v -0.100275 0.029645 -4.891192 +v 0.003189 0.024896 -4.891192 +v 0.003189 0.241321 -4.891192 +v -0.100275 0.236572 -4.891192 +v 0.003189 -0.013211 -4.891192 +v -0.143131 0.133109 -5.122173 +v -0.100275 0.029645 -5.122174 +v 0.079707 0.056591 -4.891192 +v 0.079707 0.209627 -4.891192 +v -0.100275 0.236572 -5.122174 +v 0.106653 0.029645 -4.891192 +v 0.003189 -0.013211 -5.122174 +v -0.104530 0.133109 -5.126012 +v -0.072980 0.056940 -5.126012 +v 0.111401 0.133109 -4.891192 +v 0.106653 0.236573 -4.891192 +v -0.072980 0.209277 -5.126012 +v 0.149509 0.133109 -4.891192 +v 0.106653 0.029645 -5.122174 +v 0.003189 0.025390 -5.126012 +v -0.104530 0.133109 -5.295255 +v -0.072980 0.056940 -5.295256 +v 0.106653 0.236573 -5.122174 +v 0.003189 0.240827 -5.126012 +v -0.072980 0.209277 -5.295256 +v 0.149509 0.133109 -5.122174 +v 0.079357 0.056940 -5.126012 +v 0.003189 0.025390 -5.295256 +v 0.003189 0.240827 -5.295256 +v 0.079357 0.209277 -5.295256 +v 0.110907 0.133109 -5.295256 +v 0.079357 0.056940 -5.295256 +v 0.079357 0.209277 -5.126012 +v 0.110907 0.133109 -5.126013 +v 0.003189 0.303203 -6.714530 +v 0.059309 0.326449 -6.714530 +v 0.082555 0.382569 -6.714530 +v -0.052931 0.326449 -6.714530 +v -0.076177 0.382569 -6.714530 +v -0.052931 0.438689 -6.714530 +v 0.003189 0.461935 -6.714530 +v 0.059309 0.438689 -6.714530 +v 0.003189 0.303233 -2.786079 +v 0.059309 0.326479 -2.786079 +v 0.082555 0.382599 -2.786079 +v -0.052931 0.326478 -2.786079 +v -0.076177 0.382599 -2.786079 +v -0.052931 0.438719 -2.786079 +v 0.003189 0.461965 -2.786079 +v 0.059309 0.438719 -2.786079 +v 0.207289 0.325888 -2.310173 +v 0.207289 0.325493 -1.886054 +v 0.207289 0.409709 -1.887695 +v 0.207289 0.409102 -2.310383 +v 0.176878 0.439513 -2.310461 +v 0.176878 0.440119 -1.888282 +v -0.017557 0.308944 -2.310156 +v -0.017558 0.308550 -1.886037 +v -0.017558 0.392765 -1.887678 +v -0.017557 0.392159 -2.310366 +v -0.047969 0.422570 -2.310443 +v -0.047969 0.423176 -1.888266 +v 0.094866 0.317021 -1.886046 +v 0.094866 0.401237 -1.887686 +v 0.064454 0.431647 -1.888274 +v 0.064455 0.431042 -2.310452 +v 0.094866 0.400630 -2.310374 +v 0.094866 0.317416 -2.310165 +vn 0.382700 -0.923900 -0.000000 +vn 0.923900 -0.382700 -0.000000 +vn 0.923900 0.382700 0.000000 +vn 0.382700 0.923900 0.000000 +vn -0.382700 0.923900 0.000000 +vn -0.923900 0.382700 0.000000 +vn 0.000000 0.000000 -1.000000 +vn -0.382700 -0.923900 -0.000000 +vn -0.923900 -0.382700 -0.000000 +vn -0.302000 -0.125100 -0.945100 +vn 0.125100 0.301900 -0.945100 +vn -0.301900 0.125100 -0.945100 +vn 0.301900 0.125100 -0.945100 +vn 0.125100 -0.301900 -0.945100 +vn -0.125100 -0.301900 -0.945100 +vn -0.125100 0.301900 -0.945100 +vn 0.301900 -0.125100 -0.945100 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -0.876300 -0.481800 +vn 0.000000 -0.675300 0.737600 +vn -0.000000 0.011600 0.999900 +vn -0.000000 -0.475400 -0.879700 +vn 0.000000 -0.796700 -0.604400 +vn 0.000000 -0.477700 0.878500 +vn 0.000000 0.299100 -0.954200 +vn -0.923900 -0.382400 -0.011900 +vn 0.923900 -0.382400 -0.011900 +vn -0.000000 0.192800 -0.981200 +vn -0.382000 -0.922300 -0.057600 +vn 0.382000 -0.922300 -0.057600 +vn 0.463300 -0.886200 -0.000000 +vn 0.000000 -0.842900 0.538100 +vn 0.000000 -0.819300 -0.573300 +vn 0.591700 -0.590800 0.548500 +vn 0.554000 -0.594300 -0.583000 +vn 0.765000 0.217500 0.606200 +vn 0.782800 0.083300 -0.616700 +vn 0.467500 0.754400 0.460900 +vn 0.505900 0.687600 -0.520900 +vn 0.000000 0.955200 0.295800 +vn 0.000000 0.909500 -0.415800 +vn -0.467500 0.754400 0.460900 +vn -0.505900 0.687600 -0.520900 +vn -0.765000 0.217500 0.606200 +vn -0.782800 0.083400 -0.616700 +vn -0.591700 -0.590800 0.548500 +vn -0.554000 -0.594300 -0.583000 +vn 0.000000 -0.999500 -0.031100 +vn 0.681700 -0.731300 -0.022600 +vn 0.999400 -0.035100 0.000000 +vn 0.707100 0.707100 0.000000 +vn -0.707100 0.707100 0.000000 +vn -0.999400 -0.035100 0.000000 +vn -0.681700 -0.731300 -0.022600 +vn 0.278300 -0.671800 0.686500 +vn 0.270600 -0.653300 -0.707100 +vn 0.000000 -1.000000 0.000000 +vn 0.694200 -0.718800 -0.036400 +vn 0.627300 -0.049800 0.777200 +vn 0.650600 -0.105100 -0.752100 +vn 0.999800 -0.019100 -0.009100 +vn 0.534000 0.473200 0.700700 +vn 0.583000 0.369600 -0.723600 +vn 0.315600 0.816900 0.482800 +vn 0.297700 0.758600 -0.579500 +vn -0.315600 0.816900 0.482800 +vn -0.297700 0.758600 -0.579500 +vn -0.534000 0.473200 0.700700 +vn -0.583000 0.369600 -0.723600 +vn -0.999800 -0.019100 -0.009100 +vn -0.627300 -0.049800 0.777200 +vn -0.650600 -0.105100 -0.752100 +vn -0.694200 -0.718900 -0.036400 +vn -0.278300 -0.671800 0.686500 +vn -0.270600 -0.653300 -0.707100 +vn -0.000000 -0.998100 -0.062300 +vn 0.681800 -0.731500 0.000000 +vn -0.681800 -0.731500 -0.000000 +vn -0.999900 0.011400 0.000000 +vn -0.382500 -0.923500 -0.028800 +vn 0.999900 0.011400 -0.000000 +vn 0.382500 -0.923500 -0.028800 +vn 0.000000 0.318300 0.948000 +vn 0.000000 0.011800 -0.999900 +vn 0.170000 0.082200 -0.982000 +vn 0.000000 -0.981700 -0.190200 +vn 0.303000 0.283800 -0.909700 +vn 0.713800 -0.686200 -0.139800 +vn 0.768000 -0.576000 -0.279800 +vn -0.000000 -0.981800 -0.189800 +vn 0.238300 0.510400 -0.826300 +vn 0.000000 -0.642300 0.766500 +vn 0.707100 -0.648300 -0.282200 +vn -0.000000 -0.916900 -0.399200 +vn 0.000000 -0.982000 -0.188700 +vn -0.000000 -0.408700 -0.912700 +vn 0.000000 -0.988200 -0.153000 +vn -0.000000 -0.015400 -0.999900 +vn 0.000000 0.699500 -0.714600 +vn 0.707600 0.636700 0.306300 +vn 0.000000 -0.444000 0.896000 +vn 0.680000 -0.475800 -0.557800 +vn 0.000000 -0.610100 -0.792300 +vn -0.000000 -0.652200 -0.758000 +vn 0.000000 -0.932100 -0.362300 +vn -0.000000 0.437300 -0.899300 +vn 0.000000 -0.999900 -0.014300 +vn 1.000000 -0.003200 0.000100 +vn -1.000000 -0.003200 0.000100 +vn -0.000000 0.646900 -0.762500 +vn 0.000000 0.925800 0.378000 +vn 0.707100 0.621400 0.337400 +vn 0.000000 -0.916900 0.399200 +vn -0.000000 -0.257800 -0.966200 +vn -0.713800 -0.686200 -0.139800 +vn -0.170000 0.082200 -0.982000 +vn -0.000000 0.911400 -0.411500 +vn 0.000000 -0.756800 0.653600 +vn 0.000000 -0.904300 -0.426800 +vn 0.507000 0.823800 -0.253500 +vn 0.000000 0.902900 0.429900 +vn 0.726700 0.681100 0.090000 +vn 0.000000 -0.993600 -0.112800 +vn 0.707100 -0.182300 -0.683200 +vn -0.108600 -0.274700 -0.955400 +vn -0.000000 -0.814600 -0.580000 +vn -0.940000 -0.097900 -0.326900 +vn -0.680000 -0.475800 -0.557800 +vn -0.707100 -0.648300 -0.282200 +vn -0.303000 0.283800 -0.909700 +vn -0.000000 0.993100 0.116900 +vn 0.000000 0.150000 0.988700 +vn 1.000000 0.002600 -0.001200 +vn -0.000000 -0.593100 -0.805100 +vn -1.000000 0.002600 -0.001200 +vn -0.907100 0.378000 0.185200 +vn 0.000000 0.878800 0.477200 +vn 0.707100 0.658900 -0.256600 +vn -0.000000 -0.907200 -0.420600 +vn 0.551100 -0.679800 -0.483900 +vn 0.000000 -0.997400 0.072600 +vn -0.238300 0.510400 -0.826300 +vn -0.000000 0.911300 0.411800 +vn -0.707600 0.636700 0.306300 +vn -0.990400 0.123800 0.061300 +vn -0.000000 0.998000 0.063000 +vn 0.000000 0.929100 -0.369800 +vn 0.721800 0.686800 -0.085800 +vn 0.707100 -0.705200 0.051300 +vn 0.388500 -0.777000 -0.495300 +vn 0.000000 -0.997300 0.074100 +vn 0.000000 -0.986300 -0.164700 +vn 0.000000 -0.997300 0.073200 +vn -0.704400 -0.587000 -0.399100 +vn -0.707100 -0.182300 -0.683200 +vn -0.707100 0.621400 0.337400 +vn 0.000000 0.997400 0.072200 +vn -0.000000 0.931800 -0.362900 +vn 0.000000 0.990500 -0.137300 +vn 0.707100 0.699700 0.102100 +vn 0.707100 -0.002900 0.707100 +vn 0.707900 -0.044100 0.704900 +vn 0.714600 -0.694100 -0.086800 +vn 0.000000 -0.988600 -0.150500 +vn 0.000000 -0.919600 -0.392800 +vn 0.000000 -0.986500 -0.163900 +vn -0.707100 -0.705200 0.051300 +vn -0.551100 -0.679800 -0.483900 +vn -0.726700 0.681100 0.090000 +vn -0.000000 0.993600 -0.113000 +vn 0.000000 0.989000 0.147800 +vn 0.555900 0.542400 0.629900 +vn 0.000000 -0.004300 1.000000 +vn 0.707100 -0.095900 0.700600 +vn 0.707100 -0.650300 -0.277700 +vn 0.000000 -0.911900 -0.410400 +vn 0.000000 -0.870000 0.493000 +vn 0.000000 -0.916500 -0.399900 +vn -0.714600 -0.694100 -0.086800 +vn -0.707100 0.658900 -0.256600 +vn 0.000000 0.994600 -0.103400 +vn -0.000000 0.989500 0.144400 +vn 0.000000 0.655400 0.755300 +vn 0.000000 -0.070200 0.997500 +vn 0.000000 -0.004100 1.000000 +vn 0.649300 -0.661700 0.374900 +vn 0.000000 -0.143100 0.989700 +vn 0.000000 -0.869200 0.494400 +vn 0.000000 -0.135700 0.990800 +vn -0.721800 0.686700 -0.085800 +vn 0.000000 0.989600 0.143800 +vn 0.000000 0.652500 0.757800 +vn 0.000000 -0.070100 0.997500 +vn 0.000000 -0.004200 1.000000 +vn 0.000000 -0.136400 0.990700 +vn -0.649300 -0.661700 0.374900 +vn -0.707100 -0.650300 -0.277700 +vn -0.707100 -0.095900 0.700600 +vn -0.707900 -0.044100 0.704900 +vn -0.707100 -0.002900 0.707100 +vn -0.707100 0.699700 0.102100 +vn 0.000000 0.657600 0.753400 +vn 0.000000 -0.073200 0.997300 +vn -0.555900 0.542400 0.629900 +vn 0.001300 -0.018000 -0.999800 +vn 0.001400 -0.019500 -0.999800 +vn 0.707100 0.707100 -0.001000 +vn -0.000100 0.002500 1.000000 +vn -0.075100 0.997200 0.000900 +vn 0.075100 -0.997200 0.001400 +vn 0.000000 -0.999600 0.029200 +vn 0.707100 -0.706800 0.020300 +vn 0.000000 -0.999600 0.028800 +vn 0.000000 -0.999900 0.014100 +vn 0.707100 -0.707000 0.009800 +vn 0.000000 -0.999900 0.013900 +vn 0.000000 -1.000000 -0.001100 +vn 0.707100 -0.707100 -0.000800 +vn 0.707100 0.653600 0.269700 +vn 0.000000 -0.002200 -1.000000 +vn 0.707100 0.707100 -0.000800 +vn 0.715100 0.682000 0.153100 +vn 0.000000 0.918900 0.394400 +vn 0.705400 0.708800 -0.001100 +vn 0.000000 0.924400 0.381400 +vn 0.000000 0.981200 0.193100 +vn -0.707100 -0.707100 -0.000800 +vn 0.000000 1.000000 -0.001600 +vn -0.000000 0.981100 0.193600 +vn -0.335300 0.860400 0.383800 +vn -0.707100 -0.707000 0.009800 +vn 0.000000 0.980100 0.198400 +vn -0.707100 -0.706800 0.020300 +vn -0.707100 0.707100 -0.001200 +vn 0.000000 1.000000 -0.001700 +vn -0.715100 0.682000 0.153100 +vn -0.707100 0.653600 0.269700 +vn 1.000000 0.000000 0.000100 +vn 0.707100 0.707100 -0.002300 +vn 1.000000 -0.000300 0.000000 +vn 1.000000 -0.000000 -0.000200 +vn 0.856100 0.506800 0.100900 +vn 0.903500 0.428500 0.000000 +vn 0.010000 0.929000 0.369800 +vn -0.856100 0.506800 0.100900 +vn 0.010800 0.999900 0.000000 +vn -0.010000 0.929000 0.369800 +vn -0.903500 0.428500 0.000000 +vn -0.010800 0.999900 0.000000 +vn -0.098900 -0.040900 -0.994300 +vn -0.098900 0.040900 -0.994300 +vn -0.041000 -0.098900 -0.994300 +vn -0.040900 0.098900 -0.994300 +vn 0.040900 -0.098900 -0.994300 +vn 0.040900 0.098900 -0.994300 +vn 0.098900 -0.041000 -0.994300 +vn 0.098900 0.041000 -0.994300 +usemtl BulletRed +s off +f 1//1 2//1 4//1 3//1 +f 3//2 4//2 6//2 5//2 +f 5//3 6//3 8//3 7//3 +f 7//4 8//4 10//4 9//4 +f 9//5 10//5 12//5 11//5 +f 11//6 12//6 14//6 13//6 +f 2//7 16//7 24//7 18//7 +f 15//8 16//8 2//8 1//8 +f 13//9 14//9 16//9 15//9 +f 24//3 23//3 31//3 32//3 +f 4//7 2//7 18//7 17//7 +f 8//7 6//7 19//7 20//7 +f 14//7 12//7 22//7 23//7 +f 10//7 8//7 20//7 21//7 +f 16//7 14//7 23//7 24//7 +f 6//7 4//7 17//7 19//7 +f 12//7 10//7 21//7 22//7 +f 25//7 26//7 32//7 31//7 30//7 29//7 28//7 27//7 +f 22//1 21//1 29//1 30//1 +f 20//9 19//9 27//9 28//9 +f 17//5 18//5 26//5 25//5 +f 18//4 24//4 32//4 26//4 +f 23//2 22//2 30//2 31//2 +f 21//8 20//8 28//8 29//8 +f 19//6 17//6 25//6 27//6 +usemtl BulletYellow +f 13//10 15//10 40//10 39//10 +f 7//11 9//11 37//11 36//11 +f 11//12 13//12 39//12 38//12 +f 5//13 7//13 36//13 35//13 +f 1//14 3//14 34//14 33//14 +f 15//15 1//15 33//15 40//15 +f 9//16 11//16 38//16 37//16 +f 3//17 5//17 35//17 34//17 +f 34//2 35//2 43//2 42//2 +f 42//18 43//18 51//18 50//18 +f 37//5 38//5 46//5 45//5 +f 40//8 33//8 41//8 48//8 +f 33//1 34//1 42//1 41//1 +f 35//3 36//3 44//3 43//3 +f 38//6 39//6 47//6 46//6 +f 36//4 37//4 45//4 44//4 +f 39//9 40//9 48//9 47//9 +f 49//18 50//18 51//18 52//18 53//18 54//18 55//18 56//18 +f 47//18 48//18 56//18 55//18 +f 45//18 46//18 54//18 53//18 +f 43//18 44//18 52//18 51//18 +f 41//18 42//18 50//18 49//18 +f 48//18 41//18 49//18 56//18 +f 46//18 47//18 55//18 54//18 +f 44//18 45//18 53//18 52//18 +usemtl Trigger +f 58//19 60//19 59//19 57//19 +f 60//7 64//7 63//7 59//7 +f 64//20 62//20 61//20 63//20 +f 62//18 58//18 57//18 61//18 +f 63//20 61//20 68//20 67//20 +f 62//21 64//21 60//21 58//21 +f 67//20 68//20 72//20 71//20 +f 57//19 59//19 65//19 66//19 +f 59//22 63//22 67//22 65//22 +f 61//23 57//23 66//23 68//23 +f 70//19 69//19 73//19 74//19 +f 66//19 65//19 69//19 70//19 +f 68//24 66//24 70//24 72//24 +f 65//25 67//25 71//25 69//25 +f 74//26 73//26 75//26 76//26 +f 72//27 70//27 74//27 76//27 +f 69//28 71//28 75//28 73//28 +f 71//20 72//20 76//20 75//20 +usemtl Black +f 156//8 124//8 82//8 128//8 +f 91//3 136//3 137//3 96//3 +f 97//4 140//4 141//4 102//4 +f 103//5 144//5 145//5 108//5 +f 109//6 148//6 149//6 114//6 +f 115//29 152//29 154//29 120//29 +f 85//30 132//30 133//30 90//30 +f 87//31 80//31 123//31 117//31 111//31 105//31 99//31 93//31 +f 121//32 153//32 127//32 79//32 +f 151//20 118//20 122//20 155//20 +f 77//33 126//33 129//33 84//33 +f 147//6 112//6 116//6 150//6 +f 143//5 106//5 110//5 146//5 +f 139//4 100//4 104//4 142//4 +f 135//3 94//3 98//3 138//3 +f 131//34 88//34 92//34 134//34 +f 125//1 81//1 86//1 130//1 +f 77//35 78//35 79//35 +f 80//36 81//36 82//36 +f 83//37 84//37 85//37 +f 86//38 87//38 88//38 +f 89//39 90//39 91//39 +f 92//40 93//40 94//40 +f 95//41 96//41 97//41 +f 98//42 99//42 100//42 +f 101//43 102//43 103//43 +f 104//44 105//44 106//44 +f 107//45 108//45 109//45 +f 110//46 111//46 112//46 +f 113//47 114//47 115//47 +f 116//48 117//48 118//48 +f 119//49 120//49 121//49 +f 122//50 123//50 124//50 +f 125//51 126//51 127//51 128//51 +f 129//52 130//52 131//52 132//52 +f 133//53 134//53 135//53 136//53 +f 137//54 138//54 139//54 140//54 +f 141//21 142//21 143//21 144//21 +f 145//55 146//55 147//55 148//55 +f 149//56 150//56 151//56 152//56 +f 153//57 154//57 155//57 156//57 +f 77//58 84//58 83//58 78//58 +f 86//59 81//59 80//59 87//59 +f 128//60 82//60 81//60 125//60 +f 132//61 85//61 84//61 129//61 +f 85//62 90//62 89//62 83//62 +f 92//63 88//63 87//63 93//63 +f 136//64 91//64 90//64 133//64 +f 91//65 96//65 95//65 89//65 +f 98//66 94//66 93//66 99//66 +f 140//54 97//54 96//54 137//54 +f 97//67 102//67 101//67 95//67 +f 104//68 100//68 99//68 105//68 +f 144//21 103//21 102//21 141//21 +f 103//69 108//69 107//69 101//69 +f 110//70 106//70 105//70 111//70 +f 148//55 109//55 108//55 145//55 +f 109//71 114//71 113//71 107//71 +f 116//72 112//72 111//72 117//72 +f 152//73 115//73 114//73 149//73 +f 115//74 120//74 119//74 113//74 +f 122//75 118//75 117//75 123//75 +f 153//76 121//76 120//76 154//76 +f 121//77 79//77 78//77 119//77 +f 82//78 124//78 123//78 80//78 +f 79//79 127//79 126//79 77//79 +f 88//80 131//80 130//80 86//80 +f 94//53 135//53 134//53 92//53 +f 100//54 139//54 138//54 98//54 +f 106//21 143//21 142//21 104//21 +f 112//55 147//55 146//55 110//55 +f 118//56 151//56 150//56 116//56 +f 124//81 156//81 155//81 122//81 +f 151//82 155//82 154//82 152//82 +f 156//83 128//83 127//83 153//83 +f 147//6 150//6 149//6 148//6 +f 143//5 146//5 145//5 144//5 +f 139//4 142//4 141//4 140//4 +f 135//3 138//3 137//3 136//3 +f 131//84 134//84 133//84 132//84 +f 125//85 130//85 129//85 126//85 +f 78//86 83//86 89//86 95//86 101//86 107//86 113//86 119//86 +f 158//87 157//87 163//87 164//87 +f 157//88 162//88 169//88 163//88 +f 187//87 173//87 176//87 166//87 158//87 164//87 190//87 244//87 267//87 245//87 +f 174//89 175//89 164//89 163//89 +f 176//20 177//20 178//20 165//20 166//20 +f 162//90 171//90 181//90 169//90 +f 169//91 182//91 174//91 163//91 +f 174//92 188//92 213//92 175//92 +f 164//93 175//93 189//93 190//93 +f 173//20 191//20 192//20 177//20 176//20 +f 178//20 177//20 193//20 194//20 195//20 +f 171//94 186//94 206//94 181//94 +f 169//20 181//20 207//20 182//20 +f 187//95 211//95 191//95 173//95 +f 182//96 212//96 188//96 174//96 +f 214//97 189//97 175//97 213//97 +f 190//98 189//98 252//98 215//98 +f 192//20 191//20 216//20 217//20 +f 218//99 177//99 192//99 219//99 +f 177//100 218//100 220//100 193//100 +f 194//20 193//20 221//20 198//20 +f 198//20 221//20 225//20 199//20 +f 199//20 225//20 226//20 200//20 +f 200//101 226//101 227//101 201//101 +f 201//19 227//19 228//19 202//19 +f 202//19 228//19 229//19 203//19 +f 203//19 229//19 220//19 204//19 +f 218//19 222//19 205//19 204//19 220//19 +f 186//102 209//102 235//102 206//102 +f 206//103 236//103 207//103 181//103 +f 237//20 212//20 182//20 207//20 +f 245//19 218//19 219//19 211//19 187//19 +f 191//104 211//104 246//104 216//104 +f 212//105 247//105 248//105 188//105 +f 188//106 248//106 250//106 213//106 +f 249//107 214//107 213//107 250//107 +f 214//108 251//108 252//108 189//108 +f 253//87 244//87 190//87 215//87 +f 219//109 192//109 217//109 254//109 +f 217//20 216//20 255//20 256//20 +f 193//110 220//110 229//110 221//110 +f 221//111 265//111 296//111 225//111 +f 225//110 228//110 227//110 226//110 +f 228//112 266//112 290//112 229//112 +f 222//19 218//19 245//19 267//19 268//19 +f 209//113 242//113 271//113 235//113 +f 206//114 235//114 272//114 236//114 +f 237//115 207//115 236//115 273//115 +f 212//20 237//20 274//20 275//20 +f 211//19 219//19 254//19 246//19 +f 216//116 246//116 280//116 255//116 +f 275//20 247//20 212//20 +f 281//117 249//117 250//117 282//117 +f 251//106 214//106 249//106 283//106 +f 252//118 284//118 286//118 215//118 +f 285//119 253//119 215//119 286//119 +f 254//120 217//120 256//120 287//120 +f 256//20 255//20 288//20 289//20 +f 290//121 265//121 221//121 229//121 +f 296//122 266//122 228//122 225//122 +f 271//123 242//123 314//123 303//123 +f 235//124 271//124 304//124 272//124 +f 305//18 273//18 236//18 272//18 +f 274//125 237//125 273//125 306//125 +f 307//20 308//20 275//20 274//20 +f 246//19 254//19 287//19 280//19 +f 255//126 280//126 315//126 288//126 +f 275//20 308//20 316//20 247//20 +f 317//127 248//127 247//127 318//127 +f 250//128 248//128 317//128 282//128 +f 319//129 320//129 281//129 282//129 +f 249//130 281//130 353//130 283//130 +f 251//131 283//131 354//131 321//131 +f 252//132 251//132 321//132 284//132 +f 322//133 285//133 286//133 323//133 +f 287//134 256//134 289//134 324//134 +f 289//20 288//20 325//20 326//20 +f 327//135 326//135 265//135 290//135 +f 265//136 326//136 325//136 296//136 +f 325//137 332//137 266//137 296//137 +f 266//138 332//138 327//138 290//138 +f 303//139 338//139 304//139 271//139 +f 304//140 339//140 305//140 272//140 +f 305//18 340//18 306//18 273//18 +f 306//141 341//141 307//141 274//141 +f 308//20 307//20 342//20 343//20 +f 280//19 287//19 324//19 315//19 +f 288//142 315//142 332//142 325//142 +f 343//20 348//20 316//20 308//20 +f 316//20 349//20 318//20 247//20 +f 318//143 350//143 317//143 +f 351//144 320//144 319//144 352//144 +f 355//19 356//19 284//19 321//19 +f 284//19 356//19 323//19 286//19 +f 314//145 322//145 323//145 303//145 +f 324//146 289//146 326//146 327//146 +f 303//147 323//147 356//147 338//147 +f 304//148 338//148 382//148 339//148 +f 363//149 340//149 305//149 339//149 +f 341//150 306//150 340//150 364//150 +f 341//151 365//151 342//151 307//151 +f 343//20 342//20 366//20 367//20 +f 315//19 324//19 327//19 332//19 +f 343//20 367//20 372//20 348//20 +f 349//20 316//20 348//20 373//20 +f 374//152 350//152 318//152 349//152 +f 317//153 350//153 319//153 282//153 +f 374//154 352//154 319//154 350//154 +f 352//155 375//155 376//155 351//155 +f 377//156 378//156 320//156 351//156 +f 378//157 353//157 281//157 320//157 +f 379//158 354//158 283//158 353//158 +f 354//19 380//19 321//19 +f 380//19 381//19 355//19 321//19 +f 382//159 338//159 356//159 355//159 +f 363//160 339//160 382//160 388//160 +f 363//161 389//161 364//161 340//161 +f 364//162 390//162 365//162 341//162 +f 365//163 391//163 366//163 342//163 +f 367//164 366//164 392//164 393//164 +f 372//165 367//165 393//165 398//165 +f 373//20 348//20 372//20 399//20 +f 349//166 373//166 400//166 374//166 +f 400//167 375//167 352//167 374//167 +f 401//168 376//168 375//168 402//168 +f 351//169 376//169 427//169 377//169 +f 403//170 379//170 378//170 377//170 +f 379//171 353//171 378//171 +f 404//19 354//19 379//19 403//19 +f 354//19 404//19 405//19 380//19 +f 406//19 381//19 380//19 405//19 +f 381//172 388//172 382//172 355//172 +f 389//150 363//150 388//150 414//150 +f 390//173 364//173 389//173 415//173 +f 365//174 390//174 416//174 391//174 +f 392//175 366//175 391//175 +f 393//176 392//176 417//176 418//176 +f 399//177 372//177 398//177 423//177 +f 373//178 399//178 424//178 400//178 +f 400//179 424//179 402//179 375//179 +f 402//180 425//180 426//180 401//180 +f 376//181 401//181 442//181 427//181 +f 403//182 377//182 427//182 428//182 +f 428//19 429//19 404//19 403//19 +f 430//19 405//19 404//19 429//19 +f 430//19 431//19 406//19 405//19 +f 381//183 406//183 414//183 388//183 +f 414//184 435//184 415//184 389//184 +f 415//185 436//185 416//185 390//185 +f 391//186 416//186 417//186 392//186 +f 398//187 393//187 418//187 437//187 +f 438//188 439//188 418//188 417//188 +f 399//189 423//189 424//189 +f 398//190 437//190 425//190 423//190 +f 423//191 425//191 402//191 424//191 +f 441//192 426//192 425//192 437//192 +f 442//191 401//191 426//191 443//191 +f 428//19 444//19 445//19 429//19 +f 429//19 445//19 446//19 430//19 +f 430//19 446//19 447//19 431//19 +f 414//193 406//193 431//193 435//193 +f 415//194 435//194 452//194 436//194 +f 417//195 416//195 436//195 438//195 +f 441//196 437//196 418//196 439//196 +f 439//197 438//197 451//197 449//197 +f 426//198 441//198 450//198 443//198 +f 444//199 442//199 443//199 +f 427//200 442//200 444//200 428//200 +f 443//201 450//201 445//201 444//201 +f 445//202 450//202 449//202 446//202 +f 449//203 451//203 447//203 446//203 +f 431//204 447//204 452//204 435//204 +f 438//205 436//205 452//205 451//205 +f 441//206 439//206 449//206 450//206 +f 451//207 452//207 447//207 +f 521//208 520//208 515//208 518//208 +f 520//209 519//209 514//209 515//209 +f 515//20 514//20 513//20 516//20 +f 515//210 516//210 517//210 518//210 +f 523//211 522//211 517//211 516//211 +f 524//211 523//211 516//211 513//211 +f 519//212 524//212 513//212 514//212 +f 522//213 521//213 518//213 517//213 +usemtl DarkMetal +f 157//214 158//214 159//214 160//214 +f 157//215 160//215 161//215 162//215 +f 165//216 159//216 158//216 166//216 +f 160//217 159//217 167//217 168//217 +f 160//218 168//218 170//218 161//218 +f 171//20 162//20 161//20 172//20 +f 165//219 178//219 195//219 167//219 159//219 +f 168//220 167//220 179//220 180//220 +f 183//221 170//221 168//221 180//221 +f 170//20 184//20 172//20 161//20 +f 185//222 186//222 171//222 172//222 +f 196//220 197//220 179//220 167//220 195//220 194//220 198//220 199//220 200//220 201//220 202//220 203//220 204//220 205//220 +f 234//223 230//223 240//223 276//223 309//223 345//223 238//223 208//223 183//223 180//223 179//223 231//223 232//223 233//223 +f 239//224 184//224 509//224 512//224 +f 172//225 184//225 239//225 185//225 +f 209//226 186//226 185//226 210//226 +f 205//219 222//219 268//219 257//219 196//219 +f 197//220 196//220 223//220 224//220 +f 197//223 224//223 261//223 262//223 263//223 264//223 231//223 179//223 +f 238//227 239//227 512//227 511//227 +f 241//228 242//228 209//228 210//228 +f 239//229 243//229 210//229 185//229 +f 223//217 196//217 257//217 258//217 +f 224//230 223//230 259//230 260//230 +f 269//223 230//223 234//223 270//223 +f 243//231 239//231 238//231 277//231 +f 243//232 278//232 241//232 210//232 +f 241//233 279//233 314//233 242//233 +f 253//214 258//214 257//214 244//214 +f 258//234 291//234 259//234 223//234 +f 224//223 260//223 329//223 230//223 269//223 292//223 293//223 261//223 +f 294//19 295//19 260//19 259//19 +f 244//216 257//216 268//216 267//216 +f 310//231 278//231 243//231 277//231 +f 346//223 370//223 357//223 295//223 330//223 310//223 277//223 238//223 311//223 +f 279//235 241//235 278//235 313//235 +f 285//236 291//236 258//236 253//236 +f 291//19 328//19 294//19 259//19 +f 313//237 330//237 295//237 294//237 +f 278//238 310//238 330//238 313//238 +f 238//223 345//223 311//223 +f 313//239 294//239 328//239 279//239 +f 328//240 322//240 314//240 279//240 +f 322//19 328//19 291//19 285//19 +f 329//223 260//223 295//223 357//223 358//223 331//223 +f 184//241 170//241 508//241 509//241 +f 208//242 238//242 511//242 510//242 +f 170//243 183//243 507//243 508//243 +f 183//244 208//244 510//244 507//244 +f 511//213 512//213 521//213 522//213 +f 508//212 507//212 524//212 519//212 +f 507//211 510//211 523//211 524//211 +f 510//211 511//211 522//211 523//211 +f 509//209 508//209 519//209 520//209 +f 512//208 509//208 520//208 521//208 +usemtl Barrels +f 230//1 297//1 298//1 299//1 300//1 301//1 302//1 240//1 +f 240//2 302//2 312//2 276//2 +f 331//8 333//8 301//8 300//8 334//8 335//8 297//8 230//8 329//8 +f 301//1 336//1 337//1 302//1 +f 276//3 312//3 344//3 309//3 +f 302//2 337//2 347//2 312//2 +f 358//9 359//9 333//9 331//9 +f 333//8 360//8 336//8 301//8 +f 336//1 361//1 362//1 337//1 +f 312//3 347//3 368//3 344//3 +f 309//4 344//4 369//4 346//4 311//4 345//4 +f 337//2 362//2 371//2 347//2 +f 370//6 383//6 359//6 358//6 357//6 +f 359//9 384//9 360//9 333//9 +f 360//8 385//8 361//8 336//8 +f 361//1 386//1 387//1 362//1 +f 347//3 371//3 394//3 368//3 +f 344//245 368//245 420//245 395//245 +f 369//18 344//18 395//18 396//18 +f 346//5 369//5 383//5 370//5 +f 362//2 387//2 397//2 371//2 +f 383//6 407//6 384//6 359//6 +f 384//9 408//9 385//9 360//9 +f 385//8 409//8 386//8 361//8 +f 411//7 412//7 497//7 496//7 +f 371//3 397//3 413//3 394//3 +f 368//246 394//246 419//246 420//246 +f 383//18 369//18 396//18 421//18 +f 395//247 420//247 422//247 396//247 +f 407//248 383//248 421//248 432//248 +f 407//6 433//6 408//6 384//6 +f 408//9 410//9 409//9 385//9 +f 433//6 411//6 410//6 408//6 +f 434//5 412//5 411//5 433//5 +f 394//4 413//4 412//4 434//4 +f 394//7 434//7 440//7 419//7 +f 420//249 419//249 440//249 422//249 +f 396//250 422//250 432//250 421//250 +f 433//251 407//251 432//251 448//251 +f 434//7 433//7 448//7 440//7 +f 422//252 440//252 448//252 432//252 +f 293//9 453//9 454//9 262//9 261//9 +f 292//6 455//6 453//6 293//6 +f 454//18 453//18 456//18 457//18 +f 262//8 454//8 458//8 263//8 +f 270//5 459//5 455//5 292//5 269//5 +f 453//18 455//18 460//18 456//18 +f 458//18 454//18 457//18 461//18 +f 457//9 456//9 462//9 463//9 +f 263//1 458//1 464//1 264//1 +f 233//4 465//4 459//4 270//4 234//4 +f 335//18 460//18 455//18 459//18 297//18 +f 456//6 460//6 466//6 462//6 +f 464//18 458//18 461//18 467//18 +f 461//8 457//8 463//8 468//8 +f 463//253 462//253 469//253 470//253 +f 264//2 464//2 471//2 232//2 231//2 +f 232//3 471//3 465//3 233//3 +f 297//18 459//18 465//18 472//18 298//18 +f 334//5 466//5 460//5 335//5 +f 462//254 466//254 473//254 469//254 +f 471//18 464//18 467//18 474//18 +f 467//1 461//1 468//1 475//1 +f 468//255 463//255 470//255 476//255 +f 470//9 469//9 477//9 478//9 +f 465//18 471//18 474//18 472//18 +f 298//4 472//4 479//4 299//4 +f 300//256 480//256 473//256 466//256 334//256 +f 469//6 473//6 481//6 477//6 +f 474//2 467//2 475//2 482//2 +f 475//257 468//257 476//257 483//257 +f 476//8 470//8 478//8 484//8 +f 484//7 478//7 477//7 481//7 485//7 486//7 487//7 488//7 +f 472//3 474//3 482//3 479//3 +f 299//258 479//258 489//258 480//258 300//258 +f 473//5 480//5 485//5 481//5 +f 482//259 475//259 483//259 490//259 +f 483//1 476//1 484//1 488//1 +f 480//4 489//4 486//4 485//4 +f 489//3 490//3 487//3 486//3 +f 490//2 483//2 488//2 487//2 +f 479//260 482//260 490//260 489//260 +f 493//6 492//6 500//6 501//6 +f 409//7 410//7 495//7 494//7 +f 387//7 386//7 491//7 492//7 +f 412//7 413//7 498//7 497//7 +f 410//7 411//7 496//7 495//7 +f 386//7 409//7 494//7 491//7 +f 413//7 397//7 493//7 498//7 +f 397//7 387//7 492//7 493//7 +f 500//7 499//7 502//7 503//7 504//7 505//7 506//7 501//7 +f 497//8 498//8 506//8 505//8 +f 495//2 496//2 504//2 503//2 +f 491//4 494//4 502//4 499//4 +f 492//5 491//5 499//5 500//5 +f 498//9 493//9 501//9 506//9 +f 496//1 497//1 505//1 504//1 +f 494//3 495//3 503//3 502//3 diff --git a/assets/quaternius/models/Shotgun.obj.import b/assets/quaternius/models/Shotgun.obj.import new file mode 100644 index 0000000..3202a73 --- /dev/null +++ b/assets/quaternius/models/Shotgun.obj.import @@ -0,0 +1,25 @@ +[remap] + +importer="wavefront_obj" +importer_version=1 +type="Mesh" +uid="uid://cf5at01ffsvs8" +path="res://.godot/imported/Shotgun.obj-9a9f670f1bcd4077708d4393434307ac.mesh" + +[deps] + +files=["res://.godot/imported/Shotgun.obj-9a9f670f1bcd4077708d4393434307ac.mesh"] + +source_file="res://assets/quaternius/models/Shotgun.obj" +dest_files=["res://.godot/imported/Shotgun.obj-9a9f670f1bcd4077708d4393434307ac.mesh", "res://.godot/imported/Shotgun.obj-9a9f670f1bcd4077708d4393434307ac.mesh"] + +[params] + +generate_tangents=true +generate_lods=true +generate_shadow_mesh=true +generate_lightmap_uv2=false +generate_lightmap_uv2_texel_size=0.2 +scale_mesh=Vector3(1, 1, 1) +offset_mesh=Vector3(0, 0, 0) +force_disable_mesh_compression=false diff --git a/assets/quaternius/models/SniperRifle.glb b/assets/quaternius/models/SniperRifle.glb new file mode 100644 index 0000000..417be32 Binary files /dev/null and b/assets/quaternius/models/SniperRifle.glb differ diff --git a/assets/quaternius/models/SniperRifle.glb.import b/assets/quaternius/models/SniperRifle.glb.import new file mode 100644 index 0000000..0f8c9fc --- /dev/null +++ b/assets/quaternius/models/SniperRifle.glb.import @@ -0,0 +1,45 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://d184porf2jvc8" +path="res://.godot/imported/SniperRifle.glb-6dc460dffa4334d5e53eb36b77857af1.scn" + +[deps] + +source_file="res://assets/quaternius/models/SniperRifle.glb" +dest_files=["res://.godot/imported/SniperRifle.glb-6dc460dffa4334d5e53eb36b77857af1.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/assets/quaternius/models/SniperRifle.mtl b/assets/quaternius/models/SniperRifle.mtl new file mode 100644 index 0000000..c9a4641 --- /dev/null +++ b/assets/quaternius/models/SniperRifle.mtl @@ -0,0 +1,82 @@ +# Blender MTL File: 'SniperRifle.blend' +# Material Count: 8 + +newmtl Barrel +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Black +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl BulletOrange +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl BulletYellow +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Green +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Magazine +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Metal +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 + +newmtl Trigger +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 diff --git a/assets/quaternius/models/SniperRifle.obj b/assets/quaternius/models/SniperRifle.obj new file mode 100644 index 0000000..06b7722 --- /dev/null +++ b/assets/quaternius/models/SniperRifle.obj @@ -0,0 +1,2165 @@ +# Blender v2.76 (sub 0) OBJ File: 'SniperRifle.blend' +# www.blender.org +mtllib SniperRifle.mtl +o Rifle.001 +v 0.031110 0.500903 2.866135 +v 0.031110 0.500902 2.311447 +v 0.120601 0.529980 2.866135 +v 0.120601 0.529980 2.311448 +v 0.175909 0.606106 2.866135 +v 0.175909 0.606105 2.311448 +v 0.175909 0.700202 2.866135 +v 0.175909 0.700202 2.311448 +v 0.120601 0.776328 2.866135 +v 0.120601 0.776328 2.311447 +v 0.031110 0.805405 2.866135 +v 0.031110 0.805405 2.311447 +v -0.058381 0.776328 2.866135 +v -0.058381 0.776328 2.311447 +v -0.113690 0.700202 2.866135 +v -0.113690 0.700202 2.311448 +v -0.113690 0.606106 2.866135 +v -0.113690 0.606105 2.311448 +v -0.058381 0.529980 2.866135 +v -0.058381 0.529980 2.311448 +v 0.093313 0.567538 2.092278 +v 0.031110 0.547328 2.092278 +v 0.131756 0.620452 2.092278 +v 0.131756 0.685856 2.092278 +v 0.093313 0.738769 2.092278 +v 0.031110 0.758980 2.092278 +v -0.031093 0.738769 2.092278 +v -0.069537 0.685856 2.092278 +v -0.069537 0.620452 2.092278 +v -0.031093 0.567538 2.092278 +v 0.093313 0.567538 1.091870 +v 0.031110 0.547327 1.091870 +v 0.131756 0.620452 1.091870 +v 0.131756 0.685856 1.091870 +v 0.093313 0.738769 1.091870 +v 0.031110 0.758980 1.091870 +v -0.031093 0.738769 1.091870 +v -0.069537 0.685856 1.091870 +v -0.069537 0.620452 1.091870 +v -0.031093 0.567538 1.091870 +v 0.162519 0.472284 0.620250 +v 0.031110 0.429587 0.620250 +v 0.243735 0.584068 0.620250 +v 0.243735 0.722240 0.620250 +v 0.162519 0.834023 0.620250 +v 0.031110 0.876721 0.620250 +v -0.100300 0.834023 0.620250 +v -0.181515 0.722240 0.620250 +v -0.181515 0.584068 0.620250 +v -0.100300 0.472284 0.620250 +v 0.162519 0.472284 0.337992 +v 0.031110 0.429587 0.337992 +v 0.243735 0.584068 0.337992 +v 0.243735 0.722240 0.337992 +v 0.162519 0.834023 0.337992 +v 0.031110 0.876721 0.337992 +v -0.100300 0.834023 0.337992 +v -0.181515 0.722240 0.337992 +v -0.181515 0.584068 0.337992 +v -0.100300 0.472284 0.337992 +v 0.031110 0.547328 1.783510 +v 0.093313 0.567539 1.783510 +v -0.069537 0.685856 1.783510 +v -0.069537 0.620452 1.783510 +v 0.093313 0.738769 1.783510 +v 0.031110 0.758980 1.783510 +v 0.131756 0.620452 1.783510 +v -0.031093 0.567538 1.783510 +v -0.031093 0.738769 1.783510 +v 0.131756 0.685856 1.783510 +v 0.031110 0.547328 1.476900 +v -0.069537 0.685856 1.476900 +v 0.093313 0.738769 1.476900 +v 0.093313 0.567539 1.476900 +v -0.069537 0.620452 1.476900 +v 0.031110 0.758980 1.476900 +v 0.131756 0.620452 1.476900 +v -0.031093 0.567538 1.476900 +v -0.031093 0.738769 1.476900 +v 0.131756 0.685856 1.476900 +v 0.116593 0.535497 1.479551 +v 0.116593 0.535497 1.780859 +v -0.107204 0.608213 1.479551 +v -0.107204 0.608213 1.780859 +v 0.031110 0.798586 1.479551 +v 0.031110 0.798586 1.780859 +v 0.169424 0.608213 1.479551 +v 0.169424 0.608213 1.780859 +v -0.054373 0.535497 1.479551 +v -0.054373 0.535497 1.780859 +v -0.054373 0.770811 1.479551 +v -0.054373 0.770811 1.780859 +v 0.169424 0.698095 1.479551 +v 0.169424 0.698095 1.780859 +v 0.116593 0.770811 1.780859 +v -0.107204 0.698095 1.780859 +v 0.031110 0.507722 1.780859 +v 0.031110 0.507722 1.479551 +v -0.107204 0.698095 1.479551 +v 0.116593 0.770811 1.479551 +v 0.093313 0.567539 2.027274 +v -0.069537 0.620452 2.027274 +v 0.031110 0.758980 2.027274 +v 0.131756 0.620452 2.027274 +v -0.031093 0.567538 2.027274 +v -0.031093 0.738769 2.027274 +v 0.131756 0.685856 2.027274 +v 0.031110 0.547328 2.027274 +v -0.069537 0.685856 2.027274 +v 0.093313 0.738769 2.027274 +v 0.031110 0.547328 1.891850 +v -0.069537 0.685856 1.891850 +v 0.093313 0.738769 1.891850 +v 0.093313 0.567538 1.891850 +v -0.069537 0.620452 1.891850 +v 0.031110 0.758980 1.891850 +v 0.131756 0.620452 1.891850 +v -0.031093 0.567538 1.891850 +v -0.031093 0.738769 1.891850 +v 0.131756 0.685856 1.891850 +v 0.031110 0.547328 1.375294 +v -0.069537 0.685856 1.375295 +v 0.093313 0.738769 1.375295 +v 0.093313 0.567538 1.375294 +v -0.069537 0.620452 1.375294 +v 0.031110 0.758980 1.375295 +v 0.131756 0.620452 1.375294 +v -0.031093 0.567538 1.375294 +v -0.031093 0.738769 1.375295 +v 0.131756 0.685856 1.375295 +v 0.031110 0.547328 1.233582 +v -0.069537 0.685856 1.233582 +v 0.093313 0.738769 1.233582 +v 0.093313 0.567538 1.233582 +v -0.069537 0.620452 1.233582 +v 0.031110 0.758980 1.233582 +v 0.131756 0.620452 1.233582 +v -0.031093 0.567538 1.233582 +v -0.031093 0.738769 1.233582 +v 0.131756 0.685856 1.233582 +v 0.108679 0.546388 1.231581 +v 0.108679 0.546388 1.377296 +v -0.094400 0.612373 1.231581 +v -0.094400 0.612373 1.377296 +v 0.031110 0.785123 1.231581 +v 0.031110 0.785123 1.377296 +v 0.156620 0.612373 1.231581 +v 0.156620 0.612373 1.377296 +v -0.046460 0.546388 1.231581 +v -0.046460 0.546388 1.377296 +v -0.046460 0.759919 1.231581 +v -0.046460 0.759919 1.377296 +v 0.156620 0.693934 1.231581 +v 0.156620 0.693934 1.377296 +v 0.108679 0.759919 1.377296 +v -0.094400 0.693934 1.377296 +v 0.031110 0.521185 1.377296 +v 0.031110 0.521185 1.231581 +v -0.094400 0.693934 1.231581 +v 0.108679 0.759919 1.231581 +v 0.108679 0.360466 1.231581 +v 0.108679 0.360466 1.377296 +v -0.046460 0.360466 1.231581 +v -0.046460 0.360466 1.377296 +v 0.031110 0.335262 1.377296 +v 0.031110 0.335262 1.231581 +v 0.107710 0.547722 1.891829 +v 0.107710 0.547722 2.027295 +v -0.092833 0.612882 1.891829 +v -0.092833 0.612882 2.027295 +v 0.031110 0.783475 1.891829 +v 0.031110 0.783475 2.027295 +v 0.155052 0.612882 1.891829 +v 0.155052 0.612882 2.027295 +v -0.045491 0.547722 1.891829 +v -0.045491 0.547722 2.027295 +v -0.045491 0.758586 1.891829 +v -0.045491 0.758585 2.027295 +v 0.155052 0.693425 1.891829 +v 0.155052 0.693425 2.027295 +v 0.031110 0.522833 2.027295 +v -0.092833 0.693425 2.027295 +v 0.107710 0.758585 2.027295 +v 0.031110 0.522833 1.891829 +v -0.092833 0.693425 1.891829 +v 0.107710 0.758586 1.891829 +v 0.107710 0.348362 1.891829 +v 0.107710 0.348362 2.027295 +v -0.045491 0.348362 1.891829 +v -0.045491 0.348362 2.027295 +v 0.031110 0.323473 2.027295 +v 0.031110 0.323473 1.891829 +v 0.138453 0.505409 0.337992 +v 0.031110 0.470531 0.337992 +v 0.204794 0.596720 0.337992 +v 0.204794 0.709587 0.337992 +v 0.138453 0.800899 0.337992 +v 0.031110 0.835776 0.337992 +v -0.076233 0.800898 0.337992 +v -0.142575 0.709587 0.337992 +v -0.142575 0.596720 0.337992 +v -0.076233 0.505409 0.337992 +v 0.138453 0.505409 0.375788 +v 0.031110 0.470531 0.375788 +v 0.204794 0.596720 0.375788 +v 0.204794 0.709587 0.375788 +v 0.138453 0.800899 0.375788 +v 0.031110 0.835776 0.375789 +v -0.076233 0.800899 0.375788 +v -0.142575 0.709587 0.375788 +v -0.142575 0.596720 0.375788 +v -0.076233 0.505409 0.375788 +v 0.031110 0.534987 2.866135 +v 0.100566 0.557555 2.866135 +v 0.143493 0.616638 2.866135 +v 0.143493 0.689669 2.866135 +v 0.100566 0.748753 2.866135 +v 0.031110 0.771320 2.866135 +v -0.038347 0.748753 2.866135 +v -0.081273 0.689669 2.866135 +v -0.081273 0.616638 2.866135 +v -0.038347 0.557555 2.866135 +v 0.031110 0.534987 2.830771 +v 0.100566 0.557555 2.830771 +v 0.143493 0.616638 2.830771 +v 0.143493 0.689669 2.830771 +v 0.100566 0.748753 2.830771 +v 0.031110 0.771320 2.830771 +v -0.038347 0.748753 2.830771 +v -0.081273 0.689669 2.830771 +v -0.081273 0.616638 2.830771 +v -0.038347 0.557555 2.830771 +v 0.031110 0.500903 2.693805 +v 0.120601 0.529980 2.693805 +v 0.175909 0.606106 2.693805 +v 0.175909 0.700202 2.693805 +v 0.120601 0.776328 2.693805 +v 0.031110 0.805405 2.693805 +v -0.058381 0.776328 2.693805 +v -0.113690 0.700202 2.693805 +v -0.113690 0.606106 2.693805 +v -0.058381 0.529980 2.693805 +v 0.239975 0.124435 3.993110 +v 0.239975 -0.145006 3.993110 +v 0.239975 -0.149717 3.815753 +v 0.239975 0.124435 3.816251 +v 0.149073 0.215337 3.816415 +v 0.149073 0.215337 3.993110 +v 0.239975 0.123539 4.174913 +v 0.239975 -0.145546 4.174913 +v 0.239975 -0.326873 3.993110 +v 0.239975 -0.331563 3.816541 +v 0.239975 -0.163799 3.633924 +v 0.239975 0.097223 3.634397 +v 0.149073 0.214446 4.174910 +v 0.149073 0.192103 3.637632 +v 0.034389 0.215337 3.993110 +v 0.034389 0.215337 3.816415 +v 0.239975 0.118739 4.664481 +v 0.239975 -0.161547 4.664481 +v 0.239975 -0.327446 4.174913 +v 0.239975 -0.347182 3.634895 +v 0.239975 -0.430569 3.993110 +v 0.239975 -0.430569 3.817607 +v 0.239975 -0.188254 3.456192 +v 0.239975 0.053029 3.467237 +v 0.034389 0.214446 4.174910 +v 0.149073 0.209645 4.664482 +v 0.034389 0.192103 3.637632 +v -0.080296 0.215337 3.816415 +v -0.080296 0.215337 3.993110 +v 0.253251 0.138085 4.669035 +v 0.253251 -0.157054 4.669035 +v 0.239975 -0.343155 4.655555 +v 0.239975 -0.434031 4.174913 +v 0.239975 -0.370597 3.464717 +v 0.239975 -0.482793 3.636355 +v 0.149073 -0.521470 3.993110 +v 0.149073 -0.521470 3.818580 +v 0.149073 0.147087 3.467364 +v 0.239975 -0.196300 3.273830 +v 0.239975 0.033380 3.284343 +v -0.080296 0.214446 4.174910 +v 0.034389 0.209645 4.664482 +v 0.149296 0.233808 4.669037 +v -0.080296 0.192103 3.637632 +v 0.034389 0.147087 3.467364 +v -0.171198 0.124435 3.993110 +v -0.171198 0.124435 3.816251 +v 0.253251 -0.348285 4.659636 +v 0.253251 0.134966 4.987115 +v 0.253251 -0.167450 4.987115 +v 0.239975 -0.452295 4.645089 +v 0.239975 -0.655316 4.174913 +v 0.239975 -0.381911 3.305496 +v 0.239975 -0.260534 3.289027 +v 0.239975 -0.609569 3.502648 +v 0.034389 -0.521470 3.993110 +v 0.034389 -0.521470 3.818580 +v 0.149073 0.124263 3.288580 +v 0.239975 -0.185216 3.205594 +v -0.080296 0.209645 4.664482 +v -0.171198 0.123539 4.174913 +v 0.034389 0.233808 4.669037 +v -0.080296 0.147087 3.467364 +v 0.034389 0.124263 3.288580 +v -0.171198 -0.149717 3.815753 +v -0.171198 -0.145006 3.993110 +v 0.253251 -0.463209 4.648615 +v 0.253251 -0.358492 4.971918 +v 0.149296 0.230689 4.987120 +v 0.149296 0.134032 5.082834 +v 0.149296 -0.170629 5.082834 +v 0.239975 -0.688840 4.621837 +v 0.239975 -0.707775 3.334157 +v 0.209392 -0.370650 3.262421 +v 0.149073 -0.584015 3.661714 +v 0.149073 -0.731757 3.505895 +v 0.149073 -0.648753 4.084011 +v 0.034389 -0.648753 4.084011 +v -0.080296 -0.521470 3.993110 +v -0.080296 -0.521470 3.818580 +v 0.034389 -0.584015 3.661714 +v 0.149073 0.125845 2.937806 +v 0.239975 0.034962 2.933379 +v 0.239975 -0.128933 3.036653 +v -0.171198 0.118739 4.664481 +v -0.080519 0.233808 4.669037 +v -0.171198 -0.145546 4.174913 +v 0.034389 0.230689 4.987120 +v -0.080296 0.124263 3.288580 +v -0.171198 0.097223 3.634397 +v -0.171198 0.053029 3.467237 +v 0.034389 0.125845 2.937806 +v -0.171198 -0.163799 3.633924 +v -0.171198 -0.331563 3.816541 +v -0.171198 -0.326873 3.993110 +v 0.253251 -0.712288 4.624131 +v 0.253251 -0.475076 4.954096 +v 0.149296 -0.360967 5.068370 +v 0.034389 0.134032 5.082834 +v 0.034389 -0.170629 5.082834 +v 0.149073 -0.779363 4.613385 +v 0.149073 -0.746454 4.174659 +v 0.239975 -0.469850 3.273204 +v 0.209392 -0.271448 3.248642 +v 0.209392 -0.442523 3.235405 +v 0.034389 -0.731757 3.505895 +v -0.080296 -0.648753 4.084011 +v 0.034389 -0.746454 4.174659 +v -0.171198 -0.430569 3.993110 +v -0.171198 -0.430569 3.817607 +v -0.080296 -0.584015 3.661714 +v 0.239975 0.051369 2.752167 +v 0.209392 -0.209890 3.178843 +v -0.171198 -0.161547 4.664481 +v -0.080519 0.230689 4.987120 +v -0.171198 -0.327446 4.174913 +v -0.080296 0.125845 2.937806 +v -0.171198 -0.188254 3.456192 +v 0.149073 0.142826 2.757527 +v 0.034389 0.142826 2.757527 +v -0.171198 -0.347182 3.634895 +v 0.253251 -0.734069 4.914505 +v 0.149296 -0.479421 5.050262 +v -0.080519 0.134032 5.082834 +v -0.080519 -0.170629 5.082834 +v 0.034389 -0.360967 5.068370 +v 0.034389 -0.779363 4.613385 +v 0.149073 -0.798128 3.349109 +v 0.239975 -0.546948 3.171994 +v 0.034389 -0.370650 3.262421 +v 0.034389 -0.271448 3.248642 +v 0.034389 -0.442523 3.235405 +v -0.080296 -0.731757 3.505895 +v 0.034389 -0.798128 3.349109 +v -0.080296 -0.746454 4.174659 +v -0.171198 -0.655316 4.174913 +v -0.171198 -0.482793 3.636355 +v 0.239975 -0.148430 2.920981 +v 0.239975 -0.162751 2.854221 +v 0.239975 -0.137445 2.742777 +v 0.209392 -0.163890 3.037507 +v -0.171198 -0.343155 4.655555 +v -0.184474 -0.157054 4.669035 +v -0.184474 0.138085 4.669035 +v -0.184474 0.134966 4.987115 +v -0.171198 -0.434031 4.174913 +v -0.080296 0.142826 2.757527 +v -0.171198 0.034962 2.933379 +v -0.171198 0.033380 3.284343 +v -0.171198 -0.196300 3.273830 +v -0.171198 -0.370597 3.464717 +v 0.149073 0.170026 2.610819 +v 0.034389 0.170026 2.610819 +v 0.149296 -0.807608 4.615232 +v 0.149296 -0.741529 5.010195 +v 0.149296 -0.828989 4.900280 +v 0.034389 -0.479421 5.050262 +v -0.184474 -0.167450 4.987115 +v -0.080519 -0.360967 5.068370 +v 0.034389 -0.807608 4.615232 +v -0.080296 -0.779363 4.613385 +v 0.239975 -0.720609 3.029472 +v 0.149073 -0.810772 3.048922 +v 0.209392 -0.505535 3.150732 +v 0.034389 -0.209890 3.178843 +v -0.140615 -0.271448 3.248642 +v -0.140615 -0.370650 3.262421 +v 0.034389 -0.505535 3.150732 +v -0.140615 -0.442523 3.235405 +v -0.171198 -0.609569 3.502648 +v -0.080296 -0.798128 3.349109 +v 0.034389 -0.810772 3.048922 +v 0.239975 0.079097 2.602611 +v 0.209392 -0.179825 2.940735 +v 0.239975 -0.225306 2.808340 +v 0.239975 -0.090985 2.586576 +v 0.034389 -0.163890 3.037507 +v -0.171198 -0.452295 4.645089 +v -0.184474 -0.348285 4.659636 +v -0.080296 0.170026 2.610819 +v -0.171198 0.051369 2.752167 +v -0.171198 -0.128933 3.036653 +v -0.171198 -0.185216 3.205594 +v -0.171198 -0.260534 3.289027 +v -0.171198 -0.381911 3.305496 +v 0.141101 0.190348 2.521441 +v 0.034389 0.190348 2.521441 +v 0.034389 -0.741529 5.010195 +v 0.034389 -0.828989 4.900280 +v -0.080519 -0.479421 5.050262 +v -0.080519 -0.807608 4.615232 +v -0.171198 -0.688840 4.621837 +v 0.149073 -0.827939 2.868183 +v 0.239975 -0.540932 2.983666 +v 0.209392 -0.500618 2.993179 +v -0.140615 -0.209890 3.178843 +v 0.034389 -0.500618 2.993179 +v -0.140615 -0.505535 3.150732 +v -0.171198 -0.707775 3.334157 +v -0.080296 -0.810772 3.048922 +v 0.034389 -0.827939 2.868183 +v 0.232341 0.194688 2.430539 +v 0.209392 -0.191529 2.884884 +v 0.239975 -0.329662 2.751321 +v 0.239975 -0.286231 2.605305 +v 0.239975 -0.065356 2.406383 +v 0.239975 0.100557 2.422024 +v 0.034389 -0.179825 2.940735 +v -0.140615 -0.163890 3.037507 +v -0.184474 -0.463209 4.648615 +v -0.184474 -0.358492 4.971918 +v -0.072324 0.190348 2.521441 +v -0.171198 0.079097 2.602611 +v -0.171198 -0.137445 2.742777 +v -0.171198 -0.162751 2.854221 +v -0.171198 -0.148430 2.920981 +v 0.150333 0.202568 2.430540 +v -0.080519 -0.741529 5.010195 +v -0.080519 -0.828989 4.900280 +v -0.184474 -0.475076 4.954096 +v -0.184474 -0.712288 4.624131 +v 0.239975 -0.739169 2.847103 +v 0.209392 -0.429724 2.882930 +v 0.034389 -0.429724 2.882930 +v -0.140615 -0.500618 2.993179 +v -0.171198 -0.469850 3.273204 +v -0.171198 -0.720609 3.029472 +v -0.080296 -0.827939 2.868183 +v 0.034389 -0.851517 2.709267 +v 0.149073 -0.851517 2.709267 +v 0.034389 -0.191529 2.884884 +v 0.239975 -0.338260 2.801480 +v 0.209392 -0.242656 2.846500 +v 0.239975 -0.762055 2.692860 +v 0.239975 -0.063997 2.205518 +v 0.239975 0.111201 2.209292 +v -0.140615 -0.179825 2.940735 +v -0.081556 0.202568 2.430540 +v -0.163564 0.194688 2.430539 +v -0.171198 -0.090985 2.586576 +v -0.171198 -0.225306 2.808340 +v 0.034389 0.197812 2.432166 +v -0.184474 -0.734069 4.914505 +v 0.239975 -0.454190 2.851884 +v 0.209392 -0.334974 2.840762 +v 0.034389 -0.334974 2.840762 +v -0.140615 -0.429724 2.882930 +v -0.171198 -0.546948 3.171994 +v -0.080296 -0.851517 2.709267 +v 0.034389 -0.775457 2.602899 +v 0.149073 -0.775457 2.602899 +v 0.232341 0.205657 2.211326 +v 0.034389 -0.242656 2.846500 +v -0.140615 -0.191529 2.884884 +v 0.149073 -0.156204 2.398165 +v 0.149073 -0.410763 2.529415 +v 0.149073 -0.154887 2.203550 +v 0.239975 -0.062372 2.023708 +v 0.239975 0.116539 2.027561 +v -0.171198 0.100557 2.422024 +v -0.171198 -0.065356 2.406383 +v -0.171198 -0.286231 2.605305 +v -0.171198 -0.329662 2.751321 +v 0.150333 0.213536 2.211327 +v 0.133143 0.380407 2.430652 +v -0.140615 -0.334974 2.840762 +v -0.171198 -0.540932 2.983666 +v -0.171198 -0.739169 2.847103 +v -0.171198 -0.762055 2.692860 +v -0.080296 -0.775457 2.602899 +v 0.034389 -0.410763 2.529415 +v 0.232351 0.210861 2.029524 +v -0.140615 -0.242656 2.846500 +v 0.149073 -0.246220 2.505515 +v 0.149073 -0.241543 2.087216 +v 0.034389 -0.156204 2.398165 +v 0.034389 -0.154887 2.203550 +v 0.239975 -0.243831 1.991866 +v 0.239975 0.122772 0.953377 +v 0.239975 -0.052323 0.930061 +v -0.064366 0.380407 2.430652 +v -0.081556 0.213536 2.211327 +v -0.163564 0.205657 2.211326 +v -0.171198 0.111201 2.209292 +v -0.171198 -0.063997 2.205518 +v -0.171198 -0.338260 2.801480 +v 0.034389 0.380407 2.430652 +v -0.171198 -0.454190 2.851884 +v -0.080296 -0.410763 2.529415 +v 0.034389 -0.478763 2.460404 +v 0.149073 -0.478763 2.460404 +v 0.232351 0.217092 0.980310 +v 0.034389 -0.246220 2.505515 +v 0.149073 -0.364530 2.499090 +v 0.034389 -0.241543 2.087216 +v -0.080296 -0.156204 2.398165 +v -0.080296 -0.154887 2.203550 +v 0.239975 -0.234510 0.941510 +v 0.239975 -0.051913 0.616951 +v 0.239975 0.122613 0.725619 +v -0.163573 0.210861 2.029524 +v -0.171198 0.116539 2.027561 +v -0.171198 -0.062372 2.023708 +v 0.150324 0.218959 2.029524 +v 0.133143 0.402929 0.980311 +v 0.034389 0.402929 0.980311 +v -0.080296 -0.478763 2.460404 +v 0.034389 -0.486487 2.311562 +v 0.149073 -0.486487 2.311562 +v 0.149073 -0.444621 2.449322 +v 0.150323 0.225196 0.980311 +v 0.034389 -0.364530 2.499090 +v -0.080296 -0.246220 2.505515 +v 0.239975 -0.330192 1.979414 +v -0.080296 -0.241543 2.087216 +v 0.034389 -0.334622 2.072806 +v 0.149073 -0.334622 2.072806 +v 0.239975 -0.320005 0.997330 +v 0.239975 -0.056066 -0.714713 +v 0.239975 0.121062 -0.716698 +v -0.064366 0.402929 0.980311 +v -0.081546 0.218959 2.029524 +v -0.163574 0.217092 0.980310 +v -0.171198 0.122772 0.953377 +v -0.171198 -0.052323 0.930061 +v -0.171198 -0.243831 1.991866 +v 0.110996 0.285487 0.980311 +v 0.109281 0.289627 0.980311 +v 0.107930 0.290187 0.980310 +v -0.080296 -0.486487 2.311562 +v -0.080296 -0.364530 2.499090 +v -0.080296 -0.444621 2.449322 +v 0.034389 -0.486812 2.156900 +v 0.149073 -0.486812 2.156900 +v 0.149073 -0.450610 2.312716 +v 0.034389 -0.444621 2.449322 +v 0.141101 0.217438 0.889409 +v -0.080296 -0.334622 2.072806 +v 0.034389 -0.411054 2.068381 +v 0.149073 -0.411054 2.068381 +v 0.149073 -0.142938 0.576627 +v 0.149073 -0.356182 0.894060 +v 0.149073 -0.377200 1.956476 +v 0.149073 0.211963 -0.717721 +v 0.149073 0.213592 0.798507 +v 0.149073 -0.146965 -0.713697 +v 0.034389 -0.055922 -0.781576 +v -0.036724 0.293910 0.980311 +v -0.047062 0.289627 0.980311 +v -0.060188 0.257938 0.980310 +v -0.081546 0.225196 0.980311 +v -0.171198 0.122613 0.725619 +v -0.171198 -0.051913 0.616951 +v -0.171198 -0.234510 0.941510 +v 0.034389 0.320618 0.979558 +v 0.135976 0.225160 0.980109 +v -0.080296 -0.486812 2.156900 +v -0.080296 -0.450610 2.312716 +v 0.034389 -0.429922 2.037845 +v 0.149073 -0.429922 2.037845 +v 0.149073 -0.452902 2.168674 +v 0.034389 -0.450610 2.312716 +v 0.135489 0.217830 0.894104 +v -0.171198 -0.330192 1.979414 +v -0.080296 -0.411054 2.068381 +v 0.034389 -0.452902 2.168674 +v 0.149073 -0.197200 0.740252 +v 0.149073 -0.367645 1.057684 +v 0.034389 0.122808 -0.783042 +v 0.062052 0.144313 -0.767286 +v 0.087649 0.154916 -0.755627 +v 0.093329 0.168627 -0.749472 +v 0.133330 0.213592 0.798507 +v 0.110859 0.211963 -0.717721 +v 0.110202 0.213550 0.759803 +v 0.133213 0.213589 0.795628 +v 0.034389 -0.142938 0.576627 +v 0.034389 -0.146965 -0.713697 +v 0.031109 0.321979 0.979617 +v -0.073754 0.225176 0.980201 +v -0.073282 0.217434 0.890363 +v -0.073295 0.218255 0.898982 +v -0.073692 0.216126 0.887142 +v -0.171198 0.121062 -0.716698 +v -0.171198 -0.056066 -0.714713 +v -0.171198 -0.320005 0.997330 +v -0.080296 -0.429922 2.037845 +v -0.080296 -0.452902 2.168674 +v 0.034389 -0.377200 1.956476 +v 0.135460 0.217438 0.889409 +v -0.080296 -0.377200 1.956476 +v 0.034389 -0.197200 0.740252 +v 0.034389 -0.367645 1.057684 +v 0.034389 -0.356182 0.894060 +v 0.111069 0.211456 -0.718092 +v 0.034389 0.132854 -0.775681 +v -0.080296 -0.142938 0.576627 +v -0.080296 -0.146965 -0.713697 +v -0.073048 0.217089 0.881151 +v -0.080296 0.213592 0.798507 +v -0.080296 0.211963 -0.717721 +v -0.080296 -0.356182 0.894060 +v -0.080296 -0.197200 0.740252 +v -0.080296 -0.367645 1.057684 +v 0.014206 0.138498 -0.771547 +v 0.031109 0.131496 -0.776677 +v -0.034226 0.176148 -0.743962 +v -0.025431 0.154916 -0.753492 +v -0.071112 0.213592 0.798507 +v -0.048641 0.211963 -0.717721 +v -0.070995 0.213589 0.795628 +v -0.047983 0.213550 0.759803 +v -0.048851 0.211456 -0.718092 +v 0.092594 0.211963 -0.717721 +v 0.034389 0.211963 -0.717721 +v 0.034389 0.212976 0.225277 +v 0.089136 0.212976 0.225277 +v 0.092176 0.212976 0.225277 +v 0.092804 0.211456 -0.718092 +v 0.074735 0.167834 -0.750053 +v 0.034389 0.151122 -0.762298 +v -0.030367 0.211963 -0.717721 +v -0.029947 0.212976 0.225277 +v -0.012508 0.212976 0.225277 +v 0.031113 0.149765 -0.763292 +v -0.012508 0.167834 -0.750053 +v -0.030577 0.211456 -0.718092 +v 0.031109 0.131496 -4.060572 +v 0.087649 0.154916 -4.060573 +v -0.025431 0.154916 -4.060573 +v 0.031109 0.077349 -4.060572 +v 0.125937 0.116628 -4.060572 +v 0.111069 0.211456 -4.060573 +v -0.048851 0.211456 -4.060573 +v -0.063719 0.116628 -4.060572 +v 0.165216 0.211456 -4.060573 +v 0.031109 0.077349 -4.344854 +v 0.125937 0.116628 -4.344855 +v 0.087649 0.267996 -4.060572 +v 0.087649 0.267996 0.759803 +v -0.025431 0.267996 0.759803 +v -0.025431 0.267996 -4.060572 +v -0.102998 0.211456 -4.060573 +v -0.063719 0.116628 -4.344855 +v 0.125937 0.306284 -4.060572 +v 0.165216 0.211456 -4.344854 +v 0.031109 0.130944 -4.344854 +v 0.088039 0.154525 -4.344853 +v 0.031109 0.291416 -4.060572 +v 0.031109 0.291416 0.759803 +v 0.103932 0.284279 0.795627 +v -0.041714 0.284279 0.795627 +v -0.063719 0.306284 -4.060572 +v -0.102998 0.211456 -4.344854 +v -0.025821 0.154525 -4.344853 +v 0.031109 0.345562 -4.060572 +v 0.125937 0.306283 -4.344854 +v 0.111621 0.211456 -4.344854 +v 0.031110 0.130944 -4.704440 +v 0.088040 0.154525 -4.704440 +v 0.031109 0.314444 0.795628 +v -0.063719 0.306283 -4.344854 +v -0.049402 0.211456 -4.344854 +v -0.025821 0.154525 -4.704440 +v 0.031109 0.345562 -4.344855 +v 0.088039 0.268386 -4.344854 +v 0.111621 0.211456 -4.704439 +v 0.031110 0.149765 -4.704438 +v 0.074732 0.167834 -4.704441 +v -0.025821 0.268386 -4.344854 +v -0.049402 0.211456 -4.704439 +v -0.012512 0.167834 -4.704441 +v 0.031109 0.291967 -4.344854 +v 0.088040 0.268386 -4.704440 +v 0.092800 0.211456 -4.704439 +v -0.025821 0.268386 -4.704440 +v -0.030581 0.211456 -4.704439 +v 0.031110 0.291967 -4.704439 +v 0.074732 0.255078 -4.704441 +v -0.012512 0.255078 -4.704441 +v 0.031110 0.273146 -4.704439 +v 0.074736 0.255078 0.225277 +v -0.012508 0.255078 0.225277 +v 0.031114 0.273147 0.225277 +v -0.020919 -0.235599 2.378302 +v -0.020919 -0.107840 2.379190 +v -0.020919 -0.220523 2.324887 +v -0.020919 -0.107840 2.323998 +v 0.052297 -0.235599 2.378302 +v 0.052297 -0.107840 2.379190 +v 0.052297 -0.220523 2.324887 +v 0.052297 -0.107840 2.323998 +v -0.012115 -0.300374 2.316621 +v -0.012115 -0.330021 2.347511 +v 0.043492 -0.300374 2.316621 +v 0.043492 -0.330021 2.347511 +v 0.003564 -0.374778 2.242546 +v 0.003564 -0.392072 2.260371 +v 0.046100 -0.374778 2.242546 +v 0.046100 -0.392072 2.260371 +v -0.034660 -0.488762 1.870547 +v -0.064617 -0.481399 1.802711 +v -0.034660 -0.549317 1.796156 +v -0.034660 -0.206662 1.897795 +v -0.034660 -0.131392 1.836524 +v -0.064617 -0.199309 1.829959 +v -0.034660 -0.424893 1.281707 +v -0.034660 -0.500163 1.342978 +v -0.064617 -0.432246 1.349543 +v -0.034660 -0.082239 1.383346 +v -0.034660 -0.142794 1.308955 +v -0.064617 -0.150157 1.376790 +v 0.089774 -0.488762 1.870547 +v 0.089774 -0.549317 1.796156 +v 0.119730 -0.481399 1.802711 +v 0.089774 -0.131392 1.836524 +v 0.089774 -0.206662 1.897795 +v 0.119730 -0.199309 1.829959 +v 0.119730 -0.432246 1.349543 +v 0.089774 -0.500163 1.342978 +v 0.089774 -0.424893 1.281707 +v 0.089774 -0.082239 1.383346 +v 0.119730 -0.150157 1.376790 +v 0.089774 -0.142794 1.308955 +v 0.068578 0.265594 2.339561 +v 0.068578 0.265594 2.285825 +v 0.081821 0.311923 2.339561 +v 0.081821 0.311923 2.285825 +v 0.242235 0.224309 2.295690 +v 0.242538 0.224417 2.328841 +v 0.249852 0.249979 2.295498 +v 0.250155 0.250087 2.328650 +v 0.255650 0.200155 2.286524 +v 0.256171 0.200487 2.337797 +v 0.274564 0.262528 2.286228 +v 0.275085 0.262859 2.337501 +v 0.283042 0.202280 2.286324 +v 0.283520 0.202475 2.337596 +v 0.296007 0.245743 2.286028 +v 0.296484 0.245937 2.337301 +v 0.300239 0.208481 2.295516 +v 0.300670 0.208526 2.328068 +v 0.306733 0.231375 2.295329 +v 0.307163 0.231420 2.327880 +v 0.075199 0.288759 2.285825 +v 0.075199 0.288759 2.339561 +v 0.246043 0.237144 2.289679 +v 0.246347 0.237252 2.334660 +v 0.265107 0.231342 2.276860 +v 0.265628 0.231673 2.347990 +v 0.289524 0.224012 2.276587 +v 0.290002 0.224206 2.347716 +v 0.303486 0.219928 2.290485 +v 0.303917 0.219973 2.332911 +v 0.140108 0.245560 2.338892 +v 0.152743 0.289132 2.338769 +v 0.152548 0.289062 2.286058 +v 0.139913 0.245490 2.286181 +v 0.146230 0.267276 2.282314 +v 0.146425 0.267346 2.342636 +v 0.146699 0.238975 2.099161 +v 0.140406 0.314308 2.099174 +v 0.140406 0.319061 1.657537 +v 0.146695 0.240194 1.657537 +v 0.104520 0.310860 2.099124 +v 0.104520 0.315614 1.657486 +v 0.110809 0.236746 1.657486 +v 0.110812 0.235527 2.099110 +v 0.091196 0.301865 2.078650 +v 0.091196 0.305652 1.677875 +v 0.096206 0.240465 1.677875 +v 0.096208 0.239495 2.078639 +v 0.035223 0.309241 1.851360 +v 0.032516 0.311334 2.096038 +v 0.010587 0.299033 1.851360 +v 0.007194 0.300842 2.096038 +v 0.000383 0.274390 1.851360 +v -0.003295 0.275511 2.096038 +v 0.010587 0.249747 1.851360 +v 0.007194 0.250181 2.096038 +v 0.035223 0.239539 1.851360 +v 0.032516 0.239689 2.096038 +v 0.059858 0.249747 1.851360 +v 0.057838 0.250181 2.096038 +v 0.070062 0.274390 1.851360 +v 0.068327 0.275511 2.096038 +v 0.059858 0.299033 1.851360 +v 0.057838 0.300842 2.096038 +v 0.035223 0.300671 1.830377 +v 0.016646 0.292973 1.830377 +v 0.008951 0.274390 1.830377 +v 0.016646 0.255807 1.830377 +v 0.035223 0.248109 1.830377 +v 0.053800 0.255807 1.830377 +v 0.061495 0.274390 1.830377 +v 0.053800 0.292973 1.830377 +v 0.035223 0.300671 1.765164 +v 0.016646 0.292973 1.765164 +v 0.008951 0.274390 1.765164 +v 0.016646 0.255807 1.765164 +v 0.035223 0.248109 1.765164 +v 0.053800 0.255807 1.765164 +v 0.061495 0.274390 1.765164 +v 0.053800 0.292973 1.765164 +v 0.035223 0.294976 1.765164 +v 0.020671 0.288947 1.765164 +v 0.014643 0.274390 1.765164 +v 0.020671 0.259833 1.765164 +v 0.035223 0.253803 1.765164 +v 0.049775 0.259833 1.765164 +v 0.055802 0.274390 1.765164 +v 0.049775 0.288947 1.765164 +v 0.035223 0.290324 1.712289 +v 0.023959 0.285657 1.712289 +v 0.019294 0.274390 1.712289 +v 0.023959 0.263123 1.712289 +v 0.035223 0.258456 1.712289 +v 0.046486 0.263123 1.712289 +v 0.051151 0.274390 1.712289 +v 0.046486 0.285657 1.712289 +v 0.035223 0.274390 1.662770 +vn -0.202400 -0.979300 0.003200 +vn -0.961500 0.274800 0.000000 +vn -0.454400 0.890800 -0.000200 +vn 0.372400 0.928100 -0.004100 +vn 0.166900 0.225100 0.959900 +vn 0.009900 -0.277000 -0.960800 +vn -0.028600 -0.350700 0.936000 +vn -0.871500 -0.490300 0.011100 +vn -0.616800 -0.098200 0.781000 +vn -0.460400 0.410300 -0.787200 +vn 0.803400 0.595400 -0.010400 +vn 0.144100 0.292600 -0.945300 +vn 0.618200 0.785900 -0.010100 +vn 0.074900 -0.997200 0.004400 +vn 0.962000 -0.272900 -0.010700 +vn 0.336000 -0.941900 -0.000900 +vn 0.560800 -0.471400 0.680700 +vn 0.716300 0.088000 -0.692200 +vn 0.546200 -0.469100 -0.694000 +vn 0.735000 0.096900 0.671100 +vn -0.042000 -0.332700 -0.942100 +vn -0.615600 -0.093100 -0.782500 +vn -0.459800 0.429800 0.777100 +vn 0.177400 0.314900 0.932400 +vn 0.159100 0.219400 -0.962600 +vn 0.017200 -0.270900 0.962500 +vn -0.037800 -0.072100 0.996700 +vn 0.002700 0.082200 -0.996600 +vn -0.043500 -0.073200 -0.996400 +vn 0.009800 0.082900 0.996500 +vn 0.306700 0.951800 -0.001200 +vn -0.270500 -0.962700 0.001100 +vn -0.382800 0.923800 -0.012100 +vn -0.923800 0.382500 -0.015600 +vn -0.923900 -0.382500 -0.012100 +vn -0.382800 -0.923800 -0.003700 +vn 0.382800 -0.923800 0.004800 +vn 0.923900 -0.382600 0.008300 +vn -0.000000 0.000000 1.000000 +vn 0.382800 0.923800 -0.003700 +vn 0.923900 0.382600 0.004800 +vn -0.864500 -0.358000 -0.353000 +vn 0.923900 -0.382600 0.000000 +vn 0.864500 -0.358000 -0.353000 +vn -0.358100 -0.864300 -0.353000 +vn 0.864500 0.358000 -0.353000 +vn -0.864500 0.358000 -0.353000 +vn 0.358100 -0.864300 -0.353000 +vn 0.358100 0.864300 -0.353000 +vn -0.358100 0.864300 -0.353000 +vn 0.000000 0.000000 -1.000000 +vn -0.382800 -0.923800 0.000000 +vn -0.923900 0.382600 0.000000 +vn 0.923900 0.382600 0.000000 +vn 0.382800 -0.923800 0.000000 +vn -0.923900 -0.382600 0.000000 +vn -0.382800 0.923800 0.000000 +vn 0.382800 0.923800 0.000000 +vn 0.920900 0.381300 -0.081000 +vn 0.381500 -0.920800 -0.081000 +vn -0.920900 -0.381300 -0.081000 +vn -0.381500 0.920800 -0.081000 +vn 0.381500 0.920800 -0.081000 +vn 0.920900 -0.381300 -0.081000 +vn -0.381500 -0.920800 -0.081000 +vn -0.920900 0.381300 -0.081000 +vn -0.885600 0.366700 -0.284900 +vn 0.885600 0.366700 -0.284900 +vn 0.366900 -0.885500 -0.284900 +vn -0.885600 -0.366700 -0.284900 +vn -0.366900 0.885500 -0.284900 +vn 0.366900 0.885500 -0.284900 +vn 0.885600 -0.366700 -0.284900 +vn -0.366900 -0.885500 -0.284900 +vn -1.000000 0.000000 0.000000 +vn 0.000000 -0.007900 -1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -0.007000 1.000000 +vn 0.000000 0.103000 -0.994700 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -0.814600 0.580100 +vn 0.000000 -0.310000 0.950700 +vn 0.994800 -0.089800 -0.047700 +vn -0.994800 -0.089800 -0.047700 +vn 0.000000 -0.717700 -0.696300 +vn 0.000000 0.705500 -0.708700 +vn 0.999700 0.017900 0.017200 +vn -0.989000 -0.106300 -0.102400 +vn 0.382700 -0.923900 0.000000 +vn -0.382700 -0.923900 0.000000 +vn 0.923900 -0.382700 0.000000 +vn -0.923900 -0.382700 0.000000 +vn 0.923900 0.382700 -0.000000 +vn -0.923900 0.382700 -0.000000 +vn 0.382700 0.923900 -0.000000 +vn 0.794400 0.329000 -0.510600 +vn -0.794400 0.329000 -0.510600 +vn -0.382700 0.923900 -0.000000 +vn 0.329000 0.794400 -0.510600 +vn 0.923200 0.382400 -0.037800 +vn -0.923200 0.382400 -0.037800 +vn -0.329000 0.794400 -0.510600 +vn 0.382400 0.923200 -0.037800 +vn -0.382400 0.923200 -0.037800 +vn 0.309000 -0.951100 0.000000 +vn 0.809000 -0.587800 0.000000 +vn 0.809000 0.587800 0.000000 +vn 0.309000 0.951100 0.000000 +vn -0.309000 0.951100 0.000000 +vn -0.809000 0.587800 0.000000 +vn -0.980300 0.000000 -0.197500 +vn -0.309000 -0.951100 0.000000 +vn -0.809000 -0.587800 0.000000 +vn -0.793100 0.576200 -0.197500 +vn -0.302900 0.932300 -0.197500 +vn 0.302900 0.932300 -0.197500 +vn 0.793100 0.576200 -0.197500 +vn 0.302900 -0.932300 -0.197500 +vn 0.980300 0.000000 -0.197500 +vn 0.793100 -0.576200 -0.197500 +vn -0.302900 -0.932300 -0.197500 +vn -0.793100 -0.576200 -0.197500 +vn -0.973000 0.000000 0.231000 +vn 0.300700 0.925300 0.231000 +vn 0.787100 -0.571900 0.231000 +vn -0.787100 -0.571900 0.231000 +vn -0.300700 0.925300 0.231000 +vn 0.973000 0.000000 0.231000 +vn -0.300700 -0.925300 0.231000 +vn -0.787100 0.571900 0.231000 +vn 0.787100 0.571900 0.231000 +vn 0.300700 -0.925300 0.231000 +vn 0.707100 0.707100 -0.000000 +vn 0.707100 0.707100 0.003500 +vn 0.710400 0.697000 -0.097500 +vn 0.000000 1.000000 0.004900 +vn 0.707100 0.707100 0.006900 +vn 0.000000 0.991700 -0.128900 +vn 0.707100 -0.707100 0.000000 +vn 0.707100 0.683600 -0.180700 +vn 0.000000 1.000000 0.009800 +vn 0.000000 0.966800 -0.255600 +vn -0.707100 0.707100 -0.000000 +vn 0.723200 -0.654000 0.222000 +vn 0.561900 -0.506600 -0.653900 +vn 0.000000 -1.000000 0.000000 +vn 0.709800 0.699600 -0.082200 +vn -0.707100 0.707100 0.003500 +vn -0.710400 0.697000 -0.097500 +vn 0.000000 0.991900 -0.126600 +vn 0.803800 -0.080800 -0.589400 +vn 0.707100 -0.513100 0.486500 +vn 0.000000 -0.581200 -0.813800 +vn 0.000000 -0.928900 0.370400 +vn 0.707100 0.707100 0.003200 +vn -0.707100 0.707100 0.006900 +vn -0.707100 0.683600 -0.180700 +vn 0.000000 1.000000 0.004500 +vn 0.707100 -0.705100 -0.052900 +vn 0.736400 -0.603700 0.305500 +vn 0.824900 0.196700 -0.530000 +vn 0.758800 -0.485700 -0.433900 +vn 0.000000 -0.725700 0.688100 +vn 0.564500 -0.561400 -0.605100 +vn 0.000000 -0.680200 -0.733100 +vn -0.707100 -0.707100 0.000000 +vn 0.708400 0.702800 0.064900 +vn 0.726900 -0.652200 -0.215000 +vn -0.709800 0.699600 -0.082200 +vn 0.000000 0.995600 0.093800 +vn 0.000000 -0.997200 -0.074800 +vn 0.000000 -0.137600 -0.990500 +vn 0.000000 0.351800 -0.936100 +vn 0.000000 -0.920900 0.389800 +vn -0.562000 -0.506600 -0.653900 +vn -0.723200 -0.654000 0.222000 +vn -0.707100 0.707100 0.003200 +vn 0.000000 0.983200 0.182300 +vn 0.707100 -0.706500 0.029800 +vn 0.828400 0.447400 -0.337200 +vn 0.000000 -0.750000 -0.661400 +vn 0.000000 0.802200 -0.597000 +vn -0.707100 -0.513100 0.486500 +vn 0.000000 -0.999100 0.042100 +vn -0.564500 -0.561400 -0.605100 +vn 0.707100 0.695300 0.128900 +vn 0.749900 -0.647200 0.137400 +vn 0.747500 -0.655200 0.109300 +vn 0.000000 -0.950900 -0.309500 +vn -0.708400 0.702800 0.064900 +vn 0.000000 0.975100 0.221700 +vn -0.707100 -0.705100 -0.052900 +vn 0.707600 -0.703200 0.069200 +vn 0.799100 0.600800 0.019000 +vn -0.803800 -0.080800 -0.589400 +vn 0.000000 0.999500 0.031200 +vn -0.824900 0.196700 -0.530000 +vn -0.736400 -0.603700 0.305500 +vn 0.000000 -0.995500 0.094600 +vn 0.552600 0.752500 0.358200 +vn 0.804200 -0.353900 0.477500 +vn 0.000000 -0.986700 0.162500 +vn -0.707100 0.695300 0.128900 +vn -0.020400 0.994000 0.107500 +vn -0.758800 -0.485700 -0.433900 +vn 0.000000 0.841100 0.540900 +vn -0.828400 0.447400 -0.337200 +vn -0.707100 -0.706500 0.029800 +vn 0.000000 -0.989200 0.146800 +vn 0.996800 0.080000 0.009500 +vn 0.000000 -0.978700 0.205100 +vn -0.726900 -0.652200 -0.215000 +vn -0.552600 0.752500 0.358200 +vn 0.094700 0.985300 0.142100 +vn 0.707100 -0.699400 0.103800 +vn 0.000000 0.406600 0.913600 +vn 0.000000 -0.813400 -0.581700 +vn 0.996700 0.080500 0.004000 +vn 0.000000 -0.600400 0.799700 +vn 0.707100 -0.707100 -0.004800 +vn -0.747500 -0.655200 0.109300 +vn 0.020400 0.994000 0.107500 +vn -0.094700 0.985300 0.142100 +vn -0.996800 0.080000 0.009500 +vn -0.804200 -0.353900 0.477500 +vn -0.749900 -0.647200 0.137400 +vn 0.095500 0.994200 0.049700 +vn 0.571000 -0.667800 -0.477500 +vn 0.780700 0.523600 0.341000 +vn 0.777200 0.253100 0.576100 +vn 0.000000 -0.062000 0.998100 +vn -0.780700 0.523600 0.341000 +vn -0.799200 0.600800 0.019000 +vn -0.707600 -0.703200 0.069200 +vn -0.707100 -0.699400 0.103800 +vn 0.000000 -0.197500 -0.980300 +vn 0.996800 0.080500 0.002400 +vn 0.787500 -0.037800 0.615100 +vn 0.526600 -0.596600 -0.605600 +vn 0.719600 -0.125700 -0.682900 +vn 0.574500 -0.636800 0.514300 +vn 0.000000 -1.000000 -0.006800 +vn -0.095500 0.994200 0.049700 +vn -0.996700 0.080500 0.004000 +vn 0.096900 0.994900 0.029100 +vn -0.777200 0.253100 0.576100 +vn -0.571000 -0.667800 -0.477500 +vn 0.000000 -0.712300 0.701900 +vn 0.996800 0.080500 0.000500 +vn 0.000000 -0.766300 -0.642500 +vn 0.000000 -0.802000 0.597400 +vn -0.096900 0.994900 0.029100 +vn -0.996800 0.080500 0.002400 +vn -0.707100 -0.707100 -0.004800 +vn -0.526600 -0.596600 -0.605600 +vn -0.719600 -0.125700 -0.682900 +vn -0.787500 -0.037800 0.615100 +vn 0.000000 -0.998700 0.051800 +vn 0.996700 0.080600 -0.000100 +vn 0.098300 0.995100 0.005900 +vn 0.000000 0.054200 -0.998500 +vn 0.717000 -0.103200 0.689400 +vn 0.000000 -0.153000 0.988200 +vn -0.996800 0.080500 0.000500 +vn -0.574500 -0.636800 0.514300 +vn 0.000000 -1.000000 0.002100 +vn 0.000000 0.527800 -0.849400 +vn 0.454400 0.862000 -0.224700 +vn 0.097900 0.990700 -0.094500 +vn 0.000000 -0.057800 0.998300 +vn 0.707100 0.707100 -0.000800 +vn 0.707100 -0.707100 0.002200 +vn -0.098300 0.995100 0.005900 +vn -0.996700 0.080600 -0.000100 +vn 0.000000 -0.902300 -0.431100 +vn 0.000000 0.999000 -0.043800 +vn -0.001300 0.996400 -0.084900 +vn 0.370500 -0.872200 0.319200 +vn 0.000000 0.922900 0.385100 +vn 0.645800 -0.686900 -0.333300 +vn 0.430100 -0.900600 -0.063100 +vn 0.785100 -0.403200 -0.470200 +vn 0.460200 -0.887700 -0.009300 +vn 0.296500 0.286200 -0.911100 +vn -0.000000 1.000000 -0.001100 +vn 0.294400 -0.304500 -0.905900 +vn 0.000000 -1.000000 0.003100 +vn 0.308100 -0.009200 -0.951300 +vn -0.097900 0.990700 -0.094500 +vn -0.322800 0.890500 -0.320700 +vn -0.717000 -0.103200 0.689400 +vn 0.000000 -0.839200 -0.543800 +vn 0.000000 0.999900 -0.015900 +vn 0.000000 0.999100 -0.042300 +vn 0.000000 0.996500 -0.083300 +vn -0.370500 -0.872200 0.319200 +vn -0.000000 -0.949200 -0.314800 +vn -0.000000 -0.997600 -0.069900 +vn -0.000000 -0.695300 -0.718700 +vn 0.000000 -0.999900 -0.010600 +vn -0.000000 0.591000 -0.806700 +vn 0.000000 -0.597700 -0.801700 +vn -0.308100 -0.009200 -0.951300 +vn 0.001300 0.996400 -0.084900 +vn -0.720400 0.692700 0.033900 +vn -0.707100 0.707100 -0.000800 +vn -0.707100 -0.707100 0.002200 +vn -0.645800 -0.686900 -0.333300 +vn -0.785100 -0.403200 -0.470200 +vn -0.460200 -0.887700 -0.009300 +vn -0.296500 0.286200 -0.911100 +vn -0.294400 -0.304500 -0.905900 +vn -0.430100 -0.900600 -0.063100 +vn 0.007500 0.004200 1.000000 +vn -0.007500 0.004200 1.000000 +vn 0.995800 0.091100 0.002000 +vn -0.995100 0.099100 0.001500 +vn 0.000000 0.999900 0.015500 +vn 0.014000 0.009100 -0.999900 +vn -0.014000 0.009100 -0.999900 +vn 0.995000 0.099700 0.001400 +vn 0.992800 0.120000 0.001600 +vn 0.056800 0.041300 0.997500 +vn -0.021700 -0.066800 -0.997500 +vn 0.021700 0.066800 0.997500 +vn 0.021700 -0.066800 -0.997500 +vn -0.056800 0.041300 -0.997500 +vn 0.056800 -0.041300 0.997500 +vn -0.070200 0.000000 -0.997500 +vn 0.056800 0.041300 -0.997500 +vn -0.056800 -0.041300 0.997500 +vn 0.021700 0.066800 -0.997500 +vn -0.070200 0.000000 0.997500 +vn 0.070200 0.000000 -0.997500 +vn -0.056800 0.041300 0.997500 +vn 0.021700 -0.066800 0.997500 +vn -0.021700 0.066800 -0.997500 +vn -0.021700 -0.066800 0.997500 +vn -0.056800 -0.041300 -0.997500 +vn 0.070200 0.000000 0.997500 +vn 0.056800 -0.041300 -0.997500 +vn -0.021700 0.066800 0.997500 +vn -0.000300 -0.000900 1.000000 +vn 0.000700 0.000500 -1.000000 +vn -0.000700 -0.000500 1.000000 +vn 0.000900 0.000000 1.000000 +vn -0.000700 0.000500 -1.000000 +vn 0.000700 -0.000500 1.000000 +vn -0.000300 0.000900 1.000000 +vn -0.000300 -0.000900 -1.000000 +vn 0.000300 0.000900 1.000000 +vn -0.000700 -0.000500 -1.000000 +vn -0.064900 0.047200 0.996800 +vn 0.080200 0.000000 -0.996800 +vn -0.064900 -0.047200 -0.996800 +vn 0.064900 0.047200 0.996800 +vn -0.024800 -0.076300 -0.996800 +vn 0.024800 -0.076300 0.996800 +vn -0.064900 0.047200 -0.996800 +vn -0.080200 -0.000000 0.996800 +vn 0.064900 0.047200 -0.996800 +vn 0.024800 0.076300 0.996800 +vn 0.064900 -0.047200 -0.996800 +vn -0.024800 0.076300 -0.996800 +vn -0.024800 -0.076300 0.996800 +vn 0.024800 0.076300 -0.996800 +vn -0.064900 -0.047200 0.996800 +vn 0.080200 -0.000000 0.996800 +vn -0.080200 0.000000 -0.996800 +vn 0.064900 -0.047200 0.996800 +vn -0.024800 0.076300 0.996800 +vn 0.024800 -0.076300 -0.996800 +vn 0.000300 -0.000900 -1.000000 +vn -0.000700 0.000500 1.000000 +vn -0.000900 0.000000 -1.000000 +vn 0.000700 0.000500 1.000000 +vn 0.000300 0.000900 -1.000000 +vn 0.000300 -0.000900 1.000000 +vn -0.000300 0.000900 -1.000000 +vn 0.000700 -0.000500 -1.000000 +vn -0.000900 0.000000 1.000000 +vn 0.000900 0.000000 -1.000000 +vn 0.324500 0.000000 -0.945900 +vn 0.150900 0.157500 -0.975900 +vn 0.309900 0.046700 -0.949600 +vn 0.000000 0.185200 -0.982700 +vn 0.324300 0.090300 -0.941600 +vn 0.677400 0.735600 0.007200 +vn 0.677400 0.000000 0.735700 +vn 0.325900 0.092500 -0.940900 +vn 0.678500 -0.057000 0.732400 +vn 0.543800 0.590500 0.596300 +vn -0.150900 0.157500 -0.975900 +vn 0.000000 0.703600 0.710600 +vn 0.131200 -0.045100 -0.990300 +vn 0.677400 -0.111200 0.727200 +vn 0.000000 -0.075800 0.997100 +vn -0.324500 0.000000 -0.945900 +vn -0.677400 0.735600 0.007200 +vn 0.677400 -0.733600 -0.055000 +vn 0.000000 -0.151100 0.988500 +vn -0.677400 0.000000 0.735600 +vn 0.000000 -0.065200 -0.997900 +vn -0.309900 0.046700 -0.949600 +vn -0.543800 0.590500 0.596300 +vn 0.532600 -0.662300 0.527000 +vn -0.678500 -0.057000 0.732400 +vn -0.324300 0.090300 -0.941600 +vn 0.000000 -0.782500 0.622600 +vn -0.677400 -0.111200 0.727200 +vn -0.131200 -0.045100 -0.990300 +vn -0.325900 0.092500 -0.940900 +vn -0.677400 -0.733600 -0.055000 +vn -0.532600 -0.662300 0.527000 +vn 0.001400 0.000300 -1.000000 +vn 0.254500 0.967100 0.002500 +vn 0.095600 -0.995400 -0.010700 +vn -0.095600 0.995400 0.002700 +vn -0.001400 -0.000100 1.000000 +vn 0.996900 0.078300 0.000500 +vn 0.818800 0.064200 0.570500 +vn 0.820400 0.067400 -0.567800 +vn 0.579700 -0.814800 -0.008300 +vn 0.000000 -0.994200 -0.107800 +vn 0.000000 0.994200 0.107800 +vn 0.000000 -0.096100 0.995400 +vn 0.000000 0.096100 -0.995400 +vn -0.851000 -0.407300 0.331600 +vn -0.848200 0.334400 0.410800 +vn -0.848200 -0.334400 -0.410800 +vn -0.851000 0.407300 -0.331600 +vn 0.851000 -0.407300 0.331600 +vn 0.848200 0.334400 0.410800 +vn 0.848200 -0.334400 -0.410800 +vn 0.851000 0.407300 -0.331600 +vn -0.915600 -0.038700 0.400200 +vn -0.915600 0.399700 0.043400 +vn -0.915600 0.038700 -0.400200 +vn -0.915600 -0.399700 -0.043400 +vn 0.000000 0.775500 -0.631300 +vn 0.915600 0.038700 -0.400200 +vn 0.000000 -0.631300 -0.775500 +vn 0.915600 0.399700 0.043400 +vn 0.915600 -0.038700 0.400200 +vn 0.915600 -0.399700 -0.043400 +vn 0.000000 0.631300 0.775500 +vn 0.000000 -0.775500 0.631300 +usemtl Metal +s off +f 800//1 771//1 772//1 797//1 +f 788//2 787//2 768//2 767//2 +f 773//3 774//3 778//3 777//3 +f 798//4 774//4 773//4 799//4 +f 802//5 790//5 774//5 798//5 +f 801//6 789//6 771//6 800//6 +f 792//7 776//7 780//7 794//7 +f 772//8 771//8 775//8 776//8 +f 790//9 772//9 776//9 792//9 +f 789//10 773//10 777//10 791//10 +f 781//11 782//11 786//11 785//11 +f 791//12 777//12 781//12 793//12 +f 777//13 778//13 782//13 781//13 +f 776//14 775//14 779//14 780//14 +f 796//15 795//15 785//15 786//15 +f 780//16 779//16 783//16 784//16 +f 794//17 780//17 784//17 796//17 +f 793//18 781//18 785//18 795//18 +f 779//19 793//19 795//19 783//19 +f 782//20 794//20 796//20 786//20 +f 784//15 783//15 795//15 796//15 +f 775//21 791//21 793//21 779//21 +f 771//22 789//22 791//22 775//22 +f 774//23 790//23 792//23 778//23 +f 778//24 792//24 794//24 782//24 +f 799//25 773//25 789//25 801//25 +f 797//26 772//26 790//26 802//26 +f 769//2 770//2 787//2 788//2 +f 767//27 797//27 802//27 788//27 +f 770//28 799//28 801//28 787//28 +f 787//29 801//29 800//29 768//29 +f 788//30 802//30 798//30 769//30 +f 769//31 798//31 799//31 770//31 +f 768//32 800//32 797//32 767//32 +usemtl BulletYellow +f 815//33 817//33 818//33 816//33 +f 817//34 819//34 820//34 818//34 +f 819//35 821//35 822//35 820//35 +f 821//36 823//36 824//36 822//36 +f 823//37 825//37 826//37 824//37 +f 825//38 827//38 828//38 826//38 +f 818//39 820//39 822//39 824//39 826//39 828//39 830//39 816//39 +f 829//40 815//40 816//40 830//40 +f 827//41 829//41 830//41 828//41 +f 819//42 833//42 834//42 821//42 +f 836//43 844//43 845//43 837//43 +f 825//44 836//44 837//44 827//44 +f 821//45 834//45 835//45 823//45 +f 827//46 837//46 838//46 829//46 +f 817//47 832//47 833//47 819//47 +f 823//48 835//48 836//48 825//48 +f 829//49 838//49 831//49 815//49 +f 815//50 831//50 832//50 817//50 +f 839//51 847//51 848//51 840//51 +f 834//52 842//52 843//52 835//52 +f 832//53 840//53 841//53 833//53 +f 837//54 845//54 846//54 838//54 +f 835//55 843//55 844//55 836//55 +f 833//56 841//56 842//56 834//56 +f 831//57 839//57 840//57 832//57 +f 838//58 846//58 839//58 831//58 +f 846//51 854//51 847//51 839//51 +f 844//51 852//51 853//51 845//51 +f 842//51 850//51 851//51 843//51 +f 840//51 848//51 849//51 841//51 +f 845//51 853//51 854//51 846//51 +f 843//51 851//51 852//51 844//51 +f 841//51 849//51 850//51 842//51 +usemtl BulletOrange +f 853//59 861//59 862//59 854//59 +f 851//60 859//60 860//60 852//60 +f 849//61 857//61 858//61 850//61 +f 847//62 855//62 856//62 848//62 +f 854//63 862//63 855//63 847//63 +f 852//64 860//64 861//64 853//64 +f 850//65 858//65 859//65 851//65 +f 848//66 856//66 857//66 849//66 +f 856//67 863//67 857//67 +f 861//68 863//68 862//68 +f 859//69 863//69 860//69 +f 857//70 863//70 858//70 +f 855//71 863//71 856//71 +f 862//72 863//72 855//72 +f 860//73 863//73 861//73 +f 858//74 863//74 859//74 +usemtl Trigger +f 728//75 730//75 729//75 727//75 +f 730//76 734//76 733//76 729//76 +f 734//77 732//77 731//77 733//77 +f 732//78 728//78 727//78 731//78 +f 729//79 733//79 737//79 735//79 +f 732//80 734//80 730//80 728//80 +f 738//81 736//81 740//81 742//81 +f 731//82 727//82 736//82 738//82 +f 733//83 731//83 738//83 737//83 +f 727//84 729//84 735//84 736//84 +f 740//85 739//85 741//85 742//85 +f 735//86 737//86 741//86 739//86 +f 737//87 738//87 742//87 741//87 +f 736//88 735//88 739//88 740//88 +usemtl Barrel +f 648//89 670//89 671//89 613//89 612//89 638//89 +f 650//90 672//90 670//90 648//90 647//90 +f 671//39 670//39 673//39 674//39 +f 613//91 671//91 675//91 637//91 614//91 +f 655//92 676//92 672//92 650//92 649//92 +f 670//39 672//39 677//39 673//39 +f 675//39 671//39 674//39 678//39 +f 674//89 673//89 679//89 680//89 +f 637//93 675//93 681//93 682//93 617//93 616//93 +f 683//94 684//94 676//94 655//94 652//94 654//94 +f 672//39 676//39 685//39 677//39 +f 673//90 677//90 686//90 679//90 +f 681//39 675//39 678//39 687//39 +f 678//91 674//91 680//91 688//91 +f 680//51 679//51 689//51 690//51 +f 682//95 681//95 691//95 692//95 +f 617//96 682//96 693//96 618//96 +f 653//97 694//97 683//97 654//97 +f 692//98 691//98 684//98 683//98 +f 676//39 684//39 695//39 685//39 +f 677//92 685//92 696//92 686//92 +f 679//51 686//51 697//51 689//51 +f 691//39 681//39 687//39 698//39 +f 687//93 678//93 688//93 699//93 +f 688//51 680//51 690//51 700//51 +f 690//89 689//89 701//89 702//89 +f 693//99 682//99 692//99 703//99 +f 618//100 693//100 570//100 569//100 598//100 605//100 632//100 615//100 +f 591//101 694//101 653//101 651//101 641//101 625//101 623//101 624//101 622//101 592//101 +f 703//102 692//102 683//102 694//102 +f 684//39 691//39 698//39 695//39 +f 685//94 695//94 704//94 696//94 +f 686//51 696//51 705//51 697//51 +f 689//90 697//90 706//90 701//90 +f 698//95 687//95 699//95 707//95 +f 699//51 688//51 700//51 708//51 +f 700//91 690//91 702//91 709//91 +f 702//51 701//51 710//51 711//51 +f 570//103 693//103 703//103 621//103 597//103 571//103 +f 621//104 703//104 694//104 591//104 590//104 +f 695//98 698//98 707//98 704//98 +f 696//51 704//51 712//51 705//51 +f 697//92 705//92 713//92 706//92 +f 701//51 706//51 714//51 710//51 +f 707//51 699//51 708//51 715//51 +f 708//93 700//93 709//93 716//93 +f 709//51 702//51 711//51 717//51 +f 711//98 710//98 667//98 663//98 662//98 +f 704//51 707//51 715//51 712//51 +f 705//94 712//94 718//94 713//94 +f 706//51 713//51 719//51 714//51 +f 667//95 710//95 714//95 668//95 +f 715//95 708//95 716//95 720//95 +f 716//51 709//51 717//51 721//51 +f 661//94 717//94 711//94 662//94 +f 712//98 715//98 720//98 718//98 +f 713//51 718//51 722//51 719//51 +f 668//93 714//93 719//93 669//93 +f 720//51 716//51 721//51 723//51 +f 721//92 717//92 661//92 656//92 660//92 724//92 +f 718//51 720//51 723//51 722//51 +f 719//91 722//91 725//91 665//91 664//91 669//91 +f 723//90 721//90 724//90 726//90 +f 659//51 725//51 726//51 724//51 660//51 +f 722//89 723//89 726//89 725//89 +f 665//51 725//51 666//51 +f 666//51 725//51 659//51 658//51 +usemtl Green +f 233//105 2//105 4//105 234//105 +f 234//106 4//106 6//106 235//106 +f 235//77 6//77 8//77 236//77 +f 236//107 8//107 10//107 237//107 +f 237//108 10//108 12//108 238//108 +f 238//109 12//109 14//109 239//109 +f 239//110 14//110 16//110 240//110 +f 240//75 16//75 18//75 241//75 +f 18//111 16//111 28//111 29//111 +f 242//112 20//112 2//112 233//112 +f 241//113 18//113 20//113 242//113 +f 134//105 131//105 32//105 31//105 +f 16//114 14//114 27//114 28//114 +f 14//115 12//115 26//115 27//115 +f 12//116 10//116 25//116 26//116 +f 10//117 8//117 24//117 25//117 +f 4//118 2//118 22//118 21//118 +f 8//119 6//119 23//119 24//119 +f 6//120 4//120 21//120 23//120 +f 2//121 20//121 30//121 22//121 +f 20//122 18//122 29//122 30//122 +f 39//123 38//123 48//123 49//123 +f 135//75 132//75 38//75 39//75 +f 136//108 133//108 35//108 36//108 +f 137//106 134//106 31//106 33//106 +f 138//113 135//113 39//113 40//113 +f 139//109 136//109 36//109 37//109 +f 140//77 137//77 33//77 34//77 +f 131//112 138//112 40//112 32//112 +f 132//110 139//110 37//110 38//110 +f 133//107 140//107 34//107 35//107 +f 36//124 35//124 45//124 46//124 +f 33//125 31//125 41//125 43//125 +f 40//126 39//126 49//126 50//126 +f 37//127 36//127 46//127 47//127 +f 34//128 33//128 43//128 44//128 +f 32//129 40//129 50//129 42//129 +f 38//130 37//130 47//130 48//130 +f 35//131 34//131 44//131 45//131 +f 31//132 32//132 42//132 41//132 +f 113//107 120//107 70//107 65//107 +f 112//110 119//110 69//110 63//110 +f 111//112 118//112 68//112 61//112 +f 120//77 117//77 67//77 70//77 +f 119//109 116//109 66//109 69//109 +f 118//113 115//113 64//113 68//113 +f 117//106 114//106 62//106 67//106 +f 116//108 113//108 65//108 66//108 +f 115//75 112//75 63//75 64//75 +f 114//105 111//105 61//105 62//105 +f 21//105 22//105 108//105 101//105 +f 29//75 28//75 109//75 102//75 +f 26//108 25//108 110//108 103//108 +f 23//106 21//106 101//106 104//106 +f 30//113 29//113 102//113 105//113 +f 27//109 26//109 103//109 106//109 +f 24//77 23//77 104//77 107//77 +f 22//112 30//112 105//112 108//112 +f 28//110 27//110 106//110 109//110 +f 25//107 24//107 107//107 110//107 +f 73//107 80//107 130//107 123//107 +f 72//110 79//110 129//110 122//110 +f 71//112 78//112 128//112 121//112 +f 80//77 77//77 127//77 130//77 +f 79//109 76//109 126//109 129//109 +f 78//113 75//113 125//113 128//113 +f 77//106 74//106 124//106 127//106 +f 76//108 73//108 123//108 126//108 +f 75//75 72//75 122//75 125//75 +f 74//105 71//105 121//105 124//105 +f 243//77 244//77 245//77 246//77 +f 243//133 246//133 247//133 248//133 +f 249//77 250//77 244//77 243//77 +f 245//77 244//77 251//77 252//77 +f 246//77 245//77 253//77 254//77 +f 248//134 255//134 249//134 243//134 +f 257//80 248//80 247//80 258//80 +f 249//77 259//77 260//77 250//77 +f 244//77 250//77 261//77 251//77 +f 253//77 245//77 252//77 262//77 +f 251//77 263//77 264//77 252//77 +f 254//135 256//135 247//135 246//135 +f 254//77 253//77 265//77 266//77 +f 267//136 255//136 248//136 257//136 +f 255//137 268//137 259//137 249//137 +f 258//138 247//138 256//138 269//138 +f 257//80 258//80 270//80 271//80 +f 274//77 261//77 250//77 260//77 +f 261//77 275//77 263//77 251//77 +f 265//77 253//77 262//77 276//77 +f 252//77 264//77 277//77 262//77 +f 278//139 279//139 264//139 263//139 +f 254//140 266//140 280//140 256//140 +f 266//77 265//77 281//77 282//77 +f 267//136 257//136 271//136 283//136 +f 268//141 255//141 267//141 284//141 +f 258//138 269//138 286//138 270//138 +f 269//142 256//142 280//142 287//142 +f 288//143 271//143 270//143 289//143 +f 261//77 274//77 293//77 275//77 +f 275//77 294//77 263//77 +f 265//77 276//77 295//77 296//77 281//77 +f 262//77 277//77 297//77 276//77 +f 264//144 279//144 317//144 277//144 +f 263//145 294//145 319//145 278//145 +f 278//146 298//146 299//146 279//146 +f 280//147 266//147 282//147 300//147 +f 281//77 301//77 326//77 380//77 325//77 282//77 +f 302//141 284//141 267//141 283//141 +f 271//148 288//148 303//148 283//148 +f 269//142 287//142 305//142 286//142 +f 270//149 286//149 332//149 289//149 +f 287//150 280//150 300//150 306//150 +f 288//75 289//75 307//75 308//75 +f 293//77 314//77 294//77 275//77 +f 276//77 297//77 315//77 295//77 +f 295//151 316//151 346//151 296//151 +f 296//77 301//77 281//77 +f 297//152 277//152 317//152 318//152 +f 298//153 278//153 319//153 320//153 +f 321//146 322//146 299//146 298//146 +f 279//154 299//154 323//154 317//154 +f 324//155 300//155 282//155 325//155 +f 283//156 303//156 327//156 302//156 +f 303//75 288//75 308//75 329//75 +f 287//150 306//150 331//150 305//150 +f 332//157 286//157 305//157 333//157 +f 306//158 300//158 324//158 334//158 +f 289//75 332//75 335//75 307//75 +f 307//75 336//75 337//75 308//75 +f 343//159 344//159 294//159 314//159 +f 297//160 318//160 370//160 315//160 +f 295//77 315//77 404//77 436//77 371//77 345//77 +f 316//161 295//161 345//161 347//161 +f 296//162 346//162 355//162 301//162 +f 317//163 323//163 348//163 318//163 +f 319//164 294//164 344//164 +f 298//153 320//153 349//153 321//153 +f 344//165 350//165 320//165 319//165 +f 321//166 351//166 352//166 322//166 +f 322//154 353//154 323//154 299//154 +f 325//167 354//167 361//167 324//167 +f 301//168 355//168 383//168 326//168 +f 303//75 329//75 356//75 327//75 +f 308//75 337//75 358//75 329//75 +f 306//158 334//158 359//158 331//158 +f 305//169 331//169 391//169 333//169 +f 332//75 333//75 360//75 335//75 +f 334//170 324//170 361//170 362//170 +f 335//75 363//75 336//75 307//75 +f 337//75 336//75 352//75 351//75 +f 369//171 350//171 344//171 343//171 +f 346//172 316//172 372//172 373//172 +f 316//173 347//173 374//173 372//173 +f 353//163 375//163 348//163 323//163 +f 318//174 348//174 376//174 370//174 +f 377//165 349//165 320//165 350//165 +f 349//175 378//175 351//175 321//175 +f 352//176 379//176 353//176 322//176 +f 325//77 380//77 381//77 382//77 354//77 +f 384//75 356//75 329//75 358//75 +f 358//75 337//75 351//75 388//75 +f 334//170 362//170 389//170 359//170 +f 359//177 390//177 391//177 331//177 +f 333//75 391//75 392//75 360//75 +f 360//75 393//75 363//75 335//75 +f 362//178 361//178 394//178 395//178 +f 336//75 363//75 379//75 352//75 +f 369//171 403//171 377//171 350//171 +f 404//179 315//179 370//179 405//179 +f 371//180 406//180 347//180 345//180 +f 355//181 346//181 373//181 407//181 +f 408//172 373//172 372//172 409//172 +f 347//182 406//182 410//182 374//182 +f 409//173 372//173 374//173 411//173 +f 412//183 375//183 353//183 379//183 +f 375//174 413//174 376//174 348//174 +f 370//184 376//184 414//184 405//184 +f 349//185 377//185 378//185 +f 388//75 351//75 378//75 +f 394//186 361//186 354//186 415//186 +f 380//187 416//187 445//187 381//187 +f 381//77 417//77 474//77 446//77 382//77 +f 354//77 382//77 418//77 415//77 +f 326//188 383//188 416//188 380//188 +f 383//189 355//189 407//189 419//189 +f 358//75 388//75 420//75 384//75 +f 362//178 395//178 422//178 389//178 +f 390//190 359//190 389//190 423//190 +f 391//75 390//75 458//75 424//75 425//75 392//75 +f 360//75 392//75 426//75 427//75 393//75 +f 363//75 393//75 412//75 379//75 +f 395//191 394//191 428//191 429//191 +f 403//192 434//192 378//192 377//192 +f 405//193 435//193 464//193 404//193 +f 406//194 371//194 436//194 437//194 +f 438//181 407//181 373//181 408//181 +f 408//195 409//195 427//195 426//195 +f 406//196 437//196 439//196 410//196 +f 411//182 374//182 410//182 440//182 +f 409//197 411//197 468//197 427//197 +f 412//198 441//198 413//198 375//198 +f 413//184 442//184 414//184 376//184 +f 405//199 414//199 443//199 435//199 +f 420//75 388//75 378//75 434//75 +f 415//200 444//200 428//200 394//200 +f 381//201 445//201 475//201 417//201 +f 418//77 382//77 446//77 447//77 +f 415//77 418//77 448//77 449//77 +f 416//202 383//202 419//202 450//202 +f 451//189 419//189 407//189 438//189 +f 395//191 429//191 454//191 422//191 +f 422//203 455//203 423//203 389//203 +f 390//75 423//75 456//75 457//75 458//75 +f 426//75 392//75 425//75 +f 393//75 427//75 441//75 412//75 +f 428//204 459//204 484//204 429//204 +f 404//77 464//77 446//77 474//77 486//77 436//77 +f 438//205 408//205 426//205 425//205 +f 437//206 465//206 466//206 439//206 +f 440//196 410//196 439//196 467//196 +f 411//207 440//207 490//207 468//207 +f 469//208 442//208 413//208 441//208 +f 442//199 470//199 443//199 414//199 +f 435//209 443//209 471//209 472//209 +f 415//210 449//210 444//210 +f 445//211 416//211 450//211 473//211 +f 448//77 418//77 447//77 +f 446//77 464//77 476//77 447//77 +f 449//77 448//77 477//77 478//77 +f 479//202 450//202 419//202 451//202 +f 451//212 438//212 425//212 424//212 +f 454//213 481//213 455//213 422//213 +f 423//75 455//75 482//75 456//75 +f 459//214 428//214 444//214 +f 435//215 472//215 476//215 464//215 +f 465//216 487//216 488//216 466//216 +f 467//206 439//206 466//206 489//206 +f 470//209 491//209 471//209 443//209 +f 472//217 471//217 492//217 493//217 +f 494//218 444//218 449//218 478//218 +f 475//219 445//219 473//219 495//219 +f 496//211 473//211 450//211 479//211 +f 477//220 448//220 497//220 499//220 +f 478//77 477//77 500//77 501//77 +f 479//221 451//221 424//221 458//221 +f 484//222 480//222 454//222 429//222 +f 480//223 481//223 454//223 +f 455//224 481//224 502//224 +f 455//75 502//75 503//75 482//75 +f 482//75 504//75 505//75 456//75 +f 528//75 483//75 457//75 456//75 505//75 +f 457//225 483//225 515//225 496//225 +f 496//226 479//226 458//226 457//226 +f 444//227 494//227 506//227 459//227 +f 472//228 493//228 476//228 +f 486//229 465//229 437//229 436//229 +f 465//230 486//230 474//230 487//230 +f 487//231 475//231 495//231 488//231 +f 489//216 466//216 488//216 508//216 +f 467//232 489//232 530//232 509//232 +f 509//233 490//233 440//233 467//233 +f 469//75 441//75 427//75 468//75 490//75 509//75 +f 510//234 470//234 442//234 469//234 +f 470//235 510//235 511//235 491//235 +f 491//217 512//217 492//217 471//217 +f 513//236 498//236 493//236 492//236 +f 501//237 514//237 494//237 478//237 +f 515//219 495//219 473//219 496//219 +f 487//238 474//238 417//238 475//238 +f 516//239 497//239 448//239 447//239 +f 516//240 447//240 476//240 493//240 498//240 +f 499//241 517//241 520//241 477//241 +f 497//242 518//242 519//242 499//242 +f 500//77 477//77 520//77 +f 521//77 501//77 500//77 522//77 +f 481//243 480//243 524//243 525//243 +f 525//244 526//244 502//244 481//244 +f 502//75 526//75 527//75 503//75 +f 503//75 504//75 482//75 +f 505//75 504//75 511//75 510//75 +f 494//245 514//245 546//245 506//245 +f 508//231 488//231 495//231 515//231 +f 489//246 508//246 528//246 530//246 +f 469//75 509//75 530//75 528//75 505//75 510//75 +f 491//247 511//247 512//247 +f 513//236 492//236 512//236 531//236 +f 532//248 533//248 498//248 513//248 +f 534//249 514//249 501//249 521//249 +f 516//250 535//250 518//250 497//250 +f 498//77 536//77 516//77 +f 499//251 519//251 537//251 517//251 +f 538//242 539//242 519//242 518//242 +f 522//77 500//77 520//77 540//77 +f 521//77 522//77 541//77 542//77 +f 525//252 524//252 564//252 543//252 +f 544//253 526//253 525//253 543//253 +f 526//75 544//75 545//75 527//75 +f 527//254 539//254 538//254 503//254 +f 503//255 538//255 555//255 504//255 +f 555//256 531//256 512//256 511//256 504//256 +f 483//257 528//257 508//257 515//257 +f 532//248 513//248 531//248 549//248 +f 550//258 551//258 533//258 532//258 +f 533//77 552//77 536//77 498//77 +f 534//259 521//259 542//259 +f 553//260 546//260 514//260 534//260 +f 536//261 554//261 535//261 516//261 +f 555//250 538//250 518//250 535//250 +f 520//262 517//262 559//262 556//262 +f 539//251 557//251 537//251 519//251 +f 517//263 537//263 558//263 559//263 +f 541//77 522//77 540//77 +f 540//77 520//77 556//77 560//77 +f 542//77 541//77 561//77 562//77 +f 565//264 566//264 544//264 543//264 +f 566//75 567//75 545//75 544//75 +f 545//75 568//75 527//75 +f 539//265 527//265 568//265 557//265 +f 550//258 532//258 549//258 572//258 +f 549//75 531//75 573//75 574//75 +f 575//266 576//266 551//266 550//266 +f 551//77 577//77 552//77 533//77 +f 552//267 578//267 554//267 536//267 +f 534//268 542//268 587//268 579//268 +f 553//269 534//269 579//269 +f 573//261 555//261 535//261 554//261 +f 557//263 580//263 558//263 537//263 +f 559//270 558//270 581//270 582//270 +f 542//271 562//271 586//271 587//271 +f 561//272 541//272 583//272 588//272 +f 593//273 565//273 543//273 564//273 +f 565//274 594//274 566//274 +f 566//75 594//75 595//75 567//75 +f 567//75 596//75 568//75 545//75 +f 531//75 555//75 573//75 +f 575//266 550//266 572//266 599//266 +f 572//75 549//75 574//75 600//75 +f 574//267 573//267 554//267 578//267 +f 601//275 602//275 576//275 575//275 +f 576//77 603//77 577//77 551//77 +f 577//276 604//276 578//276 552//276 +f 598//277 553//277 579//277 605//277 +f 559//278 585//278 556//278 +f 580//270 607//270 581//270 558//270 +f 585//77 559//77 582//77 602//77 +f 582//279 581//279 608//279 603//279 +f 609//280 583//280 541//280 540//280 +f 610//281 584//281 560//281 +f 609//282 540//282 560//282 584//282 +f 610//283 560//283 556//283 585//283 +f 586//284 562//284 611//284 612//284 613//284 614//284 +f 615//285 587//285 586//285 616//285 617//285 618//285 +f 561//286 588//286 589//286 +f 583//287 619//287 620//287 588//287 +f 611//288 562//288 561//288 589//288 +f 623//289 565//289 593//289 624//289 +f 625//290 594//290 565//290 623//290 +f 594//75 626//75 627//75 595//75 +f 595//75 596//75 567//75 +f 596//75 628//75 606//75 568//75 +f 568//291 606//291 580//291 557//291 +f 601//275 575//275 599//275 629//275 +f 599//75 572//75 600//75 630//75 +f 600//276 574//276 578//276 604//276 +f 631//292 585//292 602//292 601//292 +f 602//77 582//77 603//77 576//77 +f 603//293 608//293 604//293 577//293 +f 632//294 579//294 587//294 615//294 +f 605//295 579//295 632//295 +f 580//296 606//296 633//296 +f 633//75 629//75 607//75 580//75 +f 607//279 630//279 608//279 581//279 +f 609//297 634//297 619//297 583//297 +f 610//298 635//298 636//298 584//298 +f 634//299 609//299 584//299 636//299 +f 610//300 585//300 631//300 635//300 +f 616//301 586//301 614//301 637//301 +f 612//301 611//301 638//301 +f 588//302 620//302 589//302 +f 639//287 640//287 620//287 619//287 +f 611//303 589//303 627//303 626//303 +f 624//304 593//304 622//304 +f 641//305 642//305 594//305 625//305 +f 594//306 642//306 643//306 626//306 +f 627//307 640//307 639//307 595//307 +f 595//308 639//308 645//308 596//308 +f 628//309 596//309 645//309 644//309 +f 606//310 628//310 646//310 633//310 +f 631//292 601//292 629//292 633//292 +f 629//75 599//75 630//75 607//75 +f 630//293 600//293 604//293 608//293 +f 645//297 639//297 619//297 634//297 +f 646//298 644//298 636//298 635//298 +f 634//299 636//299 644//299 645//299 +f 646//300 635//300 631//300 633//300 +f 638//301 611//301 647//301 648//301 +f 640//302 589//302 620//302 +f 643//311 649//311 650//311 647//311 611//311 626//311 +f 651//294 642//294 641//294 +f 652//285 643//285 642//285 651//285 653//285 654//285 +f 627//312 589//312 640//312 +f 646//313 628//313 644//313 +f 649//301 643//301 652//301 655//301 +f 656//285 657//285 658//285 659//285 660//285 +f 657//301 656//301 661//301 662//301 663//301 +f 658//285 657//285 664//285 665//285 666//285 +f 657//301 663//301 667//301 668//301 669//301 664//301 +usemtl Metal +f 459//314 507//314 529//314 484//314 +f 480//315 484//315 529//315 523//315 +f 553//316 547//316 805//316 806//316 +f 480//317 523//317 563//317 593//317 564//317 524//317 +f 507//318 547//318 548//318 529//318 +f 523//318 529//318 548//318 563//318 +f 548//51 547//51 553//51 569//51 570//51 571//51 +f 548//51 590//51 591//51 592//51 593//51 563//51 +f 548//319 571//319 597//319 +f 569//319 553//319 598//319 +f 548//320 597//320 621//320 590//320 +f 622//320 593//320 592//320 +f 547//321 507//321 804//321 805//321 +f 459//322 506//322 546//322 553//322 806//322 803//322 804//322 507//322 +usemtl Black +f 15//39 17//39 221//39 220//39 +f 46//108 45//108 55//108 56//108 +f 53//51 51//51 193//51 195//51 +f 43//106 41//106 51//106 53//106 +f 50//113 49//113 59//113 60//113 +f 47//109 46//109 56//109 57//109 +f 44//77 43//77 53//77 54//77 +f 42//112 50//112 60//112 52//112 +f 48//110 47//110 57//110 58//110 +f 45//107 44//107 54//107 55//107 +f 41//105 42//105 52//105 51//105 +f 49//75 48//75 58//75 59//75 +f 65//323 70//323 94//323 95//323 +f 78//324 71//324 98//324 89//324 +f 66//325 65//325 95//325 86//325 +f 71//326 74//326 81//326 98//326 +f 79//327 72//327 99//327 91//327 +f 67//328 62//328 82//328 88//328 +f 72//329 75//329 83//329 99//329 +f 80//330 73//330 100//330 93//330 +f 68//331 64//331 84//331 90//331 +f 73//332 76//332 85//332 100//332 +f 95//107 94//107 93//107 100//107 +f 96//110 92//110 91//110 99//110 +f 97//112 90//112 89//112 98//112 +f 94//77 88//77 87//77 93//77 +f 92//109 86//109 85//109 91//109 +f 90//113 84//113 83//113 89//113 +f 88//106 82//106 81//106 87//106 +f 86//108 95//108 100//108 85//108 +f 84//75 96//75 99//75 83//75 +f 82//105 97//105 98//105 81//105 +f 64//333 63//333 96//333 84//333 +f 77//334 80//334 93//334 87//334 +f 63//335 69//335 92//335 96//335 +f 62//336 61//336 97//336 82//336 +f 76//337 79//337 91//337 85//337 +f 61//338 68//338 90//338 97//338 +f 75//339 78//339 89//339 83//339 +f 70//340 67//340 88//340 94//340 +f 74//341 77//341 87//341 81//341 +f 69//342 66//342 86//342 92//342 +f 103//343 110//343 183//343 172//343 +f 115//344 118//344 175//344 169//344 +f 110//345 107//345 180//345 183//345 +f 102//346 109//346 182//346 170//346 +f 114//347 117//347 173//347 167//347 +f 109//348 106//348 178//348 182//348 +f 101//349 108//349 181//349 168//349 +f 113//350 116//350 171//350 186//350 +f 108//351 105//351 176//351 181//351 +f 120//352 113//352 186//352 179//352 +f 127//353 124//353 142//353 148//353 +f 132//354 135//354 143//354 159//354 +f 140//355 133//355 160//355 153//355 +f 128//356 125//356 144//356 150//356 +f 133//357 136//357 145//357 160//357 +f 129//358 126//358 146//358 152//358 +f 134//359 137//359 147//359 141//359 +f 130//360 127//360 148//360 154//360 +f 135//361 138//361 149//361 143//361 +f 121//362 128//362 150//362 157//362 +f 155//107 154//107 153//107 160//107 +f 156//110 152//110 151//110 159//110 +f 141//77 142//77 162//77 161//77 +f 154//77 148//77 147//77 153//77 +f 152//109 146//109 145//109 151//109 +f 150//113 144//113 143//113 149//113 +f 148//106 142//106 141//106 147//106 +f 146//108 155//108 160//108 145//108 +f 144//75 156//75 159//75 143//75 +f 149//51 158//51 166//51 163//51 +f 139//363 132//363 159//363 151//363 +f 131//364 134//364 141//364 158//364 +f 126//365 123//365 155//365 146//365 +f 138//366 131//366 158//366 149//366 +f 123//367 130//367 154//367 155//367 +f 125//368 122//368 156//368 144//368 +f 137//369 140//369 153//369 147//369 +f 122//370 129//370 152//370 156//370 +f 124//371 121//371 157//371 142//371 +f 136//372 139//372 151//372 145//372 +f 165//112 164//112 163//112 166//112 +f 162//105 165//105 166//105 161//105 +f 157//39 150//39 164//39 165//39 +f 158//51 141//51 161//51 166//51 +f 142//39 157//39 165//39 162//39 +f 150//75 149//75 163//75 164//75 +f 167//77 168//77 188//77 187//77 +f 170//75 182//75 185//75 169//75 +f 172//108 183//108 186//108 171//108 +f 174//106 168//106 167//106 173//106 +f 176//113 170//113 169//113 175//113 +f 178//109 172//109 171//109 177//109 +f 180//77 174//77 173//77 179//77 +f 176//75 175//75 189//75 190//75 +f 182//110 178//110 177//110 185//110 +f 183//107 180//107 179//107 186//107 +f 116//373 119//373 177//373 171//373 +f 104//374 101//374 168//374 174//374 +f 117//375 120//375 179//375 173//375 +f 105//376 102//376 170//376 176//376 +f 118//377 111//377 184//377 175//377 +f 106//378 103//378 172//378 178//378 +f 111//379 114//379 167//379 184//379 +f 119//380 112//380 185//380 177//380 +f 107//381 104//381 174//381 180//381 +f 112//382 115//382 169//382 185//382 +f 188//105 191//105 192//105 187//105 +f 191//112 190//112 189//112 192//112 +f 184//51 167//51 187//51 192//51 +f 168//39 181//39 191//39 188//39 +f 175//51 184//51 192//51 189//51 +f 181//39 176//39 190//39 191//39 +f 201//77 200//77 210//77 211//77 +f 60//51 59//51 201//51 202//51 +f 57//51 56//51 198//51 199//51 +f 54//51 53//51 195//51 196//51 +f 52//51 60//51 202//51 194//51 +f 58//51 57//51 199//51 200//51 +f 55//51 54//51 196//51 197//51 +f 51//51 52//51 194//51 193//51 +f 59//51 58//51 200//51 201//51 +f 56//51 55//51 197//51 198//51 +f 203//51 204//51 212//51 211//51 210//51 209//51 208//51 207//51 206//51 205//51 +f 198//112 197//112 207//112 208//112 +f 195//110 193//110 203//110 205//110 +f 202//107 201//107 211//107 212//107 +f 199//105 198//105 208//105 209//105 +f 196//75 195//75 205//75 206//75 +f 194//108 202//108 212//108 204//108 +f 200//106 199//106 209//106 210//106 +f 197//113 196//113 206//113 207//113 +f 193//109 194//109 204//109 203//109 +f 222//108 213//108 223//108 232//108 +f 13//39 15//39 220//39 219//39 +f 11//39 13//39 219//39 218//39 +f 9//39 11//39 218//39 217//39 +f 7//39 9//39 217//39 216//39 +f 1//39 3//39 214//39 213//39 +f 5//39 7//39 216//39 215//39 +f 3//39 5//39 215//39 214//39 +f 19//39 1//39 213//39 222//39 +f 17//39 19//39 222//39 221//39 +f 223//39 224//39 225//39 226//39 227//39 228//39 229//39 230//39 231//39 232//39 +f 219//106 220//106 230//106 229//106 +f 216//113 217//113 227//113 226//113 +f 213//109 214//109 224//109 223//109 +f 220//77 221//77 231//77 230//77 +f 217//112 218//112 228//112 227//112 +f 214//110 215//110 225//110 224//110 +f 221//107 222//107 232//107 231//107 +f 218//105 219//105 229//105 228//105 +f 215//75 216//75 226//75 225//75 +f 17//113 241//113 242//113 19//113 +f 19//112 242//112 233//112 1//112 +f 15//75 240//75 241//75 17//75 +f 13//110 239//110 240//110 15//110 +f 11//109 238//109 239//109 13//109 +f 9//108 237//108 238//108 11//108 +f 7//107 236//107 237//107 9//107 +f 5//77 235//77 236//77 7//77 +f 3//106 234//106 235//106 5//106 +f 1//105 233//105 234//105 3//105 +f 260//383 259//383 272//383 273//383 +f 268//384 285//384 272//384 259//384 +f 274//385 260//385 273//385 290//385 +f 272//77 291//77 292//77 273//77 +f 268//386 284//386 304//386 285//386 +f 293//387 274//387 290//387 309//387 +f 310//77 290//77 273//77 292//77 +f 285//388 311//388 291//388 272//388 +f 312//389 313//389 292//389 291//389 +f 302//386 328//386 304//386 284//386 +f 311//141 285//141 304//141 330//141 +f 314//390 293//390 309//390 338//390 +f 290//77 310//77 339//77 309//77 +f 310//391 292//391 313//391 340//391 +f 291//392 311//392 312//392 +f 312//39 341//39 342//39 313//39 +f 302//393 327//393 386//393 328//393 +f 357//141 330//141 304//141 328//141 +f 311//394 330//394 341//394 312//394 +f 314//395 338//395 396//395 343//395 +f 309//77 339//77 364//77 338//77 +f 340//396 365//396 339//396 310//396 +f 366//39 367//39 342//39 341//39 +f 368//397 340//397 313//397 342//397 +f 356//398 385//398 386//398 327//398 +f 328//399 386//399 387//399 357//399 +f 357//394 366//394 341//394 330//394 +f 365//396 397//396 364//396 339//396 +f 398//400 396//400 338//400 364//400 +f 340//401 368//401 399//401 365//401 +f 366//402 387//402 400//402 367//402 +f 368//397 342//397 367//397 401//397 +f 369//403 343//403 396//403 402//403 +f 384//404 421//404 385//404 356//404 +f 386//75 385//75 400//75 387//75 +f 387//405 366//405 357//405 +f 399//401 430//401 397//401 365//401 +f 397//406 398//406 364//406 +f 431//171 402//171 396//171 398//171 +f 401//401 432//401 399//401 368//401 +f 367//407 400//407 453//407 401//407 +f 369//403 402//403 433//403 403//403 +f 420//408 452//408 421//408 384//408 +f 453//75 400//75 385//75 421//75 +f 399//401 432//401 460//401 430//401 +f 431//409 398//409 397//409 430//409 +f 431//171 461//171 433//171 402//171 +f 401//410 453//410 462//410 432//410 +f 433//411 463//411 434//411 403//411 +f 434//412 463//412 452//412 420//412 +f 421//75 452//75 462//75 453//75 +f 432//410 462//410 485//410 460//410 +f 431//409 430//409 460//409 461//409 +f 461//413 485//413 463//413 433//413 +f 452//75 463//75 485//75 462//75 +f 460//414 485//414 461//414 +f 804//415 803//415 810//415 807//415 +f 810//416 809//416 813//416 814//416 +f 805//417 804//417 807//417 808//417 +f 803//418 806//418 809//418 810//418 +f 806//419 805//419 808//419 809//419 +f 814//420 813//420 812//420 811//420 +f 809//421 808//421 812//421 813//421 +f 807//422 810//422 814//422 811//422 +f 808//423 807//423 811//423 812//423 +usemtl Magazine +f 745//424 750//424 762//424 756//424 +f 765//77 760//77 757//77 761//77 +f 758//425 764//425 752//425 747//425 +f 759//426 746//426 743//426 755//426 +f 753//427 766//427 763//427 749//427 +f 743//428 744//428 745//428 +f 746//429 747//429 748//429 +f 749//430 750//430 751//430 +f 752//431 753//431 754//431 +f 755//432 756//432 757//432 +f 758//433 759//433 760//433 +f 761//434 762//434 763//434 +f 764//435 765//435 766//435 +f 743//436 746//436 748//436 744//436 +f 747//437 752//437 754//437 748//437 +f 753//438 749//438 751//438 754//438 +f 750//439 745//439 744//439 751//439 +f 752//440 764//440 766//440 753//440 +f 765//441 761//441 763//441 766//441 +f 762//442 750//442 749//442 763//442 +f 764//443 758//443 760//443 765//443 +f 759//444 755//444 757//444 760//444 +f 756//445 762//445 761//445 757//445 +f 758//446 747//446 746//446 759//446 +f 745//447 756//447 755//447 743//447 +f 748//75 754//75 751//75 744//75 diff --git a/assets/quaternius/models/SniperRifle.obj.import b/assets/quaternius/models/SniperRifle.obj.import new file mode 100644 index 0000000..0a2227a --- /dev/null +++ b/assets/quaternius/models/SniperRifle.obj.import @@ -0,0 +1,25 @@ +[remap] + +importer="wavefront_obj" +importer_version=1 +type="Mesh" +uid="uid://ce5q4u4m722kv" +path="res://.godot/imported/SniperRifle.obj-41dcedbb93cd893f0676f56a9c467849.mesh" + +[deps] + +files=["res://.godot/imported/SniperRifle.obj-41dcedbb93cd893f0676f56a9c467849.mesh"] + +source_file="res://assets/quaternius/models/SniperRifle.obj" +dest_files=["res://.godot/imported/SniperRifle.obj-41dcedbb93cd893f0676f56a9c467849.mesh", "res://.godot/imported/SniperRifle.obj-41dcedbb93cd893f0676f56a9c467849.mesh"] + +[params] + +generate_tangents=true +generate_lods=true +generate_shadow_mesh=true +generate_lightmap_uv2=false +generate_lightmap_uv2_texel_size=0.2 +scale_mesh=Vector3(1, 1, 1) +offset_mesh=Vector3(0, 0, 0) +force_disable_mesh_compression=false diff --git a/assets/quaternius/weapons/p90.tres b/assets/quaternius/weapons/p90.tres new file mode 100644 index 0000000..cedc25b --- /dev/null +++ b/assets/quaternius/weapons/p90.tres @@ -0,0 +1,21 @@ +[gd_resource type="Resource" script_class="Weapon" load_steps=4 format=3] + +[ext_resource type="Script" path="res://assets/kenney-fps/scripts/weapon.gd" id="1"] +[ext_resource type="PackedScene" path="res://assets/quaternius/weapons/p90.tscn" id="2"] +[ext_resource type="Texture2D" uid="uid://ce3lgq7foiusl" path="res://assets/kenney-fps/sprites/crosshair-repeater.png" id="3"] + +[resource] +script = ExtResource("1") +model = ExtResource("2") +crosshair = ExtResource("3") +rotation = Vector3(0, 180, 0) +muzzle_position = Vector3(0.1, -0.4, 1.5) +cooldown = 0.08 +max_distance = 15 +damage = 18 +spread = 1.0 +shot_count = 1 +knockback = 10 +min_knockback = Vector2(0.025, 0.025) +max_knockback = Vector2(0.045, 0.04) +sound_shoot = "assets/kenney-fps/sounds/blaster_repeater.ogg" diff --git a/assets/quaternius/weapons/p90.tscn b/assets/quaternius/weapons/p90.tscn new file mode 100644 index 0000000..be1c3aa --- /dev/null +++ b/assets/quaternius/weapons/p90.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://quaternius_p90_scene"] + +[ext_resource type="ArrayMesh" path="res://assets/quaternius/models/P90.obj" id="1"] + +[node name="P90" type="MeshInstance3D"] +mesh = ExtResource("1") diff --git a/assets/quaternius/weapons/pistol.tres b/assets/quaternius/weapons/pistol.tres new file mode 100644 index 0000000..b16adb0 --- /dev/null +++ b/assets/quaternius/weapons/pistol.tres @@ -0,0 +1,21 @@ +[gd_resource type="Resource" script_class="Weapon" load_steps=4 format=3] + +[ext_resource type="Script" path="res://assets/kenney-fps/scripts/weapon.gd" id="1"] +[ext_resource type="PackedScene" path="res://assets/quaternius/weapons/pistol.tscn" id="2"] +[ext_resource type="Texture2D" uid="uid://2jld33y6h5pq" path="res://assets/kenney-fps/sprites/crosshair.png" id="3"] + +[resource] +script = ExtResource("1") +model = ExtResource("2") +crosshair = ExtResource("3") +rotation = Vector3(0, 180, 0) +muzzle_position = Vector3(0.1, -0.4, 1.5) +cooldown = 0.3 +max_distance = 15 +damage = 25 +spread = 0.5 +shot_count = 1 +knockback = 15 +min_knockback = Vector2(0.025, 0.025) +max_knockback = Vector2(0.045, 0.04) +sound_shoot = "assets/kenney-fps/sounds/blaster.ogg" diff --git a/assets/quaternius/weapons/pistol.tscn b/assets/quaternius/weapons/pistol.tscn new file mode 100644 index 0000000..e7978b4 --- /dev/null +++ b/assets/quaternius/weapons/pistol.tscn @@ -0,0 +1,5 @@ +[gd_scene format=3] +[ext_resource type="ArrayMesh" path="res://assets/quaternius/models/Pistol.obj" id="1"] + +[node name="Pistol" type="MeshInstance3D"] +mesh = ExtResource("1") diff --git a/assets/quaternius/weapons/revolver.tres b/assets/quaternius/weapons/revolver.tres new file mode 100644 index 0000000..5379368 --- /dev/null +++ b/assets/quaternius/weapons/revolver.tres @@ -0,0 +1,21 @@ +[gd_resource type="Resource" script_class="Weapon" load_steps=4 format=3] + +[ext_resource type="Script" path="res://assets/kenney-fps/scripts/weapon.gd" id="1"] +[ext_resource type="PackedScene" path="res://assets/quaternius/weapons/revolver.tscn" id="2"] +[ext_resource type="Texture2D" uid="uid://2jld33y6h5pq" path="res://assets/kenney-fps/sprites/crosshair.png" id="3"] + +[resource] +script = ExtResource("1") +model = ExtResource("2") +crosshair = ExtResource("3") +rotation = Vector3(0, 180, 0) +muzzle_position = Vector3(0.1, -0.4, 1.5) +cooldown = 0.6 +max_distance = 15 +damage = 50 +spread = 0.3 +shot_count = 1 +knockback = 25 +min_knockback = Vector2(0.025, 0.025) +max_knockback = Vector2(0.045, 0.04) +sound_shoot = "assets/kenney-fps/sounds/blaster.ogg" diff --git a/assets/quaternius/weapons/revolver.tscn b/assets/quaternius/weapons/revolver.tscn new file mode 100644 index 0000000..9657bb8 --- /dev/null +++ b/assets/quaternius/weapons/revolver.tscn @@ -0,0 +1,5 @@ +[gd_scene format=3] +[ext_resource type="ArrayMesh" path="res://assets/quaternius/models/Revolver.obj" id="1"] + +[node name="Revolver" type="MeshInstance3D"] +mesh = ExtResource("1") diff --git a/assets/quaternius/weapons/rifle.tres b/assets/quaternius/weapons/rifle.tres new file mode 100644 index 0000000..3d71efb --- /dev/null +++ b/assets/quaternius/weapons/rifle.tres @@ -0,0 +1,21 @@ +[gd_resource type="Resource" script_class="Weapon" load_steps=4 format=3] + +[ext_resource type="Script" path="res://assets/kenney-fps/scripts/weapon.gd" id="1"] +[ext_resource type="PackedScene" path="res://assets/quaternius/weapons/rifle.tscn" id="2"] +[ext_resource type="Texture2D" uid="uid://2jld33y6h5pq" path="res://assets/kenney-fps/sprites/crosshair.png" id="3"] + +[resource] +script = ExtResource("1") +model = ExtResource("2") +crosshair = ExtResource("3") +rotation = Vector3(0, 180, 0) +muzzle_position = Vector3(0.1, -0.4, 1.5) +cooldown = 0.12 +max_distance = 15 +damage = 30 +spread = 0.4 +shot_count = 1 +knockback = 18 +min_knockback = Vector2(0.025, 0.025) +max_knockback = Vector2(0.045, 0.04) +sound_shoot = "assets/kenney-fps/sounds/blaster.ogg" diff --git a/assets/quaternius/weapons/rifle.tscn b/assets/quaternius/weapons/rifle.tscn new file mode 100644 index 0000000..72da2a6 --- /dev/null +++ b/assets/quaternius/weapons/rifle.tscn @@ -0,0 +1,5 @@ +[gd_scene format=3] +[ext_resource type="ArrayMesh" path="res://assets/quaternius/models/Rifle.obj" id="1"] + +[node name="Rifle" type="MeshInstance3D"] +mesh = ExtResource("1") diff --git a/assets/quaternius/weapons/shotgun.tres b/assets/quaternius/weapons/shotgun.tres new file mode 100644 index 0000000..a9f11eb --- /dev/null +++ b/assets/quaternius/weapons/shotgun.tres @@ -0,0 +1,21 @@ +[gd_resource type="Resource" script_class="Weapon" load_steps=4 format=3] + +[ext_resource type="Script" path="res://assets/kenney-fps/scripts/weapon.gd" id="1"] +[ext_resource type="PackedScene" path="res://assets/quaternius/weapons/shotgun.tscn" id="2"] +[ext_resource type="Texture2D" uid="uid://2jld33y6h5pq" path="res://assets/kenney-fps/sprites/crosshair.png" id="3"] + +[resource] +script = ExtResource("1") +model = ExtResource("2") +crosshair = ExtResource("3") +rotation = Vector3(0, 180, 0) +muzzle_position = Vector3(0.1, -0.4, 1.5) +cooldown = 0.8 +max_distance = 15 +damage = 20 +spread = 1.5 +shot_count = 6 +knockback = 30 +min_knockback = Vector2(0.025, 0.025) +max_knockback = Vector2(0.045, 0.04) +sound_shoot = "assets/kenney-fps/sounds/blaster.ogg" diff --git a/assets/quaternius/weapons/shotgun.tscn b/assets/quaternius/weapons/shotgun.tscn new file mode 100644 index 0000000..edd6ccf --- /dev/null +++ b/assets/quaternius/weapons/shotgun.tscn @@ -0,0 +1,5 @@ +[gd_scene format=3] +[ext_resource type="ArrayMesh" path="res://assets/quaternius/models/Shotgun.obj" id="1"] + +[node name="Shotgun" type="MeshInstance3D"] +mesh = ExtResource("1") diff --git a/assets/quaternius/weapons/sniperrifle.tres b/assets/quaternius/weapons/sniperrifle.tres new file mode 100644 index 0000000..9a2e4f7 --- /dev/null +++ b/assets/quaternius/weapons/sniperrifle.tres @@ -0,0 +1,21 @@ +[gd_resource type="Resource" script_class="Weapon" load_steps=4 format=3] + +[ext_resource type="Script" path="res://assets/kenney-fps/scripts/weapon.gd" id="1"] +[ext_resource type="PackedScene" path="res://assets/quaternius/weapons/sniperrifle.tscn" id="2"] +[ext_resource type="Texture2D" uid="uid://ce3lgq7foiusl" path="res://assets/kenney-fps/sprites/crosshair-repeater.png" id="3"] + +[resource] +script = ExtResource("1") +model = ExtResource("2") +crosshair = ExtResource("3") +rotation = Vector3(0, 180, 0) +muzzle_position = Vector3(0.1, -0.4, 1.5) +cooldown = 1.2 +max_distance = 15 +damage = 90 +spread = 0.1 +shot_count = 1 +knockback = 35 +min_knockback = Vector2(0.025, 0.025) +max_knockback = Vector2(0.045, 0.04) +sound_shoot = "assets/kenney-fps/sounds/blaster_repeater.ogg" diff --git a/assets/quaternius/weapons/sniperrifle.tscn b/assets/quaternius/weapons/sniperrifle.tscn new file mode 100644 index 0000000..9bee30d --- /dev/null +++ b/assets/quaternius/weapons/sniperrifle.tscn @@ -0,0 +1,5 @@ +[gd_scene format=3] +[ext_resource type="ArrayMesh" path="res://assets/quaternius/models/SniperRifle.obj" id="1"] + +[node name="SniperRifle" type="MeshInstance3D"] +mesh = ExtResource("1") diff --git a/examples/multiplayer-fps/scripts/player-input.gd b/examples/multiplayer-fps/scripts/player-input.gd index 636d4ea..cc9fb32 100644 --- a/examples/multiplayer-fps/scripts/player-input.gd +++ b/examples/multiplayer-fps/scripts/player-input.gd @@ -21,6 +21,12 @@ var _slot_2_latch := false var _slot_3_latch := false var _slot_4_latch := false +# Direct keyboard state (bypasses Input.get_axis() for reliability) +var _key_w := false +var _key_s := false +var _key_a := false +var _key_d := false + # Input variables (frame-rate mouse accumulator) var mouse_rotation: Vector2 = Vector2.ZERO @@ -43,6 +49,7 @@ func _notification(what): if what == NOTIFICATION_WM_WINDOW_FOCUS_IN: Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) override_mouse = false + print("[INPUT] Window focus gained — recaptured mouse") func _input(event: InputEvent) -> void: if !is_multiplayer_authority(): return @@ -73,14 +80,36 @@ func _input(event: InputEvent) -> void: if event.is_action_pressed("weapon_slot_4"): _slot_4_latch = true + # Track WASD directly from key events (backup for Input.get_axis()) + if event is InputEventKey and event.keycode != 0: + match event.keycode: + KEY_W: _key_w = event.pressed + KEY_S: _key_s = event.pressed + KEY_A: _key_a = event.pressed + KEY_D: _key_d = event.pressed + # Also check physical keycode as fallback + match event.physical_keycode: + KEY_W: _key_w = event.pressed + KEY_S: _key_s = event.pressed + KEY_A: _key_a = event.pressed + KEY_D: _key_d = event.pressed + func _gather(): if !is_setup: print("[INPUT DEBUG] _gather first call - setting up") setup() - - # Movement (continuous) + + # Movement: try Input.get_axis() first, fall back to direct key tracking var mx = Input.get_axis("move_west", "move_east") var mz = Input.get_axis("move_north", "move_south") + + # If Input.get_axis() returns 0 but keys are pressed via event tracking, use event tracking + if mx == 0.0 and mz == 0.0: + if _key_d: mx = 1.0 + elif _key_a: mx = -1.0 + if _key_s: mz = 1.0 + elif _key_w: mz = -1.0 + var old_mv = movement movement = Vector3(mx, 0, mz) if movement != old_mv and (mx != 0 or mz != 0): @@ -131,3 +160,7 @@ func setup(): big_gun.hide() hud.show() Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + # Ensure window has keyboard focus for WASD + get_window().call_deferred("grab_focus") + DisplayServer.call_deferred("window_move_to_foreground") + print("[INPUT] Setup complete — camera active, mouse captured, focus grabbed") diff --git a/examples/multiplayer-fps/scripts/player-spawner.gd b/examples/multiplayer-fps/scripts/player-spawner.gd index c66d6fd..be773f4 100644 --- a/examples/multiplayer-fps/scripts/player-spawner.gd +++ b/examples/multiplayer-fps/scripts/player-spawner.gd @@ -94,8 +94,9 @@ func _handle_new_peer(id: int): if bomb: bomb.sync_to_peer(id) if avatars.size() <= 2: - # First opponent joined — restart round so both spawn alive - round_manager.start_round() + # Dedicated server handles match start via headless_server.gd + if not _dedicated_server: + round_manager.start_round() else: # 3+ players: sync state, spectate until next round round_manager.sync_to_peer(id) diff --git a/examples/multiplayer-fps/scripts/player.gd b/examples/multiplayer-fps/scripts/player.gd index 7d9ba14..490fa35 100644 --- a/examples/multiplayer-fps/scripts/player.gd +++ b/examples/multiplayer-fps/scripts/player.gd @@ -133,7 +133,14 @@ func _process(_delta: float): if _is_local and input: var mx := Input.get_axis("move_west", "move_east") var mz := Input.get_axis("move_north", "move_south") - get_window().title = "TS [mv=%.1f,%.1f] [sl=%s%s%s%s] [fire=%s]" % [mx, mz, input.slot_1, input.slot_2, input.slot_3, input.slot_4, input.fire_held] + var dead := death_tick >= 0 + var frozen := round_manager != null and round_manager.freeze_end_tick >= 0 and NetworkTime.tick < round_manager.freeze_end_tick + var hp_str := str(health) + var rm_ok := round_manager != null + # Weapon model load status from weapon_manager + var knife_ok := weapon_manager != null and weapon_manager.has_knife_model() + var gun_ok := weapon_manager != null and weapon_manager.has_gun_model() + get_window().title = "TS [mv=%.1f,%.1f] hp=%s d=%s f=%s k=%s g=%s [fire=%s]" % [mx, mz, hp_str, dead, frozen, knife_ok, gun_ok, input.fire_held] # Smooth position interpolation between ticks var f := NetworkTime.tick_factor diff --git a/examples/multiplayer-fps/scripts/round-manager.gd b/examples/multiplayer-fps/scripts/round-manager.gd index 58c6013..413ea73 100644 --- a/examples/multiplayer-fps/scripts/round-manager.gd +++ b/examples/multiplayer-fps/scripts/round-manager.gd @@ -8,7 +8,7 @@ signal round_started(round_number: int) signal round_ended(winner: TeamManager.Team) signal player_killed(victim_id: int, killer_id: int, weapon_id: int, kill_tick: int) -@export var freeze_time: float = 5.0 +@export var freeze_time: float = 0.0 @export var round_time: float = 115.0 @export var round_end_time: float = 5.0 @export var max_rounds: int = 24 diff --git a/examples/multiplayer-fps/scripts/weapon_manager.gd b/examples/multiplayer-fps/scripts/weapon_manager.gd index 94f96f8..90df756 100644 --- a/examples/multiplayer-fps/scripts/weapon_manager.gd +++ b/examples/multiplayer-fps/scripts/weapon_manager.gd @@ -26,6 +26,7 @@ var _pending_grenades: Array[Dictionary] = [] # Buffered throws, consumed in _a # Weapon models (loaded at runtime) var _knife_model: Node3D +var _pistol_model: Node3D var _gun_model: Node3D var _grenade_model: Node3D var _current_visible_slot: int = -1 @@ -40,17 +41,61 @@ func _ready(): _load_weapon_models() func _load_weapon_models(): - # Knife model - var knife_scene := load("res://examples/multiplayer-fps/models/knife.fbx") as PackedScene - if knife_scene: - _knife_model = knife_scene.instantiate() - _knife_model.scale = Vector3(0.003, 0.003, 0.003) - _knife_model.position = Vector3(0.15, -0.22, -0.35) - _knife_model.rotation_degrees = Vector3(-90, 180, 0) - add_child(_knife_model) + # Weapon models from Quaternius FPS Pack — GLB format, reliable import + + # Slot 0 (melee) + Slot 1 (pistol): Use Quaternius Pistol model + var pistol_scene := load("res://assets/quaternius/models/Pistol.glb") as PackedScene + if pistol_scene: + # Slot 0: small pistol as melee visual + var knife = pistol_scene.instantiate() + knife.scale = Vector3(0.35, 0.35, 0.35) + knife.position = Vector3(0.08, -0.18, -0.28) + knife.rotation_degrees = Vector3(-90, 180, 0) + add_child(knife) + _knife_model = knife _knife_model.hide() + + # Slot 1: same pistol model, slightly different position + var pistol = pistol_scene.instantiate() + pistol.scale = Vector3(0.35, 0.35, 0.35) + pistol.position = Vector3(0.08, -0.18, -0.28) + pistol.rotation_degrees = Vector3(-90, 180, 0) + add_child(pistol) + _pistol_model = pistol + _pistol_model.hide() + else: + print("[WM] Pistol model not available — using placeholder") + for slot in [0, 1]: + var box := MeshInstance3D.new() + box.mesh = BoxMesh.new() + box.mesh.size = Vector3(0.3, 0.05, 0.02) + box.position = Vector3(0.15, -0.22, -0.35) + box.rotation_degrees = Vector3(-90, 0, 0) + add_child(box) + if slot == 0: + _knife_model = box + else: + _pistol_model = box + box.hide() - # Grenade model + # Slot 2 (primary rifle): Use Quaternius Rifle model + var rifle_scene := load("res://assets/quaternius/models/Rifle.glb") as PackedScene + if not rifle_scene: + rifle_scene = load("res://assets/quaternius/models/P90.glb") as PackedScene + if rifle_scene: + var rifle = rifle_scene.instantiate() + rifle.scale = Vector3(0.35, 0.35, 0.35) + rifle.position = Vector3(0.06, -0.16, -0.25) + rifle.rotation_degrees = Vector3(-90, 180, 0) + add_child(rifle) + if _gun_model: + _gun_model.hide() + _gun_model = rifle + _gun_model.hide() + else: + print("[WM] Rifle model not available — using placeholder TinyGun") + + # Grenade model (keep existing) var grenade_scene := load("res://examples/multiplayer-fps/models/grenade.glb") as PackedScene if grenade_scene: _grenade_model = grenade_scene.instantiate() @@ -59,21 +104,7 @@ func _load_weapon_models(): add_child(_grenade_model) _grenade_model.hide() - # Gun model — replace placeholder box with Kenney blaster - var gun_scene := load("res://assets/kenney/models/blaster.glb") as PackedScene - if gun_scene: - var blaster = gun_scene.instantiate() - blaster.scale = Vector3(0.003, 0.003, 0.003) - blaster.position = Vector3(0.09, -0.18, -0.3) - blaster.rotation_degrees = Vector3(-90, 180, 0) - add_child(blaster) - # Hide the old box mesh, use blaster instead - if _gun_model: - _gun_model.hide() - _gun_model = blaster - _gun_model.hide() - - # Knife sound + # Knife slash sound var slash_stream := load("res://examples/multiplayer-fps/sounds/knife/knife_slash1.wav") if slash_stream: _knife_sound = AudioStreamPlayer3D.new() @@ -87,14 +118,18 @@ func _process(_delta: float): _current_visible_slot = active_slot if _knife_model: _knife_model.visible = (active_slot == 0) + if _pistol_model: + _pistol_model.visible = (active_slot == 1) if _gun_model: - _gun_model.visible = (active_slot == 1 or active_slot == 2) + _gun_model.visible = (active_slot == 2) if _grenade_model: _grenade_model.visible = (active_slot == 3) func hide_weapons(): if _knife_model: _knife_model.hide() + if _pistol_model: + _pistol_model.hide() if _gun_model: _gun_model.hide() if _grenade_model: @@ -104,6 +139,12 @@ func hide_weapons(): func show_weapons(): _current_visible_slot = -1 # Force refresh on next _process +# Debug helpers for window title +func has_knife_model() -> bool: + return _knife_model != null +func has_gun_model() -> bool: + return _gun_model != null + func get_active_weapon() -> WeaponData: var wid := inventory[active_slot] if wid == 0: diff --git a/examples/shared/scripts/lan-bootstrapper.gd b/examples/shared/scripts/lan-bootstrapper.gd index 6976eb0..8ad9f43 100644 --- a/examples/shared/scripts/lan-bootstrapper.gd +++ b/examples/shared/scripts/lan-bootstrapper.gd @@ -83,7 +83,7 @@ func _ensure_input_focus() -> void: ## Force the game window to have keyboard focus and captured mouse. ## On Windows GUI exports, the window may not hold keyboard focus after ## the connection UI is dismissed, causing Input.get_axis() to return 0. - OS.move_to_foreground() + DisplayServer.window_move_to_foreground() Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) # Deferred retry after window settles get_window().call_deferred("grab_focus") diff --git a/export_presets.cfg b/export_presets.cfg index 39d4133..efb715b 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -18,15 +18,15 @@ patch_delta_exclude_filters="" encryption_include_filters="" encryption_exclude_filters="" seed=0 -encrypt_pck=true +encrypt_pck=false encrypt_directory=false -script_export_mode=2 +script_export_mode=1 [preset.0.options] custom_template/debug="" custom_template/release="" -debug/export_console_wrapper=0 +debug/export_console_wrapper=2 binary_format/embed_pck=true binary_format/architecture="x86_64" texture_format/s3tc_bptc=true @@ -69,9 +69,9 @@ patch_delta_exclude_filters="" encryption_include_filters="" encryption_exclude_filters="" seed=0 -encrypt_pck=true +encrypt_pck=false encrypt_directory=false -script_export_mode=2 +script_export_mode=1 [preset.1.options] diff --git a/godot-mcp-runtime-3.1.2.tgz b/godot-mcp-runtime-3.1.2.tgz new file mode 100644 index 0000000..e7016f9 Binary files /dev/null and b/godot-mcp-runtime-3.1.2.tgz differ diff --git a/package/LICENSE b/package/LICENSE new file mode 100644 index 0000000..83f949f --- /dev/null +++ b/package/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025-2026 Owen Sterling + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package/README.md b/package/README.md new file mode 100644 index 0000000..3611890 --- /dev/null +++ b/package/README.md @@ -0,0 +1,168 @@ +# Godot MCP Runtime + +

+ godot-runtime-mcp MCP server +

+ +

+ MCP Server + npm version + npm downloads + License: MIT + Node.js +

+ +A lightweight [MCP](https://modelcontextprotocol.io/) server that pairs comprehensive headless editing with full runtime control over a [Godot](https://godotengine.org/) 4.x project. Scene, node, autoload, and validation ops cover everything short of the most niche corners of the engine; the runtime bridge adds screenshots, input simulation, UI discovery, and live GDScript against the running scene tree. + +

Agent driving a Godot game via MCP runtime tools

+ +

The AI doesn't just write your game, it can check its work.

+
+ +- **Headless editing** — scenes, nodes, scripts, signals, validation, no editor window +- **Runtime control** — screenshots, input simulation, UI discovery, and live GDScript against the running game +- **Zero footprint** — no Godot addon, no project commits, auto-cleanup on shutdown + +**No addon required.** Most Godot MCP servers that offer runtime support ship as a Godot addon, something you install into your project, commit to version control, and manage as a dependency. Use npx and there's no install or setup needed. + +Think of it as [Playwright MCP](https://github.com/microsoft/playwright-mcp), but for Godot. This does the same thing for games: run the project, take a screenshot, simulate input, read what's on screen, execute a script against the live scene tree. The agent closes the loop on its own changes rather than handing off to you to verify. + +> [!NOTE] +> This is not a playtesting replacement. It doesn't catch the subtle feel issues that only a human notices, and it won't tell you if your game is fun. What it does is let an agent confirm that a scene loads, a button responds, a value updated, a script ran without errors. The ability to check work is crucial for AI driven workflows. + +## Contents + +- [What It Does](#what-it-does) +- [Quick Start](#quick-start) +- [Docs](#docs) +- [Acknowledgments](#acknowledgments) +- [License](#license) + +## What It Does + +**Built for agents.** Every tool is purpose-built and self-documenting. When something fails, the response tells the agent how to fix it; when something succeeds, it points toward the next step. The result is an AI that stays unstuck and self-corrects without needing you to nudge it along. + +**Headless editing.** Create scenes, add nodes, set properties, attach scripts, connect signals, validate GDScript. All the standard operations, no editor window required. + +**Runtime bridge.** When `run_project` or `attach_project` is called, the server injects `McpBridge` as an autoload. This opens a localhost-only TCP listener (both auto-select a free port when `bridgePort` is omitted; pass `bridgePort` to pin a specific port) and enables: + +- **Screenshots:** Capture the viewport — by default returns a 960x540 preview inline plus the full PNG on disk; use `responseMode: 'full'` for pixel-perfect or `'path_only'` to skip the inline image +- **Input simulation:** Batched sequences of key presses, mouse clicks, mouse motion, UI element clicks by name or path, Godot action events, and timed waits +- **UI discovery:** Walk the live scene tree and collect every visible Control node with its position, type, text content, and disabled state +- **Live script execution:** Compile and run arbitrary GDScript with full SceneTree access while the game is running + +**Background mode.** Pass `background: true` to `run_project` and the Godot window moves off-screen (positioned at `(-9999, -9999)`) with physical input blocked: borderless, unfocusable, mouse-passthrough. Programmatic input, screenshots, and all runtime tools work exactly the same. Useful for automated agent-driven testing where the window shouldn't be visible or interactive. + +**Manual attach mode.** When something other than MCP launches the game (a CI pipeline, an external debugger, your own shell), call `attach_project` first. It injects the bridge and marks the project active without spawning Godot, so when you launch the game manually, runtime tools work against it. Use `detach_project` when done. + +> [!IMPORTANT] +> `get_debug_output` is unavailable in attached mode. stdout and stderr only flow through processes MCP started itself, so when Godot is launched externally there's no captured output to return. Use `run_project` if you need the debug stream. + +The bridge cleans itself up automatically when `stop_project` or `detach_project` is called. No leftover autoloads, no modified project files. + +## Quick Start + +### Prerequisites + +- [Node.js](https://nodejs.org/) v20+ +- [Godot 4.x](https://godotengine.org/) + +That's it. No Godot addon, no project modifications. + +### Configure Your MCP Client + +Add the following to your MCP client config. Works with Claude Code, Claude Desktop, Cursor, or any MCP-compatible client. + +**Zero-install via npx (recommended):** + +```json +{ + "mcpServers": { + "godot": { + "command": "npx", + "args": ["-y", "godot-mcp-runtime"], + "env": { + "GODOT_PATH": "" + } + } + } +} +``` + +**Or install globally:** + +```bash +npm install -g godot-mcp-runtime +``` + +```json +{ + "mcpServers": { + "godot": { + "command": "godot-mcp-runtime", + "env": { + "GODOT_PATH": "" + } + } + } +} +``` + +**Or clone from source:** + +```bash +git clone https://github.com/Erodenn/godot-mcp-runtime.git +cd godot-mcp-runtime +npm install +npm run build +``` + +```json +{ + "mcpServers": { + "godot": { + "command": "node", + "args": ["/godot-mcp-runtime/dist/index.js"], + "env": { + "GODOT_PATH": "" + } + } + } +} +``` + +> [!TIP] +> **Prefer pnpm?** All three install paths work with pnpm. Substitute `pnpm dlx godot-mcp-runtime` for `npx -y godot-mcp-runtime`, `pnpm add -g godot-mcp-runtime` for the global install, or `pnpm install && pnpm run build` for the source build. pnpm ships stronger defaults against npm supply-chain attacks; see [pnpm's supply chain security guide](https://pnpm.io/supply-chain-security). + +If Godot is on your `PATH`, you can omit `GODOT_PATH` entirely. The server will auto-detect it. Set `"DEBUG": "true"` in `env` for verbose logging. + +> [!IMPORTANT] +> **Windows path gotchas.** `GODOT_PATH` must point at the Godot executable itself, not its install folder. Backslashes in JSON must be escaped or replaced with forward slashes: +> +> ```json +> "GODOT_PATH": "D:\\Godot\\Godot_v4.4-stable_win64.exe" +> // or equivalently +> "GODOT_PATH": "D:/Godot/Godot_v4.4-stable_win64.exe" +> ``` +> +> Setting the variable from a wrapper `.bat` does not propagate to the MCP server — the path must live in the client's `env` block above. + +### Verify + +Ask your AI assistant to call `get_project_info`. If it returns a Godot version string (e.g., `4.4.stable`), you're connected and working. + +## Docs + +- [`docs/tools.md`](docs/tools.md) — full tool reference, grouped by category +- [`docs/tool-authoring.md`](docs/tool-authoring.md) — standards for adding or modifying tools +- [`docs/architecture.md`](docs/architecture.md) — source layout, bridge sequence diagram, lifecycle steps, runtime artifact behavior + +## Acknowledgments + +Built on the foundation laid by [Coding-Solo/godot-mcp](https://github.com/Coding-Solo/godot-mcp) for headless Godot operations. + +Developed with [Claude Code](https://claude.ai/code). + +## License + +[MIT](LICENSE) diff --git a/package/dist/dispatch.d.ts b/package/dist/dispatch.d.ts new file mode 100644 index 0000000..b33cb02 --- /dev/null +++ b/package/dist/dispatch.d.ts @@ -0,0 +1,16 @@ +/** + * Tool dispatch table. + * + * Maps every MCP tool name to a handler that takes the runner + raw args and + * returns the tool response. Extracted from index.ts so tests can exercise + * dispatch as a pure data structure (no Server / stdio / lifecycle setup). + * + * Behavioral contract preserved from the original switch in index.ts: + * - Each name routes to the same handler it did before. + * - Unknown tool names throw McpError(MethodNotFound, ...) — see + * `dispatchToolCall`. + */ +import type { GodotRunner, OperationParams, ToolHandler, ToolResponse } from './utils/godot-runner.js'; +export declare const toolDispatch: Record; +export declare function dispatchToolCall(runner: GodotRunner, toolName: string, args: OperationParams): Promise; +//# sourceMappingURL=dispatch.d.ts.map \ No newline at end of file diff --git a/package/dist/dispatch.d.ts.map b/package/dist/dispatch.d.ts.map new file mode 100644 index 0000000..c967270 --- /dev/null +++ b/package/dist/dispatch.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,YAAY,EACb,MAAM,yBAAyB,CAAC;AAsDjC,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CA4CpD,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,YAAY,CAAC,CAMvB"} \ No newline at end of file diff --git a/package/dist/dispatch.js b/package/dist/dispatch.js new file mode 100644 index 0000000..689282b --- /dev/null +++ b/package/dist/dispatch.js @@ -0,0 +1,69 @@ +/** + * Tool dispatch table. + * + * Maps every MCP tool name to a handler that takes the runner + raw args and + * returns the tool response. Extracted from index.ts so tests can exercise + * dispatch as a pure data structure (no Server / stdio / lifecycle setup). + * + * Behavioral contract preserved from the original switch in index.ts: + * - Each name routes to the same handler it did before. + * - Unknown tool names throw McpError(MethodNotFound, ...) — see + * `dispatchToolCall`. + */ +import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js'; +import { handleLaunchEditor, handleRunProject, handleAttachProject, handleDetachProject, handleGetDebugOutput, handleStopProject, handleTakeScreenshot, handleSimulateInput, handleGetUiElements, handleRunScript, } from './tools/runtime-tools.js'; +import { handleListAutoloads, handleAddAutoload, handleRemoveAutoload, handleUpdateAutoload, } from './tools/autoload-tools.js'; +import { handleListProjects, handleGetProjectInfo, handleGetProjectFiles, handleSearchProject, handleGetSceneDependencies, handleGetProjectSettings, } from './tools/project-tools.js'; +import { handleCreateScene, handleAddNode, handleLoadSprite, handleSaveScene, handleExportMeshLibrary, handleBatchSceneOperations, } from './tools/scene-tools.js'; +import { handleDeleteNodes, handleSetNodeProperties, handleGetNodeProperties, handleAttachScript, handleGetSceneTree, handleDuplicateNode, handleGetNodeSignals, handleConnectSignal, handleDisconnectSignal, } from './tools/node-tools.js'; +import { handleValidate } from './tools/validate-tools.js'; +export const toolDispatch = { + // Project tools + launch_editor: handleLaunchEditor, + run_project: handleRunProject, + attach_project: handleAttachProject, + detach_project: handleDetachProject, + get_debug_output: handleGetDebugOutput, + stop_project: handleStopProject, + list_projects: (_runner, args) => handleListProjects(args), + get_project_info: handleGetProjectInfo, + take_screenshot: handleTakeScreenshot, + simulate_input: handleSimulateInput, + get_ui_elements: handleGetUiElements, + run_script: handleRunScript, + list_autoloads: (_runner, args) => handleListAutoloads(args), + add_autoload: (_runner, args) => handleAddAutoload(args), + remove_autoload: (_runner, args) => handleRemoveAutoload(args), + update_autoload: (_runner, args) => handleUpdateAutoload(args), + get_project_files: (_runner, args) => handleGetProjectFiles(args), + search_project: (_runner, args) => handleSearchProject(args), + get_scene_dependencies: (_runner, args) => handleGetSceneDependencies(args), + get_project_settings: (_runner, args) => handleGetProjectSettings(args), + // Scene tools + create_scene: handleCreateScene, + add_node: handleAddNode, + load_sprite: handleLoadSprite, + save_scene: handleSaveScene, + export_mesh_library: handleExportMeshLibrary, + batch_scene_operations: handleBatchSceneOperations, + // Node tools + delete_nodes: handleDeleteNodes, + set_node_properties: handleSetNodeProperties, + get_node_properties: handleGetNodeProperties, + attach_script: handleAttachScript, + get_scene_tree: handleGetSceneTree, + duplicate_node: handleDuplicateNode, + get_node_signals: handleGetNodeSignals, + connect_signal: handleConnectSignal, + disconnect_signal: handleDisconnectSignal, + // Validate tools + validate: handleValidate, +}; +export async function dispatchToolCall(runner, toolName, args) { + const handler = toolDispatch[toolName]; + if (!handler) { + throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`); + } + return await handler(runner, args); +} +//# sourceMappingURL=dispatch.js.map \ No newline at end of file diff --git a/package/dist/dispatch.js.map b/package/dist/dispatch.js.map new file mode 100644 index 0000000..824250f --- /dev/null +++ b/package/dist/dispatch.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/index.d.ts b/package/dist/index.d.ts new file mode 100644 index 0000000..5e55fc8 --- /dev/null +++ b/package/dist/index.d.ts @@ -0,0 +1,11 @@ +#!/usr/bin/env node +/** + * Godot MCP Server + * + * This MCP server provides tools for interacting with the Godot game engine. + * It enables AI assistants to launch the Godot editor, run Godot projects, + * capture debug output, manipulate scenes and nodes, and more. + */ +export declare const allToolDefinitions: import("./utils/godot-runner.js").ToolDefinition[]; +export declare const serverInstructions = "Godot MCP Server \u2014 AI-driven Godot 4.x project manipulation.\n\nTool categories:\n- Project management: launch_editor, run_project, attach_project, detach_project, stop_project, get_debug_output, list_projects, get_project_info\n- Scene editing (headless): create_scene, add_node, load_sprite, save_scene, export_mesh_library, batch_scene_operations\n- Node editing (headless): delete_nodes, set_node_properties, get_node_properties, attach_script, get_scene_tree, duplicate_node, get_node_signals, connect_signal, disconnect_signal\n- Runtime (requires run_project or attach_project): take_screenshot, simulate_input, get_ui_elements, run_script\n- Project config (no Godot process): list_autoloads, add_autoload, remove_autoload, update_autoload, get_project_files, search_project, get_scene_dependencies, get_project_settings\n- Validation: validate\n\nKey behaviors:\n- All mutation operations (add_node, set_node_properties, delete_nodes, etc.) save the scene automatically. Only use save_scene for save-as (newPath) or re-canonicalization.\n- Headless Godot initializes ALL registered autoloads. If any autoload is broken, headless operations will fail. Use list_autoloads / remove_autoload to diagnose.\n- run_project verifies bridge readiness before returning success. If it reports degraded status, retry runtime tools after a moment or check get_debug_output.\n- attach_project is the fallback path for a manually launched Godot process. It injects the bridge and marks the project active, but it does not spawn Godot or capture stdout/stderr.\n- click_element in simulate_input resolves by node path or node name (BFS search), NOT by visible text. Use get_ui_elements to discover valid element identifiers.\n- run_script expects GDScript with \"extends RefCounted\" and \"func execute(scene_tree: SceneTree) -> Variant\".\n- run_project spawns Godot without -d so runtime errors do not pause execution; the `breakpoint` keyword in user code is a no-op (no debugger is attached). SCRIPT ERROR output and GDScript backtraces still appear in stderr."; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/package/dist/index.d.ts.map b/package/dist/index.d.ts.map new file mode 100644 index 0000000..5b8e802 --- /dev/null +++ b/package/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AAkBH,eAAO,MAAM,kBAAkB,oDAO9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,mhEAiBmM,CAAC"} \ No newline at end of file diff --git a/package/dist/index.js b/package/dist/index.js new file mode 100644 index 0000000..c4c82e4 --- /dev/null +++ b/package/dist/index.js @@ -0,0 +1,114 @@ +#!/usr/bin/env node +/** + * Godot MCP Server + * + * This MCP server provides tools for interacting with the Godot game engine. + * It enables AI assistants to launch the Godot editor, run Godot projects, + * capture debug output, manipulate scenes and nodes, and more. + */ +// Lower-level `Server` is deliberate; see CONTRIBUTING.md "MCP SDK: Server vs McpServer". +import { Server } from '@modelcontextprotocol/sdk/server/index.js'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'; +import { GodotRunner, getErrorMessage } from './utils/godot-runner.js'; +import { dispatchToolCall } from './dispatch.js'; +import { runtimeToolDefinitions } from './tools/runtime-tools.js'; +import { autoloadToolDefinitions } from './tools/autoload-tools.js'; +import { projectToolDefinitions } from './tools/project-tools.js'; +import { sceneToolDefinitions } from './tools/scene-tools.js'; +import { nodeToolDefinitions } from './tools/node-tools.js'; +import { validateToolDefinitions } from './tools/validate-tools.js'; +export const allToolDefinitions = [ + ...runtimeToolDefinitions, + ...autoloadToolDefinitions, + ...projectToolDefinitions, + ...sceneToolDefinitions, + ...nodeToolDefinitions, + ...validateToolDefinitions, +]; +export const serverInstructions = `Godot MCP Server — AI-driven Godot 4.x project manipulation. + +Tool categories: +- Project management: launch_editor, run_project, attach_project, detach_project, stop_project, get_debug_output, list_projects, get_project_info +- Scene editing (headless): create_scene, add_node, load_sprite, save_scene, export_mesh_library, batch_scene_operations +- Node editing (headless): delete_nodes, set_node_properties, get_node_properties, attach_script, get_scene_tree, duplicate_node, get_node_signals, connect_signal, disconnect_signal +- Runtime (requires run_project or attach_project): take_screenshot, simulate_input, get_ui_elements, run_script +- Project config (no Godot process): list_autoloads, add_autoload, remove_autoload, update_autoload, get_project_files, search_project, get_scene_dependencies, get_project_settings +- Validation: validate + +Key behaviors: +- All mutation operations (add_node, set_node_properties, delete_nodes, etc.) save the scene automatically. Only use save_scene for save-as (newPath) or re-canonicalization. +- Headless Godot initializes ALL registered autoloads. If any autoload is broken, headless operations will fail. Use list_autoloads / remove_autoload to diagnose. +- run_project verifies bridge readiness before returning success. If it reports degraded status, retry runtime tools after a moment or check get_debug_output. +- attach_project is the fallback path for a manually launched Godot process. It injects the bridge and marks the project active, but it does not spawn Godot or capture stdout/stderr. +- click_element in simulate_input resolves by node path or node name (BFS search), NOT by visible text. Use get_ui_elements to discover valid element identifiers. +- run_script expects GDScript with "extends RefCounted" and "func execute(scene_tree: SceneTree) -> Variant". +- run_project spawns Godot without -d so runtime errors do not pause execution; the \`breakpoint\` keyword in user code is a no-op (no debugger is attached). SCRIPT ERROR output and GDScript backtraces still appear in stderr.`; +class GodotMcpServer { + server; + runner; + constructor(config) { + this.runner = new GodotRunner(config); + this.server = new Server({ + name: 'godot-mcp', + version: '3.1.2', + }, { + capabilities: { + tools: {}, + }, + instructions: serverInstructions, + }); + this.setupToolHandlers(); + this.server.onerror = (error) => console.error('[MCP Error]', error); + process.on('SIGINT', async () => { + await this.cleanup(); + process.exit(0); + }); + process.on('SIGTERM', async () => { + await this.cleanup(); + process.exit(0); + }); + } + async cleanup() { + console.error('[SERVER] Cleaning up resources'); + await this.runner.stopProject(); + await this.server.close(); + } + setupToolHandlers() { + this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ + tools: allToolDefinitions, + })); + this.server.setRequestHandler(CallToolRequestSchema, async (request) => { + const toolName = request.params.name; + const args = request.params.arguments || {}; + console.error(`[SERVER] Handling tool request: ${toolName}`); + return await dispatchToolCall(this.runner, toolName, args); + }); + } + async run() { + try { + await this.runner.detectGodotPath(); + const godotPath = this.runner.getGodotPath(); + if (godotPath) { + console.error(`[SERVER] Using Godot at: ${godotPath}`); + } + // detectGodotPath() already emits a specific logError on failure (bad + // GODOT_PATH, no binary found, etc.). Don't duplicate with a generic + // warning here — the runner's message names the actual cause. + const transport = new StdioServerTransport(); + await this.server.connect(transport); + console.error('Godot MCP server running on stdio'); + } + catch (error) { + console.error('[SERVER] Failed to start:', getErrorMessage(error)); + process.exit(1); + } + } +} +// Create and run the server +const server = new GodotMcpServer(); +server.run().catch((error) => { + console.error('Failed to run server:', getErrorMessage(error)); + process.exit(1); +}); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/package/dist/index.js.map b/package/dist/index.js.map new file mode 100644 index 0000000..18b0b30 --- /dev/null +++ b/package/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/scripts/godot_operations.gd b/package/dist/scripts/godot_operations.gd new file mode 100644 index 0000000..f1ce056 --- /dev/null +++ b/package/dist/scripts/godot_operations.gd @@ -0,0 +1,1026 @@ +#!/usr/bin/env -S godot --headless --script +extends SceneTree + +# Debug mode flag +var debug_mode = false + +func _init(): + var args = OS.get_cmdline_args() + + # Check for debug flag + debug_mode = "--debug-godot" in args + + # SceneTree.quit(n) only schedules a quit for end-of-frame in Godot 4. + # Every quit(1) must be followed by `return` to halt the failing path, + # otherwise control falls through into success-print + scene save. + # Find the script argument and determine the positions of operation and params + var script_index = args.find("--script") + if script_index == -1: + log_error("Could not find --script argument") + quit(1) + return + + var operation_index = script_index + 2 + var params_index = script_index + 3 + + if args.size() <= params_index: + log_error("Usage: godot --headless --script godot_operations.gd ") + log_error("Not enough command-line arguments provided.") + quit(1) + return + + log_debug("All arguments: " + str(args)) + + var operation = args[operation_index] + var params_json = args[params_index] + + log_info("Operation: " + operation) + log_debug("Params JSON: " + params_json) + + var json = JSON.new() + var error = json.parse(params_json) + var params = null + + if error == OK: + params = json.get_data() + else: + log_error("Failed to parse JSON parameters: " + params_json) + log_error("JSON Error: " + json.get_error_message() + " at line " + str(json.get_error_line())) + quit(1) + return + + if not params: + log_error("Failed to parse JSON parameters: " + params_json) + quit(1) + return + + log_info("Executing operation: " + operation) + + match operation: + # Original operations + "create_scene": + create_scene(params) + "add_node": + add_node(params) + "load_sprite": + load_sprite(params) + "export_mesh_library": + export_mesh_library(params) + "save_scene": + save_scene(params) + # Node operations (always-array) + "delete_nodes": + delete_nodes(params) + "set_node_properties": + set_node_properties(params) + "get_node_properties": + get_node_properties(params) + "get_scene_tree": + get_scene_tree(params) + "attach_script": + attach_script(params) + "duplicate_node": + duplicate_node(params) + "get_node_signals": + get_node_signals(params) + "connect_signal": + connect_signal(params) + "disconnect_signal": + disconnect_signal(params) + "validate_resource": + validate_resource(params) + # Batch operations + "validate_batch": + validate_batch(params) + "batch_scene_operations": + batch_scene_operations(params) + _: + log_error("Unknown operation: " + operation) + quit(1) + return + + quit() + return + +# Logging functions +func log_debug(message): + if debug_mode: + print("[DEBUG] " + message) + +func log_info(message): + printerr("[INFO] " + message) + +func log_error(message): + printerr("[ERROR] " + message) + +# Get a script by name or path +func get_script_by_name(name_of_class): + if debug_mode: + printerr("Attempting to get script for class: " + name_of_class) + + if ResourceLoader.exists(name_of_class, "Script"): + if debug_mode: + printerr("Resource exists, loading directly: " + name_of_class) + var script = load(name_of_class) as Script + if script: + if debug_mode: + printerr("Successfully loaded script from path") + return script + else: + printerr("Failed to load script from path: " + name_of_class) + elif debug_mode: + printerr("Resource not found, checking global class registry") + + var global_classes = ProjectSettings.get_global_class_list() + if debug_mode: + printerr("Searching through " + str(global_classes.size()) + " global classes") + + for global_class in global_classes: + var found_name_of_class = global_class["class"] + var found_path = global_class["path"] + + if found_name_of_class == name_of_class: + if debug_mode: + printerr("Found matching class in registry: " + found_name_of_class + " at path: " + found_path) + var script = load(found_path) as Script + if script: + if debug_mode: + printerr("Successfully loaded script from registry") + return script + else: + printerr("Failed to load script from registry path: " + found_path) + break + + printerr("Could not find script for class: " + name_of_class) + return null + +# Instantiate a class by name +func instantiate_class(name_of_class): + if name_of_class.is_empty(): + printerr("Cannot instantiate class: name is empty") + return null + + var result = null + if debug_mode: + printerr("Attempting to instantiate class: " + name_of_class) + + if ClassDB.class_exists(name_of_class): + if debug_mode: + printerr("Class exists in ClassDB, using ClassDB.instantiate()") + if ClassDB.can_instantiate(name_of_class): + result = ClassDB.instantiate(name_of_class) + if result == null: + printerr("ClassDB.instantiate() returned null for class: " + name_of_class) + else: + printerr("Class exists but cannot be instantiated: " + name_of_class) + else: + if debug_mode: + printerr("Class not found in ClassDB, trying to get script") + var script = get_script_by_name(name_of_class) + if script is GDScript: + if debug_mode: + printerr("Found GDScript, creating instance") + result = script.new() + else: + printerr("Failed to get script for class: " + name_of_class) + return null + + if result == null: + printerr("Failed to instantiate class: " + name_of_class) + elif debug_mode: + printerr("Successfully instantiated class: " + name_of_class + " of type: " + result.get_class()) + + return result + +# Helper to normalize scene path +func normalize_scene_path(scene_path: String) -> String: + if not scene_path.begins_with("res://"): + return "res://" + scene_path + return scene_path + +# Helper to load and instantiate a scene +func load_scene_instance(scene_path: String): + var full_path = normalize_scene_path(scene_path) + log_debug("Loading scene from: " + full_path) + + if not FileAccess.file_exists(full_path): + log_error("Scene file does not exist: " + full_path) + return null + + var scene = load(full_path) + if not scene: + log_error("Failed to load scene: " + full_path) + return null + + var instance = scene.instantiate() + if not instance: + log_error("Failed to instantiate scene: " + full_path) + return null + + return instance + +# Helper to find a node by path. Accepts "root", ".", "" (all → scene_root), +# the actual scene root's name (e.g. "Main"), or a path with either as the first +# segment (e.g. "root/Button" or "Main/Button"). Bare paths ("Button") resolve +# normally via get_node_or_null. +func find_node_by_path(scene_root: Node, node_path: String) -> Node: + if node_path == "" or node_path == "." or node_path == "root": + return scene_root + if node_path == String(scene_root.name): + return scene_root + + var path = node_path + var first_slash = path.find("/") + if first_slash != -1: + var first_segment = path.substr(0, first_slash) + if first_segment == "root" or first_segment == String(scene_root.name): + path = path.substr(first_slash + 1) + + if path.is_empty(): + return scene_root + + return scene_root.get_node_or_null(path) + +# Helper to save a scene +func save_scene_to_path(scene_root: Node, save_path: String) -> bool: + var full_path = normalize_scene_path(save_path) + + var packed_scene = PackedScene.new() + var result = packed_scene.pack(scene_root) + + if result != OK: + log_error("Failed to pack scene: " + str(result)) + return false + + var save_error = ResourceSaver.save(packed_scene, full_path) + if save_error != OK: + log_error("Failed to save scene: " + str(save_error)) + return false + + return true + +# Ensure the parent directory of a res:// path exists, creating it recursively +# if needed. Returns true on success or when the directory already exists. +func _ensure_res_dir(full_res_path: String) -> bool: + var dir_path = full_res_path.get_base_dir() + if dir_path == "res://" or dir_path.is_empty(): + return true + var dir = DirAccess.open("res://") + if not dir: + return false + var relative_dir = dir_path.substr(6) if dir_path.begins_with("res://") else dir_path + if relative_dir.is_empty() or dir.dir_exists(relative_dir): + return true + return dir.make_dir_recursive(relative_dir) == OK + +# Create a new scene with a specified root node type +func create_scene(params): + printerr("Creating scene: " + params.scene_path) + + var full_scene_path = normalize_scene_path(params.scene_path) + log_debug("Scene path: " + full_scene_path) + + var root_node_type = "Node2D" + if params.has("root_node_type"): + root_node_type = params.root_node_type + log_debug("Root node type: " + root_node_type) + + var scene_root = instantiate_class(root_node_type) + if not scene_root: + log_error("Failed to instantiate node of type: " + root_node_type) + quit(1) + return + + scene_root.name = "root" + scene_root.owner = scene_root + + if not _ensure_res_dir(full_scene_path): + log_error("Failed to create directory for scene: " + full_scene_path) + quit(1) + return + + if save_scene_to_path(scene_root, full_scene_path): + print(JSON.stringify({"success": true, "scenePath": params.scene_path})) + else: + log_error("Failed to create scene: " + params.scene_path) + quit(1) + return + +# Add a node to an existing scene +# Apply an add_node mutation without saving. Shared by standalone add_node +# and batch_scene_operations so both paths validate identically. +# Returns {"ok": bool, "error": String}; error is empty on success. +func _apply_add_node(scene_root: Node, op: Dictionary) -> Dictionary: + var parent_path = "root" + if op.has("parent_node_path"): + parent_path = op.parent_node_path + var parent = find_node_by_path(scene_root, parent_path) + if not parent: + return {"ok": false, "error": "Parent node not found: " + parent_path} + if not op.has("node_type") or op.node_type == "": + return {"ok": false, "error": "node_type is required for add_node"} + if not op.has("node_name") or op.node_name == "": + return {"ok": false, "error": "node_name is required for add_node"} + var new_node = instantiate_class(op.node_type) + if not new_node: + return {"ok": false, "error": "Failed to instantiate node of type: " + op.node_type} + new_node.name = op.node_name + if op.has("properties"): + for property in op.properties: + new_node.set(property, _coerce_property_value(op.properties[property])) + parent.add_child(new_node) + new_node.owner = scene_root + return {"ok": true, "error": ""} + +# Apply a load_sprite mutation without saving. Shared by standalone load_sprite +# and batch_scene_operations. +func _apply_load_sprite(scene_root: Node, op: Dictionary) -> Dictionary: + if not op.has("node_path") or op.node_path == "": + return {"ok": false, "error": "node_path is required for load_sprite"} + if not op.has("texture_path") or op.texture_path == "": + return {"ok": false, "error": "texture_path is required for load_sprite"} + var sprite_node = find_node_by_path(scene_root, op.node_path) + if not sprite_node: + return {"ok": false, "error": "Node not found: " + op.node_path} + if not (sprite_node is Sprite2D or sprite_node is Sprite3D or sprite_node is TextureRect): + return {"ok": false, "error": "Node is not a sprite-compatible type: " + sprite_node.get_class()} + var full_texture_path = normalize_scene_path(op.texture_path) + var texture = load(full_texture_path) + if not texture: + return {"ok": false, "error": "Failed to load texture: " + full_texture_path} + if not (texture is Texture2D): + return {"ok": false, "error": "Loaded resource is not a Texture2D: " + full_texture_path} + # A texture without a resource_path is a runtime-only object — PackedScene.pack() + # cannot serialize it, so the assignment would silently vanish on save. + if texture.resource_path == "": + return {"ok": false, "error": "Texture has no resource_path — likely not imported. Open project in Godot editor once, or run 'godot --headless --editor --quit' to import assets."} + sprite_node.texture = texture + return {"ok": true, "error": ""} + +func add_node(params): + printerr("Adding node to scene: " + params.scene_path) + + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var result = _apply_add_node(scene_root, params) + if not result.ok: + log_error(result.error) + quit(1) + return + + if save_scene_to_path(scene_root, params.scene_path): + print("Node '" + params.node_name + "' of type '" + params.node_type + "' added successfully") + else: + log_error("Failed to save scene after adding node") + quit(1) + return + +# Load a sprite into a Sprite2D node +func load_sprite(params): + printerr("Loading sprite into scene: " + params.scene_path) + + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var result = _apply_load_sprite(scene_root, params) + if not result.ok: + log_error(result.error) + quit(1) + return + + if save_scene_to_path(scene_root, params.scene_path): + print("Sprite loaded successfully with texture: " + params.texture_path) + else: + log_error("Failed to save scene after loading sprite") + quit(1) + return + +# Export a scene as a MeshLibrary resource +func export_mesh_library(params): + printerr("Exporting MeshLibrary from scene: " + params.scene_path) + + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var mesh_library = MeshLibrary.new() + + var mesh_item_names = params.mesh_item_names if params.has("mesh_item_names") else [] + var use_specific_items = mesh_item_names.size() > 0 + + var item_id = 0 + + for child in scene_root.get_children(): + if use_specific_items and not (child.name in mesh_item_names): + continue + + var mesh_instance = null + if child is MeshInstance3D: + mesh_instance = child + else: + for descendant in child.get_children(): + if descendant is MeshInstance3D: + mesh_instance = descendant + break + + if mesh_instance and mesh_instance.mesh: + mesh_library.create_item(item_id) + mesh_library.set_item_name(item_id, child.name) + mesh_library.set_item_mesh(item_id, mesh_instance.mesh) + + for collision_child in child.get_children(): + if collision_child is CollisionShape3D and collision_child.shape: + mesh_library.set_item_shapes(item_id, [collision_child.shape]) + break + + mesh_library.set_item_preview(item_id, mesh_instance.mesh) + + item_id += 1 + + if item_id > 0: + var full_output_path = normalize_scene_path(params.output_path) + + if not _ensure_res_dir(full_output_path): + log_error("Failed to create directory for MeshLibrary: " + full_output_path) + quit(1) + return + + var error = ResourceSaver.save(mesh_library, full_output_path) + if error == OK: + print("MeshLibrary exported successfully with " + str(item_id) + " items to: " + params.output_path) + else: + log_error("Failed to save MeshLibrary: " + str(error)) + quit(1) + return + else: + log_error("No valid meshes found in the scene") + quit(1) + return + +# Save changes to a scene file +func save_scene(params): + printerr("Saving scene: " + params.scene_path) + + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var save_path = params.new_path if params.has("new_path") else params.scene_path + + if save_scene_to_path(scene_root, save_path): + print("Scene saved successfully to: " + save_path) + else: + log_error("Failed to save scene") + quit(1) + return + +# ============================================ +# NODE OPERATIONS +# ============================================ + +# Delete one or more nodes from a scene (saves once) +func delete_nodes(params): + printerr("Deleting nodes from scene: " + params.scene_path) + + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var node_paths: Array = params.node_paths + var results: Array = [] + var any_deleted := false + + for node_path in node_paths: + var entry = {"nodePath": node_path} + var node = find_node_by_path(scene_root, node_path) + if not node: + entry["error"] = "Node not found: " + node_path + elif node == scene_root: + entry["error"] = "Cannot delete the root node" + else: + var parent = node.get_parent() + parent.remove_child(node) + node.queue_free() + entry["success"] = true + any_deleted = true + results.append(entry) + + if any_deleted: + if not save_scene_to_path(scene_root, params.scene_path): + print(JSON.stringify({"error": "Failed to save scene after deleting nodes", "results": results})) + return + + print(JSON.stringify({"results": results})) + +# Update one or more node properties in a single headless process (saves once) +func set_node_properties(params: Dictionary) -> void: + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + print(JSON.stringify({"error": "Failed to load scene: " + params.scene_path, "results": []})) + return + + var abort_on_error = params.get("abort_on_error", false) + var results: Array = [] + var any_set := false + + for update in params.updates: + var result = {"nodePath": update.node_path, "property": update.property} + var node = find_node_by_path(scene_root, update.node_path) + if node == null: + result["error"] = "Node not found: " + update.node_path + elif not (update.property in node): + result["error"] = "Property '%s' does not exist on node of type '%s'" % [update.property, node.get_class()] + else: + node.set(update.property, _coerce_property_value(update.value)) + result["success"] = true + any_set = true + results.append(result) + if abort_on_error and result.has("error"): + break + + if any_set: + if not save_scene_to_path(scene_root, params.scene_path): + print(JSON.stringify({"error": "Failed to save scene after updates", "results": results})) + return + + print(JSON.stringify({"results": results})) + +# Get properties from one or more nodes in a single headless process (loads scene once) +func get_node_properties(params: Dictionary) -> void: + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + print(JSON.stringify({"error": "Failed to load scene: " + params.scene_path, "results": []})) + return + + var results: Array = [] + # Class-name → default-instance cache. Reused across all nodes in this call + # so we don't instantiate a fresh default per node when changed_only is true. + var defaults_cache: Dictionary = {} + + for node_spec in params.nodes: + var node_path = node_spec.get("node_path", "") + var changed_only = node_spec.get("changed_only", false) + var node = find_node_by_path(scene_root, node_path) + if node == null: + results.append({"nodePath": node_path, "error": "Node not found"}) + else: + var props = _collect_node_properties(node, changed_only, defaults_cache) + results.append({"nodePath": node_path, "nodeType": node.get_class(), "properties": props}) + + # Free cached default instances; they were created via instantiate_class. + for klass in defaults_cache: + var inst = defaults_cache[klass] + if inst: + inst.free() + + print(JSON.stringify({"results": results})) + +# Get full hierarchical tree structure of a scene +func get_scene_tree(params): + printerr("Getting scene tree for: " + params.scene_path) + + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var tree_root = scene_root + if params.has("parent_path") and params.parent_path: + tree_root = find_node_by_path(scene_root, params.parent_path) + if not tree_root: + log_error("Parent node not found: " + str(params.parent_path)) + quit(1) + return + + var max_depth = -1 + if params.has("max_depth"): + max_depth = int(params.max_depth) + + var tree = build_tree_recursive(tree_root, "", 0, max_depth) + print(JSON.stringify(tree)) + +func build_tree_recursive(node: Node, path: String, depth: int = 0, max_depth: int = -1) -> Dictionary: + var node_path = path + "/" + node.name if not path.is_empty() else node.name + + var children = [] + if max_depth < 0 or depth < max_depth: + for child in node.get_children(): + children.append(build_tree_recursive(child, node_path, depth + 1, max_depth)) + + var script_path = "" + var script = node.get_script() + if script and script.resource_path: + script_path = script.resource_path + + return { + "name": node.name, + "type": node.get_class(), + "path": node_path, + "script": script_path, + "children": children + } + +# Attach or change a script on a node +func attach_script(params): + printerr("Attaching script to node in scene: " + params.scene_path) + + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var node = find_node_by_path(scene_root, params.node_path) + if not node: + log_error("Node not found: " + params.node_path) + quit(1) + return + + var full_script_path = normalize_scene_path(params.script_path) + + if not FileAccess.file_exists(full_script_path): + log_error("Script file does not exist: " + full_script_path) + quit(1) + return + + var script = load(full_script_path) + if not script: + log_error("Failed to load script: " + full_script_path) + quit(1) + return + + node.set_script(script) + + if save_scene_to_path(scene_root, params.scene_path): + print(JSON.stringify({ + "success": true, + "nodePath": params.node_path, + "scriptPath": params.script_path + })) + else: + log_error("Failed to save scene after attaching script") + quit(1) + return + +# ============================================ +# SIGNAL AND DUPLICATE OPERATIONS +# ============================================ + +# Duplicate a node and its children within a scene +func duplicate_node(params): + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var node = find_node_by_path(scene_root, params.node_path) + if not node: + log_error("Node not found: " + params.node_path) + quit(1) + return + if node == scene_root: + log_error("Cannot duplicate the root node") + quit(1) + return + + var duplicate = node.duplicate() + if params.has("new_name"): + duplicate.name = params.new_name + else: + duplicate.name = node.name + "2" + + var parent = node.get_parent() + if params.has("target_parent_path"): + parent = find_node_by_path(scene_root, params.target_parent_path) + if not parent: + log_error("Target parent not found: " + params.target_parent_path) + quit(1) + return + + parent.add_child(duplicate) + duplicate.owner = scene_root + # Iterative BFS to set owner on all descendants — avoids recursion depth. + var queue: Array = duplicate.get_children() + while not queue.is_empty(): + var current = queue.pop_front() + current.owner = scene_root + queue.append_array(current.get_children()) + + # Compute the new node's scene-relative path: parent path + "/" + duplicate.name. + # The scene tree isn't attached in headless mode so get_path() is unreliable; + # derive parent path from the input node_path (or target_parent_path). + var parent_relative_path: String + if params.has("target_parent_path"): + parent_relative_path = params.target_parent_path + else: + var last_slash = params.node_path.rfind("/") + parent_relative_path = params.node_path.substr(0, last_slash) if last_slash > 0 else "" + var new_path: String + if parent_relative_path == "": + new_path = String(duplicate.name) + else: + new_path = parent_relative_path + "/" + String(duplicate.name) + + if save_scene_to_path(scene_root, params.scene_path): + print(JSON.stringify({ + "success": true, + "originalPath": params.node_path, + "newPath": new_path + })) + else: + log_error("Failed to save scene after duplicating node") + quit(1) + return + +# List signals defined on a node and their current connections +func get_node_signals(params): + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var node = find_node_by_path(scene_root, params.node_path) + if not node: + log_error("Node not found: " + params.node_path) + quit(1) + return + + var signals = [] + for sig in node.get_signal_list(): + var sig_name = sig["name"] + var connections = [] + for conn in node.get_signal_connection_list(sig_name): + connections.append({ + "signal": sig_name, + "target": str(conn["callable"].get_object().get_path()) if conn["callable"].get_object() else "unknown", + "method": conn["callable"].get_method() + }) + signals.append({ + "name": sig_name, + "connections": connections + }) + + print(JSON.stringify({ + "nodePath": params.node_path, + "nodeType": node.get_class(), + "signals": signals + })) + +# Connect a signal from one node to a method on another node +func connect_signal(params): + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var source = find_node_by_path(scene_root, params.node_path) + if not source: + log_error("Source node not found: " + params.node_path) + quit(1) + return + + var target = find_node_by_path(scene_root, params.target_node_path) + if not target: + log_error("Target node not found: " + params.target_node_path) + quit(1) + return + + if not source.has_signal(params.signal): + log_error("Signal does not exist: " + params.signal + " on " + source.get_class()) + quit(1) + return + + if not target.has_method(params.method): + log_error("Method does not exist: " + params.method + " on " + target.get_class()) + quit(1) + return + + # CONNECT_PERSIST is required for the connection to be serialized into the + # packed scene; without it the connection is runtime-only and disappears on save. + var err = source.connect(params.signal, Callable(target, params.method), CONNECT_PERSIST) + if err != OK: + log_error("Failed to connect signal: " + str(err)) + quit(1) + return + + if save_scene_to_path(scene_root, params.scene_path): + print("Signal '" + params.signal + "' connected from '" + params.node_path + "' to '" + params.target_node_path + "." + params.method + "'") + else: + log_error("Failed to save scene after connecting signal") + quit(1) + return + +# Disconnect a signal connection between two nodes +func disconnect_signal(params): + var scene_root = load_scene_instance(params.scene_path) + if not scene_root: + quit(1) + return + + var source = find_node_by_path(scene_root, params.node_path) + if not source: + log_error("Source node not found: " + params.node_path) + quit(1) + return + + var target = find_node_by_path(scene_root, params.target_node_path) + if not target: + log_error("Target node not found: " + params.target_node_path) + quit(1) + return + + if not source.is_connected(params.signal, Callable(target, params.method)): + log_error("Signal connection does not exist") + quit(1) + return + + source.disconnect(params.signal, Callable(target, params.method)) + + if save_scene_to_path(scene_root, params.scene_path): + print("Signal '" + params.signal + "' disconnected from '" + params.target_node_path + "." + params.method + "'") + else: + log_error("Failed to save scene after disconnecting signal") + quit(1) + return + +# ============================================ +# VALIDATE OPERATION +# ============================================ + +# Validate a GDScript or scene file by loading it headlessly +func validate_resource(params): + if not (params.has("script_path") or params.has("scene_path")): + log_error("validate_resource requires script_path or scene_path") + quit(1) + return + var result = _validate_single(params) + print(JSON.stringify({"valid": result.valid, "errors": result.errors})) + +# ============================================ +# BATCH OPERATIONS +# ============================================ + +# Helper: coerce a JSON-parsed value to a GDScript type (Vector2, Vector3, Color) +func _coerce_property_value(value): + if typeof(value) == TYPE_DICTIONARY: + if value.has("x") and value.has("y"): + if value.has("z"): + return Vector3(value.x, value.y, value.z) + else: + return Vector2(value.x, value.y) + elif value.has("r") and value.has("g") and value.has("b"): + var a = value.a if value.has("a") else 1.0 + return Color(value.r, value.g, value.b, a) + return value + +# Helper: collect node properties into a serializable Dictionary. When +# changed_only is true, compares each property against a default instance of +# the node's class. The defaults_cache dict is keyed by class name so the +# caller can reuse default instances across many nodes (caller is responsible +# for freeing the cache when done). +func _collect_node_properties(node: Node, changed_only: bool, defaults_cache: Dictionary) -> Dictionary: + var default_node = null + if changed_only: + var klass = node.get_class() + if defaults_cache.has(klass): + default_node = defaults_cache[klass] + else: + default_node = instantiate_class(klass) + defaults_cache[klass] = default_node + + var properties = {} + var property_list = node.get_property_list() + + for prop in property_list: + var prop_name = prop["name"] + var prop_usage = prop["usage"] + + if prop_usage & PROPERTY_USAGE_STORAGE or prop_usage & PROPERTY_USAGE_EDITOR: + var value = node.get(prop_name) + + if default_node and default_node.get(prop_name) == value: + continue + + if value is Vector2: + properties[prop_name] = {"x": value.x, "y": value.y} + elif value is Vector3: + properties[prop_name] = {"x": value.x, "y": value.y, "z": value.z} + elif value is Color: + properties[prop_name] = {"r": value.r, "g": value.g, "b": value.b, "a": value.a} + elif value is Transform2D: + properties[prop_name] = str(value) + elif value is Transform3D: + properties[prop_name] = str(value) + elif value is Object: + if value: + properties[prop_name] = value.get_class() + else: + properties[prop_name] = null + elif typeof(value) in [TYPE_NIL, TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARRAY, TYPE_DICTIONARY]: + properties[prop_name] = value + else: + properties[prop_name] = str(value) + + return properties + +# Helper: validate a single target dict (script_path or scene_path) +func _validate_single(target: Dictionary) -> Dictionary: + if target.has("script_path") and target.script_path != "": + var path = normalize_scene_path(target.script_path) + if not FileAccess.file_exists(path): + return {"valid": false, "errors": [{"message": "File not found: " + path}], "target": target.script_path} + var resource = load(path) + # Actual parse errors go to stderr and are parsed by TypeScript + return {"valid": resource != null, "errors": [], "target": target.script_path} + elif target.has("scene_path") and target.scene_path != "": + var path = normalize_scene_path(target.scene_path) + if not FileAccess.file_exists(path): + return {"valid": false, "errors": [{"message": "File not found: " + path}], "target": target.scene_path} + var scene = load(path) + return {"valid": scene != null, "errors": [], "target": target.scene_path} + else: + return {"valid": false, "errors": [{"message": "No valid target: provide script_path or scene_path"}], "target": ""} + +# Validate multiple scripts/scenes in a single headless process +func validate_batch(params: Dictionary) -> void: + var results: Array = [] + for target in params.targets: + results.append(_validate_single(target)) + print(JSON.stringify({"results": results})) + +# Execute multiple scene operations in a single headless process +# Scenes are loaded once and cached in memory; mutations accumulate until a save op +func batch_scene_operations(params: Dictionary) -> void: + var abort_on_error = params.get("abort_on_error", false) + var results: Array = [] + var scene_cache: Dictionary = {} + + for op in params.operations: + var op_name = op.get("operation", "") + var scene_path = op.get("scene_path", "") + var result = {"operation": op_name, "scenePath": scene_path} + + if scene_path != "" and scene_path not in scene_cache: + var scene_root = load_scene_instance(scene_path) + if scene_root: + scene_cache[scene_path] = scene_root + else: + result["error"] = "Failed to load scene: " + scene_path + results.append(result) + if abort_on_error: + break + continue + + var scene_root = scene_cache.get(scene_path, null) if scene_path != "" else null + + match op_name: + "add_node": + if scene_root == null: + result["error"] = "scene_path required for add_node" + else: + var apply_result = _apply_add_node(scene_root, op) + if not apply_result.ok: + result["error"] = apply_result.error + else: + result["success"] = true + "load_sprite": + if scene_root == null: + result["error"] = "scene_path required for load_sprite" + else: + var apply_result = _apply_load_sprite(scene_root, op) + if not apply_result.ok: + result["error"] = apply_result.error + else: + result["success"] = true + "save": + if scene_root == null: + result["error"] = "scene_path required for save" + else: + var new_path = op.get("new_path", scene_path) + if save_scene_to_path(scene_root, new_path): + result["success"] = true + # Only evict on normal save; save-as leaves the mutated scene in + # cache so subsequent ops on scene_path still see accumulated mutations. + if new_path == scene_path: + scene_cache.erase(scene_path) + else: + result["error"] = "Failed to save scene: " + scene_path + _: + result["error"] = "Unknown batch operation: " + op_name + + results.append(result) + if abort_on_error and result.has("error"): + break + + # Auto-save any scenes that were mutated but not explicitly saved + for scene_path in scene_cache: + save_scene_to_path(scene_cache[scene_path], scene_path) + + print(JSON.stringify({"results": results})) diff --git a/package/dist/scripts/godot_operations.gd.uid b/package/dist/scripts/godot_operations.gd.uid new file mode 100644 index 0000000..39f8cef --- /dev/null +++ b/package/dist/scripts/godot_operations.gd.uid @@ -0,0 +1 @@ +uid://b1jod8iwdknaw diff --git a/package/dist/scripts/mcp_bridge.gd b/package/dist/scripts/mcp_bridge.gd new file mode 100644 index 0000000..7076373 --- /dev/null +++ b/package/dist/scripts/mcp_bridge.gd @@ -0,0 +1,635 @@ +extends Node + +# KEEP IN SYNC: src/utils/bridge-protocol.ts implements the same framing on the +# Node side. Any change here MUST be mirrored there (and vice versa). +# +# Wire format: 4-byte big-endian length prefix + UTF-8 JSON payload. +# Max frame size 16 MiB; oversize frames close the offending peer. + +# Port is baked into this script at inject time by BridgeManager.inject — the +# integer literal below is rewritten in the project copy. The 9900 here is the +# source-of-truth default that ships with the script so it remains runnable +# standalone (e.g. validate, manual debugging). +const PORT := 9900 # MCP_BRIDGE_PORT_BAKED +const MAX_FRAME_BYTES := 16 * 1024 * 1024 +const FRAME_HEADER_BYTES := 4 + +class PeerState: + extends RefCounted + var stream: StreamPeerTCP + var buffer: PackedByteArray = PackedByteArray() + var expected_len: int = -1 # -1 = waiting on header + var handling: bool = false # true while a command is awaiting a response + +var tcp_server: TCPServer +var session_token: String = "" +var _peers: Array = [] # Array[PeerState] +var _shutting_down: bool = false # One-shot: set true in shutdown(); never reset (autoload is recreated on next session) + +func _ready() -> void: + process_mode = Node.PROCESS_MODE_ALWAYS + session_token = OS.get_environment("MCP_SESSION_TOKEN") + tcp_server = TCPServer.new() + var err = tcp_server.listen(PORT, "127.0.0.1") + if err != OK: + push_error("McpBridge: Failed to listen on port %d (error %d)" % [PORT, err]) + else: + print("McpBridge: Listening on TCP port %d" % PORT) + + if OS.get_environment("MCP_BACKGROUND") == "1": + DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_NO_FOCUS, true) + DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_MOUSE_PASSTHROUGH, true) + DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true) + DisplayServer.window_set_position(Vector2i(-9999, -9999)) + print("McpBridge: Background mode active - window hidden, physical input blocked") + +func _process(_delta: float) -> void: + if tcp_server == null or not tcp_server.is_listening(): + return + + while tcp_server.is_connection_available(): + var stream := tcp_server.take_connection() + if stream == null: + break + stream.set_no_delay(true) + var peer := PeerState.new() + peer.stream = stream + _peers.append(peer) + + # Backwards iteration so remove_at() doesn't shift entries we haven't seen + # yet, and avoids the O(n) cost of Array.erase() per removal. + var i := _peers.size() + while i > 0: + i -= 1 + var peer = _peers[i] + _poll_peer(peer) + if peer.stream == null or peer.stream.get_status() != StreamPeerTCP.STATUS_CONNECTED: + _peers.remove_at(i) + +func _poll_peer(peer: PeerState) -> void: + peer.stream.poll() + var status := peer.stream.get_status() + if status != StreamPeerTCP.STATUS_CONNECTED: + return + + var available := peer.stream.get_available_bytes() + if available > 0: + var chunk: Array = peer.stream.get_partial_data(available) + # get_partial_data returns [error, PackedByteArray] + if chunk[0] == OK: + peer.buffer.append_array(chunk[1]) + + while true: + if peer.expected_len < 0: + if peer.buffer.size() < FRAME_HEADER_BYTES: + return + # Read u32 BE header. + var header := peer.buffer.slice(0, FRAME_HEADER_BYTES) + var b0 := int(header[0]) + var b1 := int(header[1]) + var b2 := int(header[2]) + var b3 := int(header[3]) + peer.expected_len = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3 + peer.buffer = peer.buffer.slice(FRAME_HEADER_BYTES) + if peer.expected_len > MAX_FRAME_BYTES: + push_error("McpBridge: Frame header exceeds limit (%d), closing peer" % peer.expected_len) + peer.stream.disconnect_from_host() + peer.stream = null + return + + if peer.handling: + return + if peer.buffer.size() < peer.expected_len: + return + + var frame_bytes := peer.buffer.slice(0, peer.expected_len) + peer.buffer = peer.buffer.slice(peer.expected_len) + peer.expected_len = -1 + + var data := frame_bytes.get_string_from_utf8().strip_edges() + peer.handling = true + _dispatch_command(peer, data) + # _dispatch_command awaits internally on async branches (input, run_script, + # screenshot, shutdown), so control returns here at the first inner await. + # `peer.handling` is the gate that blocks re-entry; it is cleared by + # `_send_response` once the handler completes. + +# INVARIANT: every code path through this function and its handlers must +# eventually reach `_send_response`. `peer.handling` is set to true by the +# caller (`_poll_peer`) before dispatch and cleared inside `_send_response`. +# A handler that exits without calling `_send_response` will deadlock the +# peer — the next frame will never be polled. When adding a new branch, +# ensure the early-exit calls `_send_response` with an error payload. +func _dispatch_command(peer: PeerState, data: String) -> void: + if not data.begins_with("{"): + _send_response(peer, {"error": "Non-JSON frame (expected a JSON command object)"}) + return + + var json = JSON.new() + var err = json.parse(data) + if err != OK: + _send_response(peer, {"error": "Invalid JSON: %s" % json.get_error_message()}) + return + + var payload = json.data + if typeof(payload) != TYPE_DICTIONARY: + _send_response(peer, {"error": "Expected JSON object"}) + return + + var command = payload.get("command", "") + match command: + "input": + var actions = payload.get("actions", []) + if typeof(actions) != TYPE_ARRAY: + _send_response(peer, {"error": "actions must be an array"}) + return + if actions.is_empty(): + _send_response(peer, {"error": "actions array is empty"}) + return + await _handle_input(peer, actions) + "get_ui_elements": + _handle_get_ui_elements(peer, payload) + "run_script": + await _handle_run_script(peer, payload) + "screenshot": + await _handle_screenshot(peer, payload) + "shutdown": + await _handle_shutdown(peer) + "ping": + _send_response(peer, {"status": "pong", "session_token": session_token, "project_path": ProjectSettings.globalize_path("res://")}) + _: + _send_response(peer, {"error": "Unknown command: %s" % command}) + +# --- Screenshot --- + +func _handle_screenshot(peer: PeerState, payload: Dictionary = {}) -> void: + await RenderingServer.frame_post_draw + + var viewport := get_viewport() + if viewport == null: + _send_response(peer, {"error": "No viewport available"}) + return + + var image := viewport.get_texture().get_image() + if image == null: + _send_response(peer, {"error": "Failed to capture viewport image"}) + return + + var timestamp := str(Time.get_unix_time_from_system()).replace(".", "_") + var screenshot_dir := ProjectSettings.globalize_path("res://.mcp/screenshots") + DirAccess.make_dir_recursive_absolute(screenshot_dir) + var file_path := screenshot_dir.path_join("screenshot_%s.png" % timestamp) + + var save_err := image.save_png(file_path) + if save_err != OK: + _send_response(peer, {"error": "Failed to save screenshot (error %d)" % save_err}) + return + + var safe_path := file_path.replace("\\", "/") + var response: Dictionary = { + "path": safe_path, + "width": image.get_width(), + "height": image.get_height(), + } + + var preview_max_width: int = int(payload.get("preview_max_width", 0)) + var preview_max_height: int = int(payload.get("preview_max_height", 0)) + if preview_max_width > 0 and preview_max_height > 0: + var scale: float = min( + 1.0, + min( + float(preview_max_width) / float(image.get_width()), + float(preview_max_height) / float(image.get_height()) + ) + ) + var preview_width: int = max(1, int(floor(float(image.get_width()) * scale))) + var preview_height: int = max(1, int(floor(float(image.get_height()) * scale))) + # Full image already saved to disk — resize in-place to avoid a redundant copy + image.resize(preview_width, preview_height, Image.INTERPOLATE_LANCZOS) + var preview_path: String = screenshot_dir.path_join("screenshot_%s_preview.png" % timestamp) + var preview_err: Error = image.save_png(preview_path) + if preview_err != OK: + _send_response(peer, {"error": "Failed to save screenshot preview (error %d)" % preview_err}) + return + response["preview_path"] = preview_path.replace("\\", "/") + response["preview_width"] = preview_width + response["preview_height"] = preview_height + + _send_response(peer, response) + +# --- Input Simulation --- + +func _handle_input(peer: PeerState, actions: Array) -> void: + var processed := 0 + var error_msg := "" + + for action in actions: + if typeof(action) != TYPE_DICTIONARY: + error_msg = "Action at index %d is not an object" % processed + break + + var type = action.get("type", "") + match type: + "key": + var result = _inject_key(action) + if result != "": + error_msg = "Action %d (key): %s" % [processed, result] + break + "mouse_button": + var result = _inject_mouse_button(action) + if result != "": + error_msg = "Action %d (mouse_button): %s" % [processed, result] + break + "mouse_motion": + _inject_mouse_motion(action) + "action": + var result = _inject_action(action) + if result != "": + error_msg = "Action %d (action): %s" % [processed, result] + break + "click_element": + var result = _inject_click_element(action) + if result != "": + error_msg = "Action %d (click_element): %s" % [processed, result] + break + "wait": + var ms = action.get("ms", 0) + if typeof(ms) == TYPE_FLOAT or typeof(ms) == TYPE_INT: + if ms > 0: + await get_tree().create_timer(ms / 1000.0).timeout + else: + error_msg = "Action %d (wait): ms must be a number" % processed + break + _: + error_msg = "Action %d: unknown type '%s'" % [processed, type] + break + + processed += 1 + + # Allow queued input events to dispatch and any signal handlers + # (and their runtime errors) to fire before we reply, so the + # Node-side stderr scan in sendCommandWithErrors sees them. + await get_tree().process_frame + await get_tree().process_frame + + if error_msg != "": + _send_response(peer, {"error": error_msg, "actions_processed": processed}) + else: + _send_response(peer, {"success": true, "actions_processed": processed}) + +func _inject_key(action: Dictionary) -> String: + var key_name = action.get("key", "") + if key_name == "": + return "key name is required" + + var keycode = OS.find_keycode_from_string(key_name) + if keycode == KEY_NONE: + return "unrecognized key name: '%s'" % key_name + + var event = InputEventKey.new() + event.keycode = keycode + event.physical_keycode = keycode + event.pressed = action.get("pressed", true) + event.echo = false + event.shift_pressed = action.get("shift", false) + event.ctrl_pressed = action.get("ctrl", false) + event.alt_pressed = action.get("alt", false) + # Text-entry Controls (LineEdit, TextEdit) consume `event.unicode`, not just + # the keycode — without it, typing into a focused LineEdit produces nothing. + # Auto-derive for ASCII letters and digits; fall back to caller-supplied + # `unicode` for symbols and non-ASCII. + if action.has("unicode"): + event.unicode = int(action.unicode) + elif keycode >= KEY_A and keycode <= KEY_Z: + event.unicode = keycode if event.shift_pressed else (keycode + 32) + elif keycode >= KEY_0 and keycode <= KEY_9: + event.unicode = keycode + Input.parse_input_event(event) + return "" + +func _resolve_button_name(button_name: String) -> Array: + match button_name: + "left": + return [MOUSE_BUTTON_LEFT, ""] + "right": + return [MOUSE_BUTTON_RIGHT, ""] + "middle": + return [MOUSE_BUTTON_MIDDLE, ""] + _: + return [MOUSE_BUTTON_NONE, "unknown button: '%s' (use 'left', 'right', or 'middle')" % button_name] + +func _inject_mouse_button(action: Dictionary) -> String: + var button_result := _resolve_button_name(action.get("button", "left")) + if button_result[1] != "": + return button_result[1] + var button_index: MouseButton = button_result[0] + + var pos = Vector2(action.get("x", 0), action.get("y", 0)) + var double_click = action.get("double_click", false) + + # If pressed is explicitly set, only do that one event + if action.has("pressed"): + var event = InputEventMouseButton.new() + event.button_index = button_index + event.pressed = action.get("pressed") + event.position = pos + event.global_position = pos + event.double_click = double_click + Input.parse_input_event(event) + else: + # Auto press + release (click) + var press = InputEventMouseButton.new() + press.button_index = button_index + press.pressed = true + press.position = pos + press.global_position = pos + press.double_click = double_click + Input.parse_input_event(press) + + var release = InputEventMouseButton.new() + release.button_index = button_index + release.pressed = false + release.position = pos + release.global_position = pos + Input.parse_input_event(release) + + return "" + +func _inject_mouse_motion(action: Dictionary) -> void: + var event = InputEventMouseMotion.new() + event.position = Vector2(action.get("x", 0), action.get("y", 0)) + event.global_position = event.position + event.relative = Vector2(action.get("relative_x", 0), action.get("relative_y", 0)) + Input.parse_input_event(event) + +func _inject_action(action: Dictionary) -> String: + var action_name = action.get("action", "") + if action_name == "": + return "action name is required" + + var pressed = action.get("pressed", true) + var strength = action.get("strength", 1.0) + + if pressed: + Input.action_press(action_name, strength) + else: + Input.action_release(action_name) + return "" + +func _inject_click_element(action: Dictionary) -> String: + var identifier: String = action.get("element", "") + if identifier == "": + return "element identifier is required" + + var target := _find_control_by_identifier(identifier) + if target == null: + return "Could not find UI element: %s" % identifier + + if not target.is_visible_in_tree(): + return "UI element '%s' is not visible" % identifier + + var button_result := _resolve_button_name(action.get("button", "left")) + if button_result[1] != "": + return button_result[1] + var button_index: MouseButton = button_result[0] + var double_click: bool = action.get("double_click", false) + var rect := target.get_global_rect() + var center := rect.get_center() + + var press := InputEventMouseButton.new() + press.button_index = button_index + press.pressed = true + press.position = center + press.global_position = center + press.double_click = double_click + Input.parse_input_event(press) + + var release := InputEventMouseButton.new() + release.button_index = button_index + release.pressed = false + release.position = center + release.global_position = center + Input.parse_input_event(release) + + return "" + +# --- UI Element Discovery --- + +func _handle_get_ui_elements(peer: PeerState, payload: Dictionary) -> void: + var visible_only: bool = payload.get("visible_only", true) + var type_filter: String = payload.get("type_filter", "") + var root := get_tree().root + var elements: Array[Dictionary] = [] + _collect_control_nodes(root, elements, visible_only, type_filter) + _send_response(peer, {"elements": elements}) + +func _collect_control_nodes(node: Node, elements: Array[Dictionary], visible_only: bool, type_filter: String = "") -> void: + if node is Control: + var ctrl := node as Control + if visible_only and not ctrl.is_visible_in_tree(): + return + if type_filter != "" and not ctrl.is_class(type_filter): + # Still recurse into children even if this node doesn't match + for child in node.get_children(): + _collect_control_nodes(child, elements, visible_only, type_filter) + return + var rect := ctrl.get_global_rect() + var element := { + "name": String(ctrl.name), + "type": ctrl.get_class(), + "path": str(ctrl.get_path()), + "rect": { + "x": rect.position.x, + "y": rect.position.y, + "width": rect.size.x, + "height": rect.size.y, + }, + "visible": ctrl.is_visible_in_tree(), + } + # Extract text content for common Control types + if ctrl is Button: + element["text"] = (ctrl as Button).text + elif ctrl is Label: + element["text"] = (ctrl as Label).text + elif ctrl is LineEdit: + element["text"] = (ctrl as LineEdit).text + element["placeholder"] = (ctrl as LineEdit).placeholder_text + elif ctrl is TextEdit: + element["text"] = (ctrl as TextEdit).text + elif ctrl is RichTextLabel: + element["text"] = (ctrl as RichTextLabel).text + # Disabled state for buttons + if ctrl is BaseButton: + element["disabled"] = (ctrl as BaseButton).disabled + # Tooltip + if ctrl.tooltip_text != "": + element["tooltip"] = ctrl.tooltip_text + elements.append(element) + for child in node.get_children(): + _collect_control_nodes(child, elements, visible_only, type_filter) + +func _find_control_by_identifier(identifier: String) -> Control: + var root := get_tree().root + # Try as node path first + if identifier.begins_with("/"): + var abs_node := root.get_node_or_null(NodePath(identifier)) + if abs_node is Control: + return abs_node as Control + # Try as relative path from root + var node := root.get_node_or_null(NodePath(identifier)) + if node is Control: + return node as Control + # BFS: match by node name + var queue: Array[Node] = [] + queue.append(root) + while not queue.is_empty(): + var current: Node = queue.pop_front() + if current is Control: + if String(current.name) == identifier: + return current as Control + for child in current.get_children(): + queue.append(child) + return null + +# --- Script Execution --- + +func _handle_run_script(peer: PeerState, payload: Dictionary) -> void: + var source: String = payload.get("source", "") + if source.strip_edges() == "": + _send_response(peer, {"error": "No script source provided"}) + return + + # Compile the script at runtime + var script := GDScript.new() + script.source_code = source + var err := script.reload() + if err != OK: + _send_response(peer, {"error": "Script compilation failed (error %d). Check syntax." % err}) + return + + # Instantiate and validate + var instance = script.new() + if instance == null: + _send_response(peer, {"error": "Failed to instantiate script"}) + return + + if not instance.has_method("execute"): + if instance is RefCounted: + instance = null # Let RefCounted free itself + else: + instance.free() + _send_response(peer, {"error": "Script must define func execute(scene_tree: SceneTree) -> Variant"}) + return + + # Execute (await in case the user's script uses async/await internally) + var result = await instance.execute(get_tree()) + + # Clean up + if instance is RefCounted: + instance = null + else: + instance.free() + + # Serialize and respond + var serialized = _serialize_value(result) + _send_response(peer, {"success": true, "result": serialized}) + +func _serialize_value(value: Variant) -> Variant: + if value == null: + return null + + match typeof(value): + TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING: + return value + TYPE_VECTOR2: + var v: Vector2 = value + return {"x": v.x, "y": v.y} + TYPE_VECTOR2I: + var v: Vector2i = value + return {"x": v.x, "y": v.y} + TYPE_VECTOR3: + var v: Vector3 = value + return {"x": v.x, "y": v.y, "z": v.z} + TYPE_VECTOR3I: + var v: Vector3i = value + return {"x": v.x, "y": v.y, "z": v.z} + TYPE_COLOR: + var c: Color = value + return {"r": c.r, "g": c.g, "b": c.b, "a": c.a} + TYPE_DICTIONARY: + var d: Dictionary = value + var result := {} + for key in d: + result[str(key)] = _serialize_value(d[key]) + return result + TYPE_ARRAY: + var a: Array = value + var result := [] + for item in a: + result.append(_serialize_value(item)) + return result + TYPE_OBJECT: + if value is Node: + var node: Node = value + return {"class": node.get_class(), "name": String(node.name), "path": str(node.get_path())} + elif value is Resource: + var res: Resource = value + return {"class": res.get_class(), "path": res.resource_path} + else: + return str(value) + _: + return str(value) + +# --- Shutdown --- + +func _handle_shutdown(peer: PeerState) -> void: + _shutting_down = true + _send_response(peer, {"status": "shutting_down"}) + # Let the response flush before we tear the listener down. A new command + # arriving in this 2-frame window would dispatch against a peer that's + # about to close; the response write fails gracefully and the Node side + # sees BridgeDisconnectedError. MCP serializes calls so this is theoretical. + await get_tree().process_frame + await get_tree().process_frame + _close_all_peers() + if tcp_server != null: + tcp_server.stop() + # Detach from the tree so subsequent _process ticks don't run. + queue_free() + +# --- Utility --- + +func _send_response(peer: PeerState, data: Dictionary) -> void: + var resp := JSON.stringify(data) + var body := resp.to_utf8_buffer() + if body.size() > MAX_FRAME_BYTES: + push_error("McpBridge: Response exceeds %d bytes; dropping" % MAX_FRAME_BYTES) + peer.handling = false + return + if peer.stream != null and peer.stream.get_status() == StreamPeerTCP.STATUS_CONNECTED: + var header := PackedByteArray() + header.resize(FRAME_HEADER_BYTES) + var size := body.size() + header[0] = (size >> 24) & 0xFF + header[1] = (size >> 16) & 0xFF + header[2] = (size >> 8) & 0xFF + header[3] = size & 0xFF + peer.stream.put_data(header) + peer.stream.put_data(body) + peer.handling = false + +func _close_all_peers() -> void: + for peer in _peers: + if peer.stream != null: + peer.stream.disconnect_from_host() + peer.stream = null + _peers.clear() + +func _exit_tree() -> void: + if not _shutting_down: + push_warning("McpBridge: removed from tree without shutdown — bridge connection will be lost") + _close_all_peers() + if tcp_server != null: + tcp_server.stop() + tcp_server = null + print("McpBridge: Stopped") diff --git a/package/dist/scripts/mcp_bridge.gd.uid b/package/dist/scripts/mcp_bridge.gd.uid new file mode 100644 index 0000000..e37d0cd --- /dev/null +++ b/package/dist/scripts/mcp_bridge.gd.uid @@ -0,0 +1 @@ +uid://3qvnaku3p3c3 diff --git a/package/dist/tools/autoload-tools.d.ts b/package/dist/tools/autoload-tools.d.ts new file mode 100644 index 0000000..df7b7e1 --- /dev/null +++ b/package/dist/tools/autoload-tools.d.ts @@ -0,0 +1,51 @@ +import type { OperationParams, ToolDefinition } from '../utils/godot-runner.js'; +export declare const autoloadToolDefinitions: ToolDefinition[]; +export declare function handleListAutoloads(args: OperationParams): { + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}; +export declare function handleAddAutoload(args: OperationParams): { + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}; +export declare function handleRemoveAutoload(args: OperationParams): { + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}; +export declare function handleUpdateAutoload(args: OperationParams): { + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}; +//# sourceMappingURL=autoload-tools.d.ts.map \ No newline at end of file diff --git a/package/dist/tools/autoload-tools.d.ts.map b/package/dist/tools/autoload-tools.d.ts.map new file mode 100644 index 0000000..204e773 --- /dev/null +++ b/package/dist/tools/autoload-tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"autoload-tools.d.ts","sourceRoot":"","sources":["../../src/tools/autoload-tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAkBhF,eAAO,MAAM,uBAAuB,EAAE,cAAc,EAqEnD,CAAC;AAIF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe;;;;;;;;;;;EAcxD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe;;;;;;;;;;;EA+CtD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe;;;;;;;;;;;EA2BzD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe;;;;;;;;;;;EAsCzD"} \ No newline at end of file diff --git a/package/dist/tools/autoload-tools.js b/package/dist/tools/autoload-tools.js new file mode 100644 index 0000000..07eea48 --- /dev/null +++ b/package/dist/tools/autoload-tools.js @@ -0,0 +1,191 @@ +import { readFileSync } from 'fs'; +import { normalizeParameters, validateSubPath, validateProjectArgs, createErrorResponse, getErrorMessage, projectGodotPath, } from '../utils/godot-runner.js'; +import { parseAutoloads, addAutoloadEntry, removeAutoloadEntry, updateAutoloadEntry, } from '../utils/autoload-ini.js'; +// --- Tool definitions --- +export const autoloadToolDefinitions = [ + { + name: 'list_autoloads', + description: 'List all registered autoloads in a project with paths and singleton status. Use first when diagnosing headless failures — broken autoloads crash all headless ops, so this tells you what is loaded. No Godot process required (reads project.godot directly). Returns: [{ name, path, singleton }].', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + }, + required: ['projectPath'], + }, + }, + { + name: 'add_autoload', + description: 'Register a new autoload in a project. autoloadPath accepts "res://..." or a project-relative path (auto-prefixed). singleton defaults true (accessible globally by name). No Godot process required. Warning: autoloads initialize in headless mode — a broken script will crash every subsequent headless op; validate before adding. Returns plain-text confirmation with the registered name, path, and singleton flag. Errors if an autoload with the same name already exists; use update_autoload to modify.', + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + autoloadName: { + type: 'string', + description: 'Name of the autoload node (e.g. "MyManager")', + }, + autoloadPath: { + type: 'string', + description: 'Path to the script or scene (e.g. "res://autoload/my_manager.gd" or "autoload/my_manager.gd")', + }, + singleton: { + type: 'boolean', + description: 'Register as a globally accessible singleton by name (default: true)', + }, + }, + required: ['projectPath', 'autoloadName', 'autoloadPath'], + }, + }, + { + name: 'remove_autoload', + description: 'Unregister an autoload from a project by name. Use to recover from a broken autoload that is crashing headless ops. No Godot process required. Returns plain-text confirmation on success. Errors if no autoload with that name exists.', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + autoloadName: { type: 'string', description: 'Name of the autoload to remove' }, + }, + required: ['projectPath', 'autoloadName'], + }, + }, + { + name: 'update_autoload', + description: "Modify an existing autoload's path or singleton flag. Pass either or both — omitted fields keep their current value. Use instead of remove_autoload + add_autoload (single edit, no orphan window). No Godot process required. Returns plain-text confirmation on success. Errors if autoloadName is not registered.", + annotations: { idempotentHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + autoloadName: { type: 'string', description: 'Name of the autoload to update' }, + autoloadPath: { type: 'string', description: 'New path to the script or scene' }, + singleton: { type: 'boolean', description: 'New singleton flag' }, + }, + required: ['projectPath', 'autoloadName'], + }, + }, +]; +// --- Handlers --- +export function handleListAutoloads(args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + try { + const projectFile = projectGodotPath(v.projectPath); + const autoloads = parseAutoloads(projectFile); + return { content: [{ type: 'text', text: JSON.stringify(autoloads) }] }; + } + catch (error) { + return createErrorResponse(`Failed to list autoloads: ${getErrorMessage(error)}`, [ + 'Check if project.godot is accessible', + ]); + } +} +export function handleAddAutoload(args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + if (!args.autoloadName || !args.autoloadPath) { + return createErrorResponse('autoloadName and autoloadPath are required', [ + 'Provide the autoload node name and script/scene path', + ]); + } + if (!validateSubPath(v.projectPath, args.autoloadPath)) { + return createErrorResponse('Invalid autoload path', [ + 'Provide a valid relative path or res:// URI that stays inside the project directory', + ]); + } + try { + const projectFile = projectGodotPath(v.projectPath); + const projectFileContent = readFileSync(projectFile, 'utf8'); + const existing = parseAutoloads(projectFile, projectFileContent); + if (existing.some((a) => a.name === args.autoloadName)) { + return createErrorResponse(`Autoload '${args.autoloadName}' already exists`, [ + 'Use update_autoload to modify it', + 'Use list_autoloads to see current autoloads', + ]); + } + const isSingleton = args.singleton !== false; + addAutoloadEntry(projectFile, args.autoloadName, args.autoloadPath, isSingleton, projectFileContent); + return { + content: [ + { + type: 'text', + text: `Autoload '${args.autoloadName}' registered at '${args.autoloadPath}' (singleton: ${isSingleton}).\nWarning: autoloads initialize in headless mode too. If this script has errors, all headless operations will fail. Verify by running get_scene_tree — if it fails, use remove_autoload to remove it.`, + }, + ], + }; + } + catch (error) { + return createErrorResponse(`Failed to add autoload: ${getErrorMessage(error)}`, [ + 'Check if project.godot is accessible', + ]); + } +} +export function handleRemoveAutoload(args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + if (!args.autoloadName) { + return createErrorResponse('autoloadName is required', [ + 'Provide the name of the autoload to remove', + ]); + } + try { + const projectFile = projectGodotPath(v.projectPath); + const removed = removeAutoloadEntry(projectFile, args.autoloadName); + if (!removed) { + return createErrorResponse(`Autoload '${args.autoloadName}' not found`, [ + 'Use list_autoloads to see existing autoloads', + ]); + } + return { + content: [{ type: 'text', text: `Autoload '${args.autoloadName}' removed successfully.` }], + }; + } + catch (error) { + return createErrorResponse(`Failed to remove autoload: ${getErrorMessage(error)}`, [ + 'Check if project.godot is accessible', + ]); + } +} +export function handleUpdateAutoload(args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + if (!args.autoloadName) { + return createErrorResponse('autoloadName is required', [ + 'Provide the name of the autoload to update', + ]); + } + if (args.autoloadPath && !validateSubPath(v.projectPath, args.autoloadPath)) { + return createErrorResponse('Invalid autoload path', [ + 'Provide a valid relative path or res:// URI that stays inside the project directory', + ]); + } + try { + const projectFile = projectGodotPath(v.projectPath); + const updated = updateAutoloadEntry(projectFile, args.autoloadName, args.autoloadPath, args.singleton); + if (!updated) { + return createErrorResponse(`Autoload '${args.autoloadName}' not found`, [ + 'Use list_autoloads to see existing autoloads', + 'Use add_autoload to register a new one', + ]); + } + return { + content: [{ type: 'text', text: `Autoload '${args.autoloadName}' updated successfully.` }], + }; + } + catch (error) { + return createErrorResponse(`Failed to update autoload: ${getErrorMessage(error)}`, [ + 'Check if project.godot is accessible', + ]); + } +} +//# sourceMappingURL=autoload-tools.js.map \ No newline at end of file diff --git a/package/dist/tools/autoload-tools.js.map b/package/dist/tools/autoload-tools.js.map new file mode 100644 index 0000000..0c98a8b --- /dev/null +++ b/package/dist/tools/autoload-tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"autoload-tools.js","sourceRoot":"","sources":["../../src/tools/autoload-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAElC,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAElC,2BAA2B;AAE3B,MAAM,CAAC,MAAM,uBAAuB,GAAqB;IACvD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,sSAAsS;QACxS,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;QACnC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;aACpF;YACD,QAAQ,EAAE,CAAC,aAAa,CAAC;SAC1B;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,ofAAof;QACtf,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,8CAA8C;iBAC5D;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,+FAA+F;iBAClG;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,qEAAqE;iBACnF;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,cAAc,EAAE,cAAc,CAAC;SAC1D;KACF;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EACT,yOAAyO;QAC3O,WAAW,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;QACtC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE;aAChF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC;SAC1C;KACF;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EACT,sTAAsT;QACxT,WAAW,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;QACrC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE;gBAC/E,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iCAAiC,EAAE;gBAChF,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE;aAClE;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC;SAC1C;KACF;CACF,CAAC;AAEF,mBAAmB;AAEnB,MAAM,UAAU,mBAAmB,CAAC,IAAqB;IACvD,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;QAC9C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;IAC1E,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,mBAAmB,CAAC,6BAA6B,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE;YAChF,sCAAsC;SACvC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QAC7C,OAAO,mBAAmB,CAAC,4CAA4C,EAAE;YACvE,sDAAsD;SACvD,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,YAAsB,CAAC,EAAE,CAAC;QACjE,OAAO,mBAAmB,CAAC,uBAAuB,EAAE;YAClD,qFAAqF;SACtF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,kBAAkB,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,cAAc,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;QACjE,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAM,IAAI,CAAC,YAAuB,CAAC,EAAE,CAAC;YACnE,OAAO,mBAAmB,CAAC,aAAa,IAAI,CAAC,YAAY,kBAAkB,EAAE;gBAC3E,kCAAkC;gBAClC,6CAA6C;aAC9C,CAAC,CAAC;QACL,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC;QAC7C,gBAAgB,CACd,WAAW,EACX,IAAI,CAAC,YAAsB,EAC3B,IAAI,CAAC,YAAsB,EAC3B,WAAW,EACX,kBAAkB,CACnB,CAAC;QACF,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,aAAa,IAAI,CAAC,YAAY,oBAAoB,IAAI,CAAC,YAAY,iBAAiB,WAAW,yMAAyM;iBAC/S;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,mBAAmB,CAAC,2BAA2B,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE;YAC9E,sCAAsC;SACvC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAqB;IACxD,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACvB,OAAO,mBAAmB,CAAC,0BAA0B,EAAE;YACrD,4CAA4C;SAC7C,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,YAAsB,CAAC,CAAC;QAC9E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,mBAAmB,CAAC,aAAa,IAAI,CAAC,YAAY,aAAa,EAAE;gBACtE,8CAA8C;aAC/C,CAAC,CAAC;QACL,CAAC;QACD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,IAAI,CAAC,YAAY,yBAAyB,EAAE,CAAC;SAC3F,CAAC;IACJ,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,mBAAmB,CAAC,8BAA8B,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE;YACjF,sCAAsC;SACvC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAqB;IACxD,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACvB,OAAO,mBAAmB,CAAC,0BAA0B,EAAE;YACrD,4CAA4C;SAC7C,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,YAAsB,CAAC,EAAE,CAAC;QACtF,OAAO,mBAAmB,CAAC,uBAAuB,EAAE;YAClD,qFAAqF;SACtF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,mBAAmB,CACjC,WAAW,EACX,IAAI,CAAC,YAAsB,EAC3B,IAAI,CAAC,YAAkC,EACvC,IAAI,CAAC,SAAgC,CACtC,CAAC;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,mBAAmB,CAAC,aAAa,IAAI,CAAC,YAAY,aAAa,EAAE;gBACtE,8CAA8C;gBAC9C,wCAAwC;aACzC,CAAC,CAAC;QACL,CAAC;QACD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,IAAI,CAAC,YAAY,yBAAyB,EAAE,CAAC;SAC3F,CAAC;IACJ,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,mBAAmB,CAAC,8BAA8B,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE;YACjF,sCAAsC;SACvC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/package/dist/tools/node-tools.d.ts b/package/dist/tools/node-tools.d.ts new file mode 100644 index 0000000..fc19a3e --- /dev/null +++ b/package/dist/tools/node-tools.d.ts @@ -0,0 +1,66 @@ +import type { GodotRunner, OperationParams, ToolDefinition } from '../utils/godot-runner.js'; +export declare const nodeToolDefinitions: ToolDefinition[]; +export declare function handleDeleteNodes(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleSetNodeProperties(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleGetNodeProperties(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleAttachScript(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleGetSceneTree(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleDuplicateNode(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleGetNodeSignals(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleConnectSignal(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleDisconnectSignal(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +//# sourceMappingURL=node-tools.d.ts.map \ No newline at end of file diff --git a/package/dist/tools/node-tools.d.ts.map b/package/dist/tools/node-tools.d.ts.map new file mode 100644 index 0000000..7bff591 --- /dev/null +++ b/package/dist/tools/node-tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node-tools.d.ts","sourceRoot":"","sources":["../../src/tools/node-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAY7F,eAAO,MAAM,mBAAmB,EAAE,cAAc,EAqS/C,CAAC;AAIF,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GA6BjF;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GA0BvF;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAoBvF;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAqClF;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAsBlF;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GA6BnF;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAsBpF;AAyCD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAoBnF;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAoBtF"} \ No newline at end of file diff --git a/package/dist/tools/node-tools.js b/package/dist/tools/node-tools.js new file mode 100644 index 0000000..cba05f6 --- /dev/null +++ b/package/dist/tools/node-tools.js @@ -0,0 +1,473 @@ +import { existsSync } from 'fs'; +import { join } from 'path'; +import { normalizeParameters, validateSubPath, validateNodePath, createErrorResponse, validateSceneArgs, } from '../utils/godot-runner.js'; +import { executeSceneOp } from '../utils/handler-helpers.js'; +// --- Tool definitions --- +export const nodeToolDefinitions = [ + { + name: 'delete_nodes', + description: 'Remove one or more nodes (and their descendants) from a scene file. Always-array: pass a single-element nodePaths array for one-off deletes. Saves once at the end. Cannot delete the scene root — that entry returns an error and the rest still process. Returns: results array with one entry per nodePath in input order (success or error message).', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { + type: 'string', + description: 'Scene file path relative to the project (e.g. "scenes/main.tscn")', + }, + nodePaths: { + type: 'array', + items: { type: 'string' }, + description: 'Node paths from scene root to delete (e.g. ["root/Player/Sprite2D"])', + }, + }, + required: ['projectPath', 'scenePath', 'nodePaths'], + }, + outputSchema: { + type: 'object', + properties: { + results: { + type: 'array', + items: { + type: 'object', + properties: { + nodePath: { type: 'string' }, + success: { type: 'boolean' }, + error: { type: 'string' }, + }, + }, + }, + }, + }, + }, + { + name: 'set_node_properties', + description: 'Set one or more node properties on a scene in a single Godot process. Always-array: pass a single-element updates array for one-off edits. Vector2 ({x,y}), Vector3 ({x,y,z}), and Color ({r,g,b,a}) auto-convert; primitives pass through. For other complex GDScript types (Resource, NodePath, etc.), use run_script. abortOnError stops on first failure (default false continues). Saves once at the end. Returns: results[] with one entry per update in input order (success or error).', + annotations: { idempotentHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + updates: { + type: 'array', + description: 'Property updates to apply', + items: { + type: 'object', + properties: { + nodePath: { + type: 'string', + description: 'Node path from scene root (e.g. "root/Player")', + }, + property: { + type: 'string', + description: 'GDScript property name in snake_case (e.g. "position", "modulate", "collision_layer")', + }, + value: { description: 'New property value' }, + }, + required: ['nodePath', 'property', 'value'], + }, + }, + abortOnError: { + type: 'boolean', + description: 'Stop processing on first error (default: false)', + }, + }, + required: ['projectPath', 'scenePath', 'updates'], + }, + outputSchema: { + type: 'object', + properties: { + results: { + type: 'array', + items: { + type: 'object', + properties: { + nodePath: { type: 'string' }, + property: { type: 'string' }, + success: { type: 'boolean' }, + error: { type: 'string' }, + }, + }, + }, + }, + }, + }, + { + name: 'get_node_properties', + description: "Read one or more nodes' current property values from a scene file in a single Godot process. Always-array: pass a single-element nodes array for one-off reads. Per-node changedOnly:true filters out properties matching class defaults (useful for compact diffs). Returns: { results: [{ nodePath, nodeType, properties?, error? }] }; failed reads include error and omit properties.", + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + nodes: { + type: 'array', + description: 'Nodes to read properties from', + items: { + type: 'object', + properties: { + nodePath: { + type: 'string', + description: 'Node path from scene root (e.g. "root/Player")', + }, + changedOnly: { + type: 'boolean', + description: 'Only return properties differing from defaults (default: false)', + }, + }, + required: ['nodePath'], + }, + }, + }, + required: ['projectPath', 'scenePath', 'nodes'], + }, + }, + { + name: 'attach_script', + description: 'Attach an existing GDScript file to a node in a scene. Use after writing the script with the standard file tools and validating it via the validate tool. Replaces any previously attached script. Saves automatically. Returns: success with the resolved nodePath and scriptPath that were attached. Errors if scriptPath does not exist or nodePath is not found.', + annotations: { idempotentHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + nodePath: { type: 'string', description: 'Node path from scene root (e.g. "root/Player")' }, + scriptPath: { + type: 'string', + description: 'Path to the GDScript file relative to the project (e.g. "scripts/player.gd")', + }, + }, + required: ['projectPath', 'scenePath', 'nodePath', 'scriptPath'], + }, + outputSchema: { + type: 'object', + properties: { + success: { type: 'boolean' }, + nodePath: { type: 'string' }, + scriptPath: { type: 'string' }, + }, + }, + }, + { + name: 'get_scene_tree', + description: 'Get the scene hierarchy as a nested tree of { name, type, path, script, children }. Use maxDepth:1 for a shallow listing of direct children only; default -1 returns the full tree. parentPath scopes the result to a subtree. Returns the nested tree as JSON text. Errors if scene does not exist or parentPath is not found.', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + parentPath: { + type: 'string', + description: 'Scope to a subtree starting at this node path (e.g. "root/Player")', + }, + maxDepth: { + type: 'number', + description: 'Maximum recursion depth. -1 for unlimited (default: -1). 1 returns only direct children.', + }, + }, + required: ['projectPath', 'scenePath'], + }, + }, + { + name: 'duplicate_node', + description: 'Duplicate a node and its descendants in a Godot scene. Use to clone a configured subtree without re-creating it node-by-node via add_node. newName defaults to the original name + "2"; targetParentPath defaults to the original parent. Saves automatically. Returns: success with originalPath and the newPath where the duplicate now lives — use newPath for follow-up edits. Errors if nodePath does not exist or targetParentPath cannot accept children.', + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + nodePath: { type: 'string', description: 'Node path from scene root to duplicate' }, + newName: { + type: 'string', + description: 'Name for the duplicated node (default: original name + "2")', + }, + targetParentPath: { + type: 'string', + description: 'Parent node path for the duplicate (default: same parent as original)', + }, + }, + required: ['projectPath', 'scenePath', 'nodePath'], + }, + outputSchema: { + type: 'object', + properties: { + success: { type: 'boolean' }, + originalPath: { type: 'string' }, + newPath: { type: 'string' }, + }, + }, + }, + { + name: 'get_node_signals', + description: 'List all signals defined on a node and their current connections. Use before connect_signal/disconnect_signal to verify signal/method names. The connections[].target field uses Godot absolute path format (/root/Scene/Node) — convert to scene-root-relative (root/Node) before passing to connect/disconnect_signal. Returns: nodeType and signals[], each with name and current connections (signal/target/method). Errors if node not found.', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + nodePath: { type: 'string', description: 'Node path from scene root (e.g. "root/Button")' }, + }, + required: ['projectPath', 'scenePath', 'nodePath'], + }, + outputSchema: { + type: 'object', + properties: { + nodePath: { type: 'string' }, + nodeType: { type: 'string' }, + signals: { + type: 'array', + items: { + type: 'object', + properties: { + name: { type: 'string' }, + connections: { + type: 'array', + items: { + type: 'object', + properties: { + signal: { type: 'string' }, + target: { type: 'string' }, + method: { type: 'string' }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: 'connect_signal', + description: 'Connect a signal on a source node to a method on a target node, persisting the connection in the .tscn. Use after get_node_signals to confirm the signal name on the source and the method name on the target. Connecting the same signal+method pair twice creates a duplicate connection — call get_node_signals first if uncertain. Saves automatically. Returns a plain-text confirmation naming the source, signal, target, and method. Errors if the signal does not exist on the source node or the method does not exist on the target node.', + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + nodePath: { type: 'string', description: 'Source node path from scene root' }, + signal: { + type: 'string', + description: 'Signal name on the source node (e.g. "pressed", "body_entered")', + }, + targetNodePath: { + type: 'string', + description: 'Target node path from scene root that receives the signal', + }, + method: { + type: 'string', + description: 'Method name on the target node to call when the signal fires', + }, + }, + required: ['projectPath', 'scenePath', 'nodePath', 'signal', 'targetNodePath', 'method'], + }, + }, + { + name: 'disconnect_signal', + description: 'Remove an existing signal connection between two nodes, persisting the change in the .tscn. Use get_node_signals first to confirm the connection exists; recovery requires reconnecting via connect_signal. Saves automatically. Returns a plain-text confirmation naming the disconnected signal and target. Errors if the connection does not exist.', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + nodePath: { type: 'string', description: 'Source node path from scene root' }, + signal: { type: 'string', description: 'Signal name on the source node' }, + targetNodePath: { type: 'string', description: 'Target node path from scene root' }, + method: { type: 'string', description: 'Method name on the target node' }, + }, + required: ['projectPath', 'scenePath', 'nodePath', 'signal', 'targetNodePath', 'method'], + }, + }, +]; +// --- Handlers --- +export async function handleDeleteNodes(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.nodePaths || !Array.isArray(args.nodePaths) || args.nodePaths.length === 0) { + return createErrorResponse('nodePaths array is required', [ + 'Provide a non-empty array of node paths (e.g. ["root/Player"])', + ]); + } + for (const p of args.nodePaths) { + if (typeof p !== 'string' || !validateNodePath(p)) { + return createErrorResponse('Invalid nodePath in nodePaths', [ + 'Provide a scene-tree path without ".." (e.g. "root/Player")', + ]); + } + } + const params = { scenePath: args.scenePath, nodePaths: args.nodePaths }; + return executeSceneOp(runner, 'delete_nodes', params, v.projectPath, 'Failed to delete nodes', ['Check if the node paths are correct'], undefined, { parseStdoutAsJson: true }); +} +export async function handleSetNodeProperties(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.updates || !Array.isArray(args.updates)) { + return createErrorResponse('updates array is required', [ + 'Provide an array of { nodePath, property, value }', + ]); + } + const params = { + scenePath: args.scenePath, + updates: args.updates, + abortOnError: args.abortOnError ?? false, + }; + return executeSceneOp(runner, 'set_node_properties', params, v.projectPath, 'Failed to set node properties', ['Check node paths and property names'], undefined, { parseStdoutAsJson: true }); +} +export async function handleGetNodeProperties(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.nodes || !Array.isArray(args.nodes)) { + return createErrorResponse('nodes array is required', [ + 'Provide an array of { nodePath, changedOnly? }', + ]); + } + const params = { scenePath: args.scenePath, nodes: args.nodes }; + return executeSceneOp(runner, 'get_node_properties', params, v.projectPath, 'Failed to get node properties', ['Check node paths']); +} +export async function handleAttachScript(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.nodePath || !validateNodePath(args.nodePath)) { + return createErrorResponse('Valid nodePath is required', [ + 'Provide the node path (e.g. "root/Player")', + ]); + } + if (!args.scriptPath || !validateSubPath(v.projectPath, args.scriptPath)) { + return createErrorResponse('Valid scriptPath is required', [ + 'Provide a relative script path that stays inside the project directory', + ]); + } + const scriptFullPath = join(v.projectPath, args.scriptPath); + if (!existsSync(scriptFullPath)) { + return createErrorResponse(`Script file does not exist: ${args.scriptPath}`, [ + 'Create the script file first', + ]); + } + const params = { + scenePath: args.scenePath, + nodePath: args.nodePath, + scriptPath: args.scriptPath, + }; + return executeSceneOp(runner, 'attach_script', params, v.projectPath, 'Failed to attach script', ['Ensure the script is valid for this node type'], undefined, { parseStdoutAsJson: true }); +} +export async function handleGetSceneTree(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (args.parentPath && !validateNodePath(args.parentPath)) { + return createErrorResponse('Invalid parentPath', [ + 'Provide a scene-tree path without ".." (e.g. "root/Player")', + ]); + } + const params = { scenePath: args.scenePath }; + if (args.parentPath) + params.parentPath = args.parentPath; + if (typeof args.maxDepth === 'number') + params.maxDepth = args.maxDepth; + return executeSceneOp(runner, 'get_scene_tree', params, v.projectPath, 'Failed to get scene tree', ['Ensure the scene is valid']); +} +export async function handleDuplicateNode(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.nodePath || !validateNodePath(args.nodePath)) { + return createErrorResponse('Valid nodePath is required', [ + 'Provide the node path to duplicate', + ]); + } + if (args.targetParentPath && !validateNodePath(args.targetParentPath)) { + return createErrorResponse('Invalid targetParentPath', [ + 'Provide a scene-tree path without ".." (e.g. "root/Player")', + ]); + } + const params = { scenePath: args.scenePath, nodePath: args.nodePath }; + if (args.newName) + params.newName = args.newName; + if (args.targetParentPath) + params.targetParentPath = args.targetParentPath; + return executeSceneOp(runner, 'duplicate_node', params, v.projectPath, 'Failed to duplicate node', ['Check if the node path and target parent path are correct'], undefined, { parseStdoutAsJson: true }); +} +export async function handleGetNodeSignals(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.nodePath || !validateNodePath(args.nodePath)) { + return createErrorResponse('Valid nodePath is required', [ + 'Provide the node path (e.g. "root/Button")', + ]); + } + const params = { scenePath: args.scenePath, nodePath: args.nodePath }; + return executeSceneOp(runner, 'get_node_signals', params, v.projectPath, 'Failed to get node signals', ['Check if the node path is correct'], undefined, { parseStdoutAsJson: true }); +} +function validateSignalArgs(args) { + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.nodePath || !validateNodePath(args.nodePath)) { + return createErrorResponse('Valid nodePath is required', ['Provide the source node path']); + } + if (!args.signal || !args.targetNodePath || !args.method) { + return createErrorResponse('signal, targetNodePath, and method are required', [ + 'Provide all three parameters', + ]); + } + if (!validateNodePath(args.targetNodePath)) { + return createErrorResponse('Invalid targetNodePath', [ + 'Provide a scene-tree path without ".." (e.g. "root/Player")', + ]); + } + return { + projectPath: v.projectPath, + scenePath: v.scenePath, + nodePath: args.nodePath, + signal: args.signal, + targetNodePath: args.targetNodePath, + method: args.method, + }; +} +export async function handleConnectSignal(runner, args) { + args = normalizeParameters(args); + const v = validateSignalArgs(args); + if ('isError' in v) + return v; + const params = { + scenePath: v.scenePath, + nodePath: v.nodePath, + signal: v.signal, + targetNodePath: v.targetNodePath, + method: v.method, + }; + return executeSceneOp(runner, 'connect_signal', params, v.projectPath, 'Failed to connect signal', ['Ensure the signal exists on the source node and the method exists on the target node']); +} +export async function handleDisconnectSignal(runner, args) { + args = normalizeParameters(args); + const v = validateSignalArgs(args); + if ('isError' in v) + return v; + const params = { + scenePath: v.scenePath, + nodePath: v.nodePath, + signal: v.signal, + targetNodePath: v.targetNodePath, + method: v.method, + }; + return executeSceneOp(runner, 'disconnect_signal', params, v.projectPath, 'Failed to disconnect signal', ['Ensure the signal connection exists before trying to disconnect it']); +} +//# sourceMappingURL=node-tools.js.map \ No newline at end of file diff --git a/package/dist/tools/node-tools.js.map b/package/dist/tools/node-tools.js.map new file mode 100644 index 0000000..fd691ed --- /dev/null +++ b/package/dist/tools/node-tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"node-tools.js","sourceRoot":"","sources":["../../src/tools/node-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,2BAA2B;AAE3B,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,0VAA0V;QAC5V,WAAW,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;QACtC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,mEAAmE;iBACjF;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,WAAW,EAAE,sEAAsE;iBACpF;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,WAAW,CAAC;SACpD;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BAC5B,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;4BAC5B,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;yBAC1B;qBACF;iBACF;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EACT,geAAge;QACle,WAAW,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;QACrC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACrF,OAAO,EAAE;oBACP,IAAI,EAAE,OAAO;oBACb,WAAW,EAAE,2BAA2B;oBACxC,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,QAAQ,EAAE;gCACR,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,gDAAgD;6BAC9D;4BACD,QAAQ,EAAE;gCACR,IAAI,EAAE,QAAQ;gCACd,WAAW,EACT,uFAAuF;6BAC1F;4BACD,KAAK,EAAE,EAAE,WAAW,EAAE,oBAAoB,EAAE;yBAC7C;wBACD,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC;qBAC5C;iBACF;gBACD,YAAY,EAAE;oBACZ,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,iDAAiD;iBAC/D;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,SAAS,CAAC;SAClD;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BAC5B,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BAC5B,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;4BAC5B,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;yBAC1B;qBACF;iBACF;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EACT,2XAA2X;QAC7X,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;QACnC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACrF,KAAK,EAAE;oBACL,IAAI,EAAE,OAAO;oBACb,WAAW,EAAE,+BAA+B;oBAC5C,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,QAAQ,EAAE;gCACR,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,gDAAgD;6BAC9D;4BACD,WAAW,EAAE;gCACX,IAAI,EAAE,SAAS;gCACf,WAAW,EAAE,iEAAiE;6BAC/E;yBACF;wBACD,QAAQ,EAAE,CAAC,UAAU,CAAC;qBACvB;iBACF;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,CAAC;SAChD;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,sWAAsW;QACxW,WAAW,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;QACrC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACrF,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gDAAgD,EAAE;gBAC3F,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,8EAA8E;iBACjF;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,CAAC;SACjE;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;gBAC5B,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC5B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;aAC/B;SACF;KACF;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,iUAAiU;QACnU,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;QACnC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACrF,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oEAAoE;iBAClF;gBACD,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,0FAA0F;iBAC7F;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,WAAW,CAAC;SACvC;KACF;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,kcAAkc;QACpc,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACrF,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wCAAwC,EAAE;gBACnF,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,6DAA6D;iBAC3E;gBACD,gBAAgB,EAAE;oBAChB,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,uEAAuE;iBACrF;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,UAAU,CAAC;SACnD;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;gBAC5B,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAChC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;aAC5B;SACF;KACF;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,obAAob;QACtb,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;QACnC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACrF,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gDAAgD,EAAE;aAC5F;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,UAAU,CAAC;SACnD;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC5B,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC5B,OAAO,EAAE;oBACP,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BACxB,WAAW,EAAE;gCACX,IAAI,EAAE,OAAO;gCACb,KAAK,EAAE;oCACL,IAAI,EAAE,QAAQ;oCACd,UAAU,EAAE;wCACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wCAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wCAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;qCAC3B;iCACF;6BACF;yBACF;qBACF;iBACF;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,shBAAshB;QACxhB,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACrF,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;gBAC7E,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,iEAAiE;iBAC/E;gBACD,cAAc,EAAE;oBACd,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,2DAA2D;iBACzE;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,8DAA8D;iBAC5E;aACF;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,CAAC;SACzF;KACF;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,WAAW,EACT,wVAAwV;QAC1V,WAAW,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;QACtC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;gBACnF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;gBACrF,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;gBAC7E,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE;gBACzE,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;gBACnF,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE;aAC1E;YACD,QAAQ,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,CAAC;SACzF;KACF;CACF,CAAC;AAEF,mBAAmB;AAEnB,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAmB,EAAE,IAAqB;IAChF,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrF,OAAO,mBAAmB,CAAC,6BAA6B,EAAE;YACxD,gEAAgE;SACjE,CAAC,CAAC;IACL,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAsB,EAAE,CAAC;QAC5C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,OAAO,mBAAmB,CAAC,+BAA+B,EAAE;gBAC1D,6DAA6D;aAC9D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;IACxE,OAAO,cAAc,CACnB,MAAM,EACN,cAAc,EACd,MAAM,EACN,CAAC,CAAC,WAAW,EACb,wBAAwB,EACxB,CAAC,qCAAqC,CAAC,EACvC,SAAS,EACT,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAAmB,EAAE,IAAqB;IACtF,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAClD,OAAO,mBAAmB,CAAC,2BAA2B,EAAE;YACtD,mDAAmD;SACpD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG;QACb,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,KAAK;KACzC,CAAC;IACF,OAAO,cAAc,CACnB,MAAM,EACN,qBAAqB,EACrB,MAAM,EACN,CAAC,CAAC,WAAW,EACb,+BAA+B,EAC/B,CAAC,qCAAqC,CAAC,EACvC,SAAS,EACT,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAAmB,EAAE,IAAqB;IACtF,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9C,OAAO,mBAAmB,CAAC,yBAAyB,EAAE;YACpD,gDAAgD;SACjD,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAChE,OAAO,cAAc,CACnB,MAAM,EACN,qBAAqB,EACrB,MAAM,EACN,CAAC,CAAC,WAAW,EACb,+BAA+B,EAC/B,CAAC,kBAAkB,CAAC,CACrB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAmB,EAAE,IAAqB;IACjF,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAkB,CAAC,EAAE,CAAC;QACjE,OAAO,mBAAmB,CAAC,4BAA4B,EAAE;YACvD,4CAA4C;SAC7C,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,UAAoB,CAAC,EAAE,CAAC;QACnF,OAAO,mBAAmB,CAAC,8BAA8B,EAAE;YACzD,wEAAwE;SACzE,CAAC,CAAC;IACL,CAAC;IACD,MAAM,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,UAAoB,CAAC,CAAC;IACtE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,OAAO,mBAAmB,CAAC,+BAA+B,IAAI,CAAC,UAAU,EAAE,EAAE;YAC3E,8BAA8B;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG;QACb,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CAAC;IACF,OAAO,cAAc,CACnB,MAAM,EACN,eAAe,EACf,MAAM,EACN,CAAC,CAAC,WAAW,EACb,yBAAyB,EACzB,CAAC,+CAA+C,CAAC,EACjD,SAAS,EACT,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAmB,EAAE,IAAqB;IACjF,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAoB,CAAC,EAAE,CAAC;QACpE,OAAO,mBAAmB,CAAC,oBAAoB,EAAE;YAC/C,6DAA6D;SAC9D,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAoB,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;IAC9D,IAAI,IAAI,CAAC,UAAU;QAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IACzD,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;QAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IACvE,OAAO,cAAc,CACnB,MAAM,EACN,gBAAgB,EAChB,MAAM,EACN,CAAC,CAAC,WAAW,EACb,0BAA0B,EAC1B,CAAC,2BAA2B,CAAC,CAC9B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAmB,EAAE,IAAqB;IAClF,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAkB,CAAC,EAAE,CAAC;QACjE,OAAO,mBAAmB,CAAC,4BAA4B,EAAE;YACvD,oCAAoC;SACrC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,gBAA0B,CAAC,EAAE,CAAC;QAChF,OAAO,mBAAmB,CAAC,0BAA0B,EAAE;YACrD,6DAA6D;SAC9D,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAoB,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IACvF,IAAI,IAAI,CAAC,OAAO;QAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAChD,IAAI,IAAI,CAAC,gBAAgB;QAAE,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;IAC3E,OAAO,cAAc,CACnB,MAAM,EACN,gBAAgB,EAChB,MAAM,EACN,CAAC,CAAC,WAAW,EACb,0BAA0B,EAC1B,CAAC,2DAA2D,CAAC,EAC7D,SAAS,EACT,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAmB,EAAE,IAAqB;IACnF,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAkB,CAAC,EAAE,CAAC;QACjE,OAAO,mBAAmB,CAAC,4BAA4B,EAAE;YACvD,4CAA4C;SAC7C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IACtE,OAAO,cAAc,CACnB,MAAM,EACN,kBAAkB,EAClB,MAAM,EACN,CAAC,CAAC,WAAW,EACb,4BAA4B,EAC5B,CAAC,mCAAmC,CAAC,EACrC,SAAS,EACT,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAC5B,CAAC;AACJ,CAAC;AAWD,SAAS,kBAAkB,CACzB,IAAqB;IAErB,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAkB,CAAC,EAAE,CAAC;QACjE,OAAO,mBAAmB,CAAC,4BAA4B,EAAE,CAAC,8BAA8B,CAAC,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACzD,OAAO,mBAAmB,CAAC,iDAAiD,EAAE;YAC5E,8BAA8B;SAC/B,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAwB,CAAC,EAAE,CAAC;QACrD,OAAO,mBAAmB,CAAC,wBAAwB,EAAE;YACnD,6DAA6D;SAC9D,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,QAAQ,EAAE,IAAI,CAAC,QAAkB;QACjC,MAAM,EAAE,IAAI,CAAC,MAAgB;QAC7B,cAAc,EAAE,IAAI,CAAC,cAAwB;QAC7C,MAAM,EAAE,IAAI,CAAC,MAAgB;KAC9B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAmB,EAAE,IAAqB;IAClF,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,MAAM,MAAM,GAAG;QACb,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,cAAc,EAAE,CAAC,CAAC,cAAc;QAChC,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC;IACF,OAAO,cAAc,CACnB,MAAM,EACN,gBAAgB,EAChB,MAAM,EACN,CAAC,CAAC,WAAW,EACb,0BAA0B,EAC1B,CAAC,sFAAsF,CAAC,CACzF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAmB,EAAE,IAAqB;IACrF,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,MAAM,MAAM,GAAG;QACb,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,cAAc,EAAE,CAAC,CAAC,cAAc;QAChC,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC;IACF,OAAO,cAAc,CACnB,MAAM,EACN,mBAAmB,EACnB,MAAM,EACN,CAAC,CAAC,WAAW,EACb,6BAA6B,EAC7B,CAAC,oEAAoE,CAAC,CACvE,CAAC;AACJ,CAAC"} \ No newline at end of file diff --git a/package/dist/tools/project-tools.d.ts b/package/dist/tools/project-tools.d.ts new file mode 100644 index 0000000..a332f2e --- /dev/null +++ b/package/dist/tools/project-tools.d.ts @@ -0,0 +1,65 @@ +import type { GodotRunner, OperationParams, ToolDefinition } from '../utils/godot-runner.js'; +export declare const projectToolDefinitions: ToolDefinition[]; +export declare function handleListProjects(args: OperationParams): Promise<{ + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}>; +export declare function handleGetProjectInfo(runner: GodotRunner, args: OperationParams): Promise<{ + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}>; +export declare function handleGetProjectFiles(args: OperationParams): Promise<{ + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}>; +export declare function handleSearchProject(args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleGetSceneDependencies(args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleGetProjectSettings(args: OperationParams): Promise<{ + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}>; +//# sourceMappingURL=project-tools.d.ts.map \ No newline at end of file diff --git a/package/dist/tools/project-tools.d.ts.map b/package/dist/tools/project-tools.d.ts.map new file mode 100644 index 0000000..3e85a07 --- /dev/null +++ b/package/dist/tools/project-tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"project-tools.d.ts","sourceRoot":"","sources":["../../src/tools/project-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAoB7F,eAAO,MAAM,sBAAsB,EAAE,cAAc,EAwJlD,CAAC;AAsPF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,eAAe;;;;;;;;;;;GAkC7D;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;;;;;;GAkDpF;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,eAAe;;;;;;;;;;;GAiBhE;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,eAAe;;;;;;GA4B9D;AAED,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,eAAe;;;;;;GAoDrE;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,eAAe;;;;;;;;;;;GAkBnE"} \ No newline at end of file diff --git a/package/dist/tools/project-tools.js b/package/dist/tools/project-tools.js new file mode 100644 index 0000000..751cd63 --- /dev/null +++ b/package/dist/tools/project-tools.js @@ -0,0 +1,544 @@ +import { join, basename } from 'path'; +import { existsSync, readdirSync, readFileSync } from 'fs'; +import { normalizeParameters, validatePath, validateSubPath, validateProjectArgs, createErrorResponse, createStructuredResponse, getErrorMessage, projectGodotPath, } from '../utils/godot-runner.js'; +import { logDebug } from '../utils/logger.js'; +function fileExtension(name) { + const dotIdx = name.lastIndexOf('.'); + return dotIdx >= 0 ? name.slice(dotIdx + 1).toLowerCase() : ''; +} +// --- Tool definitions --- +export const projectToolDefinitions = [ + { + name: 'list_projects', + description: 'Find Godot projects under a directory by locating project.godot files. Use to discover available projects when the user has not specified one; for inspecting a known project, use get_project_info. recursive:true descends into subdirectories (skipping hidden ones); default false checks only the directory itself and its immediate children. Returns: [{ path, name }], empty array on no matches.', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + directory: { + type: 'string', + description: 'Directory to search for Godot projects', + }, + recursive: { + type: 'boolean', + description: 'Whether to search recursively (default: false)', + }, + }, + required: ['directory'], + }, + }, + { + name: 'get_project_info', + description: 'Get metadata about a Godot project: name, path, Godot version, and a structure summary (counts of scenes/scripts/assets/other). Omit projectPath to get just the Godot version (useful for capability checks). Returns: { name, path, godotVersion, structure } or { godotVersion } when projectPath is omitted. Errors if projectPath is set but lacks project.godot.', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { + type: 'string', + description: 'Path to the Godot project directory (optional — omit to get Godot version only)', + }, + }, + required: [], + }, + }, + { + name: 'get_project_files', + description: 'Return a recursive file tree of a Godot project. Use to discover project structure when paths are unknown. Pass extensions to filter (e.g. ["gd","tscn"]); maxDepth caps recursion (-1 unlimited). Skips hidden (dot-prefixed) entries and the .mcp directory. Returns: { name, type, path, extension?, children? } (nested tree).', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + maxDepth: { + type: 'number', + description: 'Maximum recursion depth. -1 means unlimited (default: -1)', + }, + extensions: { + type: 'array', + items: { type: 'string' }, + description: 'Filter to only these file extensions (e.g. ["gd", "tscn"]). Omit to include all.', + }, + }, + required: ['projectPath'], + }, + }, + { + name: 'search_project', + description: 'Plain-text (substring) search across project files. Use to find references, callers, or signatures across the codebase. Default fileTypes is ["gd","tscn","cs","gdshader"]; caseSensitive default false; maxResults default 100. Skips hidden entries and the .mcp directory. Returns: matches[] (project-relative file, 1-indexed lineNumber, line text) and truncated:true when maxResults was hit — consider raising it.', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + pattern: { type: 'string', description: 'Plain-text string to search for' }, + fileTypes: { + type: 'array', + items: { type: 'string' }, + description: 'File extensions to search (default: ["gd", "tscn", "cs", "gdshader"])', + }, + caseSensitive: { type: 'boolean', description: 'Case-sensitive search (default: false)' }, + maxResults: { type: 'number', description: 'Maximum matches to return (default: 100)' }, + }, + required: ['projectPath', 'pattern'], + }, + outputSchema: { + type: 'object', + properties: { + matches: { + type: 'array', + items: { + type: 'object', + properties: { + file: { type: 'string' }, + lineNumber: { type: 'number' }, + line: { type: 'string' }, + }, + }, + }, + truncated: { type: 'boolean' }, + }, + }, + }, + { + name: 'get_scene_dependencies', + description: 'Parse a .tscn file for ext_resource references (scripts, textures, subscenes). Use to inspect what a scene depends on before refactoring or moving files. Returns: the queried scene path and dependencies[] from ext_resource refs (path, type, optional uid). Errors if scene file does not exist.', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { + type: 'string', + description: 'Path to the .tscn file relative to the project root (e.g. "scenes/main.tscn")', + }, + }, + required: ['projectPath', 'scenePath'], + }, + outputSchema: { + type: 'object', + properties: { + scene: { type: 'string' }, + dependencies: { + type: 'array', + items: { + type: 'object', + properties: { + path: { type: 'string' }, + type: { type: 'string' }, + uid: { type: 'string' }, + }, + }, + }, + }, + }, + }, + { + name: 'get_project_settings', + description: 'Parse project.godot into structured JSON. Use to inspect configured display, input, rendering, etc. settings without launching Godot. Pass section to filter to one INI section (e.g. "display", "application"). Returns: { settings: { [section]: { [key]: value } } } or { settings: { [key]: value } } when section is given. Complex Godot types are returned as raw strings; keys outside any section appear under __global__.', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + section: { + type: 'string', + description: 'Filter to a specific INI section (e.g. "display", "application"). Omit for all sections.', + }, + }, + required: ['projectPath'], + }, + }, +]; +// --- Helpers --- +const PROJECT_SCAN_BLACKLIST = new Set(['.git', '.godot', '.mcp', 'node_modules', '.svn', '.hg']); +function findGodotProjects(directory, recursive) { + const projects = []; + try { + const projectFile = projectGodotPath(directory); + if (existsSync(projectFile)) { + projects.push({ + path: directory, + name: basename(directory), + }); + } + const entries = readdirSync(directory, { withFileTypes: true }); + for (const entry of entries) { + if (!entry.isDirectory() || PROJECT_SCAN_BLACKLIST.has(entry.name)) + continue; + const subdir = join(directory, entry.name); + if (existsSync(projectGodotPath(subdir))) { + projects.push({ path: subdir, name: entry.name }); + } + else if (recursive) { + projects.push(...findGodotProjects(subdir, true)); + } + } + } + catch (error) { + logDebug(`Error searching directory ${directory}: ${error}`); + } + return projects; +} +function getProjectStructure(projectPath) { + const structure = { + scenes: 0, + scripts: 0, + assets: 0, + other: 0, + }; + const scanDirectory = (currentPath) => { + try { + const entries = readdirSync(currentPath, { withFileTypes: true }); + for (const entry of entries) { + const entryPath = join(currentPath, entry.name); + if (entry.name.startsWith('.')) { + continue; + } + if (entry.isDirectory()) { + scanDirectory(entryPath); + } + else if (entry.isFile()) { + const ext = fileExtension(entry.name); + if (ext === 'tscn') { + structure.scenes++; + } + else if (ext === 'gd' || ext === 'gdscript' || ext === 'cs') { + structure.scripts++; + } + else if (['png', 'jpg', 'jpeg', 'webp', 'svg', 'ttf', 'wav', 'mp3', 'ogg'].includes(ext || '')) { + structure.assets++; + } + else { + structure.other++; + } + } + } + } + catch (error) { + logDebug(`Error scanning directory ${currentPath}: ${error}`); + } + }; + scanDirectory(projectPath); + return structure; +} +function buildFilesystemTree(currentPath, relativePath, maxDepth, currentDepth, extensions) { + const name = basename(currentPath); + const node = { name, type: 'dir', path: relativePath || '.' }; + if (maxDepth !== -1 && currentDepth >= maxDepth) { + node.children = []; + return node; + } + const children = []; + try { + const entries = readdirSync(currentPath, { withFileTypes: true }); + for (const entry of entries) { + if (entry.name.startsWith('.')) + continue; + const childRelPath = relativePath ? `${relativePath}/${entry.name}` : entry.name; + if (entry.isDirectory()) { + children.push(buildFilesystemTree(join(currentPath, entry.name), childRelPath, maxDepth, currentDepth + 1, extensions)); + } + else if (entry.isFile()) { + const ext = fileExtension(entry.name); + if (extensions && !extensions.includes(ext)) + continue; + children.push({ name: entry.name, type: 'file', path: childRelPath, extension: ext }); + } + } + } + catch (err) { + logDebug(`buildFilesystemTree error at ${currentPath}: ${err}`); + } + node.children = children; + return node; +} +function searchInFiles(rootPath, pattern, fileTypes, caseSensitive, maxResults) { + const matches = []; + let truncated = false; + const searchDir = (currentPath, relBase) => { + if (truncated) + return; + let entries; + try { + entries = readdirSync(currentPath, { withFileTypes: true }); + } + catch (err) { + logDebug(`searchInFiles readdir error at ${currentPath}: ${err}`); + return; + } + for (const entry of entries) { + if (truncated) + return; + if (entry.name.startsWith('.')) + continue; + const childRelPath = relBase ? `${relBase}/${entry.name}` : entry.name; + const fullPath = join(currentPath, entry.name); + if (entry.isDirectory()) { + searchDir(fullPath, childRelPath); + } + else if (entry.isFile()) { + const ext = fileExtension(entry.name); + if (!fileTypes.includes(ext)) + continue; + let content; + try { + content = readFileSync(fullPath, 'utf8'); + } + catch { + continue; + } + const lines = content.split('\n'); + const needle = caseSensitive ? pattern : pattern.toLowerCase(); + for (let i = 0; i < lines.length; i++) { + const haystack = caseSensitive ? lines[i] : lines[i].toLowerCase(); + if (haystack.includes(needle)) { + matches.push({ file: childRelPath, lineNumber: i + 1, line: lines[i] }); + if (matches.length >= maxResults) { + truncated = true; + return; + } + } + } + } + } + }; + searchDir(rootPath, ''); + return { matches, truncated }; +} +function parseProjectSettings(projectFilePath) { + const content = readFileSync(projectFilePath, 'utf8'); + const result = {}; + let currentSection = '__global__'; + for (const rawLine of content.split('\n')) { + const line = rawLine.trim(); + if (line === '' || line.startsWith(';') || line.startsWith('#')) + continue; + if (line.startsWith('config_version')) + continue; // header line + if (line.startsWith('[') && line.endsWith(']')) { + currentSection = line.slice(1, -1); + continue; + } + const eqIdx = line.indexOf('='); + if (eqIdx === -1) + continue; + const key = line.slice(0, eqIdx).trim(); + const rawVal = line.slice(eqIdx + 1).trim(); + let value; + if (rawVal.startsWith('"') && rawVal.endsWith('"')) { + value = rawVal.slice(1, -1); + } + else if (rawVal === 'true') { + value = true; + } + else if (rawVal === 'false') { + value = false; + } + else { + const num = Number(rawVal); + value = isNaN(num) ? rawVal : num; + } + if (!result[currentSection]) + result[currentSection] = {}; + result[currentSection][key] = value; + } + return result; +} +// --- Handlers --- +export async function handleListProjects(args) { + args = normalizeParameters(args); + if (!args.directory) { + return createErrorResponse('Directory is required', [ + 'Provide a valid directory path to search for Godot projects', + ]); + } + if (!validatePath(args.directory)) { + return createErrorResponse('Invalid directory path', [ + 'Provide a valid path without ".." or other potentially unsafe characters', + ]); + } + try { + if (!existsSync(args.directory)) { + return createErrorResponse(`Directory does not exist: ${args.directory}`, [ + 'Provide a valid directory path that exists on the system', + ]); + } + const recursive = args.recursive === true; + const projects = findGodotProjects(args.directory, recursive); + return { + content: [{ type: 'text', text: JSON.stringify(projects) }], + }; + } + catch (error) { + return createErrorResponse(`Failed to list projects: ${getErrorMessage(error)}`, [ + 'Ensure the directory exists and is accessible', + 'Check if you have permission to read the directory', + ]); + } +} +export async function handleGetProjectInfo(runner, args) { + args = normalizeParameters(args); + try { + const version = await runner.getVersion(); + // If no project path, return just the Godot version + if (!args.projectPath) { + return { + content: [{ type: 'text', text: JSON.stringify({ godotVersion: version }) }], + }; + } + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + const projectFile = projectGodotPath(v.projectPath); + const projectStructure = getProjectStructure(v.projectPath); + let projectName = basename(v.projectPath); + try { + const projectFileContent = readFileSync(projectFile, 'utf8'); + const configNameMatch = projectFileContent.match(/config\/name="([^"]+)"/); + if (configNameMatch && configNameMatch[1]) { + projectName = configNameMatch[1]; + logDebug(`Found project name in config: ${projectName}`); + } + } + catch (error) { + logDebug(`Error reading project file: ${error}`); + } + return { + content: [ + { + type: 'text', + text: JSON.stringify({ + name: projectName, + path: v.projectPath, + godotVersion: version, + structure: projectStructure, + }), + }, + ], + }; + } + catch (error) { + return createErrorResponse(`Failed to get project info: ${getErrorMessage(error)}`, [ + 'Ensure Godot is installed correctly', + 'Check if the GODOT_PATH environment variable is set correctly', + ]); + } +} +export async function handleGetProjectFiles(args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + try { + const maxDepth = typeof args.maxDepth === 'number' ? args.maxDepth : -1; + const extensions = Array.isArray(args.extensions) + ? args.extensions.map((e) => e.toLowerCase().replace(/^\./, '')) + : null; + const tree = buildFilesystemTree(v.projectPath, '', maxDepth, 0, extensions); + return { content: [{ type: 'text', text: JSON.stringify(tree) }] }; + } + catch (error) { + return createErrorResponse(`Failed to get project files: ${getErrorMessage(error)}`, [ + 'Check if the project directory is accessible', + ]); + } +} +export async function handleSearchProject(args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + if (!args.pattern || typeof args.pattern !== 'string') { + return createErrorResponse('pattern is required', ['Provide a plain-text search string']); + } + try { + const fileTypes = Array.isArray(args.fileTypes) + ? args.fileTypes.map((e) => e.toLowerCase().replace(/^\./, '')) + : ['gd', 'tscn', 'cs', 'gdshader']; + const caseSensitive = args.caseSensitive === true; + const maxResults = typeof args.maxResults === 'number' ? args.maxResults : 100; + const result = searchInFiles(v.projectPath, args.pattern, fileTypes, caseSensitive, maxResults); + return createStructuredResponse(result); + } + catch (error) { + return createErrorResponse(`Failed to search project: ${getErrorMessage(error)}`, [ + 'Check if the project directory is accessible', + ]); + } +} +export async function handleGetSceneDependencies(args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + if (!args.scenePath || typeof args.scenePath !== 'string') { + return createErrorResponse('scenePath is required', [ + 'Provide a path relative to the project root, e.g. "scenes/main.tscn"', + ]); + } + if (!validateSubPath(v.projectPath, args.scenePath)) { + return createErrorResponse('Invalid scenePath', [ + 'Provide a valid relative path without ".." that stays inside the project directory', + ]); + } + try { + const sceneFullPath = join(v.projectPath, args.scenePath); + if (!existsSync(sceneFullPath)) { + return createErrorResponse(`Scene file not found: ${args.scenePath}`, [ + 'Verify the path is relative to the project root', + 'Use get_project_files to list available .tscn files', + ]); + } + const sceneContent = readFileSync(sceneFullPath, 'utf8'); + const dependencies = []; + const extResourcePattern = /^\[ext_resource([^\]]*)\]/gm; + let match; + while ((match = extResourcePattern.exec(sceneContent)) !== null) { + const attrs = match[1]; + const typeMatch = attrs.match(/\btype="([^"]*)"/); + const pathMatch = attrs.match(/\bpath="([^"]*)"/); + const uidMatch = attrs.match(/\buid="([^"]*)"/); + if (pathMatch) { + const depPath = pathMatch[1].replace(/^res:\/\//, ''); + const dep = { + path: depPath, + type: typeMatch ? typeMatch[1] : 'Unknown', + }; + if (uidMatch) + dep.uid = uidMatch[1]; + dependencies.push(dep); + } + } + return createStructuredResponse({ + scene: args.scenePath, + dependencies, + }); + } + catch (error) { + return createErrorResponse(`Failed to get scene dependencies: ${getErrorMessage(error)}`, [ + 'Check if the scene file is accessible', + ]); + } +} +export async function handleGetProjectSettings(args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + try { + const projectFile = projectGodotPath(v.projectPath); + const allSettings = parseProjectSettings(projectFile); + if (args.section && typeof args.section === 'string') { + const sectionData = allSettings[args.section] ?? {}; + return { content: [{ type: 'text', text: JSON.stringify({ settings: sectionData }) }] }; + } + return { content: [{ type: 'text', text: JSON.stringify({ settings: allSettings }) }] }; + } + catch (error) { + return createErrorResponse(`Failed to get project settings: ${getErrorMessage(error)}`, [ + 'Check if project.godot is accessible', + ]); + } +} +//# sourceMappingURL=project-tools.js.map \ No newline at end of file diff --git a/package/dist/tools/project-tools.js.map b/package/dist/tools/project-tools.js.map new file mode 100644 index 0000000..80fd67b --- /dev/null +++ b/package/dist/tools/project-tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"project-tools.js","sourceRoot":"","sources":["../../src/tools/project-tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/tools/runtime-tools.d.ts b/package/dist/tools/runtime-tools.d.ts new file mode 100644 index 0000000..62c9170 --- /dev/null +++ b/package/dist/tools/runtime-tools.d.ts @@ -0,0 +1,88 @@ +import type { GodotRunner, OperationParams, ToolDefinition } from '../utils/godot-runner.js'; +export declare const runtimeToolDefinitions: ToolDefinition[]; +export declare function handleLaunchEditor(runner: GodotRunner, args: OperationParams): Promise<{ + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}>; +export declare function handleRunProject(runner: GodotRunner, args: OperationParams): Promise<{ + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}>; +export declare function handleAttachProject(runner: GodotRunner, args: OperationParams): Promise<{ + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}>; +export declare function handleDetachProject(runner: GodotRunner): Promise; + isError: boolean; +}>; +export declare function handleGetDebugOutput(runner: GodotRunner, args?: OperationParams): import("../utils/godot-runner.js").ToolResponse | { + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +}; +export declare function handleStopProject(runner: GodotRunner): Promise; + isError: boolean; +}>; +export declare function handleTakeScreenshot(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleSimulateInput(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleGetUiElements(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleRunScript(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +//# sourceMappingURL=runtime-tools.d.ts.map \ No newline at end of file diff --git a/package/dist/tools/runtime-tools.d.ts.map b/package/dist/tools/runtime-tools.d.ts.map new file mode 100644 index 0000000..5461c0d --- /dev/null +++ b/package/dist/tools/runtime-tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"runtime-tools.d.ts","sourceRoot":"","sources":["../../src/tools/runtime-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAqC7F,eAAO,MAAM,sBAAsB,EAAE,cAAc,EA2XlD,CAAC;AAiCF,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;;;;;;GAsClF;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;;;;;;GA+HhF;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;;;;;;GA0EnF;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,WAAW;;;;;;GAc5D;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,GAAE,eAAoB;;;;;;EAgDnF;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,WAAW;;;;;;GAoB1D;AAoBD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAyIpF;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAiEnF;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GA4CnF;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAkG/E"} \ No newline at end of file diff --git a/package/dist/tools/runtime-tools.js b/package/dist/tools/runtime-tools.js new file mode 100644 index 0000000..9f2433f --- /dev/null +++ b/package/dist/tools/runtime-tools.js @@ -0,0 +1,948 @@ +import { join, sep, resolve } from 'path'; +import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs'; +import { normalizeParameters, validateProjectArgs, validateSubPath, createErrorResponse, createStructuredResponse, getErrorMessage, isUnderDir, BRIDGE_WAIT_SPAWNED_TIMEOUT_MS, } from '../utils/godot-runner.js'; +import { attachRuntimeWarnings, parseBridgeJson, MAX_RUNTIME_ERROR_CONTEXT_LINES, } from '../utils/handler-helpers.js'; +import { logDebug } from '../utils/logger.js'; +import { randomUUID } from 'crypto'; +const SCREENSHOT_RESPONSE_MODES = ['full', 'preview', 'path_only']; +const DEFAULT_PREVIEW_MAX_WIDTH = 960; +const DEFAULT_PREVIEW_MAX_HEIGHT = 540; +// --- Tool definitions --- +export const runtimeToolDefinitions = [ + { + name: 'launch_editor', + description: 'Open the Godot editor GUI for a project for the human user. Use only when the user explicitly asks to "open the editor"; for any agent-driven work, use the headless scene/node tools (add_node, set_node_properties, etc.) instead — the editor cannot be controlled programmatically. Returns plain-text confirmation after spawning the editor process. Errors if projectPath has no project.godot.', + inputSchema: { + type: 'object', + properties: { + projectPath: { + type: 'string', + description: 'Path to the Godot project directory', + }, + }, + required: ['projectPath'], + }, + }, + { + name: 'run_project', + description: 'Spawn a Godot project as a child process with stdout/stderr captured. Required before take_screenshot, simulate_input, get_ui_elements, run_script, or get_debug_output. For a Godot process you launched yourself, use attach_project instead. Verifies MCP bridge readiness before returning success. Returns plain-text status with the assigned bridge port. Call stop_project when done. Errors if projectPath is not a Godot project or another session is already active.', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { + type: 'string', + description: 'Path to the Godot project directory', + }, + scene: { + type: 'string', + description: 'Scene to run (path relative to project, e.g. "scenes/main.tscn"). Omit to use the project\'s main scene.', + }, + background: { + type: 'boolean', + description: 'If true, hides the Godot window off-screen and blocks all physical keyboard and mouse input, while keeping programmatic input (simulate_input, run_script) and screenshots fully active. Useful for automated agent-driven testing where the window should not be visible or interactive.', + }, + bridgePort: { + type: 'number', + minimum: 1, + maximum: 65535, + description: "TCP port for the MCP bridge. Omit to auto-select a free port (recommended). The chosen port is baked into the project's `mcp_bridge.gd` at inject time, so the running Godot listens on exactly this port.", + }, + }, + required: ['projectPath'], + }, + }, + { + name: 'attach_project', + description: 'Inject the MCP bridge into a Godot process you launch yourself, then wait up to 15s for the bridge to respond. Call BEFORE Godot launches — Godot reads autoloads only at process start, so a late call returns "bridge did not respond." Recommended pattern: kick off the Godot launch in parallel with this call so the wait absorbs startup. Prefer run_project unless MCP must not spawn Godot. Returns plain-text status with the resolved bridge port. Call detach_project or stop_project when done.', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { + type: 'string', + description: 'Path to the Godot project directory', + }, + bridgePort: { + type: 'number', + minimum: 1, + maximum: 65535, + description: "TCP port for the MCP bridge. Omit to auto-select a free port (recommended). The chosen port is baked into the project's `mcp_bridge.gd` at inject time, so the running Godot listens on exactly this port.", + }, + }, + required: ['projectPath'], + }, + }, + { + name: 'detach_project', + description: 'Clear attached-mode runtime state and remove the injected McpBridge autoload. Does NOT stop the manually launched Godot process — that stays running. Use after attach_project when you are done driving the game from MCP. For spawned sessions (run_project), use stop_project instead. Returns: message confirming detach plus externalProcessPreserved (always true here — that is the point of detach vs stop_project). Errors if called outside an attached session.', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: {}, + required: [], + }, + outputSchema: { + type: 'object', + properties: { + message: { type: 'string' }, + externalProcessPreserved: { type: 'boolean' }, + }, + }, + }, + { + name: 'get_debug_output', + description: 'Get captured stdout/stderr from a spawned Godot project. Use whenever runtime tools fail unexpectedly — script errors, missing nodes, and crash backtraces all surface here. Requires run_project (not attach_project; attached mode does not capture output). Returns: output/errors (last `limit` lines each, default 200), running (false after exit, null when attached), exitCode after exit, attached:true with empty arrays in attached mode.', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + limit: { + type: 'number', + description: 'Max lines to return (default: 200, from end of output)', + }, + }, + required: [], + }, + outputSchema: { + type: 'object', + properties: { + output: { type: 'array', items: { type: 'string' } }, + errors: { type: 'array', items: { type: 'string' } }, + running: { type: ['boolean', 'null'] }, + exitCode: { type: ['number', 'null'] }, + attached: { type: 'boolean' }, + tip: { type: 'string' }, + }, + }, + }, + { + name: 'stop_project', + description: 'Stop the spawned Godot project and clean up MCP bridge state. Always call when done with runtime testing — even after a crash — to free the single process slot so run_project can be called again. For attached sessions, this detaches without killing the externally launched process. Returns: message, mode ("spawned"/"attached"), externalProcessPreserved (true only for attached), finalOutput and finalErrors (last 200 lines each). Errors if no session is active.', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: {}, + required: [], + }, + outputSchema: { + type: 'object', + properties: { + message: { type: 'string' }, + mode: { type: 'string' }, + externalProcessPreserved: { type: 'boolean' }, + finalOutput: { type: 'array', items: { type: 'string' } }, + finalErrors: { type: 'array', items: { type: 'string' } }, + }, + }, + }, + { + name: 'take_screenshot', + description: 'Capture a PNG of the running viewport. responseMode: preview (default — saves full PNG, returns bounded inline preview at 960x540), full (full inline PNG; use for small text or pixel-level inspection), path_only (saved-path only, no inline image). Saved under .mcp/screenshots. Returns: inline image block (full/preview modes), plus path and size of the saved PNG; previewPath/previewSize in preview mode; warnings for non-fatal runtime errors. Errors if no session or bridge times out (default 10000ms).', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + timeout: { + type: 'number', + description: 'Timeout in milliseconds to wait for the screenshot (default: 10000)', + }, + responseMode: { + type: 'string', + enum: ['full', 'preview', 'path_only'], + description: 'Response payload mode. "preview" returns a bounded inline preview plus paths (default). "full" returns the full inline PNG. "path_only" returns paths only.', + }, + previewMaxWidth: { + type: 'number', + description: 'Maximum preview width in pixels when responseMode is "preview" (default: 960)', + }, + previewMaxHeight: { + type: 'number', + description: 'Maximum preview height in pixels when responseMode is "preview" (default: 540)', + }, + }, + required: [], + }, + // The handler also emits an inline `image` content block for full/preview modes; + // outputSchema only describes the structured JSON text payload per MCP spec. + outputSchema: { + type: 'object', + properties: { + responseMode: { type: 'string' }, + path: { type: 'string' }, + size: { + type: 'object', + properties: { + width: { type: 'number' }, + height: { type: 'number' }, + }, + }, + previewPath: { type: 'string' }, + previewSize: { + type: 'object', + properties: { + width: { type: 'number' }, + height: { type: 'number' }, + }, + }, + warnings: { type: 'array', items: { type: 'string' } }, + }, + }, + }, + { + name: 'simulate_input', + description: "Simulate sequential input in a running project. Each action's `type` (key, mouse_button, mouse_motion, click_element, action, wait) gates which other fields apply — see per-property docs. For click_element use get_ui_elements first; resolution is by path/name, not visible text. Press/release require two actions; insert wait between for frame ticks. Returns: success, actions_processed, warnings for runtime errors fired by input handlers. Errors if no session or any action fails validation.", + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: { + actions: { + type: 'array', + description: 'Array of input actions to execute sequentially. Each object must have a "type" field.', + items: { + type: 'object', + properties: { + type: { + type: 'string', + enum: ['key', 'mouse_button', 'mouse_motion', 'click_element', 'action', 'wait'], + description: 'The type of input action', + }, + key: { + type: 'string', + description: '[key] Godot KEY_* constant name without the prefix (e.g. "W", "Space", "Escape", "Enter", "Tab", "Up", "PageUp"). Errors on unrecognized names.', + }, + pressed: { + type: 'boolean', + description: '[key, mouse_button, action] Whether the input is pressed (true) or released (false). For mouse_button: omit to auto-click (press+release in one action); set explicitly only for hold/release. For key: defaults to true and does NOT auto-release — emit a second action with pressed:false to release.', + }, + shift: { type: 'boolean', description: '[key] Shift modifier' }, + ctrl: { type: 'boolean', description: '[key] Ctrl modifier' }, + alt: { type: 'boolean', description: '[key] Alt modifier' }, + unicode: { + type: 'number', + description: '[key] Unicode codepoint for text-entry Controls (LineEdit, TextEdit). Auto-derived for ASCII letters/digits (respecting shift); pass explicitly for symbols or non-ASCII. E.g. 33 for "!", 64 for "@".', + }, + button: { + type: 'string', + enum: ['left', 'right', 'middle'], + description: '[mouse_button, click_element] Mouse button (default: left)', + }, + x: { + type: 'number', + description: '[mouse_button, mouse_motion] X position in viewport pixels (0,0 = top-left)', + }, + y: { + type: 'number', + description: '[mouse_button, mouse_motion] Y position in viewport pixels (0,0 = top-left)', + }, + relative_x: { + type: 'number', + description: '[mouse_motion] Relative X movement in pixels', + }, + relative_y: { + type: 'number', + description: '[mouse_motion] Relative Y movement in pixels', + }, + double_click: { + type: 'boolean', + description: '[mouse_button, click_element] Double click', + }, + element: { + type: 'string', + description: '[click_element] Identifies the UI element to click. Accepts: absolute node path (e.g. "/root/HUD/Button"), relative node path, or node name (BFS matched). Use get_ui_elements to discover valid names and paths.', + }, + action: { + type: 'string', + description: '[action] Godot input action name (as defined in Project Settings > Input Map)', + }, + strength: { + type: 'number', + description: '[action] Action strength (0–1, default 1.0)', + }, + ms: { + type: 'number', + description: '[wait] Duration in milliseconds to pause before the next action (~16ms = one frame at 60fps).', + }, + }, + required: ['type'], + }, + }, + }, + required: ['actions'], + }, + outputSchema: { + type: 'object', + properties: { + success: { type: 'boolean' }, + actions_processed: { type: 'number' }, + warnings: { type: 'array', items: { type: 'string' } }, + tip: { type: 'string' }, + }, + }, + }, + { + name: 'get_ui_elements', + description: 'Walk the running scene tree and return all Control nodes with positions, sizes, types, and text content. Always call this before simulate_input click_element actions to discover valid element names and paths. Requires an active runtime session (run_project or attach_project). visibleOnly defaults true; pass false to include hidden Controls. filter narrows by class. Returns: elements[] with path/type/rect/visible plus optional text/disabled/tooltip.', + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + visibleOnly: { + type: 'boolean', + description: 'Only return nodes where Control.visible is true (default: true). Set false to include hidden elements.', + }, + filter: { + type: 'string', + description: 'Filter by Control node type (e.g. "Button", "Label", "LineEdit")', + }, + }, + required: [], + }, + outputSchema: { + type: 'object', + properties: { + elements: { + type: 'array', + items: { + type: 'object', + properties: { + name: { type: 'string' }, + path: { type: 'string' }, + type: { type: 'string' }, + rect: { + type: 'object', + properties: { + x: { type: 'number' }, + y: { type: 'number' }, + width: { type: 'number' }, + height: { type: 'number' }, + }, + }, + visible: { type: 'boolean' }, + text: { type: 'string' }, + placeholder: { type: 'string' }, + disabled: { type: 'boolean' }, + tooltip: { type: 'string' }, + }, + }, + }, + warnings: { type: 'array', items: { type: 'string' } }, + tip: { type: 'string' }, + }, + }, + }, + { + name: 'run_script', + description: 'Execute a custom GDScript in the live running project with full scene tree access. Requires an active runtime session. Script must extend RefCounted and define func execute(scene_tree: SceneTree) -> Variant. Return values are JSON-serialized (primitives, Vector2/3, Color, Dictionary, Array, and Node path strings). Use print() for debug output — it appears in get_debug_output, not in the result. In spawned mode, stderr runtime errors escalate to errors (when the script returns null) or surface as warnings. Returns: { success, result, warnings?, tip? } where result is the JSON-serialized return value of execute().', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: { + script: { + type: 'string', + description: 'GDScript source code. Must contain "extends RefCounted" and "func execute(scene_tree: SceneTree) -> Variant".', + }, + timeout: { + type: 'number', + description: 'Timeout in ms (default: 30000). Increase for long-running scripts.', + }, + }, + required: ['script'], + }, + outputSchema: { + type: 'object', + properties: { + success: { type: 'boolean' }, + result: {}, + warnings: { type: 'array', items: { type: 'string' } }, + tip: { type: 'string' }, + }, + }, + }, +]; +// --- Helpers --- +function ensureRuntimeSession(runner, actionDescription) { + if (!runner.activeSessionMode || !runner.activeProjectPath) { + return createErrorResponse(`No active runtime session. A project must be running or attached to ${actionDescription}.`, [ + 'Use run_project to start a Godot project first', + 'Or use attach_project before launching Godot manually', + ]); + } + if (runner.activeSessionMode === 'spawned' && + (!runner.activeProcess || runner.activeProcess.hasExited)) { + return createErrorResponse(`The spawned Godot process has exited and cannot ${actionDescription}.`, [ + 'Use get_debug_output to inspect the last captured logs', + 'Call stop_project to clean up, then run_project again', + ]); + } + return null; +} +// --- Handlers --- +export async function handleLaunchEditor(runner, args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + try { + if (!runner.getGodotPath()) { + await runner.detectGodotPath(); + if (!runner.getGodotPath()) { + return createErrorResponse('Could not find a valid Godot executable path', [ + 'Ensure Godot is installed correctly', + 'Set GODOT_PATH environment variable', + ]); + } + } + logDebug(`Launching Godot editor for project: ${v.projectPath}`); + const process = runner.launchEditor(v.projectPath); + process.on('error', (err) => { + console.error('Failed to start Godot editor:', err); + }); + return { + content: [ + { + type: 'text', + text: `Godot editor launched successfully for project at ${v.projectPath}.\nNote: the editor is a GUI application and cannot be controlled programmatically. Use the scene and node editing tools (add_node, set_node_properties, etc.) to modify the project headlessly without the editor.`, + }, + ], + }; + } + catch (error) { + return createErrorResponse(`Failed to launch Godot editor: ${getErrorMessage(error)}`, [ + 'Ensure Godot is installed correctly', + 'Check if the GODOT_PATH environment variable is set correctly', + ]); + } +} +export async function handleRunProject(runner, args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + if (typeof args.scene === 'string') { + if (!validateSubPath(v.projectPath, args.scene)) { + return createErrorResponse(`Invalid scene path: must be project-relative without ".." (got: ${args.scene})`, ['Pass scene as a path relative to the project root, e.g. "scenes/main.tscn"']); + } + } + if (!runner.getGodotPath()) { + await runner.detectGodotPath(); + if (!runner.getGodotPath()) { + return createErrorResponse('Could not find a valid Godot executable path', [ + 'Set GODOT_PATH in your MCP client config to your Godot 4.x executable', + 'Ensure the path points at the Godot binary, not its installation folder', + 'On Windows, escape backslashes in JSON (e.g. "D:\\\\Godot\\\\Godot.exe")', + ]); + } + } + try { + const background = args.background === true; + const bridgePort = args.bridgePort; + if (bridgePort !== undefined) { + if (!Number.isInteger(bridgePort) || + bridgePort < 1 || + bridgePort > 65535) { + return createErrorResponse(`Invalid bridgePort: must be an integer in [1, 65535] (got: ${String(bridgePort)})`, ['Omit bridgePort to auto-select a free port', 'Pass a valid TCP port number']); + } + } + await runner.runProject(v.projectPath, args.scene, background, bridgePort); + const bridgeResult = await runner.waitForBridge(); + if (!bridgeResult.ready) { + if (runner.activeProcess && runner.activeProcess.hasExited) { + // Tear down the spawned-mode session state so a retry of run_project + // works without an intervening stop_project. + await runner.stopProject(); + return createErrorResponse(`Godot process exited before the MCP bridge could initialize.\n${bridgeResult.error || ''}`, [ + 'Check get_debug_output for runtime errors', + 'Verify a display server is available (Wayland/X11)', + 'Check for broken autoloads with list_autoloads', + 'Retry run_project once the underlying issue is resolved', + ]); + } + const recentErrors = runner.getRecentErrors(20); + const errorTail = recentErrors.length > 0 ? `\nLast stderr:\n${recentErrors.join('\n')}` : ''; + const expected = runner.activeBridgePort; + const onDisk = runner.readBakedBridgePort(v.projectPath); + const raceDetected = onDisk !== null && expected !== null && onDisk !== expected; + const racePrefix = raceDetected + ? `Bridge timeout: expected port ${expected}, but on-disk script now has ${onDisk}. Another MCP client likely re-injected concurrently in the same project.\n` + : ''; + const lines = [ + `${racePrefix}Godot process started, but the MCP bridge did not respond within ${BRIDGE_WAIT_SPAWNED_TIMEOUT_MS / 1000} seconds.`, + '- The bridge listener never came up — likely an early _ready error or a stuck process holding the port', + '- Session has been torn down; retry run_project to start a new one', + errorTail, + ]; + if (background) { + lines.push('- Background mode: window hidden, physical input blocked'); + } + // Tear down before returning so hasActiveRuntimeSession() reports false + // and the next run_project lazy-reconnects cleanly. + await runner.stopProject(); + const solutions = [ + 'Check for broken autoloads with list_autoloads', + `Check that the assigned bridge port (${runner.activeBridgePort}) is not occupied by another Godot process`, + 'Retry run_project', + ]; + if (raceDetected) { + solutions.push('Concurrent MCP clients in the same project are not supported — run them in separate projects or sequence the calls'); + } + return createErrorResponse(lines.join('\n'), solutions); + } + const port = runner.activeBridgePort; + const lines = [ + `Godot project started and MCP bridge is ready (port ${port}).`, + '- Runtime tools (take_screenshot, simulate_input, get_ui_elements, run_script) are available now', + '- Use get_debug_output to check runtime output and errors', + '- Call stop_project when done', + ]; + if (background) { + lines.push('- Background mode: window hidden, physical input blocked'); + } + return { + content: [{ type: 'text', text: lines.join('\n') }], + }; + } + catch (error) { + const errorMessage = getErrorMessage(error); + if (errorMessage.includes('No display server available')) { + return createErrorResponse(`Failed to run Godot project: ${errorMessage}`, [ + 'Use attach_project with an externally launched Godot process', + 'Set DISPLAY or WAYLAND_DISPLAY environment variables', + 'Run from a graphical shell session', + ]); + } + return createErrorResponse(`Failed to run Godot project: ${errorMessage}`, [ + 'Ensure Godot is installed correctly', + 'Check if the GODOT_PATH environment variable is set correctly', + ]); + } +} +export async function handleAttachProject(runner, args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + try { + const attachBridgePort = args.bridgePort; + if (attachBridgePort !== undefined) { + if (!Number.isInteger(attachBridgePort) || + attachBridgePort < 1 || + attachBridgePort > 65535) { + return createErrorResponse(`Invalid bridgePort: must be an integer in [1, 65535] (got: ${String(attachBridgePort)})`, [ + 'Omit bridgePort to auto-select a free port', + 'Pass a valid TCP port number matching the externally launched Godot', + ]); + } + } + await runner.attachProject(v.projectPath, attachBridgePort); + const bridgeResult = await runner.waitForBridgeAttached(); + if (!bridgeResult.ready) { + const expected = runner.activeBridgePort; + const onDisk = runner.readBakedBridgePort(v.projectPath); + const raceDetected = onDisk !== null && expected !== null && onDisk !== expected; + const racePrefix = raceDetected + ? `Bridge timeout: expected port ${expected}, but on-disk script now has ${onDisk}. Another MCP client likely re-injected concurrently in the same project.\n` + : ''; + // Tear down the attached-mode session state so retrying with + // attach_project (or run_project) works without a manual detach first. + await runner.stopProject(); + const solutions = [ + 'If you are launching Godot yourself, run the launch in parallel with attach_project next time so the wait absorbs the startup — do not sequentialize', + 'If a human is launching Godot, retry attach_project once they have launched — bridge.inject is idempotent', + 'If Godot is already running but was launched before the bridge was injected, restart it (autoloads are read at startup)', + `Check that no other Godot project is occupying the assigned bridge port (${runner.activeBridgePort})`, + ]; + if (raceDetected) { + solutions.push('Concurrent MCP clients in the same project are not supported — run them in separate projects or sequence the calls'); + } + return createErrorResponse(`${racePrefix}Project attached but the MCP bridge is not ready.\n${bridgeResult.error || ''}`, solutions); + } + const attachedPort = runner.activeBridgePort; + return { + content: [ + { + type: 'text', + text: [ + `Project attached and MCP bridge is ready (port ${attachedPort}).`, + '- Runtime tools (take_screenshot, simulate_input, get_ui_elements, run_script) are available now', + '- get_debug_output is unavailable in attached mode because MCP did not spawn the process', + '- Use detach_project or stop_project when done to clean up the injected bridge state', + ].join('\n'), + }, + ], + }; + } + catch (error) { + return createErrorResponse(`Failed to attach project: ${getErrorMessage(error)}`, [ + 'Check if project.godot is accessible', + 'Ensure MCP can write the bridge autoload into the project', + ]); + } +} +export async function handleDetachProject(runner) { + if (runner.activeSessionMode !== 'attached') { + return createErrorResponse('No attached project to detach.', [ + 'Use attach_project first for manual-launch workflows', + 'If MCP launched the game, use stop_project instead', + ]); + } + const result = (await runner.stopProject()); + return createStructuredResponse({ + message: 'Detached attached project and cleaned MCP bridge state', + externalProcessPreserved: result.externalProcessPreserved === true, + }); +} +export function handleGetDebugOutput(runner, args = {}) { + args = normalizeParameters(args); + if (!runner.activeSessionMode) { + return createErrorResponse('No active runtime session.', [ + 'Use run_project to start a Godot project first', + 'Or use attach_project before launching Godot manually', + ]); + } + if (runner.activeSessionMode === 'attached') { + return createStructuredResponse({ + output: [], + errors: [], + running: null, + attached: true, + tip: 'Attached mode does not capture stdout/stderr because Godot was launched outside MCP.', + }); + } + const proc = runner.activeProcess; + if (!proc) { + return createErrorResponse('No active spawned process is available for debug output.', [ + 'Use run_project to start a Godot project first', + 'Or use attach_project only when stdout/stderr capture is not needed', + ]); + } + const limit = typeof args.limit === 'number' ? args.limit : 200; + const response = { + output: proc.output.slice(-limit), + errors: proc.errors.slice(-limit), + running: !proc.hasExited, + }; + if (proc.hasExited) { + response.exitCode = proc.exitCode; + response.tip = + 'Process has exited. Call stop_project to clean up the process slot before starting a new one.'; + } + return createStructuredResponse(response); +} +export async function handleStopProject(runner) { + const result = await runner.stopProject(); + if (!result) { + return createErrorResponse('No active Godot process to stop.', [ + 'Use run_project to start a Godot project first', + 'The process may have already terminated', + ]); + } + return createStructuredResponse({ + message: result.mode === 'attached' + ? 'Attached project detached and MCP bridge state cleaned up' + : 'Godot project stopped', + mode: result.mode, + externalProcessPreserved: result.externalProcessPreserved === true, + finalOutput: result.output.slice(-200), + finalErrors: result.errors.slice(-200), + }); +} +function parseScreenshotResponseMode(value) { + if (value === undefined) + return 'preview'; + if (typeof value !== 'string') + return null; + return SCREENSHOT_RESPONSE_MODES.includes(value) + ? value + : null; +} +function parsePreviewDimension(value, fallback) { + if (value === undefined) + return fallback; + if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) + return null; + return Math.max(1, Math.floor(value)); +} +function normalizeScreenshotPath(path) { + return sep === '\\' ? path.replace(/\//g, '\\') : path; +} +export async function handleTakeScreenshot(runner, args) { + args = normalizeParameters(args); + const sessionError = ensureRuntimeSession(runner, 'take a screenshot'); + if (sessionError) { + return sessionError; + } + const timeout = typeof args.timeout === 'number' ? args.timeout : 10000; + const responseMode = parseScreenshotResponseMode(args.responseMode); + if (responseMode === null) { + return createErrorResponse('Invalid responseMode for take_screenshot', [ + 'Use one of: "full", "preview", or "path_only"', + ]); + } + const previewMaxWidth = parsePreviewDimension(args.previewMaxWidth, DEFAULT_PREVIEW_MAX_WIDTH); + const previewMaxHeight = parsePreviewDimension(args.previewMaxHeight, DEFAULT_PREVIEW_MAX_HEIGHT); + if (previewMaxWidth === null || previewMaxHeight === null) { + return createErrorResponse('Invalid preview dimensions for take_screenshot', [ + 'previewMaxWidth and previewMaxHeight must be positive numbers', + ]); + } + const commandParams = {}; + if (responseMode === 'preview') { + commandParams.preview_max_width = previewMaxWidth; + commandParams.preview_max_height = previewMaxHeight; + } + try { + const { response: responseStr, runtimeErrors } = await runner.sendCommandWithErrors('screenshot', commandParams, timeout); + const parsedResult = parseBridgeJson(responseStr, 'screenshot'); + if (!parsedResult.ok) + return parsedResult.response; + const parsed = parsedResult.data; + if (parsed.error) { + return createErrorResponse(`Screenshot server error: ${parsed.error}`, [ + 'Ensure the project has a viewport (a headless project with no display server cannot render)', + 'Check disk space and permissions on the project directory (.mcp/screenshots/)', + ]); + } + if (!parsed.path) { + return createErrorResponse('Screenshot server returned no file path', [ + 'The bridge response is missing the expected `path` field — this is a bridge bug, not a timing issue', + 'Check get_debug_output for runtime errors during the screenshot save', + ]); + } + // Normalize path for the local filesystem (forward slashes from GDScript) + const screenshotPath = normalizeScreenshotPath(parsed.path); + // Defense-in-depth: the bridge runs in user-controlled GDScript and could + // be patched to return any path. Refuse to read anything outside the + // project's own .mcp/screenshots/ directory. + const screenshotsRoot = resolve(runner.activeProjectPath, '.mcp', 'screenshots'); + if (!isUnderDir(screenshotsRoot, screenshotPath)) { + return createErrorResponse('Bridge returned a screenshot path outside .mcp/screenshots/. Refusing to read.', [ + 'This indicates a tampered or misbehaving McpBridge autoload', + 'Stop the project, verify the bridge script is the one shipped with this server, and retry', + ]); + } + if (!existsSync(screenshotPath)) { + return createErrorResponse(`Screenshot file not found at: ${screenshotPath}`, [ + 'The screenshot may have failed to save', + 'Check disk space and permissions', + ]); + } + const metadata = { + responseMode, + path: parsed.path, + size: { width: parsed.width, height: parsed.height }, + }; + const content = []; + if (responseMode === 'full') { + const imageBuffer = readFileSync(screenshotPath); + content.push({ + type: 'image', + data: imageBuffer.toString('base64'), + mimeType: 'image/png', + }); + } + else if (responseMode === 'preview') { + if (!parsed.preview_path) { + return createErrorResponse('Screenshot server returned no preview path', [ + 'Ensure the running project has the current McpBridge autoload', + 'Restart the runtime after rebuilding the MCP server', + ]); + } + const previewPath = normalizeScreenshotPath(parsed.preview_path); + if (!isUnderDir(screenshotsRoot, previewPath)) { + return createErrorResponse('Bridge returned a screenshot preview path outside .mcp/screenshots/. Refusing to read.', [ + 'This indicates a tampered or misbehaving McpBridge autoload', + 'Stop the project, verify the bridge script is the one shipped with this server, and retry', + ]); + } + if (!existsSync(previewPath)) { + return createErrorResponse(`Screenshot preview file not found at: ${previewPath}`, [ + 'The preview may have failed to save', + 'Try again, or use responseMode "full" to return the original screenshot', + ]); + } + const previewBuffer = readFileSync(previewPath); + content.push({ + type: 'image', + data: previewBuffer.toString('base64'), + mimeType: 'image/png', + }); + metadata.previewPath = parsed.preview_path; + metadata.previewSize = { width: parsed.preview_width, height: parsed.preview_height }; + } + attachRuntimeWarnings(metadata, runtimeErrors); + return createStructuredResponse(metadata, content); + } + catch (error) { + return createErrorResponse(`Failed to take screenshot: ${getErrorMessage(error)}`, [ + 'Check get_debug_output for crash backtraces or runtime errors', + 'If the game has exited, call stop_project, then run_project again', + 'For slow renders, increase the timeout parameter', + ]); + } +} +export async function handleSimulateInput(runner, args) { + args = normalizeParameters(args); + const sessionError = ensureRuntimeSession(runner, 'simulate input'); + if (sessionError) { + return sessionError; + } + const actions = args.actions; + if (!Array.isArray(actions) || actions.length === 0) { + return createErrorResponse('actions must be a non-empty array of input actions', [ + 'Provide at least one action object with a "type" field', + ]); + } + // Calculate timeout: sum of all wait durations + 10s buffer + let totalWaitMs = 0; + for (const action of actions) { + if (typeof action === 'object' && + action !== null && + action.type === 'wait' && + typeof action.ms === 'number') { + totalWaitMs += action.ms; + } + } + const timeoutMs = totalWaitMs + 10000; + try { + const { response: responseStr, runtimeErrors } = await runner.sendCommandWithErrors('input', { actions }, timeoutMs); + const parsedResult = parseBridgeJson(responseStr, 'simulate_input'); + if (!parsedResult.ok) + return parsedResult.response; + const parsed = parsedResult.data; + if (parsed.error) { + return createErrorResponse(`Input simulation error: ${parsed.error}`, [ + 'Check action types and parameters', + 'Ensure key names are valid Godot key names', + ]); + } + const payload = { + success: true, + actions_processed: parsed.actions_processed, + tip: 'Call take_screenshot to verify the input had the intended visual effect.', + }; + attachRuntimeWarnings(payload, runtimeErrors); + return createStructuredResponse(payload); + } + catch (error) { + return createErrorResponse(`Failed to simulate input: ${getErrorMessage(error)}`, [ + 'Check get_debug_output for crash backtraces or runtime errors (a signal handler firing on input may have crashed the game)', + 'If the game has exited, call stop_project, then run_project again', + ]); + } +} +export async function handleGetUiElements(runner, args) { + args = normalizeParameters(args); + const sessionError = ensureRuntimeSession(runner, 'query UI elements'); + if (sessionError) { + return sessionError; + } + const visibleOnly = args.visibleOnly !== false; + try { + const cmdParams = { visible_only: visibleOnly }; + if (args.filter) + cmdParams.type_filter = args.filter; + const { response: responseStr, runtimeErrors } = await runner.sendCommandWithErrors('get_ui_elements', cmdParams); + const parsedResult = parseBridgeJson(responseStr, 'get_ui_elements'); + if (!parsedResult.ok) + return parsedResult.response; + const parsed = parsedResult.data; + if (parsed.error) { + return createErrorResponse(`UI element query error: ${parsed.error}`, [ + 'Ensure the game has a UI with Control nodes', + ]); + } + const payload = { + ...parsed, + tip: "Use simulate_input with type 'click_element' and a node_path or node name from this list to interact with these elements.", + }; + attachRuntimeWarnings(payload, runtimeErrors); + return createStructuredResponse(payload); + } + catch (error) { + return createErrorResponse(`Failed to get UI elements: ${getErrorMessage(error)}`, [ + 'Check get_debug_output for crash backtraces or runtime errors', + 'If the game has exited, call stop_project, then run_project again', + ]); + } +} +export async function handleRunScript(runner, args) { + args = normalizeParameters(args); + const sessionError = ensureRuntimeSession(runner, 'execute scripts'); + if (sessionError) { + return sessionError; + } + const script = args.script; + if (typeof script !== 'string' || script.trim() === '') { + return createErrorResponse('script is required and must be a non-empty string', [ + 'Provide GDScript source code with extends RefCounted and func execute(scene_tree: SceneTree) -> Variant', + ]); + } + if (!script.includes('func execute')) { + return createErrorResponse('Script must define func execute(scene_tree: SceneTree) -> Variant', ['Add a func execute(scene_tree: SceneTree) -> Variant method to your script']); + } + // Write script to .mcp/scripts/ for audit trail + try { + const projectPath = runner.activeProjectPath; + if (projectPath) { + const scriptsDir = join(projectPath, '.mcp', 'scripts'); + mkdirSync(scriptsDir, { recursive: true }); + const timestamp = Date.now(); + const scriptFile = join(scriptsDir, `${timestamp}-${randomUUID()}.gd`); + writeFileSync(scriptFile, script, 'utf8'); + logDebug(`Saved script to ${scriptFile}`); + } + } + catch (error) { + logDebug(`Failed to save script for audit: ${error}`); + } + const timeout = typeof args.timeout === 'number' ? args.timeout : 30000; + try { + const { response: responseStr, runtimeErrors } = await runner.sendCommandWithErrors('run_script', { source: script }, timeout); + const parsedResult = parseBridgeJson(responseStr, 'run_script'); + if (!parsedResult.ok) + return parsedResult.response; + const parsed = parsedResult.data; + if (parsed.error) { + return createErrorResponse(`Script execution error: ${parsed.error}`, [ + 'Check your GDScript syntax', + 'Ensure the script extends RefCounted', + 'Check get_debug_output for details', + ]); + } + // Detect false-positive success: GDScript has no try-catch, so runtime errors + // return null and the real error only appears in stderr. + if (parsed.success && parsed.result === null && runner.activeSessionMode === 'spawned') { + if (runtimeErrors.length > 0) { + const errorContext = runtimeErrors.slice(0, MAX_RUNTIME_ERROR_CONTEXT_LINES).join('\n'); + return createErrorResponse(`Script runtime error detected:\n${errorContext}`, [ + 'Fix the GDScript error in your script and retry', + 'Use get_debug_output for full process output', + ]); + } + return createStructuredResponse({ + success: true, + result: null, + warnings: [ + 'Script returned null. If unexpected, check get_debug_output for runtime errors — GDScript does not propagate exceptions.', + ], + tip: 'Call take_screenshot to verify any visual changes, or get_debug_output to review print() output from your script.', + }); + } + const payload = { + success: true, + result: parsed.result, + tip: 'Call take_screenshot to verify any visual changes, or get_debug_output to review print() output from your script.', + }; + attachRuntimeWarnings(payload, runtimeErrors); + return createStructuredResponse(payload); + } + catch (error) { + return createErrorResponse(`Failed to execute script: ${getErrorMessage(error)}`, [ + 'Check get_debug_output for crash backtraces or runtime errors raised inside the script', + 'If the game has exited, call stop_project, then run_project again', + 'For long-running scripts, increase the timeout parameter', + ]); + } +} +//# sourceMappingURL=runtime-tools.js.map \ No newline at end of file diff --git a/package/dist/tools/runtime-tools.js.map b/package/dist/tools/runtime-tools.js.map new file mode 100644 index 0000000..a9222b5 --- /dev/null +++ b/package/dist/tools/runtime-tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"runtime-tools.js","sourceRoot":"","sources":["../../src/tools/runtime-tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/tools/scene-tools.d.ts b/package/dist/tools/scene-tools.d.ts new file mode 100644 index 0000000..05fcc45 --- /dev/null +++ b/package/dist/tools/scene-tools.d.ts @@ -0,0 +1,45 @@ +import type { GodotRunner, OperationParams, ToolDefinition } from '../utils/godot-runner.js'; +export declare const sceneToolDefinitions: ToolDefinition[]; +export declare function handleCreateScene(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleAddNode(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleLoadSprite(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleSaveScene(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleExportMeshLibrary(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +export declare function handleBatchSceneOperations(runner: GodotRunner, args: OperationParams): Promise; + isError: boolean; +}>; +//# sourceMappingURL=scene-tools.d.ts.map \ No newline at end of file diff --git a/package/dist/tools/scene-tools.d.ts.map b/package/dist/tools/scene-tools.d.ts.map new file mode 100644 index 0000000..3b6e7d5 --- /dev/null +++ b/package/dist/tools/scene-tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"scene-tools.d.ts","sourceRoot":"","sources":["../../src/tools/scene-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAW7F,eAAO,MAAM,oBAAoB,EAAE,cAAc,EAyNhD,CAAC;AAIF,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAmBjF;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAsC7E;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GA4BhF;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAgB/E;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GA0BvF;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;GAyB1F"} \ No newline at end of file diff --git a/package/dist/tools/scene-tools.js b/package/dist/tools/scene-tools.js new file mode 100644 index 0000000..4c43556 --- /dev/null +++ b/package/dist/tools/scene-tools.js @@ -0,0 +1,342 @@ +import { join } from 'path'; +import { existsSync } from 'fs'; +import { normalizeParameters, validateSubPath, validateNodePath, createErrorResponse, validateProjectArgs, validateSceneArgs, } from '../utils/godot-runner.js'; +import { executeSceneOp } from '../utils/handler-helpers.js'; +export const sceneToolDefinitions = [ + { + name: 'create_scene', + description: 'Create a new Godot scene file with a single root node. Writes a fresh .tscn at scenePath. Use when starting a new scene from scratch; for adding nodes to an existing scene, use add_node. rootNodeType defaults to Node2D — pass "Node3D" for 3D scenes or "Control" for UI. Saves automatically. Overwrites silently if the file already exists. Returns: success and the scenePath that was written.', + annotations: { idempotentHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { + type: 'string', + description: 'Scene file path relative to the project (e.g. "scenes/main.tscn")', + }, + rootNodeType: { type: 'string', description: 'Root node type (default: Node2D)' }, + }, + required: ['projectPath', 'scenePath'], + }, + outputSchema: { + type: 'object', + properties: { + success: { type: 'boolean' }, + scenePath: { type: 'string' }, + }, + }, + }, + { + name: 'add_node', + description: 'Add a node to a Godot scene. Saves automatically. Common spatial properties (position, position3d, rotation, scale, visible, modulate) can be set as top-level params; for any other property, pass it under properties. Vector2/Vector3/Color values auto-convert from {x,y}/{x,y,z}/{r,g,b,a}. parentNodePath defaults to the scene root. Returns a plain-text confirmation message naming the new node and type. Errors if nodeType is not a registered Godot class or parentNodePath does not exist.', + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + nodeType: { + type: 'string', + description: 'Godot node class to instantiate (e.g. "Sprite2D", "CollisionShape2D", "Label")', + }, + nodeName: { + type: 'string', + description: 'Name for the new node as it appears in the scene tree', + }, + parentNodePath: { + type: 'string', + description: 'Parent node path from scene root (e.g. "root/Player"). Defaults to the root node.', + }, + position: { + type: 'object', + description: 'Vector2 position (e.g. {"x": 100, "y": 200})', + properties: { x: { type: 'number' }, y: { type: 'number' } }, + }, + position3d: { + type: 'object', + description: 'Vector3 position for 3D nodes (e.g. {"x": 0, "y": 1, "z": 0})', + properties: { x: { type: 'number' }, y: { type: 'number' }, z: { type: 'number' } }, + }, + rotation: { type: 'number', description: 'Rotation in radians' }, + scale: { + type: 'object', + description: 'Vector2 scale (e.g. {"x": 2, "y": 2})', + properties: { x: { type: 'number' }, y: { type: 'number' } }, + }, + visible: { type: 'boolean', description: 'Whether the node is visible' }, + modulate: { + type: 'object', + description: 'Color modulation (e.g. {"r": 1, "g": 0, "b": 0, "a": 1})', + properties: { + r: { type: 'number' }, + g: { type: 'number' }, + b: { type: 'number' }, + a: { type: 'number' }, + }, + }, + properties: { + type: 'object', + description: 'Additional property values as a JSON object. Top-level params (position, rotation, etc.) take precedence over keys in this dict.', + }, + }, + required: ['projectPath', 'scenePath', 'nodeType', 'nodeName'], + }, + }, + { + name: 'load_sprite', + description: 'Set the texture on an existing Sprite2D, Sprite3D, or TextureRect node. Use this when the node already exists; for new nodes, pass texture via add_node properties. Saves automatically. texturePath must be a real file under projectPath. Returns a plain-text confirmation message naming the loaded texture. Errors if the node is not one of those three classes, or the texture file does not exist.', + annotations: { idempotentHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + nodePath: { + type: 'string', + description: 'Path to the target node from scene root (e.g. "root/Player/Sprite2D")', + }, + texturePath: { + type: 'string', + description: 'Path to the texture file relative to the project (e.g. "assets/player.png")', + }, + }, + required: ['projectPath', 'scenePath', 'nodePath', 'texturePath'], + }, + }, + { + name: 'save_scene', + description: 'Re-pack and save a scene, optionally to a different path (save-as). Most mutations (add_node, set_node_properties, delete_nodes, etc.) auto-save — only use this for save-as via newPath, or to re-canonicalize a hand-edited .tscn. Overwrites silently. Returns a plain-text confirmation naming the save path. Errors if the scene file does not exist.', + annotations: { idempotentHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + newPath: { + type: 'string', + description: 'Save to a different path (relative to project) instead of overwriting the original', + }, + }, + required: ['projectPath', 'scenePath'], + }, + }, + { + name: 'export_mesh_library', + description: 'Export a scene of MeshInstance3D nodes as a MeshLibrary .res file for use in GridMap. Use this when authoring tile palettes for grid-based 3D levels; ignore for 2D or general scene work. The source scene must contain MeshInstance3D children. Pass meshItemNames to export a subset, or omit to export all. Saves the .res to outputPath, overwriting silently. Returns a plain-text confirmation with the exported item count. Errors if the scene contains no valid meshes.', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + scenePath: { type: 'string', description: 'Scene file path relative to the project' }, + outputPath: { + type: 'string', + description: 'Output path for the MeshLibrary .res file (relative to project)', + }, + meshItemNames: { + type: 'array', + items: { type: 'string' }, + description: 'Names of specific mesh items to export. Omit to export all.', + }, + }, + required: ['projectPath', 'scenePath', 'outputPath'], + }, + }, + { + name: 'batch_scene_operations', + description: 'Use this instead of chaining add_node / load_sprite / save_scene calls when you have multiple mutations on the same or related scenes — runs in one Godot process (~3s startup avoided per call) and shares an in-memory scene cache, saving once at the end. Each item picks its sub-operation (add_node, load_sprite, save) and supplies its own params; abortOnError stops on first failure (default false continues). Returns: results[] in input order, each tagged with operation and scenePath plus success or error.', + annotations: { destructiveHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { type: 'string', description: 'Path to the Godot project directory' }, + operations: { + type: 'array', + description: 'Ordered list of scene operations. Each item has its own operation and scenePath.', + items: { + type: 'object', + properties: { + operation: { + type: 'string', + enum: ['add_node', 'load_sprite', 'save'], + description: 'The sub-operation to perform', + }, + scenePath: { type: 'string', description: 'Scene file path for this operation' }, + nodeType: { type: 'string', description: '[add_node] Node class to instantiate' }, + nodeName: { type: 'string', description: '[add_node] Name for the new node' }, + parentNodePath: { + type: 'string', + description: '[add_node] Parent node path (defaults to root)', + }, + properties: { type: 'object', description: '[add_node] Initial property values' }, + nodePath: { type: 'string', description: '[load_sprite] Target node path' }, + texturePath: { + type: 'string', + description: '[load_sprite] Texture file path relative to project', + }, + newPath: { + type: 'string', + description: '[save] Save to a different path instead of overwriting', + }, + }, + required: ['operation'], + }, + }, + abortOnError: { + type: 'boolean', + description: 'Stop processing on first error (default: false)', + }, + }, + required: ['projectPath', 'operations'], + }, + outputSchema: { + type: 'object', + properties: { + results: { + type: 'array', + items: { + type: 'object', + properties: { + operation: { type: 'string' }, + scenePath: { type: 'string' }, + success: { type: 'boolean' }, + error: { type: 'string' }, + }, + }, + }, + }, + }, + }, +]; +// --- Handlers --- +export async function handleCreateScene(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args, { sceneRequired: false }); + if ('isError' in v) + return v; + const params = { + scenePath: args.scenePath, + rootNodeType: args.rootNodeType || 'Node2D', + }; + return executeSceneOp(runner, 'create_scene', params, v.projectPath, 'Failed to create scene', ['Check if the root node type is valid'], undefined, { parseStdoutAsJson: true }); +} +export async function handleAddNode(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.nodeType || !args.nodeName) { + return createErrorResponse('nodeType and nodeName are required', [ + 'Provide both nodeType and nodeName', + ]); + } + // Merge promoted top-level params into properties dict + const promotedKeys = [ + 'position', + 'position3d', + 'rotation', + 'scale', + 'visible', + 'modulate', + ]; + const mergedProps = args.properties || {}; + for (const key of promotedKeys) { + if (args[key] !== undefined) { + mergedProps[key] = args[key]; + } + } + const params = { + scenePath: args.scenePath, + nodeType: args.nodeType, + nodeName: args.nodeName, + }; + if (args.parentNodePath) + params.parentNodePath = args.parentNodePath; + if (Object.keys(mergedProps).length > 0) + params.properties = mergedProps; + return executeSceneOp(runner, 'add_node', params, v.projectPath, 'Failed to add node', [ + 'Check if the node type is valid', + 'Ensure the parent node path exists', + ]); +} +export async function handleLoadSprite(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.nodePath || !validateNodePath(args.nodePath)) { + return createErrorResponse('Valid nodePath is required', ['Provide the target node path']); + } + if (!args.texturePath || !validateSubPath(v.projectPath, args.texturePath)) { + return createErrorResponse('Valid texturePath is required', [ + 'Provide a relative texture path that stays inside the project directory', + ]); + } + const textureFullPath = join(v.projectPath, args.texturePath); + if (!existsSync(textureFullPath)) { + return createErrorResponse(`Texture file does not exist: ${args.texturePath}`, [ + 'Ensure the texture path is correct', + ]); + } + const params = { + scenePath: args.scenePath, + nodePath: args.nodePath, + texturePath: args.texturePath, + }; + return executeSceneOp(runner, 'load_sprite', params, v.projectPath, 'Failed to load sprite', [ + 'Check if the node is a Sprite2D, Sprite3D, or TextureRect', + ]); +} +export async function handleSaveScene(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (args.newPath && !validateSubPath(v.projectPath, args.newPath)) { + return createErrorResponse('Invalid newPath', [ + 'Provide a valid relative path without ".." that stays inside the project directory', + ]); + } + const params = { scenePath: args.scenePath }; + if (args.newPath) + params.newPath = args.newPath; + return executeSceneOp(runner, 'save_scene', params, v.projectPath, 'Failed to save scene', [ + 'Check if the scene file is valid', + ]); +} +export async function handleExportMeshLibrary(runner, args) { + args = normalizeParameters(args); + const v = validateSceneArgs(args); + if ('isError' in v) + return v; + if (!args.outputPath || !validateSubPath(v.projectPath, args.outputPath)) { + return createErrorResponse('Valid outputPath is required', [ + 'Provide an output path for the .res file that stays inside the project directory', + ]); + } + const params = { + scenePath: args.scenePath, + outputPath: args.outputPath, + }; + if (args.meshItemNames && Array.isArray(args.meshItemNames)) { + params.meshItemNames = args.meshItemNames; + } + return executeSceneOp(runner, 'export_mesh_library', params, v.projectPath, 'Failed to export mesh library', ['Check if the scene contains valid 3D meshes']); +} +export async function handleBatchSceneOperations(runner, args) { + args = normalizeParameters(args); + const v = validateProjectArgs(args); + if ('isError' in v) + return v; + if (!args.operations || !Array.isArray(args.operations)) { + return createErrorResponse('operations array is required', [ + 'Provide an operations array with at least one item', + ]); + } + const params = { + operations: args.operations, + abortOnError: args.abortOnError ?? false, + }; + return executeSceneOp(runner, 'batch_scene_operations', params, v.projectPath, 'Batch scene operations failed', ['Check that all scene paths exist', 'Ensure node types are valid'], undefined, { parseStdoutAsJson: true }); +} +//# sourceMappingURL=scene-tools.js.map \ No newline at end of file diff --git a/package/dist/tools/scene-tools.js.map b/package/dist/tools/scene-tools.js.map new file mode 100644 index 0000000..db3e60f --- /dev/null +++ b/package/dist/tools/scene-tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scene-tools.js","sourceRoot":"","sources":["../../src/tools/scene-tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/tools/validate-tools.d.ts b/package/dist/tools/validate-tools.d.ts new file mode 100644 index 0000000..cc999f3 --- /dev/null +++ b/package/dist/tools/validate-tools.d.ts @@ -0,0 +1,15 @@ +import type { GodotRunner, OperationParams, ToolDefinition } from '../utils/godot-runner.js'; +export declare const validateToolDefinitions: ToolDefinition[]; +export declare function handleValidate(runner: GodotRunner, args: OperationParams): Promise<{ + content: Array<{ + type: "text"; + text: string; + }>; + isError: boolean; +} | { + content: { + type: string; + text: string; + }[]; +}>; +//# sourceMappingURL=validate-tools.d.ts.map \ No newline at end of file diff --git a/package/dist/tools/validate-tools.d.ts.map b/package/dist/tools/validate-tools.d.ts.map new file mode 100644 index 0000000..be962af --- /dev/null +++ b/package/dist/tools/validate-tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"validate-tools.d.ts","sourceRoot":"","sources":["../../src/tools/validate-tools.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAU7F,eAAO,MAAM,uBAAuB,EAAE,cAAc,EAmDnD,CAAC;AAmIF,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe;;;;;;;;;;;GAqP9E"} \ No newline at end of file diff --git a/package/dist/tools/validate-tools.js b/package/dist/tools/validate-tools.js new file mode 100644 index 0000000..f3d41ae --- /dev/null +++ b/package/dist/tools/validate-tools.js @@ -0,0 +1,375 @@ +import { join } from 'path'; +import { existsSync, writeFileSync, unlinkSync, mkdirSync } from 'fs'; +import { randomUUID } from 'crypto'; +import { normalizeParameters, validateSubPath, validateProjectArgs, createErrorResponse, extractGdError, getErrorMessage, } from '../utils/godot-runner.js'; +export const validateToolDefinitions = [ + { + name: 'validate', + description: "Validate GDScript syntax or scene file integrity using headless Godot. Use before attach_script or run_script to catch parse errors early. Single-target: provide exactly one of scriptPath, source, or scenePath. Batch: provide a targets array — runs all in one Godot process. Returns { valid, errors: [{ line?, message }] } for single, or { results: [{ target, valid, errors }] } for batch. Line numbers appear when Godot's stderr includes them (not always). Returns valid:false on any parse error; never throws.", + annotations: { readOnlyHint: true }, + inputSchema: { + type: 'object', + properties: { + projectPath: { + type: 'string', + description: 'Path to the Godot project directory', + }, + scriptPath: { + type: 'string', + description: '[single] Path to a .gd file relative to the project to validate (e.g. "scripts/player.gd")', + }, + source: { + type: 'string', + description: '[single] Inline GDScript source code to validate. Written to a temporary file and validated against the project.', + }, + scenePath: { + type: 'string', + description: '[single] Path to a .tscn scene file relative to the project to validate (e.g. "scenes/main.tscn")', + }, + targets: { + type: 'array', + description: '[batch] Array of targets to validate in a single Godot process. Each item must have exactly one of: scriptPath, source, or scenePath.', + items: { + type: 'object', + properties: { + scriptPath: { + type: 'string', + description: 'Path to a .gd file relative to the project', + }, + source: { type: 'string', description: 'Inline GDScript source code' }, + scenePath: { + type: 'string', + description: 'Path to a .tscn file relative to the project', + }, + }, + }, + }, + }, + required: ['projectPath'], + }, + }, +]; +/** + * Core Godot stderr parser. Returns a flat list of error entries, each with an + * optional line number and optional res:// file path (from the "at:" line). + */ +function parseGodotErrorEntries(stderr) { + const entries = []; + if (!stderr) + return entries; + const lines = stderr.split('\n'); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + // Pattern: "SCRIPT ERROR: Parse Error: MESSAGE" or "ERROR: MESSAGE" + // followed by " at: res://...:LINE" or " at: ...:LINE" + const scriptErrorMatch = line.match(/SCRIPT ERROR:\s*(?:Parse Error:\s*)?(.+)/); + const errorMatch = !scriptErrorMatch ? line.match(/^ERROR:\s*(.+)/) : null; + const match = scriptErrorMatch || errorMatch; + if (match) { + const message = match[1].trim(); + let lineNum; + let filePath; + if (i + 1 < lines.length) { + // Try res:// path first (captures file + line). Tolerates an optional + // " (" prefix before res:// so we catch both + // " at: res://foo.gd:3" + // and + // " at: GDScript::reload (res://foo.gd:3)" + // Real Godot 4.5 stderr uses the parenthesized form. + const resAtMatch = lines[i + 1].match(/\s*at:\s*(?:[^()\n]*\()?(res:\/\/[^):"\s]+):(\d+)/); + if (resAtMatch) { + filePath = resAtMatch[1]; + lineNum = parseInt(resAtMatch[2], 10); + i++; + } + else { + // Fall back to loose match (line only, e.g. native code "at:" lines) + const looseAtMatch = lines[i + 1].match(/\s*at:\s*.+:(\d+)/); + if (looseAtMatch) { + lineNum = parseInt(looseAtMatch[1], 10); + i++; + } + } + } + // Parse-error entries reference synthetic gdscript:// URIs in their `at:` line + // rather than a res:// path. Peek forward up to 10 lines for the secondary + // "Failed to load script/resource: \"res://...\"" message that names the file, + // and adopt that path so batch error attribution can find it. The window is + // intentionally wide enough to clear a full GDScript backtrace. + if (!filePath && /Parse Error/i.test(line)) { + const lookaheadLimit = Math.min(i + 11, lines.length); + for (let j = i + 1; j < lookaheadLimit; j++) { + const failMatch = lines[j].match(/Failed to load (?:script|resource):?\s*"?(res:\/\/[^":\s]+)/); + if (failMatch) { + filePath = failMatch[1]; + break; + } + } + } + entries.push({ message, line: lineNum, filePath }); + continue; + } + // Pattern: "Parse Error: MESSAGE at line LINE" + const parseErrorMatch = line.match(/Parse Error:\s*(.+?)\s+at line\s+(\d+)/); + if (parseErrorMatch) { + entries.push({ + line: parseInt(parseErrorMatch[2], 10), + message: parseErrorMatch[1].trim(), + }); + } + } + return entries; +} +function parseGodotErrors(stderr) { + return parseGodotErrorEntries(stderr).map(({ message, line }) => ({ message, line })); +} +/** + * Write inline GDScript source to a uniquely-named file under /.mcp/ + * for validation. Returns the project-relative path (e.g. ".mcp/validate_temp_xxx.gd") + * that the runner consumes plus the absolute path the caller cleans up. + */ +function writeTempGdScript(projectPath, source, prefix) { + const mcpDir = join(projectPath, '.mcp'); + mkdirSync(mcpDir, { recursive: true }); + const name = `${prefix}_${randomUUID()}.gd`; + const absPath = join(mcpDir, name); + writeFileSync(absPath, source, 'utf8'); + return { resPath: `.mcp/${name}`, absPath }; +} +/** + * Group Godot stderr errors by their res:// file path. + * Used for batch validation where multiple files produce output in one stderr stream. + */ +function parseGodotErrorsByPath(stderr) { + const result = new Map(); + for (const { message, line, filePath } of parseGodotErrorEntries(stderr)) { + if (filePath) { + if (!result.has(filePath)) + result.set(filePath, []); + result.get(filePath).push({ line, message }); + } + } + return result; +} +export async function handleValidate(runner, args) { + args = normalizeParameters(args); + const pv = validateProjectArgs(args); + if ('isError' in pv) + return pv; + // Batch mode: targets array + if (args.targets && Array.isArray(args.targets)) { + const targets = args.targets; + const tempFiles = []; + try { + const snakeTargets = []; + const preErrors = new Map(); + for (let i = 0; i < targets.length; i++) { + const t = targets[i]; + if (t.source) { + const { resPath, absPath } = writeTempGdScript(pv.projectPath, t.source, 'validate_batch'); + tempFiles.push(absPath); + snakeTargets.push({ script_path: resPath }); + } + else if (t.scriptPath) { + if (!validateSubPath(pv.projectPath, t.scriptPath)) { + preErrors.set(i, { + target: t.scriptPath, + errors: [ + { + message: 'Invalid scriptPath: must be a relative path inside the project root, no ".."', + }, + ], + }); + } + else { + snakeTargets.push({ script_path: t.scriptPath }); + } + } + else if (t.scenePath) { + if (!validateSubPath(pv.projectPath, t.scenePath)) { + preErrors.set(i, { + target: t.scenePath, + errors: [ + { + message: 'Invalid scenePath: must be a relative path inside the project root, no ".."', + }, + ], + }); + } + else { + snakeTargets.push({ scene_path: t.scenePath }); + } + } + else { + snakeTargets.push({}); + } + } + // Short-circuit when every target failed pre-validation — no work for + // Godot, and spawning it would just cost ~3s for a no-op. + if (snakeTargets.length === 0 && preErrors.size === targets.length) { + const results = targets.map((_, i) => { + const pre = preErrors.get(i); + return { target: pre.target, valid: false, errors: pre.errors }; + }); + return { content: [{ type: 'text', text: JSON.stringify({ results }, null, 2) }] }; + } + const { stdout, stderr } = await runner.executeOperation('validate_batch', { targets: snakeTargets }, pv.projectPath); + if (!stdout.trim()) { + return createErrorResponse(`Batch validate failed: ${extractGdError(stderr)}`, [ + 'Check that all target paths are valid', + 'Ensure Godot is installed correctly', + ]); + } + let parsed; + try { + parsed = JSON.parse(stdout.trim()); + } + catch { + return createErrorResponse(`Invalid response from validate_batch: ${stdout}`, [ + 'Ensure Godot is installed correctly', + ]); + } + const errorsByPath = parseGodotErrorsByPath(stderr || ''); + const godotResults = parsed.results.map((r) => { + const key = r.target.startsWith('res://') ? r.target : `res://${r.target}`; + const stderrErrors = errorsByPath.get(key) || errorsByPath.get(r.target) || []; + const allErrors = stderrErrors.length > 0 ? stderrErrors : r.errors || []; + return { + target: r.target, + valid: r.valid && stderrErrors.length === 0, + errors: allErrors, + }; + }); + // Merge pre-validation failures back into their original positions so + // output order matches input order. Pre-validation errors are ours, not + // Godot's — they bypass the stderr overlay above. + const results = []; + let godotIdx = 0; + for (let i = 0; i < targets.length; i++) { + if (preErrors.has(i)) { + const pre = preErrors.get(i); + results.push({ target: pre.target, valid: false, errors: pre.errors }); + } + else { + results.push(godotResults[godotIdx++]); + } + } + return { content: [{ type: 'text', text: JSON.stringify({ results }, null, 2) }] }; + } + catch (error) { + return createErrorResponse(`Batch validation failed: ${getErrorMessage(error)}`, [ + 'Ensure Godot is installed correctly', + 'Check if the GODOT_PATH environment variable is set correctly', + ]); + } + finally { + for (const f of tempFiles) { + try { + unlinkSync(f); + } + catch { + /* ignore */ + } + } + } + } + // Determine mode — exactly one must be provided + const modeCount = [args.scriptPath, args.source, args.scenePath].filter(Boolean).length; + if (modeCount === 0) { + return createErrorResponse('One of scriptPath, source, or scenePath is required', [ + 'Provide scriptPath to validate an existing .gd file, source to validate inline GDScript, or scenePath to validate a .tscn file', + ]); + } + if (modeCount > 1) { + return createErrorResponse('Provide exactly one of scriptPath, source, or scenePath — not multiple', ['Only one target can be validated per call']); + } + let tempFile = false; + let resolvedScriptPath; + let resolvedScenePath; + try { + if (args.source) { + const { resPath } = writeTempGdScript(pv.projectPath, args.source, 'validate_temp'); + resolvedScriptPath = resPath; + tempFile = true; + } + else if (args.scriptPath) { + if (!validateSubPath(pv.projectPath, args.scriptPath)) { + return createErrorResponse('Invalid scriptPath', [ + 'Provide a valid relative path without ".." that stays inside the project directory', + ]); + } + const fullPath = join(pv.projectPath, args.scriptPath); + if (!existsSync(fullPath)) { + return createErrorResponse(`Script file does not exist: ${args.scriptPath}`, [ + 'Ensure the path is correct relative to the project directory', + ]); + } + resolvedScriptPath = args.scriptPath; + } + else if (args.scenePath) { + if (!validateSubPath(pv.projectPath, args.scenePath)) { + return createErrorResponse('Invalid scenePath', [ + 'Provide a valid relative path without ".." that stays inside the project directory', + ]); + } + const fullPath = join(pv.projectPath, args.scenePath); + if (!existsSync(fullPath)) { + return createErrorResponse(`Scene file does not exist: ${args.scenePath}`, [ + 'Ensure the path is correct relative to the project directory', + ]); + } + resolvedScenePath = args.scenePath; + } + const params = {}; + if (resolvedScriptPath) + params.scriptPath = resolvedScriptPath; + if (resolvedScenePath) + params.scenePath = resolvedScenePath; + const { stdout, stderr } = await runner.executeOperation('validate_resource', params, pv.projectPath); + // Parse stdout for the base valid/invalid signal from GDScript + let valid = false; + let gdErrors = []; + try { + const parsed = JSON.parse(stdout.trim()); + valid = parsed.valid === true; + if (Array.isArray(parsed.errors) && parsed.errors.length > 0) { + gdErrors = parsed.errors; + } + } + catch { + // stdout wasn't JSON — treat as invalid + valid = false; + } + // Parse stderr for detailed error messages from Godot's script compiler + const stderrErrors = parseGodotErrors(stderr || ''); + // Merge errors: prefer detailed stderr errors when available, otherwise keep gdErrors + const allErrors = stderrErrors.length > 0 ? stderrErrors : gdErrors; + // The GDScript-side `valid` flag is unreliable for malformed scripts: load() + // returns a non-null placeholder Resource even when parsing fails, so + // resource != null is true. Fall back to the parsed stderr errors as the + // authoritative signal — matches the batch branch above. + const result = { + valid: valid && allErrors.length === 0, + errors: allErrors, + }; + return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; + } + catch (error) { + return createErrorResponse(`Validation failed: ${getErrorMessage(error)}`, [ + 'Ensure Godot is installed correctly', + 'Check if the GODOT_PATH environment variable is set correctly', + ]); + } + finally { + if (tempFile && resolvedScriptPath) { + const tempFilePath = join(pv.projectPath, resolvedScriptPath); + try { + unlinkSync(tempFilePath); + } + catch { + // Ignore cleanup errors + } + } + } +} +//# sourceMappingURL=validate-tools.js.map \ No newline at end of file diff --git a/package/dist/tools/validate-tools.js.map b/package/dist/tools/validate-tools.js.map new file mode 100644 index 0000000..00d036e --- /dev/null +++ b/package/dist/tools/validate-tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"validate-tools.js","sourceRoot":"","sources":["../../src/tools/validate-tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/utils/autoload-ini.d.ts b/package/dist/utils/autoload-ini.d.ts new file mode 100644 index 0000000..a76a188 --- /dev/null +++ b/package/dist/utils/autoload-ini.d.ts @@ -0,0 +1,38 @@ +/** + * Parsing and editing primitives for the `[autoload]` section of project.godot. + * + * Used by: + * - tools/autoload-tools.ts — list/add/remove/update_autoload handlers + * - utils/bridge-manager.ts — McpBridge inject/cleanup/repair + * + * Pure functions: each takes the absolute path to project.godot and returns + * either parsed data or a boolean indicating whether the file was mutated. + */ +export interface AutoloadEntry { + name: string; + path: string; + singleton: boolean; +} +/** + * Matches an empty `[autoload]` section (the header followed by only blank + * lines, up to the next section header or end-of-file). Used by cleanup paths + * to drop the section after the last entry is removed. + */ +export declare const EMPTY_AUTOLOAD_SECTION_REGEX: RegExp; +/** + * Mirrors the parser's `\w+` assumption (parseAutoloads / removeAutoloadEntry). + * Enforced on write paths to prevent a name with newlines or INI section + * delimiters from corrupting project.godot. + */ +export declare const VALID_AUTOLOAD_NAME_REGEX: RegExp; +export declare function normalizeAutoloadPath(p: string): string; +export declare function parseAutoloads(projectFilePath: string, existingContent?: string): AutoloadEntry[]; +export declare function addAutoloadEntry(projectFilePath: string, name: string, path: string, singleton: boolean, existingContent?: string): void; +/** + * Remove the named autoload entry. Also drops the `[autoload]` section header + * if the removed entry was the last one in it. Returns true when the file was + * mutated. + */ +export declare function removeAutoloadEntry(projectFilePath: string, name: string): boolean; +export declare function updateAutoloadEntry(projectFilePath: string, name: string, newPath?: string, singleton?: boolean): boolean; +//# sourceMappingURL=autoload-ini.d.ts.map \ No newline at end of file diff --git a/package/dist/utils/autoload-ini.d.ts.map b/package/dist/utils/autoload-ini.d.ts.map new file mode 100644 index 0000000..d5bd53a --- /dev/null +++ b/package/dist/utils/autoload-ini.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"autoload-ini.d.ts","sourceRoot":"","sources":["../../src/utils/autoload-ini.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,QAAkC,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,QAAU,CAAC;AAUjD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CAsBjG;AAED,wBAAgB,gBAAgB,CAC9B,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,OAAO,EAClB,eAAe,CAAC,EAAE,MAAM,GACvB,IAAI,CAkBN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CA6BlF;AAED,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CA8BT"} \ No newline at end of file diff --git a/package/dist/utils/autoload-ini.js b/package/dist/utils/autoload-ini.js new file mode 100644 index 0000000..306ef49 --- /dev/null +++ b/package/dist/utils/autoload-ini.js @@ -0,0 +1,124 @@ +import { readFileSync, writeFileSync } from 'fs'; +/** + * Matches an empty `[autoload]` section (the header followed by only blank + * lines, up to the next section header or end-of-file). Used by cleanup paths + * to drop the section after the last entry is removed. + */ +export const EMPTY_AUTOLOAD_SECTION_REGEX = /\[autoload\]\s*(?=\n\[|\n*$)/g; +/** + * Mirrors the parser's `\w+` assumption (parseAutoloads / removeAutoloadEntry). + * Enforced on write paths to prevent a name with newlines or INI section + * delimiters from corrupting project.godot. + */ +export const VALID_AUTOLOAD_NAME_REGEX = /^\w+$/; +function assertValidName(name) { + if (!VALID_AUTOLOAD_NAME_REGEX.test(name)) { + throw new Error(`Invalid autoload name '${name}': must contain only word characters (letters, digits, underscore)`); + } +} +export function normalizeAutoloadPath(p) { + return p.startsWith('res://') ? p : `res://${p}`; +} +export function parseAutoloads(projectFilePath, existingContent) { + const content = existingContent ?? readFileSync(projectFilePath, 'utf8'); + const autoloads = []; + let inAutoloadSection = false; + for (const line of content.split('\n')) { + const trimmed = line.trim(); + if (trimmed.startsWith('[')) { + inAutoloadSection = trimmed === '[autoload]'; + continue; + } + if (!inAutoloadSection || trimmed === '' || trimmed.startsWith(';') || trimmed.startsWith('#')) + continue; + // The surrounding `"?` are intentional: Godot always writes quotes, but + // hand-edited project.godot files sometimes omit them. Tolerating both + // shapes means a missing quote pair doesn't silently drop the entry. + const match = trimmed.match(/^(\w+)="?(\*?)([^"]*?)"?$/); + if (match) { + autoloads.push({ name: match[1], singleton: match[2] === '*', path: match[3] }); + } + } + return autoloads; +} +export function addAutoloadEntry(projectFilePath, name, path, singleton, existingContent) { + assertValidName(name); + const content = existingContent ?? readFileSync(projectFilePath, 'utf8'); + const lines = content.split('\n'); + const entry = `${name}="${singleton ? '*' : ''}${normalizeAutoloadPath(path)}"`; + const sectionIdx = lines.findIndex((l) => l.trim() === '[autoload]'); + if (sectionIdx === -1) { + writeFileSync(projectFilePath, content.trimEnd() + '\n\n[autoload]\n' + entry + '\n', 'utf8'); + return; + } + let insertIdx = sectionIdx + 1; + while (insertIdx < lines.length && !lines[insertIdx].trim().startsWith('[')) { + insertIdx++; + } + lines.splice(insertIdx, 0, entry); + writeFileSync(projectFilePath, lines.join('\n'), 'utf8'); +} +/** + * Remove the named autoload entry. Also drops the `[autoload]` section header + * if the removed entry was the last one in it. Returns true when the file was + * mutated. + */ +export function removeAutoloadEntry(projectFilePath, name) { + const content = readFileSync(projectFilePath, 'utf8'); + const lines = content.split('\n'); + let inAutoloadSection = false; + let removed = false; + const filtered = lines.filter((line) => { + const trimmed = line.trim(); + if (trimmed.startsWith('[')) { + inAutoloadSection = trimmed === '[autoload]'; + return true; + } + if (inAutoloadSection) { + const match = trimmed.match(/^(\w+)=/); + if (match && match[1] === name) { + removed = true; + return false; + } + } + return true; + }); + if (!removed) + return false; + let newContent = filtered.join('\n'); + newContent = newContent.replace(EMPTY_AUTOLOAD_SECTION_REGEX, ''); + newContent = newContent.trimEnd() + '\n'; + writeFileSync(projectFilePath, newContent, 'utf8'); + return true; +} +export function updateAutoloadEntry(projectFilePath, name, newPath, singleton) { + assertValidName(name); + const content = readFileSync(projectFilePath, 'utf8'); + const lines = content.split('\n'); + let inAutoloadSection = false; + let updated = false; + const newLines = lines.map((line) => { + const trimmed = line.trim(); + if (trimmed.startsWith('[')) { + inAutoloadSection = trimmed === '[autoload]'; + return line; + } + if (inAutoloadSection) { + // The surrounding `"?` are intentional: Godot always writes quotes, but + // hand-edited project.godot files sometimes omit them. Tolerating both + // shapes means a missing quote pair doesn't silently drop the entry. + const match = trimmed.match(/^(\w+)="?(\*?)([^"]*?)"?$/); + if (match && match[1] === name) { + const effectiveSingleton = singleton !== undefined ? singleton : match[2] === '*'; + const effectivePath = newPath !== undefined ? normalizeAutoloadPath(newPath) : match[3]; + updated = true; + return `${name}="${effectiveSingleton ? '*' : ''}${effectivePath}"`; + } + } + return line; + }); + if (updated) + writeFileSync(projectFilePath, newLines.join('\n'), 'utf8'); + return updated; +} +//# sourceMappingURL=autoload-ini.js.map \ No newline at end of file diff --git a/package/dist/utils/autoload-ini.js.map b/package/dist/utils/autoload-ini.js.map new file mode 100644 index 0000000..6b18a9e --- /dev/null +++ b/package/dist/utils/autoload-ini.js.map @@ -0,0 +1 @@ +{"version":3,"file":"autoload-ini.js","sourceRoot":"","sources":["../../src/utils/autoload-ini.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/utils/bridge-manager.d.ts b/package/dist/utils/bridge-manager.d.ts new file mode 100644 index 0000000..6cf0a1d --- /dev/null +++ b/package/dist/utils/bridge-manager.d.ts @@ -0,0 +1,46 @@ +/** + * Owns the McpBridge autoload artifact: the script copy in the target project, + * the `[autoload]` entry in project.godot, the `.mcp/.gdignore` marker, and the + * `.gitignore` augmentation. GodotRunner delegates to this for inject/cleanup + * during run_project / attach_project / stop_project flows. + * + * The project-root bridge script is runtime-owned and refreshed on first + * injection for a manager session so a rebuilt server cannot talk to stale + * GDScript from an earlier run. Idempotent within a session via + * `injectedProjects`: a second `inject()` call for the same path short-circuits + * without rewriting project.godot. + */ +export declare class BridgeManager { + private bridgeScriptPath; + private injectedProjects; + private repairedProjects; + /** + * Last port baked into the on-disk script per project. Used by the + * race-detection helper in runtime-tools to spot a concurrent re-inject + * after a bridge-wait timeout. + */ + private lastInjectedPort; + constructor(bridgeScriptPath: string); + inject(projectPath: string, port: number): void; + cleanup(projectPath: string): void; + /** + * Read the port currently baked into the project's bridge script. Returns + * the integer on success, or null if the file is missing, unreadable, or + * lacks the marker. Used to detect concurrent re-inject after a bridge- + * wait timeout (another MCP client may have rewritten the port). + */ + readBakedPort(projectPath: string): number | null; + /** + * If project.godot still has an `McpBridge=` line but the script file is + * missing, the autoload would crash every subsequent headless op. Detect and + * clean the orphan before running an operation. + * + * Cached per project: once a path has been checked clean, skip the file + * reads on subsequent ops in the same session. + */ + repairOrphaned(projectPath: string): void; + private removeBridgeArtifacts; + private ensureMcpGdignore; + private ensureGitignored; +} +//# sourceMappingURL=bridge-manager.d.ts.map \ No newline at end of file diff --git a/package/dist/utils/bridge-manager.d.ts.map b/package/dist/utils/bridge-manager.d.ts.map new file mode 100644 index 0000000..f120f61 --- /dev/null +++ b/package/dist/utils/bridge-manager.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"bridge-manager.d.ts","sourceRoot":"","sources":["../../src/utils/bridge-manager.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;GAWG;AACH,qBAAa,aAAa;IAUZ,OAAO,CAAC,gBAAgB;IATpC,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,gBAAgB,CAA0B;IAClD;;;;OAIG;IACH,OAAO,CAAC,gBAAgB,CAAkC;gBAEtC,gBAAgB,EAAE,MAAM;IAE5C,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAuC/C,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAOlC;;;;;OAKG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAejD;;;;;;;OAOG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAqBzC,OAAO,CAAC,qBAAqB;IAkC7B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;CAkBzB"} \ No newline at end of file diff --git a/package/dist/utils/bridge-manager.js b/package/dist/utils/bridge-manager.js new file mode 100644 index 0000000..6af7003 --- /dev/null +++ b/package/dist/utils/bridge-manager.js @@ -0,0 +1,186 @@ +import { join } from 'path'; +import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync } from 'fs'; +import { logDebug } from './logger.js'; +import { addAutoloadEntry, parseAutoloads, removeAutoloadEntry } from './autoload-ini.js'; +const BRIDGE_AUTOLOAD_NAME = 'McpBridge'; +const BRIDGE_SCRIPT_FILENAME = 'mcp_bridge.gd'; +const MCP_GITIGNORE_ENTRY = '.mcp/'; +// Matches the baked-port marker line inserted in src/scripts/mcp_bridge.gd — +// `const PORT := ` — so inject() can rewrite the integer per project. +const BAKED_PORT_REGEX = /const PORT := \d+/; +/** + * Owns the McpBridge autoload artifact: the script copy in the target project, + * the `[autoload]` entry in project.godot, the `.mcp/.gdignore` marker, and the + * `.gitignore` augmentation. GodotRunner delegates to this for inject/cleanup + * during run_project / attach_project / stop_project flows. + * + * The project-root bridge script is runtime-owned and refreshed on first + * injection for a manager session so a rebuilt server cannot talk to stale + * GDScript from an earlier run. Idempotent within a session via + * `injectedProjects`: a second `inject()` call for the same path short-circuits + * without rewriting project.godot. + */ +export class BridgeManager { + bridgeScriptPath; + injectedProjects = new Set(); + repairedProjects = new Set(); + /** + * Last port baked into the on-disk script per project. Used by the + * race-detection helper in runtime-tools to spot a concurrent re-inject + * after a bridge-wait timeout. + */ + lastInjectedPort = new Map(); + constructor(bridgeScriptPath) { + this.bridgeScriptPath = bridgeScriptPath; + } + inject(projectPath, port) { + // Always rewrite the destination — the per-project bridge script may + // differ from the template by exactly the baked integer, so a size/mtime + // shortcut no longer maps to "up-to-date." Bake the resolved port into + // the const PORT line so the running game listens on the exact port the + // Node side will connect to. + const template = readFileSync(this.bridgeScriptPath, 'utf8'); + if (!BAKED_PORT_REGEX.test(template)) { + throw new Error(`Bridge script template at ${this.bridgeScriptPath} is missing the 'const PORT := ' marker`); + } + const baked = template.replace(BAKED_PORT_REGEX, `const PORT := ${port}`); + const destScript = join(projectPath, BRIDGE_SCRIPT_FILENAME); + writeFileSync(destScript, baked, 'utf8'); + this.lastInjectedPort.set(projectPath, port); + logDebug(`Wrote bridge autoload at ${destScript} (baked port ${port})`); + if (this.injectedProjects.has(projectPath)) { + logDebug('Bridge already injected for this project; refreshed script only.'); + return; + } + this.ensureMcpGdignore(projectPath); + this.ensureGitignored(projectPath); + const projectFile = join(projectPath, 'project.godot'); + const existing = parseAutoloads(projectFile); + const alreadyRegistered = existing.some((a) => a.name === BRIDGE_AUTOLOAD_NAME); + if (alreadyRegistered) { + logDebug('Bridge autoload already present, skipping injection'); + } + else { + addAutoloadEntry(projectFile, BRIDGE_AUTOLOAD_NAME, BRIDGE_SCRIPT_FILENAME, true); + logDebug('Injected bridge autoload into project.godot'); + } + this.injectedProjects.add(projectPath); + } + cleanup(projectPath) { + this.removeBridgeArtifacts(projectPath); + this.injectedProjects.delete(projectPath); + this.repairedProjects.delete(projectPath); + this.lastInjectedPort.delete(projectPath); + } + /** + * Read the port currently baked into the project's bridge script. Returns + * the integer on success, or null if the file is missing, unreadable, or + * lacks the marker. Used to detect concurrent re-inject after a bridge- + * wait timeout (another MCP client may have rewritten the port). + */ + readBakedPort(projectPath) { + const destScript = join(projectPath, BRIDGE_SCRIPT_FILENAME); + if (!existsSync(destScript)) + return null; + try { + const content = readFileSync(destScript, 'utf8'); + const match = content.match(BAKED_PORT_REGEX); + if (!match) + return null; + const parsed = Number.parseInt(match[0].replace(/^const PORT := /, ''), 10); + if (!Number.isFinite(parsed) || parsed <= 0 || parsed > 65535) + return null; + return parsed; + } + catch { + return null; + } + } + /** + * If project.godot still has an `McpBridge=` line but the script file is + * missing, the autoload would crash every subsequent headless op. Detect and + * clean the orphan before running an operation. + * + * Cached per project: once a path has been checked clean, skip the file + * reads on subsequent ops in the same session. + */ + repairOrphaned(projectPath) { + if (this.repairedProjects.has(projectPath)) + return; + const projectFile = join(projectPath, 'project.godot'); + const bridgeScript = join(projectPath, BRIDGE_SCRIPT_FILENAME); + if (!existsSync(projectFile)) + return; + if (existsSync(bridgeScript)) { + this.repairedProjects.add(projectPath); + return; + } + try { + const content = readFileSync(projectFile, 'utf8'); + if (content.includes(`${BRIDGE_AUTOLOAD_NAME}=`)) { + this.removeBridgeArtifacts(projectPath); + logDebug('Cleaned up orphaned McpBridge autoload entry'); + } + this.repairedProjects.add(projectPath); + } + catch (err) { + logDebug(`Non-fatal: Failed to check/repair orphaned bridge: ${err}`); + } + } + removeBridgeArtifacts(projectPath) { + try { + const projectFile = join(projectPath, 'project.godot'); + if (existsSync(projectFile)) { + const removed = removeAutoloadEntry(projectFile, BRIDGE_AUTOLOAD_NAME); + if (removed) { + logDebug(`Removed ${BRIDGE_AUTOLOAD_NAME} autoload from project.godot`); + } + } + } + catch (err) { + logDebug(`Non-fatal: Failed to clean ${BRIDGE_AUTOLOAD_NAME} from project.godot: ${err}`); + } + try { + const scriptFile = join(projectPath, BRIDGE_SCRIPT_FILENAME); + if (existsSync(scriptFile)) { + unlinkSync(scriptFile); + logDebug(`Removed ${BRIDGE_SCRIPT_FILENAME} from project`); + } + } + catch (err) { + logDebug(`Non-fatal: Failed to remove ${BRIDGE_SCRIPT_FILENAME}: ${err}`); + } + try { + const uidFile = join(projectPath, `${BRIDGE_SCRIPT_FILENAME}.uid`); + if (existsSync(uidFile)) { + unlinkSync(uidFile); + logDebug(`Removed ${BRIDGE_SCRIPT_FILENAME}.uid from project`); + } + } + catch (err) { + logDebug(`Non-fatal: Failed to remove ${BRIDGE_SCRIPT_FILENAME}.uid: ${err}`); + } + } + ensureMcpGdignore(projectPath) { + const mcpDir = join(projectPath, '.mcp'); + mkdirSync(mcpDir, { recursive: true }); + writeFileSync(join(mcpDir, '.gdignore'), '', 'utf8'); + logDebug('Created .mcp/.gdignore'); + } + ensureGitignored(projectPath) { + const gitignorePath = join(projectPath, '.gitignore'); + if (existsSync(gitignorePath)) { + const gitignoreContent = readFileSync(gitignorePath, 'utf8'); + if (!gitignoreContent.includes(MCP_GITIGNORE_ENTRY)) { + const newline = gitignoreContent.endsWith('\n') ? '' : '\n'; + writeFileSync(gitignorePath, gitignoreContent + newline + MCP_GITIGNORE_ENTRY + '\n', 'utf8'); + logDebug('Added .mcp/ to existing .gitignore'); + } + } + else { + writeFileSync(gitignorePath, MCP_GITIGNORE_ENTRY + '\n', 'utf8'); + logDebug('Created .gitignore with .mcp/ entry'); + } + } +} +//# sourceMappingURL=bridge-manager.js.map \ No newline at end of file diff --git a/package/dist/utils/bridge-manager.js.map b/package/dist/utils/bridge-manager.js.map new file mode 100644 index 0000000..58f5571 --- /dev/null +++ b/package/dist/utils/bridge-manager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bridge-manager.js","sourceRoot":"","sources":["../../src/utils/bridge-manager.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/utils/bridge-protocol.d.ts b/package/dist/utils/bridge-protocol.d.ts new file mode 100644 index 0000000..b9e029a --- /dev/null +++ b/package/dist/utils/bridge-protocol.d.ts @@ -0,0 +1,37 @@ +/** + * Wire format shared between the Node-side `GodotRunner.sendCommand` and the + * GDScript-side `McpBridge` autoload. + * + * KEEP IN SYNC: src/scripts/mcp_bridge.gd implements the same framing on the + * Godot side. Any change here MUST be mirrored there (and vice versa). + * + * Frame: 4-byte big-endian length prefix + UTF-8 JSON payload. + * Max frame size is 16 MiB; oversize frames are rejected on receive. + */ +export declare const DEFAULT_BRIDGE_PORT = 9900; +export declare const MAX_FRAME_BYTES: number; +export declare const FRAME_HEADER_BYTES = 4; +/** + * Find an available TCP port by binding to port 0 (OS-assigned ephemeral port), + * reading the assigned port, and closing the listener. The brief TOCTOU window + * between close and the consumer's listen is acceptable — if a collision occurs, + * the bridge readiness check will surface the failure. + */ +export declare function findFreePort(): Promise; +/** + * Encode a JSON string as a length-prefixed frame. + */ +export declare function encodeFrame(payload: string): Buffer; +export interface ParseFramesResult { + frames: Buffer[]; + remainder: Buffer; +} +/** + * Pull as many complete frames as possible from a streaming buffer. Any + * partial frame at the tail is returned as `remainder` for the next call. + * + * Throws if a header advertises a payload larger than {@link MAX_FRAME_BYTES} — + * the caller should treat this as a fatal protocol error and close the socket. + */ +export declare function parseFrames(buffer: Buffer): ParseFramesResult; +//# sourceMappingURL=bridge-protocol.d.ts.map \ No newline at end of file diff --git a/package/dist/utils/bridge-protocol.d.ts.map b/package/dist/utils/bridge-protocol.d.ts.map new file mode 100644 index 0000000..8c40c8e --- /dev/null +++ b/package/dist/utils/bridge-protocol.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"bridge-protocol.d.ts","sourceRoot":"","sources":["../../src/utils/bridge-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,eAAe,QAAmB,CAAC;AAChD,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAkB9C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CASnD;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAoB7D"} \ No newline at end of file diff --git a/package/dist/utils/bridge-protocol.js b/package/dist/utils/bridge-protocol.js new file mode 100644 index 0000000..0085481 --- /dev/null +++ b/package/dist/utils/bridge-protocol.js @@ -0,0 +1,78 @@ +/** + * Wire format shared between the Node-side `GodotRunner.sendCommand` and the + * GDScript-side `McpBridge` autoload. + * + * KEEP IN SYNC: src/scripts/mcp_bridge.gd implements the same framing on the + * Godot side. Any change here MUST be mirrored there (and vice versa). + * + * Frame: 4-byte big-endian length prefix + UTF-8 JSON payload. + * Max frame size is 16 MiB; oversize frames are rejected on receive. + */ +import * as net from 'net'; +export const DEFAULT_BRIDGE_PORT = 9900; +export const MAX_FRAME_BYTES = 16 * 1024 * 1024; +export const FRAME_HEADER_BYTES = 4; +/** + * Find an available TCP port by binding to port 0 (OS-assigned ephemeral port), + * reading the assigned port, and closing the listener. The brief TOCTOU window + * between close and the consumer's listen is acceptable — if a collision occurs, + * the bridge readiness check will surface the failure. + */ +export function findFreePort() { + return new Promise((resolve, reject) => { + const srv = net.createServer(); + srv.listen(0, '127.0.0.1', () => { + const addr = srv.address(); + if (!addr || typeof addr === 'string') { + srv.close(); + reject(new Error('Failed to determine assigned port')); + return; + } + const port = addr.port; + srv.close(() => resolve(port)); + }); + // One-shot: only fires before listen() succeeds. If listen succeeded, + // we proceed to srv.close() in the listening callback — a later error + // is not possible from this server, so the listener stays safely dormant. + srv.on('error', reject); + }); +} +/** + * Encode a JSON string as a length-prefixed frame. + */ +export function encodeFrame(payload) { + const body = Buffer.from(payload, 'utf8'); + if (body.length > MAX_FRAME_BYTES) { + throw new Error(`Bridge frame too large: ${body.length} bytes (limit ${MAX_FRAME_BYTES})`); + } + const frame = Buffer.allocUnsafe(FRAME_HEADER_BYTES + body.length); + frame.writeUInt32BE(body.length, 0); + body.copy(frame, FRAME_HEADER_BYTES); + return frame; +} +/** + * Pull as many complete frames as possible from a streaming buffer. Any + * partial frame at the tail is returned as `remainder` for the next call. + * + * Throws if a header advertises a payload larger than {@link MAX_FRAME_BYTES} — + * the caller should treat this as a fatal protocol error and close the socket. + */ +export function parseFrames(buffer) { + const frames = []; + let offset = 0; + while (buffer.length - offset >= FRAME_HEADER_BYTES) { + const len = buffer.readUInt32BE(offset); + if (len > MAX_FRAME_BYTES) { + throw new Error(`Bridge frame header advertises ${len} bytes, exceeds limit ${MAX_FRAME_BYTES}`); + } + const frameStart = offset + FRAME_HEADER_BYTES; + const frameEnd = frameStart + len; + if (buffer.length < frameEnd) + break; + frames.push(buffer.subarray(frameStart, frameEnd)); + offset = frameEnd; + } + const remainder = offset === 0 ? buffer : buffer.subarray(offset); + return { frames, remainder }; +} +//# sourceMappingURL=bridge-protocol.js.map \ No newline at end of file diff --git a/package/dist/utils/bridge-protocol.js.map b/package/dist/utils/bridge-protocol.js.map new file mode 100644 index 0000000..3c7269f --- /dev/null +++ b/package/dist/utils/bridge-protocol.js.map @@ -0,0 +1 @@ +{"version":3,"file":"bridge-protocol.js","sourceRoot":"","sources":["../../src/utils/bridge-protocol.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/utils/godot-runner.d.ts b/package/dist/utils/godot-runner.d.ts new file mode 100644 index 0000000..1837b01 --- /dev/null +++ b/package/dist/utils/godot-runner.d.ts @@ -0,0 +1,248 @@ +import type { ChildProcess } from 'child_process'; +/** + * Thrown when the bridge socket closes (Godot exited, port closed, or peer + * dropped the connection mid-flight). Lets callers distinguish + * "session ended" from generic transport errors. + */ +export declare class BridgeDisconnectedError extends Error { + constructor(message: string); +} +export declare const BRIDGE_WAIT_SPAWNED_TIMEOUT_MS = 8000; +/** + * Normalize a path for cross-platform comparison. + * Folds Windows backslashes to forward slashes and strips trailing slashes, + * so Node's `path.normalize` output matches Godot's `globalize_path("res://")`. + */ +export declare function normalizeForCompare(p: string): string; +/** + * Extract JSON from Godot output by finding the first { or [ and matching to the end. + * This strips debug logs, version banners, and other noise. + */ +export declare function extractJson(output: string): string; +/** + * Strip Godot banner and debug lines from output, keeping only meaningful content. + */ +export declare function cleanOutput(output: string): string; +export declare function cleanStdout(stdout: string): string; +export interface GodotProcess { + process: ChildProcess; + output: string[]; + errors: string[]; + totalErrorsWritten: number; + exitCode: number | null; + hasExited: boolean; + sessionToken: string; +} +export type RuntimeSessionMode = 'spawned' | 'attached'; +export interface RuntimeStopResult { + mode: RuntimeSessionMode; + output: string[]; + errors: string[]; + externalProcessPreserved?: boolean; +} +export interface GodotServerConfig { + godotPath?: string; + debugMode?: boolean; +} +export interface OperationParams { + [key: string]: unknown; +} +export interface OperationResult { + stdout: string; + stderr: string; +} +export interface ToolAnnotations { + readOnlyHint?: boolean; + destructiveHint?: boolean; + idempotentHint?: boolean; + openWorldHint?: boolean; + title?: string; +} +export interface ToolDefinition { + name: string; + description: string; + inputSchema: { + type: string; + properties: Record; + required: string[]; + }; + outputSchema?: { + type: string; + properties?: Record; + required?: string[]; + }; + annotations?: ToolAnnotations; +} +export interface ToolResponse { + content: Array<{ + type: string; + text?: string; + [k: string]: unknown; + }>; + isError?: boolean; + structuredContent?: Record; + [k: string]: unknown; +} +export type ToolHandler = (runner: GodotRunner, args: OperationParams) => Promise | ToolResponse; +export declare function normalizeParameters(params: OperationParams): OperationParams; +export declare function convertCamelToSnakeCase(params: OperationParams): OperationParams; +/** + * Check whether a display server (X11 / Wayland) is available on the current + * platform. On macOS and Windows the display subsystem is always present; + * on Linux we probe the standard environment variables. + */ +export declare function checkDisplayAvailable(): boolean; +export declare function validatePath(path: string): boolean; +/** + * Stricter check for paths that must stay inside `projectPath`. Rejects `..` + * (via `validatePath`) and absolute paths that escape the project root. + * `path.join('/project', '/etc/passwd')` resolves to `/etc/passwd`, so the + * basic `..`-substring check alone permits absolute-path traversal. + * + * Tolerates a leading `res://` (Godot's project-root URI) by stripping it + * before resolving — autoload entries and resource paths use this prefix. + */ +export declare function validateSubPath(projectPath: string, userPath: string): boolean; +/** + * Validate a Godot scene-tree path (NodePath). Scene-tree paths are a + * separate namespace from filesystem paths — they address nodes inside + * a scene, not files on disk, so the project-root containment check + * in `validateSubPath` does not apply. + * + * Rejects empty strings and `..` segments. Accepts both relative + * (`root/Player`) and absolute (`/root/Player`) Godot forms; the + * codebase convention is the relative form. + */ +export declare function validateNodePath(path: string): boolean; +/** + * True when `child` resolves to `parent` or a path beneath it. Used by + * defense-in-depth checks on bridge-returned paths (e.g. screenshot files + * that must live under `.mcp/screenshots/`). + */ +export declare function isUnderDir(parent: string, child: string): boolean; +/** + * Return `error.message` when `error` is an `Error`, otherwise `'Unknown error'`. + * Centralizes the catch-block boilerplate so handlers can build error responses + * without repeating the `instanceof Error` ternary. + */ +export declare function getErrorMessage(error: unknown): string; +/** + * Build the absolute path to a project's `project.godot` manifest. Use this + * instead of `join(dir, 'project.godot')` ad hoc. + */ +export declare function projectGodotPath(projectDir: string): string; +/** + * Extract the first [ERROR] message from GDScript stderr output. + * Falls back to a generic message if no [ERROR] line is found. + */ +export declare function extractGdError(stderr: string): string; +export declare function createErrorResponse(message: string, possibleSolutions?: string[]): { + content: Array<{ + type: 'text'; + text: string; + }>; + isError: boolean; +}; +/** + * Wrap a structured payload as a ToolResponse that satisfies the MCP + * outputSchema contract. The same payload is emitted both as a JSON text + * content block (for lenient clients) and as `structuredContent` (required + * by strict clients per MCP spec revision 2025-06-18). + * + * `extraContent` is prepended for handlers that also return non-text blocks + * (e.g. `take_screenshot`'s inline image). + */ +export declare function createStructuredResponse>(payload: T, extraContent?: Array<{ + type: string; + [k: string]: unknown; +}>): ToolResponse; +interface ValidatedProjectArgs { + projectPath: string; +} +interface ValidatedSceneArgs { + projectPath: string; + scenePath: string; +} +type ValidationErrorResult = ReturnType; +export declare function validateProjectArgs(args: OperationParams): ValidatedProjectArgs | ValidationErrorResult; +export declare function validateSceneArgs(args: OperationParams, opts?: { + sceneRequired?: boolean; +}): ValidatedSceneArgs | ValidationErrorResult; +export declare class GodotRunner { + private godotPath; + private operationsScriptPath; + private bridge; + private validatedPaths; + private cachedVersion; + activeProcess: GodotProcess | null; + activeProjectPath: string | null; + activeSessionMode: RuntimeSessionMode | null; + activeBridgePort: number | null; + private socket; + private rxChunks; + private rxTotal; + private inFlight; + constructor(config?: GodotServerConfig); + private isValidGodotPathSync; + private spawnAsync; + private isValidGodotPath; + detectGodotPath(): Promise; + getGodotPath(): string | null; + /** + * Read the port currently baked into the project's bridge script. Returns + * null if the file is missing or malformed. Thin pass-through to + * BridgeManager — used by bridge-wait-timeout race detection. + */ + readBakedBridgePort(projectPath: string): number | null; + getVersion(): Promise; + executeOperation(operation: string, params: OperationParams, projectPath: string, timeoutMs?: number): Promise; + launchEditor(projectPath: string): ChildProcess; + runProject(projectPath: string, scene?: string, background?: boolean, bridgePort?: number): Promise; + attachProject(projectPath: string, bridgePort?: number): Promise; + stopProject(): Promise; + hasActiveRuntimeSession(): boolean; + /** + * Send a JSON command to the McpBridge over a long-lived TCP connection. + * + * MCP serializes tool calls so we hold one in-flight command at a time. The + * socket is lazy-connected on first call and persists across commands until + * `closeConnection` (or a peer-side close). A close mid-flight rejects with + * `BridgeDisconnectedError`; a per-command timeout rejects but does NOT + * close the socket — a slow command does not invalidate the session. + */ + sendCommand(command: string, params?: Record, timeoutMs?: number): Promise; + /** + * Tear down the bridge socket. Idempotent. Any in-flight command is + * rejected with a session-ended error. + */ + closeConnection(): void; + private resetRxBuffer; + getErrorCount(): number; + getErrorsSince(marker: number): string[]; + private static readonly SCRIPT_ERROR_PATTERNS; + private static readonly RETRYABLE_BRIDGE_COMMANDS; + extractRuntimeErrors(lines: string[]): string[]; + private sendCommandWithReconnect; + sendCommandWithErrors(command: string, params?: Record, timeoutMs?: number): Promise<{ + response: string; + runtimeErrors: string[]; + }>; + /** + * Shared poll loop for `waitForBridge` (spawned) and `waitForBridgeAttached`. + * Sends `ping` payloads until the bridge replies with a pong that + * `validatePong` accepts, the deadline passes, or `shouldAbort` reports + * the spawned process has exited. + */ + private pollBridge; + waitForBridgeAttached(timeoutMs?: number, intervalMs?: number): Promise<{ + ready: boolean; + error?: string; + }>; + waitForBridge(timeoutMs?: number, intervalMs?: number): Promise<{ + ready: boolean; + error?: string; + }>; + getRecentErrors(count?: number): string[]; +} +export {}; +//# sourceMappingURL=godot-runner.d.ts.map \ No newline at end of file diff --git a/package/dist/utils/godot-runner.d.ts.map b/package/dist/utils/godot-runner.d.ts.map new file mode 100644 index 0000000..079b595 --- /dev/null +++ b/package/dist/utils/godot-runner.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"godot-runner.d.ts","sourceRoot":"","sources":["../../src/utils/godot-runner.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/utils/godot-runner.js b/package/dist/utils/godot-runner.js new file mode 100644 index 0000000..797eeda --- /dev/null +++ b/package/dist/utils/godot-runner.js @@ -0,0 +1,1119 @@ +import { fileURLToPath } from 'url'; +import { join, dirname, normalize, resolve, sep } from 'path'; +import { existsSync } from 'fs'; +import { spawn } from 'child_process'; +import * as net from 'net'; +import { randomBytes } from 'crypto'; +import { BridgeManager } from './bridge-manager.js'; +import { DEFAULT_BRIDGE_PORT, encodeFrame, findFreePort, parseFrames, FRAME_HEADER_BYTES, MAX_FRAME_BYTES, } from './bridge-protocol.js'; +import { logDebug, logError, DEBUG_MODE } from './logger.js'; +/** + * Thrown when the bridge socket closes (Godot exited, port closed, or peer + * dropped the connection mid-flight). Lets callers distinguish + * "session ended" from generic transport errors. + */ +export class BridgeDisconnectedError extends Error { + constructor(message) { + super(message); + this.name = 'BridgeDisconnectedError'; + } +} +// Derive __filename and __dirname in ESM +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +// Bridge readiness polling +export const BRIDGE_WAIT_SPAWNED_TIMEOUT_MS = 8000; +const BRIDGE_WAIT_SPAWNED_INTERVAL_MS = 300; +const BRIDGE_WAIT_ATTACHED_TIMEOUT_MS = 15000; +const BRIDGE_WAIT_ATTACHED_INTERVAL_MS = 500; +const BRIDGE_PING_TIMEOUT_MS = 1000; +const BRIDGE_SHUTDOWN_SPAWNED_TIMEOUT_MS = 500; +const BRIDGE_SHUTDOWN_ATTACHED_TIMEOUT_MS = 1500; +const BRIDGE_PROCESS_EXIT_TIMEOUT_MS = 2000; +const BRIDGE_RECONNECT_DELAY_MS = 1000; +/** + * Normalize a path for cross-platform comparison. + * Folds Windows backslashes to forward slashes and strips trailing slashes, + * so Node's `path.normalize` output matches Godot's `globalize_path("res://")`. + */ +export function normalizeForCompare(p) { + return normalize(p).replace(/\\/g, '/').replace(/\/+$/, ''); +} +/** + * Extract JSON from Godot output by finding the first { or [ and matching to the end. + * This strips debug logs, version banners, and other noise. + */ +export function extractJson(output) { + // Find the first occurrence of { or [ + const jsonStartBrace = output.indexOf('{'); + const jsonStartBracket = output.indexOf('['); + let jsonStart = -1; + if (jsonStartBrace === -1 && jsonStartBracket === -1) { + return output; // No JSON found, return as-is + } + else if (jsonStartBrace === -1) { + jsonStart = jsonStartBracket; + } + else if (jsonStartBracket === -1) { + jsonStart = jsonStartBrace; + } + else { + jsonStart = Math.min(jsonStartBrace, jsonStartBracket); + } + // Extract from JSON start to end + const jsonPart = output.substring(jsonStart); + // Try to parse to validate, if it fails return original + try { + JSON.parse(jsonPart.trim()); + return jsonPart.trim(); + } + catch { + // If the extracted part isn't valid JSON, try to find the last } or ] + const lastBrace = jsonPart.lastIndexOf('}'); + const lastBracket = jsonPart.lastIndexOf(']'); + const lastEnd = Math.max(lastBrace, lastBracket); + if (lastEnd > 0) { + const extracted = jsonPart.substring(0, lastEnd + 1); + try { + JSON.parse(extracted); + return extracted; + } + catch { + return output; // Return original if still can't parse + } + } + return output; + } +} +/** + * Strip Godot banner and debug lines from output, keeping only meaningful content. + */ +export function cleanOutput(output) { + const lines = output.split('\n'); + const cleanedLines = lines.filter((line) => { + const trimmed = line.trim(); + // Skip empty lines + if (!trimmed) + return false; + // Skip Godot version banner + if (trimmed.startsWith('Godot Engine v')) + return false; + // Skip debug lines + if (trimmed.startsWith('[DEBUG]')) + return false; + // Skip info lines that are just status updates + if (trimmed.startsWith('[INFO] Operation:')) + return false; + if (trimmed.startsWith('[INFO] Executing operation:')) + return false; + return true; + }); + return cleanedLines.join('\n'); +} +export function cleanStdout(stdout) { + if (stdout.includes('{') || stdout.includes('[')) { + return extractJson(stdout); + } + return cleanOutput(stdout); +} +// Parameter mappings between snake_case and camelCase +// Add new entries whenever a tool surfaces a new compound parameter — the +// strict converter throws in test env on unmapped keys to catch oversights. +const parameterMappings = { + project_path: 'projectPath', + scene_path: 'scenePath', + root_node_type: 'rootNodeType', + parent_node_path: 'parentNodePath', + parent_path: 'parentPath', + node_type: 'nodeType', + node_name: 'nodeName', + texture_path: 'texturePath', + node_path: 'nodePath', + node_paths: 'nodePaths', + target_node_path: 'targetNodePath', + target_parent_path: 'targetParentPath', + new_name: 'newName', + output_path: 'outputPath', + mesh_item_names: 'meshItemNames', + new_path: 'newPath', + file_path: 'filePath', + script_path: 'scriptPath', + response_mode: 'responseMode', + preview_max_width: 'previewMaxWidth', + preview_max_height: 'previewMaxHeight', + bridge_port: 'bridgePort', + abort_on_error: 'abortOnError', + max_depth: 'maxDepth', + changed_only: 'changedOnly', + case_sensitive: 'caseSensitive', + file_types: 'fileTypes', + max_results: 'maxResults', +}; +// Reverse mapping from camelCase to snake_case +const reverseParameterMappings = {}; +for (const [snakeCase, camelCase] of Object.entries(parameterMappings)) { + reverseParameterMappings[camelCase] = snakeCase; +} +export function normalizeParameters(params) { + if (!params || typeof params !== 'object') { + return params; + } + const result = {}; + for (const key in params) { + if (Object.prototype.hasOwnProperty.call(params, key)) { + let normalizedKey = key; + if (key.includes('_') && parameterMappings[key]) { + normalizedKey = parameterMappings[key]; + } + const value = params[key]; + if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + result[normalizedKey] = normalizeParameters(value); + } + else { + result[normalizedKey] = value; + } + } + } + return result; +} +function convertCamelToSnakeValue(value) { + if (Array.isArray(value)) { + return value.map((entry) => convertCamelToSnakeValue(entry)); + } + if (typeof value === 'object' && value !== null) { + return convertCamelToSnakeCase(value); + } + return value; +} +export function convertCamelToSnakeCase(params) { + const result = {}; + const isTestEnv = process.env.NODE_ENV === 'test' || process.env.VITEST === 'true'; + for (const key in params) { + if (Object.prototype.hasOwnProperty.call(params, key)) { + const mapped = reverseParameterMappings[key]; + let snakeKey; + if (mapped) { + snakeKey = mapped; + } + else if (/[A-Z]/.test(key)) { + // Unmapped camelCase key — tolerated in production via regex fallback, + // but in tests we throw to catch missing entries in parameterMappings. + if (isTestEnv) { + throw new Error(`convertCamelToSnakeCase: unmapped camelCase key '${key}'. ` + + `Add it to parameterMappings in src/utils/godot-runner.ts so snake/camel conversion stays explicit.`); + } + snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`); + } + else { + snakeKey = key; + } + result[snakeKey] = convertCamelToSnakeValue(params[key]); + } + } + return result; +} +/** + * Check whether a display server (X11 / Wayland) is available on the current + * platform. On macOS and Windows the display subsystem is always present; + * on Linux we probe the standard environment variables. + */ +export function checkDisplayAvailable() { + if (process.platform !== 'linux') + return true; + return !!(process.env.DISPLAY || process.env.WAYLAND_DISPLAY); +} +export function validatePath(path) { + if (!path || path.includes('..')) { + return false; + } + return true; +} +/** + * Stricter check for paths that must stay inside `projectPath`. Rejects `..` + * (via `validatePath`) and absolute paths that escape the project root. + * `path.join('/project', '/etc/passwd')` resolves to `/etc/passwd`, so the + * basic `..`-substring check alone permits absolute-path traversal. + * + * Tolerates a leading `res://` (Godot's project-root URI) by stripping it + * before resolving — autoload entries and resource paths use this prefix. + */ +export function validateSubPath(projectPath, userPath) { + if (!validatePath(userPath)) + return false; + const stripped = userPath.startsWith('res://') ? userPath.slice('res://'.length) : userPath; + if (!stripped) + return false; + const projectRoot = resolve(projectPath); + const resolved = resolve(projectRoot, stripped); + const tail = projectRoot === sep ? sep : projectRoot + sep; + return resolved === projectRoot || resolved.startsWith(tail); +} +/** + * Validate a Godot scene-tree path (NodePath). Scene-tree paths are a + * separate namespace from filesystem paths — they address nodes inside + * a scene, not files on disk, so the project-root containment check + * in `validateSubPath` does not apply. + * + * Rejects empty strings and `..` segments. Accepts both relative + * (`root/Player`) and absolute (`/root/Player`) Godot forms; the + * codebase convention is the relative form. + */ +export function validateNodePath(path) { + return typeof path === 'string' && path.length > 0 && !path.includes('..'); +} +/** + * True when `child` resolves to `parent` or a path beneath it. Used by + * defense-in-depth checks on bridge-returned paths (e.g. screenshot files + * that must live under `.mcp/screenshots/`). + */ +export function isUnderDir(parent, child) { + const parentResolved = resolve(parent); + const childResolved = resolve(child); + return childResolved === parentResolved || childResolved.startsWith(parentResolved + sep); +} +/** + * Return `error.message` when `error` is an `Error`, otherwise `'Unknown error'`. + * Centralizes the catch-block boilerplate so handlers can build error responses + * without repeating the `instanceof Error` ternary. + */ +export function getErrorMessage(error) { + return error instanceof Error ? error.message : 'Unknown error'; +} +/** + * Build the absolute path to a project's `project.godot` manifest. Use this + * instead of `join(dir, 'project.godot')` ad hoc. + */ +export function projectGodotPath(projectDir) { + return join(projectDir, 'project.godot'); +} +/** + * Extract the first [ERROR] message from GDScript stderr output. + * Falls back to a generic message if no [ERROR] line is found. + */ +export function extractGdError(stderr) { + const errLine = stderr.split('\n').find((l) => l.includes('[ERROR]')); + return errLine + ? errLine.replace(/.*\[ERROR\]\s*/, '').trim() + : 'see get_debug_output for details'; +} +export function createErrorResponse(message, possibleSolutions = []) { + logError(`Error response: ${message}`); + if (possibleSolutions.length > 0) { + logError(`Possible solutions: ${possibleSolutions.join(', ')}`); + } + const response = { + content: [{ type: 'text', text: message }], + isError: true, + }; + if (possibleSolutions.length > 0) { + response.content.push({ + type: 'text', + text: 'Possible solutions:\n- ' + possibleSolutions.join('\n- '), + }); + } + return response; +} +/** + * Wrap a structured payload as a ToolResponse that satisfies the MCP + * outputSchema contract. The same payload is emitted both as a JSON text + * content block (for lenient clients) and as `structuredContent` (required + * by strict clients per MCP spec revision 2025-06-18). + * + * `extraContent` is prepended for handlers that also return non-text blocks + * (e.g. `take_screenshot`'s inline image). + */ +export function createStructuredResponse(payload, extraContent = []) { + return { + content: [...extraContent, { type: 'text', text: JSON.stringify(payload) }], + structuredContent: payload, + }; +} +export function validateProjectArgs(args) { + if (!args.projectPath) { + return createErrorResponse('projectPath is required', [ + 'Provide a valid path to a Godot project directory', + ]); + } + if (!validatePath(args.projectPath)) { + return createErrorResponse('Invalid project path', [ + 'Provide a valid path without ".." or other potentially unsafe characters', + ]); + } + const projectFile = projectGodotPath(args.projectPath); + if (!existsSync(projectFile)) { + return createErrorResponse(`Not a valid Godot project: ${args.projectPath}`, [ + 'Ensure the path points to a directory containing a project.godot file', + ]); + } + return { projectPath: args.projectPath }; +} +export function validateSceneArgs(args, opts) { + const projectResult = validateProjectArgs(args); + if ('isError' in projectResult) + return projectResult; + const sceneRequired = opts?.sceneRequired !== false; + if (!args.scenePath) { + if (sceneRequired) { + return createErrorResponse('scenePath is required', [ + 'Provide the scene file path relative to the project', + ]); + } + return { projectPath: projectResult.projectPath, scenePath: '' }; + } + if (!validateSubPath(projectResult.projectPath, args.scenePath)) { + return createErrorResponse('Invalid scene path', [ + 'Provide a valid relative path without ".." that stays inside the project directory', + ]); + } + if (sceneRequired) { + const sceneFullPath = join(projectResult.projectPath, args.scenePath); + if (!existsSync(sceneFullPath)) { + return createErrorResponse(`Scene file does not exist: ${args.scenePath}`, [ + 'Ensure the scene path is correct', + 'Use create_scene to create a new scene first', + ]); + } + } + return { projectPath: projectResult.projectPath, scenePath: args.scenePath }; +} +/** + * Read the first `n` bytes from a chunk array without concatenating the + * entire array. If the first chunk already has enough bytes, returns a + * zero-copy subarray; otherwise copies just `n` bytes into a fresh buffer. + * Caller must ensure total length across chunks is >= n. + */ +function readBytesFromChunks(chunks, n) { + if (chunks[0].length >= n) + return chunks[0].subarray(0, n); + const result = Buffer.allocUnsafe(n); + let copied = 0; + for (const c of chunks) { + const take = Math.min(c.length, n - copied); + c.copy(result, copied, 0, take); + copied += take; + if (copied >= n) + break; + } + return result; +} +export class GodotRunner { + godotPath = null; + operationsScriptPath; + bridge; + validatedPaths = new Map(); + cachedVersion = null; + activeProcess = null; + activeProjectPath = null; + activeSessionMode = null; + activeBridgePort = null; + socket = null; + // Receive buffer kept as an array of chunks until at least one complete frame + // is available. Avoids re-copying accumulated bytes on every TCP data event + // (the old `Buffer.concat([rxBuffer, chunk])` pattern was O(n²) on large + // frames split across many chunks). + rxChunks = []; + rxTotal = 0; + inFlight = null; + constructor(config) { + this.operationsScriptPath = join(__dirname, '..', 'scripts', 'godot_operations.gd'); + const bridgeScriptPath = join(__dirname, '..', 'scripts', 'mcp_bridge.gd'); + this.bridge = new BridgeManager(bridgeScriptPath); + logDebug(`Operations script path: ${this.operationsScriptPath}`); + if (config?.godotPath) { + const normalizedPath = normalize(config.godotPath); + if (this.isValidGodotPathSync(normalizedPath)) { + this.godotPath = normalizedPath; + logDebug(`Custom Godot path provided: ${this.godotPath}`); + } + else { + console.warn(`[SERVER] Invalid custom Godot path provided: ${normalizedPath}`); + } + } + } + isValidGodotPathSync(path) { + try { + logDebug(`Quick-validating Godot path: ${path}`); + return path === 'godot' || existsSync(path); + } + catch { + logDebug(`Invalid Godot path: ${path}`); + return false; + } + } + spawnAsync(cmd, args, timeoutMs = 10000) { + return new Promise((resolve, reject) => { + const proc = spawn(cmd, args, { stdio: 'pipe' }); + let stdout = ''; + let stderr = ''; + const timer = setTimeout(() => { + proc.kill(); + reject(new Error(`Process timed out after ${timeoutMs}ms`)); + }, timeoutMs); + proc.stdout?.on('data', (data) => { + stdout += data.toString(); + }); + proc.stderr?.on('data', (data) => { + stderr += data.toString(); + }); + proc.on('error', (err) => { + clearTimeout(timer); + reject(err); + }); + proc.on('close', (code) => { + clearTimeout(timer); + if (code === 0) { + resolve({ stdout, stderr }); + } + else { + const err = new Error(`Process exited with code ${code}`); + err.stdout = stdout; + err.stderr = stderr; + err.code = code; + reject(err); + } + }); + }); + } + async isValidGodotPath(path) { + if (this.validatedPaths.has(path)) { + return this.validatedPaths.get(path); + } + try { + logDebug(`Validating Godot path: ${path}`); + if (path !== 'godot' && !existsSync(path)) { + logDebug(`Path does not exist: ${path}`); + this.validatedPaths.set(path, false); + return false; + } + await this.spawnAsync(path, ['--version']); + logDebug(`Valid Godot path: ${path}`); + this.validatedPaths.set(path, true); + return true; + } + catch { + logDebug(`Invalid Godot path: ${path}`); + this.validatedPaths.set(path, false); + return false; + } + } + async detectGodotPath() { + // Explicit paths (constructor config or GODOT_PATH) are authoritative — leave + // godotPath null on failure rather than fabricating a platform default, so + // callers can produce actionable errors. + if (this.godotPath) { + if (await this.isValidGodotPath(this.godotPath)) { + logDebug(`Using existing Godot path: ${this.godotPath}`); + return; + } + logError(`Configured Godot path "${this.godotPath}" is not a working Godot executable. ` + + `Pass a valid Godot 4.x binary via the godotPath config option.`); + this.godotPath = null; + return; + } + if (process.env.GODOT_PATH) { + const normalizedPath = normalize(process.env.GODOT_PATH); + logDebug(`Checking GODOT_PATH environment variable: ${normalizedPath}`); + if (await this.isValidGodotPath(normalizedPath)) { + this.godotPath = normalizedPath; + logDebug(`Using Godot path from environment: ${this.godotPath}`); + return; + } + logError(`GODOT_PATH is set to "${normalizedPath}" but no working Godot executable was found there. ` + + `Update GODOT_PATH to your Godot 4.x binary or unset it to auto-detect.`); + return; + } + const osPlatform = process.platform; + logDebug(`Auto-detecting Godot path for platform: ${osPlatform}`); + const possiblePaths = ['godot']; + if (osPlatform === 'darwin') { + possiblePaths.push('/Applications/Godot.app/Contents/MacOS/Godot', '/Applications/Godot_4.app/Contents/MacOS/Godot', `${process.env.HOME}/Applications/Godot.app/Contents/MacOS/Godot`); + } + else if (osPlatform === 'win32') { + possiblePaths.push('C:\\Program Files\\Godot\\Godot.exe', 'C:\\Program Files (x86)\\Godot\\Godot.exe', `${process.env.USERPROFILE}\\Godot\\Godot.exe`); + } + else if (osPlatform === 'linux') { + possiblePaths.push('/usr/bin/godot', '/usr/local/bin/godot', '/snap/bin/godot', `${process.env.HOME}/.local/bin/godot`); + } + const normalizedCandidates = possiblePaths.map((p) => normalize(p)); + const probeResults = await Promise.all(normalizedCandidates.map(async (p) => ({ path: p, valid: await this.isValidGodotPath(p) }))); + const winner = probeResults.find((r) => r.valid); + if (winner) { + this.godotPath = winner.path; + logDebug(`Found Godot at: ${winner.path}`); + return; + } + logError(`Could not find Godot in common locations for ${osPlatform}. ` + + `Set GODOT_PATH to your Godot 4.x executable.`); + } + getGodotPath() { + return this.godotPath; + } + /** + * Read the port currently baked into the project's bridge script. Returns + * null if the file is missing or malformed. Thin pass-through to + * BridgeManager — used by bridge-wait-timeout race detection. + */ + readBakedBridgePort(projectPath) { + return this.bridge.readBakedPort(projectPath); + } + async getVersion() { + if (this.cachedVersion !== null) { + return this.cachedVersion; + } + if (!this.godotPath) { + await this.detectGodotPath(); + if (!this.godotPath) { + throw new Error('Could not find a valid Godot executable path'); + } + } + const { stdout } = await this.spawnAsync(this.godotPath, ['--version']); + this.cachedVersion = stdout.trim(); + return this.cachedVersion; + } + async executeOperation(operation, params, projectPath, timeoutMs = 30000) { + logDebug(`Executing operation: ${operation} in project: ${projectPath}`); + logDebug(`Original operation params: ${JSON.stringify(params)}`); + this.bridge.repairOrphaned(projectPath); + const snakeCaseParams = convertCamelToSnakeCase(params); + logDebug(`Converted snake_case params: ${JSON.stringify(snakeCaseParams)}`); + if (!this.godotPath) { + await this.detectGodotPath(); + if (!this.godotPath) { + throw new Error('Could not find a valid Godot executable path'); + } + } + const paramsJson = JSON.stringify(snakeCaseParams); + const args = [ + '--headless', + '--path', + projectPath, + '--script', + this.operationsScriptPath, + operation, + paramsJson, + ...(DEBUG_MODE ? ['--debug-godot'] : []), + ]; + logDebug(`Command: ${this.godotPath} ${args.join(' ')}`); + let stdout = ''; + let stderr = ''; + try { + ({ stdout, stderr } = await this.spawnAsync(this.godotPath, args, timeoutMs)); + } + catch (error) { + if (error instanceof Error && 'stdout' in error && 'stderr' in error) { + const execError = error; + stdout = execError.stdout; + stderr = execError.stderr; + } + else { + throw error; + } + } + // If the process produced no operation output but has errors, initialization + // failed before the script ran. Autoload errors are the most common cause. + const operationRan = stdout.trim().length > 0 || stderr.includes('[INFO] Operation:'); + if (!operationRan && (stderr.includes('ERROR:') || stderr.includes('SCRIPT ERROR:'))) { + throw new Error(`Headless Godot failed before the operation could run — likely an autoload initialization error.\n` + + `Stderr:\n${stderr.trim()}\n\n` + + `Use list_autoloads and remove_autoload to inspect or remove the failing autoload, then retry.`); + } + return { stdout: cleanStdout(stdout), stderr }; + } + launchEditor(projectPath) { + if (!this.godotPath) { + throw new Error('No Godot executable resolved. Set GODOT_PATH to a Godot 4.x binary, or pass godotPath via config.'); + } + return spawn(this.godotPath, ['-e', '--path', projectPath], { stdio: 'pipe' }); + } + async runProject(projectPath, scene, background = false, bridgePort) { + if (!this.godotPath) { + throw new Error('No Godot executable resolved. Set GODOT_PATH to a Godot 4.x binary, or pass godotPath via config.'); + } + if (this.activeSessionMode === 'spawned' && this.activeProcess) { + logDebug('Killing existing Godot process before starting a new one'); + this.closeConnection(); + this.activeProcess.process.kill(); + if (this.activeProjectPath && this.activeProjectPath !== projectPath) { + this.bridge.cleanup(this.activeProjectPath); + } + } + else if (this.activeSessionMode === 'attached' && + this.activeProjectPath && + this.activeProjectPath !== projectPath) { + this.closeConnection(); + this.bridge.cleanup(this.activeProjectPath); + } + if (!checkDisplayAvailable()) { + throw new Error('No display server available (DISPLAY and WAYLAND_DISPLAY are both unset). ' + + 'Godot requires a display to run a project window.'); + } + const port = bridgePort ?? (await findFreePort()); + this.activeBridgePort = port; + try { + this.bridge.inject(projectPath, port); + } + catch (err) { + logDebug(`Non-fatal: Failed to inject bridge autoload: ${err}`); + } + this.activeProjectPath = projectPath; + this.activeSessionMode = 'spawned'; + const cmdArgs = ['--path', projectPath]; + if (scene && validateSubPath(projectPath, scene)) { + logDebug(`Adding scene parameter: ${scene}`); + cmdArgs.push(scene); + } + const portSource = bridgePort !== undefined ? 'explicit' : 'auto'; + logDebug(`Running Godot project: ${projectPath} (bridge port ${port}, ${portSource})`); + const sessionToken = randomBytes(16).toString('hex'); + const spawnOptions = { + stdio: 'pipe', + env: { + ...process.env, + MCP_SESSION_TOKEN: sessionToken, + }, + }; + if (background) { + spawnOptions.env = { ...spawnOptions.env, MCP_BACKGROUND: '1' }; + } + const proc = spawn(this.godotPath, cmdArgs, spawnOptions); + const output = []; + const errors = []; + const godotProcess = { + process: proc, + output, + errors, + totalErrorsWritten: 0, + exitCode: null, + hasExited: false, + sessionToken, + }; + proc.stdout?.on('data', (data) => { + const lines = data.toString().split('\n'); + output.push(...lines); + if (output.length > 500) + output.splice(0, output.length - 500); + lines.forEach((line) => { + if (line.trim()) + logDebug(`[Godot stdout] ${line}`); + }); + }); + proc.stderr?.on('data', (data) => { + const lines = data.toString().split('\n'); + godotProcess.totalErrorsWritten += lines.length; + errors.push(...lines); + if (errors.length > 500) + errors.splice(0, errors.length - 500); + lines.forEach((line) => { + if (line.trim()) + logDebug(`[Godot stderr] ${line}`); + }); + }); + proc.on('exit', (code) => { + logDebug(`Godot process exited with code ${code}`); + godotProcess.exitCode = code; + godotProcess.hasExited = true; + // Don't clear activeProcess immediately - keep it so output can be retrieved + }); + proc.on('error', (err) => { + console.error('Failed to start Godot process:', err); + errors.push(`Process error: ${err.message}`); + godotProcess.hasExited = true; + }); + this.activeProcess = godotProcess; + return this.activeProcess; + } + async attachProject(projectPath, bridgePort) { + if (this.activeSessionMode === 'spawned' && this.activeProcess) { + await this.stopProject(); + } + else if (this.activeSessionMode === 'attached' && + this.activeProjectPath && + this.activeProjectPath !== projectPath) { + // Different project — detach the old one cleanly so its bridge + // releases the port before we inject into the new project. + try { + await this.sendCommand('shutdown', {}, BRIDGE_SHUTDOWN_ATTACHED_TIMEOUT_MS); + } + catch (err) { + logDebug(`Shutdown command failed during attach swap (ignored): ${err}`); + } + this.closeConnection(); + this.bridge.cleanup(this.activeProjectPath); + this.activeProjectPath = null; + this.activeSessionMode = null; + } + const port = bridgePort ?? (await findFreePort()); + this.activeBridgePort = port; + this.bridge.inject(projectPath, port); + const portSource = bridgePort !== undefined ? 'explicit' : 'auto'; + logDebug(`Attaching to Godot project: ${projectPath} (bridge port ${port}, ${portSource})`); + this.activeProjectPath = projectPath; + this.activeSessionMode = 'attached'; + this.activeProcess = null; + } + async stopProject() { + if (!this.activeSessionMode) { + return null; + } + if (this.activeSessionMode === 'attached') { + // Ask the bridge to shut down so the user's still-running Godot + // releases the port. A timeout here is non-fatal — same end state + // as today, the bridge dies when the user closes Godot. + try { + await this.sendCommand('shutdown', {}, BRIDGE_SHUTDOWN_ATTACHED_TIMEOUT_MS); + } + catch (err) { + logDebug(`Attached shutdown timed out or failed (continuing cleanup): ${err}`); + } + this.closeConnection(); + const projectPath = this.activeProjectPath; + if (projectPath) { + this.bridge.cleanup(projectPath); + } + this.activeProjectPath = null; + this.activeSessionMode = null; + this.activeBridgePort = null; + this.activeProcess = null; + return { + mode: 'attached', + output: [], + errors: [], + externalProcessPreserved: true, + }; + } + if (!this.activeProcess) { + return null; + } + // Spawned: try graceful shutdown so the bridge releases the port, + // then ensure the process actually exits. + try { + await this.sendCommand('shutdown', {}, BRIDGE_SHUTDOWN_SPAWNED_TIMEOUT_MS); + } + catch { + // Bridge may already be unreachable — proceed to kill. + } + this.closeConnection(); + logDebug('Stopping active Godot process'); + const proc = this.activeProcess.process; + proc.kill(); + // Wait up to BRIDGE_PROCESS_EXIT_TIMEOUT_MS for graceful exit; otherwise SIGKILL. + if (!this.activeProcess.hasExited) { + await new Promise((resolve) => { + const timer = setTimeout(() => { + try { + proc.kill('SIGKILL'); + } + catch { + // already dead + } + resolve(); + }, BRIDGE_PROCESS_EXIT_TIMEOUT_MS); + proc.once('exit', () => { + clearTimeout(timer); + resolve(); + }); + }); + } + const result = { + mode: 'spawned', + output: this.activeProcess.output, + errors: this.activeProcess.errors, + }; + this.activeProcess = null; + if (this.activeProjectPath) { + this.bridge.cleanup(this.activeProjectPath); + this.activeProjectPath = null; + } + this.activeSessionMode = null; + this.activeBridgePort = null; + return result; + } + hasActiveRuntimeSession() { + if (!this.activeSessionMode || !this.activeProjectPath) { + return false; + } + if (this.activeSessionMode === 'spawned') { + return this.activeProcess !== null && !this.activeProcess.hasExited; + } + return true; + } + /** + * Send a JSON command to the McpBridge over a long-lived TCP connection. + * + * MCP serializes tool calls so we hold one in-flight command at a time. The + * socket is lazy-connected on first call and persists across commands until + * `closeConnection` (or a peer-side close). A close mid-flight rejects with + * `BridgeDisconnectedError`; a per-command timeout rejects but does NOT + * close the socket — a slow command does not invalidate the session. + */ + sendCommand(command, params = {}, timeoutMs = 10000) { + return new Promise((resolve, reject) => { + if (this.inFlight) { + reject(new Error(`Command '${command}' rejected: another command ('${this.inFlight.command}') is in flight`)); + return; + } + const settle = (err, value) => { + if (!this.inFlight) + return; + const flight = this.inFlight; + this.inFlight = null; + clearTimeout(flight.timer); + if (err) { + flight.reject(err); + } + else { + flight.resolve(value ?? ''); + } + }; + const timer = setTimeout(() => { + // Destroy the socket on timeout. The bridge serializes commands + // (peer.handling gate), so a slow command's late response would + // otherwise correlate against the next command we send. The next + // sendCommand lazy-reconnects. + if (this.socket) { + const sock = this.socket; + this.socket = null; + sock.removeAllListeners(); + sock.destroy(); + } + this.resetRxBuffer(); + settle(new Error(`Command '${command}' timed out after ${timeoutMs}ms. Is the game running?`)); + }, timeoutMs); + this.inFlight = { command, resolve, reject, timer }; + const ensureSocket = (cb) => { + if (this.socket) { + cb(); + return; + } + // Fallback to DEFAULT_BRIDGE_PORT is defensive — every entry point + // (runProject, attachProject) sets activeBridgePort before sendCommand + // can be reached, so this branch is not expected in practice. + const port = this.activeBridgePort ?? DEFAULT_BRIDGE_PORT; + const sock = net.connect(port, '127.0.0.1'); + const onConnect = () => { + sock.setNoDelay(true); + sock.removeListener('error', onConnectError); + this.socket = sock; + this.resetRxBuffer(); + sock.on('data', (chunk) => { + this.rxChunks.push(chunk); + this.rxTotal += chunk.length; + // Defer the (potentially expensive) concat until we know at least + // one complete frame is ready. Peek the 4-byte header without + // copying all accumulated chunks first. + if (this.rxTotal < FRAME_HEADER_BYTES) + return; + const header = readBytesFromChunks(this.rxChunks, FRAME_HEADER_BYTES); + const firstLen = header.readUInt32BE(0); + if (firstLen > MAX_FRAME_BYTES) { + this.socket = null; + sock.destroy(); + settle(new BridgeDisconnectedError(`Bridge frame header advertises ${firstLen} bytes, exceeds limit ${MAX_FRAME_BYTES}`)); + return; + } + if (this.rxTotal < FRAME_HEADER_BYTES + firstLen) + return; + try { + const buffer = this.rxChunks.length === 1 + ? this.rxChunks[0] + : Buffer.concat(this.rxChunks, this.rxTotal); + const { frames, remainder } = parseFrames(buffer); + if (remainder.length === 0) { + this.rxChunks = []; + this.rxTotal = 0; + } + else { + this.rxChunks = [remainder]; + this.rxTotal = remainder.length; + } + for (const frame of frames) { + settle(null, frame.toString('utf8')); + } + } + catch (parseErr) { + const message = parseErr instanceof Error ? parseErr.message : String(parseErr); + this.socket = null; + sock.destroy(); + settle(new BridgeDisconnectedError(`Bridge framing error: ${message}`)); + } + }); + const onClose = () => { + this.socket = null; + settle(new BridgeDisconnectedError(`Bridge connection closed before '${command}' response was received`)); + }; + sock.once('close', onClose); + sock.on('error', (sockErr) => { + this.socket = null; + settle(new BridgeDisconnectedError(`Bridge socket error during '${command}': ${sockErr.message}`)); + }); + cb(); + }; + const onConnectError = (connErr) => { + sock.destroy(); + cb(connErr); + }; + sock.once('connect', onConnect); + sock.once('error', onConnectError); + }; + ensureSocket((err) => { + if (err) { + settle(new BridgeDisconnectedError(`Failed to connect to bridge for '${command}': ${err.message}`)); + return; + } + if (!this.socket) { + settle(new BridgeDisconnectedError(`Bridge socket unavailable for '${command}'`)); + return; + } + try { + const payload = JSON.stringify({ command, ...params }); + this.socket.write(encodeFrame(payload)); + } + catch (writeErr) { + const message = writeErr instanceof Error ? writeErr.message : String(writeErr); + settle(new Error(`Failed to send command '${command}': ${message}`)); + } + }); + }); + } + /** + * Tear down the bridge socket. Idempotent. Any in-flight command is + * rejected with a session-ended error. + */ + closeConnection() { + if (this.inFlight) { + const flight = this.inFlight; + this.inFlight = null; + clearTimeout(flight.timer); + flight.reject(new BridgeDisconnectedError('Bridge session ended')); + } + if (this.socket) { + const sock = this.socket; + this.socket = null; + sock.removeAllListeners(); + sock.destroy(); + } + this.resetRxBuffer(); + } + resetRxBuffer() { + this.rxChunks = []; + this.rxTotal = 0; + } + getErrorCount() { + return this.activeProcess?.totalErrorsWritten ?? 0; + } + getErrorsSince(marker) { + if (!this.activeProcess) + return []; + const { errors, totalErrorsWritten } = this.activeProcess; + const delta = totalErrorsWritten - marker; + if (delta <= 0) + return []; + const window = delta >= errors.length ? errors.slice() : errors.slice(errors.length - delta); + return window.filter((line) => line.trim() !== ''); + } + // Only the explicit `SCRIPT ERROR:` / `USER SCRIPT ERROR:` markers belong here — the looser + // `GDScript error` substring also matches user printerr output and produces false positives. + static SCRIPT_ERROR_PATTERNS = ['SCRIPT ERROR:', 'USER SCRIPT ERROR:']; + static RETRYABLE_BRIDGE_COMMANDS = new Set(['get_ui_elements', 'screenshot']); + extractRuntimeErrors(lines) { + return lines.filter((line) => GodotRunner.SCRIPT_ERROR_PATTERNS.some((p) => line.includes(p))); + } + async sendCommandWithReconnect(command, params = {}, timeoutMs = 10000) { + try { + return await this.sendCommand(command, params, timeoutMs); + } + catch (err) { + if (err instanceof BridgeDisconnectedError && + this.activeSessionMode && + GodotRunner.RETRYABLE_BRIDGE_COMMANDS.has(command)) { + this.closeConnection(); + await new Promise((r) => setTimeout(r, BRIDGE_RECONNECT_DELAY_MS)); + return this.sendCommand(command, params, timeoutMs); + } + throw err; + } + } + async sendCommandWithErrors(command, params = {}, timeoutMs = 10000) { + const marker = this.getErrorCount(); + const response = await this.sendCommandWithReconnect(command, params, timeoutMs); + const newErrors = this.getErrorsSince(marker); + const runtimeErrors = this.activeSessionMode === 'spawned' ? this.extractRuntimeErrors(newErrors) : []; + return { response, runtimeErrors }; + } + /** + * Shared poll loop for `waitForBridge` (spawned) and `waitForBridgeAttached`. + * Sends `ping` payloads until the bridge replies with a pong that + * `validatePong` accepts, the deadline passes, or `shouldAbort` reports + * the spawned process has exited. + */ + async pollBridge(opts) { + const deadline = Date.now() + opts.timeoutMs; + while (Date.now() < deadline) { + if (opts.shouldAbort) { + const abort = opts.shouldAbort(); + if (abort.aborted) { + const errorText = abort.tail.length > 0 ? `\nLast stderr:\n${abort.tail.join('\n')}` : ''; + return { + ready: false, + error: `Process exited with code ${this.activeProcess?.exitCode ?? '?'} before bridge was ready.${errorText}`, + }; + } + } + try { + const response = await this.sendCommand('ping', opts.pingPayload, BRIDGE_PING_TIMEOUT_MS); + const parsed = JSON.parse(response); + if (opts.validatePong(parsed)) { + if (opts.expectedPath && parsed.project_path) { + const bridgePath = normalizeForCompare(parsed.project_path); + if (bridgePath !== opts.expectedPath) { + return { + ready: false, + error: `Bridge reports project ${bridgePath}, expected ${opts.expectedPath}`, + }; + } + } + return { ready: true }; + } + } + catch { + // Expected: ping will fail until bridge is listening + } + await new Promise((resolve) => setTimeout(resolve, opts.intervalMs)); + } + return { ready: false, error: opts.timeoutError }; + } + async waitForBridgeAttached(timeoutMs = BRIDGE_WAIT_ATTACHED_TIMEOUT_MS, intervalMs = BRIDGE_WAIT_ATTACHED_INTERVAL_MS) { + return this.pollBridge({ + expectedPath: this.activeProjectPath ? normalizeForCompare(this.activeProjectPath) : null, + timeoutMs, + intervalMs, + timeoutError: 'Bridge did not respond within timeout — is Godot running with the McpBridge autoload?', + pingPayload: {}, + validatePong: (parsed) => parsed.status === 'pong', + }); + } + async waitForBridge(timeoutMs = BRIDGE_WAIT_SPAWNED_TIMEOUT_MS, intervalMs = BRIDGE_WAIT_SPAWNED_INTERVAL_MS) { + const expectedToken = this.activeProcess?.sessionToken; + if (!expectedToken) { + return { ready: false, error: 'No active spawned Godot process to verify' }; + } + return this.pollBridge({ + expectedPath: this.activeProjectPath ? normalizeForCompare(this.activeProjectPath) : null, + timeoutMs, + intervalMs, + timeoutError: 'Bridge did not respond with the expected session token within timeout', + pingPayload: { session_token: expectedToken }, + validatePong: (parsed) => parsed.status === 'pong' && parsed.session_token === expectedToken, + shouldAbort: () => ({ + aborted: this.activeProcess !== null && this.activeProcess.hasExited, + tail: this.getRecentErrors(20), + }), + }); + } + getRecentErrors(count = 20) { + if (!this.activeProcess) + return []; + return this.activeProcess.errors.slice(-count).filter((line) => line.trim() !== ''); + } +} +//# sourceMappingURL=godot-runner.js.map \ No newline at end of file diff --git a/package/dist/utils/godot-runner.js.map b/package/dist/utils/godot-runner.js.map new file mode 100644 index 0000000..b08493f --- /dev/null +++ b/package/dist/utils/godot-runner.js.map @@ -0,0 +1 @@ +{"version":3,"file":"godot-runner.js","sourceRoot":"","sources":["../../src/utils/godot-runner.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package/dist/utils/handler-helpers.d.ts b/package/dist/utils/handler-helpers.d.ts new file mode 100644 index 0000000..4a28c76 --- /dev/null +++ b/package/dist/utils/handler-helpers.d.ts @@ -0,0 +1,36 @@ +import type { GodotRunner, OperationParams, ToolResponse } from './godot-runner.js'; +export declare const MAX_RUNTIME_ERROR_CONTEXT_LINES = 30; +/** + * Wraps the execute + empty-stdout-check + try/catch around a headless GDScript + * operation. Used by the 15 scene/node mutation handlers in tools/scene-tools.ts + * and tools/node-tools.ts to eliminate identical error-handling duplication. + * + * Handlers retain control of: parameter normalization, project/scene validation, + * field validation, and constructing the `params` object — those run before the + * call. Success-shape construction (the JSON wrapping the GDScript stdout) is + * also unchanged: this helper just returns `{ content: [{ type: 'text', text: stdout }] }`, + * which is the exact shape every handler produced previously. + */ +export declare function executeSceneOp(runner: GodotRunner, operation: string, params: OperationParams, projectPath: string, failurePrefix: string, emptyStdoutSolutions: string[], exceptionSolutions?: string[], options?: { + parseStdoutAsJson?: boolean; +}): Promise; +export type ParseResult = { + ok: true; + data: T; +} | { + ok: false; + response: ToolResponse; +}; +/** + * Parse a JSON frame returned by the McpBridge. On failure, returns a + * structured error response so handlers can short-circuit with one branch. + * `context` should describe which bridge command produced the frame. + */ +export declare function parseBridgeJson(responseStr: string, context: string): ParseResult; +/** + * Attach captured runtime errors as a `warnings` array on a tool response + * payload. No-op when there are no runtime errors. Truncates to + * `MAX_RUNTIME_ERROR_CONTEXT_LINES` to keep payloads bounded. + */ +export declare function attachRuntimeWarnings(target: Record, runtimeErrors: string[]): void; +//# sourceMappingURL=handler-helpers.d.ts.map \ No newline at end of file diff --git a/package/dist/utils/handler-helpers.d.ts.map b/package/dist/utils/handler-helpers.d.ts.map new file mode 100644 index 0000000..a0217a4 --- /dev/null +++ b/package/dist/utils/handler-helpers.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"handler-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/handler-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAQpF,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAElD;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,EACvB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,oBAAoB,EAAE,MAAM,EAAE,EAC9B,kBAAkB,GAAE,MAAM,EAA4C,EACtE,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5C,OAAO,CAAC,YAAY,CAAC,CA2BvB;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC;AAE3F;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,GAAG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAejG;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,aAAa,EAAE,MAAM,EAAE,GACtB,IAAI,CAIN"} \ No newline at end of file diff --git a/package/dist/utils/handler-helpers.js b/package/dist/utils/handler-helpers.js new file mode 100644 index 0000000..0c2c5f2 --- /dev/null +++ b/package/dist/utils/handler-helpers.js @@ -0,0 +1,67 @@ +import { createErrorResponse, createStructuredResponse, extractGdError, getErrorMessage, } from './godot-runner.js'; +export const MAX_RUNTIME_ERROR_CONTEXT_LINES = 30; +/** + * Wraps the execute + empty-stdout-check + try/catch around a headless GDScript + * operation. Used by the 15 scene/node mutation handlers in tools/scene-tools.ts + * and tools/node-tools.ts to eliminate identical error-handling duplication. + * + * Handlers retain control of: parameter normalization, project/scene validation, + * field validation, and constructing the `params` object — those run before the + * call. Success-shape construction (the JSON wrapping the GDScript stdout) is + * also unchanged: this helper just returns `{ content: [{ type: 'text', text: stdout }] }`, + * which is the exact shape every handler produced previously. + */ +export async function executeSceneOp(runner, operation, params, projectPath, failurePrefix, emptyStdoutSolutions, exceptionSolutions = ['Ensure Godot is installed correctly'], options = {}) { + try { + const { stdout, stderr } = await runner.executeOperation(operation, params, projectPath); + if (!stdout.trim()) { + return createErrorResponse(`${failurePrefix}: ${extractGdError(stderr)}`, emptyStdoutSolutions); + } + if (options.parseStdoutAsJson) { + try { + const payload = JSON.parse(stdout.trim()); + return createStructuredResponse(payload); + } + catch (parseErr) { + return createErrorResponse(`${failurePrefix}: GDScript returned invalid JSON (${getErrorMessage(parseErr)})`, [ + 'This indicates a bug in godot_operations.gd — the operation should emit a JSON payload matching its outputSchema', + 'Check get_debug_output for the raw stdout and stderr', + ]); + } + } + return { content: [{ type: 'text', text: stdout }] }; + } + catch (error) { + return createErrorResponse(`${failurePrefix}: ${getErrorMessage(error)}`, exceptionSolutions); + } +} +/** + * Parse a JSON frame returned by the McpBridge. On failure, returns a + * structured error response so handlers can short-circuit with one branch. + * `context` should describe which bridge command produced the frame. + */ +export function parseBridgeJson(responseStr, context) { + try { + return { ok: true, data: JSON.parse(responseStr) }; + } + catch (error) { + return { + ok: false, + response: createErrorResponse(`Invalid response from bridge (${context}): ${getErrorMessage(error)}`, [ + 'The bridge returned non-JSON data — check Godot stderr via get_debug_output', + 'Restart the project with stop_project followed by run_project', + ]), + }; + } +} +/** + * Attach captured runtime errors as a `warnings` array on a tool response + * payload. No-op when there are no runtime errors. Truncates to + * `MAX_RUNTIME_ERROR_CONTEXT_LINES` to keep payloads bounded. + */ +export function attachRuntimeWarnings(target, runtimeErrors) { + if (runtimeErrors.length > 0) { + target.warnings = runtimeErrors.slice(0, MAX_RUNTIME_ERROR_CONTEXT_LINES); + } +} +//# sourceMappingURL=handler-helpers.js.map \ No newline at end of file diff --git a/package/dist/utils/handler-helpers.js.map b/package/dist/utils/handler-helpers.js.map new file mode 100644 index 0000000..326a1cc --- /dev/null +++ b/package/dist/utils/handler-helpers.js.map @@ -0,0 +1 @@ +{"version":3,"file":"handler-helpers.js","sourceRoot":"","sources":["../../src/utils/handler-helpers.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,cAAc,EACd,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,CAAC,MAAM,+BAA+B,GAAG,EAAE,CAAC;AAElD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAmB,EACnB,SAAiB,EACjB,MAAuB,EACvB,WAAmB,EACnB,aAAqB,EACrB,oBAA8B,EAC9B,qBAA+B,CAAC,qCAAqC,CAAC,EACtE,UAA2C,EAAE;IAE7C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACzF,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACnB,OAAO,mBAAmB,CACxB,GAAG,aAAa,KAAK,cAAc,CAAC,MAAM,CAAC,EAAE,EAC7C,oBAAoB,CACrB,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAA4B,CAAC;gBACrE,OAAO,wBAAwB,CAAC,OAAO,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,QAAQ,EAAE,CAAC;gBAClB,OAAO,mBAAmB,CACxB,GAAG,aAAa,qCAAqC,eAAe,CAAC,QAAQ,CAAC,GAAG,EACjF;oBACE,kHAAkH;oBAClH,sDAAsD;iBACvD,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,OAAO,mBAAmB,CAAC,GAAG,aAAa,KAAK,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC;IAChG,CAAC;AACH,CAAC;AAID;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAc,WAAmB,EAAE,OAAe;IAC/E,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAM,EAAE,CAAC;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,mBAAmB,CAC3B,iCAAiC,OAAO,MAAM,eAAe,CAAC,KAAK,CAAC,EAAE,EACtE;gBACE,6EAA6E;gBAC7E,+DAA+D;aAChE,CACF;SACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAA+B,EAC/B,aAAuB;IAEvB,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,+BAA+B,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/package/dist/utils/logger.d.ts b/package/dist/utils/logger.d.ts new file mode 100644 index 0000000..c597180 --- /dev/null +++ b/package/dist/utils/logger.d.ts @@ -0,0 +1,4 @@ +export declare const DEBUG_MODE: boolean; +export declare function logDebug(message: string): void; +export declare function logError(message: string): void; +//# sourceMappingURL=logger.d.ts.map \ No newline at end of file diff --git a/package/dist/utils/logger.d.ts.map b/package/dist/utils/logger.d.ts.map new file mode 100644 index 0000000..1bfa1ea --- /dev/null +++ b/package/dist/utils/logger.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,UAAU,SAA+B,CAAC;AAEvD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI9C;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE9C"} \ No newline at end of file diff --git a/package/dist/utils/logger.js b/package/dist/utils/logger.js new file mode 100644 index 0000000..3c605b5 --- /dev/null +++ b/package/dist/utils/logger.js @@ -0,0 +1,11 @@ +// Debug mode from environment +export const DEBUG_MODE = process.env.DEBUG === 'true'; +export function logDebug(message) { + if (DEBUG_MODE) { + console.error(`[DEBUG] ${message}`); + } +} +export function logError(message) { + console.error(`[SERVER] ${message}`); +} +//# sourceMappingURL=logger.js.map \ No newline at end of file diff --git a/package/dist/utils/logger.js.map b/package/dist/utils/logger.js.map new file mode 100644 index 0000000..ad30138 --- /dev/null +++ b/package/dist/utils/logger.js.map @@ -0,0 +1 @@ +{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC;AAEvD,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,OAAO,CAAC,KAAK,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;AACvC,CAAC"} \ No newline at end of file diff --git a/package/package.json b/package/package.json new file mode 100644 index 0000000..8dbe9f1 --- /dev/null +++ b/package/package.json @@ -0,0 +1,72 @@ +{ + "name": "godot-mcp-runtime", + "version": "3.1.2", + "description": "A lightweight, zero-footprint TypeScript MCP server that lets AI assistants interact with the Godot 4.x game engine: not just editing files, but playing the game.", + "main": "dist/index.js", + "type": "module", + "bin": { + "godot-mcp-runtime": "dist/index.js" + }, + "scripts": { + "build": "tsc && node scripts/copy-scripts.js", + "start": "node dist/index.js", + "dev": "npm run build && node dist/index.js", + "test": "vitest run", + "test:watch": "vitest", + "test:coverage": "vitest run --coverage", + "typecheck": "tsc --noEmit", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "format": "prettier --write .", + "format:check": "prettier --check .", + "verify": "bash scripts/verify.sh", + "safe-install": "node scripts/safe-install.js", + "snapshot-cross-platform-deps": "node scripts/snapshot-cross-platform-deps.js", + "install-hooks": "node scripts/install-hooks.js" + }, + "keywords": [ + "mcp", + "godot", + "game-development", + "model-context-protocol", + "ai", + "game-engine", + "godot4" + ], + "author": "Owen Sterling", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/Erodenn/godot-mcp-runtime.git" + }, + "homepage": "https://github.com/Erodenn/godot-mcp-runtime", + "bugs": { + "url": "https://github.com/Erodenn/godot-mcp-runtime/issues" + }, + "mcpName": "io.github.Erodenn/godot-mcp-runtime", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.25.2" + }, + "devDependencies": { + "@eslint-community/eslint-plugin-eslint-comments": "^4.7.1", + "@types/node": "^25.0.9", + "@typescript-eslint/eslint-plugin": "^8.59.1", + "@typescript-eslint/parser": "^8.59.1", + "@vitest/coverage-v8": "^4.1.5", + "ajv": "^8.20.0", + "eslint": "^9.39.4", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-import": "^2.32.0", + "prettier": "^3.8.3", + "typescript": "^5.9.3", + "vitest": "^4.1.5" + }, + "files": [ + "dist/", + "README.md", + "LICENSE" + ], + "engines": { + "node": ">=20.0.0" + } +} diff --git a/project.godot b/project.godot index 16debd4..a68390f 100644 --- a/project.godot +++ b/project.godot @@ -41,6 +41,7 @@ NetworkSynchronizationServer="*res://addons/netfox/servers/network-synchronizati NetworkIdentityServer="*res://addons/netfox/servers/network-identity-server.gd" NetworkCommandServer="*res://addons/netfox/servers/network-command-server.gd" WeaponRegistry="*res://examples/multiplayer-fps/scripts/data/weapon_registry.gd" +Audio="*res://assets/kenney-fps/scripts/audio.gd" [display] @@ -55,7 +56,7 @@ enabled=PackedStringArray("res://addons/netfox.extras/plugin.cfg", "res://addons [filesystem] import/blender/enabled=false -import/fbx/enabled=false +import/fbx/enabled=true [input]