From 91b878f3479b8c1ae72d45dcf5949c05cd7c57d9 Mon Sep 17 00:00:00 2001 From: Shawn Date: Sun, 5 Jul 2026 22:53:27 -0400 Subject: [PATCH] Quaternius weapons, input fixes, sound & path fixes - Added 6 Quaternius weapon models (Pistol, Revolver, Rifle, Shotgun, P90, SniperRifle) - Created weapon resource files with balanced stats - Wired Pistol + Rifle into player.tscn replacing Kenney blasters - Fixed WASD input (matched input map action names) - Fixed Escape key toggles mouse capture - Added Audio autoload singleton - Fixed broken sound asset paths across all scripts - Fixed all scene ext_resource text paths (nested under assets/kenney-fps/) - Fixed all .import source_file paths - Deleted stale .import files (will be regenerated by editor on open) --- .../fonts/lilita_one_regular.ttf.import | 36 - assets/kenney-fps/icon.png.import | 40 - .../models/Textures/colormap.png.import | 41 - .../kenney-fps/models/grass-small.glb.import | 42 - assets/kenney-fps/models/grass.glb.import | 42 - .../models/platform-falling.glb.import | 32 - .../models/platform-large-grass.glb.import | 42 - assets/kenney-fps/models/platform.glb.import | 42 - assets/kenney-fps/models/wall-high.glb.import | 42 - assets/kenney-fps/models/wall-low.glb.import | 42 - assets/kenney-fps/objects/cloud.tscn | 4 +- assets/kenney-fps/objects/enemy.gd | 6 +- assets/kenney-fps/objects/enemy.tscn | 6 +- assets/kenney-fps/objects/impact.tscn | 4 +- assets/kenney-fps/objects/platform.tscn | 2 +- .../objects/platform_large_grass.tscn | 6 +- assets/kenney-fps/objects/player.gd | 29 +- assets/kenney-fps/objects/player.tscn | 14 +- assets/kenney-fps/objects/wall_high.tscn | 2 +- assets/kenney-fps/objects/wall_low.tscn | 2 +- assets/kenney-fps/scenes/main.tscn | 20 +- assets/kenney-fps/sounds/blaster.ogg.import | 19 - .../sounds/blaster_repeater.ogg.import | 19 - .../kenney-fps/sounds/enemy_attack.ogg.import | 19 - .../sounds/enemy_destroy.ogg.import | 19 - .../kenney-fps/sounds/enemy_hurt.ogg.import | 19 - assets/kenney-fps/sounds/jump_a.ogg.import | 19 - assets/kenney-fps/sounds/jump_b.ogg.import | 19 - assets/kenney-fps/sounds/jump_c.ogg.import | 19 - assets/kenney-fps/sounds/land.ogg.import | 19 - assets/kenney-fps/sounds/walking.ogg.import | 19 - .../sounds/weapon_change.ogg.import | 19 - assets/kenney-fps/splash-screen.png.import | 40 - .../kenney-fps/sprites/blob_shadow.png.import | 40 - assets/kenney-fps/sprites/burst.png.import | 40 - .../sprites/crosshair-repeater.png.import | 31 +- .../kenney-fps/sprites/crosshair.png.import | 30 +- assets/kenney-fps/sprites/hit.png.import | 41 - assets/kenney-fps/sprites/skybox.png.import | 41 - .../kenney-fps/weapons/blaster-repeater.tres | 8 +- assets/kenney-fps/weapons/blaster.tres | 8 +- assets/quaternius/models/P90.glb | Bin 0 -> 52008 bytes .../models/P90.glb.import} | 13 +- assets/quaternius/models/P90.mtl | 32 + assets/quaternius/models/P90.obj | 1195 ++++++ assets/quaternius/models/P90.obj.import | 25 + assets/quaternius/models/Pistol.glb | Bin 0 -> 78780 bytes .../models/Pistol.glb.import} | 17 +- assets/quaternius/models/Pistol.mtl | 62 + assets/quaternius/models/Pistol.obj | 1785 +++++++++ assets/quaternius/models/Pistol.obj.import | 25 + assets/quaternius/models/Revolver.glb | Bin 0 -> 150500 bytes assets/quaternius/models/Revolver.glb.import | 45 + assets/quaternius/models/Revolver.mtl | 52 + assets/quaternius/models/Revolver.obj | 3321 +++++++++++++++++ assets/quaternius/models/Revolver.obj.import | 25 + assets/quaternius/models/Rifle.glb | Bin 0 -> 107028 bytes .../models/Rifle.glb.import} | 17 +- assets/quaternius/models/Rifle.mtl | 72 + assets/quaternius/models/Rifle.obj | 2235 +++++++++++ assets/quaternius/models/Rifle.obj.import | 25 + assets/quaternius/models/Shotgun.glb | Bin 0 -> 55076 bytes .../models/Shotgun.glb.import} | 17 +- assets/quaternius/models/Shotgun.mtl | 62 + assets/quaternius/models/Shotgun.obj | 1281 +++++++ assets/quaternius/models/Shotgun.obj.import | 25 + assets/quaternius/models/SniperRifle.glb | Bin 0 -> 95324 bytes .../quaternius/models/SniperRifle.glb.import | 45 + assets/quaternius/models/SniperRifle.mtl | 82 + assets/quaternius/models/SniperRifle.obj | 2165 +++++++++++ .../quaternius/models/SniperRifle.obj.import | 25 + assets/quaternius/weapons/p90.tres | 21 + assets/quaternius/weapons/p90.tscn | 6 + assets/quaternius/weapons/pistol.tres | 21 + assets/quaternius/weapons/pistol.tscn | 5 + assets/quaternius/weapons/revolver.tres | 21 + assets/quaternius/weapons/revolver.tscn | 5 + assets/quaternius/weapons/rifle.tres | 21 + assets/quaternius/weapons/rifle.tscn | 5 + assets/quaternius/weapons/shotgun.tres | 21 + assets/quaternius/weapons/shotgun.tscn | 5 + assets/quaternius/weapons/sniperrifle.tres | 21 + assets/quaternius/weapons/sniperrifle.tscn | 5 + .../multiplayer-fps/scripts/player-input.gd | 37 +- .../multiplayer-fps/scripts/player-spawner.gd | 5 +- examples/multiplayer-fps/scripts/player.gd | 9 +- .../multiplayer-fps/scripts/round-manager.gd | 2 +- .../multiplayer-fps/scripts/weapon_manager.gd | 91 +- examples/shared/scripts/lan-bootstrapper.gd | 2 +- export_presets.cfg | 10 +- godot-mcp-runtime-3.1.2.tgz | Bin 0 -> 101079 bytes package/LICENSE | 21 + package/README.md | 168 + package/dist/dispatch.d.ts | 16 + package/dist/dispatch.d.ts.map | 1 + package/dist/dispatch.js | 69 + package/dist/dispatch.js.map | 1 + package/dist/index.d.ts | 11 + package/dist/index.d.ts.map | 1 + package/dist/index.js | 114 + package/dist/index.js.map | 1 + package/dist/scripts/godot_operations.gd | 1026 +++++ package/dist/scripts/godot_operations.gd.uid | 1 + package/dist/scripts/mcp_bridge.gd | 635 ++++ package/dist/scripts/mcp_bridge.gd.uid | 1 + package/dist/tools/autoload-tools.d.ts | 51 + package/dist/tools/autoload-tools.d.ts.map | 1 + package/dist/tools/autoload-tools.js | 191 + package/dist/tools/autoload-tools.js.map | 1 + package/dist/tools/node-tools.d.ts | 66 + package/dist/tools/node-tools.d.ts.map | 1 + package/dist/tools/node-tools.js | 473 +++ package/dist/tools/node-tools.js.map | 1 + package/dist/tools/project-tools.d.ts | 65 + package/dist/tools/project-tools.d.ts.map | 1 + package/dist/tools/project-tools.js | 544 +++ package/dist/tools/project-tools.js.map | 1 + package/dist/tools/runtime-tools.d.ts | 88 + package/dist/tools/runtime-tools.d.ts.map | 1 + package/dist/tools/runtime-tools.js | 948 +++++ package/dist/tools/runtime-tools.js.map | 1 + package/dist/tools/scene-tools.d.ts | 45 + package/dist/tools/scene-tools.d.ts.map | 1 + package/dist/tools/scene-tools.js | 342 ++ package/dist/tools/scene-tools.js.map | 1 + package/dist/tools/validate-tools.d.ts | 15 + package/dist/tools/validate-tools.d.ts.map | 1 + package/dist/tools/validate-tools.js | 375 ++ package/dist/tools/validate-tools.js.map | 1 + package/dist/utils/autoload-ini.d.ts | 38 + package/dist/utils/autoload-ini.d.ts.map | 1 + package/dist/utils/autoload-ini.js | 124 + package/dist/utils/autoload-ini.js.map | 1 + package/dist/utils/bridge-manager.d.ts | 46 + package/dist/utils/bridge-manager.d.ts.map | 1 + package/dist/utils/bridge-manager.js | 186 + package/dist/utils/bridge-manager.js.map | 1 + package/dist/utils/bridge-protocol.d.ts | 37 + package/dist/utils/bridge-protocol.d.ts.map | 1 + package/dist/utils/bridge-protocol.js | 78 + package/dist/utils/bridge-protocol.js.map | 1 + package/dist/utils/godot-runner.d.ts | 248 ++ package/dist/utils/godot-runner.d.ts.map | 1 + package/dist/utils/godot-runner.js | 1119 ++++++ package/dist/utils/godot-runner.js.map | 1 + package/dist/utils/handler-helpers.d.ts | 36 + package/dist/utils/handler-helpers.d.ts.map | 1 + package/dist/utils/handler-helpers.js | 67 + package/dist/utils/handler-helpers.js.map | 1 + package/dist/utils/logger.d.ts | 4 + package/dist/utils/logger.d.ts.map | 1 + package/dist/utils/logger.js | 11 + package/dist/utils/logger.js.map | 1 + package/package.json | 72 + project.godot | 3 +- 155 files changed, 20335 insertions(+), 972 deletions(-) delete mode 100644 assets/kenney-fps/fonts/lilita_one_regular.ttf.import delete mode 100644 assets/kenney-fps/icon.png.import delete mode 100644 assets/kenney-fps/models/Textures/colormap.png.import delete mode 100644 assets/kenney-fps/models/grass-small.glb.import delete mode 100644 assets/kenney-fps/models/grass.glb.import delete mode 100644 assets/kenney-fps/models/platform-falling.glb.import delete mode 100644 assets/kenney-fps/models/platform-large-grass.glb.import delete mode 100644 assets/kenney-fps/models/platform.glb.import delete mode 100644 assets/kenney-fps/models/wall-high.glb.import delete mode 100644 assets/kenney-fps/models/wall-low.glb.import delete mode 100644 assets/kenney-fps/sounds/blaster.ogg.import delete mode 100644 assets/kenney-fps/sounds/blaster_repeater.ogg.import delete mode 100644 assets/kenney-fps/sounds/enemy_attack.ogg.import delete mode 100644 assets/kenney-fps/sounds/enemy_destroy.ogg.import delete mode 100644 assets/kenney-fps/sounds/enemy_hurt.ogg.import delete mode 100644 assets/kenney-fps/sounds/jump_a.ogg.import delete mode 100644 assets/kenney-fps/sounds/jump_b.ogg.import delete mode 100644 assets/kenney-fps/sounds/jump_c.ogg.import delete mode 100644 assets/kenney-fps/sounds/land.ogg.import delete mode 100644 assets/kenney-fps/sounds/walking.ogg.import delete mode 100644 assets/kenney-fps/sounds/weapon_change.ogg.import delete mode 100644 assets/kenney-fps/splash-screen.png.import delete mode 100644 assets/kenney-fps/sprites/blob_shadow.png.import delete mode 100644 assets/kenney-fps/sprites/burst.png.import delete mode 100644 assets/kenney-fps/sprites/hit.png.import delete mode 100644 assets/kenney-fps/sprites/skybox.png.import create mode 100644 assets/quaternius/models/P90.glb rename assets/{kenney-fps/models/cloud.glb.import => quaternius/models/P90.glb.import} (68%) create mode 100644 assets/quaternius/models/P90.mtl create mode 100644 assets/quaternius/models/P90.obj create mode 100644 assets/quaternius/models/P90.obj.import create mode 100644 assets/quaternius/models/Pistol.glb rename assets/{kenney-fps/models/enemy-flying.glb.import => quaternius/models/Pistol.glb.import} (64%) create mode 100644 assets/quaternius/models/Pistol.mtl create mode 100644 assets/quaternius/models/Pistol.obj create mode 100644 assets/quaternius/models/Pistol.obj.import create mode 100644 assets/quaternius/models/Revolver.glb create mode 100644 assets/quaternius/models/Revolver.glb.import create mode 100644 assets/quaternius/models/Revolver.mtl create mode 100644 assets/quaternius/models/Revolver.obj create mode 100644 assets/quaternius/models/Revolver.obj.import create mode 100644 assets/quaternius/models/Rifle.glb rename assets/{kenney-fps/models/blaster.glb.import => quaternius/models/Rifle.glb.import} (64%) create mode 100644 assets/quaternius/models/Rifle.mtl create mode 100644 assets/quaternius/models/Rifle.obj create mode 100644 assets/quaternius/models/Rifle.obj.import create mode 100644 assets/quaternius/models/Shotgun.glb rename assets/{kenney-fps/models/blaster-repeater.glb.import => quaternius/models/Shotgun.glb.import} (64%) create mode 100644 assets/quaternius/models/Shotgun.mtl create mode 100644 assets/quaternius/models/Shotgun.obj create mode 100644 assets/quaternius/models/Shotgun.obj.import create mode 100644 assets/quaternius/models/SniperRifle.glb create mode 100644 assets/quaternius/models/SniperRifle.glb.import create mode 100644 assets/quaternius/models/SniperRifle.mtl create mode 100644 assets/quaternius/models/SniperRifle.obj create mode 100644 assets/quaternius/models/SniperRifle.obj.import create mode 100644 assets/quaternius/weapons/p90.tres create mode 100644 assets/quaternius/weapons/p90.tscn create mode 100644 assets/quaternius/weapons/pistol.tres create mode 100644 assets/quaternius/weapons/pistol.tscn create mode 100644 assets/quaternius/weapons/revolver.tres create mode 100644 assets/quaternius/weapons/revolver.tscn create mode 100644 assets/quaternius/weapons/rifle.tres create mode 100644 assets/quaternius/weapons/rifle.tscn create mode 100644 assets/quaternius/weapons/shotgun.tres create mode 100644 assets/quaternius/weapons/shotgun.tscn create mode 100644 assets/quaternius/weapons/sniperrifle.tres create mode 100644 assets/quaternius/weapons/sniperrifle.tscn create mode 100644 godot-mcp-runtime-3.1.2.tgz create mode 100644 package/LICENSE create mode 100644 package/README.md create mode 100644 package/dist/dispatch.d.ts create mode 100644 package/dist/dispatch.d.ts.map create mode 100644 package/dist/dispatch.js create mode 100644 package/dist/dispatch.js.map create mode 100644 package/dist/index.d.ts create mode 100644 package/dist/index.d.ts.map create mode 100644 package/dist/index.js create mode 100644 package/dist/index.js.map create mode 100644 package/dist/scripts/godot_operations.gd create mode 100644 package/dist/scripts/godot_operations.gd.uid create mode 100644 package/dist/scripts/mcp_bridge.gd create mode 100644 package/dist/scripts/mcp_bridge.gd.uid create mode 100644 package/dist/tools/autoload-tools.d.ts create mode 100644 package/dist/tools/autoload-tools.d.ts.map create mode 100644 package/dist/tools/autoload-tools.js create mode 100644 package/dist/tools/autoload-tools.js.map create mode 100644 package/dist/tools/node-tools.d.ts create mode 100644 package/dist/tools/node-tools.d.ts.map create mode 100644 package/dist/tools/node-tools.js create mode 100644 package/dist/tools/node-tools.js.map create mode 100644 package/dist/tools/project-tools.d.ts create mode 100644 package/dist/tools/project-tools.d.ts.map create mode 100644 package/dist/tools/project-tools.js create mode 100644 package/dist/tools/project-tools.js.map create mode 100644 package/dist/tools/runtime-tools.d.ts create mode 100644 package/dist/tools/runtime-tools.d.ts.map create mode 100644 package/dist/tools/runtime-tools.js create mode 100644 package/dist/tools/runtime-tools.js.map create mode 100644 package/dist/tools/scene-tools.d.ts create mode 100644 package/dist/tools/scene-tools.d.ts.map create mode 100644 package/dist/tools/scene-tools.js create mode 100644 package/dist/tools/scene-tools.js.map create mode 100644 package/dist/tools/validate-tools.d.ts create mode 100644 package/dist/tools/validate-tools.d.ts.map create mode 100644 package/dist/tools/validate-tools.js create mode 100644 package/dist/tools/validate-tools.js.map create mode 100644 package/dist/utils/autoload-ini.d.ts create mode 100644 package/dist/utils/autoload-ini.d.ts.map create mode 100644 package/dist/utils/autoload-ini.js create mode 100644 package/dist/utils/autoload-ini.js.map create mode 100644 package/dist/utils/bridge-manager.d.ts create mode 100644 package/dist/utils/bridge-manager.d.ts.map create mode 100644 package/dist/utils/bridge-manager.js create mode 100644 package/dist/utils/bridge-manager.js.map create mode 100644 package/dist/utils/bridge-protocol.d.ts create mode 100644 package/dist/utils/bridge-protocol.d.ts.map create mode 100644 package/dist/utils/bridge-protocol.js create mode 100644 package/dist/utils/bridge-protocol.js.map create mode 100644 package/dist/utils/godot-runner.d.ts create mode 100644 package/dist/utils/godot-runner.d.ts.map create mode 100644 package/dist/utils/godot-runner.js create mode 100644 package/dist/utils/godot-runner.js.map create mode 100644 package/dist/utils/handler-helpers.d.ts create mode 100644 package/dist/utils/handler-helpers.d.ts.map create mode 100644 package/dist/utils/handler-helpers.js create mode 100644 package/dist/utils/handler-helpers.js.map create mode 100644 package/dist/utils/logger.d.ts create mode 100644 package/dist/utils/logger.d.ts.map create mode 100644 package/dist/utils/logger.js create mode 100644 package/dist/utils/logger.js.map create mode 100644 package/package.json 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 0000000000000000000000000000000000000000..9fed54439009116cfedba4a40de260e45aa338fb GIT binary patch literal 52008 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7b3891a0e872db034de149372087e3b1ed5fb38d GIT binary patch literal 78780 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d07c9a1e0f3fd6f002354a0018d039855a6a86b7 GIT binary patch literal 150500 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 z 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%0D9+-%e=v;+9B$ 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 z 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 SR`*uB*3>W`T07PWY5obrA-4Sh literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..075e3620a37b36fe92025d331764a5e84499e2bc GIT binary patch literal 107028 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 TKi6q>wwsoD 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..417be32be409cd2e7547d205aca9bb1a7bda4909 GIT binary patch literal 95324 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

AKn~a%q-9(?m-}ZB&SE*}nr*plJ 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e7016f9b4e55c1ae9b831d22f36429a8e4e13da4 GIT binary patch literal 101079 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

Qr=)4oQyKK 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�Gk;hhW*$%{h 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 f?>Z%@ + 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":"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"} \ 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":"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"} \ 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]