diff --git a/godot_ship/.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.md5 b/godot_ship/.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.md5 index 65f245f..f5e763d 100644 --- a/godot_ship/.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.md5 +++ b/godot_ship/.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.md5 @@ -1,3 +1,3 @@ source_md5="a88d669f1f058a347cc4de2244bac64b" -dest_md5="1073062c6e594eff250036d7489d44a7" +dest_md5="1ed8fab74f35d40e257776b2eab84c5f" diff --git a/godot_ship/.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.stex b/godot_ship/.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.stex index 1ea8a2a..502efb5 100644 Binary files a/godot_ship/.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.stex and b/godot_ship/.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.stex differ diff --git a/godot_ship/.import/HitMissAtlas.png-47e352b9aa0deb2bd08f554355b13c14.md5 b/godot_ship/.import/HitMissAtlas.png-47e352b9aa0deb2bd08f554355b13c14.md5 new file mode 100644 index 0000000..1dfc95e --- /dev/null +++ b/godot_ship/.import/HitMissAtlas.png-47e352b9aa0deb2bd08f554355b13c14.md5 @@ -0,0 +1,3 @@ +source_md5="e860aab5fa3b6ce9c5831b3624861eb0" +dest_md5="a265f8881bf649748bb86076a1059462" + diff --git a/godot_ship/.import/HitMissAtlas.png-47e352b9aa0deb2bd08f554355b13c14.stex b/godot_ship/.import/HitMissAtlas.png-47e352b9aa0deb2bd08f554355b13c14.stex new file mode 100644 index 0000000..55bfb08 Binary files /dev/null and b/godot_ship/.import/HitMissAtlas.png-47e352b9aa0deb2bd08f554355b13c14.stex differ diff --git a/godot_ship/.import/Icon128.png-8fa6a445b29adcafaf69c45a7d758b76.md5 b/godot_ship/.import/Icon128.png-8fa6a445b29adcafaf69c45a7d758b76.md5 new file mode 100644 index 0000000..af8612f --- /dev/null +++ b/godot_ship/.import/Icon128.png-8fa6a445b29adcafaf69c45a7d758b76.md5 @@ -0,0 +1,3 @@ +source_md5="f1043053126af1a739ae9a6d20541705" +dest_md5="33d90f901d38e94006bc94b2bafbcc7f" + diff --git a/godot_ship/.import/Icon128.png-8fa6a445b29adcafaf69c45a7d758b76.stex b/godot_ship/.import/Icon128.png-8fa6a445b29adcafaf69c45a7d758b76.stex new file mode 100644 index 0000000..5ff27bd Binary files /dev/null and b/godot_ship/.import/Icon128.png-8fa6a445b29adcafaf69c45a7d758b76.stex differ diff --git a/godot_ship/.import/Icon16.png-e916d7bb27530c71f994d2d2cacbe08b.md5 b/godot_ship/.import/Icon16.png-e916d7bb27530c71f994d2d2cacbe08b.md5 new file mode 100644 index 0000000..7591b93 --- /dev/null +++ b/godot_ship/.import/Icon16.png-e916d7bb27530c71f994d2d2cacbe08b.md5 @@ -0,0 +1,3 @@ +source_md5="e5510033f1a1421d95771be4d1f17c06" +dest_md5="acfea8b7761d165a201dbc0a0af2c167" + diff --git a/godot_ship/.import/Icon16.png-e916d7bb27530c71f994d2d2cacbe08b.stex b/godot_ship/.import/Icon16.png-e916d7bb27530c71f994d2d2cacbe08b.stex new file mode 100644 index 0000000..1811209 Binary files /dev/null and b/godot_ship/.import/Icon16.png-e916d7bb27530c71f994d2d2cacbe08b.stex differ diff --git a/godot_ship/.import/Icon256.png-5fcf1bd6fb6791cb3c432c7c88dff8da.md5 b/godot_ship/.import/Icon256.png-5fcf1bd6fb6791cb3c432c7c88dff8da.md5 new file mode 100644 index 0000000..87e41aa --- /dev/null +++ b/godot_ship/.import/Icon256.png-5fcf1bd6fb6791cb3c432c7c88dff8da.md5 @@ -0,0 +1,3 @@ +source_md5="236f053c1af2cb6dc8fb21dd8c49fee6" +dest_md5="e8811c15e8ebcd4a71c62994dc9c6d5a" + diff --git a/godot_ship/.import/Icon256.png-5fcf1bd6fb6791cb3c432c7c88dff8da.stex b/godot_ship/.import/Icon256.png-5fcf1bd6fb6791cb3c432c7c88dff8da.stex new file mode 100644 index 0000000..ce2db60 Binary files /dev/null and b/godot_ship/.import/Icon256.png-5fcf1bd6fb6791cb3c432c7c88dff8da.stex differ diff --git a/godot_ship/.import/Icon32.png-ba330b5438b784e541f4d4c7ff1165f1.md5 b/godot_ship/.import/Icon32.png-ba330b5438b784e541f4d4c7ff1165f1.md5 new file mode 100644 index 0000000..1e48c63 --- /dev/null +++ b/godot_ship/.import/Icon32.png-ba330b5438b784e541f4d4c7ff1165f1.md5 @@ -0,0 +1,3 @@ +source_md5="dc5c89239ead115c7989cdbee213c307" +dest_md5="d26cc3c5d8c5165d3f5afb242806bdb4" + diff --git a/godot_ship/.import/Icon32.png-ba330b5438b784e541f4d4c7ff1165f1.stex b/godot_ship/.import/Icon32.png-ba330b5438b784e541f4d4c7ff1165f1.stex new file mode 100644 index 0000000..c38240f Binary files /dev/null and b/godot_ship/.import/Icon32.png-ba330b5438b784e541f4d4c7ff1165f1.stex differ diff --git a/godot_ship/.import/Icon64.png-688550eb2085ba14f76a5ffeb3504d87.md5 b/godot_ship/.import/Icon64.png-688550eb2085ba14f76a5ffeb3504d87.md5 new file mode 100644 index 0000000..804c2ab --- /dev/null +++ b/godot_ship/.import/Icon64.png-688550eb2085ba14f76a5ffeb3504d87.md5 @@ -0,0 +1,3 @@ +source_md5="d743da5448801d5a71eb2caff679e6ff" +dest_md5="5d974b679ce52f358bf54f29b7a68669" + diff --git a/godot_ship/.import/Icon64.png-688550eb2085ba14f76a5ffeb3504d87.stex b/godot_ship/.import/Icon64.png-688550eb2085ba14f76a5ffeb3504d87.stex new file mode 100644 index 0000000..9906f38 Binary files /dev/null and b/godot_ship/.import/Icon64.png-688550eb2085ba14f76a5ffeb3504d87.stex differ diff --git a/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.md5 b/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.md5 new file mode 100644 index 0000000..18e3cff --- /dev/null +++ b/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.md5 @@ -0,0 +1,3 @@ +source_md5="136899ff4c68986c4cc62e296277b8ab" +dest_md5="3d16ccd1874686296ee01de7097a3a6f" + diff --git a/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex b/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex new file mode 100644 index 0000000..4362eb9 Binary files /dev/null and b/godot_ship/.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex differ diff --git a/godot_ship/.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.md5 b/godot_ship/.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.md5 new file mode 100644 index 0000000..c8a4281 --- /dev/null +++ b/godot_ship/.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.md5 @@ -0,0 +1,3 @@ +source_md5="8a6c98eec519fd0b594b073b527e6e96" +dest_md5="c9201153f0494a1eb4f9e353a0aafe9f" + diff --git a/godot_ship/.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.stex b/godot_ship/.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.stex new file mode 100644 index 0000000..bb956c8 Binary files /dev/null and b/godot_ship/.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.stex differ diff --git a/godot_ship/.import/TextureAtlas.png-f8378824db0f2b64b8339984d33f1a41.md5 b/godot_ship/.import/TextureAtlas.png-f8378824db0f2b64b8339984d33f1a41.md5 new file mode 100644 index 0000000..7d23ae6 --- /dev/null +++ b/godot_ship/.import/TextureAtlas.png-f8378824db0f2b64b8339984d33f1a41.md5 @@ -0,0 +1,3 @@ +source_md5="4608512057ad7b079766b3ddf107024a" +dest_md5="8f5996bd2322644767582317aefaf44d" + diff --git a/godot_ship/.import/TextureAtlas.png-f8378824db0f2b64b8339984d33f1a41.stex b/godot_ship/.import/TextureAtlas.png-f8378824db0f2b64b8339984d33f1a41.stex new file mode 100644 index 0000000..3b242eb Binary files /dev/null and b/godot_ship/.import/TextureAtlas.png-f8378824db0f2b64b8339984d33f1a41.stex differ diff --git a/godot_ship/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 b/godot_ship/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 index 7b61c3e..87e41aa 100644 --- a/godot_ship/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 +++ b/godot_ship/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5 @@ -1,3 +1,3 @@ -source_md5="47313fa4c47a9963fddd764e1ec6e4a8" -dest_md5="2ded9e7f9060e2b530aab678b135fc5b" +source_md5="236f053c1af2cb6dc8fb21dd8c49fee6" +dest_md5="e8811c15e8ebcd4a71c62994dc9c6d5a" diff --git a/godot_ship/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex b/godot_ship/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex index 3ca6461..ce2db60 100644 Binary files a/godot_ship/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex and b/godot_ship/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex differ diff --git a/godot_ship/.import/splash_image.png-6121c2cee560834f4965fe53dd93125b.md5 b/godot_ship/.import/splash_image.png-6121c2cee560834f4965fe53dd93125b.md5 new file mode 100644 index 0000000..b6747b4 --- /dev/null +++ b/godot_ship/.import/splash_image.png-6121c2cee560834f4965fe53dd93125b.md5 @@ -0,0 +1,3 @@ +source_md5="005f64fb1ff8de71218d3545cc20441c" +dest_md5="dcee8e0391b5bffbc76299f1b93a1100" + diff --git a/godot_ship/.import/splash_image.png-6121c2cee560834f4965fe53dd93125b.stex b/godot_ship/.import/splash_image.png-6121c2cee560834f4965fe53dd93125b.stex new file mode 100644 index 0000000..a57c1c5 Binary files /dev/null and b/godot_ship/.import/splash_image.png-6121c2cee560834f4965fe53dd93125b.stex differ diff --git a/godot_ship/.import/splash_image.png-f3ec9b087a00e67c0fd1d6f7f949a801.md5 b/godot_ship/.import/splash_image.png-f3ec9b087a00e67c0fd1d6f7f949a801.md5 new file mode 100644 index 0000000..636eb23 --- /dev/null +++ b/godot_ship/.import/splash_image.png-f3ec9b087a00e67c0fd1d6f7f949a801.md5 @@ -0,0 +1,3 @@ +source_md5="a177b00b79bd7412a6b0c6aa07f5020b" +dest_md5="2bf8d94b2316e0d5b19647de6827b854" + diff --git a/godot_ship/.import/splash_image.png-f3ec9b087a00e67c0fd1d6f7f949a801.stex b/godot_ship/.import/splash_image.png-f3ec9b087a00e67c0fd1d6f7f949a801.stex new file mode 100644 index 0000000..194760a Binary files /dev/null and b/godot_ship/.import/splash_image.png-f3ec9b087a00e67c0fd1d6f7f949a801.stex differ diff --git a/godot_ship/assets/backgrounds/Background_Dark.png.import b/godot_ship/assets/backgrounds/Background_Dark.png.import index d8ce35a..3cdedd7 100644 --- a/godot_ship/assets/backgrounds/Background_Dark.png.import +++ b/godot_ship/assets/backgrounds/Background_Dark.png.import @@ -20,7 +20,7 @@ compress/hdr_mode=0 compress/bptc_ldr=0 compress/normal_map=0 flags/repeat=0 -flags/filter=true +flags/filter=false flags/mipmaps=false flags/anisotropic=false flags/srgb=2 @@ -30,5 +30,5 @@ process/HDR_as_SRGB=false process/invert_color=false stream=false size_limit=0 -detect_3d=true +detect_3d=false svg/scale=1.0 diff --git a/godot_ship/assets/backgrounds/PanelBG_Dark.png b/godot_ship/assets/backgrounds/PanelBG_Dark.png new file mode 100644 index 0000000..dc4ad96 Binary files /dev/null and b/godot_ship/assets/backgrounds/PanelBG_Dark.png differ diff --git a/godot_ship/assets/backgrounds/PanelBG_Dark.png.import b/godot_ship/assets/backgrounds/PanelBG_Dark.png.import new file mode 100644 index 0000000..0921b1b --- /dev/null +++ b/godot_ship/assets/backgrounds/PanelBG_Dark.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/backgrounds/PanelBG_Dark.png" +dest_files=[ "res://.import/PanelBG_Dark.png-664d38fd54271fbacb81205517c40701.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/godot_ship/assets/backgrounds/PanelBG_Dark.tres b/godot_ship/assets/backgrounds/PanelBG_Dark.tres new file mode 100644 index 0000000..1e6ac82 --- /dev/null +++ b/godot_ship/assets/backgrounds/PanelBG_Dark.tres @@ -0,0 +1,12 @@ +[gd_resource type="StyleBoxTexture" load_steps=2 format=2] + +[ext_resource path="res://assets/backgrounds/PanelBG_Dark.png" type="Texture" id=1] + +[resource] +texture = ExtResource( 1 ) +region_rect = Rect2( 0, 0, 32, 32 ) +margin_left = 6.0 +margin_right = 6.0 +margin_top = 6.0 +margin_bottom = 6.0 +axis_stretch_horizontal = 1 diff --git a/godot_ship/assets/backgrounds/PanelBG_Light.png b/godot_ship/assets/backgrounds/PanelBG_Light.png new file mode 100644 index 0000000..318b484 Binary files /dev/null and b/godot_ship/assets/backgrounds/PanelBG_Light.png differ diff --git a/godot_ship/assets/backgrounds/PanelBG_Light.png.import b/godot_ship/assets/backgrounds/PanelBG_Light.png.import new file mode 100644 index 0000000..35d34d1 --- /dev/null +++ b/godot_ship/assets/backgrounds/PanelBG_Light.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/backgrounds/PanelBG_Light.png" +dest_files=[ "res://.import/PanelBG_Light.png-25b7c30a8a8b20ed722b3b35c8a79d7b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/godot_ship/assets/backgrounds/PanelBG_Light.tres b/godot_ship/assets/backgrounds/PanelBG_Light.tres new file mode 100644 index 0000000..89f2eb8 --- /dev/null +++ b/godot_ship/assets/backgrounds/PanelBG_Light.tres @@ -0,0 +1,11 @@ +[gd_resource type="StyleBoxTexture" load_steps=2 format=2] + +[ext_resource path="res://assets/backgrounds/PanelBG_Light.png" type="Texture" id=1] + +[resource] +texture = ExtResource( 1 ) +region_rect = Rect2( 0, 0, 32, 32 ) +margin_left = 6.0 +margin_right = 6.0 +margin_top = 6.0 +margin_bottom = 7.0 diff --git a/godot_ship/assets/backgrounds/splash_image.png b/godot_ship/assets/backgrounds/splash_image.png new file mode 100644 index 0000000..613424d Binary files /dev/null and b/godot_ship/assets/backgrounds/splash_image.png differ diff --git a/godot_ship/assets/backgrounds/splash_image.png.import b/godot_ship/assets/backgrounds/splash_image.png.import new file mode 100644 index 0000000..2015646 --- /dev/null +++ b/godot_ship/assets/backgrounds/splash_image.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/splash_image.png-6121c2cee560834f4965fe53dd93125b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/backgrounds/splash_image.png" +dest_files=[ "res://.import/splash_image.png-6121c2cee560834f4965fe53dd93125b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/godot_ship/assets/game/HitMissAtlas.png b/godot_ship/assets/game/HitMissAtlas.png new file mode 100644 index 0000000..c81acad Binary files /dev/null and b/godot_ship/assets/game/HitMissAtlas.png differ diff --git a/godot_ship/assets/game/HitMissAtlas.png.import b/godot_ship/assets/game/HitMissAtlas.png.import new file mode 100644 index 0000000..171103e --- /dev/null +++ b/godot_ship/assets/game/HitMissAtlas.png.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="StreamTexture" +<<<<<<< HEAD:godot_ship/assets/backgrounds/Background_Dark.png.import +path="res://.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.stex" +======= +path="res://.import/HitMissAtlas.png-47e352b9aa0deb2bd08f554355b13c14.stex" +>>>>>>> game-logic:godot_ship/assets/game/HitMissAtlas.png.import +metadata={ +"vram_texture": false +} + +[deps] + +<<<<<<< HEAD:godot_ship/assets/backgrounds/Background_Dark.png.import +source_file="res://assets/backgrounds/Background_Dark.png" +dest_files=[ "res://.import/Background_Dark.png-f04f9416ce96aca35dfd0f16063b0d5b.stex" ] +======= +source_file="res://assets/game/HitMissAtlas.png" +dest_files=[ "res://.import/HitMissAtlas.png-47e352b9aa0deb2bd08f554355b13c14.stex" ] +>>>>>>> game-logic:godot_ship/assets/game/HitMissAtlas.png.import + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/godot_ship/assets/game/TextureAtlas.png b/godot_ship/assets/game/TextureAtlas.png new file mode 100644 index 0000000..8427746 Binary files /dev/null and b/godot_ship/assets/game/TextureAtlas.png differ diff --git a/godot_ship/assets/game/TextureAtlas.png.import b/godot_ship/assets/game/TextureAtlas.png.import new file mode 100644 index 0000000..60101a4 --- /dev/null +++ b/godot_ship/assets/game/TextureAtlas.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/TextureAtlas.png-f8378824db0f2b64b8339984d33f1a41.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/game/TextureAtlas.png" +dest_files=[ "res://.import/TextureAtlas.png-f8378824db0f2b64b8339984d33f1a41.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/godot_ship/assets/icons/Icon128.png b/godot_ship/assets/icons/Icon128.png new file mode 100644 index 0000000..cc91751 Binary files /dev/null and b/godot_ship/assets/icons/Icon128.png differ diff --git a/godot_ship/assets/icons/Icon128.png.import b/godot_ship/assets/icons/Icon128.png.import new file mode 100644 index 0000000..56fcaa9 --- /dev/null +++ b/godot_ship/assets/icons/Icon128.png.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="StreamTexture" +<<<<<<< HEAD:godot_ship/assets/game/2Ship.png.import +path="res://.import/2Ship.png-f56f600f71c287a0900c4554ec6e9837.stex" +======= +path="res://.import/Icon128.png-8fa6a445b29adcafaf69c45a7d758b76.stex" +>>>>>>> game-logic:godot_ship/assets/icons/Icon128.png.import +metadata={ +"vram_texture": false +} + +[deps] + +<<<<<<< HEAD:godot_ship/assets/game/2Ship.png.import +source_file="res://assets/game/2Ship.png" +dest_files=[ "res://.import/2Ship.png-f56f600f71c287a0900c4554ec6e9837.stex" ] +======= +source_file="res://assets/icons/Icon128.png" +dest_files=[ "res://.import/Icon128.png-8fa6a445b29adcafaf69c45a7d758b76.stex" ] +>>>>>>> game-logic:godot_ship/assets/icons/Icon128.png.import + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/godot_ship/assets/icons/Icon16.png b/godot_ship/assets/icons/Icon16.png new file mode 100644 index 0000000..6d72965 Binary files /dev/null and b/godot_ship/assets/icons/Icon16.png differ diff --git a/godot_ship/assets/icons/Icon16.png.import b/godot_ship/assets/icons/Icon16.png.import new file mode 100644 index 0000000..198822c --- /dev/null +++ b/godot_ship/assets/icons/Icon16.png.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="StreamTexture" +<<<<<<< HEAD:godot_ship/assets/game/3ShipA.png.import +path="res://.import/3ShipA.png-1fe0003af4adcd83b8c94b2b9d6e5b6d.stex" +======= +path="res://.import/Icon16.png-e916d7bb27530c71f994d2d2cacbe08b.stex" +>>>>>>> game-logic:godot_ship/assets/icons/Icon16.png.import +metadata={ +"vram_texture": false +} + +[deps] + +<<<<<<< HEAD:godot_ship/assets/game/3ShipA.png.import +source_file="res://assets/game/3ShipA.png" +dest_files=[ "res://.import/3ShipA.png-1fe0003af4adcd83b8c94b2b9d6e5b6d.stex" ] +======= +source_file="res://assets/icons/Icon16.png" +dest_files=[ "res://.import/Icon16.png-e916d7bb27530c71f994d2d2cacbe08b.stex" ] +>>>>>>> game-logic:godot_ship/assets/icons/Icon16.png.import + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/godot_ship/assets/icons/Icon256.png b/godot_ship/assets/icons/Icon256.png new file mode 100644 index 0000000..1694226 Binary files /dev/null and b/godot_ship/assets/icons/Icon256.png differ diff --git a/godot_ship/assets/icons/Icon256.png.import b/godot_ship/assets/icons/Icon256.png.import new file mode 100644 index 0000000..3af21cf --- /dev/null +++ b/godot_ship/assets/icons/Icon256.png.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="StreamTexture" +<<<<<<< HEAD:godot_ship/assets/game/3ShipB.png.import +path="res://.import/3ShipB.png-28ed039caa6839d715648812af8f65e4.stex" +======= +path="res://.import/Icon256.png-5fcf1bd6fb6791cb3c432c7c88dff8da.stex" +>>>>>>> game-logic:godot_ship/assets/icons/Icon256.png.import +metadata={ +"vram_texture": false +} + +[deps] + +<<<<<<< HEAD:godot_ship/assets/game/3ShipB.png.import +source_file="res://assets/game/3ShipB.png" +dest_files=[ "res://.import/3ShipB.png-28ed039caa6839d715648812af8f65e4.stex" ] +======= +source_file="res://assets/icons/Icon256.png" +dest_files=[ "res://.import/Icon256.png-5fcf1bd6fb6791cb3c432c7c88dff8da.stex" ] +>>>>>>> game-logic:godot_ship/assets/icons/Icon256.png.import + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/godot_ship/assets/icons/Icon32.png b/godot_ship/assets/icons/Icon32.png new file mode 100644 index 0000000..28dee84 Binary files /dev/null and b/godot_ship/assets/icons/Icon32.png differ diff --git a/godot_ship/assets/icons/Icon32.png.import b/godot_ship/assets/icons/Icon32.png.import new file mode 100644 index 0000000..cfbcce5 --- /dev/null +++ b/godot_ship/assets/icons/Icon32.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Icon32.png-ba330b5438b784e541f4d4c7ff1165f1.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/Icon32.png" +dest_files=[ "res://.import/Icon32.png-ba330b5438b784e541f4d4c7ff1165f1.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/godot_ship/assets/icons/Icon64.png b/godot_ship/assets/icons/Icon64.png new file mode 100644 index 0000000..ab9b1f0 Binary files /dev/null and b/godot_ship/assets/icons/Icon64.png differ diff --git a/godot_ship/assets/icons/Icon64.png.import b/godot_ship/assets/icons/Icon64.png.import new file mode 100644 index 0000000..71d7482 --- /dev/null +++ b/godot_ship/assets/icons/Icon64.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Icon64.png-688550eb2085ba14f76a5ffeb3504d87.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/icons/Icon64.png" +dest_files=[ "res://.import/Icon64.png-688550eb2085ba14f76a5ffeb3504d87.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/godot_ship/dark_theme.tres b/godot_ship/dark_theme.tres new file mode 100644 index 0000000..3ed6bd8 --- /dev/null +++ b/godot_ship/dark_theme.tres @@ -0,0 +1,64 @@ +[gd_resource type="Theme" load_steps=6 format=2] + +[ext_resource path="res://assets/font/Minecraft.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://assets/backgrounds/PanelBG_Dark.tres" type="StyleBox" id=2] + +[sub_resource type="StyleBoxFlat" id=1] +bg_color = Color( 0.239216, 0.211765, 0.317647, 1 ) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +shadow_size = 4 + +[sub_resource type="StyleBoxFlat" id=2] +bg_color = Color( 0.109804, 0.0862745, 0.172549, 1 ) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +shadow_size = 3 + +[sub_resource type="DynamicFont" id=3] +outline_size = 1 +outline_color = Color( 0, 0, 0, 1 ) +extra_spacing_top = 5 +extra_spacing_bottom = 3 +extra_spacing_char = 1 +font_data = ExtResource( 1 ) + +[resource] +default_font = SubResource( 3 ) +Button/colors/font_color = Color( 1, 1, 1, 1 ) +Button/colors/font_color_disabled = Color( 0.901961, 0.901961, 0.901961, 0.2 ) +Button/colors/font_color_hover = Color( 1, 1, 1, 1 ) +Button/colors/font_color_pressed = Color( 1, 1, 1, 1 ) +Button/constants/hseparation = 2 +Button/fonts/font = null +Button/styles/disabled = null +Button/styles/focus = null +Button/styles/hover = SubResource( 1 ) +Button/styles/normal = SubResource( 2 ) +Button/styles/pressed = null +Dialogs/constants/button_margin = 100 +Dialogs/constants/margin = 8 +Label/colors/font_color = Color( 1, 1, 1, 1 ) +Label/colors/font_color_shadow = Color( 0, 0, 0, 0.25098 ) +Label/colors/font_outline_modulate = Color( 0, 0, 0, 1 ) +Label/constants/line_spacing = 3 +Label/constants/shadow_as_outline = 0 +Label/constants/shadow_offset_x = 0 +Label/constants/shadow_offset_y = 2 +Label/fonts/font = null +Label/styles/normal = null +Panel/styles/panel = ExtResource( 2 ) +PanelContainer/styles/panel = ExtResource( 2 ) +WindowDialog/colors/title_color = Color( 0.152941, 0.152941, 0.152941, 1 ) +WindowDialog/constants/close_h_ofs = 18 +WindowDialog/constants/close_v_ofs = 18 +WindowDialog/constants/scaleborder_size = 4 +WindowDialog/constants/title_height = 20 +WindowDialog/fonts/title_font = null +WindowDialog/icons/close = null +WindowDialog/icons/close_highlight = null +WindowDialog/styles/panel = null diff --git a/godot_ship/export_presets.cfg b/godot_ship/export_presets.cfg index 5a38ab4..fafb8c4 100644 --- a/godot_ship/export_presets.cfg +++ b/godot_ship/export_presets.cfg @@ -31,7 +31,7 @@ codesign/timestamp_server_url="" codesign/digest_algorithm=1 codesign/description="" codesign/custom_options=PoolStringArray( ) -application/icon="" +application/icon="res://icon.ico" application/file_version="" application/product_version="" application/company_name="" diff --git a/godot_ship/icon.icns b/godot_ship/icon.icns new file mode 100644 index 0000000..3fcc055 Binary files /dev/null and b/godot_ship/icon.icns differ diff --git a/godot_ship/icon.ico b/godot_ship/icon.ico new file mode 100644 index 0000000..4eff49a Binary files /dev/null and b/godot_ship/icon.ico differ diff --git a/godot_ship/icon.png b/godot_ship/icon.png index c98fbb6..1694226 100644 Binary files a/godot_ship/icon.png and b/godot_ship/icon.png differ diff --git a/godot_ship/light_theme.tres b/godot_ship/light_theme.tres new file mode 100644 index 0000000..da4e5b0 --- /dev/null +++ b/godot_ship/light_theme.tres @@ -0,0 +1,63 @@ +[gd_resource type="Theme" load_steps=6 format=2] + +[ext_resource path="res://assets/font/Minecraft.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://assets/backgrounds/PanelBG_Light.tres" type="StyleBox" id=2] + +[sub_resource type="StyleBoxFlat" id=1] +bg_color = Color( 1, 1, 1, 1 ) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +shadow_size = 4 + +[sub_resource type="StyleBoxFlat" id=2] +bg_color = Color( 0.847059, 0.921569, 0.964706, 1 ) +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_right = 3 +corner_radius_bottom_left = 3 +shadow_size = 3 + +[sub_resource type="DynamicFont" id=3] +outline_size = 1 +extra_spacing_top = 5 +extra_spacing_bottom = 3 +extra_spacing_char = 1 +font_data = ExtResource( 1 ) + +[resource] +default_font = SubResource( 3 ) +Button/colors/font_color = Color( 0.0784314, 0.0784314, 0.0784314, 1 ) +Button/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 ) +Button/colors/font_color_hover = Color( 0, 0, 0, 1 ) +Button/colors/font_color_pressed = Color( 0, 0, 0, 1 ) +Button/constants/hseparation = 2 +Button/fonts/font = null +Button/styles/disabled = null +Button/styles/focus = null +Button/styles/hover = SubResource( 1 ) +Button/styles/normal = SubResource( 2 ) +Button/styles/pressed = null +Dialogs/constants/button_margin = 100 +Dialogs/constants/margin = 8 +Label/colors/font_color = Color( 1, 1, 1, 1 ) +Label/colors/font_color_shadow = Color( 0, 0, 0, 1 ) +Label/colors/font_outline_modulate = Color( 0, 0, 0, 1 ) +Label/constants/line_spacing = 3 +Label/constants/shadow_as_outline = 0 +Label/constants/shadow_offset_x = 0 +Label/constants/shadow_offset_y = 2 +Label/fonts/font = null +Label/styles/normal = null +Panel/styles/panel = ExtResource( 2 ) +PanelContainer/styles/panel = ExtResource( 2 ) +WindowDialog/colors/title_color = Color( 0.152941, 0.152941, 0.152941, 1 ) +WindowDialog/constants/close_h_ofs = 18 +WindowDialog/constants/close_v_ofs = 18 +WindowDialog/constants/scaleborder_size = 4 +WindowDialog/constants/title_height = 20 +WindowDialog/fonts/title_font = null +WindowDialog/icons/close = null +WindowDialog/icons/close_highlight = null +WindowDialog/styles/panel = null diff --git a/godot_ship/project.godot b/godot_ship/project.godot index fbccc41..628cf3e 100644 --- a/godot_ship/project.godot +++ b/godot_ship/project.godot @@ -12,7 +12,10 @@ config_version=4 config/name="godot_ship" run/main_scene="res://scenes/Main.tscn" +boot_splash/image="res://assets/backgrounds/splash_image.png" config/icon="res://icon.png" +config/macos_native_icon="res://icon.icns" +config/windows_native_icon="res://icon.ico" [autoload] @@ -20,6 +23,7 @@ MessageBus="*res://script/Message Bus.gd" AudioBus="*res://script/audio controller/Audio Bus.gd" OptionsController="*res://script/options/OptionsController.gd" AudioController="*res://scenes/AudioController.tscn" +Net="*res://script/network/Net.gd" [display] @@ -30,6 +34,10 @@ window/per_pixel_transparency/allowed=true window/stretch/mode="viewport" window/stretch/aspect="keep" +[global] + +verbose=false + [input] ui_left={ diff --git a/godot_ship/scenes/Credits.tscn b/godot_ship/scenes/Credits.tscn new file mode 100644 index 0000000..f153cd1 --- /dev/null +++ b/godot_ship/scenes/Credits.tscn @@ -0,0 +1,276 @@ +[gd_scene load_steps=6 format=2] + +[ext_resource path="res://assets/font/Minecraft.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://script/credits/Credits.gd" type="Script" id=2] +[ext_resource path="res://light_theme.tres" type="Theme" id=3] + +[sub_resource type="DynamicFont" id=1] +size = 44 +outline_size = 2 +outline_color = Color( 0, 0, 0, 1 ) +font_data = ExtResource( 1 ) + +[sub_resource type="DynamicFont" id=2] +outline_size = 1 +outline_color = Color( 0, 0, 0, 1 ) +font_data = ExtResource( 1 ) + +[node name="Credits" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +theme = ExtResource( 3 ) +script = ExtResource( 2 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Back" type="Button" parent="."] +margin_left = 16.0 +margin_top = 16.0 +margin_right = 83.0 +margin_bottom = 40.0 +focus_neighbour_left = NodePath(".") +focus_neighbour_top = NodePath(".") +focus_neighbour_right = NodePath("../Sliders/SFX Setting/SFX Slider") +focus_neighbour_bottom = NodePath("../Buttons/Light") +focus_next = NodePath("../Sliders/SFX Setting/SFX Slider") +focus_previous = NodePath(".") +text = "Back" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Credits Label" type="Label" parent="."] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -82.0 +margin_top = 49.0 +margin_right = 82.0 +margin_bottom = 93.0 +custom_fonts/font = SubResource( 1 ) +custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) +custom_constants/shadow_offset_y = 8 +text = "Credits" +align = 1 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Developmental Team" type="Label" parent="."] +margin_left = 64.0 +margin_top = 99.0 +margin_right = 576.0 +margin_bottom = 115.0 +custom_fonts/font = SubResource( 2 ) +custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) +custom_constants/shadow_offset_y = 4 +text = "Developmental Team" +align = 1 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Programmer Titles" type="VBoxContainer" parent="."] +margin_left = 64.0 +margin_top = 120.0 +margin_right = 312.0 +margin_bottom = 196.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Programmer" type="Label" parent="Programmer Titles"] +margin_right = 248.0 +margin_bottom = 16.0 +custom_fonts/font = SubResource( 2 ) +text = "Lead Programmer:" +align = 2 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Design" type="Label" parent="Programmer Titles"] +margin_top = 20.0 +margin_right = 248.0 +margin_bottom = 36.0 +custom_fonts/font = SubResource( 2 ) +text = "Project Design:" +align = 2 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Art" type="Label" parent="Programmer Titles"] +margin_top = 40.0 +margin_right = 248.0 +margin_bottom = 56.0 +custom_fonts/font = SubResource( 2 ) +text = "Artist:" +align = 2 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Sound" type="Label" parent="Programmer Titles"] +margin_top = 60.0 +margin_right = 248.0 +margin_bottom = 76.0 +custom_fonts/font = SubResource( 2 ) +text = "Sound Engineer:" +align = 2 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Programmer Name" type="VBoxContainer" parent="."] +margin_left = 328.0 +margin_top = 120.0 +margin_right = 576.0 +margin_bottom = 196.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Programmer" type="Label" parent="Programmer Name"] +margin_right = 248.0 +margin_bottom = 16.0 +custom_fonts/font = SubResource( 2 ) +text = "John Breaux" +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Design" type="Label" parent="Programmer Name"] +margin_top = 20.0 +margin_right = 248.0 +margin_bottom = 36.0 +custom_fonts/font = SubResource( 2 ) +text = "Chance Atkinson" +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Art" type="Label" parent="Programmer Name"] +margin_top = 40.0 +margin_right = 248.0 +margin_bottom = 56.0 +custom_fonts/font = SubResource( 2 ) +text = "Tommy Ngo" +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Sound" type="Label" parent="Programmer Name"] +margin_top = 60.0 +margin_right = 248.0 +margin_bottom = 76.0 +custom_fonts/font = SubResource( 2 ) +text = "Hien Pham" +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Assets" type="Label" parent="."] +margin_left = 64.0 +margin_top = 203.0 +margin_right = 576.0 +margin_bottom = 219.0 +custom_fonts/font = SubResource( 2 ) +custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) +custom_constants/shadow_offset_y = 4 +text = "Assets" +align = 1 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Assets Titles" type="VBoxContainer" parent="."] +margin_left = 64.0 +margin_top = 224.0 +margin_right = 312.0 +margin_bottom = 288.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="BGM" type="Label" parent="Assets Titles"] +margin_right = 248.0 +margin_bottom = 35.0 +custom_fonts/font = SubResource( 2 ) +text = "Background Music: +" +align = 2 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="SFX" type="Label" parent="Assets Titles"] +margin_top = 39.0 +margin_right = 248.0 +margin_bottom = 55.0 +custom_fonts/font = SubResource( 2 ) +text = "SFX Sounds:" +align = 2 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Assets Credits" type="VBoxContainer" parent="."] +margin_left = 328.0 +margin_top = 225.0 +margin_right = 576.0 +margin_bottom = 299.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Composer" type="Label" parent="Assets Credits"] +margin_right = 248.0 +margin_bottom = 35.0 +custom_fonts/font = SubResource( 2 ) +text = "\"Captain Scurvy\" Kevin + MacLeod (incompetech.com)" +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="SFX creators" type="Label" parent="Assets Credits"] +margin_top = 39.0 +margin_right = 248.0 +margin_bottom = 74.0 +custom_fonts/font = SubResource( 2 ) +text = "Creator Assets +Free Sounds Library" +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Engine" type="Label" parent="."] +margin_left = 64.0 +margin_top = 312.0 +margin_right = 576.0 +margin_bottom = 328.0 +custom_fonts/font = SubResource( 2 ) +text = "Created Using Godot Engine" +align = 1 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="pressed" from="Back" to="." method="_on_Back_pressed"] diff --git a/godot_ship/scenes/Game/Board.tscn b/godot_ship/scenes/Game/Board.tscn new file mode 100644 index 0000000..75ca79a --- /dev/null +++ b/godot_ship/scenes/Game/Board.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://script/game/Gameplay/Board.gd" type="Script" id=1] +[ext_resource path="res://assets/game/board_blue.png" type="Texture" id=2] + +[node name="Board" type="Node2D"] +position = Vector2( 36, 36 ) +script = ExtResource( 1 ) + +[node name="TempBoardSprite" type="Sprite" parent="."] +texture = ExtResource( 2 ) +centered = false +offset = Vector2( -18, -18 ) diff --git a/godot_ship/scenes/Game/Fire.tscn b/godot_ship/scenes/Game/Fire.tscn index 7f42da6..fb9cde5 100644 --- a/godot_ship/scenes/Game/Fire.tscn +++ b/godot_ship/scenes/Game/Fire.tscn @@ -40,7 +40,7 @@ __meta__ = { pause_mode = 2 margin_right = 83.0 margin_bottom = 58.0 -dialog_text = "You can't fire outside the board" +dialog_text = "You must select a valid position" [connection signal="pressed" from="Fire" to="." method="_on_Fire_pressed"] [connection signal="confirmed" from="FireDialog" to="." method="_on_FireDialog_confirmed"] diff --git a/godot_ship/scenes/Game/Game.tscn b/godot_ship/scenes/Game/Game.tscn index 681939f..e585187 100644 --- a/godot_ship/scenes/Game/Game.tscn +++ b/godot_ship/scenes/Game/Game.tscn @@ -16,20 +16,20 @@ anchor_left = 0.912 anchor_top = 0.932 anchor_right = 0.912 anchor_bottom = 0.932 -margin_left = -3.68005 -margin_top = -4.52002 -margin_right = 49.3199 -margin_bottom = 15.48 +margin_left = -37.68 +margin_top = -329.52 +margin_right = 50.32 +margin_bottom = -305.52 __meta__ = { "_edit_use_anchors_": false } [node name="Forfeit" type="Button" parent="Buttons"] -margin_right = 53.0 +margin_right = 88.0 margin_bottom = 20.0 text = "Forfeit" -[node name="ConfirmationDialog" type="ConfirmationDialog" parent="."] +[node name="Forfeit Confirmation" type="ConfirmationDialog" parent="."] anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 @@ -46,5 +46,21 @@ __meta__ = { "_editor_description_": "" } +[node name="Button" type="Button" parent="."] +visible = false +margin_left = 6.4668 +margin_top = 6.14783 +margin_right = 43.4668 +margin_bottom = 26.1478 +text = "Win" + +[node name="Connection Error" type="AcceptDialog" parent="."] +margin_right = 230.0 +margin_bottom = 58.0 +window_title = "Connection Error" +dialog_text = "Host disconnected unexpectedly." + [connection signal="pressed" from="Buttons/Forfeit" to="." method="_on_Forfeit_pressed"] -[connection signal="confirmed" from="ConfirmationDialog" to="." method="_on_ConfirmationDialog_confirmed"] +[connection signal="confirmed" from="Forfeit Confirmation" to="." method="_on_Forfeit_Confirmation_confirmed"] +[connection signal="button_down" from="Button" to="." method="_on_Button_button_down"] +[connection signal="confirmed" from="Connection Error" to="." method="_on_Connection_Error_confirmed"] diff --git a/godot_ship/scenes/Game/Player.tscn b/godot_ship/scenes/Game/Player.tscn index a0e1be0..f48de99 100644 --- a/godot_ship/scenes/Game/Player.tscn +++ b/godot_ship/scenes/Game/Player.tscn @@ -1,8 +1,12 @@ -[gd_scene format=2] +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://script/game/Gameplay/Player.gd" type="Script" id=1] [node name="Player" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 +mouse_filter = 2 +script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } diff --git a/godot_ship/scenes/Game/Setup.tscn b/godot_ship/scenes/Game/Setup.tscn index 42db1cd..fdda0b1 100644 --- a/godot_ship/scenes/Game/Setup.tscn +++ b/godot_ship/scenes/Game/Setup.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=8 format=2] +[gd_scene load_steps=9 format=2] [ext_resource path="res://assets/game/board_blue.png" type="Texture" id=1] +[ext_resource path="res://dark_theme.tres" type="Theme" id=2] [ext_resource path="res://scenes/ships/3ShipB.tscn" type="PackedScene" id=4] [ext_resource path="res://scenes/ships/3shipA.tscn" type="PackedScene" id=5] [ext_resource path="res://scenes/ships/4Ship.tscn" type="PackedScene" id=6] @@ -15,6 +16,7 @@ anchor_bottom = 0.890237 margin_top = -0.445435 margin_bottom = 39.5145 mouse_filter = 2 +theme = ExtResource( 2 ) script = ExtResource( 10 ) __meta__ = { "_edit_use_anchors_": false @@ -70,20 +72,20 @@ contacts_reported = 1 contact_monitor = true [node name="Confirm Placement" type="Button" parent="."] -margin_left = 409.0 -margin_top = 331.0 -margin_right = 543.0 -margin_bottom = 351.0 +margin_left = 417.0 +margin_top = 316.0 +margin_right = 608.0 +margin_bottom = 340.0 text = "Confirm Placement" __meta__ = { "_edit_use_anchors_": false } [node name="Clear" type="Button" parent="."] -margin_left = 353.0 -margin_top = 331.0 -margin_right = 406.0 -margin_bottom = 351.0 +margin_left = 348.0 +margin_top = 316.0 +margin_right = 408.0 +margin_bottom = 340.0 text = "Clear" __meta__ = { "_edit_use_anchors_": false diff --git a/godot_ship/scenes/Game/Ship.tscn b/godot_ship/scenes/Game/Ship.tscn new file mode 100644 index 0000000..a41a401 --- /dev/null +++ b/godot_ship/scenes/Game/Ship.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://script/game/Gameplay/Ship.gd" type="Script" id=1] + +[node name="Ship" type="Node2D"] +script = ExtResource( 1 ) diff --git a/godot_ship/scenes/Game/Victory.tscn b/godot_ship/scenes/Game/Victory.tscn index 3d1091c..c6052df 100644 --- a/godot_ship/scenes/Game/Victory.tscn +++ b/godot_ship/scenes/Game/Victory.tscn @@ -10,26 +10,13 @@ font_data = ExtResource( 2 ) [node name="Victory" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 +mouse_filter = 2 script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } -[node name="Label" type="Label" parent="."] -margin_left = 118.32 -margin_top = 44.5109 -margin_right = 260.32 -margin_bottom = 84.5109 -size_flags_vertical = 0 -custom_fonts/font = SubResource( 1 ) -text = "Victory" -align = 1 -valign = 1 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Button" type="Button" parent="."] +[node name="exit_to_main" type="Button" parent="."] margin_left = 541.0 margin_top = 327.85 margin_right = 636.0 @@ -47,5 +34,20 @@ margin_right = 63.2202 margin_bottom = 357.41 text = "Restart" -[connection signal="pressed" from="Button" to="." method="_on_Button_pressed"] +[node name="Victory" type="Label" parent="."] +margin_left = 380.0 +margin_top = 44.5109 +margin_right = 260.32 +margin_bottom = 84.5109 +size_flags_vertical = 0 +custom_fonts/font = SubResource( 1 ) +text = "Victory" +align = 1 +valign = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[connection signal="button_down" from="exit_to_main" to="." method="_on_exit_to_main_button_down"] +[connection signal="pressed" from="exit_to_main" to="." method="_on_Button_pressed"] [connection signal="button_down" from="Button2" to="." method="_on_restart_button_down"] diff --git a/godot_ship/scenes/Lobby.tscn b/godot_ship/scenes/Lobby.tscn new file mode 100644 index 0000000..e8ab806 --- /dev/null +++ b/godot_ship/scenes/Lobby.tscn @@ -0,0 +1,180 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://script/network/Lobby.gd" type="Script" id=1] + +[node name="Lobby" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Player List Container" type="PanelContainer" parent="."] +anchor_left = 0.6 +anchor_top = 0.2 +anchor_right = 0.9 +anchor_bottom = 0.8 +size_flags_vertical = 4 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Align Vertically" type="VBoxContainer" parent="Player List Container"] +margin_left = 7.0 +margin_top = 7.0 +margin_right = 185.0 +margin_bottom = 209.0 +grow_horizontal = 2 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Players" type="Label" parent="Player List Container/Align Vertically"] +margin_right = 178.0 +margin_bottom = 14.0 +text = "Players" +align = 1 + +[node name="Player List" type="Label" parent="Player List Container/Align Vertically"] +margin_top = 18.0 +margin_right = 178.0 +margin_bottom = 32.0 +align = 1 + +[node name="Lobby Options" type="VBoxContainer" parent="."] +anchor_left = 0.2 +anchor_top = 0.2 +anchor_right = 0.2 +anchor_bottom = 0.2 +margin_right = 123.0 +margin_bottom = 84.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Lobby Text" type="Label" parent="Lobby Options"] +margin_right = 123.0 +margin_bottom = 14.0 +text = "Multiplayer Lobby" +align = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="IP Address" type="Label" parent="Lobby Options"] +margin_top = 18.0 +margin_right = 123.0 +margin_bottom = 32.0 +align = 1 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Host or Connect" type="VBoxContainer" parent="Lobby Options"] +margin_top = 36.0 +margin_right = 123.0 +margin_bottom = 80.0 + +[node name="Host Button" type="Button" parent="Lobby Options/Host or Connect"] +margin_right = 123.0 +margin_bottom = 20.0 +text = "Host Game" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Connect Button" type="Button" parent="Lobby Options/Host or Connect"] +margin_top = 24.0 +margin_right = 123.0 +margin_bottom = 44.0 +text = "Connect to Game" + +[node name="Connected Options" type="VBoxContainer" parent="Lobby Options"] +visible = false +margin_top = 36.0 +margin_right = 123.0 +margin_bottom = 56.0 + +[node name="Host Options" type="VBoxContainer" parent="Lobby Options/Connected Options"] +visible = false +margin_right = 123.0 +margin_bottom = 20.0 + +[node name="Start Game" type="Button" parent="Lobby Options/Connected Options/Host Options"] +margin_right = 123.0 +margin_bottom = 20.0 +text = "Start Game" + +[node name="Disconnect Button" type="Button" parent="Lobby Options/Connected Options"] +margin_right = 123.0 +margin_bottom = 20.0 +text = "Disconnect" + +[node name="Change Name Button" type="Button" parent="Lobby Options"] +margin_top = 84.0 +margin_right = 123.0 +margin_bottom = 104.0 +text = "Change Name" + +[node name="Exit Lobby Button" type="Button" parent="Lobby Options"] +margin_top = 108.0 +margin_right = 123.0 +margin_bottom = 128.0 +text = "Exit Lobby" + +[node name="Change Name" type="WindowDialog" parent="."] +visible = true +margin_left = 201.002 +margin_top = 516.255 +margin_right = 441.002 +margin_bottom = 562.255 +rect_min_size = Vector2( 240, 46 ) +window_title = "Change Name" + +[node name="Name Entry" type="LineEdit" parent="Change Name"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -112.0 +margin_top = 8.0 +margin_right = 112.0 +margin_bottom = 38.0 +grow_horizontal = 2 +rect_min_size = Vector2( 224, 30 ) +text = "127.0.0.1" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Connect to Game" type="WindowDialog" parent="."] +visible = true +margin_left = 201.136 +margin_top = 404.977 +margin_right = 441.136 +margin_bottom = 450.977 +rect_min_size = Vector2( 240, 46 ) +window_title = "Connect to Game" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="IP and Port Entry" type="LineEdit" parent="Connect to Game"] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -112.0 +margin_top = 8.0 +margin_right = 112.0 +margin_bottom = 38.0 +grow_horizontal = 2 +rect_min_size = Vector2( 224, 30 ) +text = "127.0.0.1" + +[connection signal="pressed" from="Lobby Options/Host or Connect/Host Button" to="." method="_on_Host_Button_pressed"] +[connection signal="pressed" from="Lobby Options/Host or Connect/Connect Button" to="." method="_on_Connect_Button_pressed"] +[connection signal="pressed" from="Lobby Options/Connected Options/Host Options/Start Game" to="." method="_on_Start_Game_pressed"] +[connection signal="pressed" from="Lobby Options/Connected Options/Disconnect Button" to="." method="_on_Disconnect_Button_pressed"] +[connection signal="pressed" from="Lobby Options/Change Name Button" to="." method="_on_Change_Name_Button_pressed"] +[connection signal="pressed" from="Lobby Options/Exit Lobby Button" to="." method="_on_Exit_Lobby_pressed"] +[connection signal="text_entered" from="Change Name/Name Entry" to="." method="_on_Name_Entry_text_entered"] +[connection signal="text_entered" from="Connect to Game/IP and Port Entry" to="." method="_on_IP_and_Port_Entry_text_entered"] diff --git a/godot_ship/scenes/Options.tscn b/godot_ship/scenes/Options.tscn index 2ed6077..cd80f96 100644 --- a/godot_ship/scenes/Options.tscn +++ b/godot_ship/scenes/Options.tscn @@ -1,24 +1,52 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=8 format=2] +[ext_resource path="res://assets/font/Minecraft.ttf" type="DynamicFontData" id=1] [ext_resource path="res://script/options/Options.gd" type="Script" id=2] +[ext_resource path="res://light_theme.tres" type="Theme" id=3] + +[sub_resource type="DynamicFont" id=1] +size = 44 +outline_size = 2 +outline_color = Color( 0, 0, 0, 1 ) +font_data = ExtResource( 1 ) + +[sub_resource type="DynamicFont" id=2] +outline_size = 1 +outline_color = Color( 0, 0, 0, 1 ) +font_data = ExtResource( 1 ) + +[sub_resource type="DynamicFont" id=3] +outline_size = 1 +outline_color = Color( 0, 0, 0, 1 ) +font_data = ExtResource( 1 ) + +[sub_resource type="DynamicFont" id=4] +outline_size = 1 +font_data = ExtResource( 1 ) [node name="Options" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 +theme = ExtResource( 3 ) script = ExtResource( 2 ) __meta__ = { "_edit_use_anchors_": false } -[node name="MenuLabel" type="RichTextLabel" parent="."] -margin_left = 294.0 -margin_top = 68.0 -margin_right = 346.0 -margin_bottom = 83.0 -custom_colors/default_color = Color( 0, 0, 0, 1 ) +[node name="Options Label" type="Label" parent="."] +anchor_left = 0.5 +anchor_right = 0.5 +margin_left = -82.0 +margin_top = 49.0 +margin_right = 82.0 +margin_bottom = 93.0 +custom_fonts/font = SubResource( 1 ) +custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) +custom_constants/shadow_offset_y = 8 text = "Options" +align = 2 +valign = 1 __meta__ = { -"_edit_lock_": true, "_edit_use_anchors_": false } @@ -36,11 +64,11 @@ __meta__ = { position = Vector2( 0, 8 ) [node name="Master Label" type="Label" parent="Sliders/Master Volume Setting"] -margin_left = -0.140289 -margin_top = -8.0 -margin_right = 63.8597 -margin_bottom = 8.0 -custom_colors/font_color = Color( 0, 0, 0, 1 ) +margin_left = -8.14029 +margin_top = -14.0 +margin_right = 57.8597 +margin_bottom = 10.0 +custom_fonts/font = SubResource( 2 ) text = "Volume:" align = 2 valign = 1 @@ -50,9 +78,9 @@ __meta__ = { [node name="Master Slider" type="HSlider" parent="Sliders/Master Volume Setting"] margin_left = 64.0 -margin_top = -8.0 +margin_top = -10.0 margin_right = 208.0 -margin_bottom = 8.0 +margin_bottom = 6.0 focus_neighbour_left = NodePath("../../../Back") focus_neighbour_top = NodePath("../../../Back") focus_neighbour_bottom = NodePath("../../Volume Setting/Volume Slider") @@ -61,6 +89,7 @@ focus_previous = NodePath("../../../Back") max_value = 1.0 step = 0.05 tick_count = 10 +ticks_on_borders = true __meta__ = { "_edit_use_anchors_": false } @@ -69,10 +98,11 @@ __meta__ = { position = Vector2( 0, 33 ) [node name="Music Label" type="Label" parent="Sliders/Music Volume Setting"] -margin_top = -8.0 -margin_right = 64.0 -margin_bottom = 8.0 -custom_colors/font_color = Color( 0, 0, 0, 1 ) +margin_left = -6.0 +margin_top = -13.0 +margin_right = 58.0 +margin_bottom = 11.0 +custom_fonts/font = SubResource( 3 ) text = "Music:" align = 2 valign = 1 @@ -81,10 +111,10 @@ __meta__ = { } [node name="Music Slider" type="HSlider" parent="Sliders/Music Volume Setting"] -margin_left = 64.0 -margin_top = -8.0 -margin_right = 208.0 -margin_bottom = 8.0 +margin_left = 64.25 +margin_top = -9.0 +margin_right = 208.25 +margin_bottom = 7.0 focus_neighbour_top = NodePath("../../SFX Setting/SFX Slider") focus_neighbour_bottom = NodePath("../../../Buttons/Dark") focus_next = NodePath("../../../Buttons/Dark") @@ -92,6 +122,7 @@ focus_previous = NodePath("../../SFX Setting/SFX Slider") max_value = 1.0 step = 0.05 tick_count = 10 +ticks_on_borders = true __meta__ = { "_edit_use_anchors_": false } @@ -99,10 +130,11 @@ __meta__ = { [node name="SFX Volume Setting" type="Node2D" parent="Sliders"] [node name="SFX Label" type="Label" parent="Sliders/SFX Volume Setting"] -margin_top = 48.0 -margin_right = 64.0 -margin_bottom = 64.0 -custom_colors/font_color = Color( 0, 0, 0, 1 ) +margin_left = -6.0 +margin_top = 46.0 +margin_right = 58.0 +margin_bottom = 70.0 +custom_fonts/font = SubResource( 4 ) text = "SFX:" align = 2 valign = 1 @@ -112,23 +144,27 @@ __meta__ = { [node name="SFX Slider" type="HSlider" parent="Sliders/SFX Volume Setting"] margin_left = 64.0 -margin_top = 48.0 +margin_top = 50.0 margin_right = 208.0 -margin_bottom = 64.0 +margin_bottom = 66.0 max_value = 1.0 step = 0.05 tick_count = 10 +ticks_on_borders = true __meta__ = { "_edit_use_anchors_": false } [node name="Buttons" type="HBoxContainer" parent="."] -margin_left = 216.0 -margin_top = 200.0 -margin_right = 424.0 -margin_bottom = 224.0 +anchor_left = 0.5 +anchor_top = 0.498036 +anchor_right = 0.5 +anchor_bottom = 0.498036 +margin_left = -102.0 +margin_top = 30.7071 +margin_right = 106.0 +margin_bottom = 54.7071 __meta__ = { -"_edit_lock_": true, "_edit_use_anchors_": false } @@ -157,8 +193,8 @@ text = "Dark Mode" [node name="Back" type="Button" parent="."] margin_left = 16.0 margin_top = 16.0 -margin_right = 28.0 -margin_bottom = 36.0 +margin_right = 83.0 +margin_bottom = 40.0 focus_neighbour_left = NodePath(".") focus_neighbour_top = NodePath(".") focus_neighbour_right = NodePath("../Sliders/SFX Setting/SFX Slider") @@ -167,7 +203,6 @@ focus_next = NodePath("../Sliders/SFX Setting/SFX Slider") focus_previous = NodePath(".") text = "Back" __meta__ = { -"_edit_lock_": true, "_edit_use_anchors_": false } diff --git a/godot_ship/scenes/Title Screen.tscn b/godot_ship/scenes/Title Screen.tscn index 9cc581c..2fd5dfa 100644 --- a/godot_ship/scenes/Title Screen.tscn +++ b/godot_ship/scenes/Title Screen.tscn @@ -1,5 +1,6 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=5 format=2] +[ext_resource path="res://light_theme.tres" type="Theme" id=1] [ext_resource path="res://script/title screen/Title Screen.gd" type="Script" id=2] [ext_resource path="res://assets/font/Minecraft.ttf" type="DynamicFontData" id=3] @@ -12,6 +13,7 @@ font_data = ExtResource( 3 ) [node name="Title Node" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 +theme = ExtResource( 1 ) script = ExtResource( 2 ) __meta__ = { "_edit_use_anchors_": false @@ -22,36 +24,42 @@ anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 anchor_bottom = 0.5 -margin_left = -68.077 -margin_top = 10.0 -margin_right = 68.077 -margin_bottom = 102.0 +margin_left = -80.0 +margin_top = 11.0 +margin_right = 80.0 +margin_bottom = 119.0 __meta__ = { "_edit_use_anchors_": false } [node name="Singleplayer" type="Button" parent="VBoxContainer"] -margin_right = 136.0 -margin_bottom = 20.0 +visible = false +margin_right = 160.0 +margin_bottom = 24.0 focus_neighbour_top = NodePath("../Quit") text = "Single Player" [node name="Multiplayer" type="Button" parent="VBoxContainer"] -margin_top = 24.0 -margin_right = 136.0 -margin_bottom = 44.0 +margin_right = 160.0 +margin_bottom = 24.0 text = "Multiplayer" [node name="Options" type="Button" parent="VBoxContainer"] -margin_top = 48.0 -margin_right = 136.0 -margin_bottom = 68.0 +margin_top = 28.0 +margin_right = 160.0 +margin_bottom = 52.0 text = "Options" +[node name="Credits" type="Button" parent="VBoxContainer"] +margin_top = 56.0 +margin_right = 160.0 +margin_bottom = 80.0 +text = "Credits" + [node name="Quit" type="Button" parent="VBoxContainer"] -margin_top = 72.0 -margin_right = 136.0 -margin_bottom = 92.0 +margin_top = 84.0 +margin_right = 160.0 +margin_bottom = 108.0 focus_neighbour_bottom = NodePath("../Singleplayer") text = "Quit" @@ -61,11 +69,12 @@ anchor_top = 0.5 anchor_right = 0.5 anchor_bottom = 0.5 margin_left = -157.0 -margin_top = -50.0 +margin_top = -59.0 margin_right = 157.0 -margin_bottom = -6.0 +margin_bottom = -15.0 size_flags_stretch_ratio = 0.0 custom_fonts/font = SubResource( 1 ) +custom_colors/font_color = Color( 1, 1, 1, 1 ) custom_colors/font_outline_modulate = Color( 0, 0, 0, 1 ) custom_colors/font_color_shadow = Color( 0, 0, 0, 1 ) custom_constants/shadow_offset_x = 0 @@ -80,4 +89,5 @@ __meta__ = { [connection signal="pressed" from="VBoxContainer/Singleplayer" to="." method="_on_Singleplayer_pressed"] [connection signal="pressed" from="VBoxContainer/Multiplayer" to="." method="_on_Multiplayer_pressed"] [connection signal="pressed" from="VBoxContainer/Options" to="." method="_on_Options_pressed"] +[connection signal="pressed" from="VBoxContainer/Credits" to="." method="_on_Credits_pressed"] [connection signal="pressed" from="VBoxContainer/Quit" to="." method="_on_Quit_pressed"] diff --git a/godot_ship/script/Main.gd b/godot_ship/script/Main.gd index a3d53f9..c7caaf9 100644 --- a/godot_ship/script/Main.gd +++ b/godot_ship/script/Main.gd @@ -3,12 +3,16 @@ extends Control # Scenes onready var Title_Screen = preload("res://scenes/Title Screen.tscn") onready var Game = preload("res://scenes/Game/Game.tscn" ) +onready var Lobby = preload("res://scenes/Lobby.tscn" ) onready var Options = preload("res://scenes/Options.tscn" ) +onready var Credits = preload("res://scenes/Credits.tscn" ) onready var Debug_Menu = preload("res://scenes/Debug Menu.tscn" ) # Themes -var lightmode = preload("res://assets/backgrounds/Background_Light.png"); -var darkmode = preload("res://assets/backgrounds/Background_Dark.png"); +var lightmode = preload("res://assets/backgrounds/Background_Light.png") +var darkmode = preload("res://assets/backgrounds/Background_Dark.png") +var light_theme = load("res://light_theme.tres") +var dark_theme = load("res://dark_theme.tres") #flags var power_saving = true @@ -56,19 +60,22 @@ func _on_scene_start(scene): var instance #print ("_on_scene_start(",scene,")") match scene: - "Singleplayer": + "Gameplay": instance = Game.instance() add_child (instance) return true "Multiplayer": - instance = Game.instance() - instance.is_multiplayer = true + instance = Lobby.instance() add_child (instance) return true "Options": instance = Options.instance() add_child (instance) return true + "Credits": + instance = Credits.instance() + add_child (instance) + return true "Title": instance = Title_Screen.instance() add_child (instance) @@ -104,5 +111,7 @@ func _on_title_request(): func _on_change_theme(theme): if theme == "light": get_node("Background").set_texture(lightmode) + self.set_theme(light_theme) elif theme == "dark": get_node("Background").set_texture(darkmode) + self.set_theme(dark_theme) diff --git a/godot_ship/script/credits/Credits.gd b/godot_ship/script/credits/Credits.gd new file mode 100644 index 0000000..5fcd343 --- /dev/null +++ b/godot_ship/script/credits/Credits.gd @@ -0,0 +1,21 @@ +extends Control + +var light_theme = load("res://light_theme.tres") +var dark_theme = load("res://dark_theme.tres") + +# Called when the node enters the scene tree for the first time. +func _ready(): + var _errno = 0; + _errno += OptionsController.connect("change_theme", self, "_on_change_theme") + _on_change_theme(OptionsController.get_theme()) + +func _on_Back_pressed(): + AudioBus.emit_signal("button_clicked") + queue_free() + pass # Replace with function body. + +func _on_change_theme(theme): + if theme == "light": + self.set_theme(light_theme) + elif theme == "dark": + self.set_theme(dark_theme) diff --git a/godot_ship/script/debug/debug_menu.gd b/godot_ship/script/debug/debug_menu.gd index 7e36f8e..ef2950c 100644 --- a/godot_ship/script/debug/debug_menu.gd +++ b/godot_ship/script/debug/debug_menu.gd @@ -11,6 +11,9 @@ var menu_velocity = 4 var history : Array = [] var history_pos = 0 +# Controls whether to print to the screen +var echo = true + onready var expression = Expression.new() # helptext: args list and help blurb accessed by function name @@ -38,6 +41,8 @@ var helptext = { "command_getprop": [" prop", "Get the value of property prop\n" ], "command_setprop": [" prop value", "Set the property prop to value.\n" ], + "command_script": [" path", "Load and execute a script at user://scripts/\n" ], + "command_echo": [" on/off", "Controls whether lines should be printed to the screen\n" ], "command_restart": ["", "Kill the current scene tree and plant a new Root.\n" ], "command_exit": ["", "Quits the program.\n" ], @@ -70,10 +75,12 @@ var commands = { ["getprop","get", "g"]: "command_getprop", ["setprop","set", "s"]: "command_setprop", + ["script", "sh"]: "command_script", + ["@echo"]: "command_echo", ["restart", "killall"]: "command_restart", ["exit", "quit"]: "command_exit", - [""]: "command_empty" + ["", "#"]: "command_empty" } #List of all of Godot's builtin types @@ -151,23 +158,29 @@ func _input(event): #traverse history down history_move(+1) -# Signal-processing functions: +# Command-processing functions: # _on_LineEdit_text_entered: process incoming text line # params: line: Line of text entered by user # returns: void func _on_LineEdit_text_entered(line): - if line != "": - history_append(line) emit_signal("clear_in") debug_print_line(line + "\n") var command = line.split(' ', true, 1) - var command_func = parse(command[0]) - if command_func: - call(command_func, command) + if execute_command(command): + history_append(line) else: debug_print_line("dbg: command not found: " + command[0] + "\n") debug_print_line("> ") +# execute_command: execute a line of text as a command +# params: command: partially tokenized PoolStringArray ["command_alias", "parameters ..."] +# returns: name of executed function, or null if nothing executed +func execute_command(command): + var command_func = parse(command[0]) + if command_func: + call(command_func, command) + return command_func + # History_related helper functions: # history_append: add a line of text to the history # params: text: line of text (unparsed command) to add to history @@ -195,7 +208,8 @@ func history_move(rel_pos): # params: string: Text string to print # returns: void func debug_print_line(string): - emit_signal("print_text", string.c_unescape()) + if echo: + emit_signal("print_text", string.c_unescape()) # get_pwn: get the present working node if valid, otherwise cd to root func get_pwn(): @@ -280,7 +294,7 @@ func string_to_variant(string, type): res = null TYPE_BOOL: match string.to_lower(): - "true", "1", "ok": + "true", "1", "ok", "on": res = true _: res = false @@ -369,7 +383,7 @@ func command_restart (_command): # print: prints a message to the in-game debug console func command_print(command): if command.size() > 1: - debug_print_line(command[1] + "\n") + debug_print_line(command[1]) else: debug_print_line("\n") @@ -519,6 +533,46 @@ func command_perf(command): else: debug_print_line(get_usage(command[0])) +# script: run a script from user://scripts/ +func command_script(command): + var script = [] + if (command.size() > 1): + var path = "user://scripts/" + command[1] + var f = File.new() + var err = f.open(path, File.READ) + if err == OK: + # Read the file + while not f.eof_reached(): + script.push_back(f.get_line()) + f.close() + # Save state and turn off echo + var state = {"echo": echo, + "pwn": present_working_node, + "history_pos": history_pos, + "history": history, + "expression": expression} + echo = false + # Execute the script + for cmd in script: + cmd = cmd.split(' ', true, 1) + execute_command(cmd) + # Restore state + echo = state["echo"] + present_working_node = state["pwn"] + history_pos = state["history_pos"] + history = state["history"] + expression = state["expression"] + else: + debug_print_line("File not found: " + command[1] + "\n") + else: + debug_print_line(get_usage(command[0])) + +func command_echo(command): + if command.size() > 1: + echo = string_to_variant(command[1], TYPE_BOOL) + else: + debug_print_line(get_usage(command[0])) + func perf(attribute): if attribute.is_valid_integer(): return Performance.get_monitor(int(attribute)) diff --git a/godot_ship/script/game/Gameplay/Board.gd b/godot_ship/script/game/Gameplay/Board.gd index de71f89..e482ec8 100644 --- a/godot_ship/script/game/Gameplay/Board.gd +++ b/godot_ship/script/game/Gameplay/Board.gd @@ -1,54 +1,107 @@ -extends Node +extends Node2D # Path to Ship class, for instantiating new Ships in code -onready var Ship = load("res://script/game/Gameplay/Ship.gd") +var Ship = preload("res://scenes/Game/Ship.tscn") -var bottom_board # Player board -var top_board # Opponent board -var ships # list of Ships -var ship_count # number of 'active' (un-sunk) ships +# Consts and enums +const NO_SHIP = -1 +enum {MISS = -1, READY = 0, HIT = 1, SUNK = 2, LOST = 3} -# a board is square. This is its side lengths +var bottom_board:Array # Player board +var top_board:Array # Opponent board +var ships = [] # list of Ships +var ship_data = [] # Data used to generate ships +var ship_count = 0 # number of 'active' (un-sunk) ships + +# a board is square. This is its side length var board_len = 10 -# Called when the node enters the scene tree for the first time. -func _ready(): - ships = [] - ship_count = 0 +# The top board must be marked by textures. This is where they are stored: +var sprites = [] + +# Here are where the hit/miss textures are loaded, so that they may be used: +var hit_texture = preload("res://assets/game/Hit.png") +var miss_texture = preload("res://assets/game/Miss.png") + # TODO: What state? -func getState(): +func get_state(): pass +# Evaluate being hit by an opponent +# pos: board position opponent fired at +func hit(pos): + var res = MISS + # Get the ship-metadata for that location + var ship = bottom_board[pos.x][pos.y] + # If the ship's already been hit here, don't bother beating it again + if ship[1] != READY: + return ship[1] + if ship[0] > NO_SHIP: + # Decide whether HIT or SUNK + res = ships[ship[0]].hit(pos) + # If ship sunk, + if res == SUNK: + # remove it from the count + ship_count -= 1 + # If we have no more ships left, we LOST + if ship_count == 0: + res = LOST + # Record the result on the board, and return it + ship[1] = res + return res + +# fire: Store the results of firing on an opponent +# pos: board position fired on +# res: result of firing on the opponent +func fire(pos, res): + if top_board[pos.x][pos.y] == READY: + top_board[pos.x][pos.y] = res + return res + else: + return top_board[pos.x][pos.y] + # Place a ship on the board at board-space coordinates -func placeShip(in_position, in_size, in_orientation): - ships.append(Ship.new(in_position, in_size, in_orientation)) - pass +func place_ship(in_position, in_size, in_orientation, in_variant = 0): + # Save the ship data + ship_data.append([in_position, in_size, in_orientation]) + # Create a new Ship, and give it some data + var ship = Ship.instance() + ship._init(in_position, in_size, in_orientation, in_variant) + # Mark the ship on the board + for pos in ship.get_extent(): + bottom_board[pos.x][pos.y] = [ships.size(), READY] + # Add the ship to the ships array, and keep count + ships.append(ship) + ship_count += 1 + # Add the ship to the scene tree + add_child(ship) -func getBottomBoard(): - pass -func getShipCount(): +func query_bottom(pos): + return bottom_board[pos.x][pos.y] + +func query_top(pos): + return top_board[pos.x][pos.y] + +# Get the number of live ships +func get_ship_count(): return ship_count +# _init: Constructor func _init(): - # Initialize the bottom_board to a 10x10 array - for _row in range(board_len): + # Initialize the bottom_board to a len*len array + for x in board_len: bottom_board.append([]) - for column in bottom_board: - column.resize(10) - # Initialize the top_board to a 10x10 array - for _row in range(board_len): + for y in board_len: + bottom_board[x].append([NO_SHIP, READY]) + # Initialize the top_board to a len*len array + for x in board_len: top_board.append([]) - for column in top_board: - column.resize(board_len) + for y in board_len: + top_board[x].append(READY) # worldspace_to_boardspace: convert a Vector2 in world-space to board-space func worldspace_to_boardspace(coordinate:Vector2): # subtract 36 to get the position relative to (0,0) on the board, and integer divide by 32 return Vector2(int(coordinate.x - 36) >> 5, int(coordinate.y-36) >> 5) - -# Coordinates of ship's center. Ship extends [-(size-1 >> 1), (size/2 >> 1)] -func shiptoboard(ship:Ship): - for i in range (ship.) - pass diff --git a/godot_ship/script/game/Gameplay/Fire.gd b/godot_ship/script/game/Gameplay/Fire.gd index 8ad90f4..3e1eccc 100644 --- a/godot_ship/script/game/Gameplay/Fire.gd +++ b/godot_ship/script/game/Gameplay/Fire.gd @@ -1,30 +1,53 @@ extends Control +# Signal to pass the fire location back to parent +signal fire_at + +var atlas = preload("res://assets/game/HitMissAtlas.png") +var sprites = [] +var hits + # Called when the node enters the scene tree for the first time. func _ready(): + print("Fire: _ready()") + for x in 10: + for y in 10: + texture(Vector2(x,y)) pass # Replace with function body. -# Signal to pass the fire location back to yet-unknown nodes -signal fire_at - - func _on_Fire_pressed(): var crosshair = get_node("Crosshair") - # hides crosshair - crosshair.visible = false - if crosshair.validate_position(crosshair.position) == true: + # Check if the crosshair is in a valid position + if crosshair.validate_position(crosshair.position): var crosshair_pos = crosshair.world_to_board_space(crosshair.position) - # fires at position - print("Fire at position: ", crosshair_pos) - emit_signal("fire_at", crosshair_pos) - # Close the Firing menu - queue_free() - else: - #if invalid position popup appears - var dialog = get_node("FireDialog") - dialog.popup_centered() - pass # Replace with function body. + if(hits[crosshair_pos.x][crosshair_pos.y] == 0): + # fires at position + emit_signal("fire_at", crosshair_pos) + return + #if invalid position popup appears + var dialog = get_node("FireDialog") + dialog.popup_centered() func _on_FireDialog_confirmed(): get_node("Crosshair").visible = true - pass # Replace with function body. + +const OFFSET = Vector2(18, 18) + +func texture(index): + if(hits[index.x][index.y] != 0): + var textureSize = 32 + # It's okay to create a new texture every time, as resources are refcounted + var t = AtlasTexture.new() + t.set_atlas(atlas) + t.margin = Rect2(0, 0, 0, 0) + t.region = Rect2( + 0 if(hits[index.x][index.y] < 0) else textureSize, + 0, + textureSize, + textureSize + ) + # Create a new Sprite to house the texture, or use the existing sprite + var sprite = Sprite.new() + sprite.texture = t + sprite.position = Vector2(index.x, index.y) * textureSize + OFFSET + $board_blue.add_child(sprite) diff --git a/godot_ship/script/game/Gameplay/Game.gd b/godot_ship/script/game/Gameplay/Game.gd index 9507d43..4da38cf 100644 --- a/godot_ship/script/game/Gameplay/Game.gd +++ b/godot_ship/script/game/Gameplay/Game.gd @@ -1,75 +1,204 @@ -extends Node +extends Control -class ShipData: - var Coor: Vector2 - var Length: int - var Orientation: bool #vertical is true, (Trueship = vertical) (Falseship = horizontal) +# warning-ignore-all:unused_signal +# warning-ignore-all:return_value_discarded -# Preloaded assets, to be used later -# TODO: Move Setup into the Player. It's just here, for now, so that it can be tested and the game doesn't appear broken -onready var Setup = preload("res://scenes/Game/Setup.tscn") -# TODO: Move Fire into the Player. See above. -onready var Fire = preload("res://scenes/Game/Fire.tscn") +enum {MISS = -1, READY = 0, HIT = 1, SUNK = 2, LOST = 3} + +# Signals +signal fire # fire(position) +signal hit # hit (state): see Miss/Ready/Hit/Sunk enum in Board.gd) +signal miss +signal loss +signal forfeit + +signal game_ready # Path to Player class, for instantiating new Players in code -onready var Player = preload("res://scenes/Game/Player.tscn") +var Player = preload("res://scenes/Game/Player.tscn") -onready var Victory = preload("res://scenes/Game/Victory.tscn") +var Victory = preload("res://scenes/Game/Victory.tscn") # Array of instances of the Player class; stores the Players -var players # = player1, player2, ... -# turn counter -var turn = 0 -# Variable transporting hit state between players -var hit = false -# Variable tracking whether a game is multiplayer (so that the correct Player type can be spawned) -# TODO: Multiplayer -var is_multiplayer = false +var player +var players_ready = [] + +# Every game is a multiplayer game, even the ones that aren't. +# We're taking the Minecraft approach, baby +var network_id # Called when the node enters the scene tree for the first time. func _ready(): - # TODO: Move Setup into the Player. - var setup = Setup.instance() - setup.connect("game_ready", self, "game_setup") - add_child(setup) - - get_node("ConfirmationDialog").get_ok().text = "Yes" - get_node("ConfirmationDialog").get_cancel().text = "No" -# TODO: Move Setup into the Player. -func game_setup(_ships): - print_debug("Congrats! Setup complete.") - # TODO: Move Fire into the Player. - add_child(Fire.instance()) + get_node("Forfeit Confirmation").get_ok().text = "Yes" + get_node("Forfeit Confirmation").get_cancel().text = "No" + get_node("Forfeit Confirmation").get_ok().rect_min_size.x = 100 + get_node("Forfeit Confirmation").get_cancel().rect_min_size.x = 100 + + if Net.connected: + Net.connect("disconnected", self, "connection_error") + Net.connect("incoming", self, "_on_Net_incoming") + pass + game_setup() + +# Function used to keep track of which players are ready +func player_ready(sender): + print("player_ready(%s), %d" % [sender, players_ready.size()]) + players_ready.append(sender) + if (players_ready.size() >= Net.peer_info.size()): + emit_signal("game_ready") # Member functions: -# game_start: starts the game -func game_start(): +# game_setup: starts the game +sync func game_setup(): + # If there's no server connected, create one + if not Net.connected: + # TODO: Create a fake peer who we can automate, for single-player mode + Net.start_host() + network_id = Net.get_network_id() + player = Player.instance() + player.connect("player_ready", self, "_on_player_ready") + add_child(player) + player.set_up_begin() + yield(self, "game_ready") + if Net.hosting: + state_fire() + +# state_fire: The firing state. Displays fire menu, then notifies opponent. +remote func state_fire(): + var pos = player.turn_start() + if pos is GDScriptFunctionState: + pos = yield(pos, "completed") + rpc("state_check", pos) + +# state_check: The checking state. Branches out to the other states. +# pos: Position which the opponent is trying to fire upon +remote func state_check(pos): + var res = player.hit(pos) + # Tell the opponent + Net.send(0, ["hit", res], Net.REPLY) + rpc("play_hit_sound", res) + match res: + LOST: + # the other player wins + rpc("state_win", player.board.ship_data) + victory_screen(null, false) + SUNK, HIT: + # Hit + rpc("state_fire") + MISS: + # Our turn to fire + state_fire() pass +# state_win: The winning state. If you reach here, someone's won. +# ships: The opponent's ship data, so that their board can be shown +remote func state_win(ships): + victory_screen(ships) + pass + +# play_hit_sound: Play a hit sound depending on the severity of the hit +# value: Lost/Sunk/Hit/Miss +sync func play_hit_sound(value): + match value: + LOST, SUNK: + AudioBus.emit_signal("ship_sunk") + HIT: + AudioBus.emit_signal("ship_hit") + MISS: + AudioBus.emit_signal("ship_missed") + +# hit: Update the local player's board when the opponent fires +# pos: Opponent's target +func hit(pos): + pos = Vector2(pos[0], pos[1]) + var res = player.hit(pos) + return res + +# mark: Update the local player's hit/miss board when opponent replies +func mark(res): + return player.mark(res) + +# _on_Net_incoming: Handle mail. +func _on_Net_incoming(mail): + print ("mail: ", mail, mail.size()) + if mail.size() == 3: + print ("mail: ", mail, mail.size()) + var sender = int(mail[0]) + var message = mail[1] + var mailtype = int(mail[2]) + printt(sender, message, mailtype) + match mailtype: + Net.REPLY: + print ("got REPLY") + # message is a REPLY (return value) + match message[0]: + # on "fire": fire(result) + "fire": + hit(message[1]) + # on "hit": mark(state) + "hit": + mark(message[1]) + "forfeit": + pass + Net.READY: + print ("got READY") + # Add player to the ready array + player_ready(sender) + _: + print ("got ", mailtype) + +# _on_player_ready: Player Ready signal handler +func _on_player_ready(): + print ("_on_player_ready") + Net.send(0, [], Net.READY) + player_ready(Net.get_network_id()) + # victory_screen: display the victory screen -func victory_screen(): - # TODO: Create the victory screen, fill it with knowledge - pass - -# display_turn(): display which turn it is on the screen -func display_turn(): - # TODO: Update the turn display, if there is one? - pass +func victory_screen(ships, winner = true): + if winner: + # Hide the buttons + get_node("Bittons").hide() + # Create a new Victory screen + var victory = Victory.instance() + # Give it the ships received from the opponent + victory.reveal_ships(ships) + # Print a nice message to stdout + print("You won!") + # Add victory to the scene tree + add_child(victory) + else: + end() +# _on_Forfeit_pressed: Handle forfeit button press func _on_Forfeit_pressed(): AudioBus.emit_signal("button_clicked") - get_node("ConfirmationDialog").popup() + get_node("Forfeit Confirmation").popup_centered() -func end(): +# end: end the Game +sync func end(): queue_free() + +func connection_error(): + get_node("Connection Error").popup_centered() + +# _on_Button_button_down: Handle win button press +# TODO: This isn't a thing any more func _on_Button_button_down(): AudioBus.emit_signal("button_clicked") var victory = Victory.instance() add_child(victory) victory.connect("exit_main", self, "end") -func _on_ConfirmationDialog_confirmed(): +func _on_Forfeit_Confirmation_confirmed(): + if Net.connected: + # Send forfeit request to all users + rpc("end") end() + +func _on_Connection_Error_confirmed(): + # End the game + queue_free() + diff --git a/godot_ship/script/game/Gameplay/Player.gd b/godot_ship/script/game/Gameplay/Player.gd index ca89ece..e3cb28e 100644 --- a/godot_ship/script/game/Gameplay/Player.gd +++ b/godot_ship/script/game/Gameplay/Player.gd @@ -1,55 +1,92 @@ extends Node -# Path to Board class, for instantiating new Boards in code -var Board = "res://script/game/Gameplay/Board.gd" +# Emitted when the player is ready +signal player_ready -# Player ID of this player -var pid -# board (an instance of the Board class) -onready var board = Board.new() +# Preloaded assets, to be used later +# Path to Board class, for instantiating new Boards in code +var Board = preload("res://scenes/Game/Board.tscn") +# Path to Setup menu, so the player may set up their Board +var Setup = preload("res://scenes/Game/Setup.tscn") +# Path to Fire menu, so the player may fire on the opponent +var Fire = preload("res://scenes/Game/Fire.tscn") + +# Members +var board # Board +var fire_pos = Vector2(-1,-1) +var target = Vector2(-1,-1) # Called when the node enters the scene tree for the first time. func _ready(): - pass # Replace with function body. + pass + +func set_up_begin(): + var setup = Setup.instance() + setup.connect("board_ready", self, "set_up") + add_child(setup) + board = Board.instance() # Member functions: # hit: Called when opponent fires on us. -# Update internal state, and return bool hit/miss -func hit(): - pass +# Update internal state, and return hit/miss/sunk +func hit(pos): + target = pos + var res = board.hit(pos) + return res + +# mark: Called when the opponent returns hit/miss/sunk +# Update internal state, return ack/nak +func mark(value): + # Mark the position on the top board + return board.fire(fire_pos, value) # place_ship: called when ships are placed. # forwards Ship locations to the Board, so that it may construct a ship -# ship: a list of ship properties {position, orientation, size} -func place_ship(_ship): - pass +# ship: a list of ship properties {position, orientation, size, variant} +func place_ship(pos, size, orientation, variant): + return board.place_ship(pos, size, orientation, variant) -# setUp: set up the board given the placed ship locations -# translates the ship positions in the Setup UI to board-space, then places each ship -# ships: a list of lists of ship properties {{position, orientation, size}, ...} -func set_up(_ships): - pass +# set_up: set up the board given the placed ship locations +# Places each ship onto the board +# ships: a list of lists of ship properties [[position, orientation, size, variant], ...] +func set_up(ships): + # Place all the ships + for i in ships: + place_ship(i[0], i[1], i[2], i[3]) + # Add the board to the tree + add_child(board) + emit_signal("player_ready") -# turnStart: start player's turn +# turn_start: start player's turn # Initiates the player's turn, and blocks until the player selects a location to fire upon # returns: fire = [player id, target coordinates] -func turnStart(): - var player_id = 0 - var target = Vector2(0,0) - return [player_id, target] - pass +func turn_start(): + var fire = Fire.instance() + fire.hits = board.top_board + add_child(fire) + fire_pos = yield(fire, "fire_at") + fire.queue_free() + return fire_pos + # getBoard: returns the player's board # returns: board -func getBoard(): - return board +func board_query(boardname): + match boardname: + "top": + return board.query_top (fire_pos) + "bottom": + return board.quert_bottom (target) # forfeit: ends game for player # Sinks all ships +# Ensures there are no ships left behind func forfeit(): - pass + for i in 10: + for j in 10: + # Hit the board + hit(Vector2(i, j)) # getShipCount: get the number of ships the player has left alive func getShipCount(): - pass - + return board.get_ship_count() diff --git a/godot_ship/script/game/Gameplay/Ship.gd b/godot_ship/script/game/Gameplay/Ship.gd index c6df16d..c154608 100644 --- a/godot_ship/script/game/Gameplay/Ship.gd +++ b/godot_ship/script/game/Gameplay/Ship.gd @@ -1,55 +1,148 @@ -extends Node +extends Node2D # This is the rendered element of a "ship", generated when the game transitions from the placing state to the gameplay state -# Enum denoting the orientation (X is 1, Y is 0) -enum Orientation {X = 1, Y = 0} +# Enum denoting the orientation (X is 0, Y is 1) +enum Orientation {X = 0, Y = 1} +enum {MISS = -1, READY = 0, HIT = 1, SUNK = 2} # Size of ship in board units var size +var health # Coordinates of ship's center. Ship extends [-(size-1 >> 1), (size/2 >> 1)] -var position +var boardposition = Vector2(-1,-1) # Variable storing whether the ship is sunk, for rendering purposes var sunk = false # Orientation of the ship (see enum Orientation) var orientation = Orientation.Y +# array of spots thats been hit +var hits = [] +# Variable storing the positions of each piece of the ship +var extents = [] # Ship sprite metadata -# sprite: the texture atlas containing all ship parts -var atlas # = TODO: figure out how to use one sprite for multiple textures -# texture: the offset into the texture atlas of the first part of the ship. -var texture = 0 +# atlas: the texture atlas containing all ship parts +var atlas = preload("res://assets/game/TextureAtlas.png") +# sprites: the individual sprite nodes which make up the ship +var sprites = [] +# variant: Ships of the same length can have different textures +# variant A is 0, variant B is 1, ... +var variant = 0 # Called when the node enters the scene tree for the first time. func _ready(): pass # Replace with function body. # member functions: -# getSize: get the size of the ship, in board-units (2 for 2-ship, 3 for 3-ship, ...) -func getSize(): - return size - -# getPosition: get the position of the ship's center, in board units -func getPosition(): - return position - -# getOrientation: get the orientation of the ship (see enum Orientation) -func getOrientation(): - return orientation +# getShip(): +func get_ship(): + return [boardposition, size, orientation, variant] # getSunk: get whether the ship is sunk -func getSunk(): +func get_sunk(): return sunk +func hit(pos): + # Assume the opponent missed + var res = MISS + # Find the position in the extents + var index = extents.find(pos) + # If that position exists: + if (index > -1): + # Hit the ship piece at that location + hits[index] = true + res = HIT + # Decrement its health + health -= 1 + # If there's no more health, + if health == 0: + # Sink the ship. + set_sunk() + res = SUNK + # Update graphics + update() + return res + +# update: (re)calculates extents and textures +func update(): + # Calculate the extents (shouldn't change) + extents = get_extent() + # Update the textures + for i in size: + texture(i) + +# returns an array of the positions that the ship occupies +func get_extent(): + var extent = [] + # Find each tile of the ship + for i in size: + # Calculate the x axis position + var x = boardposition.x - (1 - orientation) * ( (size - 1) / 2 - i ) + # Calculate the y axis position + var y = boardposition.y - orientation * ( (size - 1) / 2 - i ) + # Append the point onto the array + extent.push_back(Vector2(x,y)) + return extent + +# Update textures +func texture(index): + var state = 0 # ready + if(hits[index]): + state = 1 # hit + var textureSize = 32 + # It's okay to create a new texture every time, as resources are refcounted + var t = AtlasTexture.new() + t.set_atlas(atlas) + t.margin = Rect2(0, 0, 32, 32) + t.region = Rect2( + (size * variant + index) * textureSize, + #(size * textureSize) * variant + (32 * index), + (size - 2) * textureSize * 2 + (32 * state), + textureSize, + textureSize + ) + # Create a new Sprite to house the texture, or use the existing sprite + var sprite = sprites[index] + if sprite == null: + sprite = Sprite.new() + sprite.texture = t + # This is relative to the ship + # (index + 1) => Index, but 1-based + # (floor((size-1)/2) => Offset from edge to 'center' of ship + # Vector2(0.5,0.5) => Center the texture on the axis of rotation + # 32 => Converts from board-units to pixels + sprite.position = Vector2((index + 1) - (floor((size-1)/2) + 0.5), 0.5) * textureSize + sprite.rotation = 0 + # Add the sprite to the "sprites" group, persistently + sprite.add_to_group("Ship Sprites", true) + # Add the sprite node to an array so it can be modified later, unless it's already there + if not sprites[index]: + sprites[index] = sprite + add_child(sprite) + # setSunk: sink the ship -func setSunk(): +func set_sunk(): sunk = true # _init: called on object initialization. Accepts args if called via .new(...) # in_position: position of the ship, in board-coordinates; (0,0) by default # in_size: size of the ship, in board-units; 2 by default # in_orientation: orientation of the ship (see enum Orientation); vertical by default -func _init(in_position = Vector2(0,0), in_size = 2, in_orientation = Orientation.Y): - position = in_position +# in_variant: Which ship is this? +func _init(in_position = Vector2(0,0), in_size = 0, in_orientation = Orientation.Y, in_variant = 0): + # Set the ship's positions + boardposition = in_position + position = boardposition * 32 + # Set the ship's size and health size = in_size + health = size + # Set the ship's orientation/rotation orientation = in_orientation + rotation = orientation * PI/2 + # Set the ship's variant(A, B, ... ) + variant = in_variant + # Resize the size-based arrays + hits.resize(in_size) + sprites.resize(in_size) + # Update the extents and draw the textures + update() diff --git a/godot_ship/script/game/Setup.gd b/godot_ship/script/game/Setup.gd index 4493c9f..94da823 100644 --- a/godot_ship/script/game/Setup.gd +++ b/godot_ship/script/game/Setup.gd @@ -1,21 +1,28 @@ extends Control -signal game_ready +signal board_ready onready var Ships = ["2Ship", "3ShipA", "3ShipB", "4Ship", "5Ship"] -onready var Victory = preload("res://scenes/Game/Player.tscn") +var light_theme = load("res://light_theme.tres") +var dark_theme = load("res://dark_theme.tres") class ShipData: var Position: Vector2 var Length: int var Orientation: bool # (True = vertical) (False = horizontal) + var Variant: int = 0 # Called when the node enters the scene tree for the first time. func _ready(): # Moves the focus to this menu if find_next_valid_focus(): find_next_valid_focus().grab_focus() - + + get_node("PlaceShipDialog").get_ok().rect_min_size.x = 50 + + var _errno = 0; + _errno += OptionsController.connect("change_theme", self, "_on_change_theme") + _on_change_theme(OptionsController.get_theme()) func _on_Confirm_Placement_pressed(): # Make the button noise @@ -26,25 +33,17 @@ func _on_Confirm_Placement_pressed(): # if this is more than zero, the ship is invalid if get_node(ship).validate_placement(): valid = false - print ("Placement: ", valid) if valid == false: get_node("PlaceShipDialog").popup() else: #Saves the location of ships and length of ship into an array - var shipLocation = [] + var ship_data = [] for ship in Ships: - var location = ShipData.new() - location.Position = get_node(ship).position - location.Length = get_node(ship).get("ship_length") - location.Orientation = get_node(ship).get("vertical") - shipLocation.append(location) - - #print out the array for testing - for x in shipLocation: - print("Ship Length: ", x.Length, ", Ship Orientation: ", x.Orientation, ", Ship Position: ", x.Position) - + ship = get_node(ship) + var data = ship.get_shipdata() + ship_data.append(data) # Return the shipLocation array to those listening on game_ready - emit_signal("game_ready", shipLocation) + emit_signal("board_ready", ship_data) queue_free() return valid # Replace with function body. @@ -53,3 +52,9 @@ func _on_Clear_pressed(): for ship in Ships: get_node(ship).clear() pass # Replace with function body. + +func _on_change_theme(theme): + if theme == "light": + self.set_theme(light_theme) + elif theme == "dark": + self.set_theme(dark_theme) diff --git a/godot_ship/script/game/SetupShip.gd b/godot_ship/script/game/SetupShip.gd index 6d923a2..10373fb 100644 --- a/godot_ship/script/game/SetupShip.gd +++ b/godot_ship/script/game/SetupShip.gd @@ -146,6 +146,12 @@ func ship_stacked(_body): func ship_unstacked(_body): collision = false +func get_shipdata(): + var shipdata = [world_to_board_space(position), ship_length, int(vertical)] + var variant = int(name.match("*B")) + shipdata.push_back(variant) + return shipdata + # Calculate the extents (front to back) of the ship and check whether they're on the board # Returns how many squares to move the ship along its orientation axis (positive or negative) func check_extents(center, orientation, length): diff --git a/godot_ship/script/game/Victory.gd b/godot_ship/script/game/Victory.gd index 1e715f5..dcf0b43 100644 --- a/godot_ship/script/game/Victory.gd +++ b/godot_ship/script/game/Victory.gd @@ -1,30 +1,30 @@ extends Control -signal exit_main -# Declare member variables here. Examples: -# var a = 2 -# var b = "text" - +# Path to Board class, for instantiating new Boards in code +var Board = preload("res://scenes/Game/Board.tscn") # Called when the node enters the scene tree for the first time. func _ready(): pass # Replace with function body. +# Reveal a list of ships +func reveal_ships(ships:Array): + var board = Board.instance() + add_child(board); + for ship in ships: + board.callv("place_ship", ship) # Called every frame. 'delta' is the elapsed time since the previous frame. #func _process(delta): # pass - -# returns player(s) back to main menu -func _on_Button_pressed(): - AudioBus.emit_signal("button_clicked") - #MessageBus.emit_signal("change_scene", "Title") - emit_signal("exit_main") - - func _on_restart_button_down(): AudioBus.emit_signal("button_clicked") - #MessageBus.emit_signal("change_scene", "Multiplayer") - pass # Replace with function body. - + MessageBus.emit_signal("change_scene", "Multiplayer") + MessageBus.emit_signal("kill_scene", "Game") + + +# returns player(s) back to main menu +func _on_exit_to_main_button_down(): + AudioBus.emit_signal("button_clicked") + MessageBus.emit_signal("return_to_title") diff --git a/godot_ship/script/network/Lobby.gd b/godot_ship/script/network/Lobby.gd new file mode 100644 index 0000000..6464d0e --- /dev/null +++ b/godot_ship/script/network/Lobby.gd @@ -0,0 +1,132 @@ +extends Control +# Ignore discarded return values +# warning-ignore-all:return_value_discarded +onready var player_list = find_node("Player List") +onready var ip_address = find_node("IP Address") +onready var name_popup = find_node("Change Name") +onready var game_popup = find_node("Connect to Game") + +# TODO: Write a function to update Player List with the list of attached players + +func _on_peers_updated(): + var connected_peers = "" + for peer in Net.peer_info: + connected_peers += ("%s\n" % Net.peer_info[peer]["name"]) + pass + player_list.text = connected_peers.rsplit("\n", true, 1)[0].c_unescape() + pass + +func set_IP_Address_text(show): + # Print the IP address and port + if show: + ip_address.text = "IP: %s\nPort: %s" % [Net.get_ip(), Net.DEFAULT_PORT] + else: + ip_address.text = "" + +func _ready(): + Net.connect("peers_updated", self, "_on_peers_updated") + Net.connect("disconnected", self, "_on_Net_disconnected") + name_popup.get_node("Name Entry").text = Net.get_hostname() + _on_peers_updated() + pass + +func show_Connected_Options(show, host = false): + # [Hide]/Show the host options + get_node("Lobby Options/Connected Options/Host Options").visible = host + # [Hide]/Show the host and connect buttons + get_node("Lobby Options/Host or Connect").visible = !show + # [Show]/Hide the host options + get_node("Lobby Options/Connected Options").visible = show + +# Buttons +# Host Button: Host a game +# Hides the connect button +func _on_Host_Button_pressed(): + # Make noise + AudioBus.emit_signal("button_clicked") + # Show "Connected Options" + show_Connected_Options(true, true) + # Show the host IP address + set_IP_Address_text(true) + # Begin hosting + Net.start_host() + +# Disconnect +# Disconnect from (or stop hosting) a game +# Shows the host/connect buttons +func _on_Disconnect_Button_pressed(): + # Make noise + AudioBus.emit_signal("button_clicked") + # Disconnect + Net.disconnect_host() + # Hide "Connected Options" + show_Connected_Options(false) + # Hide the host IP address + set_IP_Address_text(false) + +func _on_Start_Game_pressed(): + # If there are enough players for a game + if Net.peer_info.size() >= 2: + # Start the game for all players + rpc("start_game") + pass # Replace with function body. + +func _on_Net_disconnected(): + # Hide "Connected Options" + show_Connected_Options(false) + # Hide the host IP address + set_IP_Address_text(false) + +func _on_Change_Name_Button_pressed(): + # Make noise + AudioBus.emit_signal("button_clicked") + # Show the Change Name dialogue + get_node("Change Name").popup_centered() + +func _on_Connect_Button_pressed(): + # Make noise + AudioBus.emit_signal("button_clicked") + # Show the Connect to Game dialogue + get_node("Connect to Game").popup_centered() + +func _on_Exit_Lobby_pressed(): + # Make noise + AudioBus.emit_signal("button_clicked") + # Disconnect + if Net.connected: + Net.disconnect_host() + # Close Lobby menu + queue_free() + + +func _on_IP_and_Port_Entry_text_entered(text): + # Make noise + AudioBus.emit_signal("button_clicked") + # Split it into IP and Port segments + var ip_port = text.split(":") + # If text exists and contains valid IP address + if ip_port.size() > 0 and ip_port[0].is_valid_ip_address(): + # Connect to host + var connected = Net.callv("connect_host", ip_port) + if connected == OK: + # Show "Connected Options" + show_Connected_Options(true) + # Hide the popup + game_popup.hide() + + +func _on_Name_Entry_text_entered(text): + # Make noise + AudioBus.emit_signal("button_clicked") + # Check the length of the name + if text.length() < 18: + # Change the name + Net.change_name(text) + # Hide the popup + name_popup.hide() + +sync func start_game(): + MessageBus.emit_signal("change_scene", "Gameplay") + queue_free() + + diff --git a/godot_ship/script/network/Net.gd b/godot_ship/script/network/Net.gd new file mode 100644 index 0000000..3eb3a7a --- /dev/null +++ b/godot_ship/script/network/Net.gd @@ -0,0 +1,188 @@ +extends Node + +# Constants +# DEFAULT_PORT: The port GodotShip will listen on/connect to by default +const DEFAULT_PORT = 35879 +# LOCALHOST: loopback address +const LOCALHOST = "127.0.0.1" + +# Enums, used for mail types +# Mail types: +# 0: REQUEST: Message is a request for information +# 1: REPLY: Message is a reply +# 2: READY: Message is "ready" +# 3: ACK: Message is an acknowledgement +enum {REQUEST, REPLY, READY, ACK} + +# Signals +# incoming(mail): Sent when there's an incoming message +signal incoming +# peers_updated(): Sent when the peer list is updated +signal peers_updated +# disconnected(): Sent when unexpectedly disconnected +signal disconnected +# Variables +# inbox: Array: Message history +var inbox = [] +# connected: Boolean: True when in the Connected state +var connected = false +# hosting: Boolean: True when in the Hosting state +var hosting = false +# peer_info: Dictionary: Store peer info in a dictionary, by player ID +var peer_info = {} +# local_info: Dictionary: Store this player's info +var local_info = {"name": ""} + +# Network -- handles server and client setup, and facilitates communication between the two +# receive: Receive a message (called by sender's `send` function) +# mail: The message received from the sender (implicitly JSON-decoded by JSONRPC) +# mail_type: Type of mail (see "Mail Types" enum above) +remote func receive(mail): + print_debug("recv: %s" % mail) + # Unpack the mail + # Uses json parser of unknown stability, how fun + mail = parse_json(mail) + # Get the sender's ID and force letter to be properly addressed + mail[0] = get_tree().get_rpc_sender_id() + # Add the mail to the inbox (so it can be read back later if necessary + inbox.append(mail) + # Sent it off to anything that expects mail + emit_signal("incoming", mail) + +# send: Send a message +# id: Peer ID of the recipient +# mail: Variant of a json-encodable type (non-Object) to send +# mail_type: Type of mail (see "Mail Types" enum above) +func send(id, mail, mail_type = REPLY): + print_debug("send: %d, %s, %d" % [id, mail, mail_type]) + # Make the recipient receive the mail + rpc_id(id, "receive", to_json([-1, mail, mail_type])) + +# Host +# start_host: Host the game +# port: TCP port +# max_players: Largest number of players allowed to connect at a time +func start_host(port = DEFAULT_PORT, max_players = 2): + get_hostname() + peer_info[1] = local_info + # Notify that peer list has updated + emit_signal("peers_updated") + # Create a new NetworkedMultiplayerENet (handles multiplayer communication through ENet) + var peer = NetworkedMultiplayerENet.new() + # Create a server + peer.create_server(port, max_players) + # Add the server to the scene tree + get_tree().network_peer = peer + # Update state + connected = true + hosting = true + +# accept_guests: +# Select whether to accept new guests +func accept_guests(accept:bool): + if hosting: + multiplayer.refuse_new_network_connections = not accept + +# Guest +# connect_host: Connect to a host +func connect_host(ip = LOCALHOST, port = DEFAULT_PORT): + get_hostname() + var peer = NetworkedMultiplayerENet.new() + var ret = peer.create_client(ip, int(port)) + get_tree().network_peer = peer + return ret + +# disconnect_host +func disconnect_host(): + # Send intent to disconnect + rpc("unregister_peer", get_network_id()) + # Set state to disconnected + connected = false + hosting = false + # Attempt disconnection + if get_tree().network_peer: + get_tree().network_peer.close_connection() + # Disconnect + get_tree().network_peer = null + # Clear peer info + peer_info = {} + # Notify that peer list has updated + emit_signal("peers_updated") + +# change_name: Change the local name, and re-register with all peers (including self) +func change_name(name): + # Change name locally + local_info["name"] = name + # If connected, update peers + if connected: + # Send updated info info to all peers + rpc("register_peer", local_info) + +# Helper Functions +# get_hostname: Asks the host machine to provide its hostname, +# and if the peer name isn't set, set it to the hostname +func get_hostname(): + var hostname = [] + # Execute the `hostname` command + var _ret = OS.execute("hostname", [], true, hostname) + # If there's no name set, set it to the hostname + if local_info["name"] == "": + local_info["name"] = hostname[0].split("\n")[0] + return hostname[0].split("\n")[0] + +func get_network_id(): + return get_tree().get_network_unique_id() + +func get_ip(): + return IP.resolve_hostname(get_hostname(), IP.TYPE_IPV4) + pass + +func _ready(): + var _trash + _trash = get_tree().connect("network_peer_connected", self, "_peer_connected" ) + _trash = get_tree().connect("network_peer_disconnected", self, "_peer_disconnected") + _trash = get_tree().connect("connected_to_server", self, "_host_connected" ) + _trash = get_tree().connect("server_disconnected", self, "_host_disconnected") + _trash = get_tree().connect("connection_failed", self, "_connection_fail" ) + +# Signal Handlers +func _peer_connected(id): + # Send peer info to remote peer + rpc_id(id, "register_peer", local_info) + if hosting and peer_info.size() >= 2: + pass + pass + +func _peer_disconnected(id): + # Unregister the peer locally + unregister_peer(id) + if hosting and peer_info.size() < 2: + pass + pass + + +func _host_connected(): + # On connection to the server, you get a global network id + # Save your info at this id + peer_info[get_network_id()] = local_info + # Set state to connected + connected = true + +func _host_disconnected(): + # Ensure host is disconnected + disconnect_host() + # Send disconnection message to listeners + emit_signal("disconnected") + +func _connection_fail(): + # Ensure Net state is clear + disconnect_host() + +sync func register_peer(info): + # Save player information under the sender id's peer info + peer_info[get_tree().get_rpc_sender_id()] = info + emit_signal("peers_updated") + +sync func unregister_peer(id): + peer_info.erase(id) + emit_signal("peers_updated") diff --git a/godot_ship/script/options/Network.gd b/godot_ship/script/options/Network.gd new file mode 100644 index 0000000..0362366 --- /dev/null +++ b/godot_ship/script/options/Network.gd @@ -0,0 +1,5 @@ +extends Node + + +func _ready(): + pass diff --git a/godot_ship/script/options/Options.gd b/godot_ship/script/options/Options.gd index d4e927b..378f334 100644 --- a/godot_ship/script/options/Options.gd +++ b/godot_ship/script/options/Options.gd @@ -5,6 +5,8 @@ onready var music_slider = find_node("Music Slider", true, true) onready var sound_slider = find_node("SFX Slider", true, true) onready var theme_buttons = find_node("Buttons", true, true).get_children() +var light_theme = load("res://light_theme.tres") +var dark_theme = load("res://dark_theme.tres") # Called when the node enters the scene tree for the first time. func _ready(): @@ -13,6 +15,10 @@ func _ready(): master_slider.value = db2linear(OptionsController.get_mas_volume()) music_slider.value = db2linear(OptionsController.get_mus_volume()) sound_slider.value = db2linear(OptionsController.get_sfx_volume()) + + var _errno = 0; + _errno += OptionsController.connect("change_theme", self, "_on_change_theme") + _on_change_theme(OptionsController.get_theme()) func _on_Button_pressed(): AudioBus.emit_signal("button_clicked") @@ -41,3 +47,9 @@ func _on_Light_pressed(): func _on_Dark_pressed(): AudioBus.emit_signal("button_clicked") OptionsController.set_theme("dark") + +func _on_change_theme(theme): + if theme == "light": + self.set_theme(light_theme) + elif theme == "dark": + self.set_theme(dark_theme) diff --git a/godot_ship/script/title screen/Title Screen.gd b/godot_ship/script/title screen/Title Screen.gd index af2512d..0f0fbb8 100644 --- a/godot_ship/script/title screen/Title Screen.gd +++ b/godot_ship/script/title screen/Title Screen.gd @@ -1,12 +1,18 @@ extends Control +var light_theme = load("res://light_theme.tres") +var dark_theme = load("res://dark_theme.tres") + # Called when the node enters the scene tree for the first time. func _ready(): $VBoxContainer/Singleplayer.grab_focus() + var _errno = 0; + _errno += OptionsController.connect("change_theme", self, "_on_change_theme") + _on_change_theme(OptionsController.get_theme()) func _on_Singleplayer_pressed(): AudioBus.emit_signal("button_clicked") - MessageBus.emit_signal("change_scene", "Singleplayer") + MessageBus.emit_signal("change_scene", "Gameplay") queue_free() func _on_Multiplayer_pressed(): @@ -19,7 +25,18 @@ func _on_Options_pressed(): MessageBus.emit_signal("change_scene", "Options") queue_free() +func _on_Credits_pressed(): + AudioBus.emit_signal("button_clicked") + MessageBus.emit_signal("change_scene", "Credits") + queue_free() + func _on_Quit_pressed(): AudioBus.emit_signal("button_clicked") MessageBus.emit_signal("quit") queue_free() + +func _on_change_theme(theme): + if theme == "light": + self.set_theme(light_theme) + elif theme == "dark": + self.set_theme(dark_theme)