commit 3240f079465189fb6326ae86ef8fd9b5ad48c53f Author: N0ble Date: Mon Jul 21 20:38:11 2025 -0600 Initial push diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..6248c16 Binary files /dev/null and b/.DS_Store differ diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ae13eeb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "godotTools.editorPath.godot4": "c:\\Users\\user\\Desktop\\Godot_v4.4.1-stable_win64.exe\\Godot_v4.4.1-stable_win64.exe" +} \ No newline at end of file diff --git a/Assets/Shaders/outline.gdshader b/Assets/Shaders/outline.gdshader new file mode 100644 index 0000000..6d9b0be --- /dev/null +++ b/Assets/Shaders/outline.gdshader @@ -0,0 +1,112 @@ +shader_type spatial; +render_mode unshaded; + +/* + Normal/Depth outline shader. Apply to nodes as a next pass shader texture. + Inspired by Yui Kinomoto @arlez80, lukky_nl (YT), Robin Seibold (YT) + Uses Sobel Edge detection on a normal and depth texture + Written by William Li (LoudFlameLava) + + MIT License +*/ + +// Might create an outline at the edge of the viewport + +uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap; +uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap; +uniform sampler2D NORMAL_TEXTURE : hint_normal_roughness_texture, filter_linear_mipmap; + +uniform float normal_threshold = 0.1; +uniform float depth_threshold = 0.05; +uniform float depth_artifact_correction_coef = 2; +uniform vec3 outline_color: source_color; + +const mat3 sobel_y = mat3( + vec3(1.0, 0.0, -1.0), + vec3(2.0, 0.0, -2.0), + vec3(1.0, 0.0, -1.0) +); + +const mat3 sobel_x = mat3( + vec3(1.0, 2.0, 1.0), + vec3(0.0, 0.0, 0.0), + vec3(-1.0, -2.0, -1.0) +); + +float edge_value_normal(sampler2D normal_tex, vec2 uv, vec2 pixel_size, mat3 sobel) { + float output = 0.0; + vec3 normal = texture(normal_tex, uv).rgb; + vec3 n = texture(NORMAL_TEXTURE, uv + vec2(0.0, -pixel_size.y)).rgb; + vec3 s = texture(NORMAL_TEXTURE, uv + vec2(0.0, pixel_size.y)).rgb; + vec3 e = texture(NORMAL_TEXTURE, uv + vec2(pixel_size.x, 0.0)).rgb; + vec3 w = texture(NORMAL_TEXTURE, uv + vec2(-pixel_size.x, 0.0)).rgb; + vec3 nw = texture(NORMAL_TEXTURE, uv + vec2(-pixel_size.x, -pixel_size.y)).rgb; + vec3 ne = texture(NORMAL_TEXTURE, uv + vec2(pixel_size.x, -pixel_size.y)).rgb; + vec3 sw = texture(NORMAL_TEXTURE, uv + vec2(-pixel_size.x, pixel_size.y)).rgb; + vec3 se = texture(NORMAL_TEXTURE, uv + vec2(pixel_size.x, pixel_size.y)).rgb; + + mat3 error_mat = mat3( + vec3(length(normal - nw), length(normal - n), length(normal - ne)), + vec3(length(normal - w), 0.0, length(normal - e)), + vec3(length(normal - sw), length(normal - s), length(normal - se)) + ); + + output += dot(sobel[0], error_mat[0]); + output += dot(sobel[1], error_mat[1]); + output += dot(sobel[2], error_mat[2]); + return abs(output); +} + +float get_depth(sampler2D depth_tex, vec2 uv, mat4 inv_projection_matrix) { + float depth_raw = texture(depth_tex, uv).x; + vec3 ndc = vec3(uv * 2.0 - 1.0, depth_raw); + vec4 view = inv_projection_matrix * vec4(ndc, 1.0); + view.xyz /= view.w; + float depth_linear = -view.z; + return depth_linear; +} + +float edge_value_depth(sampler2D depth_tex, vec2 uv, vec2 pixel_size, mat3 sobel, mat4 inv_projection_matrix){ + float output = 0.0; + float depth = get_depth(depth_tex, uv, inv_projection_matrix); + float n = get_depth(depth_tex, uv + vec2(0.0, -pixel_size.y), inv_projection_matrix); + float s = get_depth(depth_tex, uv + vec2(0.0, pixel_size.y), inv_projection_matrix); + float e = get_depth(depth_tex, uv + vec2(pixel_size.x, 0.0), inv_projection_matrix); + float w = get_depth(depth_tex, uv + vec2(-pixel_size.x, 0.0), inv_projection_matrix); + float ne = get_depth(depth_tex, uv + vec2(pixel_size.x, -pixel_size.y), inv_projection_matrix); + float nw = get_depth(depth_tex, uv + vec2(-pixel_size.x, -pixel_size.y), inv_projection_matrix); + float se = get_depth(depth_tex, uv + vec2(pixel_size.x, pixel_size.y), inv_projection_matrix); + float sw = get_depth(depth_tex, uv + vec2(-pixel_size.x, pixel_size.y), inv_projection_matrix); + + mat3 error_mat = mat3( + vec3((depth - nw)/depth, (depth - n)/depth, (depth - ne)/depth), + vec3((depth - w)/depth, 0.0, (depth - e)/depth), + vec3((depth - sw)/depth, (depth - s)/depth, (depth - se)/depth) + ); + + output += dot(sobel[0], error_mat[0]); + output += dot(sobel[1], error_mat[1]); + output += dot(sobel[2], error_mat[2]); + return abs(output); +} + + +void fragment() { + float has_outline = 0.0; + vec2 pixel_size = vec2(1.0) / VIEWPORT_SIZE; + ALBEDO = texture(SCREEN_TEXTURE, SCREEN_UV).xyz; + //ALBEDO = vec3(get_depth(DEPTH_TEXTURE, SCREEN_UV, INV_PROJECTION_MATRIX)); + if (edge_value_normal(NORMAL_TEXTURE, SCREEN_UV, pixel_size, sobel_x) + edge_value_normal(NORMAL_TEXTURE, SCREEN_UV, pixel_size, sobel_y) > normal_threshold){ + ALBEDO = outline_color; + has_outline += 1.0; + } + vec3 normal = texture(NORMAL_TEXTURE, SCREEN_UV).rgb; + float angle = 1.0 - dot(normalize(normal-vec3(0.5)), vec3(0.0,0.0,1.0)); + if (edge_value_depth(DEPTH_TEXTURE, SCREEN_UV, pixel_size, sobel_x, INV_PROJECTION_MATRIX) + edge_value_depth(DEPTH_TEXTURE, SCREEN_UV, pixel_size, sobel_y, INV_PROJECTION_MATRIX) > depth_threshold + angle * depth_artifact_correction_coef){ + ALBEDO = outline_color; + has_outline += 1.0; + } + if (has_outline < 0.1){ + ALPHA = 0.0; + } +} diff --git a/Assets/Shaders/outline.gdshader.uid b/Assets/Shaders/outline.gdshader.uid new file mode 100644 index 0000000..8dc51d4 --- /dev/null +++ b/Assets/Shaders/outline.gdshader.uid @@ -0,0 +1 @@ +uid://c0chn7ll6p7yk diff --git a/Assets/Textures/black_board.png b/Assets/Textures/black_board.png new file mode 100644 index 0000000..e063f8a Binary files /dev/null and b/Assets/Textures/black_board.png differ diff --git a/Assets/Textures/black_board.png.import b/Assets/Textures/black_board.png.import new file mode 100644 index 0000000..c5d6778 --- /dev/null +++ b/Assets/Textures/black_board.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ct5kq6psirv1" +path="res://.godot/imported/black_board.png-d2b5afa20c384e2e4b3e7a80827129fd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/black_board.png" +dest_files=["res://.godot/imported/black_board.png-d2b5afa20c384e2e4b3e7a80827129fd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Dark/texture_01.png b/Assets/Textures/kenny/Dark/texture_01.png new file mode 100644 index 0000000..69be211 Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_01.png differ diff --git a/Assets/Textures/kenny/Dark/texture_01.png.import b/Assets/Textures/kenny/Dark/texture_01.png.import new file mode 100644 index 0000000..3a72ae1 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bvarfgw4r5181" +path.s3tc="res://.godot/imported/texture_01.png-6071662e99660834e61c6b1e09bbab86.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-6071662e99660834e61c6b1e09bbab86.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Dark/texture_02.png b/Assets/Textures/kenny/Dark/texture_02.png new file mode 100644 index 0000000..6fb471b Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_02.png differ diff --git a/Assets/Textures/kenny/Dark/texture_02.png.import b/Assets/Textures/kenny/Dark/texture_02.png.import new file mode 100644 index 0000000..107ec0a --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_02.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://youvyib1feqp" +path.s3tc="res://.godot/imported/texture_02.png-50bb9d4d4ebbae05fd29423b1eebdf02.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-50bb9d4d4ebbae05fd29423b1eebdf02.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Dark/texture_03.png b/Assets/Textures/kenny/Dark/texture_03.png new file mode 100644 index 0000000..3f8b186 Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_03.png differ diff --git a/Assets/Textures/kenny/Dark/texture_03.png.import b/Assets/Textures/kenny/Dark/texture_03.png.import new file mode 100644 index 0000000..5d942fa --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dtr5bvxymd50e" +path="res://.godot/imported/texture_03.png-09f6510aeb06a66b61241151fd45cc12.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-09f6510aeb06a66b61241151fd45cc12.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Dark/texture_04.png b/Assets/Textures/kenny/Dark/texture_04.png new file mode 100644 index 0000000..e2bc22b Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_04.png differ diff --git a/Assets/Textures/kenny/Dark/texture_04.png.import b/Assets/Textures/kenny/Dark/texture_04.png.import new file mode 100644 index 0000000..d695f31 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://gebarmhhtmbt" +path="res://.godot/imported/texture_04.png-778404077545d0988503bb93ed90a85c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-778404077545d0988503bb93ed90a85c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Dark/texture_05.png b/Assets/Textures/kenny/Dark/texture_05.png new file mode 100644 index 0000000..3fd2e56 Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_05.png differ diff --git a/Assets/Textures/kenny/Dark/texture_05.png.import b/Assets/Textures/kenny/Dark/texture_05.png.import new file mode 100644 index 0000000..6655741 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_05.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ca0qmdc4cv8uh" +path.s3tc="res://.godot/imported/texture_05.png-0310eec4e5c94e9c6cb4c0e3fd371255.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-0310eec4e5c94e9c6cb4c0e3fd371255.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Dark/texture_06.png b/Assets/Textures/kenny/Dark/texture_06.png new file mode 100644 index 0000000..45d4a34 Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_06.png differ diff --git a/Assets/Textures/kenny/Dark/texture_06.png.import b/Assets/Textures/kenny/Dark/texture_06.png.import new file mode 100644 index 0000000..bbe7174 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://carepjxbifxnk" +path="res://.godot/imported/texture_06.png-2b3f2645aa79305efcc877465d8ddcb1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-2b3f2645aa79305efcc877465d8ddcb1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Dark/texture_07.png b/Assets/Textures/kenny/Dark/texture_07.png new file mode 100644 index 0000000..adf5e6f Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_07.png differ diff --git a/Assets/Textures/kenny/Dark/texture_07.png.import b/Assets/Textures/kenny/Dark/texture_07.png.import new file mode 100644 index 0000000..abdbb75 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://kjr70h6gg01b" +path="res://.godot/imported/texture_07.png-ba02094d10277610cee39722359a74f8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-ba02094d10277610cee39722359a74f8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Dark/texture_08.png b/Assets/Textures/kenny/Dark/texture_08.png new file mode 100644 index 0000000..a5a9f24 Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_08.png differ diff --git a/Assets/Textures/kenny/Dark/texture_08.png.import b/Assets/Textures/kenny/Dark/texture_08.png.import new file mode 100644 index 0000000..837ec38 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_08.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bhy0xbgh23y4d" +path.s3tc="res://.godot/imported/texture_08.png-66ed16371ee09d695d3da92281e2484c.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-66ed16371ee09d695d3da92281e2484c.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Dark/texture_09.png b/Assets/Textures/kenny/Dark/texture_09.png new file mode 100644 index 0000000..57cc607 Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_09.png differ diff --git a/Assets/Textures/kenny/Dark/texture_09.png.import b/Assets/Textures/kenny/Dark/texture_09.png.import new file mode 100644 index 0000000..4748cd6 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ci677phv85dbo" +path="res://.godot/imported/texture_09.png-a339e9ab2c228fa9a3d4ef6e1db33ba6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-a339e9ab2c228fa9a3d4ef6e1db33ba6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Dark/texture_10.png b/Assets/Textures/kenny/Dark/texture_10.png new file mode 100644 index 0000000..4c737d0 Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_10.png differ diff --git a/Assets/Textures/kenny/Dark/texture_10.png.import b/Assets/Textures/kenny/Dark/texture_10.png.import new file mode 100644 index 0000000..b094f99 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://beeg4qas2fsac" +path="res://.godot/imported/texture_10.png-ff641a8ee3894ad52a58711b2e06c0bf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-ff641a8ee3894ad52a58711b2e06c0bf.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Dark/texture_11.png b/Assets/Textures/kenny/Dark/texture_11.png new file mode 100644 index 0000000..424ba71 Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_11.png differ diff --git a/Assets/Textures/kenny/Dark/texture_11.png.import b/Assets/Textures/kenny/Dark/texture_11.png.import new file mode 100644 index 0000000..6653d85 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqht8ngfdmuwj" +path="res://.godot/imported/texture_11.png-355f894fc0cda8a832f22297cc09266e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-355f894fc0cda8a832f22297cc09266e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Dark/texture_12.png b/Assets/Textures/kenny/Dark/texture_12.png new file mode 100644 index 0000000..32169db Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_12.png differ diff --git a/Assets/Textures/kenny/Dark/texture_12.png.import b/Assets/Textures/kenny/Dark/texture_12.png.import new file mode 100644 index 0000000..3a1e07f --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bfh6mw4in04i4" +path="res://.godot/imported/texture_12.png-6e528b01bab6560b8cf1c4de1f66ee17.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-6e528b01bab6560b8cf1c4de1f66ee17.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Dark/texture_13.png b/Assets/Textures/kenny/Dark/texture_13.png new file mode 100644 index 0000000..13c4388 Binary files /dev/null and b/Assets/Textures/kenny/Dark/texture_13.png differ diff --git a/Assets/Textures/kenny/Dark/texture_13.png.import b/Assets/Textures/kenny/Dark/texture_13.png.import new file mode 100644 index 0000000..2c5dca2 --- /dev/null +++ b/Assets/Textures/kenny/Dark/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://e43jdimtr6vs" +path="res://.godot/imported/texture_13.png-00e2369d26e06bdd9f32f6d062d5ae9f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Dark/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-00e2369d26e06bdd9f32f6d062d5ae9f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_01.png b/Assets/Textures/kenny/Green/texture_01.png new file mode 100644 index 0000000..d576514 Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_01.png differ diff --git a/Assets/Textures/kenny/Green/texture_01.png.import b/Assets/Textures/kenny/Green/texture_01.png.import new file mode 100644 index 0000000..2e610a0 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b0e6e1xjl18aa" +path.s3tc="res://.godot/imported/texture_01.png-e84a1fc48ff8aea2304817d95826f7d1.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-e84a1fc48ff8aea2304817d95826f7d1.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Green/texture_02.png b/Assets/Textures/kenny/Green/texture_02.png new file mode 100644 index 0000000..7bc7cf8 Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_02.png differ diff --git a/Assets/Textures/kenny/Green/texture_02.png.import b/Assets/Textures/kenny/Green/texture_02.png.import new file mode 100644 index 0000000..17bdc5f --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d2r1dqvx1h5vk" +path="res://.godot/imported/texture_02.png-c0b2f3ead5d1423b3fb0f2462b41f12c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-c0b2f3ead5d1423b3fb0f2462b41f12c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_03.png b/Assets/Textures/kenny/Green/texture_03.png new file mode 100644 index 0000000..e2a3889 Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_03.png differ diff --git a/Assets/Textures/kenny/Green/texture_03.png.import b/Assets/Textures/kenny/Green/texture_03.png.import new file mode 100644 index 0000000..82b3a49 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnnes2g3lmmqc" +path="res://.godot/imported/texture_03.png-2ea7d5642901462925769bc9b4821182.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-2ea7d5642901462925769bc9b4821182.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_04.png b/Assets/Textures/kenny/Green/texture_04.png new file mode 100644 index 0000000..3952bef Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_04.png differ diff --git a/Assets/Textures/kenny/Green/texture_04.png.import b/Assets/Textures/kenny/Green/texture_04.png.import new file mode 100644 index 0000000..dd8072d --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djti0r1txl6fi" +path="res://.godot/imported/texture_04.png-4da8cab1d5443c2be1a0905e87be7e41.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-4da8cab1d5443c2be1a0905e87be7e41.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_05.png b/Assets/Textures/kenny/Green/texture_05.png new file mode 100644 index 0000000..84976ba Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_05.png differ diff --git a/Assets/Textures/kenny/Green/texture_05.png.import b/Assets/Textures/kenny/Green/texture_05.png.import new file mode 100644 index 0000000..9c84906 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bbkkd0r1324rf" +path="res://.godot/imported/texture_05.png-6112786d3ad5fc49141106fa07e460a6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-6112786d3ad5fc49141106fa07e460a6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_06.png b/Assets/Textures/kenny/Green/texture_06.png new file mode 100644 index 0000000..1128198 Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_06.png differ diff --git a/Assets/Textures/kenny/Green/texture_06.png.import b/Assets/Textures/kenny/Green/texture_06.png.import new file mode 100644 index 0000000..0c10369 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vcey0liprcku" +path="res://.godot/imported/texture_06.png-6ed4f201eb81a7ded2fcf27afbb76cd3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-6ed4f201eb81a7ded2fcf27afbb76cd3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_07.png b/Assets/Textures/kenny/Green/texture_07.png new file mode 100644 index 0000000..3160860 Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_07.png differ diff --git a/Assets/Textures/kenny/Green/texture_07.png.import b/Assets/Textures/kenny/Green/texture_07.png.import new file mode 100644 index 0000000..105f5d7 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://4fue3416xajr" +path="res://.godot/imported/texture_07.png-d690cfc57b2d71d6535bcf632bd98326.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-d690cfc57b2d71d6535bcf632bd98326.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_08.png b/Assets/Textures/kenny/Green/texture_08.png new file mode 100644 index 0000000..386293d Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_08.png differ diff --git a/Assets/Textures/kenny/Green/texture_08.png.import b/Assets/Textures/kenny/Green/texture_08.png.import new file mode 100644 index 0000000..e697347 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://poho7bpcb6ii" +path="res://.godot/imported/texture_08.png-388bcc8f4ed5730d30ef519aed5712c3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-388bcc8f4ed5730d30ef519aed5712c3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_09.png b/Assets/Textures/kenny/Green/texture_09.png new file mode 100644 index 0000000..48234f6 Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_09.png differ diff --git a/Assets/Textures/kenny/Green/texture_09.png.import b/Assets/Textures/kenny/Green/texture_09.png.import new file mode 100644 index 0000000..8a42689 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c4fay2858qj0l" +path="res://.godot/imported/texture_09.png-680667567c1aaff0ba907ed98e080d69.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-680667567c1aaff0ba907ed98e080d69.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_10.png b/Assets/Textures/kenny/Green/texture_10.png new file mode 100644 index 0000000..e4ab057 Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_10.png differ diff --git a/Assets/Textures/kenny/Green/texture_10.png.import b/Assets/Textures/kenny/Green/texture_10.png.import new file mode 100644 index 0000000..506afb1 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ba1f44g54l45m" +path="res://.godot/imported/texture_10.png-f4e6f4f72511743e87c731dc1a545bb8.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-f4e6f4f72511743e87c731dc1a545bb8.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_11.png b/Assets/Textures/kenny/Green/texture_11.png new file mode 100644 index 0000000..82ad458 Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_11.png differ diff --git a/Assets/Textures/kenny/Green/texture_11.png.import b/Assets/Textures/kenny/Green/texture_11.png.import new file mode 100644 index 0000000..c0282d3 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://hncjy0d5tnxg" +path="res://.godot/imported/texture_11.png-b7efbbf02e7aaebe01a73a52889e2db2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-b7efbbf02e7aaebe01a73a52889e2db2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_12.png b/Assets/Textures/kenny/Green/texture_12.png new file mode 100644 index 0000000..a15000d Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_12.png differ diff --git a/Assets/Textures/kenny/Green/texture_12.png.import b/Assets/Textures/kenny/Green/texture_12.png.import new file mode 100644 index 0000000..49af588 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://kdrttluayi20" +path="res://.godot/imported/texture_12.png-d600a604f3c865d458be124764f1815a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-d600a604f3c865d458be124764f1815a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Green/texture_13.png b/Assets/Textures/kenny/Green/texture_13.png new file mode 100644 index 0000000..930fdf0 Binary files /dev/null and b/Assets/Textures/kenny/Green/texture_13.png differ diff --git a/Assets/Textures/kenny/Green/texture_13.png.import b/Assets/Textures/kenny/Green/texture_13.png.import new file mode 100644 index 0000000..9c4c191 --- /dev/null +++ b/Assets/Textures/kenny/Green/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cbynwfgx1udap" +path="res://.godot/imported/texture_13.png-017338333d71c41496ec3c6b0c3f4cf5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Green/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-017338333d71c41496ec3c6b0c3f4cf5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_01.png b/Assets/Textures/kenny/Light/texture_01.png new file mode 100644 index 0000000..60b632b Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_01.png differ diff --git a/Assets/Textures/kenny/Light/texture_01.png.import b/Assets/Textures/kenny/Light/texture_01.png.import new file mode 100644 index 0000000..f5dbae7 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://7dus2yvf2ug" +path.s3tc="res://.godot/imported/texture_01.png-4e666ff013442f29d41e355995ff019c.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-4e666ff013442f29d41e355995ff019c.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Light/texture_02.png b/Assets/Textures/kenny/Light/texture_02.png new file mode 100644 index 0000000..19aad62 Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_02.png differ diff --git a/Assets/Textures/kenny/Light/texture_02.png.import b/Assets/Textures/kenny/Light/texture_02.png.import new file mode 100644 index 0000000..b99e7b4 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ct2nwmb0g0c11" +path="res://.godot/imported/texture_02.png-15f671c63a751d171fa712ed4f70138a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-15f671c63a751d171fa712ed4f70138a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_03.png b/Assets/Textures/kenny/Light/texture_03.png new file mode 100644 index 0000000..a8a6c06 Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_03.png differ diff --git a/Assets/Textures/kenny/Light/texture_03.png.import b/Assets/Textures/kenny/Light/texture_03.png.import new file mode 100644 index 0000000..e7fd3f3 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dvxbvy41idpif" +path="res://.godot/imported/texture_03.png-dabf35d6925641754119ee2126742474.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-dabf35d6925641754119ee2126742474.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_04.png b/Assets/Textures/kenny/Light/texture_04.png new file mode 100644 index 0000000..b8270e1 Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_04.png differ diff --git a/Assets/Textures/kenny/Light/texture_04.png.import b/Assets/Textures/kenny/Light/texture_04.png.import new file mode 100644 index 0000000..89b95d0 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://nsrg41iyucwk" +path="res://.godot/imported/texture_04.png-ed7440cc8ef63f2eb61e3a9c42d921cc.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-ed7440cc8ef63f2eb61e3a9c42d921cc.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_05.png b/Assets/Textures/kenny/Light/texture_05.png new file mode 100644 index 0000000..5b985bf Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_05.png differ diff --git a/Assets/Textures/kenny/Light/texture_05.png.import b/Assets/Textures/kenny/Light/texture_05.png.import new file mode 100644 index 0000000..6aead33 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d3j4vtf2aq4to" +path="res://.godot/imported/texture_05.png-3395530d01752dcf8e27fd6718497c9f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-3395530d01752dcf8e27fd6718497c9f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_06.png b/Assets/Textures/kenny/Light/texture_06.png new file mode 100644 index 0000000..195ad77 Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_06.png differ diff --git a/Assets/Textures/kenny/Light/texture_06.png.import b/Assets/Textures/kenny/Light/texture_06.png.import new file mode 100644 index 0000000..d8390d2 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dgl8yfvnfdw45" +path="res://.godot/imported/texture_06.png-487ab5f48eb725fca4e729bebdf72d2f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-487ab5f48eb725fca4e729bebdf72d2f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_07.png b/Assets/Textures/kenny/Light/texture_07.png new file mode 100644 index 0000000..fbf92e0 Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_07.png differ diff --git a/Assets/Textures/kenny/Light/texture_07.png.import b/Assets/Textures/kenny/Light/texture_07.png.import new file mode 100644 index 0000000..901cb43 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://p7b7cxvbb1cp" +path="res://.godot/imported/texture_07.png-5bc9abc0e209a8ac3f44e3b8278713fe.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-5bc9abc0e209a8ac3f44e3b8278713fe.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_08.png b/Assets/Textures/kenny/Light/texture_08.png new file mode 100644 index 0000000..72e1a07 Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_08.png differ diff --git a/Assets/Textures/kenny/Light/texture_08.png.import b/Assets/Textures/kenny/Light/texture_08.png.import new file mode 100644 index 0000000..1de110c --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ube7pfqljvyf" +path="res://.godot/imported/texture_08.png-25589eded306385399b275c6db3775cd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-25589eded306385399b275c6db3775cd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_09.png b/Assets/Textures/kenny/Light/texture_09.png new file mode 100644 index 0000000..9ada5dd Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_09.png differ diff --git a/Assets/Textures/kenny/Light/texture_09.png.import b/Assets/Textures/kenny/Light/texture_09.png.import new file mode 100644 index 0000000..4e6d36f --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djv5pftub125" +path="res://.godot/imported/texture_09.png-d03fadc65f007e08b56362a923e9de00.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-d03fadc65f007e08b56362a923e9de00.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_10.png b/Assets/Textures/kenny/Light/texture_10.png new file mode 100644 index 0000000..4fbcc80 Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_10.png differ diff --git a/Assets/Textures/kenny/Light/texture_10.png.import b/Assets/Textures/kenny/Light/texture_10.png.import new file mode 100644 index 0000000..e679b4a --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vbio6gqo77y6" +path="res://.godot/imported/texture_10.png-77bfe99d787ea2ef61f6f02a876f509e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-77bfe99d787ea2ef61f6f02a876f509e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_11.png b/Assets/Textures/kenny/Light/texture_11.png new file mode 100644 index 0000000..840ecec Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_11.png differ diff --git a/Assets/Textures/kenny/Light/texture_11.png.import b/Assets/Textures/kenny/Light/texture_11.png.import new file mode 100644 index 0000000..32ba719 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cb0mt02evssa1" +path="res://.godot/imported/texture_11.png-656e2ce8c617ee8b506ce297ee5013b7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-656e2ce8c617ee8b506ce297ee5013b7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_12.png b/Assets/Textures/kenny/Light/texture_12.png new file mode 100644 index 0000000..25c2e78 Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_12.png differ diff --git a/Assets/Textures/kenny/Light/texture_12.png.import b/Assets/Textures/kenny/Light/texture_12.png.import new file mode 100644 index 0000000..fd6e6b6 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c7h0g54nsd4en" +path="res://.godot/imported/texture_12.png-c779d9476a97c8c6f8344fc8c0acf05e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-c779d9476a97c8c6f8344fc8c0acf05e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Light/texture_13.png b/Assets/Textures/kenny/Light/texture_13.png new file mode 100644 index 0000000..a235965 Binary files /dev/null and b/Assets/Textures/kenny/Light/texture_13.png differ diff --git a/Assets/Textures/kenny/Light/texture_13.png.import b/Assets/Textures/kenny/Light/texture_13.png.import new file mode 100644 index 0000000..bed6c50 --- /dev/null +++ b/Assets/Textures/kenny/Light/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c150y2i0o0n4b" +path="res://.godot/imported/texture_13.png-e3613fd71c8fd004170df7272cdae77e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Light/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-e3613fd71c8fd004170df7272cdae77e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_01.png b/Assets/Textures/kenny/Orange/texture_01.png new file mode 100644 index 0000000..4f5bf92 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_01.png differ diff --git a/Assets/Textures/kenny/Orange/texture_01.png.import b/Assets/Textures/kenny/Orange/texture_01.png.import new file mode 100644 index 0000000..966270c --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://1eu6ubigu64i" +path.s3tc="res://.godot/imported/texture_01.png-21904ba99712468e66077bdbdb508efb.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-21904ba99712468e66077bdbdb508efb.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Orange/texture_02.png b/Assets/Textures/kenny/Orange/texture_02.png new file mode 100644 index 0000000..dec5b59 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_02.png differ diff --git a/Assets/Textures/kenny/Orange/texture_02.png.import b/Assets/Textures/kenny/Orange/texture_02.png.import new file mode 100644 index 0000000..aae1419 --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b8iefcauntlfr" +path="res://.godot/imported/texture_02.png-6ba53c85eb016038e9eb03ca867ef46d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-6ba53c85eb016038e9eb03ca867ef46d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_03.png b/Assets/Textures/kenny/Orange/texture_03.png new file mode 100644 index 0000000..666197f Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_03.png differ diff --git a/Assets/Textures/kenny/Orange/texture_03.png.import b/Assets/Textures/kenny/Orange/texture_03.png.import new file mode 100644 index 0000000..1688015 --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_03.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ck8bb11fqwytj" +path.s3tc="res://.godot/imported/texture_03.png-20f820c35e04dcdc607ba2061af190d1.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-20f820c35e04dcdc607ba2061af190d1.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Orange/texture_04.png b/Assets/Textures/kenny/Orange/texture_04.png new file mode 100644 index 0000000..23d6fc4 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_04.png differ diff --git a/Assets/Textures/kenny/Orange/texture_04.png.import b/Assets/Textures/kenny/Orange/texture_04.png.import new file mode 100644 index 0000000..7d674e3 --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dhcpwn5wpsl83" +path="res://.godot/imported/texture_04.png-5d656289d155d17452e89f79a68dd096.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-5d656289d155d17452e89f79a68dd096.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_05.png b/Assets/Textures/kenny/Orange/texture_05.png new file mode 100644 index 0000000..1e0448a Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_05.png differ diff --git a/Assets/Textures/kenny/Orange/texture_05.png.import b/Assets/Textures/kenny/Orange/texture_05.png.import new file mode 100644 index 0000000..b001350 --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bdabm8p32rpuh" +path="res://.godot/imported/texture_05.png-4173da2dfb92ee8e5cf0c0793d0919e0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-4173da2dfb92ee8e5cf0c0793d0919e0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_06.png b/Assets/Textures/kenny/Orange/texture_06.png new file mode 100644 index 0000000..5486825 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_06.png differ diff --git a/Assets/Textures/kenny/Orange/texture_06.png.import b/Assets/Textures/kenny/Orange/texture_06.png.import new file mode 100644 index 0000000..5d0b9c7 --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://10al17kdi8dt" +path="res://.godot/imported/texture_06.png-901615c60be874edc11fe06ec267294b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-901615c60be874edc11fe06ec267294b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_07.png b/Assets/Textures/kenny/Orange/texture_07.png new file mode 100644 index 0000000..95f2790 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_07.png differ diff --git a/Assets/Textures/kenny/Orange/texture_07.png.import b/Assets/Textures/kenny/Orange/texture_07.png.import new file mode 100644 index 0000000..a5bffc2 --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b22jirj6yj7jn" +path="res://.godot/imported/texture_07.png-ce29603f5e3b6487062ce4696276fe21.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-ce29603f5e3b6487062ce4696276fe21.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_08.png b/Assets/Textures/kenny/Orange/texture_08.png new file mode 100644 index 0000000..5a500d9 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_08.png differ diff --git a/Assets/Textures/kenny/Orange/texture_08.png.import b/Assets/Textures/kenny/Orange/texture_08.png.import new file mode 100644 index 0000000..fc8dcce --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ccfes61033s35" +path="res://.godot/imported/texture_08.png-23f17f2a358608a6ba99ba64d634384d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-23f17f2a358608a6ba99ba64d634384d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_09.png b/Assets/Textures/kenny/Orange/texture_09.png new file mode 100644 index 0000000..adcfa33 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_09.png differ diff --git a/Assets/Textures/kenny/Orange/texture_09.png.import b/Assets/Textures/kenny/Orange/texture_09.png.import new file mode 100644 index 0000000..6929bf5 --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bepcwfu5gwa0r" +path="res://.godot/imported/texture_09.png-28bb6eb8e1b5d72fc500acf10edb425c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-28bb6eb8e1b5d72fc500acf10edb425c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_10.png b/Assets/Textures/kenny/Orange/texture_10.png new file mode 100644 index 0000000..aa227e5 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_10.png differ diff --git a/Assets/Textures/kenny/Orange/texture_10.png.import b/Assets/Textures/kenny/Orange/texture_10.png.import new file mode 100644 index 0000000..6b41ec9 --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ds034otg5ppmx" +path="res://.godot/imported/texture_10.png-d5c32d7ba6a93e4d9448016f7d97b06a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-d5c32d7ba6a93e4d9448016f7d97b06a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_11.png b/Assets/Textures/kenny/Orange/texture_11.png new file mode 100644 index 0000000..dc94567 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_11.png differ diff --git a/Assets/Textures/kenny/Orange/texture_11.png.import b/Assets/Textures/kenny/Orange/texture_11.png.import new file mode 100644 index 0000000..eb0c21f --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://o7y5ldmo52gb" +path="res://.godot/imported/texture_11.png-0db65240315324be71fbaf9d0ba7f26f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-0db65240315324be71fbaf9d0ba7f26f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_12.png b/Assets/Textures/kenny/Orange/texture_12.png new file mode 100644 index 0000000..b730544 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_12.png differ diff --git a/Assets/Textures/kenny/Orange/texture_12.png.import b/Assets/Textures/kenny/Orange/texture_12.png.import new file mode 100644 index 0000000..6aee8c3 --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dcvo8pyt3dob2" +path="res://.godot/imported/texture_12.png-a3fe18fff68d7047e511ab031d0ed2de.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-a3fe18fff68d7047e511ab031d0ed2de.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Orange/texture_13.png b/Assets/Textures/kenny/Orange/texture_13.png new file mode 100644 index 0000000..01f4aa8 Binary files /dev/null and b/Assets/Textures/kenny/Orange/texture_13.png differ diff --git a/Assets/Textures/kenny/Orange/texture_13.png.import b/Assets/Textures/kenny/Orange/texture_13.png.import new file mode 100644 index 0000000..24c96ab --- /dev/null +++ b/Assets/Textures/kenny/Orange/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cseg1slj8ywc2" +path="res://.godot/imported/texture_13.png-54559e1053242f28de103e8bcd7b6c9a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Orange/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-54559e1053242f28de103e8bcd7b6c9a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_01.png b/Assets/Textures/kenny/Purple/texture_01.png new file mode 100644 index 0000000..d501875 Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_01.png differ diff --git a/Assets/Textures/kenny/Purple/texture_01.png.import b/Assets/Textures/kenny/Purple/texture_01.png.import new file mode 100644 index 0000000..7a36356 --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dfsldrhd5gg5j" +path.s3tc="res://.godot/imported/texture_01.png-7061b8dad3a290ac2eeb105c0380d20e.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-7061b8dad3a290ac2eeb105c0380d20e.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Purple/texture_02.png b/Assets/Textures/kenny/Purple/texture_02.png new file mode 100644 index 0000000..48a51c1 Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_02.png differ diff --git a/Assets/Textures/kenny/Purple/texture_02.png.import b/Assets/Textures/kenny/Purple/texture_02.png.import new file mode 100644 index 0000000..445cc7b --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bw5hqj0tq8yuv" +path="res://.godot/imported/texture_02.png-452946ab99e6cdaaf9f22986eba7a429.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-452946ab99e6cdaaf9f22986eba7a429.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_03.png b/Assets/Textures/kenny/Purple/texture_03.png new file mode 100644 index 0000000..5f97f24 Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_03.png differ diff --git a/Assets/Textures/kenny/Purple/texture_03.png.import b/Assets/Textures/kenny/Purple/texture_03.png.import new file mode 100644 index 0000000..49cc95b --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bb2vapfa1ypyx" +path="res://.godot/imported/texture_03.png-b41d8b2987700ea392a736376d846ca6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-b41d8b2987700ea392a736376d846ca6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_04.png b/Assets/Textures/kenny/Purple/texture_04.png new file mode 100644 index 0000000..b81951c Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_04.png differ diff --git a/Assets/Textures/kenny/Purple/texture_04.png.import b/Assets/Textures/kenny/Purple/texture_04.png.import new file mode 100644 index 0000000..e9a604f --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dpnhrn6ojgtgc" +path="res://.godot/imported/texture_04.png-90d25a46e339068806ce962b2b7011ee.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-90d25a46e339068806ce962b2b7011ee.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_05.png b/Assets/Textures/kenny/Purple/texture_05.png new file mode 100644 index 0000000..52352c8 Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_05.png differ diff --git a/Assets/Textures/kenny/Purple/texture_05.png.import b/Assets/Textures/kenny/Purple/texture_05.png.import new file mode 100644 index 0000000..e084dc1 --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://com3jlavoextm" +path="res://.godot/imported/texture_05.png-54ad07a32f1018b46ea846b4f45f5341.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-54ad07a32f1018b46ea846b4f45f5341.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_06.png b/Assets/Textures/kenny/Purple/texture_06.png new file mode 100644 index 0000000..86deeb3 Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_06.png differ diff --git a/Assets/Textures/kenny/Purple/texture_06.png.import b/Assets/Textures/kenny/Purple/texture_06.png.import new file mode 100644 index 0000000..64f2a66 --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ebbaxhn8e1xb" +path="res://.godot/imported/texture_06.png-9c0680d74e22754b24feffe370d06340.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-9c0680d74e22754b24feffe370d06340.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_07.png b/Assets/Textures/kenny/Purple/texture_07.png new file mode 100644 index 0000000..b71ce4e Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_07.png differ diff --git a/Assets/Textures/kenny/Purple/texture_07.png.import b/Assets/Textures/kenny/Purple/texture_07.png.import new file mode 100644 index 0000000..7d3a41e --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dg25hk82shhyl" +path="res://.godot/imported/texture_07.png-e09d9fb5e25f6e52305c8bb974b4af7f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-e09d9fb5e25f6e52305c8bb974b4af7f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_08.png b/Assets/Textures/kenny/Purple/texture_08.png new file mode 100644 index 0000000..470cc5c Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_08.png differ diff --git a/Assets/Textures/kenny/Purple/texture_08.png.import b/Assets/Textures/kenny/Purple/texture_08.png.import new file mode 100644 index 0000000..8e47149 --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cgi8pjwpl7t66" +path="res://.godot/imported/texture_08.png-98135aa1b06e14f0afd3ff96254f03de.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-98135aa1b06e14f0afd3ff96254f03de.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_09.png b/Assets/Textures/kenny/Purple/texture_09.png new file mode 100644 index 0000000..4a3f689 Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_09.png differ diff --git a/Assets/Textures/kenny/Purple/texture_09.png.import b/Assets/Textures/kenny/Purple/texture_09.png.import new file mode 100644 index 0000000..252bddc --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cflf2eh506won" +path="res://.godot/imported/texture_09.png-5f2a1e7e5c02f883f15f06b25b0169c4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-5f2a1e7e5c02f883f15f06b25b0169c4.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_10.png b/Assets/Textures/kenny/Purple/texture_10.png new file mode 100644 index 0000000..ab7e84b Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_10.png differ diff --git a/Assets/Textures/kenny/Purple/texture_10.png.import b/Assets/Textures/kenny/Purple/texture_10.png.import new file mode 100644 index 0000000..a488693 --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bdln2o524vva7" +path="res://.godot/imported/texture_10.png-6f727fd722909977332b5bf687299368.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-6f727fd722909977332b5bf687299368.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_11.png b/Assets/Textures/kenny/Purple/texture_11.png new file mode 100644 index 0000000..ad7bebc Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_11.png differ diff --git a/Assets/Textures/kenny/Purple/texture_11.png.import b/Assets/Textures/kenny/Purple/texture_11.png.import new file mode 100644 index 0000000..8275d30 --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bb5cuipdh77go" +path="res://.godot/imported/texture_11.png-e4fe1b32c0f967466cb17dc2ed9cd637.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-e4fe1b32c0f967466cb17dc2ed9cd637.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_12.png b/Assets/Textures/kenny/Purple/texture_12.png new file mode 100644 index 0000000..979ac5a Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_12.png differ diff --git a/Assets/Textures/kenny/Purple/texture_12.png.import b/Assets/Textures/kenny/Purple/texture_12.png.import new file mode 100644 index 0000000..8f40d19 --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cv3khmgxn7qvj" +path="res://.godot/imported/texture_12.png-95239019241f5e4e9503d6d4c208fc5b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-95239019241f5e4e9503d6d4c208fc5b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Purple/texture_13.png b/Assets/Textures/kenny/Purple/texture_13.png new file mode 100644 index 0000000..2a9df22 Binary files /dev/null and b/Assets/Textures/kenny/Purple/texture_13.png differ diff --git a/Assets/Textures/kenny/Purple/texture_13.png.import b/Assets/Textures/kenny/Purple/texture_13.png.import new file mode 100644 index 0000000..034bb72 --- /dev/null +++ b/Assets/Textures/kenny/Purple/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://clocipa51sdoa" +path="res://.godot/imported/texture_13.png-aa0eca751c61b5956056dca5d29b2d6f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Purple/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-aa0eca751c61b5956056dca5d29b2d6f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_01.png b/Assets/Textures/kenny/Red/texture_01.png new file mode 100644 index 0000000..1aaab41 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_01.png differ diff --git a/Assets/Textures/kenny/Red/texture_01.png.import b/Assets/Textures/kenny/Red/texture_01.png.import new file mode 100644 index 0000000..69eff5d --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_01.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bh16g6j32q42o" +path.s3tc="res://.godot/imported/texture_01.png-549b58ed7e30d026165be9e13d5d92bc.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-549b58ed7e30d026165be9e13d5d92bc.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Red/texture_02.png b/Assets/Textures/kenny/Red/texture_02.png new file mode 100644 index 0000000..bf1cb17 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_02.png differ diff --git a/Assets/Textures/kenny/Red/texture_02.png.import b/Assets/Textures/kenny/Red/texture_02.png.import new file mode 100644 index 0000000..cb3c161 --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://doch175dkew6l" +path="res://.godot/imported/texture_02.png-103a57fa97142313d6de55eacf864156.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-103a57fa97142313d6de55eacf864156.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_03.png b/Assets/Textures/kenny/Red/texture_03.png new file mode 100644 index 0000000..ff09c22 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_03.png differ diff --git a/Assets/Textures/kenny/Red/texture_03.png.import b/Assets/Textures/kenny/Red/texture_03.png.import new file mode 100644 index 0000000..6787857 --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_03.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dnxi4gebmhjd8" +path.s3tc="res://.godot/imported/texture_03.png-1d6eb170932a721c4b2d928f47e2311c.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-1d6eb170932a721c4b2d928f47e2311c.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Textures/kenny/Red/texture_04.png b/Assets/Textures/kenny/Red/texture_04.png new file mode 100644 index 0000000..b5b77ff Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_04.png differ diff --git a/Assets/Textures/kenny/Red/texture_04.png.import b/Assets/Textures/kenny/Red/texture_04.png.import new file mode 100644 index 0000000..3f1b616 --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bmobdvhm6lda6" +path="res://.godot/imported/texture_04.png-9b0487b31c9447ab66f4e7cb7e634efb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-9b0487b31c9447ab66f4e7cb7e634efb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_05.png b/Assets/Textures/kenny/Red/texture_05.png new file mode 100644 index 0000000..7827035 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_05.png differ diff --git a/Assets/Textures/kenny/Red/texture_05.png.import b/Assets/Textures/kenny/Red/texture_05.png.import new file mode 100644 index 0000000..46e7b48 --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://co07dkdvoptpa" +path="res://.godot/imported/texture_05.png-35b98d6db02dd2c2f2c750965353806f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-35b98d6db02dd2c2f2c750965353806f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_06.png b/Assets/Textures/kenny/Red/texture_06.png new file mode 100644 index 0000000..914a6f1 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_06.png differ diff --git a/Assets/Textures/kenny/Red/texture_06.png.import b/Assets/Textures/kenny/Red/texture_06.png.import new file mode 100644 index 0000000..cea929f --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://2hfc6ktxmmkw" +path="res://.godot/imported/texture_06.png-57d3ea73786f1597a04f69016f5e55f5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-57d3ea73786f1597a04f69016f5e55f5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_07.png b/Assets/Textures/kenny/Red/texture_07.png new file mode 100644 index 0000000..47d517b Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_07.png differ diff --git a/Assets/Textures/kenny/Red/texture_07.png.import b/Assets/Textures/kenny/Red/texture_07.png.import new file mode 100644 index 0000000..f2df5d1 --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bo5par3o6fw66" +path="res://.godot/imported/texture_07.png-c537230f7478a87f275d9f492dd05c8a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-c537230f7478a87f275d9f492dd05c8a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_08.png b/Assets/Textures/kenny/Red/texture_08.png new file mode 100644 index 0000000..07cfc41 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_08.png differ diff --git a/Assets/Textures/kenny/Red/texture_08.png.import b/Assets/Textures/kenny/Red/texture_08.png.import new file mode 100644 index 0000000..75789ba --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_08.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://62wgiaxs1wx5" +path="res://.godot/imported/texture_08.png-af6dcee1bcc58a3e1a90eb56d1a52b06.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-af6dcee1bcc58a3e1a90eb56d1a52b06.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_09.png b/Assets/Textures/kenny/Red/texture_09.png new file mode 100644 index 0000000..86d67d8 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_09.png differ diff --git a/Assets/Textures/kenny/Red/texture_09.png.import b/Assets/Textures/kenny/Red/texture_09.png.import new file mode 100644 index 0000000..bb9069e --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c2wxo7o13cob1" +path="res://.godot/imported/texture_09.png-254cb1193af53a2be6add745610771ca.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-254cb1193af53a2be6add745610771ca.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_10.png b/Assets/Textures/kenny/Red/texture_10.png new file mode 100644 index 0000000..a9266d1 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_10.png differ diff --git a/Assets/Textures/kenny/Red/texture_10.png.import b/Assets/Textures/kenny/Red/texture_10.png.import new file mode 100644 index 0000000..45a1072 --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://2lf0v3lain05" +path="res://.godot/imported/texture_10.png-b99488c8376839e9659212836a4f779a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-b99488c8376839e9659212836a4f779a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_11.png b/Assets/Textures/kenny/Red/texture_11.png new file mode 100644 index 0000000..2acc544 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_11.png differ diff --git a/Assets/Textures/kenny/Red/texture_11.png.import b/Assets/Textures/kenny/Red/texture_11.png.import new file mode 100644 index 0000000..29fff57 --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://fhlv6uvffslr" +path="res://.godot/imported/texture_11.png-d371f1ae8072c74eda0a72c5aedaeb5b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-d371f1ae8072c74eda0a72c5aedaeb5b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_12.png b/Assets/Textures/kenny/Red/texture_12.png new file mode 100644 index 0000000..7054c4d Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_12.png differ diff --git a/Assets/Textures/kenny/Red/texture_12.png.import b/Assets/Textures/kenny/Red/texture_12.png.import new file mode 100644 index 0000000..c4f56b6 --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dfje8xtld0cnm" +path="res://.godot/imported/texture_12.png-2c9c8d078c5a586bf8f5dbd6d9328fc7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-2c9c8d078c5a586bf8f5dbd6d9328fc7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Textures/kenny/Red/texture_13.png b/Assets/Textures/kenny/Red/texture_13.png new file mode 100644 index 0000000..ab8c7b9 Binary files /dev/null and b/Assets/Textures/kenny/Red/texture_13.png differ diff --git a/Assets/Textures/kenny/Red/texture_13.png.import b/Assets/Textures/kenny/Red/texture_13.png.import new file mode 100644 index 0000000..407a4d7 --- /dev/null +++ b/Assets/Textures/kenny/Red/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b8davjerh21ln" +path="res://.godot/imported/texture_13.png-8052da5f6a2ff263030f7fb8cca4efe6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Textures/kenny/Red/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-8052da5f6a2ff263030f7fb8cca4efe6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Themes/theme.tres b/Assets/Themes/theme.tres new file mode 100644 index 0000000..edbbfe8 --- /dev/null +++ b/Assets/Themes/theme.tres @@ -0,0 +1,13 @@ +[gd_resource type="Theme" load_steps=2 format=3 uid="uid://bvso6uowlb8dh"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_4rowt"] +bg_color = Color(0.18359, 0.18359, 0.18359, 1) +border_width_left = 20 +border_width_top = 20 +border_width_right = 20 +border_width_bottom = 20 +border_color = Color(0, 0, 0, 1) + +[resource] +HeaderLarge/font_sizes/font_size = 28 +PanelContainer/styles/panel = SubResource("StyleBoxFlat_4rowt") diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9c0ef87 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Kirill Ivanov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Scenes/Chat/ChatMenu.tscn b/Scenes/Chat/ChatMenu.tscn new file mode 100644 index 0000000..ca9888a --- /dev/null +++ b/Scenes/Chat/ChatMenu.tscn @@ -0,0 +1,60 @@ +[gd_scene load_steps=2 format=3 uid="uid://dtpqexue3vgl6"] + +[ext_resource type="Script" uid="uid://c8k0usfm5rdm3" path="res://Scripts/Chat/chat_menu.gd" id="1_8p1r2"] + +[node name="ChatMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = 298.0 +offset_right = -852.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 8 +script = ExtResource("1_8p1r2") + +[node name="AspectRatioContainer" type="AspectRatioContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="MarginContainer" type="MarginContainer" parent="AspectRatioContainer"] +custom_minimum_size = Vector2(200, 0) +layout_mode = 2 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 10 +theme_override_constants/margin_right = 10 +theme_override_constants/margin_bottom = 10 + +[node name="VBoxContainer" type="VBoxContainer" parent="AspectRatioContainer/MarginContainer"] +layout_mode = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="AspectRatioContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +follow_focus = true +horizontal_scroll_mode = 0 + +[node name="MessageContainer" type="VBoxContainer" parent="AspectRatioContainer/MarginContainer/VBoxContainer/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 10 + +[node name="Label" type="Label" parent="AspectRatioContainer/MarginContainer/VBoxContainer/ScrollContainer/MessageContainer"] +layout_mode = 2 + +[node name="CommandScrollContainer" type="ScrollContainer" parent="AspectRatioContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +vertical_scroll_mode = 0 + +[node name="CommandTextEdit" type="TextEdit" parent="AspectRatioContainer/MarginContainer/VBoxContainer/CommandScrollContainer"] +custom_minimum_size = Vector2(0, 35) +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="VisibleTimer" type="Timer" parent="."] +wait_time = 5.0 diff --git a/Scenes/Items/goblet.tscn b/Scenes/Items/goblet.tscn new file mode 100644 index 0000000..f321721 --- /dev/null +++ b/Scenes/Items/goblet.tscn @@ -0,0 +1,80 @@ +[gd_scene load_steps=12 format=3 uid="uid://cfsot3wc41tx"] + +[ext_resource type="Script" uid="uid://bntxwxn6ns5l0" path="res://Scripts/Items/goblet.gd" id="1_ihtnh"] +[ext_resource type="Script" uid="uid://ctwdmnqaxkty" path="res://Scripts/Resources/item.gd" id="2_ihtnh"] +[ext_resource type="Texture2D" uid="uid://1eu6ubigu64i" path="res://Assets/Textures/kenny/Orange/texture_01.png" id="3_ihtnh"] +[ext_resource type="Script" uid="uid://bahmrqvs4pafg" path="res://Scripts/Items/interactable.gd" id="4_ajay6"] +[ext_resource type="Shader" uid="uid://c0chn7ll6p7yk" path="res://Assets/Shaders/outline.gdshader" id="4_lowgp"] + +[sub_resource type="Resource" id="Resource_lowgp"] +script = ExtResource("2_ihtnh") +value = 100 +name = "Golden Goblet" +weight = 10 +primary_objective = true +secondary_objective = false +metadata/_custom_type_script = "uid://ctwdmnqaxkty" + +[sub_resource type="BoxMesh" id="BoxMesh_lowgp"] +size = Vector3(0.25, 1, 0.25) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ajay6"] +albedo_texture = ExtResource("3_ihtnh") +uv1_triplanar = true + +[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_ihtnh"] +points = PackedVector3Array(-0.125, -0.5, -0.125, -0.125, -0.5, 0.125, -0.125, 0.5, -0.125, 0.125, -0.5, -0.125, 0.125, -0.5, 0.125, -0.125, 0.5, 0.125, 0.125, 0.5, -0.125, 0.125, 0.5, 0.125) + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_ajay6"] +render_priority = 0 +shader = ExtResource("4_lowgp") +shader_parameter/normal_threshold = 1.5 +shader_parameter/depth_threshold = 0.05 +shader_parameter/depth_artifact_correction_coef = 2.0 +shader_parameter/outline_color = Color(0.882353, 0.882353, 0.882353, 1) + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_ajay6"] +properties/0/path = NodePath(".:position") +properties/0/spawn = true +properties/0/replication_mode = 1 +properties/1/path = NodePath(".:rotation") +properties/1/spawn = true +properties/1/replication_mode = 1 +properties/2/path = NodePath(".:visible") +properties/2/spawn = true +properties/2/replication_mode = 1 +properties/3/path = NodePath(".:collision_layer") +properties/3/spawn = true +properties/3/replication_mode = 1 +properties/4/path = NodePath(".:freeze") +properties/4/spawn = true +properties/4/replication_mode = 1 + +[node name="Goblet" type="RigidBody3D"] +collision_layer = 2 +collision_mask = 3 +continuous_cd = true +script = ExtResource("1_ihtnh") +item = SubResource("Resource_lowgp") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +mesh = SubResource("BoxMesh_lowgp") +surface_material_override/0 = SubResource("StandardMaterial3D_ajay6") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +shape = SubResource("ConvexPolygonShape3D_ihtnh") + +[node name="Interactable" type="Node3D" parent="."] +script = ExtResource("4_ajay6") + +[node name="outline" type="MeshInstance3D" parent="Interactable"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +visible = false +mesh = SubResource("BoxMesh_lowgp") +skeleton = NodePath("../..") +surface_material_override/0 = SubResource("ShaderMaterial_ajay6") + +[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] +replication_config = SubResource("SceneReplicationConfig_ajay6") diff --git a/Scenes/Lobby.tscn b/Scenes/Lobby.tscn new file mode 100644 index 0000000..e44e8e9 --- /dev/null +++ b/Scenes/Lobby.tscn @@ -0,0 +1,59 @@ +[gd_scene load_steps=5 format=3 uid="uid://x4ohd5qj3xpy"] + +[ext_resource type="Texture2D" uid="uid://youvyib1feqp" path="res://Assets/Textures/kenny/Dark/texture_02.png" id="1_bpe3w"] +[ext_resource type="Script" uid="uid://cdc5npqxn0eda" path="res://Scripts/Level/lobby.gd" id="1_lolwk"] +[ext_resource type="PackedScene" uid="uid://cfsot3wc41tx" path="res://Scenes/Items/goblet.tscn" id="3_wgubu"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8j60k"] +albedo_texture = ExtResource("1_bpe3w") +uv1_triplanar = true + +[node name="Lobby" type="Node3D"] +script = ExtResource("1_lolwk") + +[node name="Terrain" type="Node3D" parent="."] + +[node name="Floor" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.25, 0) +material_override = SubResource("StandardMaterial3D_8j60k") +use_collision = true +size = Vector3(25, 0.5, 25) + +[node name="Wall1" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 13) +material_override = SubResource("StandardMaterial3D_8j60k") +use_collision = true +size = Vector3(27, 3, 1) + +[node name="Wall2" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -13) +material_override = SubResource("StandardMaterial3D_8j60k") +use_collision = true +size = Vector3(27, 3, 1) + +[node name="Wall3" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13, 1, 0) +material_override = SubResource("StandardMaterial3D_8j60k") +use_collision = true +size = Vector3(1, 3, 25) + +[node name="Wall4" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13, 1, 0) +material_override = SubResource("StandardMaterial3D_8j60k") +use_collision = true +size = Vector3(1, 3, 25) + +[node name="spawnpoint1" type="Marker3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.06025, 9.57144) + +[node name="spawnpoint2" type="Marker3D" parent="."] +transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 1.75494, -11.1718) + +[node name="spawnpoint3" type="Marker3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.3942, 1.59, -0.787676) + +[node name="spawnpoint4" type="Marker3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.92384, 1.69536, -1.57535) + +[node name="Goblet" parent="." instance=ExtResource("3_wgubu")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.07599, 2, 0) diff --git a/Scenes/Menu/InventoryMenu.tscn b/Scenes/Menu/InventoryMenu.tscn new file mode 100644 index 0000000..cd5e04d --- /dev/null +++ b/Scenes/Menu/InventoryMenu.tscn @@ -0,0 +1,58 @@ +[gd_scene load_steps=5 format=3 uid="uid://01ujg1e7atlb"] + +[ext_resource type="Script" uid="uid://ddwvtegkiite7" path="res://Scripts/Menu/inventory_menu.gd" id="1_iulmg"] +[ext_resource type="Theme" uid="uid://bvso6uowlb8dh" path="res://Assets/Themes/theme.tres" id="1_r3ydb"] +[ext_resource type="PackedScene" uid="uid://bnpbkpr5ref6k" path="res://Scenes/Menu/InventoryUiItem.tscn" id="2_o58an"] + +[sub_resource type="Theme" id="Theme_r3ydb"] + +[node name="InventoryMenu" type="Node"] +script = ExtResource("1_iulmg") + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="Panel" type="Panel" parent="CanvasLayer"] +offset_left = 241.0 +offset_top = 146.0 +offset_right = 241.0 +offset_bottom = 146.0 + +[node name="PanelContainer" type="PanelContainer" parent="CanvasLayer"] +offset_left = 159.0 +offset_top = 94.0 +offset_right = 1042.0 +offset_bottom = 578.0 +theme = ExtResource("1_r3ydb") + +[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/PanelContainer"] +layout_mode = 2 + +[node name="Title" type="Label" parent="CanvasLayer/PanelContainer/VBoxContainer"] +layout_mode = 2 +theme = SubResource("Theme_r3ydb") +theme_type_variation = &"HeaderLarge" +text = "Inventory" +horizontal_alignment = 1 + +[node name="MarginContainer" type="MarginContainer" parent="CanvasLayer/PanelContainer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 + +[node name="ScrollContainer" type="ScrollContainer" parent="CanvasLayer/PanelContainer/VBoxContainer/MarginContainer"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/PanelContainer/VBoxContainer/MarginContainer/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ItemHeader" parent="CanvasLayer/PanelContainer/VBoxContainer/MarginContainer/ScrollContainer/VBoxContainer" instance=ExtResource("2_o58an")] +layout_mode = 2 + +[node name="CloseButton" type="Button" parent="CanvasLayer/PanelContainer/VBoxContainer"] +layout_mode = 2 +text = "Close +" diff --git a/Scenes/Menu/InventoryUiItem.tscn b/Scenes/Menu/InventoryUiItem.tscn new file mode 100644 index 0000000..76e9ac7 --- /dev/null +++ b/Scenes/Menu/InventoryUiItem.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=2 format=3 uid="uid://bnpbkpr5ref6k"] + +[ext_resource type="Script" uid="uid://bv3glh0xi771m" path="res://Scripts/Menu/inventory_ui_item.gd" id="1_ahd61"] + +[node name="ItemHeader" type="HBoxContainer"] +size_flags_vertical = 0 +script = ExtResource("1_ahd61") + +[node name="Icon" type="Label" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Icon" + +[node name="Name" type="Label" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 5.0 +text = "Name" + +[node name="Value" type="Label" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Value" + +[node name="Weight" type="Label" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Weight" diff --git a/Scenes/Menu/LobbyMenu.tscn b/Scenes/Menu/LobbyMenu.tscn new file mode 100644 index 0000000..268c809 --- /dev/null +++ b/Scenes/Menu/LobbyMenu.tscn @@ -0,0 +1,137 @@ +[gd_scene load_steps=3 format=3 uid="uid://dt1v3f2oc7vbw"] + +[ext_resource type="Script" uid="uid://b2pee67ics25u" path="res://Scripts/Menu/lobby_menu.gd" id="1_4ga1p"] +[ext_resource type="Theme" uid="uid://bvso6uowlb8dh" path="res://Assets/Themes/theme.tres" id="2_oc7xs"] + +[node name="LobbyMenu" type="Control"] +process_mode = 3 +z_index = 1 +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 6 +size_flags_vertical = 6 +script = ExtResource("1_4ga1p") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 20 + +[node name="LobbyLabel" type="Label" parent="VBoxContainer/HBoxContainer"] +layout_mode = 2 +text = "Lobby" + +[node name="SteamLobbyIdButton" type="Button" parent="VBoxContainer/HBoxContainer"] +visible = false +layout_mode = 2 +text = "Copy Lobby Code" + +[node name="Disconnect" type="Button" parent="VBoxContainer/HBoxContainer"] +visible = false +layout_mode = 2 +text = "Disconnect" + +[node name="Name" type="LineEdit" parent="VBoxContainer"] +layout_mode = 2 + +[node name="TabContainer" type="TabContainer" parent="VBoxContainer"] +layout_mode = 2 +current_tab = 0 + +[node name="Steam" type="Control" parent="VBoxContainer/TabContainer"] +layout_mode = 2 +metadata/_tab_index = 0 + +[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer/TabContainer/Steam"] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 187.0 +grow_horizontal = 2 + +[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/TabContainer/Steam/PanelContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 10 +theme_override_constants/margin_right = 10 +theme_override_constants/margin_bottom = 10 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/TabContainer/Steam/PanelContainer/MarginContainer"] +layout_mode = 2 + +[node name="Address" type="LineEdit" parent="VBoxContainer/TabContainer/Steam/PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="Host" type="Button" parent="VBoxContainer/TabContainer/Steam/PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Host +" + +[node name="Join" type="Button" parent="VBoxContainer/TabContainer/Steam/PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Join +" + +[node name="ENet" type="Control" parent="VBoxContainer/TabContainer"] +visible = false +layout_mode = 2 +metadata/_tab_index = 1 + +[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer/TabContainer/ENet"] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 83.0 +grow_horizontal = 2 + +[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/TabContainer/ENet/PanelContainer"] +layout_mode = 2 +theme = ExtResource("2_oc7xs") +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/TabContainer/ENet/PanelContainer/MarginContainer"] +layout_mode = 2 + +[node name="HostToggleContainer" type="HBoxContainer" parent="VBoxContainer/TabContainer/ENet/PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 + +[node name="HostLabel" type="Label" parent="VBoxContainer/TabContainer/ENet/PanelContainer/MarginContainer/VBoxContainer/HostToggleContainer"] +layout_mode = 2 +text = "Host" + +[node name="Host" type="CheckButton" parent="VBoxContainer/TabContainer/ENet/PanelContainer/MarginContainer/VBoxContainer/HostToggleContainer"] +layout_mode = 2 + +[node name="Address" type="LineEdit" parent="VBoxContainer/TabContainer/ENet/PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +placeholder_text = "Enter IP Address to Join" + +[node name="Join" type="Button" parent="VBoxContainer/TabContainer/ENet/PanelContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +text = "Join" + +[node name="LobbyContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -40.0 +offset_top = -40.0 +grow_horizontal = 0 +grow_vertical = 0 diff --git a/Scenes/Mobs/character.tscn b/Scenes/Mobs/character.tscn new file mode 100644 index 0000000..b6b180a --- /dev/null +++ b/Scenes/Mobs/character.tscn @@ -0,0 +1,483 @@ +[gd_scene load_steps=26 format=3 uid="uid://cc1m2a1obsyn4"] + +[ext_resource type="Script" uid="uid://c1um4tmthbbpk" path="res://Scripts/fpc/character.gd" id="1_0t4e8"] +[ext_resource type="Script" uid="uid://darcj1vokaiv2" path="res://Scripts/Resources/inventory.gd" id="2_bmlhv"] +[ext_resource type="Script" uid="uid://c5g0jt1apb2al" path="res://Scripts/fpc/EditorModule.gd" id="3_v3ckk"] +[ext_resource type="Script" uid="uid://bhfftu01dsfk7" path="res://Scripts/fpc/debug.gd" id="3_x1wcc"] +[ext_resource type="PackedScene" uid="uid://01ujg1e7atlb" path="res://Scenes/Menu/InventoryMenu.tscn" id="4_8j081"] + +[sub_resource type="Resource" id="Resource_jcsm3"] +script = ExtResource("2_bmlhv") +metadata/_custom_type_script = "uid://darcj1vokaiv2" + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_kp17n"] +albedo_color = Color(0, 1, 0, 1) +clearcoat_enabled = true +clearcoat_roughness = 0.2 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_jw1de"] +material = SubResource("StandardMaterial3D_kp17n") + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_uy03j"] + +[sub_resource type="Animation" id="Animation_j8cx7"] +resource_name = "RESET" +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Mesh:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Collision:position") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Head:position") +tracks/2/interp = 2 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1.5, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Mesh:mesh:height") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [2.0] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Collision:shape:height") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [2.0] +} + +[sub_resource type="Animation" id="Animation_5ec5e"] +resource_name = "crouch" +length = 0.2 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Mesh:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 0.75, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Collision:position") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 0.75, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Head:position") +tracks/2/interp = 2 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1.5, 0), Vector3(0, 1.12508, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Mesh:mesh:height") +tracks/3/interp = 2 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [2.0, 1.5] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Collision:shape:height") +tracks/4/interp = 2 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [2.0, 1.5] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_5e5t5"] +_data = { +&"RESET": SubResource("Animation_j8cx7"), +&"crouch": SubResource("Animation_5ec5e") +} + +[sub_resource type="Animation" id="Animation_gh776"] +resource_name = "RESET" +length = 0.001 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_8ku67"] +resource_name = "sprint" +length = 2.0 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 1, 0, 1, 0), +"points": PackedFloat32Array(0.06, -0.25, 0, 0.25, -0.01, 0, 0, 0, 0, 0, -0.06, -0.25, 0.01, 0.25, 0.01, 0, 0, 0, 0, 0, 0.06, -0.25, -0.01, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0, 0, 0), +"points": PackedFloat32Array(0.05, -0.25, 0, 0.2, -0.01, 0, -0.2, 0.000186046, 0.2, 0.000186046, 0.05, -0.2, -0.01, 0.2, -0.01, 0, -0.2, 0, 0.2, 0, 0.05, -0.2, -0.01, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} + +[sub_resource type="Animation" id="Animation_lrqmv"] +resource_name = "walk" +length = 2.0 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 1, 0, 1, 0), +"points": PackedFloat32Array(0.04, -0.25, 0, 0.25, 0, 0, 0, 0, 0, 0, -0.04, -0.25, 0, 0.25, 0, 0, 0, 0, 0, 0, 0.04, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0, 0, 0), +"points": PackedFloat32Array(-0.05, -0.25, 0, 0.2, 0.005, 0, -0.2, 0.000186046, 0.2, 0.000186046, -0.05, -0.2, 0.005, 0.2, 0.005, 0, -0.2, 0, 0.2, 0, -0.05, -0.2, 0.005, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_o0unb"] +_data = { +&"RESET": SubResource("Animation_gh776"), +&"sprint": SubResource("Animation_8ku67"), +&"walk": SubResource("Animation_lrqmv") +} + +[sub_resource type="Animation" id="Animation_fvvjq"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_s07ye"] +resource_name = "jump" +length = 3.0 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.6, 3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0.0349066, 0, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_3eyjl"] +resource_name = "land_center" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, 0), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_l1rph"] +resource_name = "land_left" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, 0.0174533), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_vsknp"] +resource_name = "land_right" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, -0.0174533), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_qeg5r"] +_data = { +&"RESET": SubResource("Animation_fvvjq"), +&"jump": SubResource("Animation_s07ye"), +&"land_center": SubResource("Animation_3eyjl"), +&"land_left": SubResource("Animation_l1rph"), +&"land_right": SubResource("Animation_vsknp") +} + +[sub_resource type="Theme" id="Theme_wdf0f"] +MarginContainer/constants/margin_bottom = 10 +MarginContainer/constants/margin_left = 10 +MarginContainer/constants/margin_right = 10 +MarginContainer/constants/margin_top = 10 + +[sub_resource type="SphereShape3D" id="SphereShape3D_k4wwl"] + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_a88hh"] +properties/0/path = NodePath(".:position") +properties/0/spawn = true +properties/0/replication_mode = 1 +properties/1/path = NodePath(".:rotation") +properties/1/spawn = true +properties/1/replication_mode = 1 +properties/2/path = NodePath("Head:rotation") +properties/2/spawn = true +properties/2/replication_mode = 1 + +[node name="Character" type="CharacterBody3D" node_paths=PackedStringArray("HEAD", "CAMERA", "CAMERA_RAYCAST", "HEADBOB_ANIMATION", "JUMP_ANIMATION", "CROUCH_ANIMATION", "COLLISION_MESH")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 0, 0) +script = ExtResource("1_0t4e8") +HEAD = NodePath("Head") +CAMERA = NodePath("Head/Camera") +CAMERA_RAYCAST = NodePath("Head/Camera/CamRayCast3D") +INVENTORY = SubResource("Resource_jcsm3") +HEADBOB_ANIMATION = NodePath("Head/HeadbobAnimation") +JUMP_ANIMATION = NodePath("Head/JumpAnimation") +CROUCH_ANIMATION = NodePath("CrouchAnimation") +COLLISION_MESH = NodePath("Collision") + +[node name="Mesh" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +mesh = SubResource("CapsuleMesh_jw1de") + +[node name="Collision" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("CapsuleShape3D_uy03j") + +[node name="CrouchAnimation" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_5e5t5") +} + +[node name="Head" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0) + +[node name="Camera" type="Camera3D" parent="Head"] + +[node name="CamRayCast3D" type="RayCast3D" parent="Head/Camera"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.72772e-08, 0, -0.395256) +target_position = Vector3(0, 0, -2) +collision_mask = 3 + +[node name="HeadbobAnimation" type="AnimationPlayer" parent="Head"] +libraries = { +&"": SubResource("AnimationLibrary_o0unb") +} +blend_times = [&"RESET", &"RESET", 0.5, &"RESET", &"walk", 0.5, &"walk", &"RESET", 0.5] + +[node name="JumpAnimation" type="AnimationPlayer" parent="Head"] +libraries = { +&"": SubResource("AnimationLibrary_qeg5r") +} +speed_scale = 4.0 + +[node name="UserInterface" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 1 + +[node name="DebugPanel" type="PanelContainer" parent="UserInterface"] +visible = false +layout_mode = 0 +offset_left = 10.0 +offset_top = 10.0 +offset_right = 453.0 +offset_bottom = 50.0 +theme = SubResource("Theme_wdf0f") +script = ExtResource("3_x1wcc") + +[node name="MarginContainer" type="MarginContainer" parent="UserInterface/DebugPanel"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="UserInterface/DebugPanel/MarginContainer"] +layout_mode = 2 + +[node name="InventoryMenu" parent="UserInterface" instance=ExtResource("4_8j081")] + +[node name="CrouchCeilingDetection" type="ShapeCast3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("SphereShape3D_k4wwl") +target_position = Vector3(0, 0.5, 0) + +[node name="EditorModule" type="Node" parent="."] +script = ExtResource("3_v3ckk") + +[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] +replication_config = SubResource("SceneReplicationConfig_a88hh") diff --git a/Scenes/Server/Server.tscn b/Scenes/Server/Server.tscn new file mode 100644 index 0000000..af9547c --- /dev/null +++ b/Scenes/Server/Server.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://d1ofd327cqcd1"] + +[ext_resource type="Script" uid="uid://dwwtrox3lp2jp" path="res://scripts/server/server.gd" id="1_tov25"] + +[node name="Server" type="Node"] +script = ExtResource("1_tov25") diff --git a/Scenes/Server/ServerLobby.tscn b/Scenes/Server/ServerLobby.tscn new file mode 100644 index 0000000..f50e889 --- /dev/null +++ b/Scenes/Server/ServerLobby.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://cibp7jxet63em"] + +[ext_resource type="Script" uid="uid://dql0i4kd8813p" path="res://scripts/server/server_lobby.gd" id="1_omv2j"] + +[node name="ServerLobby" type="Node"] +script = ExtResource("1_omv2j") diff --git a/Scenes/quality-godot-first-person-2-main/.gitattributes b/Scenes/quality-godot-first-person-2-main/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/Scenes/quality-godot-first-person-2-main/.gitignore b/Scenes/quality-godot-first-person-2-main/.gitignore new file mode 100644 index 0000000..4709183 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/.gitignore @@ -0,0 +1,2 @@ +# Godot 4+ specific ignores +.godot/ diff --git a/Scenes/quality-godot-first-person-2-main/LICENSE b/Scenes/quality-godot-first-person-2-main/LICENSE new file mode 100644 index 0000000..f34733d --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Colormatic + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Scenes/quality-godot-first-person-2-main/README.md b/Scenes/quality-godot-first-person-2-main/README.md new file mode 100644 index 0000000..0acb1cb --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/README.md @@ -0,0 +1,67 @@ +# quality-godot-first-person-2 +Actually good first person controller for the Godot Engine. +MIT License (credit Colormatic Studios) + +This first person controller was made because there aren't many first person controllers for Godot, and the ones that do exist are pretty bad. +It is highly customizable and comes with many features, QOL, and clean code. + +Some parts came from StayAtHomeDev's FPS tutorial. You can find that [here](https://www.youtube.com/playlist?list=PLEHvj4yeNfeF6s-UVs5Zx5TfNYmeCiYwf). + +# Directions +Move with WASD, space to jump, shift to sprint, C to crouch. + +**FEATURES:** +- Extremely configurable +- In-air momentum +- Motion smoothing +- FOV smoothing +- Movement animations +- Crouching +- Sprinting +- 2 crosshairs/reticles, one is animated (more to come?) +- Controller/GamePad support (enabled through code, see wiki) +- In-editor tools (enable editable children to use) + +If you make a cool game with this addon, I would love to hear about it! + +# Wiki +**To start out**, you should probably remap all of the movement keys to your own control set. + +You can make this a super basic controller by just disabling everything. + +**How to add controller/GamePad support** +- In the controls export group, there is a commented section at the end that says "Uncomment this if you want full controller support". Uncomment that block. +- Make a key map for each direction (left, right, up, down) and map them to your joystick. +- Write in these keymaps in the controls section of the player settings. +- In the `handle_head_rotation` function, there is another block of commented code that says the same thing. Uncomment that too. +- You should now be able to look around with the joystick. Make sure you add the other controls to the input map. (movement, jumping, crouching, sprinting, etc.) + +**Slope/staircase:** +Credit to [roberto-urbani23](https://github.com/roberto-urbani23) +In the character inspector, you can uncheck Stop on Slope and set the max angle to 89 (for some reason, 90 will make the player stuck). Also Snap Length to 1 otherwise your character will not remain attached to stairs if you sprint while going downstairs. + +**How to change settings:** +Click on the character node and there should be settings in the "Feature Settings" group. + +**How to add animations for a mesh:** +- Create a function for your animation and attach it to `_physics_process` to call it every frame. +- Use `input_dir` as a boolean (it is actually a `Vector2`) to know if the player is walking. +- Use the `state` member variable to tell if the player is sprinting or crouching. +- Use the `is_on_floor` function to tell if the player is standing or falling. + +**How to change reticles (crosshairs):** +Change the "Default Reticle" setting to your reticle file. +During runtime: +Use the `change_reticle` function on the character. + +**How to create a new reticle:** +- Choose a reticle to base it off of. +- Open that reticle and save it as a new reticle. +- Remove the script from the reticle and create a new one. (for some reason you have to do this) +- Edit the reticle to your needs. +- Follow the "how to change reticles" directions to use it. + +**How to use the editor tools:** +- Enable editable children on the `CharacterBody` node +- Use the options in the Properties tab to change things +- These changes apply in runtime as well diff --git a/Scenes/quality-godot-first-person-2-main/addons/fpc/EditorModule.gd b/Scenes/quality-godot-first-person-2-main/addons/fpc/EditorModule.gd new file mode 100644 index 0000000..0a3a74f --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/addons/fpc/EditorModule.gd @@ -0,0 +1,49 @@ +@tool +extends Node + +# This does not effect runtime yet but will in the future. + +@export_category("Controller Editor Module") +@export_range(-360.0, 360.0, 0.01, "or_greater", "or_less") var head_y_rotation : float = 0.0: + set(new_rotation): + if HEAD: + head_y_rotation = new_rotation + HEAD.rotation.y = deg_to_rad(head_y_rotation) + update_configuration_warnings() +@export_range(-90.0, 90.0, 0.01, "or_greater", "or_less") var head_x_rotation : float = 0.0: + set(new_rotation): + if HEAD: + head_x_rotation = new_rotation + HEAD.rotation.x = deg_to_rad(head_x_rotation) + update_configuration_warnings() + +@export_group("Nodes") +@export var CHARACTER : CharacterBody3D +@export var head_path : String = "Head" # Relative to the parent node +#@export var CAMERA : Camera3D +#@export var HEADBOB_ANIMATION : AnimationPlayer +#@export var JUMP_ANIMATION : AnimationPlayer +#@export var CROUCH_ANIMATION : AnimationPlayer +#@export var COLLISION_MESH : CollisionShape3D + +@onready var HEAD = get_node("../" + head_path) + + +func _ready(): + if !Engine.is_editor_hint(): + #print("not editor") + HEAD.rotation.y = deg_to_rad(head_y_rotation) + HEAD.rotation.x = deg_to_rad(head_x_rotation) + + +func _get_configuration_warnings(): + var warnings = [] + + if head_y_rotation > 360: + warnings.append("The head rotation is greater than 360") + + if head_y_rotation < -360: + warnings.append("The head rotation is less than -360") + + # Returning an empty array gives no warnings + return warnings diff --git a/Scenes/quality-godot-first-person-2-main/addons/fpc/character.gd b/Scenes/quality-godot-first-person-2-main/addons/fpc/character.gd new file mode 100644 index 0000000..5a5f7f7 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/addons/fpc/character.gd @@ -0,0 +1,488 @@ +# COPYRIGHT Colormatic Studios +# MIT license +# Quality Godot First Person Controller v2 + + +extends CharacterBody3D + + +#region Character Export Group + +## The settings for the character's movement and feel. +@export_category("Character") +## The speed that the character moves at without crouching or sprinting. +@export var base_speed : float = 3.0 +## The speed that the character moves at when sprinting. +@export var sprint_speed : float = 6.0 +## The speed that the character moves at when crouching. +@export var crouch_speed : float = 1.0 + +## How fast the character speeds up and slows down when Motion Smoothing is on. +@export var acceleration : float = 10.0 +## How high the player jumps. +@export var jump_velocity : float = 4.5 +## How far the player turns when the mouse is moved. +@export var mouse_sensitivity : float = 0.1 +## Invert the X axis input for the camera. +@export var invert_camera_x_axis : bool = false +## Invert the Y axis input for the camera. +@export var invert_camera_y_axis : bool = false +## Whether the player can use movement inputs. Does not stop outside forces or jumping. See Jumping Enabled. +@export var immobile : bool = false +## The reticle file to import at runtime. By default are in res://addons/fpc/reticles/. Set to an empty string to remove. +@export_file var default_reticle + +#endregion + +#region Nodes Export Group + +@export_group("Nodes") +## A reference to the camera for use in the character script. This is the parent node to the camera and is rotated instead of the camera for mouse input. +@export var HEAD : Node3D +## A reference to the camera for use in the character script. +@export var CAMERA : Camera3D +## A reference to the headbob animation for use in the character script. +@export var HEADBOB_ANIMATION : AnimationPlayer +## A reference to the jump animation for use in the character script. +@export var JUMP_ANIMATION : AnimationPlayer +## A reference to the crouch animation for use in the character script. +@export var CROUCH_ANIMATION : AnimationPlayer +## A reference to the the player's collision shape for use in the character script. +@export var COLLISION_MESH : CollisionShape3D + +#endregion + +#region Controls Export Group + +# We are using UI controls because they are built into Godot Engine so they can be used right away +@export_group("Controls") +## Use the Input Map to map a mouse/keyboard input to an action and add a reference to it to this dictionary to be used in the script. +@export var controls : Dictionary = { + LEFT = "ui_left", + RIGHT = "ui_right", + FORWARD = "ui_up", + BACKWARD = "ui_down", + JUMP = "ui_accept", + CROUCH = "crouch", + SPRINT = "sprint", + PAUSE = "ui_cancel" + } +@export_subgroup("Controller Specific") +## This only affects how the camera is handled, the rest should be covered by adding controller inputs to the existing actions in the Input Map. +@export var controller_support : bool = false +## Use the Input Map to map a controller input to an action and add a reference to it to this dictionary to be used in the script. +@export var controller_controls : Dictionary = { + LOOK_LEFT = "look_left", + LOOK_RIGHT = "look_right", + LOOK_UP = "look_up", + LOOK_DOWN = "look_down" + } +## The sensitivity of the analog stick that controls camera rotation. Lower is less sensitive and higher is more sensitive. +@export_range(0.001, 1, 0.001) var look_sensitivity : float = 0.035 + +#endregion + +#region Feature Settings Export Group + +@export_group("Feature Settings") +## Enable or disable jumping. Useful for restrictive storytelling environments. +@export var jumping_enabled : bool = true +## Whether the player can move in the air or not. +@export var in_air_momentum : bool = true +## Smooths the feel of walking. +@export var motion_smoothing : bool = true +## Enables or disables sprinting. +@export var sprint_enabled : bool = true +## Toggles the sprinting state when button is pressed or requires the player to hold the button down to remain sprinting. +@export_enum("Hold to Sprint", "Toggle Sprint") var sprint_mode : int = 0 +## Enables or disables crouching. +@export var crouch_enabled : bool = true +## Toggles the crouch state when button is pressed or requires the player to hold the button down to remain crouched. +@export_enum("Hold to Crouch", "Toggle Crouch") var crouch_mode : int = 0 +## Wether sprinting should effect FOV. +@export var dynamic_fov : bool = true +## If the player holds down the jump button, should the player keep hopping. +@export var continuous_jumping : bool = true +## Enables the view bobbing animation. +@export var view_bobbing : bool = true +## Enables an immersive animation when the player jumps and hits the ground. +@export var jump_animation : bool = true +## This determines wether the player can use the pause button, not wether the game will actually pause. +@export var pausing_enabled : bool = true +## Use with caution. +@export var gravity_enabled : bool = true +## If your game changes the gravity value during gameplay, check this property to allow the player to experience the change in gravity. +@export var dynamic_gravity : bool = false + +#endregion + +#region Member Variable Initialization + +# These are variables used in this script that don't need to be exposed in the editor. +var speed : float = base_speed +var current_speed : float = 0.0 +# States: normal, crouching, sprinting +var state : String = "normal" +var low_ceiling : bool = false # This is for when the ceiling is too low and the player needs to crouch. +var was_on_floor : bool = true # Was the player on the floor last frame (for landing animation) + +# The reticle should always have a Control node as the root +var RETICLE : Control + +# Get the gravity from the project settings to be synced with RigidBody nodes +var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity") # Don't set this as a const, see the gravity section in _physics_process + +# Stores mouse input for rotating the camera in the physics process +var mouseInput : Vector2 = Vector2(0,0) + +#endregion + + + +#region Main Control Flow + +func _ready(): + #It is safe to comment this line if your game doesn't start with the mouse captured + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + + # If the controller is rotated in a certain direction for game design purposes, redirect this rotation into the head. + HEAD.rotation.y = rotation.y + rotation.y = 0 + + if default_reticle: + change_reticle(default_reticle) + + initialize_animations() + check_controls() + enter_normal_state() + + +func _process(_delta): + if pausing_enabled: + handle_pausing() + + update_debug_menu_per_frame() + + +func _physics_process(delta): # Most things happen here. + # Gravity + if dynamic_gravity: + gravity = ProjectSettings.get_setting("physics/3d/default_gravity") + if not is_on_floor() and gravity and gravity_enabled: + velocity.y -= gravity * delta + + handle_jumping() + + var input_dir = Vector2.ZERO + + if not immobile: # Immobility works by interrupting user input, so other forces can still be applied to the player + input_dir = Input.get_vector(controls.LEFT, controls.RIGHT, controls.FORWARD, controls.BACKWARD) + + handle_movement(delta, input_dir) + + handle_head_rotation() + + # The player is not able to stand up if the ceiling is too low + low_ceiling = $CrouchCeilingDetection.is_colliding() + + handle_state(input_dir) + if dynamic_fov: # This may be changed to an AnimationPlayer + update_camera_fov() + + if view_bobbing: + play_headbob_animation(input_dir) + + if jump_animation: + play_jump_animation() + + update_debug_menu_per_tick() + + was_on_floor = is_on_floor() # This must always be at the end of physics_process + +#endregion + +#region Input Handling + +func handle_jumping(): + if jumping_enabled: + if continuous_jumping: # Hold down the jump button + if Input.is_action_pressed(controls.JUMP) and is_on_floor() and !low_ceiling: + if jump_animation: + JUMP_ANIMATION.play("jump", 0.25) + velocity.y += jump_velocity # Adding instead of setting so jumping on slopes works properly + else: + if Input.is_action_just_pressed(controls.JUMP) and is_on_floor() and !low_ceiling: + if jump_animation: + JUMP_ANIMATION.play("jump", 0.25) + velocity.y += jump_velocity + + +func handle_movement(delta, input_dir): + var direction = input_dir.rotated(-HEAD.rotation.y) + direction = Vector3(direction.x, 0, direction.y) + move_and_slide() + + if in_air_momentum: + if is_on_floor(): + if motion_smoothing: + velocity.x = lerp(velocity.x, direction.x * speed, acceleration * delta) + velocity.z = lerp(velocity.z, direction.z * speed, acceleration * delta) + else: + velocity.x = direction.x * speed + velocity.z = direction.z * speed + else: + if motion_smoothing: + velocity.x = lerp(velocity.x, direction.x * speed, acceleration * delta) + velocity.z = lerp(velocity.z, direction.z * speed, acceleration * delta) + else: + velocity.x = direction.x * speed + velocity.z = direction.z * speed + + +func handle_head_rotation(): + if invert_camera_x_axis: + HEAD.rotation_degrees.y -= mouseInput.x * mouse_sensitivity * -1 + else: + HEAD.rotation_degrees.y -= mouseInput.x * mouse_sensitivity + + if invert_camera_y_axis: + HEAD.rotation_degrees.x -= mouseInput.y * mouse_sensitivity * -1 + else: + HEAD.rotation_degrees.x -= mouseInput.y * mouse_sensitivity + + if controller_support: + var controller_view_rotation = Input.get_vector(controller_controls.LOOK_DOWN, controller_controls.LOOK_UP, controller_controls.LOOK_RIGHT, controller_controls.LOOK_LEFT) * look_sensitivity # These are inverted because of the nature of 3D rotation. + if invert_camera_x_axis: + HEAD.rotation.x += controller_view_rotation.x * -1 + else: + HEAD.rotation.x += controller_view_rotation.x + + if invert_camera_y_axis: + HEAD.rotation.y += controller_view_rotation.y * -1 + else: + HEAD.rotation.y += controller_view_rotation.y + + mouseInput = Vector2(0,0) + HEAD.rotation.x = clamp(HEAD.rotation.x, deg_to_rad(-90), deg_to_rad(90)) + + +func check_controls(): # If you add a control, you might want to add a check for it here. + # The actions are being disabled so the engine doesn't halt the entire project in debug mode + if !InputMap.has_action(controls.JUMP): + push_error("No control mapped for jumping. Please add an input map control. Disabling jump.") + jumping_enabled = false + if !InputMap.has_action(controls.LEFT): + push_error("No control mapped for move left. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.RIGHT): + push_error("No control mapped for move right. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.FORWARD): + push_error("No control mapped for move forward. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.BACKWARD): + push_error("No control mapped for move backward. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.PAUSE): + push_error("No control mapped for pause. Please add an input map control. Disabling pausing.") + pausing_enabled = false + if !InputMap.has_action(controls.CROUCH): + push_error("No control mapped for crouch. Please add an input map control. Disabling crouching.") + crouch_enabled = false + if !InputMap.has_action(controls.SPRINT): + push_error("No control mapped for sprint. Please add an input map control. Disabling sprinting.") + sprint_enabled = false + +#endregion + +#region State Handling + +func handle_state(moving): + if sprint_enabled: + if sprint_mode == 0: + if Input.is_action_pressed(controls.SPRINT) and state != "crouching": + if moving: + if state != "sprinting": + enter_sprint_state() + else: + if state == "sprinting": + enter_normal_state() + elif state == "sprinting": + enter_normal_state() + elif sprint_mode == 1: + if moving: + # If the player is holding sprint before moving, handle that scenario + if Input.is_action_pressed(controls.SPRINT) and state == "normal": + enter_sprint_state() + if Input.is_action_just_pressed(controls.SPRINT): + match state: + "normal": + enter_sprint_state() + "sprinting": + enter_normal_state() + elif state == "sprinting": + enter_normal_state() + + if crouch_enabled: + if crouch_mode == 0: + if Input.is_action_pressed(controls.CROUCH) and state != "sprinting": + if state != "crouching": + enter_crouch_state() + elif state == "crouching" and !$CrouchCeilingDetection.is_colliding(): + enter_normal_state() + elif crouch_mode == 1: + if Input.is_action_just_pressed(controls.CROUCH): + match state: + "normal": + enter_crouch_state() + "crouching": + if !$CrouchCeilingDetection.is_colliding(): + enter_normal_state() + + +# Any enter state function should only be called once when you want to enter that state, not every frame. +func enter_normal_state(): + #print("entering normal state") + var prev_state = state + if prev_state == "crouching": + CROUCH_ANIMATION.play_backwards("crouch") + state = "normal" + speed = base_speed + +func enter_crouch_state(): + #print("entering crouch state") + state = "crouching" + speed = crouch_speed + CROUCH_ANIMATION.play("crouch") + +func enter_sprint_state(): + #print("entering sprint state") + var prev_state = state + if prev_state == "crouching": + CROUCH_ANIMATION.play_backwards("crouch") + state = "sprinting" + speed = sprint_speed + +#endregion + +#region Animation Handling + +func initialize_animations(): + # Reset the camera position + # If you want to change the default head height, change these animations. + HEADBOB_ANIMATION.play("RESET") + JUMP_ANIMATION.play("RESET") + CROUCH_ANIMATION.play("RESET") + +func play_headbob_animation(moving): + if moving and is_on_floor(): + var use_headbob_animation : String + match state: + "normal","crouching": + use_headbob_animation = "walk" + "sprinting": + use_headbob_animation = "sprint" + + var was_playing : bool = false + if HEADBOB_ANIMATION.current_animation == use_headbob_animation: + was_playing = true + + HEADBOB_ANIMATION.play(use_headbob_animation, 0.25) + HEADBOB_ANIMATION.speed_scale = (current_speed / base_speed) * 1.75 + if !was_playing: + HEADBOB_ANIMATION.seek(float(randi() % 2)) # Randomize the initial headbob direction + # Let me explain that piece of code because it looks like it does the opposite of what it actually does. + # The headbob animation has two starting positions. One is at 0 and the other is at 1. + # randi() % 2 returns either 0 or 1, and so the animation randomly starts at one of the starting positions. + # This code is extremely performant but it makes no sense. + + else: + if HEADBOB_ANIMATION.current_animation == "sprint" or HEADBOB_ANIMATION.current_animation == "walk": + HEADBOB_ANIMATION.speed_scale = 1 + HEADBOB_ANIMATION.play("RESET", 1) + +func play_jump_animation(): + if !was_on_floor and is_on_floor(): # The player just landed + var facing_direction : Vector3 = CAMERA.get_global_transform().basis.x + var facing_direction_2D : Vector2 = Vector2(facing_direction.x, facing_direction.z).normalized() + var velocity_2D : Vector2 = Vector2(velocity.x, velocity.z).normalized() + + # Compares velocity direction against the camera direction (via dot product) to determine which landing animation to play. + var side_landed : int = round(velocity_2D.dot(facing_direction_2D)) + + if side_landed > 0: + JUMP_ANIMATION.play("land_right", 0.25) + elif side_landed < 0: + JUMP_ANIMATION.play("land_left", 0.25) + else: + JUMP_ANIMATION.play("land_center", 0.25) + +#endregion + +#region Debug Menu + +func update_debug_menu_per_frame(): + $UserInterface/DebugPanel.add_property("FPS", Performance.get_monitor(Performance.TIME_FPS), 0) + var status : String = state + if !is_on_floor(): + status += " in the air" + $UserInterface/DebugPanel.add_property("State", status, 4) + + +func update_debug_menu_per_tick(): + # Big thanks to github.com/LorenzoAncora for the concept of the improved debug values + current_speed = Vector3.ZERO.distance_to(get_real_velocity()) + $UserInterface/DebugPanel.add_property("Speed", snappedf(current_speed, 0.001), 1) + $UserInterface/DebugPanel.add_property("Target speed", speed, 2) + var cv : Vector3 = get_real_velocity() + var vd : Array[float] = [ + snappedf(cv.x, 0.001), + snappedf(cv.y, 0.001), + snappedf(cv.z, 0.001) + ] + var readable_velocity : String = "X: " + str(vd[0]) + " Y: " + str(vd[1]) + " Z: " + str(vd[2]) + $UserInterface/DebugPanel.add_property("Velocity", readable_velocity, 3) + + +func _unhandled_input(event : InputEvent): + if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + mouseInput.x += event.relative.x + mouseInput.y += event.relative.y + # Toggle debug menu + elif event is InputEventKey: + if event.is_released(): + # Where we're going, we don't need InputMap + if event.keycode == 4194338: # F7 + $UserInterface/DebugPanel.visible = !$UserInterface/DebugPanel.visible + +#endregion + +#region Misc Functions + +func change_reticle(reticle): # Yup, this function is kinda strange + if RETICLE: + RETICLE.queue_free() + + RETICLE = load(reticle).instantiate() + RETICLE.character = self + $UserInterface.add_child(RETICLE) + + +func update_camera_fov(): + if state == "sprinting": + CAMERA.fov = lerp(CAMERA.fov, 85.0, 0.3) + else: + CAMERA.fov = lerp(CAMERA.fov, 75.0, 0.3) + +func handle_pausing(): + if Input.is_action_just_pressed(controls.PAUSE): + # You may want another node to handle pausing, because this player may get paused too. + match Input.mouse_mode: + Input.MOUSE_MODE_CAPTURED: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + #get_tree().paused = false + Input.MOUSE_MODE_VISIBLE: + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + #get_tree().paused = false + +#endregion diff --git a/Scenes/quality-godot-first-person-2-main/addons/fpc/character.tscn b/Scenes/quality-godot-first-person-2-main/addons/fpc/character.tscn new file mode 100644 index 0000000..3cfd7c8 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/addons/fpc/character.tscn @@ -0,0 +1,455 @@ +[gd_scene load_steps=22 format=3 uid="uid://cc1m2a1obsyn4"] + +[ext_resource type="Script" path="res://addons/fpc/character.gd" id="1_0t4e8"] +[ext_resource type="Script" path="res://addons/fpc/EditorModule.gd" id="3_v3ckk"] +[ext_resource type="Script" path="res://addons/fpc/debug.gd" id="3_x1wcc"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_kp17n"] +albedo_color = Color(0.909804, 0.596078, 0, 1) +clearcoat_enabled = true +clearcoat_roughness = 0.2 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_jw1de"] +material = SubResource("StandardMaterial3D_kp17n") + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_uy03j"] + +[sub_resource type="Animation" id="Animation_j8cx7"] +resource_name = "RESET" +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Mesh:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Collision:position") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Head:position") +tracks/2/interp = 2 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1.5, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Mesh:mesh:height") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [2.0] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Collision:shape:height") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [2.0] +} + +[sub_resource type="Animation" id="Animation_5ec5e"] +resource_name = "crouch" +length = 0.2 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Mesh:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 0.75, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Collision:position") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 0.75, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Head:position") +tracks/2/interp = 2 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1.5, 0), Vector3(0, 1.12508, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Mesh:mesh:height") +tracks/3/interp = 2 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [2.0, 1.5] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Collision:shape:height") +tracks/4/interp = 2 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [2.0, 1.5] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_5e5t5"] +_data = { +"RESET": SubResource("Animation_j8cx7"), +"crouch": SubResource("Animation_5ec5e") +} + +[sub_resource type="Animation" id="Animation_gh776"] +resource_name = "RESET" +length = 0.001 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_8ku67"] +resource_name = "sprint" +length = 2.0 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 1, 0, 1, 0), +"points": PackedFloat32Array(0.06, -0.25, 0, 0.25, -0.01, 0, 0, 0, 0, 0, -0.06, -0.25, 0.01, 0.25, 0.01, 0, 0, 0, 0, 0, 0.06, -0.25, -0.01, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0, 0, 0), +"points": PackedFloat32Array(0.05, -0.25, 0, 0.2, -0.01, 0, -0.2, 0.000186046, 0.2, 0.000186046, 0.05, -0.2, -0.01, 0.2, -0.01, 0, -0.2, 0, 0.2, 0, 0.05, -0.2, -0.01, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} + +[sub_resource type="Animation" id="Animation_lrqmv"] +resource_name = "walk" +length = 2.0 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 1, 0, 1, 0), +"points": PackedFloat32Array(0.04, -0.25, 0, 0.25, 0, 0, 0, 0, 0, 0, -0.04, -0.25, 0, 0.25, 0, 0, 0, 0, 0, 0, 0.04, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0, 0, 0), +"points": PackedFloat32Array(-0.05, -0.25, 0, 0.2, 0.005, 0, -0.2, 0.000186046, 0.2, 0.000186046, -0.05, -0.2, 0.005, 0.2, 0.005, 0, -0.2, 0, 0.2, 0, -0.05, -0.2, 0.005, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_o0unb"] +_data = { +"RESET": SubResource("Animation_gh776"), +"sprint": SubResource("Animation_8ku67"), +"walk": SubResource("Animation_lrqmv") +} + +[sub_resource type="Animation" id="Animation_fvvjq"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_s07ye"] +resource_name = "jump" +length = 3.0 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.6, 3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0.0349066, 0, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_3eyjl"] +resource_name = "land_center" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, 0), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_l1rph"] +resource_name = "land_left" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, 0.0174533), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_vsknp"] +resource_name = "land_right" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, -0.0174533), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_qeg5r"] +_data = { +"RESET": SubResource("Animation_fvvjq"), +"jump": SubResource("Animation_s07ye"), +"land_center": SubResource("Animation_3eyjl"), +"land_left": SubResource("Animation_l1rph"), +"land_right": SubResource("Animation_vsknp") +} + +[sub_resource type="Theme" id="Theme_wdf0f"] +MarginContainer/constants/margin_bottom = 10 +MarginContainer/constants/margin_left = 10 +MarginContainer/constants/margin_right = 10 +MarginContainer/constants/margin_top = 10 + +[sub_resource type="SphereShape3D" id="SphereShape3D_k4wwl"] + +[node name="Character" type="CharacterBody3D" node_paths=PackedStringArray("HEAD", "CAMERA", "HEADBOB_ANIMATION", "JUMP_ANIMATION", "CROUCH_ANIMATION", "COLLISION_MESH")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 0, 0) +script = ExtResource("1_0t4e8") +default_reticle = "res://addons/fpc/reticles/reticle_1.tscn" +HEAD = NodePath("Head") +CAMERA = NodePath("Head/Camera") +HEADBOB_ANIMATION = NodePath("Head/HeadbobAnimation") +JUMP_ANIMATION = NodePath("Head/JumpAnimation") +CROUCH_ANIMATION = NodePath("CrouchAnimation") +COLLISION_MESH = NodePath("Collision") + +[node name="Mesh" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +mesh = SubResource("CapsuleMesh_jw1de") + +[node name="Collision" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("CapsuleShape3D_uy03j") + +[node name="CrouchAnimation" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_5e5t5") +} + +[node name="Head" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0) + +[node name="Camera" type="Camera3D" parent="Head"] + +[node name="HeadbobAnimation" type="AnimationPlayer" parent="Head"] +libraries = { +"": SubResource("AnimationLibrary_o0unb") +} +blend_times = [&"RESET", &"RESET", 0.5, &"RESET", &"walk", 0.5, &"walk", &"RESET", 0.5] + +[node name="JumpAnimation" type="AnimationPlayer" parent="Head"] +libraries = { +"": SubResource("AnimationLibrary_qeg5r") +} +speed_scale = 4.0 + +[node name="UserInterface" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 1 + +[node name="DebugPanel" type="PanelContainer" parent="UserInterface"] +visible = false +layout_mode = 0 +offset_left = 10.0 +offset_top = 10.0 +offset_right = 453.0 +offset_bottom = 50.0 +theme = SubResource("Theme_wdf0f") +script = ExtResource("3_x1wcc") + +[node name="MarginContainer" type="MarginContainer" parent="UserInterface/DebugPanel"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="UserInterface/DebugPanel/MarginContainer"] +layout_mode = 2 + +[node name="CrouchCeilingDetection" type="ShapeCast3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("SphereShape3D_k4wwl") +target_position = Vector3(0, 0.5, 0) + +[node name="EditorModule" type="Node" parent="."] +script = ExtResource("3_v3ckk") diff --git a/Scenes/quality-godot-first-person-2-main/addons/fpc/debug.gd b/Scenes/quality-godot-first-person-2-main/addons/fpc/debug.gd new file mode 100644 index 0000000..efdb7a4 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/addons/fpc/debug.gd @@ -0,0 +1,18 @@ +extends PanelContainer + + +func _process(delta): + if visible: + pass + +func add_property(title : String, value, order : int): # This can either be called once for a static property or called every frame for a dynamic property + var target + target = $MarginContainer/VBoxContainer.find_child(title, true, false) # I have no idea what true and false does here, the function should be more specific + if !target: + target = Label.new() # Debug lines are of type Label + $MarginContainer/VBoxContainer.add_child(target) + target.name = title + target.text = title + ": " + str(value) + elif visible: + target.text = title + ": " + str(value) + $MarginContainer/VBoxContainer.move_child(target, order) diff --git a/Scenes/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_0.tscn b/Scenes/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_0.tscn new file mode 100644 index 0000000..2828124 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_0.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=2 format=3 uid="uid://coqpusufa8a6k"] + +[sub_resource type="GDScript" id="GDScript_10f85"] +script/source = "extends CenterContainer + + +@export_category(\"Reticle\") +@export_group(\"Nodes\") +@export var character : CharacterBody3D + +@export_group(\"Settings\") +@export var dot_size : int = 1 +@export var dot_color : Color = Color.WHITE + + +func _process(_delta): + if visible: # If the reticle is disabled (not visible), don't bother updating it + update_reticle_settings() + +func update_reticle_settings(): + $dot.scale.x = dot_size + $dot.scale.y = dot_size + $dot.color = dot_color +" + +[node name="Reticle" type="CenterContainer"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_10f85") + +[node name="dot" type="Polygon2D" parent="."] +polygon = PackedVector2Array(-1, -1, 1, -1, 1, 1, -1, 1) diff --git a/Scenes/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_1.tscn b/Scenes/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_1.tscn new file mode 100644 index 0000000..bb83b83 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_1.tscn @@ -0,0 +1,104 @@ +[gd_scene load_steps=2 format=3 uid="uid://3mij3cjhkwsm"] + +[sub_resource type="GDScript" id="GDScript_a8kpl"] +script/source = "extends CenterContainer + + +@export_category(\"Reticle\") +@export_group(\"Nodes\") +@export var reticle_lines : Array[Line2D] +@export var character : CharacterBody3D + +@export_group(\"Animate\") +@export var animated_reticle : bool = true +@export var reticle_speed : float = 0.5 +@export var reticle_spread : float = 4.0 + +@export_group(\"Dot Settings\") +@export var dot_size : int = 1 +@export var dot_color : Color = Color.WHITE + +@export_group(\"Line Settings\") +@export var line_color : Color = Color.WHITE +@export var line_width : int = 2 +@export var line_length : int = 10 +@export var line_distance : int = 5 +@export_enum(\"None\", \"Round\") var cap_mode : int = 0 + + +func _process(_delta): + if visible: # If the reticle is disabled (not visible), don't bother updating it + update_reticle_settings() + if animated_reticle: + animate_reticle_lines() + + +func animate_reticle_lines(): + var vel = character.get_real_velocity() + var origin = Vector3(0,0,0) + var pos = Vector2(0,0) + var speed = origin.distance_to(vel) + + reticle_lines[0].position = lerp(reticle_lines[0].position, pos + Vector2(0, -speed * reticle_spread), reticle_speed) + reticle_lines[1].position = lerp(reticle_lines[1].position, pos + Vector2(-speed * reticle_spread, 0), reticle_speed) + reticle_lines[2].position = lerp(reticle_lines[2].position, pos + Vector2(speed * reticle_spread, 0), reticle_speed) + reticle_lines[3].position = lerp(reticle_lines[3].position, pos + Vector2(0, speed * reticle_spread), reticle_speed) + + +func update_reticle_settings(): + # Dot + $dot.scale.x = dot_size + $dot.scale.y = dot_size + $dot.color = dot_color + + # Lines + for line in reticle_lines: + line.default_color = line_color + line.width = line_width + if cap_mode == 0: + line.begin_cap_mode = Line2D.LINE_CAP_NONE + line.end_cap_mode = Line2D.LINE_CAP_NONE + elif cap_mode == 1: + line.begin_cap_mode = Line2D.LINE_CAP_ROUND + line.end_cap_mode = Line2D.LINE_CAP_ROUND + + # Please someone find a better way to do this + reticle_lines[0].points[0].y = -line_distance + reticle_lines[0].points[1].y = -line_length - line_distance + reticle_lines[1].points[0].x = -line_distance + reticle_lines[1].points[1].x = -line_length - line_distance + reticle_lines[2].points[0].x = line_distance + reticle_lines[2].points[1].x = line_length + line_distance + reticle_lines[3].points[0].y = line_distance + reticle_lines[3].points[1].y = line_length + line_distance +" + +[node name="Reticle" type="CenterContainer" node_paths=PackedStringArray("reticle_lines")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_a8kpl") +reticle_lines = [NodePath("top"), NodePath("left"), NodePath("right"), NodePath("bottom")] + +[node name="dot" type="Polygon2D" parent="."] +polygon = PackedVector2Array(-1, -1, 1, -1, 1, 1, -1, 1) + +[node name="top" type="Line2D" parent="."] +points = PackedVector2Array(0, -5, 0, -15) +width = 2.0 + +[node name="left" type="Line2D" parent="."] +points = PackedVector2Array(-5, 0, -15, 0) +width = 2.0 + +[node name="right" type="Line2D" parent="."] +points = PackedVector2Array(5, 0, 15, 0) +width = 2.0 + +[node name="bottom" type="Line2D" parent="."] +points = PackedVector2Array(0, 5, 0, 15) +width = 2.0 diff --git a/Scenes/quality-godot-first-person-2-main/icon.svg b/Scenes/quality-godot-first-person-2-main/icon.svg new file mode 100644 index 0000000..ea6ce87 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/icon.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Scenes/quality-godot-first-person-2-main/icon.svg.import b/Scenes/quality-godot-first-person-2-main/icon.svg.import new file mode 100644 index 0000000..9e0a681 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://64npoko7rqya" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/Scenes/quality-godot-first-person-2-main/project.godot b/Scenes/quality-godot-first-person-2-main/project.godot new file mode 100644 index 0000000..4626ad9 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/project.godot @@ -0,0 +1,65 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="first person controller 2.0" +run/main_scene="res://test_world.tscn" +config/features=PackedStringArray("4.3", "Forward Plus") +config/icon="res://icon.svg" + +[display] + +window/size/mode=2 + +[input] + +ui_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +ui_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +ui_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +ui_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} +crouch={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":99,"location":0,"echo":false,"script":null) +] +} +sprint={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} diff --git a/Scenes/quality-godot-first-person-2-main/test_world.tscn b/Scenes/quality-godot-first-person-2-main/test_world.tscn new file mode 100644 index 0000000..b6901b9 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/test_world.tscn @@ -0,0 +1,106 @@ +[gd_scene load_steps=15 format=3 uid="uid://cs4drhmc1bql5"] + +[ext_resource type="PackedScene" uid="uid://cc1m2a1obsyn4" path="res://addons/fpc/character.tscn" id="1_e18vq"] +[ext_resource type="Texture2D" uid="uid://pe7a4weirj2g" path="res://textures/dark.png" id="2_08fdt"] +[ext_resource type="Texture2D" uid="uid://cxjxvqmf4boxq" path="res://textures/green.png" id="3_q4clv"] +[ext_resource type="Texture2D" uid="uid://dsv4jm4vydflb" path="res://textures/orange.png" id="4_1ns5t"] + +[sub_resource type="PhysicalSkyMaterial" id="PhysicalSkyMaterial_edcox"] +ground_color = Color(0.160784, 0.815686, 0.905882, 1) + +[sub_resource type="Sky" id="Sky_2iust"] +sky_material = SubResource("PhysicalSkyMaterial_edcox") + +[sub_resource type="Environment" id="Environment_20rw3"] +background_mode = 2 +sky = SubResource("Sky_2iust") +tonemap_mode = 1 +ssao_enabled = true + +[sub_resource type="Gradient" id="Gradient_ur0vy"] +colors = PackedColorArray(0, 0.476245, 0.0193456, 1, 0.360494, 0.612721, 0.119744, 1) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_jd3pw"] +frequency = 0.0027 + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_7akuf"] +width = 1024 +height = 1024 +in_3d_space = true +seamless = true +color_ramp = SubResource("Gradient_ur0vy") +noise = SubResource("FastNoiseLite_jd3pw") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_67ysu"] +albedo_texture = SubResource("NoiseTexture2D_7akuf") +uv1_scale = Vector3(0.1, 0.1, 0.1) +uv1_triplanar = true + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gomnb"] +albedo_texture = ExtResource("2_08fdt") +metallic = 0.81 +metallic_specular = 0.2 +roughness = 0.5 +uv1_triplanar = true +uv1_triplanar_sharpness = 0.000850145 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_u0sbk"] +albedo_texture = ExtResource("3_q4clv") +metallic = 0.81 +metallic_specular = 0.2 +roughness = 0.5 +uv1_triplanar = true +uv1_triplanar_sharpness = 0.000850145 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_7j4uu"] +albedo_texture = ExtResource("4_1ns5t") +metallic = 0.81 +metallic_specular = 0.2 +roughness = 0.5 +uv1_triplanar = true +uv1_triplanar_sharpness = 0.000850145 + +[node name="test_world" type="Node3D"] + +[node name="Character" parent="." instance=ExtResource("1_e18vq")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_20rw3") + +[node name="sun" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.87959, -0.436605, 0.188936, 0, 0.397148, 0.917755, -0.475732, -0.807248, 0.349328, 0, 0, 0) +light_energy = 2.0 +shadow_enabled = true + +[node name="terrain" type="Node3D" parent="."] + +[node name="CSGBox3D" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -0.5, 10) +use_collision = true +size = Vector3(30, 1, 30) +material = SubResource("StandardMaterial3D_67ysu") + +[node name="CSGBox3D2" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, -10) +use_collision = true +size = Vector3(10, 1, 10) +material = SubResource("StandardMaterial3D_gomnb") + +[node name="CSGBox3D3" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 1.8, -13) +use_collision = true +size = Vector3(4, 0.5, 4) +material = SubResource("StandardMaterial3D_gomnb") + +[node name="CSGBox3D4" type="CSGBox3D" parent="terrain"] +transform = Transform3D(0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 0, 0, 1, -9.5, 1.2, -10) +use_collision = true +size = Vector3(10, 1, 10) +material = SubResource("StandardMaterial3D_u0sbk") + +[node name="CSGBox3D5" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 3, -15.5) +use_collision = true +size = Vector3(19, 8, 1) +material = SubResource("StandardMaterial3D_7j4uu") diff --git a/Scenes/quality-godot-first-person-2-main/textures/dark.png b/Scenes/quality-godot-first-person-2-main/textures/dark.png new file mode 100644 index 0000000..69be211 Binary files /dev/null and b/Scenes/quality-godot-first-person-2-main/textures/dark.png differ diff --git a/Scenes/quality-godot-first-person-2-main/textures/dark.png.import b/Scenes/quality-godot-first-person-2-main/textures/dark.png.import new file mode 100644 index 0000000..2a82a3f --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/textures/dark.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://pe7a4weirj2g" +path.s3tc="res://.godot/imported/dark.png-6d46f668c80e231a58e570df85aad257.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/dark.png" +dest_files=["res://.godot/imported/dark.png-6d46f668c80e231a58e570df85aad257.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Scenes/quality-godot-first-person-2-main/textures/green.png b/Scenes/quality-godot-first-person-2-main/textures/green.png new file mode 100644 index 0000000..7bc7cf8 Binary files /dev/null and b/Scenes/quality-godot-first-person-2-main/textures/green.png differ diff --git a/Scenes/quality-godot-first-person-2-main/textures/green.png.import b/Scenes/quality-godot-first-person-2-main/textures/green.png.import new file mode 100644 index 0000000..7c7e044 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/textures/green.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cxjxvqmf4boxq" +path.s3tc="res://.godot/imported/green.png-b4f8ddc6b00d4e627f0e027e2e1193bf.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/green.png" +dest_files=["res://.godot/imported/green.png-b4f8ddc6b00d4e627f0e027e2e1193bf.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Scenes/quality-godot-first-person-2-main/textures/orange.png b/Scenes/quality-godot-first-person-2-main/textures/orange.png new file mode 100644 index 0000000..dec5b59 Binary files /dev/null and b/Scenes/quality-godot-first-person-2-main/textures/orange.png differ diff --git a/Scenes/quality-godot-first-person-2-main/textures/orange.png.import b/Scenes/quality-godot-first-person-2-main/textures/orange.png.import new file mode 100644 index 0000000..311f8ac --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/textures/orange.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dsv4jm4vydflb" +path.s3tc="res://.godot/imported/orange.png-6785d3f8216fd22318e8ea839823715b.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/orange.png" +dest_files=["res://.godot/imported/orange.png-6785d3f8216fd22318e8ea839823715b.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/Scenes/quality-godot-first-person-2-main/textures/purple.png b/Scenes/quality-godot-first-person-2-main/textures/purple.png new file mode 100644 index 0000000..48a51c1 Binary files /dev/null and b/Scenes/quality-godot-first-person-2-main/textures/purple.png differ diff --git a/Scenes/quality-godot-first-person-2-main/textures/purple.png.import b/Scenes/quality-godot-first-person-2-main/textures/purple.png.import new file mode 100644 index 0000000..9dc0969 --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/textures/purple.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cl4kewig3pk7s" +path="res://.godot/imported/purple.png-23488e84f4f0a47488be2c78494f2155.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://textures/purple.png" +dest_files=["res://.godot/imported/purple.png-23488e84f4f0a47488be2c78494f2155.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Scenes/quality-godot-first-person-2-main/textures/red.png b/Scenes/quality-godot-first-person-2-main/textures/red.png new file mode 100644 index 0000000..bf1cb17 Binary files /dev/null and b/Scenes/quality-godot-first-person-2-main/textures/red.png differ diff --git a/Scenes/quality-godot-first-person-2-main/textures/red.png.import b/Scenes/quality-godot-first-person-2-main/textures/red.png.import new file mode 100644 index 0000000..c8c15aa --- /dev/null +++ b/Scenes/quality-godot-first-person-2-main/textures/red.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1h161t0v6hau" +path="res://.godot/imported/red.png-3cad0ca19141406d60f5fd2311159a86.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://textures/red.png" +dest_files=["res://.godot/imported/red.png-3cad0ca19141406d60f5fd2311159a86.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Scenes/reticles/reticle_0.tscn b/Scenes/reticles/reticle_0.tscn new file mode 100644 index 0000000..2828124 --- /dev/null +++ b/Scenes/reticles/reticle_0.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=2 format=3 uid="uid://coqpusufa8a6k"] + +[sub_resource type="GDScript" id="GDScript_10f85"] +script/source = "extends CenterContainer + + +@export_category(\"Reticle\") +@export_group(\"Nodes\") +@export var character : CharacterBody3D + +@export_group(\"Settings\") +@export var dot_size : int = 1 +@export var dot_color : Color = Color.WHITE + + +func _process(_delta): + if visible: # If the reticle is disabled (not visible), don't bother updating it + update_reticle_settings() + +func update_reticle_settings(): + $dot.scale.x = dot_size + $dot.scale.y = dot_size + $dot.color = dot_color +" + +[node name="Reticle" type="CenterContainer"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_10f85") + +[node name="dot" type="Polygon2D" parent="."] +polygon = PackedVector2Array(-1, -1, 1, -1, 1, 1, -1, 1) diff --git a/Scenes/reticles/reticle_1.tscn b/Scenes/reticles/reticle_1.tscn new file mode 100644 index 0000000..bb83b83 --- /dev/null +++ b/Scenes/reticles/reticle_1.tscn @@ -0,0 +1,104 @@ +[gd_scene load_steps=2 format=3 uid="uid://3mij3cjhkwsm"] + +[sub_resource type="GDScript" id="GDScript_a8kpl"] +script/source = "extends CenterContainer + + +@export_category(\"Reticle\") +@export_group(\"Nodes\") +@export var reticle_lines : Array[Line2D] +@export var character : CharacterBody3D + +@export_group(\"Animate\") +@export var animated_reticle : bool = true +@export var reticle_speed : float = 0.5 +@export var reticle_spread : float = 4.0 + +@export_group(\"Dot Settings\") +@export var dot_size : int = 1 +@export var dot_color : Color = Color.WHITE + +@export_group(\"Line Settings\") +@export var line_color : Color = Color.WHITE +@export var line_width : int = 2 +@export var line_length : int = 10 +@export var line_distance : int = 5 +@export_enum(\"None\", \"Round\") var cap_mode : int = 0 + + +func _process(_delta): + if visible: # If the reticle is disabled (not visible), don't bother updating it + update_reticle_settings() + if animated_reticle: + animate_reticle_lines() + + +func animate_reticle_lines(): + var vel = character.get_real_velocity() + var origin = Vector3(0,0,0) + var pos = Vector2(0,0) + var speed = origin.distance_to(vel) + + reticle_lines[0].position = lerp(reticle_lines[0].position, pos + Vector2(0, -speed * reticle_spread), reticle_speed) + reticle_lines[1].position = lerp(reticle_lines[1].position, pos + Vector2(-speed * reticle_spread, 0), reticle_speed) + reticle_lines[2].position = lerp(reticle_lines[2].position, pos + Vector2(speed * reticle_spread, 0), reticle_speed) + reticle_lines[3].position = lerp(reticle_lines[3].position, pos + Vector2(0, speed * reticle_spread), reticle_speed) + + +func update_reticle_settings(): + # Dot + $dot.scale.x = dot_size + $dot.scale.y = dot_size + $dot.color = dot_color + + # Lines + for line in reticle_lines: + line.default_color = line_color + line.width = line_width + if cap_mode == 0: + line.begin_cap_mode = Line2D.LINE_CAP_NONE + line.end_cap_mode = Line2D.LINE_CAP_NONE + elif cap_mode == 1: + line.begin_cap_mode = Line2D.LINE_CAP_ROUND + line.end_cap_mode = Line2D.LINE_CAP_ROUND + + # Please someone find a better way to do this + reticle_lines[0].points[0].y = -line_distance + reticle_lines[0].points[1].y = -line_length - line_distance + reticle_lines[1].points[0].x = -line_distance + reticle_lines[1].points[1].x = -line_length - line_distance + reticle_lines[2].points[0].x = line_distance + reticle_lines[2].points[1].x = line_length + line_distance + reticle_lines[3].points[0].y = line_distance + reticle_lines[3].points[1].y = line_length + line_distance +" + +[node name="Reticle" type="CenterContainer" node_paths=PackedStringArray("reticle_lines")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_a8kpl") +reticle_lines = [NodePath("top"), NodePath("left"), NodePath("right"), NodePath("bottom")] + +[node name="dot" type="Polygon2D" parent="."] +polygon = PackedVector2Array(-1, -1, 1, -1, 1, 1, -1, 1) + +[node name="top" type="Line2D" parent="."] +points = PackedVector2Array(0, -5, 0, -15) +width = 2.0 + +[node name="left" type="Line2D" parent="."] +points = PackedVector2Array(-5, 0, -15, 0) +width = 2.0 + +[node name="right" type="Line2D" parent="."] +points = PackedVector2Array(5, 0, 15, 0) +width = 2.0 + +[node name="bottom" type="Line2D" parent="."] +points = PackedVector2Array(0, 5, 0, 15) +width = 2.0 diff --git a/Scenes/town.tscn b/Scenes/town.tscn new file mode 100644 index 0000000..b5e2cb7 --- /dev/null +++ b/Scenes/town.tscn @@ -0,0 +1,47 @@ +[gd_scene load_steps=3 format=3 uid="uid://b5lihf68rflsh"] + +[ext_resource type="Texture2D" uid="uid://youvyib1feqp" path="res://Assets/Textures/kenny/Dark/texture_02.png" id="1_kswdu"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_iau6b"] +albedo_texture = ExtResource("1_kswdu") +uv1_triplanar = true + +[node name="Town" type="Node3D"] + +[node name="Terrain" type="Node3D" parent="."] + +[node name="Floor" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.25, 0) +material_override = SubResource("StandardMaterial3D_iau6b") +use_collision = true +size = Vector3(50, 0.5, 50) + +[node name="wall 1" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, 12) +material_override = SubResource("StandardMaterial3D_iau6b") +use_collision = true +size = Vector3(25, 10, 1) + +[node name="wall 2" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, -12) +material_override = SubResource("StandardMaterial3D_iau6b") +use_collision = true +size = Vector3(25, 10, 1) + +[node name="wall 3" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13, 5, 0) +material_override = SubResource("StandardMaterial3D_iau6b") +use_collision = true +size = Vector3(1, 10, 25) + +[node name="wall 4" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16, 5, 0) +material_override = SubResource("StandardMaterial3D_iau6b") +use_collision = true +size = Vector3(1, 10, 25) + +[node name="platform" type="CSGBox3D" parent="Terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 7) +material_override = SubResource("StandardMaterial3D_iau6b") +use_collision = true +size = Vector3(5, 0.5, 5) diff --git a/Scenes/world.tscn b/Scenes/world.tscn new file mode 100644 index 0000000..150a537 --- /dev/null +++ b/Scenes/world.tscn @@ -0,0 +1,56 @@ +[gd_scene load_steps=11 format=3 uid="uid://cjimt73bcja16"] + +[ext_resource type="Script" uid="uid://klp20wju1i26" path="res://Scripts/world.gd" id="1_8j60k"] +[ext_resource type="PackedScene" uid="uid://x4ohd5qj3xpy" path="res://Scenes/Lobby.tscn" id="2_5a7ea"] +[ext_resource type="PackedScene" uid="uid://dt1v3f2oc7vbw" path="res://Scenes/Menu/LobbyMenu.tscn" id="4_fo5ed"] +[ext_resource type="Script" uid="uid://bsyvwqveefopb" path="res://Scripts/Level/level.gd" id="5_5ukr8"] +[ext_resource type="PackedScene" uid="uid://d1ofd327cqcd1" path="res://Scenes/Server/Server.tscn" id="5_fo5ed"] +[ext_resource type="PackedScene" uid="uid://b5lihf68rflsh" path="res://Scenes/town.tscn" id="5_o06y3"] +[ext_resource type="PackedScene" uid="uid://dtpqexue3vgl6" path="res://Scenes/Chat/ChatMenu.tscn" id="7_k7acu"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_go701"] +sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) +ground_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) + +[sub_resource type="Sky" id="Sky_5a7ea"] +sky_material = SubResource("ProceduralSkyMaterial_go701") + +[sub_resource type="Environment" id="Environment_8j60k"] +background_mode = 2 +sky = SubResource("Sky_5a7ea") +tonemap_mode = 2 +glow_enabled = true + +[node name="World" type="Node" node_paths=PackedStringArray("lobby_menu", "server", "level")] +script = ExtResource("1_8j60k") +lobby_menu = NodePath("LobbyMenu") +server = NodePath("Server") +level = NodePath("Level") + +[node name="Server" parent="." instance=ExtResource("5_fo5ed")] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_8j60k") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) +shadow_enabled = true + +[node name="Level" type="Node" parent="." node_paths=PackedStringArray("lobby")] +script = ExtResource("5_5ukr8") +lobby = NodePath("Lobby") + +[node name="Lobby" parent="Level" instance=ExtResource("2_5a7ea")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 48.3442, -31.095, 21.7287) + +[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="Level"] +_spawnable_scenes = PackedStringArray("uid://cc1m2a1obsyn4") +spawn_path = NodePath("..") + +[node name="Town" parent="Level" instance=ExtResource("5_o06y3")] + +[node name="LobbyMenu" parent="." instance=ExtResource("4_fo5ed")] +visible = false + +[node name="ChatMenu" parent="." instance=ExtResource("7_k7acu")] +visible = false diff --git a/Scripts/Chat/chat_menu.gd b/Scripts/Chat/chat_menu.gd new file mode 100644 index 0000000..9172fed --- /dev/null +++ b/Scripts/Chat/chat_menu.gd @@ -0,0 +1,246 @@ +class_name ChatMenu +extends Control + + +#region Onready Variables + +@onready var scroll_container = $AspectRatioContainer/MarginContainer/VBoxContainer/ScrollContainer +@onready var command_text_edit = $AspectRatioContainer/MarginContainer/VBoxContainer/CommandScrollContainer/CommandTextEdit +@onready var message_container = $AspectRatioContainer/MarginContainer/VBoxContainer/ScrollContainer/MessageContainer +@onready var visible_timer = $VisibleTimer + +#endregion + + +#region Variables + +var opened : bool = false +var clear_command_text : bool = false + +#endregion + + +#region Signals + +signal chat_opened() +signal spawn_item(item_name : String, x : String, y : String, z : String) +signal lobby_move(x : String, z : String) + +#endregion + + +#region Godot Functions + +func _ready() -> void: + hide() + opened = false + command_text_edit.gui_input.connect(_command_text_edit_gui_input) + visible_timer.timeout.connect(hide) + +func _process(_delta : float): + if clear_command_text == true: + command_text_edit.text = "" + clear_command_text = false + + if opened == true: + if Input.is_action_just_pressed("pause"): + remove_focus() + visible_timer.start() + return + + if Input.is_action_just_pressed("open_chat"): + visible_timer.stop() + chat_opened.emit() + show() + focus() + + if Input.is_action_just_pressed("open_chat_as_command"): + visible_timer.stop() + command_text_edit.text = "/" + chat_opened.emit() + show() + focus() + command_text_edit.set_caret_column(1, false, 0) + +#endregion + + +#region Public Functions + +func focus(): + mouse_filter = Control.MOUSE_FILTER_STOP + opened = true + Global.in_menu = true + command_text_edit.grab_focus() + +func remove_focus(): + mouse_filter = Control.MOUSE_FILTER_IGNORE + opened = false + command_text_edit.release_focus() + Global.in_menu = false + +func send_message(message : String, keep_focus : bool, label_color : Color = Color(1, 1, 1, 1)): + visible_timer.stop() + show() + var message_label : Label = Label.new() + message_label.text = message + message_label.label_settings = LabelSettings.new() + message_label.label_settings.font_color = label_color + message_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART + message_container.add_child(message_label) + + if keep_focus == false: + remove_focus() + visible_timer.start() + + get_tree().create_timer(0.01).timeout.connect( + func() -> void: + scroll_container.scroll_vertical = scroll_container.get_v_scroll_bar().max_value + ) + +#endregion + + +#region Signal Functions + +func _command_text_edit_gui_input(event : InputEvent): + if event.is_action_pressed("chat_send"): + send_message(command_text_edit.text, false) + check_command(command_text_edit.text) + clear_command_text = true + +#endregion + + +#region "Private" Functions + +func check_command(command : String): + command.strip_edges(true, true) + + if command.begins_with("/") == false: + return + + if Global.is_admin == false: + send_message("Cannot run command without admin status", false) + return + + command = command.lstrip("/") + + # ~ SPAWN ~ # + if command.begins_with("spawn ") or command == "spawn": + command = command.lstrip("spawn ") + command = command.trim_prefix(" ") + + #get the item name and check that it exists + var item_next_space : int = command.find(" ") + if item_next_space == -1: + send_message("Spawn Syntax error, spawn command looks like `spawn x y z`", false, Color(1, 0, 0, 1)) + return + + var item_name : String = command.substr(0, item_next_space) + command = command.lstrip(item_name) + command = command.trim_prefix(" ") + + # if EntityResource.ids_by_name.has(item_name) == false: + # var entity_names = "" + # for key in EntityResource.data: + # if EntityResource.data[key].spawnable == false: + # continue + + # entity_names += EntityResource.data[key].name + " " + + # send_message("Entity: \"" + item_name + "\" was not found, cannot spawn. Entity List is: " + entity_names, false, Color(1, 0, 0, 1)) + # return + + #get x + item_next_space = command.find(" ") + if item_next_space == -1: + send_message("Spawn Syntax error, spawn command looks like `spawn x y z`", false, Color(1, 0, 0, 1)) + return + + var x_name : String = command.substr(0, item_next_space) + command = command.lstrip(x_name) + command = command.trim_prefix(" ") + + if x_name != "~" and x_name.is_valid_int() == false: + send_message("Spawn Syntax error: x value was not ~ or int", false, Color(1, 0, 0, 1)) + return + + #get y + item_next_space = command.find(" ") + if item_next_space == -1: + send_message("Spawn Syntax error, spawn command looks like `spawn x y z`", false, Color(1, 0, 0, 1)) + return + + var y_name : String = command.substr(0, item_next_space) + command = command.lstrip(y_name) + command = command.trim_prefix(" ") + + if y_name != "~" and y_name.is_valid_int() == false: + send_message("Spawn Syntax error: y value was not ~ or int", false, Color(1, 0, 0, 1)) + return + + #check z (which is what is left in command) + command = command.trim_prefix(" ") + command = command.trim_suffix(" ") + if command == "": + send_message("Spawn Syntax error, spawn command looks like `spawn x y z`", false, Color(1, 0, 0, 1)) + + if command != "~" and command.is_valid_int() == false: + send_message("Item Spawn Syntax error: z value was not ~ or int", false, Color(1, 0, 0, 1)) + return + + #call spawn item + spawn_item.emit(item_name, x_name, y_name, command) + return + + # ~ LOBBY ~ # + if command.begins_with("lobby ") or command == "lobby": + command = command.lstrip("lobby ") + command = command.trim_prefix(" ") + + #get the type name and check that it exists + var type_next_space : int = command.find(" ") + if type_next_space == -1: + send_message("Lobby Syntax error, lobby command looks like `lobby [args]`", false, Color(1, 0, 0, 1)) + return + + # ~ move ~ # + if command.begins_with("move ") or command == "move": + command = command.lstrip("move ") + command = command.trim_prefix(" ") + + #error check for if there is no position + if command == "": + send_message("Lobby Move Syntax error, lobby move command looks like `lobby move x z`", false, Color(1, 0, 0, 1)) + return + + #get x + var position_space : int = command.find(" ") + if position_space == -1: + send_message("Lobby Move Syntax error, lobby move command looks like `lobby move x z`", false, Color(1, 0, 0, 1)) + return + + var x_name : String = command.substr(0, position_space) + command = command.lstrip(x_name) + command = command.trim_prefix(" ") + + if x_name != "~" and x_name.is_valid_int() == false: + send_message("Lobby Move Syntax error: x value was not ~ or int", false, Color(1, 0, 0, 1)) + return + + #check z (which is what is left in command) + command = command.trim_prefix(" ") + command = command.trim_suffix(" ") + if command == "": + send_message("Lobby Move Syntax error, lobby move command looks like `lobby move x z`", false, Color(1, 0, 0, 1)) + + if command != "~" and command.is_valid_int() == false: + send_message("Lobby Move Syntax error: z value was not ~ or int", false, Color(1, 0, 0, 1)) + return + + #call spawn item + lobby_move.emit(x_name, command) + return + +#endregion diff --git a/Scripts/Chat/chat_menu.gd.uid b/Scripts/Chat/chat_menu.gd.uid new file mode 100644 index 0000000..3fafcc7 --- /dev/null +++ b/Scripts/Chat/chat_menu.gd.uid @@ -0,0 +1 @@ +uid://c8k0usfm5rdm3 diff --git a/Scripts/Items/goblet.gd b/Scripts/Items/goblet.gd new file mode 100644 index 0000000..a28fc86 --- /dev/null +++ b/Scripts/Items/goblet.gd @@ -0,0 +1,5 @@ +extends RigidBody3D + +@export var item : Item +@onready var interactable : Interactable = $Interactable +@onready var is_interactable : bool = true \ No newline at end of file diff --git a/Scripts/Items/goblet.gd.uid b/Scripts/Items/goblet.gd.uid new file mode 100644 index 0000000..922da1e --- /dev/null +++ b/Scripts/Items/goblet.gd.uid @@ -0,0 +1 @@ +uid://bntxwxn6ns5l0 diff --git a/Scripts/Items/interactable.gd b/Scripts/Items/interactable.gd new file mode 100644 index 0000000..eeeaf47 --- /dev/null +++ b/Scripts/Items/interactable.gd @@ -0,0 +1,5 @@ +extends Node3D + +class_name Interactable + +@onready var outline : MeshInstance3D = $outline \ No newline at end of file diff --git a/Scripts/Items/interactable.gd.uid b/Scripts/Items/interactable.gd.uid new file mode 100644 index 0000000..bd711d3 --- /dev/null +++ b/Scripts/Items/interactable.gd.uid @@ -0,0 +1 @@ +uid://bahmrqvs4pafg diff --git a/Scripts/Level/level.gd b/Scripts/Level/level.gd new file mode 100644 index 0000000..3da97c4 --- /dev/null +++ b/Scripts/Level/level.gd @@ -0,0 +1,60 @@ +class_name Level +extends Node + +var player_scene : PackedScene = preload("res://Scenes/Mobs/character.tscn") + +@export var lobby : Lobby + +var spawnid : int = 0 + +func _ready() -> void: + spawn_player.rpc_id(1, 1) + +@rpc("any_peer", "call_local") +func request_spawn_player(id : int) -> void: + #only run on the multiplayer instance + if not multiplayer.is_server(): + return + + #don't spawn an already spawned player + if get_node_or_null("Player" + str(id)) != null: + return + + spawn_player.rpc_id(1, id) + +@rpc("any_peer", "call_local") +func spawn_player(id: int) -> void: + var new_player : Player = player_scene.instantiate() + + new_player.name = "Player" + str(id) + print("Spawning ID: ", id) + add_child(new_player) + var spawn_point: Marker3D = lobby.spawnpoints[spawnid] + print(spawn_point.global_position) + new_player.teleport_player.rpc(spawn_point.global_position, spawn_point.rotation) + spawnid += 1 + +@rpc("authority", "call_local") +func remove_client_from_server(id : int) -> void: + var disconnected_player : Player = get_node("Player" + str(id)) + spawnid = 1 + remove_child.call_deferred(disconnected_player) + disconnected_player.queue_free() + +@rpc("any_peer", "call_local") +func disconnect_from_server(): + remove_players() + spawnid = 0 + # reset map + print("Disconnect: ", multiplayer.get_unique_id()) + request_spawn_player.rpc(1) + + + +func remove_players(remove_host : bool = true) -> void: + for child in get_children(): + if child is Player: + if !remove_host and child.name == "Player1": + continue + remove_child(child) + child.queue_free() diff --git a/Scripts/Level/level.gd.uid b/Scripts/Level/level.gd.uid new file mode 100644 index 0000000..c604e64 --- /dev/null +++ b/Scripts/Level/level.gd.uid @@ -0,0 +1 @@ +uid://bsyvwqveefopb diff --git a/Scripts/Level/lobby.gd b/Scripts/Level/lobby.gd new file mode 100644 index 0000000..ec7dd0a --- /dev/null +++ b/Scripts/Level/lobby.gd @@ -0,0 +1,5 @@ +class_name Lobby +extends Node3D + + +@onready var spawnpoints : Array[Marker3D] = [$spawnpoint1, $spawnpoint2, $spawnpoint3, $spawnpoint4] \ No newline at end of file diff --git a/Scripts/Level/lobby.gd.uid b/Scripts/Level/lobby.gd.uid new file mode 100644 index 0000000..1e360b7 --- /dev/null +++ b/Scripts/Level/lobby.gd.uid @@ -0,0 +1 @@ +uid://cdc5npqxn0eda diff --git a/Scripts/Menu/inventory_menu.gd b/Scripts/Menu/inventory_menu.gd new file mode 100644 index 0000000..ace3f44 --- /dev/null +++ b/Scripts/Menu/inventory_menu.gd @@ -0,0 +1,33 @@ +extends Node + +class_name InventoryMenu + + +@onready var inventory : Inventory +@onready var item_list : VBoxContainer = $CanvasLayer/PanelContainer/VBoxContainer/MarginContainer/ScrollContainer/VBoxContainer +var item_scene : PackedScene = preload("res://Scenes/Menu/InventoryUiItem.tscn") + +func _ready() -> void: + $CanvasLayer.hide() + pass + + +func toggle_inventory() -> bool: + var canvas = $CanvasLayer + if canvas.visible == true: + $CanvasLayer.hide() + return false + else: + update_inventory() + $CanvasLayer.show() + return true + +func update_inventory(): + for i in inventory.items: + var new_item = item_scene.instantiate() + # new_item.set_values(i.item.name, i.item.value, i.item.weight) + item_list.add_child(new_item) + new_item.set_values(i.item.name, 10, 10) + print(i.item.name) + print(i) + pass diff --git a/Scripts/Menu/inventory_menu.gd.uid b/Scripts/Menu/inventory_menu.gd.uid new file mode 100644 index 0000000..7c50a50 --- /dev/null +++ b/Scripts/Menu/inventory_menu.gd.uid @@ -0,0 +1 @@ +uid://ddwvtegkiite7 diff --git a/Scripts/Menu/inventory_ui_item.gd b/Scripts/Menu/inventory_ui_item.gd new file mode 100644 index 0000000..4a8cf55 --- /dev/null +++ b/Scripts/Menu/inventory_ui_item.gd @@ -0,0 +1,11 @@ +extends Node + +@onready var title : Label = $Name +@onready var value : Label = $Value +@onready var weight : Label = $Weight + + +func set_values(new_title : String, new_value : int, new_weight : int) -> void: + title.text = new_title + value.text = str(new_value) + weight.text = str(new_weight) diff --git a/Scripts/Menu/inventory_ui_item.gd.uid b/Scripts/Menu/inventory_ui_item.gd.uid new file mode 100644 index 0000000..897b78f --- /dev/null +++ b/Scripts/Menu/inventory_ui_item.gd.uid @@ -0,0 +1 @@ +uid://bv3glh0xi771m diff --git a/Scripts/Menu/lobby_menu.gd b/Scripts/Menu/lobby_menu.gd new file mode 100644 index 0000000..a2f8ece --- /dev/null +++ b/Scripts/Menu/lobby_menu.gd @@ -0,0 +1,169 @@ +class_name LobbyMenu +extends Node + + +#region Onready Variables + +@onready var lobby_container : Container = $LobbyContainer +@onready var username : LineEdit = $VBoxContainer/Name +@onready var lobby_label : Label = $VBoxContainer/HBoxContainer/LobbyLabel +@onready var steam_lobby_id_button : Button = $VBoxContainer/HBoxContainer/SteamLobbyIdButton +@onready var disconnect_button : Button = $VBoxContainer/HBoxContainer/Disconnect +@onready var tab_container : TabContainer = $VBoxContainer/TabContainer + +@onready var steam_tab : Control = $VBoxContainer/TabContainer/Steam +@onready var steam_address_entry : LineEdit = $VBoxContainer/TabContainer/Steam/PanelContainer/MarginContainer/VBoxContainer/Address +@onready var steam_host_button : Button = $VBoxContainer/TabContainer/Steam/PanelContainer/MarginContainer/VBoxContainer/Host +@onready var steam_join_button : Button = $VBoxContainer/TabContainer/Steam/PanelContainer/MarginContainer/VBoxContainer/Join + +@onready var enet_address_entry : LineEdit = $VBoxContainer/TabContainer/ENet/PanelContainer/MarginContainer/VBoxContainer/Address +@onready var enet_host_toggle : CheckButton = $VBoxContainer/TabContainer/ENet/PanelContainer/MarginContainer/VBoxContainer/HostToggleContainer/Host +@onready var enet_join_button : Button = $VBoxContainer/TabContainer/ENet/PanelContainer/MarginContainer/VBoxContainer/Join + +#endregion + + +#region Variables + +var steam_lobby_id : String = "" + +#endregion + + +#region Signals + +signal disconnect_button_pressed() + +signal steam_host_pressed(new_username : String) +signal steam_join_pressed(new_username : String) + +signal enet_host_toggled_on(new_username : String) +signal enet_host_toggled_off() +signal enet_join_pressed(new_username : String) + +#endregion + + +#region Godot Functions + +func _ready() -> void: + #set username to steam username + username.text = "username" + + disconnect_button.pressed.connect(_on_disconnet_button_pressed) + + #steam + if Global.steam_connected == true: + username.text = Steam.getPersonaName() + + steam_lobby_id_button.pressed.connect(_on_steam_lobby_id_button_pressed) + steam_host_button.pressed.connect(_on_steam_host_pressed) + steam_join_button.pressed.connect(_on_steam_join_pressed) + + #enet + enet_host_toggle.toggled.connect(_on_enet_host_toggled) + enet_join_button.pressed.connect(_on_enet_join_pressed) + + if Global.steam_connected == false: + tab_container.remove_child(steam_tab) + +#endregion + + +#region Public Functions + +func reset_visible() -> void: + steam_lobby_id_button.hide() + disconnect_button.hide() + clear_lobby_text() + username.show() + + #steam + steam_join_button.show() + steam_address_entry.show() + steam_host_button.show() + + #enet + tab_container.tabs_visible = true + tab_container.show() + enet_address_entry.show() + enet_join_button.show() + +func request_lobby_list() -> void: + for child in lobby_container.get_children(): + child.queue_free() + + Steam.requestLobbyList() + +func set_lobby_text(new_names : Array[String]) -> void: + clear_lobby_text() + + for new_name in new_names: + var name_label : Label = Label.new() + name_label.text = new_name + lobby_container.add_child(name_label) + +func clear_lobby_text() -> void: + var lobby_container_children = lobby_container.get_children() + for child in lobby_container_children: + child.free() + +func update_steam_lobby_id_button(): + steam_lobby_id_button.show() + steam_lobby_id = Global.steam_lobby_id + +#endregion + + +#region Signal Functions +func _on_disconnet_button_pressed() -> void: + disconnect_button_pressed.emit() + +func _on_steam_host_pressed() -> void: + steam_host_pressed.emit(username.text) + steam_join_button.hide() + tab_container.tabs_visible = false + steam_address_entry.hide() + steam_host_button.hide() + username.hide() + +func _on_steam_join_pressed() -> void: + Global.steam_lobby_id = steam_address_entry.text + steam_join_pressed.emit(username.text) + steam_join_button.hide() + tab_container.tabs_visible = false + steam_address_entry.hide() + steam_host_button.hide() + username.hide() + disconnect_button.show() + +func _on_enet_host_toggled(toggled_on : bool) -> void: + if toggled_on: + enet_address_entry.hide() + enet_join_button.hide() + username.hide() + enet_host_toggled_on.emit(username.text) + tab_container.tabs_visible = false + return + + tab_container.tabs_visible = true + enet_host_toggled_off.emit() + enet_address_entry.show() + enet_join_button.show() + username.show() + +func _on_enet_join_pressed() -> void: + if enet_address_entry.text.is_empty() == false: + Global.enet_address = enet_address_entry.text + + tab_container.tabs_visible = false + enet_join_pressed.emit(username.text) + enet_join_button.hide() + tab_container.hide() + username.hide() + disconnect_button.show() + +func _on_steam_lobby_id_button_pressed(): + DisplayServer.clipboard_set(steam_lobby_id) + +#endregion diff --git a/Scripts/Menu/lobby_menu.gd.uid b/Scripts/Menu/lobby_menu.gd.uid new file mode 100644 index 0000000..d4cffb8 --- /dev/null +++ b/Scripts/Menu/lobby_menu.gd.uid @@ -0,0 +1 @@ +uid://b2pee67ics25u diff --git a/Scripts/Resources/inventory.gd b/Scripts/Resources/inventory.gd new file mode 100644 index 0000000..e115b09 --- /dev/null +++ b/Scripts/Resources/inventory.gd @@ -0,0 +1,15 @@ +extends Resource + +class_name Inventory + +var items : Array[RigidBody3D] + + +func get_current_slot(index : int) -> RigidBody3D: + return items[index] + +func add_item(item : RigidBody3D) -> void: + items.append(item) + +func remove_items(item : RigidBody3D) -> void: + items.erase(item) \ No newline at end of file diff --git a/Scripts/Resources/inventory.gd.uid b/Scripts/Resources/inventory.gd.uid new file mode 100644 index 0000000..508e8fe --- /dev/null +++ b/Scripts/Resources/inventory.gd.uid @@ -0,0 +1 @@ +uid://darcj1vokaiv2 diff --git a/Scripts/Resources/item.gd b/Scripts/Resources/item.gd new file mode 100644 index 0000000..0f5557e --- /dev/null +++ b/Scripts/Resources/item.gd @@ -0,0 +1,9 @@ +extends Resource + +class_name Item + +@export var value : int +@export var name : String +@export var weight : int +@export var primary_objective : bool +@export var secondary_objective : bool diff --git a/Scripts/Resources/item.gd.uid b/Scripts/Resources/item.gd.uid new file mode 100644 index 0000000..05d2279 --- /dev/null +++ b/Scripts/Resources/item.gd.uid @@ -0,0 +1 @@ +uid://ctwdmnqaxkty diff --git a/Scripts/Server/player_data.gd b/Scripts/Server/player_data.gd new file mode 100644 index 0000000..2b89d68 --- /dev/null +++ b/Scripts/Server/player_data.gd @@ -0,0 +1,12 @@ +class_name PlayerData + +extends Resource + +@export var id : int +@export var lobby_index : int +@export var name : String + +func _init(new_id : int = -1, new_lobby_index : int = -1, new_name : String = "username"): + id = new_id + lobby_index = new_lobby_index + name = new_name \ No newline at end of file diff --git a/Scripts/Server/player_data.gd.uid b/Scripts/Server/player_data.gd.uid new file mode 100644 index 0000000..95d0899 --- /dev/null +++ b/Scripts/Server/player_data.gd.uid @@ -0,0 +1 @@ +uid://b8fojvchw16hl diff --git a/Scripts/Server/server.gd b/Scripts/Server/server.gd new file mode 100644 index 0000000..31e49c8 --- /dev/null +++ b/Scripts/Server/server.gd @@ -0,0 +1,273 @@ +class_name Server + +extends Node + + +#region Constants + +const DEFAULT_PORT = 10567 +const MAX_CLIENTS = 3 + +#endregion + + +#region Onready Variables + +# @onready var microphone : AudioStreamPlayer3D = $Microphone + +#endregion + + +#region Variables + +var players_ready : Array = [] + +var peer : MultiplayerPeer = null + +#var mic_capture : AudioEffectOpusChunked + +var lobby_id : int = -1 + +#endregion + + +#region RPC + +# @rpc("any_peer", "unreliable") +# func voice_packet_recieved(packet): +# var sender_id = multiplayer.get_remote_sender_id() + # push_opus_packet_to_player.emit(sender_id, packet) + +#endregion + + +#region Signals + +signal game_log(message : String, color : Color) + +signal server_close() + +signal client_connected_to_server() + +signal client_disconnected_from_server() + +signal remove_client_from_server(id : int) + +signal steam_lobby_created() + +# signal push_opus_packet_to_player(id : int, packet) + +#endregion + + +#region Godot Functions + +func _ready() -> void: + for argument in OS.get_cmdline_args(): + if argument == "-steam": + ready_steam() + + # ready_voip() + + #set multiplayer signals + multiplayer.peer_connected.connect(_multiplayer_peer_connected) + multiplayer.peer_disconnected.connect(_multiplayer_peer_disconnected) + multiplayer.connected_to_server.connect(_multiplayer_connected_to_server) + multiplayer.connection_failed.connect(_multiplayer_connection_failed) + multiplayer.server_disconnected.connect(_multiplayer_server_disconnected) + + + #set steam signals + if Global.steam_connected == true: + Steam.lobby_joined.connect(_steam_lobby_joined) + Steam.lobby_created.connect(_steam_lobby_created) + +func _process(_delta : float): + # process_voip() + Steam.run_callbacks() + +#endregion + + +#region Ready Functions + +func ready_steam() -> void: + var steam_response : Dictionary = Steam.steamInitEx() + Global.steam_connected = steam_response["status"] == 0 + + if Global.steam_connected == false: + get_tree().create_timer(3.0).timeout.connect( + func(): + game_log.emit("Could Not Connect To Steam", Color(1, 0, 0, 1)) + ) + +# func ready_voip() -> void: +# assert(microphone.bus == "MicrophoneBus") +# var mic_bus = AudioServer.get_bus_index("MicrophoneBus") +# mic_capture = AudioServer.get_bus_effect(mic_bus, 0) + +#endregion + + +#region Process Functions + +# func process_voip() -> void: +# if mic_capture == null: +# return + +# while mic_capture.chunk_available(): +# var packet = mic_capture.read_opus_packet(PackedByteArray()) +# mic_capture.drop_chunk() + +# if Global.voip_on == false: +# continue + +# if Global.is_multiplayer and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED: +# voice_packet_recieved.rpc(packet) + +#endregion + + +#region Default Multiplayer Functions + +func destroy_lobby() -> void: + Global.is_multiplayer = false + + multiplayer.multiplayer_peer.close() + peer = OfflineMultiplayerPeer.new() + multiplayer.multiplayer_peer = peer + + server_close.emit() + +func disconnect_client() -> void: + Global.is_multiplayer = false + + multiplayer.multiplayer_peer.close() + peer = OfflineMultiplayerPeer.new() + multiplayer.multiplayer_peer = peer + + client_disconnected_from_server.emit() + +#endregion + + +#region Enet Functions + +func enet_create_host() -> void: + #set multiplayer to true + Global.is_multiplayer = true + + #init multiplayer host + peer = ENetMultiplayerPeer.new() + (peer as ENetMultiplayerPeer).create_server(DEFAULT_PORT, MAX_CLIENTS) + multiplayer.multiplayer_peer = peer + +func enet_create_client(address : String) -> void: + #set multiplayer to true + Global.is_multiplayer = true + + #init client and wait for connection + peer = ENetMultiplayerPeer.new() + (peer as ENetMultiplayerPeer).create_client(address, DEFAULT_PORT) + multiplayer.set_multiplayer_peer(peer) + await multiplayer.connected_to_server + +#endregion + + +#region Steam Functions + +func steam_create_host() -> void: + #players[1] = PlayerData.new(1, 0, new_username) + Steam.createLobby(Steam.LOBBY_TYPE_FRIENDS_ONLY, MAX_CLIENTS) + +func steam_join_lobby(new_lobby_id : int) -> void: + Steam.joinLobby(new_lobby_id) + +func steam_create_socket(): + Global.is_multiplayer = true + + peer = SteamMultiplayerPeer.new() + peer.create_host(0) + multiplayer.set_multiplayer_peer(peer) + +func steam_connect_socket(steam_id : int) -> void: + Global.is_multiplayer = true + + peer = SteamMultiplayerPeer.new() + peer.create_client(steam_id, 0) + multiplayer.set_multiplayer_peer(peer) + +#endregion + + +#region Signal Functions + +func _multiplayer_peer_connected(_id : int): + pass + +func _multiplayer_peer_disconnected(id : int): + if multiplayer.is_server(): + game_log.emit("Player \"" + str(id) + "\" disconnected", Color(1, 0, 0, 1)) + remove_client_from_server.emit(id) + +func _multiplayer_connected_to_server() -> void: + client_connected_to_server.emit() + +func _multiplayer_connection_failed() -> void: + Global.is_multiplayer = false + peer = OfflineMultiplayerPeer.new() + multiplayer.multiplayer_peer = peer + client_disconnected_from_server.emit() + game_log.emit("Server connection failed", Color(1, 0, 0, 1)) + +func _multiplayer_server_disconnected() -> void: + Global.is_multiplayer = false + peer = OfflineMultiplayerPeer.new() + multiplayer.multiplayer_peer = peer + client_disconnected_from_server.emit() + game_log.emit("Server disconnected", Color(1, 0, 0, 1)) + +func _steam_lobby_joined(new_lobby_id : int, _permissions : int, _locked : bool, response : int) -> void: + if response == Steam.CHAT_ROOM_ENTER_RESPONSE_SUCCESS: + lobby_id = new_lobby_id + var id : int = Steam.getLobbyOwner(new_lobby_id) + if id != Steam.getSteamID(): + steam_connect_socket(id) + #player_register.rpc(username) + #players[multiplayer.get_unique_id()] = username + return + var message : String + match response: + Steam.CHAT_ROOM_ENTER_RESPONSE_DOESNT_EXIST: + message = "This lobby no longer exists." + Steam.CHAT_ROOM_ENTER_RESPONSE_NOT_ALLOWED: + message = "You don't have permission to join this lobby." + Steam.CHAT_ROOM_ENTER_RESPONSE_FULL: + message = "The lobby is now full." + Steam.CHAT_ROOM_ENTER_RESPONSE_ERROR: + message = "Response errored." + Steam.CHAT_ROOM_ENTER_RESPONSE_BANNED: + message = "You are banned from this lobby." + Steam.CHAT_ROOM_ENTER_RESPONSE_LIMITED: + message = "You cannot join due to having a limited account." + Steam.CHAT_ROOM_ENTER_RESPONSE_CLAN_DISABLED: + message = "This lobby is locked or disabled." + Steam.CHAT_ROOM_ENTER_RESPONSE_COMMUNITY_BAN: + message = "This lobby is community locked." + Steam.CHAT_ROOM_ENTER_RESPONSE_MEMBER_BLOCKED_YOU: + message = "A user in the lobby has blocked you from joining." + Steam.CHAT_ROOM_ENTER_RESPONSE_YOU_BLOCKED_MEMBER: + message = "A user you have blocked is in the lobby." + game_log.emit(message, Color(1, 0, 0, 1)) + +func _steam_lobby_created(connected: int, this_lobby_id: int) -> void: + if connected == 1: + Global.steam_lobby_id = str(this_lobby_id) + Steam.setLobbyData(this_lobby_id, "name", str(Steam.getPersonaName(), "'s test server")) + steam_create_socket() + steam_lobby_created.emit() + return + game_log.emit("Error on create lobby!", Color(1, 0, 0, 1)) + +#endregion diff --git a/Scripts/Server/server.gd.uid b/Scripts/Server/server.gd.uid new file mode 100644 index 0000000..c8949f5 --- /dev/null +++ b/Scripts/Server/server.gd.uid @@ -0,0 +1 @@ +uid://dwwtrox3lp2jp diff --git a/Scripts/Server/server_lobby.gd b/Scripts/Server/server_lobby.gd new file mode 100644 index 0000000..9d3da72 --- /dev/null +++ b/Scripts/Server/server_lobby.gd @@ -0,0 +1,71 @@ +class_name ServerLobby +extends Node + + +#region Exports + +@export var players : Dictionary[int, PlayerData] = {} + +#endregion + + +#region Variables + +var free_lobby_indexs : Array[int] = [] + +#endregion + + +#region Signals + +signal player_registered() + +#endregion + + +#region Client RPC + +@rpc("any_peer", "call_local") +func request_player_register(id: int, username) -> void: + #only run on the multiplayer instance + if not multiplayer.is_server(): + return + + player_register.rpc_id(1, id, username) + +@rpc("any_peer", "call_local") +func update_client_players(id : int, username : String) -> void: + if not players.has(id): + players[id] = PlayerData.new(id, players.size(), username) + + player_registered.emit() + +#endregion + + +#region Server RPC + +@rpc("authority", "call_local") +func player_register(id : int, username : String) -> void: + var lobby_index : int = players.size() + if free_lobby_indexs.size() != 0: + lobby_index = free_lobby_indexs.pop_front() + + players[id] = PlayerData.new(id, lobby_index, username) + + #send the entire list for clients that join later + for player_id in players: + update_client_players.rpc(player_id, players[player_id].name) + +@rpc("authority", "call_local") +func player_unregister(id) -> void: + free_lobby_indexs.append(players[id].lobby_index) + players.erase(id) + player_registered.emit() + +@rpc("authority", "call_local") +func players_clear() -> void: + players.clear() + player_registered.emit() + +#endregion diff --git a/Scripts/Server/server_lobby.gd.uid b/Scripts/Server/server_lobby.gd.uid new file mode 100644 index 0000000..f516d7a --- /dev/null +++ b/Scripts/Server/server_lobby.gd.uid @@ -0,0 +1 @@ +uid://k0xvfdmvtyrt diff --git a/Scripts/fpc/EditorModule.gd b/Scripts/fpc/EditorModule.gd new file mode 100644 index 0000000..0a3a74f --- /dev/null +++ b/Scripts/fpc/EditorModule.gd @@ -0,0 +1,49 @@ +@tool +extends Node + +# This does not effect runtime yet but will in the future. + +@export_category("Controller Editor Module") +@export_range(-360.0, 360.0, 0.01, "or_greater", "or_less") var head_y_rotation : float = 0.0: + set(new_rotation): + if HEAD: + head_y_rotation = new_rotation + HEAD.rotation.y = deg_to_rad(head_y_rotation) + update_configuration_warnings() +@export_range(-90.0, 90.0, 0.01, "or_greater", "or_less") var head_x_rotation : float = 0.0: + set(new_rotation): + if HEAD: + head_x_rotation = new_rotation + HEAD.rotation.x = deg_to_rad(head_x_rotation) + update_configuration_warnings() + +@export_group("Nodes") +@export var CHARACTER : CharacterBody3D +@export var head_path : String = "Head" # Relative to the parent node +#@export var CAMERA : Camera3D +#@export var HEADBOB_ANIMATION : AnimationPlayer +#@export var JUMP_ANIMATION : AnimationPlayer +#@export var CROUCH_ANIMATION : AnimationPlayer +#@export var COLLISION_MESH : CollisionShape3D + +@onready var HEAD = get_node("../" + head_path) + + +func _ready(): + if !Engine.is_editor_hint(): + #print("not editor") + HEAD.rotation.y = deg_to_rad(head_y_rotation) + HEAD.rotation.x = deg_to_rad(head_x_rotation) + + +func _get_configuration_warnings(): + var warnings = [] + + if head_y_rotation > 360: + warnings.append("The head rotation is greater than 360") + + if head_y_rotation < -360: + warnings.append("The head rotation is less than -360") + + # Returning an empty array gives no warnings + return warnings diff --git a/Scripts/fpc/EditorModule.gd.uid b/Scripts/fpc/EditorModule.gd.uid new file mode 100644 index 0000000..96be9c8 --- /dev/null +++ b/Scripts/fpc/EditorModule.gd.uid @@ -0,0 +1 @@ +uid://c5g0jt1apb2al diff --git a/Scripts/fpc/character.gd b/Scripts/fpc/character.gd new file mode 100644 index 0000000..c2db386 --- /dev/null +++ b/Scripts/fpc/character.gd @@ -0,0 +1,551 @@ +# COPYRIGHT Colormatic Studios +# MIT license +# Quality Godot First Person Controller v2 + +class_name Player +extends CharacterBody3D + + +#region Character Export Group + +## The settings for the character's movement and feel. +@export_category("Character") +## The speed that the character moves at without crouching or sprinting. +@export var base_speed : float = 3.0 +## The speed that the character moves at when sprinting. +@export var sprint_speed : float = 6.0 +## The speed that the character moves at when crouching. +@export var crouch_speed : float = 1.0 + +## How fast the character speeds up and slows down when Motion Smoothing is on. +@export var acceleration : float = 10.0 +## How high the player jumps. +@export var jump_velocity : float = 4.5 +## How far the player turns when the mouse is moved. +@export var mouse_sensitivity : float = 0.1 +## Invert the X axis input for the camera. +@export var invert_camera_x_axis : bool = false +## Invert the Y axis input for the camera. +@export var invert_camera_y_axis : bool = false +## Whether the player can use movement inputs. Does not stop outside forces or jumping. See Jumping Enabled. +@export var immobile : bool = false +## The reticle file to import at runtime. By default are in res://addons/fpc/reticles/. Set to an empty string to remove. +@export_file var default_reticle = "res://Scenes/reticles/reticle_1.tscn" + +#endregion + +#region Nodes Export Group + +@export_group("Nodes") +## A reference to the camera for use in the character script. This is the parent node to the camera and is rotated instead of the camera for mouse input. +@export var HEAD : Node3D +## A reference to the camera for use in the character script. +@export var CAMERA : Camera3D +# A reference to the Camera Ray Cast +@export var CAMERA_RAYCAST : RayCast3D +# current item player is looking at +@onready var HIGHLIGHTED_ITEM : RigidBody3D +# A reference to the inventory +@export var INVENTORY : Inventory +# A reference to the inventory menu +@onready var inventory_menu : InventoryMenu +## A reference to the headbob animation for use in the character script. +@export var HEADBOB_ANIMATION : AnimationPlayer +## A reference to the jump animation for use in the character script. +@export var JUMP_ANIMATION : AnimationPlayer +## A reference to the crouch animation for use in the character script. +@export var CROUCH_ANIMATION : AnimationPlayer +## A reference to the the player's collision shape for use in the character script. +@export var COLLISION_MESH : CollisionShape3D + +#endregion + +#region Controls Export Group + +# We are using UI controls because they are built into Godot Engine so they can be used right away +@export_group("Controls") +## Use the Input Map to map a mouse/keyboard input to an action and add a reference to it to this dictionary to be used in the script. +@export var controls : Dictionary = { + LEFT = "move_left", + RIGHT = "move_right", + FORWARD = "move_forward", + BACKWARD = "move_back", + JUMP = "jump", + CROUCH = "crouch", + SPRINT = "sprint", + PAUSE = "pause", + INTERACT = "interact", + INVENTORY = "inventory" + } +@export_subgroup("Controller Specific") +## This only affects how the camera is handled, the rest should be covered by adding controller inputs to the existing actions in the Input Map. +@export var controller_support : bool = false +## Use the Input Map to map a controller input to an action and add a reference to it to this dictionary to be used in the script. +@export var controller_controls : Dictionary = { + LOOK_LEFT = "look_left", + LOOK_RIGHT = "look_right", + LOOK_UP = "look_up", + LOOK_DOWN = "look_down" + } +## The sensitivity of the analog stick that controls camera rotation. Lower is less sensitive and higher is more sensitive. +@export_range(0.001, 1, 0.001) var look_sensitivity : float = 0.035 + +#endregion + +#region Feature Settings Export Group + +@export_group("Feature Settings") +## Enable or disable jumping. Useful for restrictive storytelling environments. +@export var jumping_enabled : bool = true +## Whether the player can move in the air or not. +@export var in_air_momentum : bool = true +## Smooths the feel of walking. +@export var motion_smoothing : bool = true +## Enables or disables sprinting. +@export var sprint_enabled : bool = true +## Toggles the sprinting state when button is pressed or requires the player to hold the button down to remain sprinting. +@export_enum("Hold to Sprint", "Toggle Sprint") var sprint_mode : int = 0 +## Enables or disables crouching. +@export var crouch_enabled : bool = true +## Toggles the crouch state when button is pressed or requires the player to hold the button down to remain crouched. +@export_enum("Hold to Crouch", "Toggle Crouch") var crouch_mode : int = 0 +## Wether sprinting should effect FOV. +@export var dynamic_fov : bool = true +## If the player holds down the jump button, should the player keep hopping. +@export var continuous_jumping : bool = true +## Enables the view bobbing animation. +@export var view_bobbing : bool = true +## Enables an immersive animation when the player jumps and hits the ground. +@export var jump_animation : bool = true +## This determines wether the player can use the pause button, not wether the game will actually pause. +@export var pausing_enabled : bool = true +## Use with caution. +@export var gravity_enabled : bool = true +## If your game changes the gravity value during gameplay, check this property to allow the player to experience the change in gravity. +@export var dynamic_gravity : bool = false + +#endregion + +#region Member Variable Initialization + +# These are variables used in this script that don't need to be exposed in the editor. +var speed : float = base_speed +var current_speed : float = 0.0 +# States: normal, crouching, sprinting +var state : String = "normal" +var low_ceiling : bool = false # This is for when the ceiling is too low and the player needs to crouch. +var was_on_floor : bool = true # Was the player on the floor last frame (for landing animation) + +# The reticle should always have a Control node as the root +var RETICLE : Control + +# Get the gravity from the project settings to be synced with RigidBody nodes +var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity") # Don't set this as a const, see the gravity section in _physics_process + +# Stores mouse input for rotating the camera in the physics process +var mouseInput : Vector2 = Vector2(0,0) + +#endregion + + +#region Godot Functions +func _enter_tree() -> void: + + #get the id off the player name and set authority + var new_id = name.lstrip("Player") + set_multiplayer_authority(new_id.to_int()) + +func _ready(): + #It is safe to comment this line if your game doesn't start with the mouse captured + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + + # If the controller is rotated in a certain direction for game design purposes, redirect this rotation into the head. + HEAD.rotation.y = rotation.y + rotation.y = 0 + + if default_reticle: + change_reticle(default_reticle) + + initialize_animations() + check_controls() + enter_normal_state() + if is_multiplayer_authority(): + CAMERA.current = true + inventory_menu = $UserInterface/InventoryMenu + inventory_menu.inventory = INVENTORY + +func _process(_delta): + # if pausing_enabled: + # handle_pausing() + + update_debug_menu_per_frame() + + handle_open_inventory() + + +func _physics_process(delta): # Most things happen here. + # Gravity + if dynamic_gravity: + gravity = ProjectSettings.get_setting("physics/3d/default_gravity") + if not is_on_floor() and gravity and gravity_enabled: + velocity.y -= gravity * delta + handle_jumping() + + var input_dir = Vector2.ZERO + + if not immobile && !Global.in_menu: # Immobility works by interrupting user input, so other forces can still be applied to the player + input_dir = Input.get_vector(controls.LEFT, controls.RIGHT, controls.FORWARD, controls.BACKWARD) + + handle_movement(delta, input_dir) + + handle_head_rotation() + + # The player is not able to stand up if the ceiling is too low + low_ceiling = $CrouchCeilingDetection.is_colliding() + + handle_state(input_dir) + if dynamic_fov: # This may be changed to an AnimationPlayer + update_camera_fov() + + if view_bobbing: + play_headbob_animation(input_dir) + + if jump_animation: + play_jump_animation() + handle_interact() + update_debug_menu_per_tick() + + was_on_floor = is_on_floor() # This must always be at the end of physics_process + +#endregion + +#region Server Functions + +@rpc("any_peer", "call_local") +func teleport_player(location: Vector3, new_rotation: Vector3) -> void: + if not is_multiplayer_authority(): + return + global_position = location + HEAD.rotation = new_rotation + velocity = Vector3.ZERO + + +#endregion + +#region Input Handling + +func handle_jumping(): + if jumping_enabled: + if continuous_jumping: # Hold down the jump button + if Input.is_action_pressed(controls.JUMP) and is_on_floor() and !low_ceiling and !Global.in_menu: + if jump_animation: + JUMP_ANIMATION.play("jump", 0.25) + velocity.y += jump_velocity # Adding instead of setting so jumping on slopes works properly + else: + if Input.is_action_just_pressed(controls.JUMP) and is_on_floor() and !low_ceiling and !Global.in_menu: + if jump_animation: + JUMP_ANIMATION.play("jump", 0.25) + velocity.y += jump_velocity + + +func handle_movement(delta, input_dir): + var direction = input_dir.rotated(-HEAD.rotation.y) + direction = Vector3(direction.x, 0, direction.y) + move_and_slide() + + if in_air_momentum: + if is_on_floor(): + if motion_smoothing: + velocity.x = lerp(velocity.x, direction.x * speed, acceleration * delta) + velocity.z = lerp(velocity.z, direction.z * speed, acceleration * delta) + else: + velocity.x = direction.x * speed + velocity.z = direction.z * speed + else: + if motion_smoothing: + velocity.x = lerp(velocity.x, direction.x * speed, acceleration * delta) + velocity.z = lerp(velocity.z, direction.z * speed, acceleration * delta) + else: + velocity.x = direction.x * speed + velocity.z = direction.z * speed + + +func handle_head_rotation(): + if invert_camera_x_axis: + HEAD.rotation_degrees.y -= mouseInput.x * mouse_sensitivity * -1 + else: + HEAD.rotation_degrees.y -= mouseInput.x * mouse_sensitivity + + if invert_camera_y_axis: + HEAD.rotation_degrees.x -= mouseInput.y * mouse_sensitivity * -1 + else: + HEAD.rotation_degrees.x -= mouseInput.y * mouse_sensitivity + + if controller_support: + var controller_view_rotation = Input.get_vector(controller_controls.LOOK_DOWN, controller_controls.LOOK_UP, controller_controls.LOOK_RIGHT, controller_controls.LOOK_LEFT) * look_sensitivity # These are inverted because of the nature of 3D rotation. + if invert_camera_x_axis: + HEAD.rotation.x += controller_view_rotation.x * -1 + else: + HEAD.rotation.x += controller_view_rotation.x + + if invert_camera_y_axis: + HEAD.rotation.y += controller_view_rotation.y * -1 + else: + HEAD.rotation.y += controller_view_rotation.y + + mouseInput = Vector2(0,0) + HEAD.rotation.x = clamp(HEAD.rotation.x, deg_to_rad(-90), deg_to_rad(90)) + +func handle_interact(): + if CAMERA_RAYCAST.is_colliding(): + var interactable = CAMERA_RAYCAST.get_collider() + if "interactable" in interactable: + HIGHLIGHTED_ITEM = interactable + interactable.interactable.outline.show() + if "item" in interactable: + if Input.is_action_just_pressed(controls.INTERACT): + print(CAMERA_RAYCAST.get_collider()) + var item = interactable as RigidBody3D + item.freeze = true + item.collision_layer = 0 + item.hide() + INVENTORY.add_item(item) + print("This is a item") + elif HIGHLIGHTED_ITEM != null: + HIGHLIGHTED_ITEM.get_node("Interactable").outline.hide() + HIGHLIGHTED_ITEM = null + +func check_controls(): # If you add a control, you might want to add a check for it here. + # The actions are being disabled so the engine doesn't halt the entire project in debug mode + if !InputMap.has_action(controls.JUMP): + push_error("No control mapped for jumping. Please add an input map control. Disabling jump.") + jumping_enabled = false + if !InputMap.has_action(controls.LEFT): + push_error("No control mapped for move left. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.RIGHT): + push_error("No control mapped for move right. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.FORWARD): + push_error("No control mapped for move forward. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.BACKWARD): + push_error("No control mapped for move backward. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.PAUSE): + push_error("No control mapped for pause. Please add an input map control. Disabling pausing.") + pausing_enabled = false + if !InputMap.has_action(controls.CROUCH): + push_error("No control mapped for crouch. Please add an input map control. Disabling crouching.") + crouch_enabled = false + if !InputMap.has_action(controls.SPRINT): + push_error("No control mapped for sprint. Please add an input map control. Disabling sprinting.") + sprint_enabled = false + +func handle_open_inventory(force_toggle : bool = false): + if Input.is_action_just_pressed(controls.INVENTORY) || force_toggle: + Global.inventory_showing = inventory_menu.toggle_inventory() + match Input.mouse_mode: + Input.MOUSE_MODE_CAPTURED: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + #get_tree().paused = false + Input.MOUSE_MODE_VISIBLE: + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + #get_tree().paused = false +#endregion + +#region State Handling + +func handle_state(moving): + if sprint_enabled: + if sprint_mode == 0: + if Input.is_action_pressed(controls.SPRINT) and state != "crouching": + if moving: + if state != "sprinting": + enter_sprint_state() + else: + if state == "sprinting": + enter_normal_state() + elif state == "sprinting": + enter_normal_state() + elif sprint_mode == 1: + if moving: + # If the player is holding sprint before moving, handle that scenario + if Input.is_action_pressed(controls.SPRINT) and state == "normal": + enter_sprint_state() + if Input.is_action_just_pressed(controls.SPRINT): + match state: + "normal": + enter_sprint_state() + "sprinting": + enter_normal_state() + elif state == "sprinting": + enter_normal_state() + + if crouch_enabled: + if crouch_mode == 0: + if Input.is_action_pressed(controls.CROUCH) and state != "sprinting": + if state != "crouching": + enter_crouch_state() + elif state == "crouching" and !$CrouchCeilingDetection.is_colliding(): + enter_normal_state() + elif crouch_mode == 1: + if Input.is_action_just_pressed(controls.CROUCH): + match state: + "normal": + enter_crouch_state() + "crouching": + if !$CrouchCeilingDetection.is_colliding(): + enter_normal_state() + + +# Any enter state function should only be called once when you want to enter that state, not every frame. +func enter_normal_state(): + #print("entering normal state") + var prev_state = state + if prev_state == "crouching": + CROUCH_ANIMATION.play_backwards("crouch") + state = "normal" + speed = base_speed + +func enter_crouch_state(): + #print("entering crouch state") + state = "crouching" + speed = crouch_speed + CROUCH_ANIMATION.play("crouch") + +func enter_sprint_state(): + #print("entering sprint state") + var prev_state = state + if prev_state == "crouching": + CROUCH_ANIMATION.play_backwards("crouch") + state = "sprinting" + speed = sprint_speed + +#endregion + +#region Animation Handling + +func initialize_animations(): + # Reset the camera position + # If you want to change the default head height, change these animations. + HEADBOB_ANIMATION.play("RESET") + JUMP_ANIMATION.play("RESET") + CROUCH_ANIMATION.play("RESET") + +func play_headbob_animation(moving): + if moving and is_on_floor(): + var use_headbob_animation : String + match state: + "normal","crouching": + use_headbob_animation = "walk" + "sprinting": + use_headbob_animation = "sprint" + + var was_playing : bool = false + if HEADBOB_ANIMATION.current_animation == use_headbob_animation: + was_playing = true + + HEADBOB_ANIMATION.play(use_headbob_animation, 0.25) + HEADBOB_ANIMATION.speed_scale = (current_speed / base_speed) * 1.75 + if !was_playing: + HEADBOB_ANIMATION.seek(float(randi() % 2)) # Randomize the initial headbob direction + # Let me explain that piece of code because it looks like it does the opposite of what it actually does. + # The headbob animation has two starting positions. One is at 0 and the other is at 1. + # randi() % 2 returns either 0 or 1, and so the animation randomly starts at one of the starting positions. + # This code is extremely performant but it makes no sense. + + else: + if HEADBOB_ANIMATION.current_animation == "sprint" or HEADBOB_ANIMATION.current_animation == "walk": + HEADBOB_ANIMATION.speed_scale = 1 + HEADBOB_ANIMATION.play("RESET", 1) + +func play_jump_animation(): + if !was_on_floor and is_on_floor(): # The player just landed + var facing_direction : Vector3 = CAMERA.get_global_transform().basis.x + var facing_direction_2D : Vector2 = Vector2(facing_direction.x, facing_direction.z).normalized() + var velocity_2D : Vector2 = Vector2(velocity.x, velocity.z).normalized() + + # Compares velocity direction against the camera direction (via dot product) to determine which landing animation to play. + var side_landed : int = round(velocity_2D.dot(facing_direction_2D)) + + if side_landed > 0: + JUMP_ANIMATION.play("land_right", 0.25) + elif side_landed < 0: + JUMP_ANIMATION.play("land_left", 0.25) + else: + JUMP_ANIMATION.play("land_center", 0.25) + +#endregion + +#region Debug Menu + +func update_debug_menu_per_frame(): + $UserInterface/DebugPanel.add_property("FPS", Performance.get_monitor(Performance.TIME_FPS), 0) + var status : String = state + if !is_on_floor(): + status += " in the air" + $UserInterface/DebugPanel.add_property("State", status, 4) + + +func update_debug_menu_per_tick(): + # Big thanks to github.com/LorenzoAncora for the concept of the improved debug values + current_speed = Vector3.ZERO.distance_to(get_real_velocity()) + $UserInterface/DebugPanel.add_property("Speed", snappedf(current_speed, 0.001), 1) + $UserInterface/DebugPanel.add_property("Target speed", speed, 2) + var cv : Vector3 = get_real_velocity() + var vd : Array[float] = [ + snappedf(cv.x, 0.001), + snappedf(cv.y, 0.001), + snappedf(cv.z, 0.001) + ] + var readable_velocity : String = "X: " + str(vd[0]) + " Y: " + str(vd[1]) + " Z: " + str(vd[2]) + $UserInterface/DebugPanel.add_property("Velocity", readable_velocity, 3) + + +func _unhandled_input(event : InputEvent): + if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + mouseInput.x += event.relative.x + mouseInput.y += event.relative.y + # Toggle debug menu + elif event is InputEventKey: + if event.is_released(): + # Where we're going, we don't need InputMap + if event.keycode == 4194338: # F7 + $UserInterface/DebugPanel.visible = !$UserInterface/DebugPanel.visible + +#endregion + +#region Misc Functions + +func change_reticle(reticle): # Yup, this function is kinda strange + if not is_multiplayer_authority(): + return + if RETICLE: + RETICLE.queue_free() + + RETICLE = load(reticle).instantiate() + RETICLE.character = self + $UserInterface.add_child(RETICLE) + + +func update_camera_fov(): + if state == "sprinting": + CAMERA.fov = lerp(CAMERA.fov, 85.0, 0.3) + else: + CAMERA.fov = lerp(CAMERA.fov, 75.0, 0.3) + +func handle_pausing(): + if Global.inventory_showing: + handle_open_inventory() + if Input.is_action_just_pressed(controls.PAUSE): + # You may want another node to handle pausing, because this player may get paused too. + match Input.mouse_mode: + Input.MOUSE_MODE_CAPTURED: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + #get_tree().paused = false + Input.MOUSE_MODE_VISIBLE: + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + #get_tree().paused = false + +#endregion diff --git a/Scripts/fpc/character.gd.uid b/Scripts/fpc/character.gd.uid new file mode 100644 index 0000000..26b6d96 --- /dev/null +++ b/Scripts/fpc/character.gd.uid @@ -0,0 +1 @@ +uid://c1um4tmthbbpk diff --git a/Scripts/fpc/debug.gd b/Scripts/fpc/debug.gd new file mode 100644 index 0000000..e274258 --- /dev/null +++ b/Scripts/fpc/debug.gd @@ -0,0 +1,18 @@ +extends PanelContainer + + +func _process(_delta): + if visible: + pass + +func add_property(title : String, value, order : int): # This can either be called once for a static property or called every frame for a dynamic property + var target + target = $MarginContainer/VBoxContainer.find_child(title, true, false) # I have no idea what true and false does here, the function should be more specific + if !target: + target = Label.new() # Debug lines are of type Label + $MarginContainer/VBoxContainer.add_child(target) + target.name = title + target.text = title + ": " + str(value) + elif visible: + target.text = title + ": " + str(value) + $MarginContainer/VBoxContainer.move_child(target, order) diff --git a/Scripts/fpc/debug.gd.uid b/Scripts/fpc/debug.gd.uid new file mode 100644 index 0000000..c5b6f3e --- /dev/null +++ b/Scripts/fpc/debug.gd.uid @@ -0,0 +1 @@ +uid://bhfftu01dsfk7 diff --git a/Scripts/global.gd b/Scripts/global.gd new file mode 100644 index 0000000..d29f5e0 --- /dev/null +++ b/Scripts/global.gd @@ -0,0 +1,29 @@ +extends Node + +#region Constants + +const DEFAULT_ENET_ADDRESS = "127.0.0.1" + +#endregion + + +#region Variables + +var is_admin : bool = true + +var is_multiplayer : bool = false + +var steam_connected : bool = false + +var in_game : bool = false +var in_menu : bool = false +var inventory_showing : bool = false + +var enet_address : String = DEFAULT_ENET_ADDRESS +var steam_lobby_id : String = "" + +var controller_connected : bool = false + +var voip_on : bool = false + +#endregion \ No newline at end of file diff --git a/Scripts/global.gd.uid b/Scripts/global.gd.uid new file mode 100644 index 0000000..524b7ce --- /dev/null +++ b/Scripts/global.gd.uid @@ -0,0 +1 @@ +uid://bma0n1wnb0yxd diff --git a/Scripts/world.gd b/Scripts/world.gd new file mode 100644 index 0000000..1249e2d --- /dev/null +++ b/Scripts/world.gd @@ -0,0 +1,86 @@ +extends Node + +@export var lobby_menu : LobbyMenu +var menu_showing : bool = false; + +@export var server : Server + +@export var level: Level + +@onready var chat : ChatMenu = $ChatMenu + +func _ready() -> void: + lobby_menu.enet_host_toggled_on.connect(_enet_host_on) + lobby_menu.enet_join_pressed.connect(_enet_join_pressed) + lobby_menu.disconnect_button_pressed.connect(_disconnect_button_pressed) + lobby_menu.enet_host_toggled_off.connect(_menu_toggle_host_off) + server.client_connected_to_server.connect(_client_joined_server) + server.remove_client_from_server.connect(_remove_client_from_server) + server.client_disconnected_from_server.connect(_disconnect_from_server) + server.server_close.connect(_server_close) + server.game_log.connect(_server_send_chat_message) + +func _physics_process(_delta: float) -> void: + pause_toggle() + + +func pause_toggle(): + if Input.is_action_just_pressed("pause"): + if Global.inventory_showing: + var player_id : int = multiplayer.get_unique_id() + var player : Player = level.get_node("Player"+str(player_id)) + player.handle_open_inventory(true) + return + if !menu_showing: + lobby_menu.show() + menu_showing = true + Global.in_menu = true + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + + elif menu_showing: + lobby_menu.hide() + menu_showing = false + Global.in_menu = false + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + +func _enet_host_on(username: String) -> void: + print("Server started, Host: " + username); + server.enet_create_host() + + +func _enet_join_pressed(_username: String) -> void: + print("... Joining " + Global.enet_address) + var playername : Player = level.get_node("Player1") + level.remove_child(playername) + server.enet_create_client(Global.enet_address) + + +func _client_joined_server() -> void: + + var player_id : int = multiplayer.get_unique_id() + level.request_spawn_player.rpc(player_id) + lobby_menu.hide() + menu_showing = false + Global.in_menu = false + +func _menu_toggle_host_off() -> void: + server.destroy_lobby() + lobby_menu.reset_visible() + +func _server_close() -> void: + level.remove_players(false) + lobby_menu.reset_visible() + +func _disconnect_button_pressed(): + server.disconnect_client() + lobby_menu.reset_visible() + +func _remove_client_from_server(id : int) -> void: + level.remove_client_from_server.rpc_id(1, id) + +func _disconnect_from_server(): + level.disconnect_from_server() + + +func _server_send_chat_message(message : String, color : Color) -> void: + chat.send_message(message, false, color) diff --git a/Scripts/world.gd.uid b/Scripts/world.gd.uid new file mode 100644 index 0000000..eb541fb --- /dev/null +++ b/Scripts/world.gd.uid @@ -0,0 +1 @@ +uid://klp20wju1i26 diff --git a/addons/godotsteam/godotsteam.gdextension b/addons/godotsteam/godotsteam.gdextension new file mode 100644 index 0000000..5917bed --- /dev/null +++ b/addons/godotsteam/godotsteam.gdextension @@ -0,0 +1,22 @@ +[configuration] +entry_symbol = "godotsteam_init" +compatibility_minimum = "4.4" + +[libraries] +macos.debug = "res://addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework" +macos.release = "res://addons/godotsteam/osx/libgodotsteam.macos.template_release.framework" +windows.debug.x86_64 = "res://addons/godotsteam/win64/libgodotsteam.windows.template_debug.x86_64.dll" +windows.debug.x86_32 = "res://addons/godotsteam/win32/libgodotsteam.windows.template_debug.x86_32.dll" +windows.release.x86_64 = "res://addons/godotsteam/win64/libgodotsteam.windows.template_release.x86_64.dll" +windows.release.x86_32 = "res://addons/godotsteam/win32/libgodotsteam.windows.template_release.x86_32.dll" +linux.debug.x86_64 = "res://addons/godotsteam/linux64/libgodotsteam.linux.template_debug.x86_64.so" +linux.debug.x86_32 = "res://addons/godotsteam/linux32/libgodotsteam.linux.template_debug.x86_32.so" +linux.release.x86_64 = "res://addons/godotsteam/linux64/libgodotsteam.linux.template_release.x86_64.so" +linux.release.x86_32 = "res://addons/godotsteam/linux32/libgodotsteam.linux.template_release.x86_32.so" + +[dependencies] +macos.universal = { "res://addons/godotsteam/osx/libsteam_api.dylib": "" } +windows.x86_64 = { "res://addons/godotsteam/win64/steam_api64.dll": "" } +windows.x86_32 = { "res://addons/godotsteam/win32/steam_api.dll": "" } +linux.x86_64 = { "res://addons/godotsteam/linux64/libsteam_api.so": "" } +linux.x86_32 = { "res://addons/godotsteam/linux32/libsteam_api.so": "" } diff --git a/addons/godotsteam/godotsteam.gdextension.uid b/addons/godotsteam/godotsteam.gdextension.uid new file mode 100644 index 0000000..8b94933 --- /dev/null +++ b/addons/godotsteam/godotsteam.gdextension.uid @@ -0,0 +1 @@ +uid://d02t56dfoplvx diff --git a/addons/godotsteam/linux32/libgodotsteam.linux.template_debug.x86_32.so b/addons/godotsteam/linux32/libgodotsteam.linux.template_debug.x86_32.so new file mode 100644 index 0000000..00be7c5 Binary files /dev/null and b/addons/godotsteam/linux32/libgodotsteam.linux.template_debug.x86_32.so differ diff --git a/addons/godotsteam/linux32/libgodotsteam.linux.template_release.x86_32.so b/addons/godotsteam/linux32/libgodotsteam.linux.template_release.x86_32.so new file mode 100644 index 0000000..658694b Binary files /dev/null and b/addons/godotsteam/linux32/libgodotsteam.linux.template_release.x86_32.so differ diff --git a/addons/godotsteam/linux32/libsteam_api.so b/addons/godotsteam/linux32/libsteam_api.so new file mode 100644 index 0000000..2d9e8a7 Binary files /dev/null and b/addons/godotsteam/linux32/libsteam_api.so differ diff --git a/addons/godotsteam/linux64/libgodotsteam.linux.template_debug.x86_64.so b/addons/godotsteam/linux64/libgodotsteam.linux.template_debug.x86_64.so new file mode 100644 index 0000000..045b00d Binary files /dev/null and b/addons/godotsteam/linux64/libgodotsteam.linux.template_debug.x86_64.so differ diff --git a/addons/godotsteam/linux64/libgodotsteam.linux.template_release.x86_64.so b/addons/godotsteam/linux64/libgodotsteam.linux.template_release.x86_64.so new file mode 100644 index 0000000..b273ec7 Binary files /dev/null and b/addons/godotsteam/linux64/libgodotsteam.linux.template_release.x86_64.so differ diff --git a/addons/godotsteam/linux64/libsteam_api.so b/addons/godotsteam/linux64/libsteam_api.so new file mode 100644 index 0000000..8783570 Binary files /dev/null and b/addons/godotsteam/linux64/libsteam_api.so differ diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/Resources/Info.plist b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/Resources/Info.plist new file mode 100644 index 0000000..68caf2b --- /dev/null +++ b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/Resources/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleExecutable + libgodotsteam.debug + CFBundleIdentifier + org.godotsteam.godotsteam + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + libgodotsteam.debug + CFBundlePackageType + FMWK + CFBundleShortVersionString + 4.15 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 4.15 + LSMinimumSystemVersion + 10.12 + + \ No newline at end of file diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libgodotsteam.macos.template_debug b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libgodotsteam.macos.template_debug new file mode 100644 index 0000000..8a8b2b7 Binary files /dev/null and b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libgodotsteam.macos.template_debug differ diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libsteam_api.dylib b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libsteam_api.dylib new file mode 100644 index 0000000..c493b2b Binary files /dev/null and b/addons/godotsteam/osx/libgodotsteam.macos.template_debug.framework/libsteam_api.dylib differ diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/Resources/Info.plist b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/Resources/Info.plist new file mode 100644 index 0000000..e3e8dac --- /dev/null +++ b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/Resources/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleExecutable + libgodotsteam + CFBundleIdentifier + org.godotsteam.godotsteam + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + libgodotsteam + CFBundlePackageType + FMWK + CFBundleShortVersionString + 4.15 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 4.15 + LSMinimumSystemVersion + 10.12 + + \ No newline at end of file diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libgodotsteam.macos.template_release b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libgodotsteam.macos.template_release new file mode 100644 index 0000000..ce91b3e Binary files /dev/null and b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libgodotsteam.macos.template_release differ diff --git a/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libsteam_api.dylib b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libsteam_api.dylib new file mode 100644 index 0000000..c493b2b Binary files /dev/null and b/addons/godotsteam/osx/libgodotsteam.macos.template_release.framework/libsteam_api.dylib differ diff --git a/addons/godotsteam/osx/libsteam_api.dylib b/addons/godotsteam/osx/libsteam_api.dylib new file mode 100644 index 0000000..c493b2b Binary files /dev/null and b/addons/godotsteam/osx/libsteam_api.dylib differ diff --git a/addons/godotsteam/win32/libgodotsteam.windows.template_debug.x86_32.dll b/addons/godotsteam/win32/libgodotsteam.windows.template_debug.x86_32.dll new file mode 100644 index 0000000..cebcc9b Binary files /dev/null and b/addons/godotsteam/win32/libgodotsteam.windows.template_debug.x86_32.dll differ diff --git a/addons/godotsteam/win32/libgodotsteam.windows.template_release.x86_32.dll b/addons/godotsteam/win32/libgodotsteam.windows.template_release.x86_32.dll new file mode 100644 index 0000000..21c3a1e Binary files /dev/null and b/addons/godotsteam/win32/libgodotsteam.windows.template_release.x86_32.dll differ diff --git a/addons/godotsteam/win32/steam_api.dll b/addons/godotsteam/win32/steam_api.dll new file mode 100644 index 0000000..2372ab1 Binary files /dev/null and b/addons/godotsteam/win32/steam_api.dll differ diff --git a/addons/godotsteam/win64/libgodotsteam.windows.template_debug.x86_64.dll b/addons/godotsteam/win64/libgodotsteam.windows.template_debug.x86_64.dll new file mode 100644 index 0000000..3d02848 Binary files /dev/null and b/addons/godotsteam/win64/libgodotsteam.windows.template_debug.x86_64.dll differ diff --git a/addons/godotsteam/win64/libgodotsteam.windows.template_release.x86_64.dll b/addons/godotsteam/win64/libgodotsteam.windows.template_release.x86_64.dll new file mode 100644 index 0000000..6bb49b3 Binary files /dev/null and b/addons/godotsteam/win64/libgodotsteam.windows.template_release.x86_64.dll differ diff --git a/addons/godotsteam/win64/steam_api64.dll b/addons/godotsteam/win64/steam_api64.dll new file mode 100644 index 0000000..6d11825 Binary files /dev/null and b/addons/godotsteam/win64/steam_api64.dll differ diff --git a/addons/godotsteam/win64/~libgodotsteam.windows.template_debug.x86_64.dll b/addons/godotsteam/win64/~libgodotsteam.windows.template_debug.x86_64.dll new file mode 100644 index 0000000..3d02848 Binary files /dev/null and b/addons/godotsteam/win64/~libgodotsteam.windows.template_debug.x86_64.dll differ diff --git a/addons/steam-multiplayer-peer/.gitignore b/addons/steam-multiplayer-peer/.gitignore new file mode 100644 index 0000000..9581441 --- /dev/null +++ b/addons/steam-multiplayer-peer/.gitignore @@ -0,0 +1 @@ +~*.dll \ No newline at end of file diff --git a/addons/steam-multiplayer-peer/LICENSE b/addons/steam-multiplayer-peer/LICENSE new file mode 100644 index 0000000..0cefe81 --- /dev/null +++ b/addons/steam-multiplayer-peer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Expresso Bits + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/addons/steam-multiplayer-peer/README.md b/addons/steam-multiplayer-peer/README.md new file mode 100644 index 0000000..cbaf359 --- /dev/null +++ b/addons/steam-multiplayer-peer/README.md @@ -0,0 +1,87 @@ +# “icon” Welcome to Expresso Steam Multiplayer Peer 👋 +![Version](https://img.shields.io/badge/version-0.2.0-blue.svg?cacheSeconds=2592000) +[![Documentation](https://img.shields.io/badge/documentation-no-red.svg)](todo-doc) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](MIT) + +See demos in: +Github: [Branch demos](https://github.com/expressobits/steam-multiplayer-peer/tree/demos) +Godot Asset Lib: https://godotengine.org/asset-library/asset/2258 + +## Tutorial and Learnings (How to use) + +See post of Michael Macha +https://michaelmacha.wordpress.com/2024/04/08/godotsteam-and-steammultiplayerpeer/ + +See too on youtube videos +https://www.youtube.com/playlist?list=PLg_8mgEWE2p8ZA-AqUUJ3CYEtrRVFhl_v + +Thank you Michael! + +## Features + +✔️ Change easy Enet peer to Steam Peer + +✔️ Use Steam Sockets (Low level like enet). + +✔️ GDExtension (Easy to add your project) + +✔️ No dependency with GodotSteam, but demo use GodotSteam to handle connections with lobbies (See lobbies tutorial in Godot Steam [here](https://godotsteam.com/tutorials/lobbies/)). + + +## GodotSteam SteamMultiplayerPeer Differences + +| Differences | This SteamMultiplayerPeer | GodotSteam SteamMultiplayerPeer | +|---|---|---| +| Lib Type | GDExtension, add on your project libs to use easy. | C++ module, you need to use the precompiled
ones from godotsteam or compile it yourself | +| Steam Connection | Steam Sockets [Steam Docs](https://partner.steamgames.com/doc/api/ISteamNetworkingSockets)
Steam's lowest connection level,
manages a connection
(It's very close to Enet,
that's why I chose this approach for the plugin) | Steam Messages [Steam Docs](https://partner.steamgames.com/doc/api/ISteamNetworkingMessages)
Without a connection idea,
the connection is managed by the lobby,
Need Steam lobbies. | +| TODO | | | + +## Known issues + +⚠️ Features No channel support currently +At some point I intend to integrate channels to be used in rpcs commands, but currently it is only necessary to use channel 0 or the default rpcs. + +## In Progress + +🔨 Bugs fixes + +## Planneds + +📅 No planned features. + + + +## Authors + +👤 **Rafael Correa** +* Twitter: [@ScriptsEngineer](https://twitter.com/ScriptsEngineer) +* Github: [@scriptsengineer](https://github.com/scriptsengineer) + +👤 **Zennyth** +* Github: [@Zennyth](https://github.com/Zennyth) + +👤 **greenfox1505** +* Github: [@greenfox1505](https://github.com/greenfox1505) + +👤 **MichaelMacha** +* Github: [@MichaelMacha](https://github.com/MichaelMacha) + + +## 🤝 Contributing + +Contributions, issues and feature requests are welcome! + +Feel free to check [issues page](https://github.com/ExpressoBits/steam-multiplayer-peer/issues). + +To suggest or discuss some project structure, feel free here [discussions page](https://github.com/expressobits/steam-multiplayer-peer/discussions) + + +## Show your support + +Give a ⭐️ if this project helped you! + + +## 📝 License + +This project is [MIT](MIT) licensed. \ No newline at end of file diff --git a/addons/steam-multiplayer-peer/linux/.gitkeep b/addons/steam-multiplayer-peer/linux/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_debug.double.x86_64.so b/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_debug.double.x86_64.so new file mode 100644 index 0000000..a8a45e9 Binary files /dev/null and b/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_debug.double.x86_64.so differ diff --git a/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_debug.x86_64.so b/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_debug.x86_64.so new file mode 100644 index 0000000..3d1ee20 Binary files /dev/null and b/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_debug.x86_64.so differ diff --git a/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_release.double.x86_64.so b/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_release.double.x86_64.so new file mode 100644 index 0000000..30d1bdf Binary files /dev/null and b/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_release.double.x86_64.so differ diff --git a/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_release.x86_64.so b/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_release.x86_64.so new file mode 100644 index 0000000..4b34abf Binary files /dev/null and b/addons/steam-multiplayer-peer/linux/libsteam-multiplayer-peer.linux.template_release.x86_64.so differ diff --git a/addons/steam-multiplayer-peer/linux/libsteam_api.so b/addons/steam-multiplayer-peer/linux/libsteam_api.so new file mode 100644 index 0000000..4a1260c Binary files /dev/null and b/addons/steam-multiplayer-peer/linux/libsteam_api.so differ diff --git a/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_debug.double.universal.dylib b/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_debug.double.universal.dylib new file mode 100644 index 0000000..eda02f2 Binary files /dev/null and b/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_debug.double.universal.dylib differ diff --git a/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_debug.universal.dylib b/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_debug.universal.dylib new file mode 100644 index 0000000..820ea49 Binary files /dev/null and b/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_debug.universal.dylib differ diff --git a/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_release.double.universal.dylib b/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_release.double.universal.dylib new file mode 100644 index 0000000..1f74832 Binary files /dev/null and b/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_release.double.universal.dylib differ diff --git a/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_release.universal.dylib b/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_release.universal.dylib new file mode 100644 index 0000000..6bf8111 Binary files /dev/null and b/addons/steam-multiplayer-peer/macos/libsteam-multiplayer-peer.macos.template_release.universal.dylib differ diff --git a/addons/steam-multiplayer-peer/macos/libsteam_api.dylib b/addons/steam-multiplayer-peer/macos/libsteam_api.dylib new file mode 100644 index 0000000..1897bef Binary files /dev/null and b/addons/steam-multiplayer-peer/macos/libsteam_api.dylib differ diff --git a/addons/steam-multiplayer-peer/steam-multiplayer-peer.gdextension b/addons/steam-multiplayer-peer/steam-multiplayer-peer.gdextension new file mode 100644 index 0000000..c877cf5 --- /dev/null +++ b/addons/steam-multiplayer-peer/steam-multiplayer-peer.gdextension @@ -0,0 +1,25 @@ +[configuration] +entry_symbol = "steam_multiplayer_peer_init" +compatibility_minimum = 4.2 + +[libraries] +linux.debug.x86_64 = "./linux/libsteam-multiplayer-peer.linux.template_debug.x86_64.so" +linux.release.x86_64 = "./linux/libsteam-multiplayer-peer.linux.template_release.x86_64.so" +linux.debug.arm64 = "./linux/libsteam-multiplayer-peer.linux.template_debug.arm64.so" +linux.release.arm64 = "./linux/libsteam-multiplayer-peer.linux.template_release.arm64.so" +linux.debug.rv64 = "./linux/libsteam-multiplayer-peer.linux.template_debug.rv64.so" +linux.release.rv64 = "./linux/libsteam-multiplayer-peer.linux.template_release.rv64.so" +macos.debug = "./macos/libsteam-multiplayer-peer.macos.template_debug.universal.dylib" +macos.release = "./macos/libsteam-multiplayer-peer.macos.template_release.universal.dylib" +windows.debug.x86_32 = "./windows/steam-multiplayer-peer.windows.template_debug.x86_32.dll" +windows.release.x86_32 = "./windows/steam-multiplayer-peer.windows.template_release.x86_32.dll" +windows.debug.x86_64 = "./windows/steam-multiplayer-peer.windows.template_debug.x86_64.dll" +windows.release.x86_64 = "./windows/steam-multiplayer-peer.windows.template_release.x86_64.dll" + +[dependencies] +linux.x86_64 = { "linux/libsteam_api.so": "" } +linux.arm64 = { "linux/libsteam_api.so": "" } +linux.rv64 = { "linux/libsteam_api.so": "" } +macos.universal = { "macos/libsteam_api.dylib": "" } +windows.x86_64 = { "windows/steam_api64.dll": "" } +windows.x86_32 = { "windows/steam_api.dll": "" } \ No newline at end of file diff --git a/addons/steam-multiplayer-peer/steam-multiplayer-peer.gdextension.uid b/addons/steam-multiplayer-peer/steam-multiplayer-peer.gdextension.uid new file mode 100644 index 0000000..0bf22ce --- /dev/null +++ b/addons/steam-multiplayer-peer/steam-multiplayer-peer.gdextension.uid @@ -0,0 +1 @@ +uid://2kvjphhw06ra diff --git a/addons/steam-multiplayer-peer/windows/.gitkeep b/addons/steam-multiplayer-peer/windows/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_debug.double.x86_64.dll b/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_debug.double.x86_64.dll new file mode 100644 index 0000000..5069c2c Binary files /dev/null and b/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_debug.double.x86_64.dll differ diff --git a/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_debug.x86_64.dll b/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_debug.x86_64.dll new file mode 100644 index 0000000..11292cf Binary files /dev/null and b/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_debug.x86_64.dll differ diff --git a/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_release.double.x86_64.dll b/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_release.double.x86_64.dll new file mode 100644 index 0000000..f1a81c2 Binary files /dev/null and b/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_release.double.x86_64.dll differ diff --git a/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_release.x86_64.dll b/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_release.x86_64.dll new file mode 100644 index 0000000..f6f4e55 Binary files /dev/null and b/addons/steam-multiplayer-peer/windows/steam-multiplayer-peer.windows.template_release.x86_64.dll differ diff --git a/addons/steam-multiplayer-peer/windows/steam_api.dll b/addons/steam-multiplayer-peer/windows/steam_api.dll new file mode 100644 index 0000000..0bcfde3 Binary files /dev/null and b/addons/steam-multiplayer-peer/windows/steam_api.dll differ diff --git a/addons/steam-multiplayer-peer/windows/steam_api64.dll b/addons/steam-multiplayer-peer/windows/steam_api64.dll new file mode 100644 index 0000000..6594c50 Binary files /dev/null and b/addons/steam-multiplayer-peer/windows/steam_api64.dll differ diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..09ff5a7 --- /dev/null +++ b/project.godot @@ -0,0 +1,105 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Goblin Dishonored" +run/main_scene="uid://cjimt73bcja16" +config/features=PackedStringArray("4.4", "Forward Plus") + +[autoload] + +Global="*res://Scripts/global.gd" + +[file_customization] + +folder_colors={ +"res://Assets/": "red", +"res://Scenes/": "purple", +"res://Scripts/": "green" +} + +[gui] + +theme/custom="uid://bvso6uowlb8dh" + +[input] + +move_forward={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +move_back={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} +move_left={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +move_right={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +jump={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +] +} +crouch={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +sprint={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +pause={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +open_chat={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +open_chat_as_command={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":47,"key_label":0,"unicode":47,"location":0,"echo":false,"script":null) +] +} +chat_send={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +interact={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) +] +} +inventory={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} + +[layer_names] + +3d_physics/layer_1="Terrain and Players" +3d_physics/layer_2="Interactables" +3d_physics/layer_3="Enemies" diff --git a/quality-godot-first-person-2-2.6.1/.gitattributes b/quality-godot-first-person-2-2.6.1/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/quality-godot-first-person-2-2.6.1/.gitignore b/quality-godot-first-person-2-2.6.1/.gitignore new file mode 100644 index 0000000..4709183 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/.gitignore @@ -0,0 +1,2 @@ +# Godot 4+ specific ignores +.godot/ diff --git a/quality-godot-first-person-2-2.6.1/LICENSE b/quality-godot-first-person-2-2.6.1/LICENSE new file mode 100644 index 0000000..f34733d --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Colormatic + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/quality-godot-first-person-2-2.6.1/README.md b/quality-godot-first-person-2-2.6.1/README.md new file mode 100644 index 0000000..6e64887 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/README.md @@ -0,0 +1,67 @@ +# quality-godot-first-person-2 +Actually good first person controller for the Godot Engine. +MIT License (credit Colormatic Studios) + +This first person controller was made because there aren't many first person controllers for Godot, and the ones that do exist are pretty bad. +It is highly customizable and comes with many features, QOL, and clean code. + +Some parts came from StayAtHomeDev's FPS tutorial. You can find that [here](https://www.youtube.com/playlist?list=PLEHvj4yeNfeF6s-UVs5Zx5TfNYmeCiYwf). + +# Directions +Move with WASD, space to jump, shift to sprint, C to crouch. + +**FEATURES:** +- Extremely configurable +- In-air momentum +- Motion smoothing +- FOV smoothing +- Movement animations +- Crouching +- Sprinting +- 2 crosshairs/reticles, one is animated (more to come?) +- Controller/GamePad support (enabled through code, see wiki) +- In-editor tools (enable editable children to use) + +If you make a cool game with this addon, I would love to hear about it! + +# Wiki +**To start out**, you should probably remap all of the movement keys to your own control set. + +You can make this a super basic controller by just disabling everything. + +**How to add controller/GamePad support** +- In the controls export group, there is a commented section at the end that says "Uncomment this if you want full controller support". Uncomment that block. +- Make a key map for each direction (left, right, up, down) and map them to your joystick. +- Write in these keymaps in the controls section of the player settings. +- In the `handle_head_rotation` function, there is another block of commented code that says the same thing. Uncomment that too. +- You should now be able to look around with the joystick. Make sure you add the other controls to the input map. (movement, jumping, crouching, sprinting, etc.) + +**Slope/staircase:** +Credit to @roberto-urbani23 +In the character inspector, you can uncheck Stop on Slope and set the max angle to 89 (for some reason, 90 will make the player stuck). Also Snap Length to 1 otherwise your character will not remain attached to stairs if you sprint while going downstairs. + +**How to change settings:** +Click on the character node and there should be settings in the "Feature Settings" group. + +**How to add animations for a mesh:** +- Create a function for your animation and attach it to `_physics_process` to call it every frame. +- Use `input_dir` as a boolean (it is actually a `Vector2`) to know if the player is walking. +- Use the `state` member variable to tell if the player is sprinting or crouching. +- Use the `is_on_floor` function to tell if the player is standing or falling. + +**How to change reticles (crosshairs):** +Change the "Default Reticle" setting to your reticle file. +During runtime: +Use the `change_reticle` function on the character. + +**How to create a new reticle:** +- Choose a reticle to base it off of. +- Open that reticle and save it as a new reticle. +- Remove the script from the reticle and create a new one. (for some reason you have to do this) +- Edit the reticle to your needs. +- Follow the "how to change reticles" directions to use it. + +**How to use the editor tools:** +- Enable editable children on the `CharacterBody` node +- Use the options in the Properties tab to change things +- These changes apply in runtime as well diff --git a/quality-godot-first-person-2-2.6.1/addons/fpc/EditorModule.gd b/quality-godot-first-person-2-2.6.1/addons/fpc/EditorModule.gd new file mode 100644 index 0000000..0a3a74f --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/addons/fpc/EditorModule.gd @@ -0,0 +1,49 @@ +@tool +extends Node + +# This does not effect runtime yet but will in the future. + +@export_category("Controller Editor Module") +@export_range(-360.0, 360.0, 0.01, "or_greater", "or_less") var head_y_rotation : float = 0.0: + set(new_rotation): + if HEAD: + head_y_rotation = new_rotation + HEAD.rotation.y = deg_to_rad(head_y_rotation) + update_configuration_warnings() +@export_range(-90.0, 90.0, 0.01, "or_greater", "or_less") var head_x_rotation : float = 0.0: + set(new_rotation): + if HEAD: + head_x_rotation = new_rotation + HEAD.rotation.x = deg_to_rad(head_x_rotation) + update_configuration_warnings() + +@export_group("Nodes") +@export var CHARACTER : CharacterBody3D +@export var head_path : String = "Head" # Relative to the parent node +#@export var CAMERA : Camera3D +#@export var HEADBOB_ANIMATION : AnimationPlayer +#@export var JUMP_ANIMATION : AnimationPlayer +#@export var CROUCH_ANIMATION : AnimationPlayer +#@export var COLLISION_MESH : CollisionShape3D + +@onready var HEAD = get_node("../" + head_path) + + +func _ready(): + if !Engine.is_editor_hint(): + #print("not editor") + HEAD.rotation.y = deg_to_rad(head_y_rotation) + HEAD.rotation.x = deg_to_rad(head_x_rotation) + + +func _get_configuration_warnings(): + var warnings = [] + + if head_y_rotation > 360: + warnings.append("The head rotation is greater than 360") + + if head_y_rotation < -360: + warnings.append("The head rotation is less than -360") + + # Returning an empty array gives no warnings + return warnings diff --git a/quality-godot-first-person-2-2.6.1/addons/fpc/character.gd b/quality-godot-first-person-2-2.6.1/addons/fpc/character.gd new file mode 100644 index 0000000..5a5f7f7 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/addons/fpc/character.gd @@ -0,0 +1,488 @@ +# COPYRIGHT Colormatic Studios +# MIT license +# Quality Godot First Person Controller v2 + + +extends CharacterBody3D + + +#region Character Export Group + +## The settings for the character's movement and feel. +@export_category("Character") +## The speed that the character moves at without crouching or sprinting. +@export var base_speed : float = 3.0 +## The speed that the character moves at when sprinting. +@export var sprint_speed : float = 6.0 +## The speed that the character moves at when crouching. +@export var crouch_speed : float = 1.0 + +## How fast the character speeds up and slows down when Motion Smoothing is on. +@export var acceleration : float = 10.0 +## How high the player jumps. +@export var jump_velocity : float = 4.5 +## How far the player turns when the mouse is moved. +@export var mouse_sensitivity : float = 0.1 +## Invert the X axis input for the camera. +@export var invert_camera_x_axis : bool = false +## Invert the Y axis input for the camera. +@export var invert_camera_y_axis : bool = false +## Whether the player can use movement inputs. Does not stop outside forces or jumping. See Jumping Enabled. +@export var immobile : bool = false +## The reticle file to import at runtime. By default are in res://addons/fpc/reticles/. Set to an empty string to remove. +@export_file var default_reticle + +#endregion + +#region Nodes Export Group + +@export_group("Nodes") +## A reference to the camera for use in the character script. This is the parent node to the camera and is rotated instead of the camera for mouse input. +@export var HEAD : Node3D +## A reference to the camera for use in the character script. +@export var CAMERA : Camera3D +## A reference to the headbob animation for use in the character script. +@export var HEADBOB_ANIMATION : AnimationPlayer +## A reference to the jump animation for use in the character script. +@export var JUMP_ANIMATION : AnimationPlayer +## A reference to the crouch animation for use in the character script. +@export var CROUCH_ANIMATION : AnimationPlayer +## A reference to the the player's collision shape for use in the character script. +@export var COLLISION_MESH : CollisionShape3D + +#endregion + +#region Controls Export Group + +# We are using UI controls because they are built into Godot Engine so they can be used right away +@export_group("Controls") +## Use the Input Map to map a mouse/keyboard input to an action and add a reference to it to this dictionary to be used in the script. +@export var controls : Dictionary = { + LEFT = "ui_left", + RIGHT = "ui_right", + FORWARD = "ui_up", + BACKWARD = "ui_down", + JUMP = "ui_accept", + CROUCH = "crouch", + SPRINT = "sprint", + PAUSE = "ui_cancel" + } +@export_subgroup("Controller Specific") +## This only affects how the camera is handled, the rest should be covered by adding controller inputs to the existing actions in the Input Map. +@export var controller_support : bool = false +## Use the Input Map to map a controller input to an action and add a reference to it to this dictionary to be used in the script. +@export var controller_controls : Dictionary = { + LOOK_LEFT = "look_left", + LOOK_RIGHT = "look_right", + LOOK_UP = "look_up", + LOOK_DOWN = "look_down" + } +## The sensitivity of the analog stick that controls camera rotation. Lower is less sensitive and higher is more sensitive. +@export_range(0.001, 1, 0.001) var look_sensitivity : float = 0.035 + +#endregion + +#region Feature Settings Export Group + +@export_group("Feature Settings") +## Enable or disable jumping. Useful for restrictive storytelling environments. +@export var jumping_enabled : bool = true +## Whether the player can move in the air or not. +@export var in_air_momentum : bool = true +## Smooths the feel of walking. +@export var motion_smoothing : bool = true +## Enables or disables sprinting. +@export var sprint_enabled : bool = true +## Toggles the sprinting state when button is pressed or requires the player to hold the button down to remain sprinting. +@export_enum("Hold to Sprint", "Toggle Sprint") var sprint_mode : int = 0 +## Enables or disables crouching. +@export var crouch_enabled : bool = true +## Toggles the crouch state when button is pressed or requires the player to hold the button down to remain crouched. +@export_enum("Hold to Crouch", "Toggle Crouch") var crouch_mode : int = 0 +## Wether sprinting should effect FOV. +@export var dynamic_fov : bool = true +## If the player holds down the jump button, should the player keep hopping. +@export var continuous_jumping : bool = true +## Enables the view bobbing animation. +@export var view_bobbing : bool = true +## Enables an immersive animation when the player jumps and hits the ground. +@export var jump_animation : bool = true +## This determines wether the player can use the pause button, not wether the game will actually pause. +@export var pausing_enabled : bool = true +## Use with caution. +@export var gravity_enabled : bool = true +## If your game changes the gravity value during gameplay, check this property to allow the player to experience the change in gravity. +@export var dynamic_gravity : bool = false + +#endregion + +#region Member Variable Initialization + +# These are variables used in this script that don't need to be exposed in the editor. +var speed : float = base_speed +var current_speed : float = 0.0 +# States: normal, crouching, sprinting +var state : String = "normal" +var low_ceiling : bool = false # This is for when the ceiling is too low and the player needs to crouch. +var was_on_floor : bool = true # Was the player on the floor last frame (for landing animation) + +# The reticle should always have a Control node as the root +var RETICLE : Control + +# Get the gravity from the project settings to be synced with RigidBody nodes +var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity") # Don't set this as a const, see the gravity section in _physics_process + +# Stores mouse input for rotating the camera in the physics process +var mouseInput : Vector2 = Vector2(0,0) + +#endregion + + + +#region Main Control Flow + +func _ready(): + #It is safe to comment this line if your game doesn't start with the mouse captured + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + + # If the controller is rotated in a certain direction for game design purposes, redirect this rotation into the head. + HEAD.rotation.y = rotation.y + rotation.y = 0 + + if default_reticle: + change_reticle(default_reticle) + + initialize_animations() + check_controls() + enter_normal_state() + + +func _process(_delta): + if pausing_enabled: + handle_pausing() + + update_debug_menu_per_frame() + + +func _physics_process(delta): # Most things happen here. + # Gravity + if dynamic_gravity: + gravity = ProjectSettings.get_setting("physics/3d/default_gravity") + if not is_on_floor() and gravity and gravity_enabled: + velocity.y -= gravity * delta + + handle_jumping() + + var input_dir = Vector2.ZERO + + if not immobile: # Immobility works by interrupting user input, so other forces can still be applied to the player + input_dir = Input.get_vector(controls.LEFT, controls.RIGHT, controls.FORWARD, controls.BACKWARD) + + handle_movement(delta, input_dir) + + handle_head_rotation() + + # The player is not able to stand up if the ceiling is too low + low_ceiling = $CrouchCeilingDetection.is_colliding() + + handle_state(input_dir) + if dynamic_fov: # This may be changed to an AnimationPlayer + update_camera_fov() + + if view_bobbing: + play_headbob_animation(input_dir) + + if jump_animation: + play_jump_animation() + + update_debug_menu_per_tick() + + was_on_floor = is_on_floor() # This must always be at the end of physics_process + +#endregion + +#region Input Handling + +func handle_jumping(): + if jumping_enabled: + if continuous_jumping: # Hold down the jump button + if Input.is_action_pressed(controls.JUMP) and is_on_floor() and !low_ceiling: + if jump_animation: + JUMP_ANIMATION.play("jump", 0.25) + velocity.y += jump_velocity # Adding instead of setting so jumping on slopes works properly + else: + if Input.is_action_just_pressed(controls.JUMP) and is_on_floor() and !low_ceiling: + if jump_animation: + JUMP_ANIMATION.play("jump", 0.25) + velocity.y += jump_velocity + + +func handle_movement(delta, input_dir): + var direction = input_dir.rotated(-HEAD.rotation.y) + direction = Vector3(direction.x, 0, direction.y) + move_and_slide() + + if in_air_momentum: + if is_on_floor(): + if motion_smoothing: + velocity.x = lerp(velocity.x, direction.x * speed, acceleration * delta) + velocity.z = lerp(velocity.z, direction.z * speed, acceleration * delta) + else: + velocity.x = direction.x * speed + velocity.z = direction.z * speed + else: + if motion_smoothing: + velocity.x = lerp(velocity.x, direction.x * speed, acceleration * delta) + velocity.z = lerp(velocity.z, direction.z * speed, acceleration * delta) + else: + velocity.x = direction.x * speed + velocity.z = direction.z * speed + + +func handle_head_rotation(): + if invert_camera_x_axis: + HEAD.rotation_degrees.y -= mouseInput.x * mouse_sensitivity * -1 + else: + HEAD.rotation_degrees.y -= mouseInput.x * mouse_sensitivity + + if invert_camera_y_axis: + HEAD.rotation_degrees.x -= mouseInput.y * mouse_sensitivity * -1 + else: + HEAD.rotation_degrees.x -= mouseInput.y * mouse_sensitivity + + if controller_support: + var controller_view_rotation = Input.get_vector(controller_controls.LOOK_DOWN, controller_controls.LOOK_UP, controller_controls.LOOK_RIGHT, controller_controls.LOOK_LEFT) * look_sensitivity # These are inverted because of the nature of 3D rotation. + if invert_camera_x_axis: + HEAD.rotation.x += controller_view_rotation.x * -1 + else: + HEAD.rotation.x += controller_view_rotation.x + + if invert_camera_y_axis: + HEAD.rotation.y += controller_view_rotation.y * -1 + else: + HEAD.rotation.y += controller_view_rotation.y + + mouseInput = Vector2(0,0) + HEAD.rotation.x = clamp(HEAD.rotation.x, deg_to_rad(-90), deg_to_rad(90)) + + +func check_controls(): # If you add a control, you might want to add a check for it here. + # The actions are being disabled so the engine doesn't halt the entire project in debug mode + if !InputMap.has_action(controls.JUMP): + push_error("No control mapped for jumping. Please add an input map control. Disabling jump.") + jumping_enabled = false + if !InputMap.has_action(controls.LEFT): + push_error("No control mapped for move left. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.RIGHT): + push_error("No control mapped for move right. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.FORWARD): + push_error("No control mapped for move forward. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.BACKWARD): + push_error("No control mapped for move backward. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.PAUSE): + push_error("No control mapped for pause. Please add an input map control. Disabling pausing.") + pausing_enabled = false + if !InputMap.has_action(controls.CROUCH): + push_error("No control mapped for crouch. Please add an input map control. Disabling crouching.") + crouch_enabled = false + if !InputMap.has_action(controls.SPRINT): + push_error("No control mapped for sprint. Please add an input map control. Disabling sprinting.") + sprint_enabled = false + +#endregion + +#region State Handling + +func handle_state(moving): + if sprint_enabled: + if sprint_mode == 0: + if Input.is_action_pressed(controls.SPRINT) and state != "crouching": + if moving: + if state != "sprinting": + enter_sprint_state() + else: + if state == "sprinting": + enter_normal_state() + elif state == "sprinting": + enter_normal_state() + elif sprint_mode == 1: + if moving: + # If the player is holding sprint before moving, handle that scenario + if Input.is_action_pressed(controls.SPRINT) and state == "normal": + enter_sprint_state() + if Input.is_action_just_pressed(controls.SPRINT): + match state: + "normal": + enter_sprint_state() + "sprinting": + enter_normal_state() + elif state == "sprinting": + enter_normal_state() + + if crouch_enabled: + if crouch_mode == 0: + if Input.is_action_pressed(controls.CROUCH) and state != "sprinting": + if state != "crouching": + enter_crouch_state() + elif state == "crouching" and !$CrouchCeilingDetection.is_colliding(): + enter_normal_state() + elif crouch_mode == 1: + if Input.is_action_just_pressed(controls.CROUCH): + match state: + "normal": + enter_crouch_state() + "crouching": + if !$CrouchCeilingDetection.is_colliding(): + enter_normal_state() + + +# Any enter state function should only be called once when you want to enter that state, not every frame. +func enter_normal_state(): + #print("entering normal state") + var prev_state = state + if prev_state == "crouching": + CROUCH_ANIMATION.play_backwards("crouch") + state = "normal" + speed = base_speed + +func enter_crouch_state(): + #print("entering crouch state") + state = "crouching" + speed = crouch_speed + CROUCH_ANIMATION.play("crouch") + +func enter_sprint_state(): + #print("entering sprint state") + var prev_state = state + if prev_state == "crouching": + CROUCH_ANIMATION.play_backwards("crouch") + state = "sprinting" + speed = sprint_speed + +#endregion + +#region Animation Handling + +func initialize_animations(): + # Reset the camera position + # If you want to change the default head height, change these animations. + HEADBOB_ANIMATION.play("RESET") + JUMP_ANIMATION.play("RESET") + CROUCH_ANIMATION.play("RESET") + +func play_headbob_animation(moving): + if moving and is_on_floor(): + var use_headbob_animation : String + match state: + "normal","crouching": + use_headbob_animation = "walk" + "sprinting": + use_headbob_animation = "sprint" + + var was_playing : bool = false + if HEADBOB_ANIMATION.current_animation == use_headbob_animation: + was_playing = true + + HEADBOB_ANIMATION.play(use_headbob_animation, 0.25) + HEADBOB_ANIMATION.speed_scale = (current_speed / base_speed) * 1.75 + if !was_playing: + HEADBOB_ANIMATION.seek(float(randi() % 2)) # Randomize the initial headbob direction + # Let me explain that piece of code because it looks like it does the opposite of what it actually does. + # The headbob animation has two starting positions. One is at 0 and the other is at 1. + # randi() % 2 returns either 0 or 1, and so the animation randomly starts at one of the starting positions. + # This code is extremely performant but it makes no sense. + + else: + if HEADBOB_ANIMATION.current_animation == "sprint" or HEADBOB_ANIMATION.current_animation == "walk": + HEADBOB_ANIMATION.speed_scale = 1 + HEADBOB_ANIMATION.play("RESET", 1) + +func play_jump_animation(): + if !was_on_floor and is_on_floor(): # The player just landed + var facing_direction : Vector3 = CAMERA.get_global_transform().basis.x + var facing_direction_2D : Vector2 = Vector2(facing_direction.x, facing_direction.z).normalized() + var velocity_2D : Vector2 = Vector2(velocity.x, velocity.z).normalized() + + # Compares velocity direction against the camera direction (via dot product) to determine which landing animation to play. + var side_landed : int = round(velocity_2D.dot(facing_direction_2D)) + + if side_landed > 0: + JUMP_ANIMATION.play("land_right", 0.25) + elif side_landed < 0: + JUMP_ANIMATION.play("land_left", 0.25) + else: + JUMP_ANIMATION.play("land_center", 0.25) + +#endregion + +#region Debug Menu + +func update_debug_menu_per_frame(): + $UserInterface/DebugPanel.add_property("FPS", Performance.get_monitor(Performance.TIME_FPS), 0) + var status : String = state + if !is_on_floor(): + status += " in the air" + $UserInterface/DebugPanel.add_property("State", status, 4) + + +func update_debug_menu_per_tick(): + # Big thanks to github.com/LorenzoAncora for the concept of the improved debug values + current_speed = Vector3.ZERO.distance_to(get_real_velocity()) + $UserInterface/DebugPanel.add_property("Speed", snappedf(current_speed, 0.001), 1) + $UserInterface/DebugPanel.add_property("Target speed", speed, 2) + var cv : Vector3 = get_real_velocity() + var vd : Array[float] = [ + snappedf(cv.x, 0.001), + snappedf(cv.y, 0.001), + snappedf(cv.z, 0.001) + ] + var readable_velocity : String = "X: " + str(vd[0]) + " Y: " + str(vd[1]) + " Z: " + str(vd[2]) + $UserInterface/DebugPanel.add_property("Velocity", readable_velocity, 3) + + +func _unhandled_input(event : InputEvent): + if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + mouseInput.x += event.relative.x + mouseInput.y += event.relative.y + # Toggle debug menu + elif event is InputEventKey: + if event.is_released(): + # Where we're going, we don't need InputMap + if event.keycode == 4194338: # F7 + $UserInterface/DebugPanel.visible = !$UserInterface/DebugPanel.visible + +#endregion + +#region Misc Functions + +func change_reticle(reticle): # Yup, this function is kinda strange + if RETICLE: + RETICLE.queue_free() + + RETICLE = load(reticle).instantiate() + RETICLE.character = self + $UserInterface.add_child(RETICLE) + + +func update_camera_fov(): + if state == "sprinting": + CAMERA.fov = lerp(CAMERA.fov, 85.0, 0.3) + else: + CAMERA.fov = lerp(CAMERA.fov, 75.0, 0.3) + +func handle_pausing(): + if Input.is_action_just_pressed(controls.PAUSE): + # You may want another node to handle pausing, because this player may get paused too. + match Input.mouse_mode: + Input.MOUSE_MODE_CAPTURED: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + #get_tree().paused = false + Input.MOUSE_MODE_VISIBLE: + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + #get_tree().paused = false + +#endregion diff --git a/quality-godot-first-person-2-2.6.1/addons/fpc/character.tscn b/quality-godot-first-person-2-2.6.1/addons/fpc/character.tscn new file mode 100644 index 0000000..3cfd7c8 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/addons/fpc/character.tscn @@ -0,0 +1,455 @@ +[gd_scene load_steps=22 format=3 uid="uid://cc1m2a1obsyn4"] + +[ext_resource type="Script" path="res://addons/fpc/character.gd" id="1_0t4e8"] +[ext_resource type="Script" path="res://addons/fpc/EditorModule.gd" id="3_v3ckk"] +[ext_resource type="Script" path="res://addons/fpc/debug.gd" id="3_x1wcc"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_kp17n"] +albedo_color = Color(0.909804, 0.596078, 0, 1) +clearcoat_enabled = true +clearcoat_roughness = 0.2 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_jw1de"] +material = SubResource("StandardMaterial3D_kp17n") + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_uy03j"] + +[sub_resource type="Animation" id="Animation_j8cx7"] +resource_name = "RESET" +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Mesh:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Collision:position") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Head:position") +tracks/2/interp = 2 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1.5, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Mesh:mesh:height") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [2.0] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Collision:shape:height") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [2.0] +} + +[sub_resource type="Animation" id="Animation_5ec5e"] +resource_name = "crouch" +length = 0.2 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Mesh:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 0.75, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Collision:position") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 0.75, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Head:position") +tracks/2/interp = 2 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1.5, 0), Vector3(0, 1.12508, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Mesh:mesh:height") +tracks/3/interp = 2 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [2.0, 1.5] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Collision:shape:height") +tracks/4/interp = 2 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [2.0, 1.5] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_5e5t5"] +_data = { +"RESET": SubResource("Animation_j8cx7"), +"crouch": SubResource("Animation_5ec5e") +} + +[sub_resource type="Animation" id="Animation_gh776"] +resource_name = "RESET" +length = 0.001 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_8ku67"] +resource_name = "sprint" +length = 2.0 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 1, 0, 1, 0), +"points": PackedFloat32Array(0.06, -0.25, 0, 0.25, -0.01, 0, 0, 0, 0, 0, -0.06, -0.25, 0.01, 0.25, 0.01, 0, 0, 0, 0, 0, 0.06, -0.25, -0.01, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0, 0, 0), +"points": PackedFloat32Array(0.05, -0.25, 0, 0.2, -0.01, 0, -0.2, 0.000186046, 0.2, 0.000186046, 0.05, -0.2, -0.01, 0.2, -0.01, 0, -0.2, 0, 0.2, 0, 0.05, -0.2, -0.01, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} + +[sub_resource type="Animation" id="Animation_lrqmv"] +resource_name = "walk" +length = 2.0 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 1, 0, 1, 0), +"points": PackedFloat32Array(0.04, -0.25, 0, 0.25, 0, 0, 0, 0, 0, 0, -0.04, -0.25, 0, 0.25, 0, 0, 0, 0, 0, 0, 0.04, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0, 0, 0), +"points": PackedFloat32Array(-0.05, -0.25, 0, 0.2, 0.005, 0, -0.2, 0.000186046, 0.2, 0.000186046, -0.05, -0.2, 0.005, 0.2, 0.005, 0, -0.2, 0, 0.2, 0, -0.05, -0.2, 0.005, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_o0unb"] +_data = { +"RESET": SubResource("Animation_gh776"), +"sprint": SubResource("Animation_8ku67"), +"walk": SubResource("Animation_lrqmv") +} + +[sub_resource type="Animation" id="Animation_fvvjq"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_s07ye"] +resource_name = "jump" +length = 3.0 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.6, 3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0.0349066, 0, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_3eyjl"] +resource_name = "land_center" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, 0), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_l1rph"] +resource_name = "land_left" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, 0.0174533), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_vsknp"] +resource_name = "land_right" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, -0.0174533), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_qeg5r"] +_data = { +"RESET": SubResource("Animation_fvvjq"), +"jump": SubResource("Animation_s07ye"), +"land_center": SubResource("Animation_3eyjl"), +"land_left": SubResource("Animation_l1rph"), +"land_right": SubResource("Animation_vsknp") +} + +[sub_resource type="Theme" id="Theme_wdf0f"] +MarginContainer/constants/margin_bottom = 10 +MarginContainer/constants/margin_left = 10 +MarginContainer/constants/margin_right = 10 +MarginContainer/constants/margin_top = 10 + +[sub_resource type="SphereShape3D" id="SphereShape3D_k4wwl"] + +[node name="Character" type="CharacterBody3D" node_paths=PackedStringArray("HEAD", "CAMERA", "HEADBOB_ANIMATION", "JUMP_ANIMATION", "CROUCH_ANIMATION", "COLLISION_MESH")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 0, 0) +script = ExtResource("1_0t4e8") +default_reticle = "res://addons/fpc/reticles/reticle_1.tscn" +HEAD = NodePath("Head") +CAMERA = NodePath("Head/Camera") +HEADBOB_ANIMATION = NodePath("Head/HeadbobAnimation") +JUMP_ANIMATION = NodePath("Head/JumpAnimation") +CROUCH_ANIMATION = NodePath("CrouchAnimation") +COLLISION_MESH = NodePath("Collision") + +[node name="Mesh" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +mesh = SubResource("CapsuleMesh_jw1de") + +[node name="Collision" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("CapsuleShape3D_uy03j") + +[node name="CrouchAnimation" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_5e5t5") +} + +[node name="Head" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0) + +[node name="Camera" type="Camera3D" parent="Head"] + +[node name="HeadbobAnimation" type="AnimationPlayer" parent="Head"] +libraries = { +"": SubResource("AnimationLibrary_o0unb") +} +blend_times = [&"RESET", &"RESET", 0.5, &"RESET", &"walk", 0.5, &"walk", &"RESET", 0.5] + +[node name="JumpAnimation" type="AnimationPlayer" parent="Head"] +libraries = { +"": SubResource("AnimationLibrary_qeg5r") +} +speed_scale = 4.0 + +[node name="UserInterface" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 1 + +[node name="DebugPanel" type="PanelContainer" parent="UserInterface"] +visible = false +layout_mode = 0 +offset_left = 10.0 +offset_top = 10.0 +offset_right = 453.0 +offset_bottom = 50.0 +theme = SubResource("Theme_wdf0f") +script = ExtResource("3_x1wcc") + +[node name="MarginContainer" type="MarginContainer" parent="UserInterface/DebugPanel"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="UserInterface/DebugPanel/MarginContainer"] +layout_mode = 2 + +[node name="CrouchCeilingDetection" type="ShapeCast3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("SphereShape3D_k4wwl") +target_position = Vector3(0, 0.5, 0) + +[node name="EditorModule" type="Node" parent="."] +script = ExtResource("3_v3ckk") diff --git a/quality-godot-first-person-2-2.6.1/addons/fpc/debug.gd b/quality-godot-first-person-2-2.6.1/addons/fpc/debug.gd new file mode 100644 index 0000000..efdb7a4 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/addons/fpc/debug.gd @@ -0,0 +1,18 @@ +extends PanelContainer + + +func _process(delta): + if visible: + pass + +func add_property(title : String, value, order : int): # This can either be called once for a static property or called every frame for a dynamic property + var target + target = $MarginContainer/VBoxContainer.find_child(title, true, false) # I have no idea what true and false does here, the function should be more specific + if !target: + target = Label.new() # Debug lines are of type Label + $MarginContainer/VBoxContainer.add_child(target) + target.name = title + target.text = title + ": " + str(value) + elif visible: + target.text = title + ": " + str(value) + $MarginContainer/VBoxContainer.move_child(target, order) diff --git a/quality-godot-first-person-2-2.6.1/addons/fpc/reticles/reticle_0.tscn b/quality-godot-first-person-2-2.6.1/addons/fpc/reticles/reticle_0.tscn new file mode 100644 index 0000000..2828124 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/addons/fpc/reticles/reticle_0.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=2 format=3 uid="uid://coqpusufa8a6k"] + +[sub_resource type="GDScript" id="GDScript_10f85"] +script/source = "extends CenterContainer + + +@export_category(\"Reticle\") +@export_group(\"Nodes\") +@export var character : CharacterBody3D + +@export_group(\"Settings\") +@export var dot_size : int = 1 +@export var dot_color : Color = Color.WHITE + + +func _process(_delta): + if visible: # If the reticle is disabled (not visible), don't bother updating it + update_reticle_settings() + +func update_reticle_settings(): + $dot.scale.x = dot_size + $dot.scale.y = dot_size + $dot.color = dot_color +" + +[node name="Reticle" type="CenterContainer"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_10f85") + +[node name="dot" type="Polygon2D" parent="."] +polygon = PackedVector2Array(-1, -1, 1, -1, 1, 1, -1, 1) diff --git a/quality-godot-first-person-2-2.6.1/addons/fpc/reticles/reticle_1.tscn b/quality-godot-first-person-2-2.6.1/addons/fpc/reticles/reticle_1.tscn new file mode 100644 index 0000000..bb83b83 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/addons/fpc/reticles/reticle_1.tscn @@ -0,0 +1,104 @@ +[gd_scene load_steps=2 format=3 uid="uid://3mij3cjhkwsm"] + +[sub_resource type="GDScript" id="GDScript_a8kpl"] +script/source = "extends CenterContainer + + +@export_category(\"Reticle\") +@export_group(\"Nodes\") +@export var reticle_lines : Array[Line2D] +@export var character : CharacterBody3D + +@export_group(\"Animate\") +@export var animated_reticle : bool = true +@export var reticle_speed : float = 0.5 +@export var reticle_spread : float = 4.0 + +@export_group(\"Dot Settings\") +@export var dot_size : int = 1 +@export var dot_color : Color = Color.WHITE + +@export_group(\"Line Settings\") +@export var line_color : Color = Color.WHITE +@export var line_width : int = 2 +@export var line_length : int = 10 +@export var line_distance : int = 5 +@export_enum(\"None\", \"Round\") var cap_mode : int = 0 + + +func _process(_delta): + if visible: # If the reticle is disabled (not visible), don't bother updating it + update_reticle_settings() + if animated_reticle: + animate_reticle_lines() + + +func animate_reticle_lines(): + var vel = character.get_real_velocity() + var origin = Vector3(0,0,0) + var pos = Vector2(0,0) + var speed = origin.distance_to(vel) + + reticle_lines[0].position = lerp(reticle_lines[0].position, pos + Vector2(0, -speed * reticle_spread), reticle_speed) + reticle_lines[1].position = lerp(reticle_lines[1].position, pos + Vector2(-speed * reticle_spread, 0), reticle_speed) + reticle_lines[2].position = lerp(reticle_lines[2].position, pos + Vector2(speed * reticle_spread, 0), reticle_speed) + reticle_lines[3].position = lerp(reticle_lines[3].position, pos + Vector2(0, speed * reticle_spread), reticle_speed) + + +func update_reticle_settings(): + # Dot + $dot.scale.x = dot_size + $dot.scale.y = dot_size + $dot.color = dot_color + + # Lines + for line in reticle_lines: + line.default_color = line_color + line.width = line_width + if cap_mode == 0: + line.begin_cap_mode = Line2D.LINE_CAP_NONE + line.end_cap_mode = Line2D.LINE_CAP_NONE + elif cap_mode == 1: + line.begin_cap_mode = Line2D.LINE_CAP_ROUND + line.end_cap_mode = Line2D.LINE_CAP_ROUND + + # Please someone find a better way to do this + reticle_lines[0].points[0].y = -line_distance + reticle_lines[0].points[1].y = -line_length - line_distance + reticle_lines[1].points[0].x = -line_distance + reticle_lines[1].points[1].x = -line_length - line_distance + reticle_lines[2].points[0].x = line_distance + reticle_lines[2].points[1].x = line_length + line_distance + reticle_lines[3].points[0].y = line_distance + reticle_lines[3].points[1].y = line_length + line_distance +" + +[node name="Reticle" type="CenterContainer" node_paths=PackedStringArray("reticle_lines")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_a8kpl") +reticle_lines = [NodePath("top"), NodePath("left"), NodePath("right"), NodePath("bottom")] + +[node name="dot" type="Polygon2D" parent="."] +polygon = PackedVector2Array(-1, -1, 1, -1, 1, 1, -1, 1) + +[node name="top" type="Line2D" parent="."] +points = PackedVector2Array(0, -5, 0, -15) +width = 2.0 + +[node name="left" type="Line2D" parent="."] +points = PackedVector2Array(-5, 0, -15, 0) +width = 2.0 + +[node name="right" type="Line2D" parent="."] +points = PackedVector2Array(5, 0, 15, 0) +width = 2.0 + +[node name="bottom" type="Line2D" parent="."] +points = PackedVector2Array(0, 5, 0, 15) +width = 2.0 diff --git a/quality-godot-first-person-2-2.6.1/icon.svg b/quality-godot-first-person-2-2.6.1/icon.svg new file mode 100644 index 0000000..ea6ce87 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/icon.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/quality-godot-first-person-2-2.6.1/icon.svg.import b/quality-godot-first-person-2-2.6.1/icon.svg.import new file mode 100644 index 0000000..9e0a681 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://64npoko7rqya" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/quality-godot-first-person-2-2.6.1/project.godot b/quality-godot-first-person-2-2.6.1/project.godot new file mode 100644 index 0000000..4626ad9 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/project.godot @@ -0,0 +1,65 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="first person controller 2.0" +run/main_scene="res://test_world.tscn" +config/features=PackedStringArray("4.3", "Forward Plus") +config/icon="res://icon.svg" + +[display] + +window/size/mode=2 + +[input] + +ui_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +ui_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +ui_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +ui_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} +crouch={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":99,"location":0,"echo":false,"script":null) +] +} +sprint={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} diff --git a/quality-godot-first-person-2-2.6.1/test_world.tscn b/quality-godot-first-person-2-2.6.1/test_world.tscn new file mode 100644 index 0000000..b6901b9 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/test_world.tscn @@ -0,0 +1,106 @@ +[gd_scene load_steps=15 format=3 uid="uid://cs4drhmc1bql5"] + +[ext_resource type="PackedScene" uid="uid://cc1m2a1obsyn4" path="res://addons/fpc/character.tscn" id="1_e18vq"] +[ext_resource type="Texture2D" uid="uid://pe7a4weirj2g" path="res://textures/dark.png" id="2_08fdt"] +[ext_resource type="Texture2D" uid="uid://cxjxvqmf4boxq" path="res://textures/green.png" id="3_q4clv"] +[ext_resource type="Texture2D" uid="uid://dsv4jm4vydflb" path="res://textures/orange.png" id="4_1ns5t"] + +[sub_resource type="PhysicalSkyMaterial" id="PhysicalSkyMaterial_edcox"] +ground_color = Color(0.160784, 0.815686, 0.905882, 1) + +[sub_resource type="Sky" id="Sky_2iust"] +sky_material = SubResource("PhysicalSkyMaterial_edcox") + +[sub_resource type="Environment" id="Environment_20rw3"] +background_mode = 2 +sky = SubResource("Sky_2iust") +tonemap_mode = 1 +ssao_enabled = true + +[sub_resource type="Gradient" id="Gradient_ur0vy"] +colors = PackedColorArray(0, 0.476245, 0.0193456, 1, 0.360494, 0.612721, 0.119744, 1) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_jd3pw"] +frequency = 0.0027 + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_7akuf"] +width = 1024 +height = 1024 +in_3d_space = true +seamless = true +color_ramp = SubResource("Gradient_ur0vy") +noise = SubResource("FastNoiseLite_jd3pw") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_67ysu"] +albedo_texture = SubResource("NoiseTexture2D_7akuf") +uv1_scale = Vector3(0.1, 0.1, 0.1) +uv1_triplanar = true + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gomnb"] +albedo_texture = ExtResource("2_08fdt") +metallic = 0.81 +metallic_specular = 0.2 +roughness = 0.5 +uv1_triplanar = true +uv1_triplanar_sharpness = 0.000850145 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_u0sbk"] +albedo_texture = ExtResource("3_q4clv") +metallic = 0.81 +metallic_specular = 0.2 +roughness = 0.5 +uv1_triplanar = true +uv1_triplanar_sharpness = 0.000850145 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_7j4uu"] +albedo_texture = ExtResource("4_1ns5t") +metallic = 0.81 +metallic_specular = 0.2 +roughness = 0.5 +uv1_triplanar = true +uv1_triplanar_sharpness = 0.000850145 + +[node name="test_world" type="Node3D"] + +[node name="Character" parent="." instance=ExtResource("1_e18vq")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_20rw3") + +[node name="sun" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.87959, -0.436605, 0.188936, 0, 0.397148, 0.917755, -0.475732, -0.807248, 0.349328, 0, 0, 0) +light_energy = 2.0 +shadow_enabled = true + +[node name="terrain" type="Node3D" parent="."] + +[node name="CSGBox3D" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -0.5, 10) +use_collision = true +size = Vector3(30, 1, 30) +material = SubResource("StandardMaterial3D_67ysu") + +[node name="CSGBox3D2" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, -10) +use_collision = true +size = Vector3(10, 1, 10) +material = SubResource("StandardMaterial3D_gomnb") + +[node name="CSGBox3D3" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 1.8, -13) +use_collision = true +size = Vector3(4, 0.5, 4) +material = SubResource("StandardMaterial3D_gomnb") + +[node name="CSGBox3D4" type="CSGBox3D" parent="terrain"] +transform = Transform3D(0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 0, 0, 1, -9.5, 1.2, -10) +use_collision = true +size = Vector3(10, 1, 10) +material = SubResource("StandardMaterial3D_u0sbk") + +[node name="CSGBox3D5" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 3, -15.5) +use_collision = true +size = Vector3(19, 8, 1) +material = SubResource("StandardMaterial3D_7j4uu") diff --git a/quality-godot-first-person-2-2.6.1/textures/dark.png b/quality-godot-first-person-2-2.6.1/textures/dark.png new file mode 100644 index 0000000..69be211 Binary files /dev/null and b/quality-godot-first-person-2-2.6.1/textures/dark.png differ diff --git a/quality-godot-first-person-2-2.6.1/textures/dark.png.import b/quality-godot-first-person-2-2.6.1/textures/dark.png.import new file mode 100644 index 0000000..2a82a3f --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/textures/dark.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://pe7a4weirj2g" +path.s3tc="res://.godot/imported/dark.png-6d46f668c80e231a58e570df85aad257.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/dark.png" +dest_files=["res://.godot/imported/dark.png-6d46f668c80e231a58e570df85aad257.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/quality-godot-first-person-2-2.6.1/textures/green.png b/quality-godot-first-person-2-2.6.1/textures/green.png new file mode 100644 index 0000000..7bc7cf8 Binary files /dev/null and b/quality-godot-first-person-2-2.6.1/textures/green.png differ diff --git a/quality-godot-first-person-2-2.6.1/textures/green.png.import b/quality-godot-first-person-2-2.6.1/textures/green.png.import new file mode 100644 index 0000000..7c7e044 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/textures/green.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cxjxvqmf4boxq" +path.s3tc="res://.godot/imported/green.png-b4f8ddc6b00d4e627f0e027e2e1193bf.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/green.png" +dest_files=["res://.godot/imported/green.png-b4f8ddc6b00d4e627f0e027e2e1193bf.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/quality-godot-first-person-2-2.6.1/textures/orange.png b/quality-godot-first-person-2-2.6.1/textures/orange.png new file mode 100644 index 0000000..dec5b59 Binary files /dev/null and b/quality-godot-first-person-2-2.6.1/textures/orange.png differ diff --git a/quality-godot-first-person-2-2.6.1/textures/orange.png.import b/quality-godot-first-person-2-2.6.1/textures/orange.png.import new file mode 100644 index 0000000..311f8ac --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/textures/orange.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dsv4jm4vydflb" +path.s3tc="res://.godot/imported/orange.png-6785d3f8216fd22318e8ea839823715b.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/orange.png" +dest_files=["res://.godot/imported/orange.png-6785d3f8216fd22318e8ea839823715b.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/quality-godot-first-person-2-2.6.1/textures/purple.png b/quality-godot-first-person-2-2.6.1/textures/purple.png new file mode 100644 index 0000000..48a51c1 Binary files /dev/null and b/quality-godot-first-person-2-2.6.1/textures/purple.png differ diff --git a/quality-godot-first-person-2-2.6.1/textures/purple.png.import b/quality-godot-first-person-2-2.6.1/textures/purple.png.import new file mode 100644 index 0000000..9dc0969 --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/textures/purple.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cl4kewig3pk7s" +path="res://.godot/imported/purple.png-23488e84f4f0a47488be2c78494f2155.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://textures/purple.png" +dest_files=["res://.godot/imported/purple.png-23488e84f4f0a47488be2c78494f2155.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/quality-godot-first-person-2-2.6.1/textures/red.png b/quality-godot-first-person-2-2.6.1/textures/red.png new file mode 100644 index 0000000..bf1cb17 Binary files /dev/null and b/quality-godot-first-person-2-2.6.1/textures/red.png differ diff --git a/quality-godot-first-person-2-2.6.1/textures/red.png.import b/quality-godot-first-person-2-2.6.1/textures/red.png.import new file mode 100644 index 0000000..c8c15aa --- /dev/null +++ b/quality-godot-first-person-2-2.6.1/textures/red.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1h161t0v6hau" +path="res://.godot/imported/red.png-3cad0ca19141406d60f5fd2311159a86.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://textures/red.png" +dest_files=["res://.godot/imported/red.png-3cad0ca19141406d60f5fd2311159a86.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/quality-godot-first-person-2-main/.gitattributes b/quality-godot-first-person-2-main/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/quality-godot-first-person-2-main/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/quality-godot-first-person-2-main/.gitignore b/quality-godot-first-person-2-main/.gitignore new file mode 100644 index 0000000..4709183 --- /dev/null +++ b/quality-godot-first-person-2-main/.gitignore @@ -0,0 +1,2 @@ +# Godot 4+ specific ignores +.godot/ diff --git a/quality-godot-first-person-2-main/LICENSE b/quality-godot-first-person-2-main/LICENSE new file mode 100644 index 0000000..f34733d --- /dev/null +++ b/quality-godot-first-person-2-main/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Colormatic + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/quality-godot-first-person-2-main/README.md b/quality-godot-first-person-2-main/README.md new file mode 100644 index 0000000..0acb1cb --- /dev/null +++ b/quality-godot-first-person-2-main/README.md @@ -0,0 +1,67 @@ +# quality-godot-first-person-2 +Actually good first person controller for the Godot Engine. +MIT License (credit Colormatic Studios) + +This first person controller was made because there aren't many first person controllers for Godot, and the ones that do exist are pretty bad. +It is highly customizable and comes with many features, QOL, and clean code. + +Some parts came from StayAtHomeDev's FPS tutorial. You can find that [here](https://www.youtube.com/playlist?list=PLEHvj4yeNfeF6s-UVs5Zx5TfNYmeCiYwf). + +# Directions +Move with WASD, space to jump, shift to sprint, C to crouch. + +**FEATURES:** +- Extremely configurable +- In-air momentum +- Motion smoothing +- FOV smoothing +- Movement animations +- Crouching +- Sprinting +- 2 crosshairs/reticles, one is animated (more to come?) +- Controller/GamePad support (enabled through code, see wiki) +- In-editor tools (enable editable children to use) + +If you make a cool game with this addon, I would love to hear about it! + +# Wiki +**To start out**, you should probably remap all of the movement keys to your own control set. + +You can make this a super basic controller by just disabling everything. + +**How to add controller/GamePad support** +- In the controls export group, there is a commented section at the end that says "Uncomment this if you want full controller support". Uncomment that block. +- Make a key map for each direction (left, right, up, down) and map them to your joystick. +- Write in these keymaps in the controls section of the player settings. +- In the `handle_head_rotation` function, there is another block of commented code that says the same thing. Uncomment that too. +- You should now be able to look around with the joystick. Make sure you add the other controls to the input map. (movement, jumping, crouching, sprinting, etc.) + +**Slope/staircase:** +Credit to [roberto-urbani23](https://github.com/roberto-urbani23) +In the character inspector, you can uncheck Stop on Slope and set the max angle to 89 (for some reason, 90 will make the player stuck). Also Snap Length to 1 otherwise your character will not remain attached to stairs if you sprint while going downstairs. + +**How to change settings:** +Click on the character node and there should be settings in the "Feature Settings" group. + +**How to add animations for a mesh:** +- Create a function for your animation and attach it to `_physics_process` to call it every frame. +- Use `input_dir` as a boolean (it is actually a `Vector2`) to know if the player is walking. +- Use the `state` member variable to tell if the player is sprinting or crouching. +- Use the `is_on_floor` function to tell if the player is standing or falling. + +**How to change reticles (crosshairs):** +Change the "Default Reticle" setting to your reticle file. +During runtime: +Use the `change_reticle` function on the character. + +**How to create a new reticle:** +- Choose a reticle to base it off of. +- Open that reticle and save it as a new reticle. +- Remove the script from the reticle and create a new one. (for some reason you have to do this) +- Edit the reticle to your needs. +- Follow the "how to change reticles" directions to use it. + +**How to use the editor tools:** +- Enable editable children on the `CharacterBody` node +- Use the options in the Properties tab to change things +- These changes apply in runtime as well diff --git a/quality-godot-first-person-2-main/addons/fpc/EditorModule.gd b/quality-godot-first-person-2-main/addons/fpc/EditorModule.gd new file mode 100644 index 0000000..0a3a74f --- /dev/null +++ b/quality-godot-first-person-2-main/addons/fpc/EditorModule.gd @@ -0,0 +1,49 @@ +@tool +extends Node + +# This does not effect runtime yet but will in the future. + +@export_category("Controller Editor Module") +@export_range(-360.0, 360.0, 0.01, "or_greater", "or_less") var head_y_rotation : float = 0.0: + set(new_rotation): + if HEAD: + head_y_rotation = new_rotation + HEAD.rotation.y = deg_to_rad(head_y_rotation) + update_configuration_warnings() +@export_range(-90.0, 90.0, 0.01, "or_greater", "or_less") var head_x_rotation : float = 0.0: + set(new_rotation): + if HEAD: + head_x_rotation = new_rotation + HEAD.rotation.x = deg_to_rad(head_x_rotation) + update_configuration_warnings() + +@export_group("Nodes") +@export var CHARACTER : CharacterBody3D +@export var head_path : String = "Head" # Relative to the parent node +#@export var CAMERA : Camera3D +#@export var HEADBOB_ANIMATION : AnimationPlayer +#@export var JUMP_ANIMATION : AnimationPlayer +#@export var CROUCH_ANIMATION : AnimationPlayer +#@export var COLLISION_MESH : CollisionShape3D + +@onready var HEAD = get_node("../" + head_path) + + +func _ready(): + if !Engine.is_editor_hint(): + #print("not editor") + HEAD.rotation.y = deg_to_rad(head_y_rotation) + HEAD.rotation.x = deg_to_rad(head_x_rotation) + + +func _get_configuration_warnings(): + var warnings = [] + + if head_y_rotation > 360: + warnings.append("The head rotation is greater than 360") + + if head_y_rotation < -360: + warnings.append("The head rotation is less than -360") + + # Returning an empty array gives no warnings + return warnings diff --git a/quality-godot-first-person-2-main/addons/fpc/character.gd b/quality-godot-first-person-2-main/addons/fpc/character.gd new file mode 100644 index 0000000..5a5f7f7 --- /dev/null +++ b/quality-godot-first-person-2-main/addons/fpc/character.gd @@ -0,0 +1,488 @@ +# COPYRIGHT Colormatic Studios +# MIT license +# Quality Godot First Person Controller v2 + + +extends CharacterBody3D + + +#region Character Export Group + +## The settings for the character's movement and feel. +@export_category("Character") +## The speed that the character moves at without crouching or sprinting. +@export var base_speed : float = 3.0 +## The speed that the character moves at when sprinting. +@export var sprint_speed : float = 6.0 +## The speed that the character moves at when crouching. +@export var crouch_speed : float = 1.0 + +## How fast the character speeds up and slows down when Motion Smoothing is on. +@export var acceleration : float = 10.0 +## How high the player jumps. +@export var jump_velocity : float = 4.5 +## How far the player turns when the mouse is moved. +@export var mouse_sensitivity : float = 0.1 +## Invert the X axis input for the camera. +@export var invert_camera_x_axis : bool = false +## Invert the Y axis input for the camera. +@export var invert_camera_y_axis : bool = false +## Whether the player can use movement inputs. Does not stop outside forces or jumping. See Jumping Enabled. +@export var immobile : bool = false +## The reticle file to import at runtime. By default are in res://addons/fpc/reticles/. Set to an empty string to remove. +@export_file var default_reticle + +#endregion + +#region Nodes Export Group + +@export_group("Nodes") +## A reference to the camera for use in the character script. This is the parent node to the camera and is rotated instead of the camera for mouse input. +@export var HEAD : Node3D +## A reference to the camera for use in the character script. +@export var CAMERA : Camera3D +## A reference to the headbob animation for use in the character script. +@export var HEADBOB_ANIMATION : AnimationPlayer +## A reference to the jump animation for use in the character script. +@export var JUMP_ANIMATION : AnimationPlayer +## A reference to the crouch animation for use in the character script. +@export var CROUCH_ANIMATION : AnimationPlayer +## A reference to the the player's collision shape for use in the character script. +@export var COLLISION_MESH : CollisionShape3D + +#endregion + +#region Controls Export Group + +# We are using UI controls because they are built into Godot Engine so they can be used right away +@export_group("Controls") +## Use the Input Map to map a mouse/keyboard input to an action and add a reference to it to this dictionary to be used in the script. +@export var controls : Dictionary = { + LEFT = "ui_left", + RIGHT = "ui_right", + FORWARD = "ui_up", + BACKWARD = "ui_down", + JUMP = "ui_accept", + CROUCH = "crouch", + SPRINT = "sprint", + PAUSE = "ui_cancel" + } +@export_subgroup("Controller Specific") +## This only affects how the camera is handled, the rest should be covered by adding controller inputs to the existing actions in the Input Map. +@export var controller_support : bool = false +## Use the Input Map to map a controller input to an action and add a reference to it to this dictionary to be used in the script. +@export var controller_controls : Dictionary = { + LOOK_LEFT = "look_left", + LOOK_RIGHT = "look_right", + LOOK_UP = "look_up", + LOOK_DOWN = "look_down" + } +## The sensitivity of the analog stick that controls camera rotation. Lower is less sensitive and higher is more sensitive. +@export_range(0.001, 1, 0.001) var look_sensitivity : float = 0.035 + +#endregion + +#region Feature Settings Export Group + +@export_group("Feature Settings") +## Enable or disable jumping. Useful for restrictive storytelling environments. +@export var jumping_enabled : bool = true +## Whether the player can move in the air or not. +@export var in_air_momentum : bool = true +## Smooths the feel of walking. +@export var motion_smoothing : bool = true +## Enables or disables sprinting. +@export var sprint_enabled : bool = true +## Toggles the sprinting state when button is pressed or requires the player to hold the button down to remain sprinting. +@export_enum("Hold to Sprint", "Toggle Sprint") var sprint_mode : int = 0 +## Enables or disables crouching. +@export var crouch_enabled : bool = true +## Toggles the crouch state when button is pressed or requires the player to hold the button down to remain crouched. +@export_enum("Hold to Crouch", "Toggle Crouch") var crouch_mode : int = 0 +## Wether sprinting should effect FOV. +@export var dynamic_fov : bool = true +## If the player holds down the jump button, should the player keep hopping. +@export var continuous_jumping : bool = true +## Enables the view bobbing animation. +@export var view_bobbing : bool = true +## Enables an immersive animation when the player jumps and hits the ground. +@export var jump_animation : bool = true +## This determines wether the player can use the pause button, not wether the game will actually pause. +@export var pausing_enabled : bool = true +## Use with caution. +@export var gravity_enabled : bool = true +## If your game changes the gravity value during gameplay, check this property to allow the player to experience the change in gravity. +@export var dynamic_gravity : bool = false + +#endregion + +#region Member Variable Initialization + +# These are variables used in this script that don't need to be exposed in the editor. +var speed : float = base_speed +var current_speed : float = 0.0 +# States: normal, crouching, sprinting +var state : String = "normal" +var low_ceiling : bool = false # This is for when the ceiling is too low and the player needs to crouch. +var was_on_floor : bool = true # Was the player on the floor last frame (for landing animation) + +# The reticle should always have a Control node as the root +var RETICLE : Control + +# Get the gravity from the project settings to be synced with RigidBody nodes +var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity") # Don't set this as a const, see the gravity section in _physics_process + +# Stores mouse input for rotating the camera in the physics process +var mouseInput : Vector2 = Vector2(0,0) + +#endregion + + + +#region Main Control Flow + +func _ready(): + #It is safe to comment this line if your game doesn't start with the mouse captured + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + + # If the controller is rotated in a certain direction for game design purposes, redirect this rotation into the head. + HEAD.rotation.y = rotation.y + rotation.y = 0 + + if default_reticle: + change_reticle(default_reticle) + + initialize_animations() + check_controls() + enter_normal_state() + + +func _process(_delta): + if pausing_enabled: + handle_pausing() + + update_debug_menu_per_frame() + + +func _physics_process(delta): # Most things happen here. + # Gravity + if dynamic_gravity: + gravity = ProjectSettings.get_setting("physics/3d/default_gravity") + if not is_on_floor() and gravity and gravity_enabled: + velocity.y -= gravity * delta + + handle_jumping() + + var input_dir = Vector2.ZERO + + if not immobile: # Immobility works by interrupting user input, so other forces can still be applied to the player + input_dir = Input.get_vector(controls.LEFT, controls.RIGHT, controls.FORWARD, controls.BACKWARD) + + handle_movement(delta, input_dir) + + handle_head_rotation() + + # The player is not able to stand up if the ceiling is too low + low_ceiling = $CrouchCeilingDetection.is_colliding() + + handle_state(input_dir) + if dynamic_fov: # This may be changed to an AnimationPlayer + update_camera_fov() + + if view_bobbing: + play_headbob_animation(input_dir) + + if jump_animation: + play_jump_animation() + + update_debug_menu_per_tick() + + was_on_floor = is_on_floor() # This must always be at the end of physics_process + +#endregion + +#region Input Handling + +func handle_jumping(): + if jumping_enabled: + if continuous_jumping: # Hold down the jump button + if Input.is_action_pressed(controls.JUMP) and is_on_floor() and !low_ceiling: + if jump_animation: + JUMP_ANIMATION.play("jump", 0.25) + velocity.y += jump_velocity # Adding instead of setting so jumping on slopes works properly + else: + if Input.is_action_just_pressed(controls.JUMP) and is_on_floor() and !low_ceiling: + if jump_animation: + JUMP_ANIMATION.play("jump", 0.25) + velocity.y += jump_velocity + + +func handle_movement(delta, input_dir): + var direction = input_dir.rotated(-HEAD.rotation.y) + direction = Vector3(direction.x, 0, direction.y) + move_and_slide() + + if in_air_momentum: + if is_on_floor(): + if motion_smoothing: + velocity.x = lerp(velocity.x, direction.x * speed, acceleration * delta) + velocity.z = lerp(velocity.z, direction.z * speed, acceleration * delta) + else: + velocity.x = direction.x * speed + velocity.z = direction.z * speed + else: + if motion_smoothing: + velocity.x = lerp(velocity.x, direction.x * speed, acceleration * delta) + velocity.z = lerp(velocity.z, direction.z * speed, acceleration * delta) + else: + velocity.x = direction.x * speed + velocity.z = direction.z * speed + + +func handle_head_rotation(): + if invert_camera_x_axis: + HEAD.rotation_degrees.y -= mouseInput.x * mouse_sensitivity * -1 + else: + HEAD.rotation_degrees.y -= mouseInput.x * mouse_sensitivity + + if invert_camera_y_axis: + HEAD.rotation_degrees.x -= mouseInput.y * mouse_sensitivity * -1 + else: + HEAD.rotation_degrees.x -= mouseInput.y * mouse_sensitivity + + if controller_support: + var controller_view_rotation = Input.get_vector(controller_controls.LOOK_DOWN, controller_controls.LOOK_UP, controller_controls.LOOK_RIGHT, controller_controls.LOOK_LEFT) * look_sensitivity # These are inverted because of the nature of 3D rotation. + if invert_camera_x_axis: + HEAD.rotation.x += controller_view_rotation.x * -1 + else: + HEAD.rotation.x += controller_view_rotation.x + + if invert_camera_y_axis: + HEAD.rotation.y += controller_view_rotation.y * -1 + else: + HEAD.rotation.y += controller_view_rotation.y + + mouseInput = Vector2(0,0) + HEAD.rotation.x = clamp(HEAD.rotation.x, deg_to_rad(-90), deg_to_rad(90)) + + +func check_controls(): # If you add a control, you might want to add a check for it here. + # The actions are being disabled so the engine doesn't halt the entire project in debug mode + if !InputMap.has_action(controls.JUMP): + push_error("No control mapped for jumping. Please add an input map control. Disabling jump.") + jumping_enabled = false + if !InputMap.has_action(controls.LEFT): + push_error("No control mapped for move left. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.RIGHT): + push_error("No control mapped for move right. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.FORWARD): + push_error("No control mapped for move forward. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.BACKWARD): + push_error("No control mapped for move backward. Please add an input map control. Disabling movement.") + immobile = true + if !InputMap.has_action(controls.PAUSE): + push_error("No control mapped for pause. Please add an input map control. Disabling pausing.") + pausing_enabled = false + if !InputMap.has_action(controls.CROUCH): + push_error("No control mapped for crouch. Please add an input map control. Disabling crouching.") + crouch_enabled = false + if !InputMap.has_action(controls.SPRINT): + push_error("No control mapped for sprint. Please add an input map control. Disabling sprinting.") + sprint_enabled = false + +#endregion + +#region State Handling + +func handle_state(moving): + if sprint_enabled: + if sprint_mode == 0: + if Input.is_action_pressed(controls.SPRINT) and state != "crouching": + if moving: + if state != "sprinting": + enter_sprint_state() + else: + if state == "sprinting": + enter_normal_state() + elif state == "sprinting": + enter_normal_state() + elif sprint_mode == 1: + if moving: + # If the player is holding sprint before moving, handle that scenario + if Input.is_action_pressed(controls.SPRINT) and state == "normal": + enter_sprint_state() + if Input.is_action_just_pressed(controls.SPRINT): + match state: + "normal": + enter_sprint_state() + "sprinting": + enter_normal_state() + elif state == "sprinting": + enter_normal_state() + + if crouch_enabled: + if crouch_mode == 0: + if Input.is_action_pressed(controls.CROUCH) and state != "sprinting": + if state != "crouching": + enter_crouch_state() + elif state == "crouching" and !$CrouchCeilingDetection.is_colliding(): + enter_normal_state() + elif crouch_mode == 1: + if Input.is_action_just_pressed(controls.CROUCH): + match state: + "normal": + enter_crouch_state() + "crouching": + if !$CrouchCeilingDetection.is_colliding(): + enter_normal_state() + + +# Any enter state function should only be called once when you want to enter that state, not every frame. +func enter_normal_state(): + #print("entering normal state") + var prev_state = state + if prev_state == "crouching": + CROUCH_ANIMATION.play_backwards("crouch") + state = "normal" + speed = base_speed + +func enter_crouch_state(): + #print("entering crouch state") + state = "crouching" + speed = crouch_speed + CROUCH_ANIMATION.play("crouch") + +func enter_sprint_state(): + #print("entering sprint state") + var prev_state = state + if prev_state == "crouching": + CROUCH_ANIMATION.play_backwards("crouch") + state = "sprinting" + speed = sprint_speed + +#endregion + +#region Animation Handling + +func initialize_animations(): + # Reset the camera position + # If you want to change the default head height, change these animations. + HEADBOB_ANIMATION.play("RESET") + JUMP_ANIMATION.play("RESET") + CROUCH_ANIMATION.play("RESET") + +func play_headbob_animation(moving): + if moving and is_on_floor(): + var use_headbob_animation : String + match state: + "normal","crouching": + use_headbob_animation = "walk" + "sprinting": + use_headbob_animation = "sprint" + + var was_playing : bool = false + if HEADBOB_ANIMATION.current_animation == use_headbob_animation: + was_playing = true + + HEADBOB_ANIMATION.play(use_headbob_animation, 0.25) + HEADBOB_ANIMATION.speed_scale = (current_speed / base_speed) * 1.75 + if !was_playing: + HEADBOB_ANIMATION.seek(float(randi() % 2)) # Randomize the initial headbob direction + # Let me explain that piece of code because it looks like it does the opposite of what it actually does. + # The headbob animation has two starting positions. One is at 0 and the other is at 1. + # randi() % 2 returns either 0 or 1, and so the animation randomly starts at one of the starting positions. + # This code is extremely performant but it makes no sense. + + else: + if HEADBOB_ANIMATION.current_animation == "sprint" or HEADBOB_ANIMATION.current_animation == "walk": + HEADBOB_ANIMATION.speed_scale = 1 + HEADBOB_ANIMATION.play("RESET", 1) + +func play_jump_animation(): + if !was_on_floor and is_on_floor(): # The player just landed + var facing_direction : Vector3 = CAMERA.get_global_transform().basis.x + var facing_direction_2D : Vector2 = Vector2(facing_direction.x, facing_direction.z).normalized() + var velocity_2D : Vector2 = Vector2(velocity.x, velocity.z).normalized() + + # Compares velocity direction against the camera direction (via dot product) to determine which landing animation to play. + var side_landed : int = round(velocity_2D.dot(facing_direction_2D)) + + if side_landed > 0: + JUMP_ANIMATION.play("land_right", 0.25) + elif side_landed < 0: + JUMP_ANIMATION.play("land_left", 0.25) + else: + JUMP_ANIMATION.play("land_center", 0.25) + +#endregion + +#region Debug Menu + +func update_debug_menu_per_frame(): + $UserInterface/DebugPanel.add_property("FPS", Performance.get_monitor(Performance.TIME_FPS), 0) + var status : String = state + if !is_on_floor(): + status += " in the air" + $UserInterface/DebugPanel.add_property("State", status, 4) + + +func update_debug_menu_per_tick(): + # Big thanks to github.com/LorenzoAncora for the concept of the improved debug values + current_speed = Vector3.ZERO.distance_to(get_real_velocity()) + $UserInterface/DebugPanel.add_property("Speed", snappedf(current_speed, 0.001), 1) + $UserInterface/DebugPanel.add_property("Target speed", speed, 2) + var cv : Vector3 = get_real_velocity() + var vd : Array[float] = [ + snappedf(cv.x, 0.001), + snappedf(cv.y, 0.001), + snappedf(cv.z, 0.001) + ] + var readable_velocity : String = "X: " + str(vd[0]) + " Y: " + str(vd[1]) + " Z: " + str(vd[2]) + $UserInterface/DebugPanel.add_property("Velocity", readable_velocity, 3) + + +func _unhandled_input(event : InputEvent): + if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + mouseInput.x += event.relative.x + mouseInput.y += event.relative.y + # Toggle debug menu + elif event is InputEventKey: + if event.is_released(): + # Where we're going, we don't need InputMap + if event.keycode == 4194338: # F7 + $UserInterface/DebugPanel.visible = !$UserInterface/DebugPanel.visible + +#endregion + +#region Misc Functions + +func change_reticle(reticle): # Yup, this function is kinda strange + if RETICLE: + RETICLE.queue_free() + + RETICLE = load(reticle).instantiate() + RETICLE.character = self + $UserInterface.add_child(RETICLE) + + +func update_camera_fov(): + if state == "sprinting": + CAMERA.fov = lerp(CAMERA.fov, 85.0, 0.3) + else: + CAMERA.fov = lerp(CAMERA.fov, 75.0, 0.3) + +func handle_pausing(): + if Input.is_action_just_pressed(controls.PAUSE): + # You may want another node to handle pausing, because this player may get paused too. + match Input.mouse_mode: + Input.MOUSE_MODE_CAPTURED: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + #get_tree().paused = false + Input.MOUSE_MODE_VISIBLE: + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + #get_tree().paused = false + +#endregion diff --git a/quality-godot-first-person-2-main/addons/fpc/character.tscn b/quality-godot-first-person-2-main/addons/fpc/character.tscn new file mode 100644 index 0000000..3cfd7c8 --- /dev/null +++ b/quality-godot-first-person-2-main/addons/fpc/character.tscn @@ -0,0 +1,455 @@ +[gd_scene load_steps=22 format=3 uid="uid://cc1m2a1obsyn4"] + +[ext_resource type="Script" path="res://addons/fpc/character.gd" id="1_0t4e8"] +[ext_resource type="Script" path="res://addons/fpc/EditorModule.gd" id="3_v3ckk"] +[ext_resource type="Script" path="res://addons/fpc/debug.gd" id="3_x1wcc"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_kp17n"] +albedo_color = Color(0.909804, 0.596078, 0, 1) +clearcoat_enabled = true +clearcoat_roughness = 0.2 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_jw1de"] +material = SubResource("StandardMaterial3D_kp17n") + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_uy03j"] + +[sub_resource type="Animation" id="Animation_j8cx7"] +resource_name = "RESET" +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Mesh:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Collision:position") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Head:position") +tracks/2/interp = 2 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1.5, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Mesh:mesh:height") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [2.0] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Collision:shape:height") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [2.0] +} + +[sub_resource type="Animation" id="Animation_5ec5e"] +resource_name = "crouch" +length = 0.2 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Mesh:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 0.75, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Collision:position") +tracks/1/interp = 2 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 0.75, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Head:position") +tracks/2/interp = 2 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 1.5, 0), Vector3(0, 1.12508, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Mesh:mesh:height") +tracks/3/interp = 2 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [2.0, 1.5] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Collision:shape:height") +tracks/4/interp = 2 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [2.0, 1.5] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_5e5t5"] +_data = { +"RESET": SubResource("Animation_j8cx7"), +"crouch": SubResource("Animation_5ec5e") +} + +[sub_resource type="Animation" id="Animation_gh776"] +resource_name = "RESET" +length = 0.001 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} + +[sub_resource type="Animation" id="Animation_8ku67"] +resource_name = "sprint" +length = 2.0 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 1, 0, 1, 0), +"points": PackedFloat32Array(0.06, -0.25, 0, 0.25, -0.01, 0, 0, 0, 0, 0, -0.06, -0.25, 0.01, 0.25, 0.01, 0, 0, 0, 0, 0, 0.06, -0.25, -0.01, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0, 0, 0), +"points": PackedFloat32Array(0.05, -0.25, 0, 0.2, -0.01, 0, -0.2, 0.000186046, 0.2, 0.000186046, 0.05, -0.2, -0.01, 0.2, -0.01, 0, -0.2, 0, 0.2, 0, 0.05, -0.2, -0.01, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} + +[sub_resource type="Animation" id="Animation_lrqmv"] +resource_name = "walk" +length = 2.0 +loop_mode = 1 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:position:x") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0, 1, 0, 1, 0), +"points": PackedFloat32Array(0.04, -0.25, 0, 0.25, 0, 0, 0, 0, 0, 0, -0.04, -0.25, 0, 0.25, 0, 0, 0, 0, 0, 0, 0.04, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} +tracks/1/type = "bezier" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position:y") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"handle_modes": PackedInt32Array(0, 0, 0, 0, 0), +"points": PackedFloat32Array(-0.05, -0.25, 0, 0.2, 0.005, 0, -0.2, 0.000186046, 0.2, 0.000186046, -0.05, -0.2, 0.005, 0.2, 0.005, 0, -0.2, 0, 0.2, 0, -0.05, -0.2, 0.005, 0.25, 0), +"times": PackedFloat32Array(0, 0.5, 1, 1.5, 2) +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_o0unb"] +_data = { +"RESET": SubResource("Animation_gh776"), +"sprint": SubResource("Animation_8ku67"), +"walk": SubResource("Animation_lrqmv") +} + +[sub_resource type="Animation" id="Animation_fvvjq"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_s07ye"] +resource_name = "jump" +length = 3.0 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.6, 3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0.0349066, 0, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_3eyjl"] +resource_name = "land_center" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, 0), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_l1rph"] +resource_name = "land_left" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, 0.0174533), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_vsknp"] +resource_name = "land_right" +length = 1.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Camera:rotation") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, -0.0174533), Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Camera:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.5, 1.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_qeg5r"] +_data = { +"RESET": SubResource("Animation_fvvjq"), +"jump": SubResource("Animation_s07ye"), +"land_center": SubResource("Animation_3eyjl"), +"land_left": SubResource("Animation_l1rph"), +"land_right": SubResource("Animation_vsknp") +} + +[sub_resource type="Theme" id="Theme_wdf0f"] +MarginContainer/constants/margin_bottom = 10 +MarginContainer/constants/margin_left = 10 +MarginContainer/constants/margin_right = 10 +MarginContainer/constants/margin_top = 10 + +[sub_resource type="SphereShape3D" id="SphereShape3D_k4wwl"] + +[node name="Character" type="CharacterBody3D" node_paths=PackedStringArray("HEAD", "CAMERA", "HEADBOB_ANIMATION", "JUMP_ANIMATION", "CROUCH_ANIMATION", "COLLISION_MESH")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 0, 0) +script = ExtResource("1_0t4e8") +default_reticle = "res://addons/fpc/reticles/reticle_1.tscn" +HEAD = NodePath("Head") +CAMERA = NodePath("Head/Camera") +HEADBOB_ANIMATION = NodePath("Head/HeadbobAnimation") +JUMP_ANIMATION = NodePath("Head/JumpAnimation") +CROUCH_ANIMATION = NodePath("CrouchAnimation") +COLLISION_MESH = NodePath("Collision") + +[node name="Mesh" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +mesh = SubResource("CapsuleMesh_jw1de") + +[node name="Collision" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("CapsuleShape3D_uy03j") + +[node name="CrouchAnimation" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_5e5t5") +} + +[node name="Head" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0) + +[node name="Camera" type="Camera3D" parent="Head"] + +[node name="HeadbobAnimation" type="AnimationPlayer" parent="Head"] +libraries = { +"": SubResource("AnimationLibrary_o0unb") +} +blend_times = [&"RESET", &"RESET", 0.5, &"RESET", &"walk", 0.5, &"walk", &"RESET", 0.5] + +[node name="JumpAnimation" type="AnimationPlayer" parent="Head"] +libraries = { +"": SubResource("AnimationLibrary_qeg5r") +} +speed_scale = 4.0 + +[node name="UserInterface" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 1 + +[node name="DebugPanel" type="PanelContainer" parent="UserInterface"] +visible = false +layout_mode = 0 +offset_left = 10.0 +offset_top = 10.0 +offset_right = 453.0 +offset_bottom = 50.0 +theme = SubResource("Theme_wdf0f") +script = ExtResource("3_x1wcc") + +[node name="MarginContainer" type="MarginContainer" parent="UserInterface/DebugPanel"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="UserInterface/DebugPanel/MarginContainer"] +layout_mode = 2 + +[node name="CrouchCeilingDetection" type="ShapeCast3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("SphereShape3D_k4wwl") +target_position = Vector3(0, 0.5, 0) + +[node name="EditorModule" type="Node" parent="."] +script = ExtResource("3_v3ckk") diff --git a/quality-godot-first-person-2-main/addons/fpc/debug.gd b/quality-godot-first-person-2-main/addons/fpc/debug.gd new file mode 100644 index 0000000..efdb7a4 --- /dev/null +++ b/quality-godot-first-person-2-main/addons/fpc/debug.gd @@ -0,0 +1,18 @@ +extends PanelContainer + + +func _process(delta): + if visible: + pass + +func add_property(title : String, value, order : int): # This can either be called once for a static property or called every frame for a dynamic property + var target + target = $MarginContainer/VBoxContainer.find_child(title, true, false) # I have no idea what true and false does here, the function should be more specific + if !target: + target = Label.new() # Debug lines are of type Label + $MarginContainer/VBoxContainer.add_child(target) + target.name = title + target.text = title + ": " + str(value) + elif visible: + target.text = title + ": " + str(value) + $MarginContainer/VBoxContainer.move_child(target, order) diff --git a/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_0.tscn b/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_0.tscn new file mode 100644 index 0000000..2828124 --- /dev/null +++ b/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_0.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=2 format=3 uid="uid://coqpusufa8a6k"] + +[sub_resource type="GDScript" id="GDScript_10f85"] +script/source = "extends CenterContainer + + +@export_category(\"Reticle\") +@export_group(\"Nodes\") +@export var character : CharacterBody3D + +@export_group(\"Settings\") +@export var dot_size : int = 1 +@export var dot_color : Color = Color.WHITE + + +func _process(_delta): + if visible: # If the reticle is disabled (not visible), don't bother updating it + update_reticle_settings() + +func update_reticle_settings(): + $dot.scale.x = dot_size + $dot.scale.y = dot_size + $dot.color = dot_color +" + +[node name="Reticle" type="CenterContainer"] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_10f85") + +[node name="dot" type="Polygon2D" parent="."] +polygon = PackedVector2Array(-1, -1, 1, -1, 1, 1, -1, 1) diff --git a/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_1.tscn b/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_1.tscn new file mode 100644 index 0000000..bb83b83 --- /dev/null +++ b/quality-godot-first-person-2-main/addons/fpc/reticles/reticle_1.tscn @@ -0,0 +1,104 @@ +[gd_scene load_steps=2 format=3 uid="uid://3mij3cjhkwsm"] + +[sub_resource type="GDScript" id="GDScript_a8kpl"] +script/source = "extends CenterContainer + + +@export_category(\"Reticle\") +@export_group(\"Nodes\") +@export var reticle_lines : Array[Line2D] +@export var character : CharacterBody3D + +@export_group(\"Animate\") +@export var animated_reticle : bool = true +@export var reticle_speed : float = 0.5 +@export var reticle_spread : float = 4.0 + +@export_group(\"Dot Settings\") +@export var dot_size : int = 1 +@export var dot_color : Color = Color.WHITE + +@export_group(\"Line Settings\") +@export var line_color : Color = Color.WHITE +@export var line_width : int = 2 +@export var line_length : int = 10 +@export var line_distance : int = 5 +@export_enum(\"None\", \"Round\") var cap_mode : int = 0 + + +func _process(_delta): + if visible: # If the reticle is disabled (not visible), don't bother updating it + update_reticle_settings() + if animated_reticle: + animate_reticle_lines() + + +func animate_reticle_lines(): + var vel = character.get_real_velocity() + var origin = Vector3(0,0,0) + var pos = Vector2(0,0) + var speed = origin.distance_to(vel) + + reticle_lines[0].position = lerp(reticle_lines[0].position, pos + Vector2(0, -speed * reticle_spread), reticle_speed) + reticle_lines[1].position = lerp(reticle_lines[1].position, pos + Vector2(-speed * reticle_spread, 0), reticle_speed) + reticle_lines[2].position = lerp(reticle_lines[2].position, pos + Vector2(speed * reticle_spread, 0), reticle_speed) + reticle_lines[3].position = lerp(reticle_lines[3].position, pos + Vector2(0, speed * reticle_spread), reticle_speed) + + +func update_reticle_settings(): + # Dot + $dot.scale.x = dot_size + $dot.scale.y = dot_size + $dot.color = dot_color + + # Lines + for line in reticle_lines: + line.default_color = line_color + line.width = line_width + if cap_mode == 0: + line.begin_cap_mode = Line2D.LINE_CAP_NONE + line.end_cap_mode = Line2D.LINE_CAP_NONE + elif cap_mode == 1: + line.begin_cap_mode = Line2D.LINE_CAP_ROUND + line.end_cap_mode = Line2D.LINE_CAP_ROUND + + # Please someone find a better way to do this + reticle_lines[0].points[0].y = -line_distance + reticle_lines[0].points[1].y = -line_length - line_distance + reticle_lines[1].points[0].x = -line_distance + reticle_lines[1].points[1].x = -line_length - line_distance + reticle_lines[2].points[0].x = line_distance + reticle_lines[2].points[1].x = line_length + line_distance + reticle_lines[3].points[0].y = line_distance + reticle_lines[3].points[1].y = line_length + line_distance +" + +[node name="Reticle" type="CenterContainer" node_paths=PackedStringArray("reticle_lines")] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_a8kpl") +reticle_lines = [NodePath("top"), NodePath("left"), NodePath("right"), NodePath("bottom")] + +[node name="dot" type="Polygon2D" parent="."] +polygon = PackedVector2Array(-1, -1, 1, -1, 1, 1, -1, 1) + +[node name="top" type="Line2D" parent="."] +points = PackedVector2Array(0, -5, 0, -15) +width = 2.0 + +[node name="left" type="Line2D" parent="."] +points = PackedVector2Array(-5, 0, -15, 0) +width = 2.0 + +[node name="right" type="Line2D" parent="."] +points = PackedVector2Array(5, 0, 15, 0) +width = 2.0 + +[node name="bottom" type="Line2D" parent="."] +points = PackedVector2Array(0, 5, 0, 15) +width = 2.0 diff --git a/quality-godot-first-person-2-main/icon.svg b/quality-godot-first-person-2-main/icon.svg new file mode 100644 index 0000000..ea6ce87 --- /dev/null +++ b/quality-godot-first-person-2-main/icon.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/quality-godot-first-person-2-main/icon.svg.import b/quality-godot-first-person-2-main/icon.svg.import new file mode 100644 index 0000000..9e0a681 --- /dev/null +++ b/quality-godot-first-person-2-main/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://64npoko7rqya" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/quality-godot-first-person-2-main/project.godot b/quality-godot-first-person-2-main/project.godot new file mode 100644 index 0000000..4626ad9 --- /dev/null +++ b/quality-godot-first-person-2-main/project.godot @@ -0,0 +1,65 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="first person controller 2.0" +run/main_scene="res://test_world.tscn" +config/features=PackedStringArray("4.3", "Forward Plus") +config/icon="res://icon.svg" + +[display] + +window/size/mode=2 + +[input] + +ui_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +ui_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +ui_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +ui_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} +crouch={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":99,"location":0,"echo":false,"script":null) +] +} +sprint={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} diff --git a/quality-godot-first-person-2-main/test_world.tscn b/quality-godot-first-person-2-main/test_world.tscn new file mode 100644 index 0000000..b6901b9 --- /dev/null +++ b/quality-godot-first-person-2-main/test_world.tscn @@ -0,0 +1,106 @@ +[gd_scene load_steps=15 format=3 uid="uid://cs4drhmc1bql5"] + +[ext_resource type="PackedScene" uid="uid://cc1m2a1obsyn4" path="res://addons/fpc/character.tscn" id="1_e18vq"] +[ext_resource type="Texture2D" uid="uid://pe7a4weirj2g" path="res://textures/dark.png" id="2_08fdt"] +[ext_resource type="Texture2D" uid="uid://cxjxvqmf4boxq" path="res://textures/green.png" id="3_q4clv"] +[ext_resource type="Texture2D" uid="uid://dsv4jm4vydflb" path="res://textures/orange.png" id="4_1ns5t"] + +[sub_resource type="PhysicalSkyMaterial" id="PhysicalSkyMaterial_edcox"] +ground_color = Color(0.160784, 0.815686, 0.905882, 1) + +[sub_resource type="Sky" id="Sky_2iust"] +sky_material = SubResource("PhysicalSkyMaterial_edcox") + +[sub_resource type="Environment" id="Environment_20rw3"] +background_mode = 2 +sky = SubResource("Sky_2iust") +tonemap_mode = 1 +ssao_enabled = true + +[sub_resource type="Gradient" id="Gradient_ur0vy"] +colors = PackedColorArray(0, 0.476245, 0.0193456, 1, 0.360494, 0.612721, 0.119744, 1) + +[sub_resource type="FastNoiseLite" id="FastNoiseLite_jd3pw"] +frequency = 0.0027 + +[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_7akuf"] +width = 1024 +height = 1024 +in_3d_space = true +seamless = true +color_ramp = SubResource("Gradient_ur0vy") +noise = SubResource("FastNoiseLite_jd3pw") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_67ysu"] +albedo_texture = SubResource("NoiseTexture2D_7akuf") +uv1_scale = Vector3(0.1, 0.1, 0.1) +uv1_triplanar = true + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gomnb"] +albedo_texture = ExtResource("2_08fdt") +metallic = 0.81 +metallic_specular = 0.2 +roughness = 0.5 +uv1_triplanar = true +uv1_triplanar_sharpness = 0.000850145 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_u0sbk"] +albedo_texture = ExtResource("3_q4clv") +metallic = 0.81 +metallic_specular = 0.2 +roughness = 0.5 +uv1_triplanar = true +uv1_triplanar_sharpness = 0.000850145 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_7j4uu"] +albedo_texture = ExtResource("4_1ns5t") +metallic = 0.81 +metallic_specular = 0.2 +roughness = 0.5 +uv1_triplanar = true +uv1_triplanar_sharpness = 0.000850145 + +[node name="test_world" type="Node3D"] + +[node name="Character" parent="." instance=ExtResource("1_e18vq")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_20rw3") + +[node name="sun" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.87959, -0.436605, 0.188936, 0, 0.397148, 0.917755, -0.475732, -0.807248, 0.349328, 0, 0, 0) +light_energy = 2.0 +shadow_enabled = true + +[node name="terrain" type="Node3D" parent="."] + +[node name="CSGBox3D" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10, -0.5, 10) +use_collision = true +size = Vector3(30, 1, 30) +material = SubResource("StandardMaterial3D_67ysu") + +[node name="CSGBox3D2" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, -10) +use_collision = true +size = Vector3(10, 1, 10) +material = SubResource("StandardMaterial3D_gomnb") + +[node name="CSGBox3D3" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 1.8, -13) +use_collision = true +size = Vector3(4, 0.5, 4) +material = SubResource("StandardMaterial3D_gomnb") + +[node name="CSGBox3D4" type="CSGBox3D" parent="terrain"] +transform = Transform3D(0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 0, 0, 1, -9.5, 1.2, -10) +use_collision = true +size = Vector3(10, 1, 10) +material = SubResource("StandardMaterial3D_u0sbk") + +[node name="CSGBox3D5" type="CSGBox3D" parent="terrain"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 3, -15.5) +use_collision = true +size = Vector3(19, 8, 1) +material = SubResource("StandardMaterial3D_7j4uu") diff --git a/quality-godot-first-person-2-main/textures/dark.png b/quality-godot-first-person-2-main/textures/dark.png new file mode 100644 index 0000000..69be211 Binary files /dev/null and b/quality-godot-first-person-2-main/textures/dark.png differ diff --git a/quality-godot-first-person-2-main/textures/dark.png.import b/quality-godot-first-person-2-main/textures/dark.png.import new file mode 100644 index 0000000..2a82a3f --- /dev/null +++ b/quality-godot-first-person-2-main/textures/dark.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://pe7a4weirj2g" +path.s3tc="res://.godot/imported/dark.png-6d46f668c80e231a58e570df85aad257.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/dark.png" +dest_files=["res://.godot/imported/dark.png-6d46f668c80e231a58e570df85aad257.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/quality-godot-first-person-2-main/textures/green.png b/quality-godot-first-person-2-main/textures/green.png new file mode 100644 index 0000000..7bc7cf8 Binary files /dev/null and b/quality-godot-first-person-2-main/textures/green.png differ diff --git a/quality-godot-first-person-2-main/textures/green.png.import b/quality-godot-first-person-2-main/textures/green.png.import new file mode 100644 index 0000000..7c7e044 --- /dev/null +++ b/quality-godot-first-person-2-main/textures/green.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cxjxvqmf4boxq" +path.s3tc="res://.godot/imported/green.png-b4f8ddc6b00d4e627f0e027e2e1193bf.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/green.png" +dest_files=["res://.godot/imported/green.png-b4f8ddc6b00d4e627f0e027e2e1193bf.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/quality-godot-first-person-2-main/textures/orange.png b/quality-godot-first-person-2-main/textures/orange.png new file mode 100644 index 0000000..dec5b59 Binary files /dev/null and b/quality-godot-first-person-2-main/textures/orange.png differ diff --git a/quality-godot-first-person-2-main/textures/orange.png.import b/quality-godot-first-person-2-main/textures/orange.png.import new file mode 100644 index 0000000..311f8ac --- /dev/null +++ b/quality-godot-first-person-2-main/textures/orange.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dsv4jm4vydflb" +path.s3tc="res://.godot/imported/orange.png-6785d3f8216fd22318e8ea839823715b.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://textures/orange.png" +dest_files=["res://.godot/imported/orange.png-6785d3f8216fd22318e8ea839823715b.s3tc.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +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/fix_alpha_border=true +process/premult_alpha=false +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/quality-godot-first-person-2-main/textures/purple.png b/quality-godot-first-person-2-main/textures/purple.png new file mode 100644 index 0000000..48a51c1 Binary files /dev/null and b/quality-godot-first-person-2-main/textures/purple.png differ diff --git a/quality-godot-first-person-2-main/textures/purple.png.import b/quality-godot-first-person-2-main/textures/purple.png.import new file mode 100644 index 0000000..9dc0969 --- /dev/null +++ b/quality-godot-first-person-2-main/textures/purple.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cl4kewig3pk7s" +path="res://.godot/imported/purple.png-23488e84f4f0a47488be2c78494f2155.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://textures/purple.png" +dest_files=["res://.godot/imported/purple.png-23488e84f4f0a47488be2c78494f2155.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/quality-godot-first-person-2-main/textures/red.png b/quality-godot-first-person-2-main/textures/red.png new file mode 100644 index 0000000..bf1cb17 Binary files /dev/null and b/quality-godot-first-person-2-main/textures/red.png differ diff --git a/quality-godot-first-person-2-main/textures/red.png.import b/quality-godot-first-person-2-main/textures/red.png.import new file mode 100644 index 0000000..c8c15aa --- /dev/null +++ b/quality-godot-first-person-2-main/textures/red.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1h161t0v6hau" +path="res://.godot/imported/red.png-3cad0ca19141406d60f5fd2311159a86.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://textures/red.png" +dest_files=["res://.godot/imported/red.png-3cad0ca19141406d60f5fd2311159a86.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/steam_appid.txt b/steam_appid.txt new file mode 100644 index 0000000..36e0826 --- /dev/null +++ b/steam_appid.txt @@ -0,0 +1 @@ +480