diff --git a/assets/fonts/CFSpaceship-Regular.ttf b/assets/fonts/CFSpaceship-Regular.ttf new file mode 100644 index 0000000..a1f0a97 Binary files /dev/null and b/assets/fonts/CFSpaceship-Regular.ttf differ diff --git a/assets/fonts/CFSpaceship-Regular.ttf.import b/assets/fonts/CFSpaceship-Regular.ttf.import new file mode 100644 index 0000000..91d2478 --- /dev/null +++ b/assets/fonts/CFSpaceship-Regular.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://n4g02h0piglf" +path="res://.godot/imported/CFSpaceship-Regular.ttf-cb3aa1558311321cd644c365de2a3af9.fontdata" + +[deps] + +source_file="res://assets/fonts/CFSpaceship-Regular.ttf" +dest_files=["res://.godot/imported/CFSpaceship-Regular.ttf-cb3aa1558311321cd644c365de2a3af9.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/fonts/Chopsic.otf b/assets/fonts/Chopsic.otf new file mode 100644 index 0000000..dec2e88 Binary files /dev/null and b/assets/fonts/Chopsic.otf differ diff --git a/assets/fonts/Chopsic.otf.import b/assets/fonts/Chopsic.otf.import new file mode 100644 index 0000000..cae7ea1 --- /dev/null +++ b/assets/fonts/Chopsic.otf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://bytgiothu0eoy" +path="res://.godot/imported/Chopsic.otf-19021191d64f4100b8d788dd6de17791.fontdata" + +[deps] + +source_file="res://assets/fonts/Chopsic.otf" +dest_files=["res://.godot/imported/Chopsic.otf-19021191d64f4100b8d788dd6de17791.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/fonts/font.ttf b/assets/fonts/font.ttf new file mode 100644 index 0000000..e89b0fe Binary files /dev/null and b/assets/fonts/font.ttf differ diff --git a/assets/fonts/font.ttf.import b/assets/fonts/font.ttf.import new file mode 100644 index 0000000..324bd6b --- /dev/null +++ b/assets/fonts/font.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://bwvx53j60bvtd" +path="res://.godot/imported/font.ttf-39b250d5b3aa0fc62f2ec61dd6a2edd2.fontdata" + +[deps] + +source_file="res://assets/fonts/font.ttf" +dest_files=["res://.godot/imported/font.ttf-39b250d5b3aa0fc62f2ec61dd6a2edd2.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/fonts/font2.ttf b/assets/fonts/font2.ttf new file mode 100644 index 0000000..03979d1 Binary files /dev/null and b/assets/fonts/font2.ttf differ diff --git a/assets/fonts/font2.ttf.import b/assets/fonts/font2.ttf.import new file mode 100644 index 0000000..3373930 --- /dev/null +++ b/assets/fonts/font2.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://drp85tpfncq5m" +path="res://.godot/imported/font2.ttf-59e4c6b4a5306e7f84a55bb565749f73.fontdata" + +[deps] + +source_file="res://assets/fonts/font2.ttf" +dest_files=["res://.godot/imported/font2.ttf-59e4c6b4a5306e7f84a55bb565749f73.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/fonts/font3.ttf b/assets/fonts/font3.ttf new file mode 100644 index 0000000..3aeaae8 Binary files /dev/null and b/assets/fonts/font3.ttf differ diff --git a/assets/fonts/font3.ttf.import b/assets/fonts/font3.ttf.import new file mode 100644 index 0000000..3dffc10 --- /dev/null +++ b/assets/fonts/font3.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://choploj3iec0a" +path="res://.godot/imported/font3.ttf-2cd23d8fac261e9271189c108512bad4.fontdata" + +[deps] + +source_file="res://assets/fonts/font3.ttf" +dest_files=["res://.godot/imported/font3.ttf-2cd23d8fac261e9271189c108512bad4.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/fonts/main_font.ttf b/assets/fonts/main_font.ttf new file mode 100644 index 0000000..03979d1 Binary files /dev/null and b/assets/fonts/main_font.ttf differ diff --git a/assets/fonts/main_font.ttf.import b/assets/fonts/main_font.ttf.import new file mode 100644 index 0000000..ea3414d --- /dev/null +++ b/assets/fonts/main_font.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://chk8jrn2ighpx" +path="res://.godot/imported/main_font.ttf-36d79ba454878c9b3ab34b1c4d76239a.fontdata" + +[deps] + +source_file="res://assets/fonts/main_font.ttf" +dest_files=["res://.godot/imported/main_font.ttf-36d79ba454878c9b3ab34b1c4d76239a.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/fonts/quantfh.ttf b/assets/fonts/quantfh.ttf new file mode 100644 index 0000000..009a186 Binary files /dev/null and b/assets/fonts/quantfh.ttf differ diff --git a/assets/fonts/quantfh.ttf.import b/assets/fonts/quantfh.ttf.import new file mode 100644 index 0000000..fcf9114 --- /dev/null +++ b/assets/fonts/quantfh.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://66bk4oa8nj7x" +path="res://.godot/imported/quantfh.ttf-ca1ea5ed2797d3db11502ea87c32ea2c.fontdata" + +[deps] + +source_file="res://assets/fonts/quantfh.ttf" +dest_files=["res://.godot/imported/quantfh.ttf-ca1ea5ed2797d3db11502ea87c32ea2c.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/fonts/redlinecondital.ttf b/assets/fonts/redlinecondital.ttf new file mode 100644 index 0000000..73d46a7 Binary files /dev/null and b/assets/fonts/redlinecondital.ttf differ diff --git a/assets/fonts/redlinecondital.ttf.import b/assets/fonts/redlinecondital.ttf.import new file mode 100644 index 0000000..d66a219 --- /dev/null +++ b/assets/fonts/redlinecondital.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://8sj6q1y0q32u" +path="res://.godot/imported/redlinecondital.ttf-960a4982ce41081189bfe55b4ec01b32.fontdata" + +[deps] + +source_file="res://assets/fonts/redlinecondital.ttf" +dest_files=["res://.godot/imported/redlinecondital.ttf-960a4982ce41081189bfe55b4ec01b32.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/planets/moon.png b/assets/planets/moon.png new file mode 100644 index 0000000..afcc99c Binary files /dev/null and b/assets/planets/moon.png differ diff --git a/assets/planets/moon.png.import b/assets/planets/moon.png.import new file mode 100644 index 0000000..d311b41 --- /dev/null +++ b/assets/planets/moon.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnltmrot4rttt" +path="res://.godot/imported/moon.png-fdd37828089db886514f0188cd312e48.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/moon.png" +dest_files=["res://.godot/imported/moon.png-fdd37828089db886514f0188cd312e48.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p1.png b/assets/planets/p1.png new file mode 100644 index 0000000..f1c7c96 Binary files /dev/null and b/assets/planets/p1.png differ diff --git a/assets/planets/p1.png.import b/assets/planets/p1.png.import new file mode 100644 index 0000000..c245de4 --- /dev/null +++ b/assets/planets/p1.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://jrrrdbusn4mw" +path="res://.godot/imported/p1.png-c42c3e40721fc6fe437938de585480cd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p1.png" +dest_files=["res://.godot/imported/p1.png-c42c3e40721fc6fe437938de585480cd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p10.png b/assets/planets/p10.png new file mode 100644 index 0000000..e81d38e Binary files /dev/null and b/assets/planets/p10.png differ diff --git a/assets/planets/p10.png.import b/assets/planets/p10.png.import new file mode 100644 index 0000000..998f8e3 --- /dev/null +++ b/assets/planets/p10.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bfjiu6gvn2msl" +path="res://.godot/imported/p10.png-eb46ef667e70ba9df6a4dbacc6709925.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p10.png" +dest_files=["res://.godot/imported/p10.png-eb46ef667e70ba9df6a4dbacc6709925.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p11.png b/assets/planets/p11.png new file mode 100644 index 0000000..a2aaf34 Binary files /dev/null and b/assets/planets/p11.png differ diff --git a/assets/planets/p11.png.import b/assets/planets/p11.png.import new file mode 100644 index 0000000..3aadb00 --- /dev/null +++ b/assets/planets/p11.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://e13d2cukyvdx" +path="res://.godot/imported/p11.png-40f511c796ef38e6f2dc1d6ce8c6dcc1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p11.png" +dest_files=["res://.godot/imported/p11.png-40f511c796ef38e6f2dc1d6ce8c6dcc1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p12.png b/assets/planets/p12.png new file mode 100644 index 0000000..ce13954 Binary files /dev/null and b/assets/planets/p12.png differ diff --git a/assets/planets/p12.png.import b/assets/planets/p12.png.import new file mode 100644 index 0000000..594a2ea --- /dev/null +++ b/assets/planets/p12.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b2iopee4im0at" +path="res://.godot/imported/p12.png-6346e34cd32a168f5869989e8c974f5a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p12.png" +dest_files=["res://.godot/imported/p12.png-6346e34cd32a168f5869989e8c974f5a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p13.png b/assets/planets/p13.png new file mode 100644 index 0000000..d98c385 Binary files /dev/null and b/assets/planets/p13.png differ diff --git a/assets/planets/p13.png.import b/assets/planets/p13.png.import new file mode 100644 index 0000000..78655eb --- /dev/null +++ b/assets/planets/p13.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vm6csbtc5bxq" +path="res://.godot/imported/p13.png-4d7623696829ebbf329c027e02f35262.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p13.png" +dest_files=["res://.godot/imported/p13.png-4d7623696829ebbf329c027e02f35262.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p14.png b/assets/planets/p14.png new file mode 100644 index 0000000..41cd97d Binary files /dev/null and b/assets/planets/p14.png differ diff --git a/assets/planets/p14.png.import b/assets/planets/p14.png.import new file mode 100644 index 0000000..ba08311 --- /dev/null +++ b/assets/planets/p14.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://da6uiusxao104" +path="res://.godot/imported/p14.png-62146a691c78fe48b52ce92ace152029.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p14.png" +dest_files=["res://.godot/imported/p14.png-62146a691c78fe48b52ce92ace152029.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p15.png b/assets/planets/p15.png new file mode 100644 index 0000000..71ca79a Binary files /dev/null and b/assets/planets/p15.png differ diff --git a/assets/planets/p15.png.import b/assets/planets/p15.png.import new file mode 100644 index 0000000..2461b9f --- /dev/null +++ b/assets/planets/p15.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://buxv8tpwvtaey" +path="res://.godot/imported/p15.png-1d9dc7e436e8054302dc10c56dafe4f6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p15.png" +dest_files=["res://.godot/imported/p15.png-1d9dc7e436e8054302dc10c56dafe4f6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p16.png b/assets/planets/p16.png new file mode 100644 index 0000000..4cd931e Binary files /dev/null and b/assets/planets/p16.png differ diff --git a/assets/planets/p16.png.import b/assets/planets/p16.png.import new file mode 100644 index 0000000..78d7da4 --- /dev/null +++ b/assets/planets/p16.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b7iawobp4kghl" +path="res://.godot/imported/p16.png-37255585be8a1d1ca338f4b53c5b7bd5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p16.png" +dest_files=["res://.godot/imported/p16.png-37255585be8a1d1ca338f4b53c5b7bd5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p17.png b/assets/planets/p17.png new file mode 100644 index 0000000..adc1d89 Binary files /dev/null and b/assets/planets/p17.png differ diff --git a/assets/planets/p17.png.import b/assets/planets/p17.png.import new file mode 100644 index 0000000..152793b --- /dev/null +++ b/assets/planets/p17.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d2w7eg66pvoy2" +path="res://.godot/imported/p17.png-4ec0c958a41097207878a3f69431c3eb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p17.png" +dest_files=["res://.godot/imported/p17.png-4ec0c958a41097207878a3f69431c3eb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p18.png b/assets/planets/p18.png new file mode 100644 index 0000000..24dc1d8 Binary files /dev/null and b/assets/planets/p18.png differ diff --git a/assets/planets/p18.png.import b/assets/planets/p18.png.import new file mode 100644 index 0000000..16583ea --- /dev/null +++ b/assets/planets/p18.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://vijfoksvs1r8" +path="res://.godot/imported/p18.png-ae13acf38f064d372f95b0ce9091814f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p18.png" +dest_files=["res://.godot/imported/p18.png-ae13acf38f064d372f95b0ce9091814f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p2.png b/assets/planets/p2.png new file mode 100644 index 0000000..60cc640 Binary files /dev/null and b/assets/planets/p2.png differ diff --git a/assets/planets/p2.png.import b/assets/planets/p2.png.import new file mode 100644 index 0000000..0752723 --- /dev/null +++ b/assets/planets/p2.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dovg8k2mmd23h" +path="res://.godot/imported/p2.png-4ac3d58689143f5132a9012c89a0fbae.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p2.png" +dest_files=["res://.godot/imported/p2.png-4ac3d58689143f5132a9012c89a0fbae.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p3.png b/assets/planets/p3.png new file mode 100644 index 0000000..e06bcf3 Binary files /dev/null and b/assets/planets/p3.png differ diff --git a/assets/planets/p3.png.import b/assets/planets/p3.png.import new file mode 100644 index 0000000..0ca6a75 --- /dev/null +++ b/assets/planets/p3.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b1n351g52jvfm" +path="res://.godot/imported/p3.png-2d30cfbfeec8bca778c6cd027f163bb1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p3.png" +dest_files=["res://.godot/imported/p3.png-2d30cfbfeec8bca778c6cd027f163bb1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p4.png b/assets/planets/p4.png new file mode 100644 index 0000000..c8ba6c8 Binary files /dev/null and b/assets/planets/p4.png differ diff --git a/assets/planets/p4.png.import b/assets/planets/p4.png.import new file mode 100644 index 0000000..37aebcc --- /dev/null +++ b/assets/planets/p4.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://3lypab822baw" +path="res://.godot/imported/p4.png-9964b13870cffc622e37a2b6896c7cf1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p4.png" +dest_files=["res://.godot/imported/p4.png-9964b13870cffc622e37a2b6896c7cf1.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p5.png b/assets/planets/p5.png new file mode 100644 index 0000000..9d6dfc7 Binary files /dev/null and b/assets/planets/p5.png differ diff --git a/assets/planets/p5.png.import b/assets/planets/p5.png.import new file mode 100644 index 0000000..c38f7cd --- /dev/null +++ b/assets/planets/p5.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cwjee3thi5rfu" +path="res://.godot/imported/p5.png-68ab4cc45e4d08d164da276c3ff7b785.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p5.png" +dest_files=["res://.godot/imported/p5.png-68ab4cc45e4d08d164da276c3ff7b785.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p6.png b/assets/planets/p6.png new file mode 100644 index 0000000..f080112 Binary files /dev/null and b/assets/planets/p6.png differ diff --git a/assets/planets/p6.png.import b/assets/planets/p6.png.import new file mode 100644 index 0000000..3a37fe7 --- /dev/null +++ b/assets/planets/p6.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cy1qe3g2e6jhe" +path="res://.godot/imported/p6.png-febdf0f58c8ef1fb1ede562a4060468a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p6.png" +dest_files=["res://.godot/imported/p6.png-febdf0f58c8ef1fb1ede562a4060468a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p7.png b/assets/planets/p7.png new file mode 100644 index 0000000..4a51251 Binary files /dev/null and b/assets/planets/p7.png differ diff --git a/assets/planets/p7.png.import b/assets/planets/p7.png.import new file mode 100644 index 0000000..da9e0eb --- /dev/null +++ b/assets/planets/p7.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b5511kavwbf48" +path="res://.godot/imported/p7.png-ddd667980fc6e83e7c1d5387c3063563.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p7.png" +dest_files=["res://.godot/imported/p7.png-ddd667980fc6e83e7c1d5387c3063563.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p8.png b/assets/planets/p8.png new file mode 100644 index 0000000..d441182 Binary files /dev/null and b/assets/planets/p8.png differ diff --git a/assets/planets/p8.png.import b/assets/planets/p8.png.import new file mode 100644 index 0000000..ba9a10a --- /dev/null +++ b/assets/planets/p8.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://gqhc87677lax" +path="res://.godot/imported/p8.png-8986b535a1202d2c734eaf2aa2a0e649.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p8.png" +dest_files=["res://.godot/imported/p8.png-8986b535a1202d2c734eaf2aa2a0e649.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/planets/p9.png b/assets/planets/p9.png new file mode 100644 index 0000000..2fe301d Binary files /dev/null and b/assets/planets/p9.png differ diff --git a/assets/planets/p9.png.import b/assets/planets/p9.png.import new file mode 100644 index 0000000..29e3885 --- /dev/null +++ b/assets/planets/p9.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bragncjfur5p6" +path="res://.godot/imported/p9.png-62dc16a69062b00a41056d31b9f878c5.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/planets/p9.png" +dest_files=["res://.godot/imported/p9.png-62dc16a69062b00a41056d31b9f878c5.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/s1.png b/assets/stars/s1.png new file mode 100644 index 0000000..2438458 Binary files /dev/null and b/assets/stars/s1.png differ diff --git a/assets/stars/s1.png.import b/assets/stars/s1.png.import new file mode 100644 index 0000000..9222ace --- /dev/null +++ b/assets/stars/s1.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b4iycl7xcvpkp" +path="res://.godot/imported/s1.png-0ce7911f6abb547ddafc2aa0bfb91618.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/s1.png" +dest_files=["res://.godot/imported/s1.png-0ce7911f6abb547ddafc2aa0bfb91618.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/s2.png b/assets/stars/s2.png new file mode 100644 index 0000000..f0583ac Binary files /dev/null and b/assets/stars/s2.png differ diff --git a/assets/stars/s2.png.import b/assets/stars/s2.png.import new file mode 100644 index 0000000..a28bdde --- /dev/null +++ b/assets/stars/s2.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cy0es1o28j37" +path="res://.godot/imported/s2.png-d2771d54a25579b5eda9f285828bb196.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/s2.png" +dest_files=["res://.godot/imported/s2.png-d2771d54a25579b5eda9f285828bb196.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/s3.png b/assets/stars/s3.png new file mode 100644 index 0000000..83f9730 Binary files /dev/null and b/assets/stars/s3.png differ diff --git a/assets/stars/s3.png.import b/assets/stars/s3.png.import new file mode 100644 index 0000000..ef790fb --- /dev/null +++ b/assets/stars/s3.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dsfxgajg3jodv" +path="res://.godot/imported/s3.png-2199ae6533f1c33882b790c8560ad7da.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/s3.png" +dest_files=["res://.godot/imported/s3.png-2199ae6533f1c33882b790c8560ad7da.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/s4.png b/assets/stars/s4.png new file mode 100644 index 0000000..00e32f1 Binary files /dev/null and b/assets/stars/s4.png differ diff --git a/assets/stars/s4.png.import b/assets/stars/s4.png.import new file mode 100644 index 0000000..a04e34d --- /dev/null +++ b/assets/stars/s4.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dgbb5uhvxihjd" +path="res://.godot/imported/s4.png-5717c99e544d0cd724c5890ea28c93eb.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/s4.png" +dest_files=["res://.godot/imported/s4.png-5717c99e544d0cd724c5890ea28c93eb.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/s5.png b/assets/stars/s5.png new file mode 100644 index 0000000..902a0d3 Binary files /dev/null and b/assets/stars/s5.png differ diff --git a/assets/stars/s5.png.import b/assets/stars/s5.png.import new file mode 100644 index 0000000..d6e5575 --- /dev/null +++ b/assets/stars/s5.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bh1jqxw7ikd6n" +path="res://.godot/imported/s5.png-7ca1baeba6ecd3eba7c0cebbcb2a8991.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/s5.png" +dest_files=["res://.godot/imported/s5.png-7ca1baeba6ecd3eba7c0cebbcb2a8991.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/s6.png b/assets/stars/s6.png new file mode 100644 index 0000000..0eca92c Binary files /dev/null and b/assets/stars/s6.png differ diff --git a/assets/stars/s6.png.import b/assets/stars/s6.png.import new file mode 100644 index 0000000..a602a0a --- /dev/null +++ b/assets/stars/s6.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://rp6gc81hhvpu" +path="res://.godot/imported/s6.png-3977e4c129c61357b29ca5586abe9f75.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/s6.png" +dest_files=["res://.godot/imported/s6.png-3977e4c129c61357b29ca5586abe9f75.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/s7.png b/assets/stars/s7.png new file mode 100644 index 0000000..fd0ef8a Binary files /dev/null and b/assets/stars/s7.png differ diff --git a/assets/stars/s7.png.import b/assets/stars/s7.png.import new file mode 100644 index 0000000..9246e61 --- /dev/null +++ b/assets/stars/s7.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djmcbja37qn5v" +path="res://.godot/imported/s7.png-1d3f0d7a902a12e0a73a7297cd5b7134.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/s7.png" +dest_files=["res://.godot/imported/s7.png-1d3f0d7a902a12e0a73a7297cd5b7134.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/s8.png b/assets/stars/s8.png new file mode 100644 index 0000000..f944e6c Binary files /dev/null and b/assets/stars/s8.png differ diff --git a/assets/stars/s8.png.import b/assets/stars/s8.png.import new file mode 100644 index 0000000..c46c3c0 --- /dev/null +++ b/assets/stars/s8.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://boh4ab2pue4os" +path="res://.godot/imported/s8.png-5881c6e0aa1014c097aead63f0e6269f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/s8.png" +dest_files=["res://.godot/imported/s8.png-5881c6e0aa1014c097aead63f0e6269f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/small_star.png b/assets/stars/small_star.png new file mode 100644 index 0000000..4e00e4b Binary files /dev/null and b/assets/stars/small_star.png differ diff --git a/assets/stars/small_star.png.import b/assets/stars/small_star.png.import new file mode 100644 index 0000000..c12602b --- /dev/null +++ b/assets/stars/small_star.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cm376wgq8l0n4" +path="res://.godot/imported/small_star.png-2d9a9a02accf80f624cd11d747414afd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/small_star.png" +dest_files=["res://.godot/imported/small_star.png-2d9a9a02accf80f624cd11d747414afd.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/license.txt b/assets/stars/stars_anim/license.txt new file mode 100644 index 0000000..dba9d41 --- /dev/null +++ b/assets/stars/stars_anim/license.txt @@ -0,0 +1,6 @@ +This work, made by Viktor Hahn (Viktor.Hahn@web.de), is +licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. +http://creativecommons.org/licenses/by-sa/3.0/ +and the Creative Commons Attribution 4.0 International License (CC BY 4.0). +https://creativecommons.org/licenses/by/4.0/ + diff --git a/assets/stars/stars_anim/star_blue01.png b/assets/stars/stars_anim/star_blue01.png new file mode 100644 index 0000000..d9cb10a Binary files /dev/null and b/assets/stars/stars_anim/star_blue01.png differ diff --git a/assets/stars/stars_anim/star_blue01.png.import b/assets/stars/stars_anim/star_blue01.png.import new file mode 100644 index 0000000..51da4bd --- /dev/null +++ b/assets/stars/stars_anim/star_blue01.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://btv7sp768x6jh" +path="res://.godot/imported/star_blue01.png-7ceacba937b06646ac69276966d92c1e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_blue01.png" +dest_files=["res://.godot/imported/star_blue01.png-7ceacba937b06646ac69276966d92c1e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_blue02.png b/assets/stars/stars_anim/star_blue02.png new file mode 100644 index 0000000..338cd30 Binary files /dev/null and b/assets/stars/stars_anim/star_blue02.png differ diff --git a/assets/stars/stars_anim/star_blue02.png.import b/assets/stars/stars_anim/star_blue02.png.import new file mode 100644 index 0000000..7cf3eb5 --- /dev/null +++ b/assets/stars/stars_anim/star_blue02.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ddl6kd42nnqgp" +path="res://.godot/imported/star_blue02.png-a5f853c39f0dbba853dfb797aaa3ad3f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_blue02.png" +dest_files=["res://.godot/imported/star_blue02.png-a5f853c39f0dbba853dfb797aaa3ad3f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_blue03.png b/assets/stars/stars_anim/star_blue03.png new file mode 100644 index 0000000..50807f6 Binary files /dev/null and b/assets/stars/stars_anim/star_blue03.png differ diff --git a/assets/stars/stars_anim/star_blue03.png.import b/assets/stars/stars_anim/star_blue03.png.import new file mode 100644 index 0000000..08365c4 --- /dev/null +++ b/assets/stars/stars_anim/star_blue03.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dghtcw0nle871" +path="res://.godot/imported/star_blue03.png-e559c3a94f5fc221e7dea078fcd9fa44.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_blue03.png" +dest_files=["res://.godot/imported/star_blue03.png-e559c3a94f5fc221e7dea078fcd9fa44.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_blue04.png b/assets/stars/stars_anim/star_blue04.png new file mode 100644 index 0000000..e4627d3 Binary files /dev/null and b/assets/stars/stars_anim/star_blue04.png differ diff --git a/assets/stars/stars_anim/star_blue04.png.import b/assets/stars/stars_anim/star_blue04.png.import new file mode 100644 index 0000000..27393c3 --- /dev/null +++ b/assets/stars/stars_anim/star_blue04.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://npxi1tplw72c" +path="res://.godot/imported/star_blue04.png-679746a9708d941618eaf937b6559859.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_blue04.png" +dest_files=["res://.godot/imported/star_blue04.png-679746a9708d941618eaf937b6559859.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_orange01.png b/assets/stars/stars_anim/star_orange01.png new file mode 100644 index 0000000..bafc6d7 Binary files /dev/null and b/assets/stars/stars_anim/star_orange01.png differ diff --git a/assets/stars/stars_anim/star_orange01.png.import b/assets/stars/stars_anim/star_orange01.png.import new file mode 100644 index 0000000..6953e94 --- /dev/null +++ b/assets/stars/stars_anim/star_orange01.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://l7bbst7h3e3d" +path="res://.godot/imported/star_orange01.png-a241e38f985fd5131f0b80a6e20baf40.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_orange01.png" +dest_files=["res://.godot/imported/star_orange01.png-a241e38f985fd5131f0b80a6e20baf40.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_orange02.png b/assets/stars/stars_anim/star_orange02.png new file mode 100644 index 0000000..8e870e5 Binary files /dev/null and b/assets/stars/stars_anim/star_orange02.png differ diff --git a/assets/stars/stars_anim/star_orange02.png.import b/assets/stars/stars_anim/star_orange02.png.import new file mode 100644 index 0000000..a64810f --- /dev/null +++ b/assets/stars/stars_anim/star_orange02.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b4pmtxdqlqnt8" +path="res://.godot/imported/star_orange02.png-5b8e4f38447d6c203677f0fe820f54b2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_orange02.png" +dest_files=["res://.godot/imported/star_orange02.png-5b8e4f38447d6c203677f0fe820f54b2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_orange03.png b/assets/stars/stars_anim/star_orange03.png new file mode 100644 index 0000000..8007755 Binary files /dev/null and b/assets/stars/stars_anim/star_orange03.png differ diff --git a/assets/stars/stars_anim/star_orange03.png.import b/assets/stars/stars_anim/star_orange03.png.import new file mode 100644 index 0000000..a67b589 --- /dev/null +++ b/assets/stars/stars_anim/star_orange03.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dtwa3yxe5fcaq" +path="res://.godot/imported/star_orange03.png-ded5cbaeaa444c8af77b916b38aef95a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_orange03.png" +dest_files=["res://.godot/imported/star_orange03.png-ded5cbaeaa444c8af77b916b38aef95a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_orange04.png b/assets/stars/stars_anim/star_orange04.png new file mode 100644 index 0000000..bfce169 Binary files /dev/null and b/assets/stars/stars_anim/star_orange04.png differ diff --git a/assets/stars/stars_anim/star_orange04.png.import b/assets/stars/stars_anim/star_orange04.png.import new file mode 100644 index 0000000..5f195fe --- /dev/null +++ b/assets/stars/stars_anim/star_orange04.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bm8q5qly218xn" +path="res://.godot/imported/star_orange04.png-d61ba2ab966402cebaac43584b46da68.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_orange04.png" +dest_files=["res://.godot/imported/star_orange04.png-d61ba2ab966402cebaac43584b46da68.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_red01.png b/assets/stars/stars_anim/star_red01.png new file mode 100644 index 0000000..126d9c4 Binary files /dev/null and b/assets/stars/stars_anim/star_red01.png differ diff --git a/assets/stars/stars_anim/star_red01.png.import b/assets/stars/stars_anim/star_red01.png.import new file mode 100644 index 0000000..7fbf891 --- /dev/null +++ b/assets/stars/stars_anim/star_red01.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://otfvkc7pds1c" +path="res://.godot/imported/star_red01.png-14e7a69e35045462e106257bbc799d92.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_red01.png" +dest_files=["res://.godot/imported/star_red01.png-14e7a69e35045462e106257bbc799d92.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_red02.png b/assets/stars/stars_anim/star_red02.png new file mode 100644 index 0000000..477b311 Binary files /dev/null and b/assets/stars/stars_anim/star_red02.png differ diff --git a/assets/stars/stars_anim/star_red02.png.import b/assets/stars/stars_anim/star_red02.png.import new file mode 100644 index 0000000..db5395d --- /dev/null +++ b/assets/stars/stars_anim/star_red02.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bm7hr6va1djdg" +path="res://.godot/imported/star_red02.png-85f1c65878d98757b079dd291ee58878.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_red02.png" +dest_files=["res://.godot/imported/star_red02.png-85f1c65878d98757b079dd291ee58878.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_red03.png b/assets/stars/stars_anim/star_red03.png new file mode 100644 index 0000000..504a1fb Binary files /dev/null and b/assets/stars/stars_anim/star_red03.png differ diff --git a/assets/stars/stars_anim/star_red03.png.import b/assets/stars/stars_anim/star_red03.png.import new file mode 100644 index 0000000..879fd69 --- /dev/null +++ b/assets/stars/stars_anim/star_red03.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://6jjk6h1aihsw" +path="res://.godot/imported/star_red03.png-3d6f19c309e06ba4a7bbc2487cb696f3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_red03.png" +dest_files=["res://.godot/imported/star_red03.png-3d6f19c309e06ba4a7bbc2487cb696f3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_red04.png b/assets/stars/stars_anim/star_red04.png new file mode 100644 index 0000000..35067d9 Binary files /dev/null and b/assets/stars/stars_anim/star_red04.png differ diff --git a/assets/stars/stars_anim/star_red04.png.import b/assets/stars/stars_anim/star_red04.png.import new file mode 100644 index 0000000..52b642d --- /dev/null +++ b/assets/stars/stars_anim/star_red04.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cupuo3cglvatl" +path="res://.godot/imported/star_red04.png-512998e170eaa0e4771038797ce74907.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_red04.png" +dest_files=["res://.godot/imported/star_red04.png-512998e170eaa0e4771038797ce74907.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_white01.png b/assets/stars/stars_anim/star_white01.png new file mode 100644 index 0000000..6ba14e1 Binary files /dev/null and b/assets/stars/stars_anim/star_white01.png differ diff --git a/assets/stars/stars_anim/star_white01.png.import b/assets/stars/stars_anim/star_white01.png.import new file mode 100644 index 0000000..d619e27 --- /dev/null +++ b/assets/stars/stars_anim/star_white01.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dbdoguerkaubn" +path="res://.godot/imported/star_white01.png-49ce70bbcd34e09d6039a4295ef19062.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_white01.png" +dest_files=["res://.godot/imported/star_white01.png-49ce70bbcd34e09d6039a4295ef19062.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_white02.png b/assets/stars/stars_anim/star_white02.png new file mode 100644 index 0000000..93aa88e Binary files /dev/null and b/assets/stars/stars_anim/star_white02.png differ diff --git a/assets/stars/stars_anim/star_white02.png.import b/assets/stars/stars_anim/star_white02.png.import new file mode 100644 index 0000000..d3ce499 --- /dev/null +++ b/assets/stars/stars_anim/star_white02.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://r8nuxqpjnhxy" +path="res://.godot/imported/star_white02.png-566afe5020e86027112b246edf07677c.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_white02.png" +dest_files=["res://.godot/imported/star_white02.png-566afe5020e86027112b246edf07677c.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_white03.png b/assets/stars/stars_anim/star_white03.png new file mode 100644 index 0000000..bc0adc6 Binary files /dev/null and b/assets/stars/stars_anim/star_white03.png differ diff --git a/assets/stars/stars_anim/star_white03.png.import b/assets/stars/stars_anim/star_white03.png.import new file mode 100644 index 0000000..b1fd61f --- /dev/null +++ b/assets/stars/stars_anim/star_white03.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b83jwumh3r5kj" +path="res://.godot/imported/star_white03.png-d64b24b80caf39a45a818236c15e71db.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_white03.png" +dest_files=["res://.godot/imported/star_white03.png-d64b24b80caf39a45a818236c15e71db.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_white04.png b/assets/stars/stars_anim/star_white04.png new file mode 100644 index 0000000..eb69539 Binary files /dev/null and b/assets/stars/stars_anim/star_white04.png differ diff --git a/assets/stars/stars_anim/star_white04.png.import b/assets/stars/stars_anim/star_white04.png.import new file mode 100644 index 0000000..38b2e55 --- /dev/null +++ b/assets/stars/stars_anim/star_white04.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cnnellmy2f5ek" +path="res://.godot/imported/star_white04.png-cc91efb49869eef04bc4604645587225.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_white04.png" +dest_files=["res://.godot/imported/star_white04.png-cc91efb49869eef04bc4604645587225.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_yellow01.png b/assets/stars/stars_anim/star_yellow01.png new file mode 100644 index 0000000..2a83284 Binary files /dev/null and b/assets/stars/stars_anim/star_yellow01.png differ diff --git a/assets/stars/stars_anim/star_yellow01.png.import b/assets/stars/stars_anim/star_yellow01.png.import new file mode 100644 index 0000000..a6b0695 --- /dev/null +++ b/assets/stars/stars_anim/star_yellow01.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cc5r6x34yelmi" +path="res://.godot/imported/star_yellow01.png-7bc8e4a91f5c7c5c7bf3f9379cc604a2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_yellow01.png" +dest_files=["res://.godot/imported/star_yellow01.png-7bc8e4a91f5c7c5c7bf3f9379cc604a2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_yellow02.png b/assets/stars/stars_anim/star_yellow02.png new file mode 100644 index 0000000..dbb3136 Binary files /dev/null and b/assets/stars/stars_anim/star_yellow02.png differ diff --git a/assets/stars/stars_anim/star_yellow02.png.import b/assets/stars/stars_anim/star_yellow02.png.import new file mode 100644 index 0000000..4e99659 --- /dev/null +++ b/assets/stars/stars_anim/star_yellow02.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ltoro3q2c60d" +path="res://.godot/imported/star_yellow02.png-c80b441b0567331b97b7328f4ab4d281.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_yellow02.png" +dest_files=["res://.godot/imported/star_yellow02.png-c80b441b0567331b97b7328f4ab4d281.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_yellow03.png b/assets/stars/stars_anim/star_yellow03.png new file mode 100644 index 0000000..869b98d Binary files /dev/null and b/assets/stars/stars_anim/star_yellow03.png differ diff --git a/assets/stars/stars_anim/star_yellow03.png.import b/assets/stars/stars_anim/star_yellow03.png.import new file mode 100644 index 0000000..17d7d60 --- /dev/null +++ b/assets/stars/stars_anim/star_yellow03.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dwinfe2nx83au" +path="res://.godot/imported/star_yellow03.png-cce16f817bff87c962db42e8d6688104.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_yellow03.png" +dest_files=["res://.godot/imported/star_yellow03.png-cce16f817bff87c962db42e8d6688104.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_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/stars/stars_anim/star_yellow04.png b/assets/stars/stars_anim/star_yellow04.png new file mode 100644 index 0000000..d8ab2c6 Binary files /dev/null and b/assets/stars/stars_anim/star_yellow04.png differ diff --git a/assets/stars/stars_anim/star_yellow04.png.import b/assets/stars/stars_anim/star_yellow04.png.import new file mode 100644 index 0000000..2c3ebc4 --- /dev/null +++ b/assets/stars/stars_anim/star_yellow04.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c8bjg3byd5rds" +path="res://.godot/imported/star_yellow04.png-8e11153a375b9289bd2f4f91db94e552.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/stars/stars_anim/star_yellow04.png" +dest_files=["res://.godot/imported/star_yellow04.png-8e11153a375b9289bd2f4f91db94e552.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/documentation.txt b/documentation.txt index dc1f9a6..21063e4 100644 --- a/documentation.txt +++ b/documentation.txt @@ -2,7 +2,7 @@ SYSTEM PRZEDMIOTÓW I LOOTU Przedmioty: Weapon, Shield, Hull, Generator, Extension. Baza typów znajduje się w resources/items, generator w scripts/items/item_generator.gd. -Poziom przedmiotu = GameState.system_level (1–1000; obecnie układ 1). +Poziom przedmiotu = GameState.system_level (1–1000; aktualny poziom układu). Cecha główna modułów i regeneracja generatora: baza * (1 + 0.05 * (L - 1)) * losowe 0.8–1.2. Definicje bazowe pozostają wspólne i nie są zmieniane; wylosowane wartości zapisuje ItemInstance. Każdy drop ma 1–5 różnych addonów z bazy zasobów affix_database.tres. @@ -13,7 +13,7 @@ Zakresy addonów interpolują liniowo między poziomem 1 a 1000 wg concept_game. Cap dotyczy pojedynczego addonu; bonusy zamontowanych przedmiotów sumują się. Po zniszczeniu wroga: Normal 65%, Elite 90%, Boss 100% szansy na jeden przedmiot. -Typ wroga ustawia eksportowane loot_tier; obecna mapa nadal tworzy zwykłych wrogów. +Typ wroga ustawia loot_tier; generator układu dobiera skład zależnie od poziomu. Drop pozostaje na mapie, przyciąga się z 150 px i zbiera do wolnego slotu z 48 px. Pełna ładownia: drop czeka i pokazuje komunikat. Zniszczony gracz nie zbiera lootu. Niezebrany loot znika przy restarcie poziomu. Zebrane przedmioty zachowują wszystkie @@ -22,8 +22,8 @@ wylosowane wartości, addony, poziomy i rozmieszczenie po śmierci gracza. Addony działają wyłącznie w zamontowanej broni/modułach. Procenty kadłuba, tarcz i prędkości mnożą bazę powiększoną o bonusy płaskie. Bonus obrażeń działa na obie bronie (także laser i rakiety). Regeneracja dodaje punkty na sekundę. -EXP i kredyty mają obliczone mnożniki statku; naliczanie nagród wymaga przyszłego -systemu postępu pilota i waluty, których gra obecnie nie posiada. +EXP i kredyty mają obliczone mnożniki statku i zwiększają nagrody kapitana +za zniszczonego wroga. Bonusy działają wyłącznie po zamontowaniu przedmiotu. UI: kolor przedmiotu wskazuje rzadkość. Najechanie na slot pokazuje pełne parametry, poziom, rzadkość, addony i parametry broni. Przenoszenie nadal odbywa się drag/drop. @@ -60,7 +60,7 @@ W Godocie wybierz plik cechy .tres w FileSystem i edytuj go w Inspectorze: Aby dodać cechę: utwórz zasób ItemAffixDefinition, zapisz w affixes i dodaj do tablicy affixes w affix_database.tres. Sama obecność pliku w katalogu nie dodaje -go do losowania. Aktualne osiem cech ma wagę 1 i nie ma wzajemnych wykluczeń. +go do losowania. Aktualne dziesięć cech ma wagę 1 i nie ma wzajemnych wykluczeń. Nowy stat_key wymaga również implementacji efektu w kodzie; baza opisuje reguły losowania i prezentację, nie tworzy automatycznie nowych mechanik statku. Tooltip pobiera nazwę i jednostkę z definicji cechy. Wylosowana wartość pozostaje @@ -90,3 +90,129 @@ Tooltip i etykieta slotu pokazują bazowy zakres broni; bonus procentowy statku jest naliczany w walce. Zakres dropu zachowuje się po restarcie poziomu. Bronie startowe mają zakres z wartości środkowych ustawień w definicji. Starszy item z primary_value_override i bez zakresu zachowuje stałe obrażenia. + +UKŁADY I PRZECHODZENIE POZIOMÓW + +Generator: scripts/levels/system_generator.gd. Balans: scripts/levels/level_balance.gd. +Nowa gra zaczyna się na poziomie 1. Poziom widoczny jest wyłącznie w debug HUD. +Każdy układ ma gwiazdę w (0,0) i 1–5 planet w odległości ok. 960–1480 px. +Tekstury są losowane z assets/stars/s1–s8 i assets/planets/p1–p18. +Dokładnie jedna planeta ma chronioną rasę, oznaczoną podpisem i kolorową obwódką. +Znacznik na HUD wskazuje kierunek do tej planety, kiedy jest poza obszarem widoku. +Numer układu, liczba planet, cel, odległość i kierunek są podane w oknie debug. +Stare dekoracyjne planety, boja nawigacyjna i cel testowy zniknęły z poziomu gry. + +Gracz zaczyna w (180,200), obok centralnej gwiazdy. Przy generowaniu wrogowie nie +pojawiają się w promieniu 1200 px od gwiazdy ani bliżej niż 940 px od gracza. +Jest to bezpieczny obszar startowy; aktywowany podczas walki wróg może tam dolecieć. +Wrogowie powstają w skupiskach 2–5 przy planetach, z zachowaniem granic mapy, +odległości od planet i minimum 110 px między jednostkami. Boss ma dwie elitarne +jednostki w swoim skupisku. Końcowe skupisko może być mniejsze. +Liczba wrogów interpoluje między punktami koncepcji: +1=5, 10=10, 50=18, 100=23, 250=29, 500=34, 1000=40. +Poziomy 1–10: wyłącznie zwykli. Udziały Elite/Boss interpolują od 50:15%/0%, +100:25%/5%, 500:45%/10% do 1000:55%/15%. Wyniki są zaokrąglane; od 100 +jest co najmniej jeden Boss, a liczba Elite gwarantuje dwie obstawy na Bossa. +Kadłub i obrażenia wrogów skalują się jak loot: 1 + 0.05 * (L - 1). +Elite: x2 kadłub, x1.3 obrażenia; Boss: x6 kadłub, x1.7 obrażenia i Mega_boss.png. +Prędkość: 62 * (1 + 0.0005 * (L - 1)); cooldown: max(0.55, 1.5/(1+0.001*(L-1))). + +Po pokonaniu wszystkich wrogów chroniona planeta otwiera usługi. Przy podlocie +na odległość radius_planety + 180 px menu pojawia się automatycznie. Na razie +zawiera miejsce na usługi, przycisk następnego układu i powrotu do statku. +Podczas wizyty statek stoi, nie strzela i nie przyjmuje obrażeń. Zamknięcie menu +nie otwiera go ponownie, dopóki gracz nie opuści zasięgu i nie podleci ponownie. +Następny układ: poziom +1, nowy seed, nowe planety i wrogowie, zachowany ekwipunek, +poziomy itemów, addony i konfiguracja. Kadłub, tarcze i energia są uzupełnione. +Nowe dropy korzystają z nowego poziomu; wcześniej zdobyte nie zmieniają statystyk. +Po śmierci poziom i seed pozostają te same: układ odtwarza planety i pełny skład +wrogów. Niezebrany loot znika; zebrane itemy pozostają. Maksymalny poziom to 1000; +na nim menu usług działa, ale przycisk następnego poziomu jest zablokowany. + +KAPITAN, XP, KREDYTY I NAUKA + +Stan kapitana: GameState.captain (CaptainProgress), zachowany przy śmierci +i zmianie układu. Nowa gra zeruje postać: poziom 1, XP 0, kredyty 0, punkty nauki 0, +wszystkie umiejętności 0. Balans: scripts/captain/captain_balance.gd. +Awans wymaga 100 + 50 * (poziom_kapitana - 1) XP. Nadwyżka przechodzi dalej, +jedna nagroda może dać kilka awansów. Każdy awans daje 1 punkt nauki. +Plus w panelu kapitana kupuje 1 poziom wybranej umiejętności za 1 punkt nauki. +Umiejętności mają limit 100; nie da się wydać punktów, których postać nie ma. + +Nagroda za wroga (XP / kredyty): Normal 20/15, Elite 50/40, Boss 150/120. +Nagrody mnożą się przez 1 + 0.05 * (poziom_układu - 1) oraz odpowiedni mnożnik +EXP/kredytów wyposażenia i są zaokrąglane do całkowitych punktów. +Wróg wypłaca nagrodę dokładnie raz przy zniszczeniu, niezależnie od dropu itemu. +XP i kredyty są przyznawane bez konieczności podlatywania do wraku. + +Każdy poziom umiejętności: +- Pilotaż: +1 punkt procentowy szansy na unik. Unik anuluje 100% danego trafienia, + nie zabiera tarcz ani kadłuba i pokazuje napis UNIK. +- Strzelec: +1% obrażeń. Mnożnik kapitana mnoży się z mnożnikiem wyposażenia. +- Mechanik: -1% otrzymywanych obrażeń, po próbie uniku, przed tarczami i kadłubem. +- Celne oko: +1 punkt procentowy szansy na krytyk. +Pilotaż 100 = 100% uniku, Mechanik 100 = 100% redukcji. Obrażenia nigdy nie leczą. + +TRAFIENIA KRYTYCZNE + +Bazowa szansa: 0%. Szansa = Celne oko + suma critical_chance_percent z wyposażenia, +ograniczona do 100%. Bazowe obrażenia krytyczne: x2. Mnożnik krytyka wynosi +2 * (1 + suma critical_damage_percent / 100), więc addon +20% daje x2.4. +Losowanie odbywa się raz dla pocisku lub trafiającego impulsu lasera. Rakieta +ma ten sam wynik obrażeń i krytyka dla całej eksplozji; ten sam cel nie dostaje +obrażeń dwa razy. Trafienie krytyczne pokazuje wyróżniony napis KRYT!. +Dwa nowe zasoby w resources/items/affixes, edytowalne jak pozostałe: +critical_chance_percent: 1–2% na poziomie 1, 10–20% na poziomie 1000. +critical_damage_percent: 5–10% na poziomie 1, 50–100% na poziomie 1000. +Obecnie dozwolone na wszystkich kategoriach; można zmienić maskę w Inspectorze. + +INTERFEJS + +Kompaktowy panel kapitana znajduje się nad wyposażeniem statku po prawej stronie: +poziom postaci, XP i pasek postępu, kredyty, punkty nauki, cztery umiejętności +z plusami, łączna szansa i mnożnik krytyka. Numer układu nadal jest tylko w debug. +Panel statku ma mniejszy schemat i sloty. Magazyn ma 5 kolumn i 4 wiersze, +przyciski kasowania, drag/drop i pełne podpowiedzi statystyk zachowują działanie. + +AKTYWNE ROZSZERZENIA I CZĘŚCI + +Nowa kategoria ItemDefinition.Category.ACTIVE_EXTENSION (5), odrębna od starszych +pasywnych rozszerzeń (4). Aktywne rozszerzenie zajmuje jeden z sześciu slotów modułów. +Numer slotu przypisuje klawisz 1–6; przeniesienie modułu zmienia przypisanie. +Na dole ekranu pojawia się przycisk z nazwą i klawiszem. Nieaktywny przycisk ma +w podpowiedzi przyczynę (energia, pełne tarcze/kadłub, brak części). Można też kliknąć. +Dopalacz, Ładowanie tarcz i Drony naprawcze są w startowym magazynie i puli łupów. +Dodatkowe statystyki losują się jak na pozostałych modułach; siła aktywnej umiejętności +jest ustalona przez jej zasób i nie skaluje się automatycznie z poziomem itemu. + +Dopalacz: wymaga pełnej energii i zużywa całą aktualną maksymalną energię. +Rozpędza w kierunku przodu statku do 300% maksymalnej prędkości (+200%) w 0.3 s. +Nadmiar prędkości potem maleje ze zwykłym space_drag. Hamulec nadal działa. +Nie można ponownie odpalić podczas trwania dopalacza. +Ładowanie tarcz: wymaga pełnej energii, zużywa ją i dodaje 100 pkt tarcz do maksimum. +Drony naprawcze: bez kosztu energii, natychmiast naprawiają maksymalnie możliwy kadłub, +wydając 1 część za 1 pkt. Części mogą mieć ułamkową wartość, ponieważ kadłub także ją ma. +Pełne tarcze/kadłub lub brak zasobów blokują użycie bez wydawania kosztu. +Umiejętności są zablokowane podczas dokowania i po zniszczeniu statku. + +Kliknięcie × przy przedmiocie w magazynie rozkłada go na 10 części. Pusty slot +nie daje części. Licznik jest w panelu kapitana i nagłówku magazynu. Części są +w CaptainProgress i pozostają przy restarcie oraz zmianie układu; nowa gra je zeruje. + +DODAWANIE NASTĘPNEJ UMIEJĘTNOŚCI + +1. Utwórz skrypt extends ActiveAbility w scripts/abilities. Zaimplementuj + unavailable_reason(ship): String (pusty tekst oznacza gotowość) oraz activate(ship). + Eksportowane parametry służą do regulowania działania w Inspectorze. + Zasób opisuje działanie; stan czasowy efektu trzymaj na statku, nie na współdzielonym zasobie. +2. Skopiuj np. resources/items/shield_charge.tres. W sub_resource Ability ustaw skrypt, + display_name, description i jego parametry. W ItemDefinition ustaw unikalne item_id, + nazwę, category = 5 i active_ability wskazujące ten zasób. +3. Dopisz preload nowego .tres do DEFINITIONS w scripts/items/item_generator.gd, + aby losował się z wrogów. Opcjonalnie dodaj ścieżkę do starter_items + w scripts/items/ship_inventory.gd, aby od razu był dostępny w nowej grze. +4. Załóż go w dowolnym slocie modułu. Pasek, klawisz i blokady zasobów działają + automatycznie — nie trzeba dopisywać wyjątków w HUD ani obsłudze klawiatury. + +Maska addonów ma teraz sześć kategorii. 63 oznacza wszystkie, 32 tylko aktywne rozszerzenia. +Test integracyjny: tests/abilities/active_abilities_test.tscn. diff --git a/resources/items/affix_database.tres b/resources/items/affix_database.tres index 62f500a..ec1c2c3 100644 --- a/resources/items/affix_database.tres +++ b/resources/items/affix_database.tres @@ -1,4 +1,4 @@ -[gd_resource type="Resource" script_class="ItemAffixDatabase" load_steps=11 format=3] +[gd_resource type="Resource" script_class="ItemAffixDatabase" load_steps=13 format=3] [ext_resource type="Script" path="res://scripts/items/item_affix_database.gd" id="1_database"] [ext_resource type="Script" path="res://scripts/items/item_affix_definition.gd" id="2_type"] @@ -10,8 +10,9 @@ [ext_resource type="Resource" path="res://resources/items/affixes/speed_percent.tres" id="8_affix"] [ext_resource type="Resource" path="res://resources/items/affixes/experience_percent.tres" id="9_affix"] [ext_resource type="Resource" path="res://resources/items/affixes/credits_percent.tres" id="10_affix"] +[ext_resource type="Resource" path="res://resources/items/affixes/critical_chance_percent.tres" id="11_affix"] +[ext_resource type="Resource" path="res://resources/items/affixes/critical_damage_percent.tres" id="12_affix"] [resource] script = ExtResource("1_database") -affixes = Array[ExtResource("2_type")]([ExtResource("3_affix"), ExtResource("4_affix"), ExtResource("5_affix"), ExtResource("6_affix"), ExtResource("7_affix"), ExtResource("8_affix"), ExtResource("9_affix"), ExtResource("10_affix")]) - +affixes = Array[ExtResource("2_type")]([ExtResource("3_affix"), ExtResource("4_affix"), ExtResource("5_affix"), ExtResource("6_affix"), ExtResource("7_affix"), ExtResource("8_affix"), ExtResource("9_affix"), ExtResource("10_affix"), ExtResource("11_affix"), ExtResource("12_affix")]) diff --git a/resources/items/affixes/credits_percent.tres b/resources/items/affixes/credits_percent.tres index ecc9d3a..c8bbe18 100644 --- a/resources/items/affixes/credits_percent.tres +++ b/resources/items/affixes/credits_percent.tres @@ -9,7 +9,7 @@ display_name = "Kredyty" stat_key = "credits_percent" unit = "%" selection_weight = 1.0 -category_mask = 31 +category_mask = 63 minimum_value_level_1 = 2 maximum_value_level_1 = 5 minimum_value_level_1000 = 40 diff --git a/resources/items/affixes/critical_chance_percent.tres b/resources/items/affixes/critical_chance_percent.tres new file mode 100644 index 0000000..7935605 --- /dev/null +++ b/resources/items/affixes/critical_chance_percent.tres @@ -0,0 +1,15 @@ +[gd_resource type="Resource" script_class="ItemAffixDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_affix_definition.gd" id="1_affix"] + +[resource] +script = ExtResource("1_affix") +affix_id = "critical_chance_percent" +display_name = "Szansa na trafienie krytyczne" +stat_key = "critical_chance_percent" +unit = "%" +category_mask = 63 +minimum_value_level_1 = 1.0 +maximum_value_level_1 = 2.0 +minimum_value_level_1000 = 10.0 +maximum_value_level_1000 = 20.0 diff --git a/resources/items/affixes/critical_damage_percent.tres b/resources/items/affixes/critical_damage_percent.tres new file mode 100644 index 0000000..009086b --- /dev/null +++ b/resources/items/affixes/critical_damage_percent.tres @@ -0,0 +1,15 @@ +[gd_resource type="Resource" script_class="ItemAffixDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_affix_definition.gd" id="1_affix"] + +[resource] +script = ExtResource("1_affix") +affix_id = "critical_damage_percent" +display_name = "Obrażenia krytyczne" +stat_key = "critical_damage_percent" +unit = "%" +category_mask = 63 +minimum_value_level_1 = 5.0 +maximum_value_level_1 = 10.0 +minimum_value_level_1000 = 50.0 +maximum_value_level_1000 = 100.0 diff --git a/resources/items/affixes/damage_percent.tres b/resources/items/affixes/damage_percent.tres index f16b63e..8562174 100644 --- a/resources/items/affixes/damage_percent.tres +++ b/resources/items/affixes/damage_percent.tres @@ -9,7 +9,7 @@ display_name = "Obrażenia broni" stat_key = "damage_percent" unit = "%" selection_weight = 1.0 -category_mask = 31 +category_mask = 63 minimum_value_level_1 = 1 maximum_value_level_1 = 3 minimum_value_level_1000 = 25 diff --git a/resources/items/affixes/energy_regeneration.tres b/resources/items/affixes/energy_regeneration.tres index 1b9b84c..04341c6 100644 --- a/resources/items/affixes/energy_regeneration.tres +++ b/resources/items/affixes/energy_regeneration.tres @@ -9,7 +9,7 @@ display_name = "Regeneracja energii" stat_key = "energy_regeneration" unit = "/s" selection_weight = 1.0 -category_mask = 31 +category_mask = 63 minimum_value_level_1 = 0.2 maximum_value_level_1 = 0.5 minimum_value_level_1000 = 100 diff --git a/resources/items/affixes/experience_percent.tres b/resources/items/affixes/experience_percent.tres index 4da9778..0b8ee4f 100644 --- a/resources/items/affixes/experience_percent.tres +++ b/resources/items/affixes/experience_percent.tres @@ -9,7 +9,7 @@ display_name = "Doświadczenie (EXP)" stat_key = "experience_percent" unit = "%" selection_weight = 1.0 -category_mask = 31 +category_mask = 63 minimum_value_level_1 = 2 maximum_value_level_1 = 5 minimum_value_level_1000 = 40 diff --git a/resources/items/affixes/hull_percent.tres b/resources/items/affixes/hull_percent.tres index 095c6d1..46dd7d6 100644 --- a/resources/items/affixes/hull_percent.tres +++ b/resources/items/affixes/hull_percent.tres @@ -9,7 +9,7 @@ display_name = "Kadłub" stat_key = "hull_percent" unit = "%" selection_weight = 1.0 -category_mask = 31 +category_mask = 63 minimum_value_level_1 = 1 maximum_value_level_1 = 3 minimum_value_level_1000 = 25 diff --git a/resources/items/affixes/shield_percent.tres b/resources/items/affixes/shield_percent.tres index febb45e..c41995e 100644 --- a/resources/items/affixes/shield_percent.tres +++ b/resources/items/affixes/shield_percent.tres @@ -9,7 +9,7 @@ display_name = "Tarcze" stat_key = "shield_percent" unit = "%" selection_weight = 1.0 -category_mask = 31 +category_mask = 63 minimum_value_level_1 = 1 maximum_value_level_1 = 3 minimum_value_level_1000 = 25 diff --git a/resources/items/affixes/shield_regeneration.tres b/resources/items/affixes/shield_regeneration.tres index 6496ba7..d2dd53c 100644 --- a/resources/items/affixes/shield_regeneration.tres +++ b/resources/items/affixes/shield_regeneration.tres @@ -9,7 +9,7 @@ display_name = "Regeneracja tarcz" stat_key = "shield_regeneration" unit = "/s" selection_weight = 1.0 -category_mask = 31 +category_mask = 63 minimum_value_level_1 = 0.5 maximum_value_level_1 = 1 minimum_value_level_1000 = 200 diff --git a/resources/items/affixes/speed_percent.tres b/resources/items/affixes/speed_percent.tres index 294643a..bde71fe 100644 --- a/resources/items/affixes/speed_percent.tres +++ b/resources/items/affixes/speed_percent.tres @@ -9,7 +9,7 @@ display_name = "Prędkość statku" stat_key = "speed_percent" unit = "%" selection_weight = 1.0 -category_mask = 31 +category_mask = 63 minimum_value_level_1 = 1 maximum_value_level_1 = 2 minimum_value_level_1000 = 15 diff --git a/resources/items/afterburner.tres b/resources/items/afterburner.tres new file mode 100644 index 0000000..0512d36 --- /dev/null +++ b/resources/items/afterburner.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=4 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1"] +[ext_resource type="Script" path="res://scripts/abilities/afterburner_ability.gd" id="2"] + +[sub_resource type="Resource" id="Ability"] +script = ExtResource("2") +display_name = "Dopalacz" +description = "Szybko rozpędza do 300% zwykłej prędkości (+200%), następnie wytraca nadmiar prędkości. Wymaga i zużywa 100% energii." + +[resource] +script = ExtResource("1") +item_id = "afterburner" +display_name = "Dopalacz" +category = 5 +description = "Aktywne rozszerzenie silnika." +active_ability = SubResource("Ability") diff --git a/resources/items/repair_drones.tres b/resources/items/repair_drones.tres new file mode 100644 index 0000000..c7be008 --- /dev/null +++ b/resources/items/repair_drones.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=4 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1"] +[ext_resource type="Script" path="res://scripts/abilities/repair_drones_ability.gd" id="2"] + +[sub_resource type="Resource" id="Ability"] +script = ExtResource("2") +display_name = "Drony naprawcze" +description = "Naprawiają tyle kadłuba, ile pozwalają części i brakujące punkty. Koszt: 1 część za 1 punkt kadłuba. Nie zużywają energii." + +[resource] +script = ExtResource("1") +item_id = "repair_drones" +display_name = "Drony naprawcze" +category = 5 +description = "Aktywne rozszerzenie naprawcze." +active_ability = SubResource("Ability") diff --git a/resources/items/shield_charge.tres b/resources/items/shield_charge.tres new file mode 100644 index 0000000..e86afa3 --- /dev/null +++ b/resources/items/shield_charge.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=4 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1"] +[ext_resource type="Script" path="res://scripts/abilities/shield_charge_ability.gd" id="2"] + +[sub_resource type="Resource" id="Ability"] +script = ExtResource("2") +display_name = "Ładowanie tarcz" +description = "Przywraca 100 punktów tarcz, do ich maksimum. Wymaga i zużywa 100% energii." + +[resource] +script = ExtResource("1") +item_id = "shield_charge" +display_name = "Ładowanie tarcz" +category = 5 +description = "Aktywne rozszerzenie tarcz." +active_ability = SubResource("Ability") diff --git a/scenes/game/game.tscn b/scenes/game/game.tscn index 8b3ac16..b7a3e7e 100644 --- a/scenes/game/game.tscn +++ b/scenes/game/game.tscn @@ -6,8 +6,8 @@ [ext_resource type="Script" uid="uid://bcfvflaqnmfa5" path="res://scripts/game/flight_hud.gd" id="4_hud"] [ext_resource type="PackedScene" path="res://scenes/ui/ship_equipment_panel.tscn" id="5_equipment"] [ext_resource type="PackedScene" path="res://scenes/ui/ship_inventory_panel.tscn" id="6_inventory"] -[ext_resource type="PackedScene" path="res://scenes/game/weapon_test_target.tscn" id="7_target"] [ext_resource type="Script" path="res://scripts/game/scene_music_player.gd" id="8_scene_music"] +[ext_resource type="PackedScene" path="res://scenes/ui/captain_panel.tscn" id="9_captain"] [sub_resource type="RectangleShape2D" id="TopWall"] size = Vector2(5200, 40) @@ -54,9 +54,6 @@ shape = SubResource("RightWall") [node name="PlayerShip" parent="." unique_id=1837545573 instance=ExtResource("3_player")] -[node name="WeaponTestTarget" parent="." unique_id=1240462223 instance=ExtResource("7_target")] -position = Vector2(240, 0) - [node name="HUD" type="CanvasLayer" parent="." unique_id=733012261] script = ExtResource("4_hud") @@ -97,10 +94,10 @@ layout_mode = 0 anchors_preset = 1 anchor_left = 1.0 anchor_right = 1.0 -offset_left = -248.0 -offset_top = 14.0 -offset_right = -14.0 -offset_bottom = 454.0 +offset_left = -270.0 +offset_top = 224.0 +offset_right = -10.0 +offset_bottom = 504.0 grow_horizontal = 0 grow_vertical = 0 @@ -111,9 +108,20 @@ anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 anchor_bottom = 0.5 -offset_left = -195.0 -offset_top = -165.0 -offset_right = 195.0 -offset_bottom = 165.0 +offset_left = -230.0 +offset_top = -128.0 +offset_right = 230.0 +offset_bottom = 128.0 grow_horizontal = 2 grow_vertical = 2 + +[node name="CaptainPanel" parent="HUD/HUDRoot" instance=ExtResource("9_captain")] +layout_mode = 0 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -270.0 +offset_top = 8.0 +offset_right = -10.0 +offset_bottom = 218.0 +grow_horizontal = 0 diff --git a/scenes/ui/captain_panel.tscn b/scenes/ui/captain_panel.tscn new file mode 100644 index 0000000..0f058bd --- /dev/null +++ b/scenes/ui/captain_panel.tscn @@ -0,0 +1,81 @@ +[gd_scene load_steps=5 format=3] + +[ext_resource type="Script" path="res://scripts/ui/captain_panel.gd" id="1_panel"] + +[sub_resource type="StyleBoxFlat" id="PanelStyle"] +bg_color = Color(0.018, 0.045, 0.085, 0.96) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.18, 0.4, 0.51, 1) +content_margin_left = 8.0 +content_margin_top = 7.0 +content_margin_right = 8.0 +content_margin_bottom = 7.0 + +[sub_resource type="StyleBoxFlat" id="XPBackground"] +bg_color = Color(0.055, 0.11, 0.16, 1) + +[sub_resource type="StyleBoxFlat" id="XPFill"] +bg_color = Color(0.25, 0.68, 0.85, 1) + +[node name="CaptainPanel" type="PanelContainer"] +custom_minimum_size = Vector2(260, 210) +theme_override_styles/panel = SubResource("PanelStyle") +script = ExtResource("1_panel") + +[node name="Contents" type="VBoxContainer" parent="."] +layout_mode = 2 +theme_override_constants/separation = 4 + +[node name="Header" type="HBoxContainer" parent="Contents"] +layout_mode = 2 + +[node name="Title" type="Label" parent="Contents/Header"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) +theme_override_font_sizes/font_size = 12 +text = "KAPITAN" + +[node name="Level" type="Label" parent="Contents/Header"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.98, 0.78, 0.43, 1) +theme_override_font_sizes/font_size = 11 + +[node name="XPLabel" type="Label" parent="Contents"] +layout_mode = 2 +theme_override_font_sizes/font_size = 10 + +[node name="XPBar" type="ProgressBar" parent="Contents"] +custom_minimum_size = Vector2(0, 8) +layout_mode = 2 +mouse_filter = 2 +theme_override_styles/background = SubResource("XPBackground") +theme_override_styles/fill = SubResource("XPFill") +show_percentage = false + +[node name="Wallet" type="HBoxContainer" parent="Contents"] +layout_mode = 2 + +[node name="Credits" type="Label" parent="Contents/Wallet"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_colors/font_color = Color(0.98, 0.78, 0.43, 1) +theme_override_font_sizes/font_size = 11 + +[node name="Points" type="Label" parent="Contents/Wallet"] +layout_mode = 2 +tooltip_text = "Punkty nauki: +1 za każdy zdobyty poziom kapitana." +theme_override_colors/font_color = Color(0.47, 0.91, 0.74, 1) +theme_override_font_sizes/font_size = 11 + +[node name="Skills" type="VBoxContainer" parent="Contents"] +layout_mode = 2 +theme_override_constants/separation = 2 + +[node name="Critical" type="Label" parent="Contents"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.98, 0.68, 0.5, 1) +theme_override_font_sizes/font_size = 10 diff --git a/scenes/ui/inventory_slot_view.tscn b/scenes/ui/inventory_slot_view.tscn index acfa153..2c76fd5 100644 --- a/scenes/ui/inventory_slot_view.tscn +++ b/scenes/ui/inventory_slot_view.tscn @@ -14,3 +14,5 @@ theme_override_font_sizes/font_size = 9 text = "PUSTY" horizontal_alignment = 1 vertical_alignment = 1 +clip_text = true +text_overrun_behavior = 3 diff --git a/scenes/ui/planet_services_menu.tscn b/scenes/ui/planet_services_menu.tscn new file mode 100644 index 0000000..8d65c42 --- /dev/null +++ b/scenes/ui/planet_services_menu.tscn @@ -0,0 +1,88 @@ +[gd_scene load_steps=3 format=3] + +[ext_resource type="Script" path="res://scripts/ui/planet_services_menu.gd" id="1_services"] + +[sub_resource type="StyleBoxFlat" id="PanelStyle"] +bg_color = Color(0.045, 0.075, 0.11, 1) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.28, 0.63, 0.54, 1) +content_margin_left = 24.0 +content_margin_top = 24.0 +content_margin_right = 24.0 +content_margin_bottom = 24.0 +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_left = 8 +corner_radius_bottom_right = 8 + +[node name="PlanetServicesMenu" type="Control"] +visible = false +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 0 +script = ExtResource("1_services") + +[node name="Dim" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +color = Color(0.01, 0.025, 0.045, 0.78) + +[node name="Center" type="CenterContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 + +[node name="Panel" type="PanelContainer" parent="Center"] +custom_minimum_size = Vector2(460, 310) +layout_mode = 2 +theme_override_styles/panel = SubResource("PanelStyle") + +[node name="Contents" type="VBoxContainer" parent="Center/Panel"] +layout_mode = 2 +theme_override_constants/separation = 16 + +[node name="Title" type="Label" parent="Center/Panel/Contents"] +layout_mode = 2 +theme_override_colors/font_color = Color(0.47, 0.91, 0.74, 1) +theme_override_font_sizes/font_size = 21 +text = "USŁUGI CHRONIONEJ RASY" +horizontal_alignment = 1 + +[node name="Status" type="Label" parent="Center/Panel/Contents"] +layout_mode = 2 +theme_override_font_sizes/font_size = 14 +text = "Układ jest bezpieczny. Mieszkańcy otwierają przejście." +horizontal_alignment = 1 + +[node name="Services" type="Label" parent="Center/Panel/Contents"] +layout_mode = 2 +size_flags_vertical = 3 +theme_override_colors/font_color = Color(0.59, 0.67, 0.75, 1) +theme_override_font_sizes/font_size = 14 +text = "Usługi w przygotowaniu" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="NextButton" type="Button" parent="Center/Panel/Contents"] +custom_minimum_size = Vector2(0, 44) +layout_mode = 2 +theme_override_font_sizes/font_size = 15 +text = "PRZEJDŹ DO NASTĘPNEGO UKŁADU" + +[node name="CloseButton" type="Button" parent="Center/Panel/Contents"] +custom_minimum_size = Vector2(0, 32) +layout_mode = 2 +theme_override_font_sizes/font_size = 14 +text = "WRÓĆ DO STATKU" diff --git a/scenes/ui/ship_equipment_panel.tscn b/scenes/ui/ship_equipment_panel.tscn index e295f47..ccd4984 100644 --- a/scenes/ui/ship_equipment_panel.tscn +++ b/scenes/ui/ship_equipment_panel.tscn @@ -29,16 +29,17 @@ theme_override_styles/panel = SubResource("EquipmentPanelStyle") [node name="Contents" type="VBoxContainer" parent="."] layout_mode = 2 -theme_override_constants/separation = 6 +theme_override_constants/separation = 3 [node name="Title" type="Label" parent="Contents"] layout_mode = 2 theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) -theme_override_font_sizes/font_size = 12 +theme_override_font_sizes/font_size = 11 text = "WYPOSAŻENIE STATKU" horizontal_alignment = 1 [node name="WeaponLabel" type="Label" parent="Contents"] +visible = false layout_mode = 2 theme_override_colors/font_color = Color(0.98, 0.72, 0.38, 1) theme_override_font_sizes/font_size = 10 @@ -62,7 +63,7 @@ slot_kind = "weapon" slot_index = 1 [node name="Schematic" type="Control" parent="Contents"] -custom_minimum_size = Vector2(0, 104) +custom_minimum_size = Vector2(0, 64) layout_mode = 2 script = ExtResource("1_schematic") @@ -70,14 +71,14 @@ script = ExtResource("1_schematic") layout_mode = 2 theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) theme_override_font_sizes/font_size = 10 -text = "MODUŁY NIEBOJOWE (6)" +text = "MODUŁY (1–6)" horizontal_alignment = 1 [node name="ModuleSlots" type="GridContainer" parent="Contents"] layout_mode = 2 columns = 2 -theme_override_constants/h_separation = 8 -theme_override_constants/v_separation = 6 +theme_override_constants/h_separation = 6 +theme_override_constants/v_separation = 3 [node name="Module1" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] layout_mode = 2 @@ -111,4 +112,5 @@ slot_index = 5 [node name="InventoryButton" type="Button" parent="Contents"] layout_mode = 2 -text = "OTWÓRZ MAGAZYN" +theme_override_font_sizes/font_size = 12 +text = "MAGAZYN" diff --git a/scenes/ui/ship_inventory_panel.tscn b/scenes/ui/ship_inventory_panel.tscn index ca407ae..06b6061 100644 --- a/scenes/ui/ship_inventory_panel.tscn +++ b/scenes/ui/ship_inventory_panel.tscn @@ -1,7 +1,19 @@ -[gd_scene load_steps=2 format=3] +[gd_scene load_steps=3 format=3] [ext_resource type="Script" path="res://scripts/ui/ship_inventory_panel.gd" id="1_inventory"] +[sub_resource type="StyleBoxFlat" id="InventoryStyle"] +bg_color = Color(0.018, 0.045, 0.085, 0.98) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.18, 0.4, 0.51, 1) +content_margin_left = 8.0 +content_margin_top = 8.0 +content_margin_right = 8.0 +content_margin_bottom = 8.0 + [node name="ShipInventoryPanel" type="PanelContainer"] visible = false anchors_preset = 8 @@ -16,6 +28,7 @@ offset_bottom = 165.0 grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_inventory") +theme_override_styles/panel = SubResource("InventoryStyle") [node name="Contents" type="VBoxContainer" parent="."] layout_mode = 2 @@ -33,12 +46,13 @@ text = "MAGAZYN (0 / 20)" [node name="CloseButton" type="Button" parent="Contents/Header"] layout_mode = 2 +theme_override_font_sizes/font_size = 11 text = "ZAMKNIJ" [node name="CargoGrid" type="GridContainer" parent="Contents"] layout_mode = 2 size_flags_horizontal = 4 size_flags_vertical = 4 -columns = 4 -theme_override_constants/h_separation = 6 -theme_override_constants/v_separation = 6 +columns = 5 +theme_override_constants/h_separation = 4 +theme_override_constants/v_separation = 4 diff --git a/scripts/abilities/active_ability.gd b/scripts/abilities/active_ability.gd new file mode 100644 index 0000000..d900b94 --- /dev/null +++ b/scripts/abilities/active_ability.gd @@ -0,0 +1,12 @@ +extends Resource +class_name ActiveAbility + +@export var display_name: String = "" +@export_multiline var description: String = "" + +# Subclasses return an empty string when ready, otherwise a reason. +func unavailable_reason(_ship: CharacterBody2D) -> String: + return "" + +func activate(_ship: CharacterBody2D) -> void: + pass diff --git a/scripts/abilities/active_ability.gd.uid b/scripts/abilities/active_ability.gd.uid new file mode 100644 index 0000000..e50694f --- /dev/null +++ b/scripts/abilities/active_ability.gd.uid @@ -0,0 +1 @@ +uid://c8t74ir8i52fq diff --git a/scripts/abilities/afterburner_ability.gd b/scripts/abilities/afterburner_ability.gd new file mode 100644 index 0000000..90a6bd1 --- /dev/null +++ b/scripts/abilities/afterburner_ability.gd @@ -0,0 +1,13 @@ +extends ActiveAbility + +@export var speed_bonus: float = 2.0 +@export var acceleration_time: float = 0.3 + +func unavailable_reason(ship: CharacterBody2D) -> String: + if ship.call("is_boosting"): + return "Dopalacz już działa" + return "Wymagana pełna energia" if ship.get("energy") < ship.get("max_energy") else "" + +func activate(ship: CharacterBody2D) -> void: + ship.set("energy", 0.0) + ship.call("start_boost", speed_bonus, acceleration_time) diff --git a/scripts/abilities/afterburner_ability.gd.uid b/scripts/abilities/afterburner_ability.gd.uid new file mode 100644 index 0000000..0eaf05e --- /dev/null +++ b/scripts/abilities/afterburner_ability.gd.uid @@ -0,0 +1 @@ +uid://bpaiuqwsxswii diff --git a/scripts/abilities/repair_drones_ability.gd b/scripts/abilities/repair_drones_ability.gd new file mode 100644 index 0000000..cfa9418 --- /dev/null +++ b/scripts/abilities/repair_drones_ability.gd @@ -0,0 +1,12 @@ +extends ActiveAbility + +func unavailable_reason(ship: CharacterBody2D) -> String: + if ship.get("hull") >= ship.get("max_hull"): + return "Kadłub jest pełny" + return "Brak części" if GameState.captain.parts <= 0.0 else "" + +func activate(ship: CharacterBody2D) -> void: + var amount := minf(GameState.captain.parts, ship.get("max_hull") - ship.get("hull")) + ship.set("hull", ship.get("hull") + amount) + GameState.captain.parts -= amount + GameState.captain.emit_changed() diff --git a/scripts/abilities/repair_drones_ability.gd.uid b/scripts/abilities/repair_drones_ability.gd.uid new file mode 100644 index 0000000..72717b9 --- /dev/null +++ b/scripts/abilities/repair_drones_ability.gd.uid @@ -0,0 +1 @@ +uid://bgofku10gduus diff --git a/scripts/abilities/shield_charge_ability.gd b/scripts/abilities/shield_charge_ability.gd new file mode 100644 index 0000000..59d596e --- /dev/null +++ b/scripts/abilities/shield_charge_ability.gd @@ -0,0 +1,13 @@ +extends ActiveAbility + +@export var shield_amount: float = 100.0 + +func unavailable_reason(ship: CharacterBody2D) -> String: + if ship.get("shields") >= ship.get("max_shields"): + return "Tarcze są pełne" + return "Wymagana pełna energia" if ship.get("energy") < ship.get("max_energy") else "" + +func activate(ship: CharacterBody2D) -> void: + ship.set("energy", 0.0) + ship.set("shields", minf(ship.get("max_shields"), ship.get("shields") + shield_amount)) + ship.call("_update_shield_visual") diff --git a/scripts/abilities/shield_charge_ability.gd.uid b/scripts/abilities/shield_charge_ability.gd.uid new file mode 100644 index 0000000..b815ef6 --- /dev/null +++ b/scripts/abilities/shield_charge_ability.gd.uid @@ -0,0 +1 @@ +uid://bwka1dwxq64sl diff --git a/scripts/captain/captain_balance.gd b/scripts/captain/captain_balance.gd new file mode 100644 index 0000000..59dfa6e --- /dev/null +++ b/scripts/captain/captain_balance.gd @@ -0,0 +1,22 @@ +extends RefCounted + +const XP_BASE := 100 +const XP_PER_LEVEL := 50 +const LEARNING_POINTS_PER_LEVEL := 1 +const MAX_SKILL_RANK := 100 +const BASE_CRITICAL_MULTIPLIER := 2.0 +const KILL_XP := [20, 50, 150] +const KILL_CREDITS := [15, 40, 120] +const SKILL_NAMES := { + "piloting": "Pilotaż", "gunner": "Strzelec", + "mechanic": "Mechanik", "sharp_eye": "Celne oko", +} +const SKILL_HELP := { + "piloting": "Każdy poziom: +1 punkt procentowy szansy na unik. Unik anuluje całe trafienie.", + "gunner": "Każdy poziom: +1% obrażeń wszystkich broni.", + "mechanic": "Każdy poziom: otrzymywane obrażenia mniejsze o 1% (przed tarczami i kadłubem).", + "sharp_eye": "Każdy poziom: +1 punkt procentowy szansy na trafienie krytyczne.", +} + +static func xp_required(level: int) -> int: + return XP_BASE + XP_PER_LEVEL * (maxi(1, level) - 1) diff --git a/scripts/captain/captain_balance.gd.uid b/scripts/captain/captain_balance.gd.uid new file mode 100644 index 0000000..f65ba88 --- /dev/null +++ b/scripts/captain/captain_balance.gd.uid @@ -0,0 +1 @@ +uid://cs4kncrh1vd8o diff --git a/scripts/captain/captain_progress.gd b/scripts/captain/captain_progress.gd new file mode 100644 index 0000000..87e2dc8 --- /dev/null +++ b/scripts/captain/captain_progress.gd @@ -0,0 +1,47 @@ +extends Resource +class_name CaptainProgress + +const BALANCE := preload("res://scripts/captain/captain_balance.gd") + +@export var level: int = 1 +@export var experience: int = 0 +@export var credits: int = 0 +@export var parts: float = 0.0 +@export var learning_points: int = 0 +@export var skills: Dictionary = { + "piloting": 0, "gunner": 0, "mechanic": 0, "sharp_eye": 0, +} + +func get_xp_required() -> int: + return BALANCE.xp_required(level) + +func get_skill_rank(skill: String) -> int: + return clampi(int(skills.get(skill, 0)), 0, BALANCE.MAX_SKILL_RANK) + +func can_train(skill: String) -> bool: + return skills.has(skill) and learning_points > 0 and get_skill_rank(skill) < BALANCE.MAX_SKILL_RANK + +func train_skill(skill: String) -> bool: + if not can_train(skill): + return false + skills[skill] = get_skill_rank(skill) + 1 + learning_points -= 1 + emit_changed() + return true + +func add_rewards(xp_amount: int, credit_amount: int) -> void: + experience += maxi(0, xp_amount) + credits += maxi(0, credit_amount) + while experience >= get_xp_required(): + experience -= get_xp_required() + level += 1 + learning_points += BALANCE.LEARNING_POINTS_PER_LEVEL + emit_changed() + +func reward_enemy(system_level: int, tier: int, xp_multiplier: float, credit_multiplier: float) -> Vector2i: + var index := clampi(tier, 0, 2) + var scale_factor := 1.0 + 0.05 * (clampi(system_level, 1, 1000) - 1) + var xp := roundi(BALANCE.KILL_XP[index] * scale_factor * maxf(0.0, xp_multiplier)) + var money := roundi(BALANCE.KILL_CREDITS[index] * scale_factor * maxf(0.0, credit_multiplier)) + add_rewards(xp, money) + return Vector2i(xp, money) diff --git a/scripts/captain/captain_progress.gd.uid b/scripts/captain/captain_progress.gd.uid new file mode 100644 index 0000000..f2b3a67 --- /dev/null +++ b/scripts/captain/captain_progress.gd.uid @@ -0,0 +1 @@ +uid://d0rxo6xorrw4c diff --git a/scripts/game/combat_rolls.gd b/scripts/game/combat_rolls.gd new file mode 100644 index 0000000..ee8dcd8 --- /dev/null +++ b/scripts/game/combat_rolls.gd @@ -0,0 +1,17 @@ +extends RefCounted + +static func weapon_hit(base_damage: float, damage_multiplier: float, critical_chance: float, critical_multiplier: float, roll: float = -1.0) -> Dictionary: + var random_value := randf() if roll < 0.0 else roll + var chance := clampf(critical_chance, 0.0, 1.0) + var critical := base_damage > 0.0 and (chance >= 1.0 or random_value < chance) + var damage := maxf(0.0, base_damage) * maxf(0.0, damage_multiplier) + if critical: + damage *= maxf(1.0, critical_multiplier) + return {"damage": damage, "critical": critical} + +static func incoming_hit(amount: float, evasion_chance: float, reduction: float, roll: float = -1.0) -> Dictionary: + var random_value := randf() if roll < 0.0 else roll + var chance := clampf(evasion_chance, 0.0, 1.0) + var evaded := amount > 0.0 and (chance >= 1.0 or random_value < chance) + var damage := 0.0 if evaded else maxf(0.0, amount) * (1.0 - clampf(reduction, 0.0, 1.0)) + return {"damage": damage, "evaded": evaded} diff --git a/scripts/game/combat_rolls.gd.uid b/scripts/game/combat_rolls.gd.uid new file mode 100644 index 0000000..1e57fbf --- /dev/null +++ b/scripts/game/combat_rolls.gd.uid @@ -0,0 +1 @@ +uid://cm0dgjkxym6m1 diff --git a/scripts/game/damage_popup.gd b/scripts/game/damage_popup.gd index a048d30..947c518 100644 --- a/scripts/game/damage_popup.gd +++ b/scripts/game/damage_popup.gd @@ -1,12 +1,15 @@ extends Label +@export var text_color := Color(1.0, 0.78, 0.28, 1.0) +@export var is_critical := false + func _ready() -> void: z_index = 30 - add_theme_color_override("font_color", Color(1.0, 0.78, 0.28, 1.0)) + add_theme_color_override("font_color", Color("ff8b64") if is_critical else text_color) add_theme_color_override("font_shadow_color", Color(0.05, 0.08, 0.12, 0.95)) add_theme_constant_override("shadow_offset_x", 2) add_theme_constant_override("shadow_offset_y", 2) - add_theme_font_size_override("font_size", 22) + add_theme_font_size_override("font_size", 25 if is_critical else 19) var tween := create_tween() tween.set_parallel(true) tween.tween_property(self, "position:y", position.y - 48.0, 0.8).set_ease(Tween.EASE_OUT) diff --git a/scripts/game/enemy_plasma_projectile.gd b/scripts/game/enemy_plasma_projectile.gd index 6aaa97d..6abb4ce 100644 --- a/scripts/game/enemy_plasma_projectile.gd +++ b/scripts/game/enemy_plasma_projectile.gd @@ -8,6 +8,7 @@ var projectile_speed := 300.0 var damage := 8.0 var max_range := 1000.0 var _distance_travelled := 0.0 +var _impact_handled := false func _ready() -> void: body_entered.connect(_on_body_entered) @@ -40,6 +41,9 @@ func _on_body_entered(body: Node2D) -> void: _hit_target(body) func _hit_target(target: Variant) -> void: + if _impact_handled: + return + _impact_handled = true var effect := IMPACT_EFFECT_SCENE.instantiate() as Node2D effect.global_position = global_position get_parent().add_child(effect) diff --git a/scripts/game/enemy_ship.gd b/scripts/game/enemy_ship.gd index c6caf6c..eae38b9 100644 --- a/scripts/game/enemy_ship.gd +++ b/scripts/game/enemy_ship.gd @@ -6,6 +6,7 @@ const PLASMA_PROJECTILE_SCENE := preload("res://scenes/game/enemy_plasma_project const WEAPON_AUDIO_SCRIPT := preload("res://scripts/game/weapon_audio.gd") const ITEM_GENERATOR := preload("res://scripts/items/item_generator.gd") const LOOT_PICKUP := preload("res://scripts/items/loot_pickup.gd") +const LEVEL_BALANCE := preload("res://scripts/levels/level_balance.gd") @export_enum("Normal", "Elite", "Boss") var loot_tier: int = 0 @@ -30,12 +31,25 @@ func _ready() -> void: add_to_group("enemies") _weapon_timer = randf_range(0.2, weapon_cooldown) +func apply_level_settings(level: int, tier: int) -> void: + loot_tier = tier + var power := LEVEL_BALANCE.power_scale(level) + var hull_multiplier := 1.0 if tier == 0 else (2.0 if tier == 1 else 6.0) + var damage_bonus := 1.0 if tier == 0 else (1.3 if tier == 1 else 1.7) + max_hull = 50.0 * power * hull_multiplier + hull = max_hull + weapon_damage = 8.0 * power * damage_bonus + approach_speed = 62.0 * (1.0 + 0.0005 * (clampi(level, 1, 1000) - 1)) + weapon_cooldown = maxf(0.55, 1.5 / (1.0 + 0.001 * (clampi(level, 1, 1000) - 1))) + func configure(player: CharacterBody2D, ship_texture: Texture2D) -> void: _player = player _sprite = $Sprite2D _sprite.texture = ship_texture var largest_dimension := maxf(ship_texture.get_width(), ship_texture.get_height()) - _sprite.scale = Vector2.ONE * (56.0 / largest_dimension) + var visual_size := 56.0 if loot_tier == 0 else (68.0 if loot_tier == 1 else 104.0) + _sprite.scale = Vector2.ONE * (visual_size / largest_dimension) + _sprite.modulate = Color("ffc785") if loot_tier == 1 else Color.WHITE func _physics_process(delta: float) -> void: if not is_instance_valid(_player): @@ -73,16 +87,24 @@ func _fire_plasma(direction: Vector2) -> void: get_parent().add_child(projectile) WEAPON_AUDIO_SCRIPT.play(get_parent(), global_position, ItemDefinition.WeaponKind.PLASMA, -10.0) -func take_damage(amount: float) -> void: +func take_weapon_hit(amount: float, critical: bool) -> void: + take_damage(amount, critical) + +func take_damage(amount: float, critical: bool = false) -> void: if is_queued_for_deletion() or hull <= 0.0: return - hull = maxf(0.0, hull - amount) - _show_damage_popup(amount) + hull = maxf(0.0, hull - maxf(0.0, amount)) + _show_damage_popup(amount, critical) if hull <= 0.0: + _reward_captain() _drop_loot() _spawn_destruction_effect() queue_free() +func _reward_captain() -> void: + if is_instance_valid(_player): + GameState.captain.reward_enemy(GameState.system_level, loot_tier, float(_player.get("experience_multiplier")), float(_player.get("credits_multiplier"))) + func _drop_loot() -> void: var chance := 0.65 if loot_tier == 0 else (0.9 if loot_tier == 1 else 1.0) if randf() > chance: @@ -99,9 +121,10 @@ func _spawn_destruction_effect() -> void: get_parent().add_child(effect) effect.call("configure", true, Color(1.0, 0.36, 0.18)) -func _show_damage_popup(amount: float) -> void: +func _show_damage_popup(amount: float, critical: bool = false) -> void: var popup := DAMAGE_POPUP_SCENE.instantiate() as Label - popup.text = "-%s DMG" % _format_damage(amount) + popup.text = "%s-%s DMG" % ["KRYT! " if critical else "", _format_damage(amount)] + popup.set("is_critical", critical) popup.global_position = global_position + Vector2(randf_range(-16.0, 16.0), -28.0) get_parent().add_child(popup) diff --git a/scripts/game/flight_hud.gd b/scripts/game/flight_hud.gd index 6596351..2c7d1d4 100644 --- a/scripts/game/flight_hud.gd +++ b/scripts/game/flight_hud.gd @@ -7,47 +7,63 @@ extends CanvasLayer @onready var inventory_panel: Control = $HUDRoot/ShipInventoryPanel var _debug_expanded := true +var _ability_buttons: Dictionary = {} +var _ability_bar: HBoxContainer func _ready() -> void: + _create_ability_bar() debug_toggle.pressed.connect(_toggle_debug) inventory_button.pressed.connect(_toggle_inventory) _update_debug_toggle() + $HUDRoot/CaptainPanel.resized.connect(func() -> void: _layout_sidebar.call_deferred()) + _layout_sidebar.call_deferred() + +func _layout_sidebar() -> void: + var captain_panel := $HUDRoot/CaptainPanel as Control + var equipment_panel := $HUDRoot/ShipEquipmentPanel as Control + captain_panel.grow_vertical = Control.GROW_DIRECTION_END + equipment_panel.grow_vertical = Control.GROW_DIRECTION_END + equipment_panel.position.y = captain_panel.position.y + captain_panel.size.y + 6.0 + equipment_panel.size.y = equipment_panel.get_combined_minimum_size().y func _process(_delta: float) -> void: + _update_ability_bar() if not _debug_expanded: return var ship_position := player.global_position var ship_velocity := player.velocity var angular_speed := float(player.get("angular_velocity")) - var enemy_count := 0 - for enemy in get_tree().get_nodes_in_group("enemies"): - if not enemy.is_queued_for_deletion(): - enemy_count += 1 + var game := get_parent() + var enemy_count: int = game.call("get_remaining_enemies") + var goal: Node2D = game.get("protected_planet") + var to_planet := goal.global_position - player.global_position debug_info.text = """STEROWANIE W: ciąg S: hamulec / wsteczny Q / E: strafe A / D: obrót LPM / PPM: broń 1 / broń 2 +1–6: aktywne rozszerzenia -POZIOM +UKŁAD: %d · PLANETY: %d WROGOWIE: %d +CEL: %s +PLANETA RASY: %.0f px · %.0f° STATEK KADŁUB: %d / %d TARCZE: %d / %d ENERGIA: %d / %d -ENERGIA REGEN: %.1f /s -TARCZE REGEN: %.1f /s +REGEN E / T: %.1f / %.1f /s RUCH PRĘDKOŚĆ: %.1f px/s -WEKTOR X: %.1f px/s -WEKTOR Y: %.1f px/s -POZYCJA X: %.1f -POZYCJA Y: %.1f +WEKTOR: [%.1f, %.1f] px/s +POZYCJA: [%.1f, %.1f] KIERUNEK: %.1f° OBRÓT: %.2f rad/s""" % [ - enemy_count, + GameState.system_level, int(game.get("system_data")["planets"].size()), enemy_count, + "Odwiedź chronioną rasę" if bool(game.get("system_cleared")) else "Oczyść układ", + to_planet.length(), wrapf(rad_to_deg(to_planet.angle()) + 90.0, 0.0, 360.0), roundi(float(player.get("hull"))), roundi(float(player.get("max_hull"))), roundi(float(player.get("shields"))), roundi(float(player.get("max_shields"))), roundi(float(player.get("energy"))), roundi(float(player.get("max_energy"))), @@ -67,3 +83,40 @@ func _update_debug_toggle() -> void: func _toggle_inventory() -> void: inventory_panel.visible = not inventory_panel.visible + +func _create_ability_bar() -> void: + var panel := PanelContainer.new() + panel.name = "ActiveAbilities" + $HUDRoot.add_child(panel) + panel.set_anchors_and_offsets_preset(Control.PRESET_BOTTOM_LEFT) + panel.offset_left = 12.0 + panel.offset_right = 12.0 + panel.offset_top = -54.0 + panel.offset_bottom = -12.0 + _ability_bar = HBoxContainer.new() + _ability_bar.add_theme_constant_override("separation", 4) + panel.add_child(_ability_bar) + for index in 6: + var button := Button.new() + button.name = "Ability%d" % (index + 1) + button.custom_minimum_size = Vector2(120, 40) + button.add_theme_font_size_override("font_size", 11) + button.pressed.connect(func() -> void: player.call("activate_ability", index)) + _ability_bar.add_child(button) + _ability_buttons[index] = button + _update_ability_bar() + +func _update_ability_bar() -> void: + var any_equipped := false + for index in _ability_buttons: + var button: Button = _ability_buttons[index] + var ability: ActiveAbility = player.call("get_active_ability", index) + button.visible = ability != null + if ability == null: + continue + any_equipped = true + var reason: String = player.call("ability_unavailable_reason", index) + button.disabled = not reason.is_empty() + button.text = "[%d] %s" % [index + 1, ability.display_name] + button.tooltip_text = ability.description + ("\n" + reason if not reason.is_empty() else "\nGotowe") + _ability_bar.get_parent().visible = any_equipped diff --git a/scripts/game/game.gd b/scripts/game/game.gd index 3e16185..4b17213 100644 --- a/scripts/game/game.gd +++ b/scripts/game/game.gd @@ -1,9 +1,13 @@ extends Node2D -const WORLD_SIZE := Vector2(5200.0, 3600.0) -const ENEMY_COUNT := 20 -const SAFE_ZONE_RADIUS := 440.0 -const ENEMY_MIN_SEPARATION := 240.0 +const SYSTEM_GENERATOR := preload("res://scripts/levels/system_generator.gd") +const LEVEL_BALANCE := preload("res://scripts/levels/level_balance.gd") +const CELESTIAL_BODY := preload("res://scripts/levels/celestial_body.gd") +const SERVICES_MENU := preload("res://scenes/ui/planet_services_menu.tscn") +const PLANET_MARKER := preload("res://scripts/ui/protected_planet_marker.gd") +const WORLD_SIZE := SYSTEM_GENERATOR.WORLD_SIZE +const SERVICE_APPROACH_DISTANCE := 180.0 +const BOSS_TEXTURE := preload("res://assets/alien ship/Mega_boss.png") const ENEMY_SCENE := preload("res://scenes/game/enemy_ship.tscn") const ENEMY_TEXTURES: Array[Texture2D] = [ preload("res://assets/alien ship/Ship_1.png"), @@ -21,39 +25,124 @@ const ENEMY_TEXTURES: Array[Texture2D] = [ @onready var player: CharacterBody2D = $PlayerShip +var system_data: Dictionary = {} +var protected_planet: Node2D +var services_menu: Control +var system_cleared := false +var _services_dismissed := false +var _transitioning := false + func _ready() -> void: - # Keep the camera limits aligned with the test map if its size is tuned later. + GameState.system_level = clampi(GameState.system_level, 1, LEVEL_BALANCE.MAX_LEVEL) + if GameState.system_seed == 0: + GameState.system_seed = GameState.create_system_seed() + system_data = SYSTEM_GENERATOR.generate(GameState.system_level, GameState.system_seed) + player.position = system_data["player_start"] var camera := player.get_node_or_null("Camera2D") as Camera2D if camera: camera.limit_left = int(-WORLD_SIZE.x * 0.5) camera.limit_right = int(WORLD_SIZE.x * 0.5) camera.limit_top = int(-WORLD_SIZE.y * 0.5) camera.limit_bottom = int(WORLD_SIZE.y * 0.5) + _spawn_celestial_bodies() _spawn_enemies() + var marker := Control.new() + marker.set_script(PLANET_MARKER) + marker.name = "ProtectedPlanetMarker" + marker.mouse_filter = Control.MOUSE_FILTER_IGNORE + marker.set("game", self) + $HUD/HUDRoot.add_child(marker) + marker.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + services_menu = SERVICES_MENU.instantiate() as Control + $HUD/HUDRoot.add_child(services_menu) + services_menu.connect("next_level_requested", advance_to_next_level) + services_menu.connect("closed", _on_services_closed) + +func _spawn_celestial_bodies() -> void: + var bodies := Node2D.new() + bodies.name = "CelestialBodies" + bodies.z_index = -10 + add_child(bodies) + var star := Node2D.new() + star.set_script(CELESTIAL_BODY) + star.name = "CentralStar" + star.set("body_texture", system_data["star_texture"]) + star.set("radius", 140.0) + star.set("is_star", true) + bodies.add_child(star) + for index in system_data["planets"].size(): + var data: Dictionary = system_data["planets"][index] + var planet := Node2D.new() + planet.set_script(CELESTIAL_BODY) + planet.name = "Planet%d" % (index + 1) + planet.position = data["position"] + planet.set("body_texture", data["texture"]) + planet.set("radius", data["radius"]) + planet.set("is_protected", data["protected"]) + bodies.add_child(planet) + if data["protected"]: + protected_planet = planet func _spawn_enemies() -> void: - var rng := RandomNumberGenerator.new() - rng.randomize() - var spawn_positions: Array[Vector2] = [] - var attempts := 0 - while spawn_positions.size() < ENEMY_COUNT and attempts < 3000: - attempts += 1 - var candidate := Vector2( - rng.randf_range(-WORLD_SIZE.x * 0.5 + 130.0, WORLD_SIZE.x * 0.5 - 130.0), - rng.randf_range(-WORLD_SIZE.y * 0.5 + 130.0, WORLD_SIZE.y * 0.5 - 130.0) - ) - if candidate.length_squared() < SAFE_ZONE_RADIUS * SAFE_ZONE_RADIUS: - continue - var too_close := false - for other_position in spawn_positions: - if candidate.distance_squared_to(other_position) < ENEMY_MIN_SEPARATION * ENEMY_MIN_SEPARATION: - too_close = true - break - if not too_close: - spawn_positions.append(candidate) - - for spawn_position in spawn_positions: + for data in system_data["enemies"]: var enemy := ENEMY_SCENE.instantiate() as CharacterBody2D - enemy.position = spawn_position + enemy.position = data["position"] + enemy.call("apply_level_settings", GameState.system_level, int(data["tier"])) add_child(enemy) - enemy.call("configure", player, ENEMY_TEXTURES[rng.randi_range(0, ENEMY_TEXTURES.size() - 1)]) + var texture := BOSS_TEXTURE if int(data["tier"]) == 2 else ENEMY_TEXTURES[int(data["texture_index"])] + enemy.call("configure", player, texture) + +func get_remaining_enemies() -> int: + var remaining := 0 + for enemy in get_tree().get_nodes_in_group("enemies"): + if is_ancestor_of(enemy) and not enemy.is_queued_for_deletion() and float(enemy.get("hull")) > 0.0: + remaining += 1 + return remaining + +func _physics_process(_delta: float) -> void: + if _transitioning or bool(player.get("_is_destroyed")): + return + if not system_cleared and get_remaining_enemies() == 0: + system_cleared = true + protected_planet.call("set_safe", true) + var near_planet := is_near_protected_planet() + if not near_planet: + _services_dismissed = false + if system_cleared and near_planet and not _services_dismissed and not services_menu.visible: + player.velocity = Vector2.ZERO + player.set("angular_velocity", 0.0) + player.set("is_docked", true) + $HUD/HUDRoot/ShipInventoryPanel.hide() + services_menu.call("show_services", GameState.system_level >= LEVEL_BALANCE.MAX_LEVEL) + +func is_near_protected_planet() -> bool: + return player.global_position.distance_to(protected_planet.global_position) <= float(protected_planet.get("radius")) + SERVICE_APPROACH_DISTANCE + +func _on_services_closed() -> void: + player.set("is_docked", false) + _services_dismissed = true + +func advance_to_next_level() -> bool: + if _transitioning or not system_cleared or not services_menu.visible or not is_near_protected_planet(): + return false + if bool(player.get("_is_destroyed")) or GameState.system_level >= LEVEL_BALANCE.MAX_LEVEL: + return false + _transitioning = true + services_menu.get_node("Center/Panel/Contents/NextButton").set("disabled", true) + _load_next_level.call_deferred() + return true + +func _load_next_level() -> void: + var previous_level := GameState.system_level + var previous_seed := GameState.system_seed + player.get_node("ShipInventory").call("preserve_for_restart") + GameState.system_level += 1 + GameState.system_seed = GameState.create_system_seed() + var error := get_tree().reload_current_scene() + if error != OK: + GameState.system_level = previous_level + GameState.system_seed = previous_seed + GameState.restart_inventory.clear() + _transitioning = false + services_menu.call("show_services", false) + push_error("Could not enter next system: %s" % error_string(error)) diff --git a/scripts/game/game_state.gd b/scripts/game/game_state.gd index 3f5c6a4..5377972 100644 --- a/scripts/game/game_state.gd +++ b/scripts/game/game_state.gd @@ -1,8 +1,23 @@ extends Node +const CAPTAIN_PROGRESS := preload("res://scripts/captain/captain_progress.gd") +var captain: CaptainProgress = CAPTAIN_PROGRESS.new() + var selected_ship_path: String = "" var restart_inventory: Dictionary = {} var system_level: int = 1 +var system_seed: int = 0 + +func create_system_seed() -> int: + var rng := RandomNumberGenerator.new() + rng.randomize() + return maxi(1, rng.randi()) + +func start_new_run() -> void: + captain = CAPTAIN_PROGRESS.new() + system_level = 1 + system_seed = create_system_seed() + restart_inventory.clear() func _ready() -> void: var game_window := get_tree().root diff --git a/scripts/game/ship_controller.gd b/scripts/game/ship_controller.gd index 78807c3..36adcf3 100644 --- a/scripts/game/ship_controller.gd +++ b/scripts/game/ship_controller.gd @@ -2,6 +2,9 @@ extends CharacterBody2D const DEFAULT_SHIP_TEXTURE := "res://assets/Ships/Spaceship_0.png" const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn") +const DAMAGE_POPUP_SCENE := preload("res://scenes/game/damage_popup.tscn") +const COMBAT_ROLLS := preload("res://scripts/game/combat_rolls.gd") +const CAPTAIN_BALANCE := preload("res://scripts/captain/captain_balance.gd") @export var max_speed := 76.0 @export var reverse_max_speed := 210.0 @@ -17,7 +20,7 @@ const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn") @export var base_max_shields := 100.0 @export var base_max_energy := 100.0 @export var base_max_speed := 90.0 -@export var base_energy_regeneration := 12.0 +@export var base_energy_regeneration := 5.0 @export var base_shield_regeneration := 0.0 @export var max_hull := 100.0 @export var max_shields := 100.0 @@ -25,16 +28,23 @@ const IMPACT_EFFECT_SCENE := preload("res://scenes/game/impact_effect.tscn") var hull := 100.0 var shields := 100.0 var energy := 100.0 -var energy_regeneration := 12.0 +var energy_regeneration := 5.0 var shield_regeneration := 0.0 var damage_multiplier := 1.0 var experience_multiplier := 1.0 var credits_multiplier := 1.0 +var critical_chance_bonus := 0.0 +var critical_damage_bonus := 0.0 var angular_velocity := 0.0 var _sprite: Sprite2D var _contact_damage_timer := 0.0 var _is_destroyed := false +var is_docked := false +var _boost_speed := 0.0 +var _boost_target := 0.0 +var _boost_acceleration := 0.0 +var _boost_velocity_acceleration := 0.0 @onready var _shield_visual: Node2D = $ShieldVisual func apply_equipment_bonuses(bonuses: Dictionary) -> void: @@ -45,6 +55,8 @@ func apply_equipment_bonuses(bonuses: Dictionary) -> void: damage_multiplier = 1.0 + float(bonuses.get("damage_percent", 0.0)) / 100.0 experience_multiplier = 1.0 + float(bonuses.get("experience_percent", 0.0)) / 100.0 credits_multiplier = 1.0 + float(bonuses.get("credits_percent", 0.0)) / 100.0 + critical_chance_bonus = float(bonuses.get("critical_chance_percent", 0.0)) / 100.0 + critical_damage_bonus = float(bonuses.get("critical_damage_percent", 0.0)) / 100.0 energy_regeneration = base_energy_regeneration + float(bonuses.get("energy_regeneration", 0.0)) shield_regeneration = base_shield_regeneration + float(bonuses.get("shield_regeneration", 0.0)) reverse_max_speed = max_speed * 0.5 @@ -55,6 +67,8 @@ func apply_equipment_bonuses(bonuses: Dictionary) -> void: _update_shield_visual() func _ready() -> void: + for index in 6: + _ensure_input_action(StringName("ability_%d" % (index + 1)), (KEY_1 + index) as Key) _ensure_input_action(&"ship_thrust", KEY_W) _ensure_input_action(&"ship_brake", KEY_S) _ensure_input_action(&"ship_turn_left", KEY_A) @@ -87,9 +101,17 @@ func _ensure_input_action(action_name: StringName, physical_key: Key) -> void: InputMap.action_add_event(action_name, event) func take_damage(amount: float) -> void: - if _is_destroyed: + if _is_destroyed or is_docked or amount <= 0.0: return - var remaining_damage := maxf(0.0, amount) + var hit := COMBAT_ROLLS.incoming_hit(amount, get_evasion_chance(), get_damage_reduction()) + if hit["evaded"]: + var popup := DAMAGE_POPUP_SCENE.instantiate() as Label + popup.text = "UNIK" + popup.set("text_color", Color("77e8bc")) + popup.position = position + Vector2(-20, -38) + get_parent().add_child(popup) + return + var remaining_damage: float = hit["damage"] var shield_damage := minf(shields, remaining_damage) shields -= shield_damage remaining_damage -= shield_damage @@ -100,6 +122,24 @@ func take_damage(amount: float) -> void: if hull <= 0.0: _destroy_ship() +func get_evasion_chance() -> float: + return GameState.captain.get_skill_rank("piloting") / 100.0 + +func get_damage_reduction() -> float: + return GameState.captain.get_skill_rank("mechanic") / 100.0 + +func get_weapon_damage_multiplier() -> float: + return damage_multiplier * (1.0 + GameState.captain.get_skill_rank("gunner") / 100.0) + +func get_critical_chance() -> float: + return clampf(critical_chance_bonus + GameState.captain.get_skill_rank("sharp_eye") / 100.0, 0.0, 1.0) + +func get_critical_multiplier() -> float: + return CAPTAIN_BALANCE.BASE_CRITICAL_MULTIPLIER * (1.0 + maxf(0.0, critical_damage_bonus)) + +func roll_weapon_hit(item: ItemInstance) -> Dictionary: + return COMBAT_ROLLS.weapon_hit(item.roll_damage(), get_weapon_damage_multiplier(), get_critical_chance(), get_critical_multiplier()) + func register_enemy_collision(enemy_position: Vector2) -> void: if _is_destroyed or _contact_damage_timer > 0.0: return @@ -139,10 +179,20 @@ func _restart_level_after_destruction() -> void: get_tree().reload_current_scene() func _physics_process(delta: float) -> void: - if _is_destroyed: + if _is_destroyed or is_docked: return _contact_damage_timer = maxf(0.0, _contact_damage_timer - delta) energy = minf(max_energy, energy + energy_regeneration * delta) + var was_boosting := is_boosting() + if _boost_target > 0.0: + _boost_speed = move_toward(_boost_speed, _boost_target, _boost_acceleration * delta) + velocity = velocity.move_toward(Vector2.UP.rotated(rotation) * (max_speed + _boost_target), _boost_velocity_acceleration * delta) + if _boost_speed >= _boost_target: + _boost_target = 0.0 + else: + _boost_speed = move_toward(_boost_speed, 0.0, space_drag * delta) + if was_boosting: + velocity = velocity.move_toward(Vector2.ZERO, space_drag * delta) if shield_regeneration > 0.0 and shields < max_shields: var previous_shields := shields shields = minf(max_shields, shields + shield_regeneration * delta) @@ -172,7 +222,7 @@ func _physics_process(delta: float) -> void: elif Input.is_action_pressed("ship_thrust"): velocity += forward * thrust_acceleration * delta var forward_speed := velocity.dot(forward) - if forward_speed > max_speed: + if forward_speed > max_speed and not was_boosting: velocity += forward * (max_speed - forward_speed) var strafe_input := Input.get_axis("ship_strafe_left", "ship_strafe_right") @@ -183,6 +233,8 @@ func _physics_process(delta: float) -> void: velocity += right * (clampf(strafe_speed, -max_strafe_speed, max_strafe_speed) - strafe_speed) if ( + not was_boosting + and not Input.is_action_pressed("ship_brake") and not Input.is_action_pressed("ship_thrust") and is_zero_approx(strafe_input) @@ -196,9 +248,43 @@ func _physics_process(delta: float) -> void: func _clamp_velocity_to_max_speed() -> void: var speed_squared := velocity.length_squared() - var max_speed_squared := max_speed * max_speed + var allowed_speed := max_speed + _boost_speed + var max_speed_squared := allowed_speed * allowed_speed if speed_squared > max_speed_squared: - velocity = velocity.normalized() * max_speed + velocity = velocity.normalized() * allowed_speed + +func is_boosting() -> bool: + return _boost_target > 0.0 or _boost_speed > 0.0 + +func start_boost(speed_bonus: float, acceleration_time: float) -> void: + _boost_target = max_speed * maxf(0.0, speed_bonus) + _boost_acceleration = _boost_target / maxf(0.01, acceleration_time) + _boost_velocity_acceleration = (max_speed + _boost_target) / maxf(0.01, acceleration_time) + +func get_active_ability(slot_index: int) -> ActiveAbility: + var item: ItemInstance = $ShipInventory.get_item("module", slot_index) + return item.definition.active_ability if item != null and item.definition != null else null + +func ability_unavailable_reason(slot_index: int) -> String: + if _is_destroyed or is_docked: + return "Statek niedostępny" + var ability := get_active_ability(slot_index) + return ability.unavailable_reason(self) if ability != null else "Brak rozszerzenia" + +func activate_ability(slot_index: int) -> bool: + if not ability_unavailable_reason(slot_index).is_empty(): + return false + get_active_ability(slot_index).activate(self) + return true + +func _unhandled_key_input(event: InputEvent) -> void: + if event is InputEventKey and event.echo: + return + for index in 6: + if event.is_action_pressed("ability_%d" % (index + 1)): + activate_ability(index) + get_viewport().set_input_as_handled() + return func _check_enemy_collisions() -> void: for collision_index in get_slide_collision_count(): diff --git a/scripts/game/space_level_background.gd b/scripts/game/space_level_background.gd index 186cd94..f0b2507 100644 --- a/scripts/game/space_level_background.gd +++ b/scripts/game/space_level_background.gd @@ -1,88 +1,18 @@ extends Node2D const WORLD_SIZE := Vector2(5200.0, 3600.0) -const GRID_STEP := 320 func _draw() -> void: var half_size := WORLD_SIZE * 0.5 draw_rect(Rect2(-half_size, WORLD_SIZE), Color("050b18"), true) - _draw_grid(half_size) - _draw_stars(half_size) - _draw_landmarks() - _draw_world_border(half_size) - -func _draw_grid(half_size: Vector2) -> void: - for x in range(-2600, 2601, GRID_STEP): - var major := x % (GRID_STEP * 4) == 0 - var color := Color(0.16, 0.28, 0.42, 0.2 if major else 0.075) - draw_line(Vector2(x, -half_size.y), Vector2(x, half_size.y), color, 1.0) - for y in range(-1800, 1801, GRID_STEP): - var major := y % (GRID_STEP * 4) == 0 - var color := Color(0.16, 0.28, 0.42, 0.2 if major else 0.075) - draw_line(Vector2(-half_size.x, y), Vector2(half_size.x, y), color, 1.0) - -func _draw_stars(half_size: Vector2) -> void: var rng := RandomNumberGenerator.new() - rng.seed = 640_118 + rng.seed = GameState.system_seed for index in 420: var point := Vector2( rng.randf_range(-half_size.x + 35.0, half_size.x - 35.0), rng.randf_range(-half_size.y + 35.0, half_size.y - 35.0) ) var radius := rng.randf_range(0.7, 2.0) - var alpha := rng.randf_range(0.2, 0.72) - var color := Color(0.58, 0.76, 1.0, alpha) - if index % 9 == 0: - color = Color(0.35, 0.88, 0.94, alpha) + var color := Color(0.58, 0.76, 1.0, rng.randf_range(0.2, 0.72)) draw_circle(point, radius, color) - -func _draw_landmarks() -> void: - # Safe starting area around the spawn point. - draw_circle(Vector2.ZERO, 300.0, Color(0.08, 0.65, 0.72, 0.035)) - draw_arc(Vector2.ZERO, 300.0, 0.0, TAU, 96, Color(0.16, 0.78, 0.84, 0.32), 2.0) - _draw_label(Vector2(28, -316), "STREFA STARTOWA", Color(0.38, 0.81, 0.87, 0.78)) - - _draw_planet(Vector2(-1420, -760), 150.0, Color("e9904e"), "HELION") - _draw_planet(Vector2(1420, -940), 112.0, Color("397fa9"), "NEREIDA") - _draw_planet(Vector2(1110, 1170), 86.0, Color("8d6cbb"), "VESPER") - _draw_planet(Vector2(-1580, 1120), 72.0, Color("72a58b"), "TUBYLCY") - _draw_asteroid_field(Vector2(420, 160), 400.0, 34, 9_183) - _draw_asteroid_field(Vector2(-930, 460), 270.0, 22, 3_277) - _draw_navigation_beacon(Vector2(520, -190)) - -func _draw_navigation_beacon(center: Vector2) -> void: - draw_circle(center, 58.0, Color(0.1, 0.72, 0.86, 0.07)) - draw_arc(center, 44.0, 0.0, TAU, 64, Color(0.25, 0.82, 0.9, 0.75), 2.0) - draw_arc(center, 31.0, 0.0, TAU, 64, Color(0.25, 0.82, 0.9, 0.4), 1.0) - draw_line(center + Vector2(-54, 0), center + Vector2(54, 0), Color(0.25, 0.82, 0.9, 0.6), 1.0) - draw_line(center + Vector2(0, -54), center + Vector2(0, 54), Color(0.25, 0.82, 0.9, 0.6), 1.0) - draw_circle(center, 12.0, Color(0.35, 0.92, 1.0, 0.9)) - _draw_label(center + Vector2(-88, 78), "BOJA NAWIGACYJNA", Color(0.45, 0.83, 0.9, 0.82)) - -func _draw_planet(center: Vector2, radius: float, color: Color, label: String) -> void: - draw_circle(center, radius * 1.55, Color(color.r, color.g, color.b, 0.055)) - draw_arc(center, radius * 1.42, 0.0, TAU, 96, Color(color.r, color.g, color.b, 0.2), 2.0) - draw_circle(center, radius, color.darkened(0.48)) - draw_circle(center + Vector2(-radius * 0.22, -radius * 0.24), radius * 0.68, color.darkened(0.15)) - draw_arc(center, radius * 1.26, deg_to_rad(-18), deg_to_rad(205), 64, Color(0.64, 0.79, 0.91, 0.55), 5.0) - _draw_label(center + Vector2(-radius, radius + 34.0), label, Color(0.77, 0.85, 0.95, 0.76)) - -func _draw_asteroid_field(center: Vector2, spread: float, count: int, seed_value: int) -> void: - var rng := RandomNumberGenerator.new() - rng.seed = seed_value - for index in count: - var angle := rng.randf_range(0.0, TAU) - var distance := sqrt(rng.randf()) * spread - var point := center + Vector2.RIGHT.rotated(angle) * distance - var size := rng.randf_range(5.0, 15.0) - var color := Color(0.42, 0.53, 0.65, rng.randf_range(0.35, 0.75)) - draw_circle(point, size, color) - draw_circle(point + Vector2(-size * 0.25, -size * 0.25), size * 0.55, color.lightened(0.18)) - -func _draw_world_border(half_size: Vector2) -> void: - var bounds := Rect2(-half_size, WORLD_SIZE) - draw_rect(bounds, Color(0.12, 0.52, 0.68, 0.48), false, 3.0) - _draw_label(Vector2(-half_size.x + 22.0, -half_size.y + 38.0), "SEKTOR TESTOWY 01 / 5200 × 3600", Color(0.4, 0.7, 0.8, 0.7)) - -func _draw_label(position: Vector2, text: String, color: Color) -> void: - draw_string(ThemeDB.fallback_font, position, text, HORIZONTAL_ALIGNMENT_LEFT, -1.0, 18, color) + draw_rect(Rect2(-half_size, WORLD_SIZE), Color(0.12, 0.52, 0.68, 0.48), false, 3.0) \ No newline at end of file diff --git a/scripts/game/weapon_controller.gd b/scripts/game/weapon_controller.gd index 891f4a2..6cada2a 100644 --- a/scripts/game/weapon_controller.gd +++ b/scripts/game/weapon_controller.gd @@ -49,7 +49,7 @@ func _unhandled_input(event: InputEvent) -> void: _fire_just_pressed[slot_index] = true func _physics_process(delta: float) -> void: - if bool(ship.get("_is_destroyed")): + if bool(ship.get("_is_destroyed")) or bool(ship.get("is_docked")): for line in _laser_lines: line.visible = false return @@ -99,6 +99,7 @@ func _physics_process(delta: float) -> void: func _fire_projectile(item: ItemInstance) -> void: var definition := item.definition + var hit: Dictionary = ship.call("roll_weapon_hit", item) var muzzle_position := _muzzle_position() var direction := _aim_direction_from(muzzle_position) var projectile := PROJECTILE_SCENE.instantiate() @@ -108,8 +109,10 @@ func _fire_projectile(item: ItemInstance) -> void: direction, definition.weapon_kind, definition.projectile_speed, - item.roll_damage() * float(ship.get("damage_multiplier")), - definition.weapon_range + float(hit["damage"]), + definition.weapon_range, + null, + bool(hit["critical"]) ) ship.get_parent().add_child(projectile) WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), muzzle_position, definition.weapon_kind) @@ -140,7 +143,8 @@ func _fire_laser(slot_index: int, item: ItemInstance) -> void: return WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), muzzle_position, ItemDefinition.WeaponKind.LASER) if not result.is_empty(): - _apply_damage(result.get("collider"), item.roll_damage() * float(ship.get("damage_multiplier"))) + var hit: Dictionary = ship.call("roll_weapon_hit", item) + _apply_damage(result.get("collider"), float(hit["damage"]), bool(hit["critical"])) _spawn_laser_impact(endpoint) _laser_pulse_timers[slot_index] = definition.laser_pulse_duration _shot_timers[slot_index] = definition.fire_interval @@ -160,8 +164,10 @@ func _consume_energy(amount: float) -> bool: ship.set("energy", current_energy - amount) return true -func _apply_damage(target: Variant, damage: float) -> void: - if target is Node and target.has_method("take_damage"): +func _apply_damage(target: Variant, damage: float, critical: bool = false) -> void: + if target is Node and target.has_method("take_weapon_hit"): + target.call("take_weapon_hit", damage, critical) + elif target is Node and target.has_method("take_damage"): target.call("take_damage", damage) func _spawn_laser_impact(at_position: Vector2) -> void: diff --git a/scripts/game/weapon_projectile.gd b/scripts/game/weapon_projectile.gd index 978ceef..0ce365d 100644 --- a/scripts/game/weapon_projectile.gd +++ b/scripts/game/weapon_projectile.gd @@ -7,6 +7,7 @@ const PLASMA_VISUAL_WIDTH := 24.0 var direction := Vector2.UP var projectile_speed := 600.0 var damage := 1.0 +var is_critical := false var max_range := 800.0 var weapon_kind := ItemDefinition.WeaponKind.PLASMA var homing_target: Node2D @@ -40,7 +41,8 @@ func configure( speed: float, projectile_damage: float, projectile_range: float, - target: Node2D = null + target: Node2D = null, + critical_hit: bool = false ) -> void: global_position = start_position direction = travel_direction.normalized() @@ -50,6 +52,7 @@ func configure( _flight_velocity = direction * projectile_speed _launch_wobble_phase = randf_range(0.0, TAU) damage = projectile_damage + is_critical = critical_hit max_range = projectile_range homing_target = target @@ -253,5 +256,7 @@ func _apply_damage_once(target: Variant) -> void: if _already_hit.has(instance_id): return _already_hit[instance_id] = true - if target.has_method("take_damage"): + if target.has_method("take_weapon_hit"): + target.call("take_weapon_hit", damage, is_critical) + elif target.has_method("take_damage"): target.call("take_damage", damage) diff --git a/scripts/items/item_affix_definition.gd b/scripts/items/item_affix_definition.gd index ecacf18..a369a03 100644 --- a/scripts/items/item_affix_definition.gd +++ b/scripts/items/item_affix_definition.gd @@ -10,7 +10,7 @@ class_name ItemAffixDefinition @export_range(0.0, 1000.0, 0.1) var selection_weight: float = 1.0 @export_group("Dozwolone przedmioty") -@export_flags("Weapon", "Shield", "Hull", "Generator", "Extension") var category_mask: int = 31 +@export_flags("Weapon", "Shield", "Hull", "Generator", "Extension", "Active extension") var category_mask: int = 63 # Empty means every item in the allowed categories. @export var allowed_item_ids: PackedStringArray = PackedStringArray() @export var excluded_item_ids: PackedStringArray = PackedStringArray() diff --git a/scripts/items/item_definition.gd b/scripts/items/item_definition.gd index 437b5e0..9991a5f 100644 --- a/scripts/items/item_definition.gd +++ b/scripts/items/item_definition.gd @@ -1,7 +1,7 @@ extends Resource class_name ItemDefinition -enum Category { WEAPON, SHIELD, HULL, GENERATOR, EXTENSION } +enum Category { WEAPON, SHIELD, HULL, GENERATOR, EXTENSION, ACTIVE_EXTENSION } enum WeaponKind { PLASMA, MACHINE_GUN, LASER, MISSILE } @export var item_id: String = "" @@ -19,6 +19,7 @@ enum WeaponKind { PLASMA, MACHINE_GUN, LASER, MISSILE } @export var projectile_speed: float = 0.0 @export var weapon_range: float = 0.0 @export var energy_cost: float = 0.0 +@export var active_ability: ActiveAbility @export_group("Losowanie zakresu obrażeń broni (poziom 1)") @export_range(1, 10000) var damage_lower_roll_min: int = 1 diff --git a/scripts/items/item_generator.gd b/scripts/items/item_generator.gd index 0fe1cb4..bda1283 100644 --- a/scripts/items/item_generator.gd +++ b/scripts/items/item_generator.gd @@ -11,6 +11,9 @@ const DEFINITIONS := [ preload("res://resources/items/engine_extension.tres"), preload("res://resources/items/tuned_thrusters.tres"), preload("res://resources/items/shield_recharger.tres"), + preload("res://resources/items/afterburner.tres"), + preload("res://resources/items/shield_charge.tres"), + preload("res://resources/items/repair_drones.tres"), ] const AFFIX_DATABASE := preload("res://resources/items/affix_database.tres") diff --git a/scripts/items/item_instance.gd b/scripts/items/item_instance.gd index a410370..1f50295 100644 --- a/scripts/items/item_instance.gd +++ b/scripts/items/item_instance.gd @@ -69,6 +69,8 @@ func get_tooltip_text() -> String: var primary_text := "%s: +%.1f%s" % [stat_name(definition.primary_stat), get_stat_total(definition.primary_stat), definition.stat_suffix] if definition.category == ItemDefinition.Category.WEAPON: primary_text = "Obrażenia: %s" % get_damage_range_text() + elif definition.active_ability != null: + primary_text = definition.active_ability.description var lines: Array[String] = [definition.display_name, "%s • Poziom %d" % [get_rarity_name(), item_level], "", definition.description, "", "CECHA GŁÓWNA", primary_text] if definition.energy_regeneration_bonus > 0.0: lines.append("Regeneracja generatora: +%.1f /s" % (energy_regeneration_override if energy_regeneration_override >= 0.0 else definition.energy_regeneration_bonus)) @@ -85,4 +87,4 @@ func get_tooltip_text() -> String: return "\n".join(lines) static func stat_name(key: String) -> String: - return str({"damage": "Obrażenia", "max_hull": "Kadłub", "max_shields": "Tarcze", "max_energy": "Energia", "max_speed": "Prędkość", "energy_regeneration": "Regeneracja energii", "shield_regeneration": "Regeneracja tarcz", "hull_percent": "Kadłub", "shield_percent": "Tarcze", "damage_percent": "Obrażenia broni", "speed_percent": "Prędkość statku", "experience_percent": "Doświadczenie (EXP)", "credits_percent": "Kredyty"}.get(key, key)) + return str({"damage": "Obrażenia", "max_hull": "Kadłub", "max_shields": "Tarcze", "max_energy": "Energia", "max_speed": "Prędkość", "energy_regeneration": "Regeneracja energii", "shield_regeneration": "Regeneracja tarcz", "hull_percent": "Kadłub", "shield_percent": "Tarcze", "damage_percent": "Obrażenia broni", "speed_percent": "Prędkość statku", "experience_percent": "Doświadczenie (EXP)", "credits_percent": "Kredyty", "critical_chance_percent": "Szansa na trafienie krytyczne", "critical_damage_percent": "Obrażenia krytyczne"}.get(key, key)) diff --git a/scripts/items/ship_inventory.gd b/scripts/items/ship_inventory.gd index f48174c..8ca35a4 100644 --- a/scripts/items/ship_inventory.gd +++ b/scripts/items/ship_inventory.gd @@ -63,6 +63,8 @@ func delete_cargo_item(index: int) -> bool: if index < 0 or index >= cargo.size() or cargo[index] == null: return false cargo[index] = null + GameState.captain.parts += 10.0 + GameState.captain.emit_changed() inventory_changed.emit() return true @@ -115,7 +117,7 @@ func _recalculate_ship_stats() -> void: for item in weapon_slots + module_slots: if item == null or item.definition == null: continue - for stat_key in ["max_hull", "max_shields", "max_energy", "max_speed", "energy_regeneration", "shield_regeneration", "hull_percent", "shield_percent", "damage_percent", "speed_percent", "experience_percent", "credits_percent"]: + for stat_key in ["max_hull", "max_shields", "max_energy", "max_speed", "energy_regeneration", "shield_regeneration", "hull_percent", "shield_percent", "damage_percent", "speed_percent", "experience_percent", "credits_percent", "critical_chance_percent", "critical_damage_percent"]: bonuses[stat_key] = float(bonuses.get(stat_key, 0.0)) + item.get_stat_total(stat_key) ship.call("apply_equipment_bonuses", bonuses) @@ -131,6 +133,9 @@ func _add_starter_items() -> void: "res://resources/items/engine_extension.tres", "res://resources/items/tuned_thrusters.tres", "res://resources/items/shield_recharger.tres", + "res://resources/items/afterburner.tres", + "res://resources/items/shield_charge.tres", + "res://resources/items/repair_drones.tres", ] var cargo_index := 0 var weapon_index := 0 diff --git a/scripts/levels/celestial_body.gd b/scripts/levels/celestial_body.gd new file mode 100644 index 0000000..cc90494 --- /dev/null +++ b/scripts/levels/celestial_body.gd @@ -0,0 +1,46 @@ +extends Node2D + +var body_texture: Texture2D +var radius := 100.0 +var is_star := false +var is_protected := false +var is_safe := false +var _label: Label + +func _ready() -> void: + var sprite := Sprite2D.new() + sprite.texture = body_texture + sprite.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR + var longest_side := maxf(body_texture.get_width(), body_texture.get_height()) + sprite.scale = Vector2.ONE * (radius * 2.0 / longest_side) + add_child(sprite) + _label = Label.new() + _label.position = Vector2(-160, radius + 14) + _label.size = Vector2(320, 54) + _label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + _label.add_theme_font_size_override("font_size", 14) + _update_label() + +func set_safe(value: bool) -> void: + is_safe = value + if is_node_ready(): + _update_label() + queue_redraw() + +func _update_label() -> void: + if _label.get_parent() == null: + add_child(_label) + if is_star: + _label.text = "GWIAZDA CENTRALNA" + _label.add_theme_color_override("font_color", Color("ffdb98")) + elif is_protected: + _label.text = "PLANETA CHRONIONEJ RASY\n" + ("USŁUGI DOSTĘPNE" if is_safe else "POKONAJ WSZYSTKICH WROGÓW") + _label.add_theme_color_override("font_color", Color("77e8bc") if is_safe else Color("ffbd83")) + else: + _label.text = "PLANETA" + _label.add_theme_color_override("font_color", Color("9baec6")) + +func _draw() -> void: + if is_protected: + var color := Color("77e8bc") if is_safe else Color("ffbd83") + draw_arc(Vector2.ZERO, radius + 20.0, 0, TAU, 96, Color(color, 0.65), 2.0, true) diff --git a/scripts/levels/celestial_body.gd.uid b/scripts/levels/celestial_body.gd.uid new file mode 100644 index 0000000..1ed84f6 --- /dev/null +++ b/scripts/levels/celestial_body.gd.uid @@ -0,0 +1 @@ +uid://cf7tijssnmhj diff --git a/scripts/levels/level_balance.gd b/scripts/levels/level_balance.gd new file mode 100644 index 0000000..5f5d484 --- /dev/null +++ b/scripts/levels/level_balance.gd @@ -0,0 +1,45 @@ +extends RefCounted + +const MAX_LEVEL := 1000 +const COUNT_POINTS := [Vector2(1, 5), Vector2(10, 10), Vector2(50, 18), Vector2(100, 23), Vector2(250, 29), Vector2(500, 34), Vector2(1000, 40)] +# x = level, y = elite fraction, z = boss fraction. +const TIER_POINTS := [Vector3(10, 0, 0), Vector3(50, 0.15, 0), Vector3(100, 0.25, 0.05), Vector3(500, 0.45, 0.10), Vector3(1000, 0.55, 0.15)] + +static func enemy_count(level: int) -> int: + var clamped_level := clampi(level, 1, MAX_LEVEL) + for index in range(1, COUNT_POINTS.size()): + var before: Vector2 = COUNT_POINTS[index - 1] + var after: Vector2 = COUNT_POINTS[index] + if clamped_level <= after.x: + return roundi(lerpf(before.y, after.y, inverse_lerp(before.x, after.x, clamped_level))) + return 40 + +static func enemy_tiers(level: int) -> Array[int]: + var count := enemy_count(level) + var fractions := Vector2.ZERO + for index in range(1, TIER_POINTS.size()): + var before: Vector3 = TIER_POINTS[index - 1] + var after: Vector3 = TIER_POINTS[index] + if level <= after.x: + var progress := clampf(inverse_lerp(before.x, after.x, level), 0.0, 1.0) + fractions = Vector2(lerpf(before.y, after.y, progress), lerpf(before.z, after.z, progress)) + break + if level >= MAX_LEVEL: + fractions = Vector2(0.55, 0.15) + var bosses := roundi(count * fractions.y) + var elites := roundi(count * fractions.x) + if level >= 100: + bosses = maxi(1, bosses) + # Every boss begins a cluster with at least two elite escorts. + elites = mini(count - bosses, maxi(elites, bosses * 2)) + var tiers: Array[int] = [] + for boss in bosses: + tiers.append_array([2, 1, 1]) + for elite in elites - bosses * 2: + tiers.append(1) + for normal in count - bosses - elites: + tiers.append(0) + return tiers + +static func power_scale(level: int) -> float: + return 1.0 + 0.05 * (clampi(level, 1, MAX_LEVEL) - 1) diff --git a/scripts/levels/level_balance.gd.uid b/scripts/levels/level_balance.gd.uid new file mode 100644 index 0000000..7502032 --- /dev/null +++ b/scripts/levels/level_balance.gd.uid @@ -0,0 +1 @@ +uid://cvyjcm0qdjjy1 diff --git a/scripts/levels/system_generator.gd b/scripts/levels/system_generator.gd new file mode 100644 index 0000000..6f694ca --- /dev/null +++ b/scripts/levels/system_generator.gd @@ -0,0 +1,113 @@ +extends RefCounted + +const BALANCE := preload("res://scripts/levels/level_balance.gd") +const WORLD_SIZE := Vector2(5200, 3600) +const PLAYER_START := Vector2(180, 200) +const SAFE_ZONE_RADIUS := 1200.0 +const ENEMY_MIN_SEPARATION := 110.0 +const STAR_TEXTURES: Array[Texture2D] = [ + preload("res://assets/stars/s1.png"), + preload("res://assets/stars/s2.png"), + preload("res://assets/stars/s3.png"), + preload("res://assets/stars/s4.png"), + preload("res://assets/stars/s5.png"), + preload("res://assets/stars/s6.png"), + preload("res://assets/stars/s7.png"), + preload("res://assets/stars/s8.png"), +] +const PLANET_TEXTURES: Array[Texture2D] = [ + preload("res://assets/planets/p1.png"), + preload("res://assets/planets/p2.png"), + preload("res://assets/planets/p3.png"), + preload("res://assets/planets/p4.png"), + preload("res://assets/planets/p5.png"), + preload("res://assets/planets/p6.png"), + preload("res://assets/planets/p7.png"), + preload("res://assets/planets/p8.png"), + preload("res://assets/planets/p9.png"), + preload("res://assets/planets/p10.png"), + preload("res://assets/planets/p11.png"), + preload("res://assets/planets/p12.png"), + preload("res://assets/planets/p13.png"), + preload("res://assets/planets/p14.png"), + preload("res://assets/planets/p15.png"), + preload("res://assets/planets/p16.png"), + preload("res://assets/planets/p17.png"), + preload("res://assets/planets/p18.png"), +] + +static func generate(level: int, seed_value: int) -> Dictionary: + var rng := RandomNumberGenerator.new() + rng.seed = seed_value + var star_texture := STAR_TEXTURES[rng.randi_range(0, STAR_TEXTURES.size() - 1)] + var planet_count := rng.randi_range(1, 5) + var protected_index := rng.randi_range(0, planet_count - 1) + var angle_offset := rng.randf_range(0.0, TAU) + var planets: Array[Dictionary] = [] + for index in planet_count: + var angle := angle_offset + TAU * index / planet_count + rng.randf_range(-0.12, 0.12) + var orbit := 1000.0 + 110.0 * index + rng.randf_range(-40.0, 40.0) + planets.append({ + "position": Vector2.RIGHT.rotated(angle) * orbit, + "radius": rng.randf_range(70.0, 105.0), + "texture": PLANET_TEXTURES[rng.randi_range(0, PLANET_TEXTURES.size() - 1)], + "protected": index == protected_index, + }) + var enemies: Array[Dictionary] = [] + var tiers := BALANCE.enemy_tiers(level) + var cursor := 0 + while cursor < tiers.size(): + var cluster_size := 3 if tiers[cursor] == 2 else rng.randi_range(2, 5) + cluster_size = mini(cluster_size, tiers.size() - cursor) + var planet: Dictionary = planets[rng.randi_range(0, planets.size() - 1)] + var anchor: Vector2 = planet["position"] + anchor += anchor.normalized() * rng.randf_range(250.0, 450.0) + for member in cluster_size: + var position := _find_enemy_position(anchor, planets, enemies, rng) + enemies.append({ + "position": position, + "tier": tiers[cursor], + "texture_index": rng.randi_range(0, 10), + }) + cursor += 1 + return { + "star_texture": star_texture, + "star_position": Vector2.ZERO, + "player_start": PLAYER_START, + "planets": planets, + "protected_index": protected_index, + "enemies": enemies, + } + +static func _find_enemy_position(anchor: Vector2, planets: Array[Dictionary], enemies: Array[Dictionary], rng: RandomNumberGenerator) -> Vector2: + for attempt in 3000: + var candidate: Vector2 + if attempt < 500: + candidate = anchor + Vector2.RIGHT.rotated(rng.randf_range(0, TAU)) * rng.randf_range(130, 420) + else: + candidate = Vector2(rng.randf_range(-2380, 2380), rng.randf_range(-1580, 1580)) + if _is_valid_enemy_position(candidate, planets, enemies): + return candidate + # Deterministic fallback for crowded clusters, still respecting the safe area. + for x in range(-2280, 2281, 130): + for y in range(-1500, 1501, 130): + var candidate := Vector2(x, y) + if _is_valid_enemy_position(candidate, planets, enemies): + return candidate + push_error("Could not place an enemy outside the safe zone.") + return Vector2(2380, 1580) + +static func _is_valid_enemy_position(candidate: Vector2, planets: Array[Dictionary], enemies: Array[Dictionary]) -> bool: + if absf(candidate.x) > 2380 or absf(candidate.y) > 1580: + return false + if candidate.length() < SAFE_ZONE_RADIUS or candidate.distance_to(PLAYER_START) < 940.0: + return false + for planet in planets: + var center: Vector2 = planet["position"] + if candidate.distance_to(center) < float(planet["radius"]) + 75.0: + return false + for enemy in enemies: + var center: Vector2 = enemy["position"] + if candidate.distance_to(center) < ENEMY_MIN_SEPARATION: + return false + return true diff --git a/scripts/levels/system_generator.gd.uid b/scripts/levels/system_generator.gd.uid new file mode 100644 index 0000000..6877244 --- /dev/null +++ b/scripts/levels/system_generator.gd.uid @@ -0,0 +1 @@ +uid://c1guubx4ymk2c diff --git a/scripts/ui/captain_panel.gd b/scripts/ui/captain_panel.gd new file mode 100644 index 0000000..8447dd0 --- /dev/null +++ b/scripts/ui/captain_panel.gd @@ -0,0 +1,72 @@ +extends PanelContainer + +const BALANCE := preload("res://scripts/captain/captain_balance.gd") + +@onready var player: CharacterBody2D = get_node("../../../PlayerShip") +@onready var level_label: Label = $Contents/Header/Level +@onready var xp_label: Label = $Contents/XPLabel +@onready var xp_bar: ProgressBar = $Contents/XPBar +@onready var credits_label: Label = $Contents/Wallet/Credits +@onready var points_label: Label = $Contents/Wallet/Points +@onready var critical_label: Label = $Contents/Critical + +var _captain: CaptainProgress +var _rank_labels: Dictionary = {} +var _effect_labels: Dictionary = {} +var _buttons: Dictionary = {} + +func _ready() -> void: + _captain = GameState.captain + for skill in BALANCE.SKILL_NAMES: + var row := HBoxContainer.new() + row.name = skill + row.add_theme_constant_override("separation", 5) + var title := Label.new() + title.text = BALANCE.SKILL_NAMES[skill] + title.tooltip_text = BALANCE.SKILL_HELP[skill] + title.size_flags_horizontal = Control.SIZE_EXPAND_FILL + title.add_theme_font_size_override("font_size", 11) + row.add_child(title) + var rank := Label.new() + rank.custom_minimum_size.x = 22 + rank.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT + rank.add_theme_font_size_override("font_size", 11) + row.add_child(rank) + _rank_labels[skill] = rank + var effect := Label.new() + effect.custom_minimum_size.x = 58 + effect.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT + effect.add_theme_font_size_override("font_size", 10) + row.add_child(effect) + _effect_labels[skill] = effect + var button := Button.new() + button.name = "Train_" + skill + button.text = "+" + button.custom_minimum_size = Vector2(24, 22) + button.add_theme_font_size_override("font_size", 13) + button.tooltip_text = "Rozwiń umiejętność za 1 punkt nauki.\n" + BALANCE.SKILL_HELP[skill] + button.pressed.connect(_train.bind(skill)) + row.add_child(button) + _buttons[skill] = button + $Contents/Skills.add_child(row) + _captain.changed.connect(_refresh) + player.get_node("ShipInventory").connect("inventory_changed", _refresh) + _refresh() + +func _train(skill: String) -> void: + _captain.train_skill(skill) + +func _refresh() -> void: + level_label.text = "POZ. %d" % _captain.level + xp_label.text = "XP %d / %d" % [_captain.experience, _captain.get_xp_required()] + xp_bar.max_value = _captain.get_xp_required() + xp_bar.value = _captain.experience + credits_label.text = "Kredyty: %d" % _captain.credits + points_label.text = "Punkty: %d" % _captain.learning_points + for skill in _buttons: + var rank := _captain.get_skill_rank(skill) + _rank_labels[skill].text = str(rank) + var suffix: String = {"piloting": "unik", "gunner": "DMG", "mechanic": "redukcji", "sharp_eye": "kryt"}[skill] + _effect_labels[skill].text = "%d%% %s" % [rank, suffix] + _buttons[skill].disabled = not _captain.can_train(skill) + critical_label.text = "Krytyk: %.1f%% · ×%.2f\nCzęści: %.1f" % [float(player.call("get_critical_chance")) * 100.0, float(player.call("get_critical_multiplier")), _captain.parts] diff --git a/scripts/ui/captain_panel.gd.uid b/scripts/ui/captain_panel.gd.uid new file mode 100644 index 0000000..d0846d3 --- /dev/null +++ b/scripts/ui/captain_panel.gd.uid @@ -0,0 +1 @@ +uid://nkf6tqs8w4ss diff --git a/scripts/ui/equipment_slot_view.gd b/scripts/ui/equipment_slot_view.gd index 101e5d8..0024e31 100644 --- a/scripts/ui/equipment_slot_view.gd +++ b/scripts/ui/equipment_slot_view.gd @@ -15,7 +15,7 @@ func _ready() -> void: add_child(overlay) _delete_button = Button.new() _delete_button.text = "×" - _delete_button.tooltip_text = "Usuń przedmiot z magazynu" + _delete_button.tooltip_text = "Rozłóż przedmiot: +10 części" _delete_button.flat = true _delete_button.add_theme_font_size_override("font_size", 13) _delete_button.add_theme_color_override("font_color", Color("ff8989")) @@ -33,9 +33,9 @@ func _ready() -> void: "weapon": custom_minimum_size = Vector2(90, 38) "module": - custom_minimum_size = Vector2(72, 44) + custom_minimum_size = Vector2(104, 36) _: - custom_minimum_size = Vector2(72, 48) + custom_minimum_size = Vector2(84, 40) _refresh() func _refresh() -> void: @@ -136,6 +136,8 @@ func _category_name(category: int) -> String: return "GENERATOR" ItemDefinition.Category.EXTENSION: return "ROZSZERZENIE" + ItemDefinition.Category.ACTIVE_EXTENSION: + return "ROZSZERZENIE AKTYWNE" return "PRZEDMIOT" func _stat_text(item: ItemInstance) -> String: diff --git a/scripts/ui/planet_services_menu.gd b/scripts/ui/planet_services_menu.gd new file mode 100644 index 0000000..5a047f3 --- /dev/null +++ b/scripts/ui/planet_services_menu.gd @@ -0,0 +1,25 @@ +extends Control + +signal next_level_requested +signal closed + +@onready var next_button: Button = $Center/Panel/Contents/NextButton +@onready var close_button: Button = $Center/Panel/Contents/CloseButton + +func _ready() -> void: + next_button.pressed.connect(func() -> void: next_level_requested.emit()) + close_button.pressed.connect(_close) + +func show_services(at_level_cap: bool) -> void: + next_button.disabled = at_level_cap + next_button.text = "OSIĄGNIĘTO OSTATNI UKŁAD" if at_level_cap else "PRZEJDŹ DO NASTĘPNEGO UKŁADU" + show() + +func _close() -> void: + hide() + closed.emit() + +func _unhandled_key_input(event: InputEvent) -> void: + if visible and event.is_action_pressed("ui_cancel"): + _close() + get_viewport().set_input_as_handled() diff --git a/scripts/ui/planet_services_menu.gd.uid b/scripts/ui/planet_services_menu.gd.uid new file mode 100644 index 0000000..82764db --- /dev/null +++ b/scripts/ui/planet_services_menu.gd.uid @@ -0,0 +1 @@ +uid://cj8jrdwo55pmy diff --git a/scripts/ui/protected_planet_marker.gd b/scripts/ui/protected_planet_marker.gd new file mode 100644 index 0000000..d5332cd --- /dev/null +++ b/scripts/ui/protected_planet_marker.gd @@ -0,0 +1,26 @@ +extends Control + +var game: Node2D + +func _process(_delta: float) -> void: + queue_redraw() + +func _draw() -> void: + if not is_instance_valid(game) or not is_instance_valid(game.get("protected_planet")): + return + var planet: Node2D = game.get("protected_planet") + var screen_position := get_viewport().get_canvas_transform() * planet.global_position + # Leave the bottom strip free for active extension buttons. + var bounds := Rect2(Vector2(32, 56), Vector2(maxf(100.0, size.x - 320.0), maxf(100.0, size.y - 160.0))) + if bounds.has_point(screen_position): + return + var center := bounds.get_center() + var direction := (screen_position - center).normalized() + var half_size := bounds.size * 0.5 + var distance := minf(half_size.x / maxf(absf(direction.x), 0.001), half_size.y / maxf(absf(direction.y), 0.001)) + var point := center + direction * distance + var side := Vector2(-direction.y, direction.x) + var color := Color("77e8bc") if bool(game.get("system_cleared")) else Color("ffbd83") + draw_colored_polygon(PackedVector2Array([point + direction * 10, point - direction * 7 + side * 7, point - direction * 7 - side * 7]), color) + var label_position := Vector2(clampf(point.x - 45, 8, size.x - 120), clampf(point.y + 25, 20, size.y - 12)) + draw_string(ThemeDB.fallback_font, label_position, "Planeta rasy", HORIZONTAL_ALIGNMENT_LEFT, -1, 12, color) diff --git a/scripts/ui/protected_planet_marker.gd.uid b/scripts/ui/protected_planet_marker.gd.uid new file mode 100644 index 0000000..0fd92d8 --- /dev/null +++ b/scripts/ui/protected_planet_marker.gd.uid @@ -0,0 +1 @@ +uid://dmagteipidq0 diff --git a/scripts/ui/ship_inventory_panel.gd b/scripts/ui/ship_inventory_panel.gd index ea594ef..9a09245 100644 --- a/scripts/ui/ship_inventory_panel.gd +++ b/scripts/ui/ship_inventory_panel.gd @@ -14,6 +14,7 @@ func _ready() -> void: _inventory = get_tree().get_first_node_in_group("ship_inventory") as ShipInventory if _inventory: _inventory.inventory_changed.connect(_refresh_title) + GameState.captain.changed.connect(_refresh_title) for index in CARGO_SIZE: var slot := SLOT_SCENE.instantiate() slot.set("slot_kind", "cargo") @@ -23,4 +24,4 @@ func _ready() -> void: func _refresh_title() -> void: if _inventory: - title_label.text = "MAGAZYN (%d / %d)" % [_inventory.get_cargo_used(), CARGO_SIZE] + title_label.text = "MAGAZYN (%d/%d) · Części: %.1f" % [_inventory.get_cargo_used(), CARGO_SIZE, GameState.captain.parts] diff --git a/scripts/ui/ship_schematic.gd b/scripts/ui/ship_schematic.gd index af749ef..b8a74cb 100644 --- a/scripts/ui/ship_schematic.gd +++ b/scripts/ui/ship_schematic.gd @@ -1,8 +1,9 @@ extends Control func _draw() -> void: - var center := size.x * 0.5 - draw_set_transform(Vector2(center * 0.28, 0.0), 0.0, Vector2(0.72, 0.72)) + var center := 0.0 + var diagram_scale := minf(size.y / 140.0, size.x / 140.0) + draw_set_transform(Vector2(size.x * 0.5, 0.0), 0.0, Vector2.ONE * diagram_scale) var hull_color := Color(0.35, 0.72, 0.85, 1.0) var hull_highlight := Color(0.72, 0.9, 0.96, 1.0) var weapon_color := Color(0.98, 0.65, 0.28, 1.0) diff --git a/scripts/ui/ship_selection.gd b/scripts/ui/ship_selection.gd index b1996d4..c6b401f 100644 --- a/scripts/ui/ship_selection.gd +++ b/scripts/ui/ship_selection.gd @@ -61,4 +61,5 @@ func _select_ship(ship_path: String, ship_number: int, button: Button) -> void: continue_button.disabled = false func _start_game() -> void: + GameState.start_new_run() get_tree().change_scene_to_file(GAME_SCENE) diff --git a/tests/abilities/active_abilities_test.gd b/tests/abilities/active_abilities_test.gd new file mode 100644 index 0000000..539c42b --- /dev/null +++ b/tests/abilities/active_abilities_test.gd @@ -0,0 +1,96 @@ +extends Node + +const GAME := preload("res://scenes/game/game.tscn") +const GENERATOR := preload("res://scripts/items/item_generator.gd") + +func equip(inventory: ShipInventory, id: String, slot: int) -> void: + for index in inventory.cargo.size(): + var item := inventory.cargo[index] + if item != null and item.definition.item_id == id: + assert(inventory.move_item("cargo", index, "module", slot)) + return + assert(false, "Starter extension missing: " + id) + +func _ready() -> void: + GameState.start_new_run() + var game := GAME.instantiate() + add_child(game) + await get_tree().process_frame + var ship: CharacterBody2D = game.get_node("PlayerShip") + ship.set_physics_process(false) + var inventory: ShipInventory = ship.get_node("ShipInventory") + equip(inventory, "afterburner", 0) + equip(inventory, "shield_charge", 1) + equip(inventory, "repair_drones", 5) + assert(ship.call("get_active_ability", 2) == null) + assert(not ship.call("activate_ability", 2)) + ship.set("energy", ship.get("max_energy") - 0.01) + assert(not ship.call("activate_ability", 0)) + assert(not ship.call("activate_ability", 1)) + ship.set("energy", ship.get("max_energy")) + assert(not ship.call("activate_ability", 1)) # Full shields: no wasted energy. + ship.set("shields", ship.get("max_shields") - 30.0) + assert(ship.call("activate_ability", 1)) + assert(ship.get("shields") == ship.get("max_shields") and ship.get("energy") == 0.0) + ship.set("shields", 0.0) + ship.set("energy", ship.get("max_energy")) + assert(ship.call("activate_ability", 1)) + assert(ship.get("shields") == minf(100.0, ship.get("max_shields"))) + assert(not inventory.delete_cargo_item(-1)) + assert(GameState.captain.parts == 0.0) + assert(inventory.delete_cargo_item(0)) + assert(not inventory.delete_cargo_item(0)) + assert(GameState.captain.parts == 10.0) + ship.set("hull", ship.get("max_hull") - 4.25) + ship.set("energy", 0.0) + assert(ship.call("activate_ability", 5)) + assert(ship.get("hull") == ship.get("max_hull")) + assert(is_equal_approx(GameState.captain.parts, 5.75) and ship.get("energy") == 0.0) + assert(not ship.call("activate_ability", 5)) + ship.set("hull", ship.get("max_hull") - 20.0) + assert(ship.call("activate_ability", 5)) + assert(GameState.captain.parts == 0.0) + assert(not ship.call("activate_ability", 5)) + ship.set("energy", ship.get("max_energy")) + ship.velocity = Vector2.ZERO + var key := InputEventKey.new() + key.physical_keycode = KEY_1 + key.pressed = true + ship.call("_unhandled_key_input", key) + assert(ship.get("energy") == 0.0 and ship.call("is_boosting")) + assert(not ship.call("activate_ability", 0)) + ship.call("_physics_process", 0.1) + var first_speed := ship.velocity.length() + assert(first_speed > 0.0 and first_speed < ship.get("max_speed") * 3.0) + ship.call("_physics_process", 0.1) + ship.call("_physics_process", 0.1) + assert(is_equal_approx(ship.velocity.length(), ship.get("max_speed") * 3.0)) + ship.call("_physics_process", 0.1) + assert(ship.velocity.length() < ship.get("max_speed") * 3.0 and ship.velocity.length() > ship.get("max_speed")) + for frame in 300: + ship.call("_physics_process", 0.1) + assert(not ship.call("is_boosting")) + ship.set("is_docked", true) + ship.set("energy", ship.get("max_energy")) + assert(not ship.call("activate_ability", 0)) + ship.set("is_docked", false) + var item := inventory.get_item("module", 0) + assert(inventory.move_item("module", 0, "cargo", 0)) + assert(ship.call("get_active_ability", 0) == null) + assert(inventory.move_item("cargo", 0, "module", 3)) + assert(ship.call("get_active_ability", 3) == item.definition.active_ability) + for definition in GENERATOR.DEFINITIONS: + if definition.category == ItemDefinition.Category.ACTIVE_EXTENSION: + var loot := GENERATOR.generate_for_definition(definition, 100) + assert(loot.definition.active_ability != null and not loot.additional_modifiers.is_empty()) + GameState.captain.parts = 17.5 + inventory.preserve_for_restart() + game.queue_free() + await get_tree().process_frame + var restarted := GAME.instantiate() + add_child(restarted) + await get_tree().process_frame + assert(GameState.captain.parts == 17.5) + assert(restarted.get_node("PlayerShip/ShipInventory").get_item("module", 3) == item) + assert(not restarted.get_node("PlayerShip").call("is_boosting")) + print("ACTIVE_ABILITIES_TEST: PASS — costs, hotkeys, boost ramp/decay, salvage, repairs, equipment, loot, restart") diff --git a/tests/abilities/active_abilities_test.gd.uid b/tests/abilities/active_abilities_test.gd.uid new file mode 100644 index 0000000..c8b54d3 --- /dev/null +++ b/tests/abilities/active_abilities_test.gd.uid @@ -0,0 +1 @@ +uid://d4jqfgeom2jcp diff --git a/tests/abilities/active_abilities_test.tscn b/tests/abilities/active_abilities_test.tscn new file mode 100644 index 0000000..2974cbb --- /dev/null +++ b/tests/abilities/active_abilities_test.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3] + +[ext_resource type="Script" path="res://tests/abilities/active_abilities_test.gd" id="1"] + +[node name="ActiveAbilitiesTest" type="Node"] +script = ExtResource("1") diff --git a/tests/captain/captain_system_test.gd b/tests/captain/captain_system_test.gd new file mode 100644 index 0000000..5840a2b --- /dev/null +++ b/tests/captain/captain_system_test.gd @@ -0,0 +1,136 @@ +extends Node + +const PROGRESS := preload("res://scripts/captain/captain_progress.gd") +const COMBAT := preload("res://scripts/game/combat_rolls.gd") +const GAME_SCENE := preload("res://scenes/game/game.tscn") +const GENERATOR := preload("res://scripts/items/item_generator.gd") +const PROJECTILE := preload("res://scenes/game/weapon_projectile.tscn") + +class DamageReceiver: + extends Node2D + var hits: Array[Dictionary] = [] + func take_weapon_hit(amount: float, critical: bool) -> void: + hits.append({"damage": amount, "critical": critical}) + +func _ready() -> void: + var profile := PROGRESS.new() + assert(not profile.train_skill("gunner")) + profile.add_rewards(99, 60) + assert(profile.level == 1 and profile.experience == 99) + profile.add_rewards(1, 15) + assert(profile.level == 2 and profile.experience == 0 and profile.learning_points == 1 and profile.credits == 75) + assert(profile.train_skill("gunner") and profile.get_skill_rank("gunner") == 1) + assert(not profile.train_skill("piloting") and not profile.train_skill("unknown")) + profile.add_rewards(450, 0) + assert(profile.level == 4 and profile.experience == 100 and profile.learning_points == 2) + profile.skills["piloting"] = 100 + assert(not profile.train_skill("piloting")) + assert(profile.reward_enemy(10, 2, 1.25, 1.5) == Vector2i(272, 261)) + var hit := COMBAT.weapon_hit(10, 1.1, 0, 2, 0) + assert(not hit["critical"] and is_equal_approx(hit["damage"], 11)) + hit = COMBAT.weapon_hit(10, 1.1, 1, 2.4, 1) + assert(hit["critical"] and is_equal_approx(hit["damage"], 26.4)) + assert(not COMBAT.weapon_hit(10, 1, 0.01, 2, 0.01)["critical"]) + assert(COMBAT.incoming_hit(100, 1, 0, 1)["evaded"]) + assert(is_equal_approx(COMBAT.incoming_hit(100, 0.01, 0.5, 0.01)["damage"], 50)) + assert(COMBAT.incoming_hit(100, 0, 1, 0)["damage"] == 0) + assert(COMBAT.incoming_hit(-100, 0, 0, 0)["damage"] == 0) + + GameState.start_new_run() + var game := GAME_SCENE.instantiate() as Node2D + get_tree().root.call_deferred("add_child", game) + await get_tree().process_frame + await get_tree().process_frame + get_tree().current_scene = game + _freeze(game) + profile = GameState.captain + var enemies := get_tree().get_nodes_in_group("enemies") + for enemy in enemies: + enemy.call("take_weapon_hit", 1000000.0, true) + enemy.call("take_damage", 1000000.0) + assert(profile.level == 2 and profile.experience == 0 and profile.learning_points == 1) + assert(profile.credits == 75) + var panel := game.get_node("HUD/HUDRoot/CaptainPanel") + panel.get_node("Contents/Skills/gunner/Train_gunner").emit_signal("pressed") + assert(profile.get_skill_rank("gunner") == 1 and profile.learning_points == 0) + panel.get_node("Contents/Skills/piloting/Train_piloting").emit_signal("pressed") + assert(profile.get_skill_rank("piloting") == 0) + assert(panel.get_node("Contents/Header/Level").get("text") == "POZ. 2") + var player := game.get_node("PlayerShip") as CharacterBody2D + profile.skills["piloting"] = 100 + var before := Vector2(float(player.get("hull")), float(player.get("shields"))) + player.call("take_damage", 1000.0) + assert(before == Vector2(float(player.get("hull")), float(player.get("shields")))) + profile.skills["piloting"] = 0 + profile.skills["mechanic"] = 50 + player.call("take_damage", 100.0) + assert(float(player.get("shields")) == 50 and float(player.get("hull")) == 100) + player.set("shields", 0.0) + player.call("take_damage", 40.0) + assert(float(player.get("hull")) == 80) + profile.skills["mechanic"] = 100 + player.call("take_damage", 1000000.0) + assert(float(player.get("hull")) == 80) + profile.skills["mechanic"] = 0 + profile.skills["sharp_eye"] = 1 + var inventory := player.get_node("ShipInventory") as ShipInventory + var weapon := GENERATOR.generate_for_definition(preload("res://resources/items/plasma_cannon.tres"), 1) + weapon.additional_modifiers.clear() + weapon.damage_min = 10 + weapon.damage_max = 10 + for data in [["critical_chance_percent", 25.0], ["critical_damage_percent", 20.0], ["damage_percent", 10.0], ["experience_percent", 25.0], ["credits_percent", 50.0]]: + var modifier := ItemStatModifier.new() + modifier.stat_key = data[0] + modifier.value = data[1] + weapon.additional_modifiers.append(modifier) + var free_slot := inventory.cargo.find(null) + assert(inventory.add_item(weapon) and inventory.move_item("cargo", free_slot, "weapon", 0)) + assert(is_equal_approx(float(player.call("get_critical_chance")), 0.26)) + assert(is_equal_approx(float(player.call("get_critical_multiplier")), 2.4)) + assert(is_equal_approx(float(player.call("get_weapon_damage_multiplier")), 1.111)) + profile.skills["sharp_eye"] = 100 + hit = player.call("roll_weapon_hit", weapon) + assert(hit["critical"] and is_equal_approx(hit["damage"], 26.664)) + var receiver := DamageReceiver.new() + game.add_child(receiver) + var projectile := PROJECTILE.instantiate() + projectile.call("configure", Vector2.ZERO, Vector2.RIGHT, ItemDefinition.WeaponKind.MISSILE, 400.0, 26.664, 1000.0, null, true) + game.add_child(projectile) + projectile.set_physics_process(false) + projectile.call("_apply_damage_once", receiver) + projectile.call("_apply_damage_once", receiver) + assert(receiver.hits.size() == 1 and receiver.hits[0]["critical"]) + assert(is_equal_approx(receiver.hits[0]["damage"], 26.664)) + player.call("take_damage", 1000000.0) + await get_tree().create_timer(1.3).timeout + game = get_tree().current_scene as Node2D + _freeze(game) + assert(GameState.captain == profile and profile.level == 2 and profile.credits == 75) + player = game.get_node("PlayerShip") as CharacterBody2D + assert(player.get_node("ShipInventory").call("get_item", "weapon", 0) == weapon) + for enemy in get_tree().get_nodes_in_group("enemies"): + enemy.call("take_damage", 1000000.0) + assert(profile.experience == 125 and profile.credits == 190) + var planet: Node2D = game.get("protected_planet") + player.position = planet.position + game.call("_physics_process", 0.0) + assert(bool(game.call("advance_to_next_level"))) + await get_tree().process_frame + await get_tree().process_frame + await get_tree().process_frame + game = get_tree().current_scene as Node2D + _freeze(game) + assert(GameState.captain == profile and GameState.system_level == 2) + assert(profile.get_skill_rank("gunner") == 1 and profile.get_skill_rank("sharp_eye") == 100) + var enemy := get_tree().get_nodes_in_group("enemies")[0] as CharacterBody2D + enemy.call("take_damage", 1000000.0) + assert(profile.level == 3 and profile.experience == 1 and profile.credits == 214) + print("CAPTAIN_SYSTEM_TEST: PASS (XP, multiple levels, learning UI, rewards once, dodge, reduction, critical addons, projectile metadata, death and next system)") + +func _freeze(game: Node2D) -> void: + game.set_physics_process(false) + game.get_node("PlayerShip").set_physics_process(false) + game.get_node("PlayerShip/WeaponController").set_physics_process(false) + for enemy in get_tree().get_nodes_in_group("enemies"): + if game.is_ancestor_of(enemy): + enemy.set_physics_process(false) diff --git a/tests/captain/captain_system_test.gd.uid b/tests/captain/captain_system_test.gd.uid new file mode 100644 index 0000000..5a612a5 --- /dev/null +++ b/tests/captain/captain_system_test.gd.uid @@ -0,0 +1 @@ +uid://df23vyxa26ymc diff --git a/tests/captain/captain_system_test.tscn b/tests/captain/captain_system_test.tscn new file mode 100644 index 0000000..c938376 --- /dev/null +++ b/tests/captain/captain_system_test.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3] + +[ext_resource type="Script" path="res://tests/captain/captain_system_test.gd" id="1_test"] + +[node name="CaptainSystemTest" type="Node"] +script = ExtResource("1_test") diff --git a/tests/items/affix_database_test.gd b/tests/items/affix_database_test.gd index 35d2748..7bc1918 100644 --- a/tests/items/affix_database_test.gd +++ b/tests/items/affix_database_test.gd @@ -4,7 +4,7 @@ const GENERATOR := preload("res://scripts/items/item_generator.gd") const DATABASE := preload("res://resources/items/affix_database.tres") func _ready() -> void: - assert(DATABASE.affixes.size() == 8) + assert(DATABASE.affixes.size() == 10) for level in [1, 50, 1000]: for tier in [0, 1, 2]: for sample in 50: diff --git a/tests/items/weapon_damage_test.gd b/tests/items/weapon_damage_test.gd index ead2e36..5185b69 100644 --- a/tests/items/weapon_damage_test.gd +++ b/tests/items/weapon_damage_test.gd @@ -9,7 +9,7 @@ class LaserProbe: var hits: Array[float] = [] func _aim_direction_from(_origin: Vector2) -> Vector2: return Vector2.RIGHT - func _apply_damage(_target: Variant, damage: float) -> void: + func _apply_damage(_target: Variant, damage: float, _critical: bool = false) -> void: hits.append(damage) func _ready() -> void: diff --git a/tests/levels/system_generation_test.gd b/tests/levels/system_generation_test.gd new file mode 100644 index 0000000..f476698 --- /dev/null +++ b/tests/levels/system_generation_test.gd @@ -0,0 +1,49 @@ +extends Node + +const GENERATOR := preload("res://scripts/levels/system_generator.gd") +const BALANCE := preload("res://scripts/levels/level_balance.gd") + +func _ready() -> void: + for point in BALANCE.COUNT_POINTS: + assert(BALANCE.enemy_count(int(point.x)) == int(point.y)) + var previous_count := 0 + for level in range(1, 1001): + var count := BALANCE.enemy_count(level) + assert(count >= previous_count and count <= 40) + assert(BALANCE.enemy_tiers(level).size() == count) + previous_count = count + var observed_counts: Dictionary = {} + for level in [1, 10, 50, 100, 250, 500, 1000]: + for seed_value in range(1, 61): + var data := GENERATOR.generate(level, seed_value) + assert(data == GENERATOR.generate(level, seed_value)) + assert(data["star_position"] == Vector2.ZERO) + assert(data["player_start"].distance_to(Vector2.ZERO) <= 300.0) + var planets: Array[Dictionary] = data["planets"] + assert(planets.size() >= 1 and planets.size() <= 5) + observed_counts[planets.size()] = true + var protected_count := 0 + for planet in planets: + if planet["protected"]: + protected_count += 1 + var position: Vector2 = planet["position"] + assert(position.length() > 900) + assert(absf(position.x) + float(planet["radius"]) < 2580) + assert(absf(position.y) + float(planet["radius"]) < 1780) + assert(protected_count == 1) + assert(planets[data["protected_index"]]["protected"]) + var enemies: Array[Dictionary] = data["enemies"] + assert(enemies.size() == BALANCE.enemy_count(level)) + for index in enemies.size(): + var position: Vector2 = enemies[index]["position"] + assert(position.length() >= GENERATOR.SAFE_ZONE_RADIUS) + assert(position.distance_to(data["player_start"]) >= 940.0) + assert(absf(position.x) <= 2380 and absf(position.y) <= 1580) + for other_index in range(index + 1, enemies.size()): + assert(position.distance_to(enemies[other_index]["position"]) >= GENERATOR.ENEMY_MIN_SEPARATION) + if level <= 10: + assert(enemies[index]["tier"] == 0) + if enemies[index]["tier"] == 2: + assert(enemies[index + 1]["tier"] == 1 and enemies[index + 2]["tier"] == 1) + assert(observed_counts.size() == 5) + print("SYSTEM_GENERATION_TEST: PASS (420 layouts, deterministic retries, planets, safe spawn and level balance 1–1000)") diff --git a/tests/levels/system_generation_test.gd.uid b/tests/levels/system_generation_test.gd.uid new file mode 100644 index 0000000..35ddb5b --- /dev/null +++ b/tests/levels/system_generation_test.gd.uid @@ -0,0 +1 @@ +uid://dcat3dskon61c diff --git a/tests/levels/system_generation_test.tscn b/tests/levels/system_generation_test.tscn new file mode 100644 index 0000000..21d2f27 --- /dev/null +++ b/tests/levels/system_generation_test.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3] + +[ext_resource type="Script" path="res://tests/levels/system_generation_test.gd" id="1_test"] + +[node name="SystemGenerationTest" type="Node"] +script = ExtResource("1_test") diff --git a/tests/levels/system_lifecycle_test.gd b/tests/levels/system_lifecycle_test.gd new file mode 100644 index 0000000..af18569 --- /dev/null +++ b/tests/levels/system_lifecycle_test.gd @@ -0,0 +1,131 @@ +extends Node + +const GAME_SCENE := preload("res://scenes/game/game.tscn") +const ITEM_GENERATOR := preload("res://scripts/items/item_generator.gd") + +func _ready() -> void: + GameState.start_new_run() + GameState.system_seed = 314159 + var game := GAME_SCENE.instantiate() as Node2D + get_tree().root.call_deferred("add_child", game) + await get_tree().process_frame + await get_tree().process_frame + get_tree().current_scene = game + _freeze(game) + assert(GameState.system_level == 1 and int(game.call("get_remaining_enemies")) == 5) + assert(not game.has_node("WeaponTestTarget")) + assert(game.get_node("CelestialBodies").get_child_count() >= 2) + var player := game.get_node("PlayerShip") as CharacterBody2D + var inventory := player.get_node("ShipInventory") as ShipInventory + var weapon := ITEM_GENERATOR.generate_for_definition(preload("res://resources/items/beam_laser.tres"), 1) + weapon.damage_min = 1 + weapon.damage_max = 5 + var free_slot := inventory.cargo.find(null) + assert(inventory.add_item(weapon)) + assert(inventory.move_item("cargo", free_slot, "weapon", 0)) + assert(inventory.move_item("cargo", 2, "module", 0)) + var equipped_module := inventory.get_item("module", 0) + var tooltip := weapon.get_tooltip_text() + var initial_data: Dictionary = game.get("system_data") + var initial_seed := GameState.system_seed + var planet: Node2D = game.get("protected_planet") + player.position = planet.position + game.call("_physics_process", 0.0) + var menu: Control = game.get("services_menu") + assert(not menu.visible and not bool(game.call("advance_to_next_level"))) + _clear_enemies(game) + game.call("_physics_process", 0.0) + assert(menu.visible and bool(player.get("is_docked"))) + assert(bool(game.get("system_cleared")) and bool(planet.get("is_safe"))) + var previous_hull := float(player.get("hull")) + player.call("take_damage", 100000.0) + assert(float(player.get("hull")) == previous_hull) + menu.call("_close") + game.call("_physics_process", 0.0) + assert(not menu.visible and not bool(player.get("is_docked"))) + player.position = initial_data["player_start"] + game.call("_physics_process", 0.0) + player.position = planet.position + game.call("_physics_process", 0.0) + assert(menu.visible) + menu.call("_close") + player.position = initial_data["player_start"] + player.call("take_damage", 100000.0) + await get_tree().create_timer(1.3).timeout + game = get_tree().current_scene as Node2D + _freeze(game) + player = game.get_node("PlayerShip") as CharacterBody2D + inventory = player.get_node("ShipInventory") as ShipInventory + assert(GameState.system_level == 1 and GameState.system_seed == initial_seed) + assert(game.get("system_data") == initial_data) + assert(int(game.call("get_remaining_enemies")) == 5) + assert(inventory.get_item("weapon", 0) == weapon) + assert(inventory.get_item("module", 0) == equipped_module) + assert(weapon.get_tooltip_text() == tooltip) + _assert_full_resources(player) + _clear_enemies(game) + planet = game.get("protected_planet") + player.position = planet.position + game.call("_physics_process", 0.0) + assert(bool(game.call("advance_to_next_level"))) + assert(not bool(game.call("advance_to_next_level"))) + await get_tree().process_frame + await get_tree().process_frame + await get_tree().process_frame + game = get_tree().current_scene as Node2D + _freeze(game) + player = game.get_node("PlayerShip") as CharacterBody2D + inventory = player.get_node("ShipInventory") as ShipInventory + assert(GameState.system_level == 2 and GameState.system_seed != initial_seed) + assert(game.get("system_data") != initial_data) + assert(inventory.get_item("weapon", 0) == weapon and inventory.get_item("module", 0) == equipped_module) + assert(weapon.get_tooltip_text() == tooltip) + _assert_full_resources(player) + var enemy := get_tree().get_nodes_in_group("enemies")[0] as CharacterBody2D + enemy.call("apply_level_settings", 2, 2) + assert(float(enemy.get("max_hull")) > 300.0) + enemy.call("take_damage", 100000.0) + await get_tree().process_frame + await get_tree().process_frame + var found_level_two_loot := false + for loot in get_tree().get_nodes_in_group("loot"): + if game.is_ancestor_of(loot): + assert(int(loot.get("item").get("item_level")) == 2) + found_level_two_loot = true + assert(found_level_two_loot) + inventory.preserve_for_restart() + GameState.system_level = 1000 + assert(get_tree().reload_current_scene() == OK) + await get_tree().process_frame + await get_tree().process_frame + await get_tree().process_frame + game = get_tree().current_scene as Node2D + _freeze(game) + assert(int(game.call("get_remaining_enemies")) == 40) + _clear_enemies(game) + player = game.get_node("PlayerShip") as CharacterBody2D + planet = game.get("protected_planet") + player.position = planet.position + game.call("_physics_process", 0.0) + menu = game.get("services_menu") + assert(menu.visible) + assert(bool(menu.get_node("Center/Panel/Contents/NextButton").get("disabled"))) + assert(not bool(game.call("advance_to_next_level"))) + print("SYSTEM_LIFECYCLE_TEST: PASS (locked services, docking, retry, inventory preservation, next level, scaled loot and level cap)") + +func _freeze(game: Node2D) -> void: + game.set_physics_process(false) + game.get_node("PlayerShip").set_physics_process(false) + game.get_node("PlayerShip/WeaponController").set_physics_process(false) + for enemy in get_tree().get_nodes_in_group("enemies"): + if game.is_ancestor_of(enemy): + enemy.set_physics_process(false) + +func _clear_enemies(game: Node2D) -> void: + for enemy in get_tree().get_nodes_in_group("enemies"): + if game.is_ancestor_of(enemy): + enemy.call("take_damage", 100000.0) + +func _assert_full_resources(player: CharacterBody2D) -> void: + for resource in ["hull", "shields", "energy"]: + assert(is_equal_approx(float(player.get(resource)), float(player.get("max_" + resource)))) diff --git a/tests/levels/system_lifecycle_test.gd.uid b/tests/levels/system_lifecycle_test.gd.uid new file mode 100644 index 0000000..e1546bd --- /dev/null +++ b/tests/levels/system_lifecycle_test.gd.uid @@ -0,0 +1 @@ +uid://ffuq4nmpvr33 diff --git a/tests/levels/system_lifecycle_test.tscn b/tests/levels/system_lifecycle_test.tscn new file mode 100644 index 0000000..2fecf88 --- /dev/null +++ b/tests/levels/system_lifecycle_test.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3] + +[ext_resource type="Script" path="res://tests/levels/system_lifecycle_test.gd" id="1_test"] + +[node name="SystemLifecycleTest" type="Node"] +script = ExtResource("1_test")