Compare commits
5 Commits
400415f8a5
...
3c5c8f1a44
Author | SHA1 | Date | |
---|---|---|---|
3c5c8f1a44 | |||
64befd8ec7 | |||
20cde0a778 | |||
c6763afd62 | |||
6f4f465e37 |
15
3dtree.tscn
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://406wnf58lo7h"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bvyx8hxvka7vu" path="res://tree_test.glb" id="1_pscrb"]
|
||||||
|
[ext_resource type="Material" uid="uid://cqwo7la40rbkn" path="res://foliage/foliage.material" id="2_kkjgf"]
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_us4dp"]
|
||||||
|
albedo_color = Color(0.326727, 0.157357, 0.00483305, 1)
|
||||||
|
|
||||||
|
[node name="tree_test" instance=ExtResource("1_pscrb")]
|
||||||
|
|
||||||
|
[node name="Cube" parent="." index="0"]
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_us4dp")
|
||||||
|
|
||||||
|
[node name="Cube_001" parent="." index="1"]
|
||||||
|
surface_material_override/0 = ExtResource("2_kkjgf")
|
BIN
Assets/Fonts/OpenType (.otf)/Kaph-Italic.otf
Normal file
35
Assets/Fonts/OpenType (.otf)/Kaph-Italic.otf.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://batrfsos6x38m"
|
||||||
|
path="res://.godot/imported/Kaph-Italic.otf-b932c8d71aaa63b737342951ee078e8c.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Fonts/OpenType (.otf)/Kaph-Italic.otf"
|
||||||
|
dest_files=["res://.godot/imported/Kaph-Italic.otf-b932c8d71aaa63b737342951ee078e8c.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
disable_embedded_bitmaps=true
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=4
|
||||||
|
keep_rounding_remainders=true
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
BIN
Assets/Fonts/OpenType (.otf)/Kaph-Regular.otf
Normal file
35
Assets/Fonts/OpenType (.otf)/Kaph-Regular.otf.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://c3hwdjscf2hnk"
|
||||||
|
path="res://.godot/imported/Kaph-Regular.otf-c770fc91b9eb1ce8db6944bab31619b9.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Fonts/OpenType (.otf)/Kaph-Regular.otf"
|
||||||
|
dest_files=["res://.godot/imported/Kaph-Regular.otf-c770fc91b9eb1ce8db6944bab31619b9.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
disable_embedded_bitmaps=true
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=4
|
||||||
|
keep_rounding_remainders=true
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
BIN
Assets/Fonts/TrueType (.ttf)/Kaph-Italic.ttf
Normal file
35
Assets/Fonts/TrueType (.ttf)/Kaph-Italic.ttf.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://cx86thi8mw004"
|
||||||
|
path="res://.godot/imported/Kaph-Italic.ttf-31eaeaf877ae291841853cd19c804cff.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Fonts/TrueType (.ttf)/Kaph-Italic.ttf"
|
||||||
|
dest_files=["res://.godot/imported/Kaph-Italic.ttf-31eaeaf877ae291841853cd19c804cff.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
disable_embedded_bitmaps=true
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=4
|
||||||
|
keep_rounding_remainders=true
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
BIN
Assets/Fonts/TrueType (.ttf)/Kaph-Regular.ttf
Normal file
35
Assets/Fonts/TrueType (.ttf)/Kaph-Regular.ttf.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://nplrjxvauux5"
|
||||||
|
path="res://.godot/imported/Kaph-Regular.ttf-3e4a3d814747db553ebe53d1dc381d87.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Fonts/TrueType (.ttf)/Kaph-Regular.ttf"
|
||||||
|
dest_files=["res://.godot/imported/Kaph-Regular.ttf-3e4a3d814747db553ebe53d1dc381d87.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
disable_embedded_bitmaps=true
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=4
|
||||||
|
keep_rounding_remainders=true
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
BIN
Assets/Fonts/Web Open Font Format (.woff)/Kaph-Italic.woff
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://ybhk4hblpvu2"
|
||||||
|
path="res://.godot/imported/Kaph-Italic.woff-408cfefde00325f89e26cdd96bcff524.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Fonts/Web Open Font Format (.woff)/Kaph-Italic.woff"
|
||||||
|
dest_files=["res://.godot/imported/Kaph-Italic.woff-408cfefde00325f89e26cdd96bcff524.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
disable_embedded_bitmaps=true
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=4
|
||||||
|
keep_rounding_remainders=true
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
BIN
Assets/Fonts/Web Open Font Format (.woff)/Kaph-Italic.woff2
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://e2e3jmoyo8p6"
|
||||||
|
path="res://.godot/imported/Kaph-Italic.woff2-00d7afb1c8d47f57b914cef10b8f58d1.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Fonts/Web Open Font Format (.woff)/Kaph-Italic.woff2"
|
||||||
|
dest_files=["res://.godot/imported/Kaph-Italic.woff2-00d7afb1c8d47f57b914cef10b8f58d1.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
disable_embedded_bitmaps=true
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=4
|
||||||
|
keep_rounding_remainders=true
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
BIN
Assets/Fonts/Web Open Font Format (.woff)/Kaph-Regular.woff
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://cnikb22cx5s51"
|
||||||
|
path="res://.godot/imported/Kaph-Regular.woff-fc271f9b94e07fbf896c6ad9c61a5014.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Fonts/Web Open Font Format (.woff)/Kaph-Regular.woff"
|
||||||
|
dest_files=["res://.godot/imported/Kaph-Regular.woff-fc271f9b94e07fbf896c6ad9c61a5014.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
disable_embedded_bitmaps=true
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=4
|
||||||
|
keep_rounding_remainders=true
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
BIN
Assets/Fonts/Web Open Font Format (.woff)/Kaph-Regular.woff2
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://dskkuioa22v7a"
|
||||||
|
path="res://.godot/imported/Kaph-Regular.woff2-79e390799d1d1d3f7ecd9fa77b6726a8.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Fonts/Web Open Font Format (.woff)/Kaph-Regular.woff2"
|
||||||
|
dest_files=["res://.godot/imported/Kaph-Regular.woff2-79e390799d1d1d3f7ecd9fa77b6726a8.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
disable_embedded_bitmaps=true
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=4
|
||||||
|
keep_rounding_remainders=true
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
BIN
Assets/TextureAtlases/puppyfruit.png
Normal file
After Width: | Height: | Size: 228 KiB |
34
Assets/TextureAtlases/puppyfruit.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://6frn8lcwwehv"
|
||||||
|
path="res://.godot/imported/puppyfruit.png-4202c2b53b1e609128620576392b70df.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/TextureAtlases/puppyfruit.png"
|
||||||
|
dest_files=["res://.godot/imported/puppyfruit.png-4202c2b53b1e609128620576392b70df.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
Assets/Textures/bracket_b_vertical.png
Normal file
After Width: | Height: | Size: 260 B |
34
Assets/Textures/bracket_b_vertical.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://broy365egmulr"
|
||||||
|
path="res://.godot/imported/bracket_b_vertical.png-315545aada90ad95c2805a4864e6e856.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Textures/bracket_b_vertical.png"
|
||||||
|
dest_files=["res://.godot/imported/bracket_b_vertical.png-315545aada90ad95c2805a4864e6e856.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
Assets/Textures/bridge_map.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
35
Assets/Textures/bridge_map.png.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dqrfgw65d0sq8"
|
||||||
|
path.s3tc="res://.godot/imported/bridge_map.png-c72524a9194bfb29ec0afa9089c51f6d.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Textures/bridge_map.png"
|
||||||
|
dest_files=["res://.godot/imported/bridge_map.png-c72524a9194bfb29ec0afa9089c51f6d.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
BIN
Assets/Textures/bridge_map.png.kra
Normal file
BIN
Assets/Textures/crosshair159.png
Normal file
After Width: | Height: | Size: 482 B |
34
Assets/Textures/crosshair159.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bs2mskoyvyehv"
|
||||||
|
path="res://.godot/imported/crosshair159.png-1ca12955e39d6730ad57a007ee3592c9.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Textures/crosshair159.png"
|
||||||
|
dest_files=["res://.godot/imported/crosshair159.png-1ca12955e39d6730ad57a007ee3592c9.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
Assets/Textures/cursor_none.png
Normal file
After Width: | Height: | Size: 409 B |
34
Assets/Textures/cursor_none.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bc2pqfjucp6c3"
|
||||||
|
path="res://.godot/imported/cursor_none.png-8ef0d513f5b0742e2a06563125975c2c.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Textures/cursor_none.png"
|
||||||
|
dest_files=["res://.godot/imported/cursor_none.png-8ef0d513f5b0742e2a06563125975c2c.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
BIN
Assets/Textures/hand_small_point.png
Normal file
After Width: | Height: | Size: 673 B |
34
Assets/Textures/hand_small_point.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://0x80ptif1diq"
|
||||||
|
path="res://.godot/imported/hand_small_point.png-dd650890c01dd4526b4ed41c883582ff.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Textures/hand_small_point.png"
|
||||||
|
dest_files=["res://.godot/imported/hand_small_point.png-dd650890c01dd4526b4ed41c883582ff.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
@ -3,25 +3,26 @@
|
|||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://cb66pspr16scy"
|
uid="uid://cb66pspr16scy"
|
||||||
path="res://.godot/imported/leapfrog_2.png-6ca968bda2f2a97809552ed0bab21743.ctex"
|
path.s3tc="res://.godot/imported/leapfrog_2.png-6ca968bda2f2a97809552ed0bab21743.s3tc.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://Assets/Textures/leapfrog_2.png"
|
source_file="res://Assets/Textures/leapfrog_2.png"
|
||||||
dest_files=["res://.godot/imported/leapfrog_2.png-6ca968bda2f2a97809552ed0bab21743.ctex"]
|
dest_files=["res://.godot/imported/leapfrog_2.png-6ca968bda2f2a97809552ed0bab21743.s3tc.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
compress/mode=0
|
compress/mode=2
|
||||||
compress/high_quality=false
|
compress/high_quality=false
|
||||||
compress/lossy_quality=0.7
|
compress/lossy_quality=0.7
|
||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=true
|
||||||
mipmaps/limit=-1
|
mipmaps/limit=-1
|
||||||
roughness/mode=0
|
roughness/mode=0
|
||||||
roughness/src_normal=""
|
roughness/src_normal=""
|
||||||
@ -31,4 +32,4 @@ process/normal_map_invert_y=false
|
|||||||
process/hdr_as_srgb=false
|
process/hdr_as_srgb=false
|
||||||
process/hdr_clamp_exposure=false
|
process/hdr_clamp_exposure=false
|
||||||
process/size_limit=0
|
process/size_limit=0
|
||||||
detect_3d/compress_to=1
|
detect_3d/compress_to=0
|
||||||
|
BIN
Assets/Textures/prototype.png
Normal file
After Width: | Height: | Size: 16 KiB |
35
Assets/Textures/prototype.png.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://cwykwcaxbrxdi"
|
||||||
|
path.s3tc="res://.godot/imported/prototype.png-2678c44321b389387a13e51fcac78d61.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Textures/prototype.png"
|
||||||
|
dest_files=["res://.godot/imported/prototype.png-2678c44321b389387a13e51fcac78d61.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
BIN
Assets/Textures/tile.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
35
Assets/Textures/tile.png.import
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ds4ccfym5ej7w"
|
||||||
|
path.s3tc="res://.godot/imported/tile.png-f2c836729428dd06f567f8db05c6afb6.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Assets/Textures/tile.png"
|
||||||
|
dest_files=["res://.godot/imported/tile.png-f2c836729428dd06f567f8db05c6afb6.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
BIN
Assets/Textures/tile.png~
Normal file
After Width: | Height: | Size: 3.3 KiB |
@ -1,4 +1,4 @@
|
|||||||
[gd_resource type="Resource" script_class="HeroClass" load_steps=12 format=3 uid="uid://b5pc3frhx467q"]
|
[gd_resource type="Resource" script_class="HeroClass" load_steps=11 format=3 uid="uid://b5pc3frhx467q"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://dq8v5e11rvyi6" path="res://Classes/Engineer/plan.tscn" id="1_2m5d7"]
|
[ext_resource type="PackedScene" uid="uid://dq8v5e11rvyi6" path="res://Classes/Engineer/plan.tscn" id="1_2m5d7"]
|
||||||
[ext_resource type="Script" uid="uid://d40isem6w5d8" path="res://Scripts/Resources/card.gd" id="1_t4fvj"]
|
[ext_resource type="Script" uid="uid://d40isem6w5d8" path="res://Scripts/Resources/card.gd" id="1_t4fvj"]
|
||||||
@ -7,7 +7,6 @@
|
|||||||
[ext_resource type="Resource" uid="uid://cvto66tp7rrst" path="res://Cards/gatling.tres" id="4_ovvb2"]
|
[ext_resource type="Resource" uid="uid://cvto66tp7rrst" path="res://Cards/gatling.tres" id="4_ovvb2"]
|
||||||
[ext_resource type="Resource" uid="uid://cucdevshmdohf" path="res://Cards/overclock_card.tres" id="5_vqkxt"]
|
[ext_resource type="Resource" uid="uid://cucdevshmdohf" path="res://Cards/overclock_card.tres" id="5_vqkxt"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ctkixdue3o7ec" path="res://Classes/Engineer/red_hand.png" id="6_a8dvt"]
|
[ext_resource type="Texture2D" uid="uid://ctkixdue3o7ec" path="res://Classes/Engineer/red_hand.png" id="6_a8dvt"]
|
||||||
[ext_resource type="Resource" uid="uid://b3o112jw3loiu" path="res://Cards/reactor.tres" id="7_1qd1v"]
|
|
||||||
[ext_resource type="Script" uid="uid://dcwtg2gev3uia" path="res://Scripts/Resources/hero_class.gd" id="7_ftkad"]
|
[ext_resource type="Script" uid="uid://dcwtg2gev3uia" path="res://Scripts/Resources/hero_class.gd" id="7_ftkad"]
|
||||||
[ext_resource type="PackedScene" uid="uid://ciagj1hfn4gou" path="res://Classes/Engineer/podium.tscn" id="7_nyup7"]
|
[ext_resource type="PackedScene" uid="uid://ciagj1hfn4gou" path="res://Classes/Engineer/podium.tscn" id="7_nyup7"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d4jd718brpsed" path="res://Classes/Engineer/doe.png" id="8_0o0bw"]
|
[ext_resource type="Texture2D" uid="uid://d4jd718brpsed" path="res://Classes/Engineer/doe.png" id="8_0o0bw"]
|
||||||
@ -17,7 +16,7 @@ script = ExtResource("7_ftkad")
|
|||||||
hero_name = "Engineer"
|
hero_name = "Engineer"
|
||||||
texture = ExtResource("8_0o0bw")
|
texture = ExtResource("8_0o0bw")
|
||||||
hand_texture = ExtResource("6_a8dvt")
|
hand_texture = ExtResource("6_a8dvt")
|
||||||
deck = Array[ExtResource("1_t4fvj")]([ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("3_eml7q"), ExtResource("4_ovvb2"), ExtResource("5_vqkxt"), ExtResource("7_1qd1v")])
|
deck = Array[ExtResource("1_t4fvj")]([ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("3_eml7q"), ExtResource("4_ovvb2"), ExtResource("5_vqkxt")])
|
||||||
faction = 1
|
faction = 1
|
||||||
podium = ExtResource("7_nyup7")
|
podium = ExtResource("7_nyup7")
|
||||||
card_item = ExtResource("1_2m5d7")
|
card_item = ExtResource("1_2m5d7")
|
||||||
|
31
Enemies/Crystalisk/airenemy2.tres
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
[gd_resource type="Resource" script_class="Enemy" load_steps=6 format=3 uid="uid://bffhb5krs5elm"]
|
||||||
|
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b1lwaxw62yp3p" path="res://Assets/Textures/dead_spike.png" id="1_skyfd"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://duywsy7jmh4u" path="res://Assets/Textures/spike.png" id="2_idym2"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cveiaa0y66gln" path="res://Enemies/Crystalisk/crystal_enemy.tscn" id="3_7w5fm"]
|
||||||
|
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="4_x2l2n"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://sybn6bjbj5fh" path="res://Assets/TextureAtlases/spike.tres" id="5_okcvf"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("4_x2l2n")
|
||||||
|
title = "Crystalisk"
|
||||||
|
target_type = 2
|
||||||
|
scene = ExtResource("3_7w5fm")
|
||||||
|
icon = ExtResource("2_idym2")
|
||||||
|
death_sprite = ExtResource("1_skyfd")
|
||||||
|
sprite = ExtResource("5_okcvf")
|
||||||
|
spawn_power = 6
|
||||||
|
health = 120
|
||||||
|
penalty = 7
|
||||||
|
movement_speed = 1.0
|
||||||
|
spawn_cooldown = 1.0
|
||||||
|
common_group = 5
|
||||||
|
common_cost = 2
|
||||||
|
uncommon_group = 10
|
||||||
|
uncommon_cost = 3
|
||||||
|
rare_group = 18
|
||||||
|
rare_cost = 4
|
||||||
|
epic_group = 26
|
||||||
|
epic_cost = 6
|
||||||
|
legendary_group = 42
|
||||||
|
legendary_cost = 8
|
BIN
Enemies/Crystalisk/crystal_enemy.glb
Normal file
1845
Enemies/Crystalisk/crystal_enemy.glb.import
Normal file
BIN
Enemies/Crystalisk/crystal_enemy.png
Normal file
After Width: | Height: | Size: 354 B |
34
Enemies/Crystalisk/crystal_enemy.png.import
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://d01y8kogfuayr"
|
||||||
|
path="res://.godot/imported/crystal_enemy.png-47c4105ce5ff19d6a767c397a2a82c0d.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Enemies/Crystalisk/crystal_enemy.png"
|
||||||
|
dest_files=["res://.godot/imported/crystal_enemy.png-47c4105ce5ff19d6a767c397a2a82c0d.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
58
Enemies/Crystalisk/crystal_enemy.tscn
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
[gd_scene load_steps=7 format=3 uid="uid://cveiaa0y66gln"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bjo2q6vca5qlv" path="res://Worlds/GreenPlanet/Enemies/air_enemy.tscn" id="1_aormu"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://o6whohcbalui" path="res://Enemies/Crystalisk/crystal_enemy.glb" id="2_myjng"]
|
||||||
|
[ext_resource type="Script" uid="uid://cummt2be3r1gq" path="res://Scripts/hitbox.gd" id="3_myjng"]
|
||||||
|
|
||||||
|
[sub_resource type="ViewportTexture" id="ViewportTexture_c5uwa"]
|
||||||
|
viewport_path = NodePath("SubViewport")
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_c5uwa"]
|
||||||
|
radius = 0.332871
|
||||||
|
height = 1.415
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_d7aub"]
|
||||||
|
radius = 0.133503
|
||||||
|
height = 0.56
|
||||||
|
|
||||||
|
[node name="Dog" instance=ExtResource("1_aormu")]
|
||||||
|
|
||||||
|
[node name="Sprite3D" parent="." index="1"]
|
||||||
|
texture = SubResource("ViewportTexture_c5uwa")
|
||||||
|
|
||||||
|
[node name="crystal_enemy" parent="." index="7" instance=ExtResource("2_myjng")]
|
||||||
|
|
||||||
|
[node name="RemoteTransform3D" type="RemoteTransform3D" parent="crystal_enemy/Cube_001" index="0"]
|
||||||
|
remote_path = NodePath("../../../MiniHitbox2")
|
||||||
|
|
||||||
|
[node name="RemoteTransform3D" type="RemoteTransform3D" parent="crystal_enemy/Cube_002" index="0"]
|
||||||
|
remote_path = NodePath("../../../MiniHitbox")
|
||||||
|
|
||||||
|
[node name="AnimationPlayer" parent="crystal_enemy" index="3"]
|
||||||
|
autoplay = "Spin"
|
||||||
|
speed_scale = 2.0
|
||||||
|
|
||||||
|
[node name="MainHitbox" type="CollisionShape3D" parent="." index="8"]
|
||||||
|
shape = SubResource("CapsuleShape3D_c5uwa")
|
||||||
|
script = ExtResource("3_myjng")
|
||||||
|
metadata/_custom_type_script = "uid://cummt2be3r1gq"
|
||||||
|
|
||||||
|
[node name="MiniHitbox" type="CollisionShape3D" parent="." index="9"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.601335, 0.59523, 0)
|
||||||
|
shape = SubResource("CapsuleShape3D_d7aub")
|
||||||
|
script = ExtResource("3_myjng")
|
||||||
|
critical_zone = true
|
||||||
|
metadata/_custom_type_script = "uid://cummt2be3r1gq"
|
||||||
|
|
||||||
|
[node name="MiniHitbox2" type="CollisionShape3D" parent="." index="10"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.599804, -0.600394, 0)
|
||||||
|
shape = SubResource("CapsuleShape3D_d7aub")
|
||||||
|
script = ExtResource("3_myjng")
|
||||||
|
critical_zone = true
|
||||||
|
metadata/_custom_type_script = "uid://cummt2be3r1gq"
|
||||||
|
|
||||||
|
[connection signal="took_damage" from="MainHitbox" to="Health" method="take_damage"]
|
||||||
|
[connection signal="took_damage" from="MiniHitbox" to="Health" method="take_damage"]
|
||||||
|
[connection signal="took_damage" from="MiniHitbox2" to="Health" method="take_damage"]
|
||||||
|
|
||||||
|
[editable path="crystal_enemy"]
|
13
Enemies/Crystalisk/crystal_enemy_mat.tres
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://dylmoyx1tasat"]
|
||||||
|
|
||||||
|
[ext_resource type="Shader" uid="uid://c5bffujq0l70k" path="res://jitter.gdshader" id="1_4cwdh"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://d01y8kogfuayr" path="res://Enemies/Crystalisk/crystal_enemy.png" id="2_l5awy"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
render_priority = 0
|
||||||
|
shader = ExtResource("1_4cwdh")
|
||||||
|
shader_parameter/affine_mapping = true
|
||||||
|
shader_parameter/albedo = ExtResource("2_l5awy")
|
||||||
|
shader_parameter/alpha_scissor = 0.5
|
||||||
|
shader_parameter/jitter = 0.25
|
||||||
|
shader_parameter/resolution = Vector2i(320, 240)
|
@ -1,8 +1,9 @@
|
|||||||
[gd_resource type="Resource" script_class="Enemy" load_steps=6 format=3 uid="uid://8eba45hql7bo"]
|
[gd_resource type="Resource" script_class="Enemy" load_steps=7 format=3 uid="uid://8eba45hql7bo"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_ivs7a"]
|
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_ivs7a"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cdnhe2mi5c5ln" path="res://Assets/Textures/dead_eye_dog.png" id="1_r8gpy"]
|
[ext_resource type="Texture2D" uid="uid://cdnhe2mi5c5ln" path="res://Assets/Textures/dead_eye_dog.png" id="1_r8gpy"]
|
||||||
[ext_resource type="Texture2D" uid="uid://g00wwrlxxdc5" path="res://Assets/Textures/icon_eye_dog.png" id="2_tyyee"]
|
[ext_resource type="Texture2D" uid="uid://g00wwrlxxdc5" path="res://Assets/Textures/icon_eye_dog.png" id="2_tyyee"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bvq6tbkuv2mfp" path="res://Enemies/EyeDog/eye_dog.tscn" id="3_tyyee"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dj13g1w14mekw" path="res://Assets/Textures/eye_dog.png" id="4_7ypa6"]
|
[ext_resource type="Texture2D" uid="uid://dj13g1w14mekw" path="res://Assets/Textures/eye_dog.png" id="4_7ypa6"]
|
||||||
|
|
||||||
[sub_resource type="AtlasTexture" id="AtlasTexture_n6kdu"]
|
[sub_resource type="AtlasTexture" id="AtlasTexture_n6kdu"]
|
||||||
@ -15,6 +16,7 @@ resource_local_to_scene = true
|
|||||||
script = ExtResource("1_ivs7a")
|
script = ExtResource("1_ivs7a")
|
||||||
title = "dog"
|
title = "dog"
|
||||||
target_type = 1
|
target_type = 1
|
||||||
|
scene = ExtResource("3_tyyee")
|
||||||
icon = ExtResource("2_tyyee")
|
icon = ExtResource("2_tyyee")
|
||||||
death_sprite = ExtResource("1_r8gpy")
|
death_sprite = ExtResource("1_r8gpy")
|
||||||
sprite = SubResource("AtlasTexture_n6kdu")
|
sprite = SubResource("AtlasTexture_n6kdu")
|
||||||
@ -23,13 +25,13 @@ health = 180
|
|||||||
penalty = 10
|
penalty = 10
|
||||||
movement_speed = 1.2
|
movement_speed = 1.2
|
||||||
spawn_cooldown = 1.2
|
spawn_cooldown = 1.2
|
||||||
common_group = 4
|
common_group = 8
|
||||||
common_cost = 1
|
common_cost = 1
|
||||||
uncommon_group = 6
|
uncommon_group = 12
|
||||||
uncommon_cost = 2
|
uncommon_cost = 2
|
||||||
rare_group = 8
|
rare_group = 18
|
||||||
rare_cost = 3
|
rare_cost = 3
|
||||||
epic_group = 10
|
epic_group = 26
|
||||||
epic_cost = 4
|
epic_cost = 5
|
||||||
legendary_group = 12
|
legendary_group = 34
|
||||||
legendary_cost = 5
|
legendary_cost = 6
|
100
Enemies/EyeDog/eye_dog.tscn
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
[gd_scene load_steps=14 format=3 uid="uid://bvq6tbkuv2mfp"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://ejqql2660u6h" path="res://Worlds/GreenPlanet/Enemies/enemy_controller.gd" id="1_1dh2f"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://canrxnpxcugc2" path="res://Scenes/corpse.tscn" id="2_1dh2f"]
|
||||||
|
[ext_resource type="Script" uid="uid://bamhci3kawuyt" path="res://Scripts/health.gd" id="2_bckix"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cqtew0t8sttpm" path="res://Scenes/damage_particle.tscn" id="3_wnwjl"]
|
||||||
|
[ext_resource type="Script" uid="uid://cummt2be3r1gq" path="res://Scripts/hitbox.gd" id="6_3v8fr"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://b1fn60m6xfcsq" path="res://Assets/Textures/minimap_enemy.png" id="7_bkkhh"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://hjq3nrnumklp" path="res://Scenes/health_bar.tscn" id="8_k2835"]
|
||||||
|
[ext_resource type="Script" uid="uid://b62xnsbki8axa" path="res://Scripts/EnemyAI/pathing_controller.gd" id="9_t4oco"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dlhx6r23m5ceg" path="res://Enemies/EyeDog/eyedog.glb" id="10_h25mw"]
|
||||||
|
[ext_resource type="Script" uid="uid://cojjgevmbhwal" path="res://Scripts/status_effector.gd" id="11_kpdsm"]
|
||||||
|
|
||||||
|
[sub_resource type="SphereShape3D" id="SphereShape3D_cavbv"]
|
||||||
|
radius = 0.42
|
||||||
|
|
||||||
|
[sub_resource type="SphereShape3D" id="SphereShape3D_h25mw"]
|
||||||
|
radius = 0.151085
|
||||||
|
|
||||||
|
[sub_resource type="ViewportTexture" id="ViewportTexture_1kwxq"]
|
||||||
|
viewport_path = NodePath("SubViewport")
|
||||||
|
|
||||||
|
[node name="Node3D" type="CharacterBody3D" node_paths=PackedStringArray("status_manager", "movement_controller", "health", "d_n") groups=["Enemies"]]
|
||||||
|
collision_layer = 4
|
||||||
|
collision_mask = 0
|
||||||
|
script = ExtResource("1_1dh2f")
|
||||||
|
status_manager = NodePath("StatusEffector")
|
||||||
|
movement_controller = NodePath("PathingController")
|
||||||
|
health = NodePath("Health")
|
||||||
|
d_n = NodePath("Node3D")
|
||||||
|
corpse_scene = ExtResource("2_1dh2f")
|
||||||
|
metadata/_custom_type_script = "uid://ejqql2660u6h"
|
||||||
|
|
||||||
|
[node name="Health" type="Node" parent="."]
|
||||||
|
script = ExtResource("2_bckix")
|
||||||
|
damage_particle_scene = ExtResource("3_wnwjl")
|
||||||
|
|
||||||
|
[node name="Hitbox" type="CollisionShape3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.33811, 0.0832841)
|
||||||
|
shape = SubResource("SphereShape3D_cavbv")
|
||||||
|
script = ExtResource("6_3v8fr")
|
||||||
|
metadata/_custom_type_script = "uid://cummt2be3r1gq"
|
||||||
|
|
||||||
|
[node name="Hitbox2" type="CollisionShape3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.601201, -0.436369)
|
||||||
|
shape = SubResource("SphereShape3D_h25mw")
|
||||||
|
script = ExtResource("6_3v8fr")
|
||||||
|
critical_zone = true
|
||||||
|
metadata/_custom_type_script = "uid://cummt2be3r1gq"
|
||||||
|
|
||||||
|
[node name="HealthBar" type="Sprite3D" parent="."]
|
||||||
|
transform = Transform3D(0.2, 0, 0, 0, 0.2, 0, 0, 0, 0.2, 0, 1.20821, 0)
|
||||||
|
sorting_offset = 1.0
|
||||||
|
pixel_size = 0.02
|
||||||
|
billboard = 1
|
||||||
|
texture_filter = 0
|
||||||
|
texture = SubResource("ViewportTexture_1kwxq")
|
||||||
|
|
||||||
|
[node name="MinimapIcon" type="Sprite3D" parent="."]
|
||||||
|
transform = Transform3D(2, 0, 0, 0, -8.74228e-08, 2, 0, -2, -8.74228e-08, 0, 1.40824, 0)
|
||||||
|
layers = 4
|
||||||
|
texture_filter = 0
|
||||||
|
texture = ExtResource("7_bkkhh")
|
||||||
|
|
||||||
|
[node name="SubViewport" type="SubViewport" parent="."]
|
||||||
|
transparent_bg = true
|
||||||
|
size = Vector2i(200, 55)
|
||||||
|
render_target_update_mode = 4
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="SubViewport"]
|
||||||
|
anchors_preset = 10
|
||||||
|
anchor_right = 1.0
|
||||||
|
offset_bottom = 32.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="HealthBar" parent="SubViewport" instance=ExtResource("8_k2835")]
|
||||||
|
visible = false
|
||||||
|
offset_top = 36.0
|
||||||
|
offset_bottom = 236.0
|
||||||
|
|
||||||
|
[node name="PathingController" type="Node" parent="." node_paths=PackedStringArray("character")]
|
||||||
|
script = ExtResource("9_t4oco")
|
||||||
|
character = NodePath("..")
|
||||||
|
|
||||||
|
[node name="StatusEffector" type="Node" parent="." node_paths=PackedStringArray("sprite_container")]
|
||||||
|
script = ExtResource("11_kpdsm")
|
||||||
|
sprite_container = NodePath("../SubViewport/HBoxContainer")
|
||||||
|
metadata/_custom_type_script = "uid://cojjgevmbhwal"
|
||||||
|
|
||||||
|
[node name="Node3D" type="Node3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.39813, 0)
|
||||||
|
|
||||||
|
[node name="eyedog" parent="." instance=ExtResource("10_h25mw")]
|
||||||
|
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0.3764, 0)
|
||||||
|
|
||||||
|
[connection signal="health_changed" from="Health" to="SubViewport/HealthBar" method="on_health_changed"]
|
||||||
|
[connection signal="health_depleted" from="Health" to="." method="die"]
|
||||||
|
[connection signal="took_damage" from="Hitbox" to="Health" method="take_damage"]
|
||||||
|
[connection signal="took_damage" from="Hitbox2" to="Health" method="take_damage"]
|
BIN
Enemies/EyeDog/eyedog.glb
Normal file
44
Enemies/EyeDog/eyedog.glb.import
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="scene"
|
||||||
|
importer_version=1
|
||||||
|
type="PackedScene"
|
||||||
|
uid="uid://dlhx6r23m5ceg"
|
||||||
|
path="res://.godot/imported/eyedog.glb-066d1d46e7943baa72fec506b08447f4.scn"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Enemies/EyeDog/eyedog.glb"
|
||||||
|
dest_files=["res://.godot/imported/eyedog.glb-066d1d46e7943baa72fec506b08447f4.scn"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
nodes/root_type=""
|
||||||
|
nodes/root_name=""
|
||||||
|
nodes/apply_root_scale=true
|
||||||
|
nodes/root_scale=0.08
|
||||||
|
nodes/import_as_skeleton_bones=false
|
||||||
|
nodes/use_node_type_suffixes=true
|
||||||
|
meshes/ensure_tangents=true
|
||||||
|
meshes/generate_lods=true
|
||||||
|
meshes/create_shadow_meshes=true
|
||||||
|
meshes/light_baking=1
|
||||||
|
meshes/lightmap_texel_size=0.2
|
||||||
|
meshes/force_disable_compression=false
|
||||||
|
skins/use_named_skins=true
|
||||||
|
animation/import=true
|
||||||
|
animation/fps=30
|
||||||
|
animation/trimming=false
|
||||||
|
animation/remove_immutable_tracks=true
|
||||||
|
animation/import_rest_as_RESET=false
|
||||||
|
import_script/path=""
|
||||||
|
_subresources={
|
||||||
|
"materials": {
|
||||||
|
"Material": {
|
||||||
|
"use_external/enabled": true,
|
||||||
|
"use_external/path": "uid://bo82o88d7vo1x"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gltf/naming_version=1
|
||||||
|
gltf/embedded_image_handling=1
|
BIN
Enemies/EyeDog/eyedog_eyedog_tex.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
38
Enemies/EyeDog/eyedog_eyedog_tex.png.import
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://wx4d2upch81n"
|
||||||
|
path.s3tc="res://.godot/imported/eyedog_eyedog_tex.png-1f14344e8bf95fbf8ece2e5fc948c9ad.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
generator_parameters={
|
||||||
|
"md5": "27dfa54e4c46b8fd6e6f12450e4ca070"
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://Enemies/EyeDog/eyedog_eyedog_tex.png"
|
||||||
|
dest_files=["res://.godot/imported/eyedog_eyedog_tex.png-1f14344e8bf95fbf8ece2e5fc948c9ad.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
13
Enemies/EyeDog/psx_model_material.tres
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://bo82o88d7vo1x"]
|
||||||
|
|
||||||
|
[ext_resource type="Shader" uid="uid://c5bffujq0l70k" path="res://jitter.gdshader" id="1_crvh7"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://wx4d2upch81n" path="res://Enemies/EyeDog/eyedog_eyedog_tex.png" id="2_j3hec"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
render_priority = 0
|
||||||
|
shader = ExtResource("1_crvh7")
|
||||||
|
shader_parameter/affine_mapping = true
|
||||||
|
shader_parameter/albedo = ExtResource("2_j3hec")
|
||||||
|
shader_parameter/alpha_scissor = 0.5
|
||||||
|
shader_parameter/jitter = 0.25
|
||||||
|
shader_parameter/resolution = Vector2i(320, 240)
|
@ -1,34 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://dngl8iot8uqet"
|
|
||||||
path="res://.godot/imported/xbox_stick_r_left.png-396824eb8a716515d7b92ff5c3e85c2b.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://KennyControllerPrompts/Xbox/xbox_stick_r_left.png"
|
|
||||||
dest_files=["res://.godot/imported/xbox_stick_r_left.png-396824eb8a716515d7b92ff5c3e85c2b.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
190
PCs/PathEditTool/path_edit_tool.gd
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
class_name PathEditTool extends Node3D
|
||||||
|
|
||||||
|
@export var hero: Hero
|
||||||
|
@export var inventory: Inventory
|
||||||
|
@export var ray: RayCast3D
|
||||||
|
@export var wall_preview: TowerBase
|
||||||
|
@export var progress_bar: TextureProgressBar
|
||||||
|
|
||||||
|
var enabled: bool = true
|
||||||
|
var level: Level
|
||||||
|
var point: FlowNode
|
||||||
|
var obstacle_last_point: int = -1
|
||||||
|
var valid_point: bool = false # a point is valid if the path would still be traversable overall if this point was made untraversable
|
||||||
|
var tower_preview: Tower
|
||||||
|
var ray_collider: Object
|
||||||
|
var ray_point: Vector3
|
||||||
|
var last_point: FlowNode
|
||||||
|
var last_tower_base: TowerBase
|
||||||
|
|
||||||
|
var interact_key_held: bool = false
|
||||||
|
var interacted_once: bool = false
|
||||||
|
var interact_held_time: float = 0.0
|
||||||
|
var interact_hold_time: float = 0.4
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
var c: Color = Color.GREEN
|
||||||
|
c.a = 0.8
|
||||||
|
wall_preview.set_color(c)
|
||||||
|
wall_preview.set_float(0.0)
|
||||||
|
wall_preview.toggle_collision()
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
if !enabled:
|
||||||
|
reset()
|
||||||
|
return
|
||||||
|
|
||||||
|
if interact_key_held:
|
||||||
|
if !interacted_once:
|
||||||
|
if valid_point and hero.currency >= Data.wall_cost and ray_collider and point.buildable:
|
||||||
|
interact_held_time += delta
|
||||||
|
set_progress_percent(interact_held_time / interact_hold_time)
|
||||||
|
wall_preview.set_float(interact_held_time / interact_hold_time)
|
||||||
|
if interact_held_time >= interact_hold_time:
|
||||||
|
set_progress_percent(0)
|
||||||
|
interacted_once = true
|
||||||
|
build_wall()
|
||||||
|
elif ray_collider is TowerBase:
|
||||||
|
interact_held_time += delta
|
||||||
|
set_progress_percent(interact_held_time / interact_hold_time)
|
||||||
|
if interact_held_time >= interact_hold_time:
|
||||||
|
set_progress_percent(0)
|
||||||
|
interacted_once = true
|
||||||
|
refund_wall(ray_collider)
|
||||||
|
else:
|
||||||
|
interact_held_time = 0.0
|
||||||
|
interacted_once = false
|
||||||
|
set_progress_percent(0)
|
||||||
|
wall_preview.set_float(0.0)
|
||||||
|
|
||||||
|
if !interacted_once and ray.is_colliding():
|
||||||
|
#if statement makes sure once the building animation has started then
|
||||||
|
#the position the wall builds in is already decided and moving the mouse
|
||||||
|
#around isnt going to make the resulting
|
||||||
|
#wall teleport to the new mouse location
|
||||||
|
if !interact_key_held:
|
||||||
|
wall_preview.set_visible(true)
|
||||||
|
if is_instance_valid(ray_collider) and ray_collider is TowerBase:
|
||||||
|
level.walls[ray_collider.point].set_float(1.0)
|
||||||
|
ray_collider = ray.get_collider()
|
||||||
|
ray_point = ray.get_collision_point()
|
||||||
|
|
||||||
|
if ray_collider is TowerBase:
|
||||||
|
process_looking_at_tower()
|
||||||
|
elif level:
|
||||||
|
process_looking_at_level()
|
||||||
|
elif !interact_key_held:
|
||||||
|
reset()
|
||||||
|
if !valid_point:
|
||||||
|
wall_preview.set_visible(false)
|
||||||
|
if point:
|
||||||
|
wall_preview.global_position = point.global_position
|
||||||
|
wall_preview.global_rotation = Vector3.ZERO
|
||||||
|
|
||||||
|
|
||||||
|
func reset() -> void:
|
||||||
|
if is_instance_valid(ray_collider) and ray_collider is TowerBase and level.walls.has(ray_collider.point):
|
||||||
|
level.walls[ray_collider.point].set_float(1.0)
|
||||||
|
ray_collider = null
|
||||||
|
delete_tower_preview()
|
||||||
|
wall_preview.set_visible(false)
|
||||||
|
clear_previous_point()
|
||||||
|
last_point = null
|
||||||
|
|
||||||
|
|
||||||
|
func process_looking_at_level() -> void:
|
||||||
|
if tower_preview:
|
||||||
|
delete_tower_preview()
|
||||||
|
point = level.flow_field.get_closest_buildable_point(ray_point)
|
||||||
|
if level.walls.has(point) or !point.buildable or hero.currency < Data.wall_cost:
|
||||||
|
wall_preview.set_visible(false)
|
||||||
|
valid_point = false
|
||||||
|
clear_previous_point()
|
||||||
|
last_point = point
|
||||||
|
else:
|
||||||
|
if last_point != point:
|
||||||
|
clear_previous_point()
|
||||||
|
last_point = point
|
||||||
|
if !level.walls.has(point) and level.flow_field.traversable_after_blocking_point(point):
|
||||||
|
level.flow_field.toggle_traversable(point)
|
||||||
|
wall_preview.set_float(0.0)
|
||||||
|
valid_point = true
|
||||||
|
else:
|
||||||
|
valid_point = false
|
||||||
|
|
||||||
|
|
||||||
|
func clear_previous_point() -> void:
|
||||||
|
if last_point and !level.walls.has(last_point) and !last_point.traversable:
|
||||||
|
level.flow_field.toggle_traversable(last_point)
|
||||||
|
|
||||||
|
|
||||||
|
func process_looking_at_tower() -> void:
|
||||||
|
valid_point = false
|
||||||
|
point = ray_collider.point
|
||||||
|
if last_point != point:
|
||||||
|
clear_previous_point()
|
||||||
|
|
||||||
|
if tower_preview:
|
||||||
|
delete_tower_preview()
|
||||||
|
wall_preview.set_visible(false)
|
||||||
|
ray_collider.set_color(Color.RED)
|
||||||
|
ray_collider.set_float(0.0)
|
||||||
|
if inventory.contents.size() > 0 and !ray_collider.has_card:
|
||||||
|
if ray_collider != last_tower_base or inventory.selected_item != inventory.contents.keys()[hero.inventory_selected_index]:
|
||||||
|
spawn_tower_preview()
|
||||||
|
|
||||||
|
|
||||||
|
func spawn_tower_preview() -> void:
|
||||||
|
delete_tower_preview()
|
||||||
|
last_tower_base = ray_collider
|
||||||
|
var card: Card = inventory.contents.keys()[hero.inventory_selected_index]
|
||||||
|
tower_preview = card.turret_scene.instantiate() as Tower
|
||||||
|
tower_preview.stats = card.tower_stats
|
||||||
|
tower_preview.position = Vector3.UP
|
||||||
|
tower_preview.preview_range(true)
|
||||||
|
ray_collider.add_child(tower_preview)
|
||||||
|
|
||||||
|
|
||||||
|
func delete_tower_preview() -> void:
|
||||||
|
last_tower_base = null
|
||||||
|
if is_instance_valid(tower_preview):
|
||||||
|
tower_preview.queue_free()
|
||||||
|
tower_preview = null
|
||||||
|
|
||||||
|
|
||||||
|
func interact() -> void:
|
||||||
|
if ray_collider is TowerBase:
|
||||||
|
var tower_base: TowerBase = ray_collider as TowerBase
|
||||||
|
put_card_in_tower_base(tower_base)
|
||||||
|
|
||||||
|
|
||||||
|
func build_wall() -> void:
|
||||||
|
if point and valid_point and hero.currency >= Data.wall_cost:
|
||||||
|
hero.currency -= Data.wall_cost
|
||||||
|
level.set_wall(point, multiplayer.get_unique_id())
|
||||||
|
wall_preview.visible = false
|
||||||
|
|
||||||
|
|
||||||
|
func refund_wall(wall: TowerBase) -> void:
|
||||||
|
if !is_instance_valid(wall):
|
||||||
|
return
|
||||||
|
if wall.has_card:
|
||||||
|
wall.remove_card()
|
||||||
|
level.remove_wall(wall.point)
|
||||||
|
|
||||||
|
|
||||||
|
func put_card_in_tower_base(tower_base: TowerBase) -> void:
|
||||||
|
if tower_base.has_card:
|
||||||
|
tower_base.remove_card()
|
||||||
|
elif inventory.size > 0:
|
||||||
|
var card: Card = inventory.remove_at(hero.inventory_selected_index)
|
||||||
|
if !inventory.contents.has(card):
|
||||||
|
hero.decrement_selected()
|
||||||
|
tower_base.add_card(card, multiplayer.get_unique_id())
|
||||||
|
hero.place_card_audio.play()
|
||||||
|
|
||||||
|
|
||||||
|
func set_progress_percent(value: float) -> void:
|
||||||
|
progress_bar.value = progress_bar.max_value * value
|
@ -1,26 +1,20 @@
|
|||||||
[gd_scene load_steps=5 format=3 uid="uid://dqt1ggtkpkuhs"]
|
[gd_scene load_steps=4 format=3 uid="uid://dqt1ggtkpkuhs"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ckm02cx0ai624" path="res://Scripts/edit_tool.gd" id="1_yf8lt"]
|
[ext_resource type="Script" uid="uid://ckm02cx0ai624" path="res://PCs/PathEditTool/path_edit_tool.gd" id="1_l8cck"]
|
||||||
[ext_resource type="PackedScene" uid="uid://ddbbwx0yy16lh" path="res://Scenes/TowerBase/tower_base.tscn" id="2_r3632"]
|
[ext_resource type="PackedScene" uid="uid://ddbbwx0yy16lh" path="res://Scenes/TowerBase/tower_base.tscn" id="2_pjtpe"]
|
||||||
[ext_resource type="Texture2D" uid="uid://gh4yvnerf1f5" path="res://Assets/Textures/radial.png" id="3_a323w"]
|
[ext_resource type="Texture2D" uid="uid://gh4yvnerf1f5" path="res://Assets/Textures/radial.png" id="3_fs118"]
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_36ot1"]
|
[node name="PathEditTool" type="Node3D" node_paths=PackedStringArray("ray", "wall_preview", "progress_bar")]
|
||||||
transparency = 1
|
script = ExtResource("1_l8cck")
|
||||||
depth_draw_mode = 1
|
|
||||||
|
|
||||||
[node name="EditTool" type="Node3D" node_paths=PackedStringArray("ray", "wall_preview", "progress_bar")]
|
|
||||||
script = ExtResource("1_yf8lt")
|
|
||||||
ray = NodePath("RayCast3D")
|
ray = NodePath("RayCast3D")
|
||||||
wall_preview = NodePath("WallPreview")
|
wall_preview = NodePath("WallPreview")
|
||||||
build_preview_material = SubResource("StandardMaterial3D_36ot1")
|
|
||||||
progress_bar = NodePath("ProgressBar")
|
progress_bar = NodePath("ProgressBar")
|
||||||
|
|
||||||
[node name="RayCast3D" type="RayCast3D" parent="."]
|
[node name="RayCast3D" type="RayCast3D" parent="."]
|
||||||
target_position = Vector3(0, 0, -20)
|
target_position = Vector3(0, 0, -20)
|
||||||
collision_mask = 25
|
collision_mask = 25
|
||||||
|
|
||||||
[node name="WallPreview" parent="." instance=ExtResource("2_r3632")]
|
[node name="WallPreview" parent="." instance=ExtResource("2_pjtpe")]
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="ProgressBar" type="TextureProgressBar" parent="."]
|
[node name="ProgressBar" type="TextureProgressBar" parent="."]
|
||||||
anchors_preset = 8
|
anchors_preset = 8
|
||||||
@ -38,4 +32,4 @@ scale = Vector2(0.5, 0.5)
|
|||||||
pivot_offset = Vector2(90, 90)
|
pivot_offset = Vector2(90, 90)
|
||||||
step = 0.0
|
step = 0.0
|
||||||
fill_mode = 4
|
fill_mode = 4
|
||||||
texture_progress = ExtResource("3_a323w")
|
texture_progress = ExtResource("3_fs118")
|
12
PCs/hero.gd
@ -10,7 +10,7 @@ signal ready_state_changed(state: bool)
|
|||||||
@export var left_hand: Node3D
|
@export var left_hand: Node3D
|
||||||
@export var right_hand: Node3D
|
@export var right_hand: Node3D
|
||||||
@export var right_hand_animator: AnimationPlayer
|
@export var right_hand_animator: AnimationPlayer
|
||||||
@export var edit_tool: EditTool
|
@export var edit_tool: PathEditTool
|
||||||
@export var gauntlet_sprite: Sprite3D
|
@export var gauntlet_sprite: Sprite3D
|
||||||
@export var sprite: EightDirectionSprite3D
|
@export var sprite: EightDirectionSprite3D
|
||||||
@export var hand_sprite: Sprite2D
|
@export var hand_sprite: Sprite2D
|
||||||
@ -35,6 +35,7 @@ signal ready_state_changed(state: bool)
|
|||||||
@export var swap_off_audio: AudioStreamPlayer
|
@export var swap_off_audio: AudioStreamPlayer
|
||||||
@export var swap_on_audio: AudioStreamPlayer
|
@export var swap_on_audio: AudioStreamPlayer
|
||||||
|
|
||||||
|
var game_manager: GameManager
|
||||||
var hovering_item: InteractButton = null
|
var hovering_item: InteractButton = null
|
||||||
var weapons_spawn_count: int = 0 #Used to prevent node name collisions for multiplayer
|
var weapons_spawn_count: int = 0 #Used to prevent node name collisions for multiplayer
|
||||||
var inventory_selected_index: int = 0
|
var inventory_selected_index: int = 0
|
||||||
@ -120,7 +121,7 @@ func _process(delta: float) -> void:
|
|||||||
hovering_item.disable_hover_effect()
|
hovering_item.disable_hover_effect()
|
||||||
hovering_item = null
|
hovering_item = null
|
||||||
|
|
||||||
if edit_tool.is_looking_at_tower_base:
|
if is_instance_valid(edit_tool.ray_collider) and edit_tool.ray_collider is TowerBase:
|
||||||
card_sprites[0].view_tower()
|
card_sprites[0].view_tower()
|
||||||
else:
|
else:
|
||||||
card_sprites[0].view_weapon()
|
card_sprites[0].view_weapon()
|
||||||
@ -191,10 +192,10 @@ func _process(delta: float) -> void:
|
|||||||
camera.fov = Data.graphics.hfov * (1.0 / movement.zoom_factor)
|
camera.fov = Data.graphics.hfov * (1.0 / movement.zoom_factor)
|
||||||
|
|
||||||
if Input.is_action_just_pressed("View Map"):
|
if Input.is_action_just_pressed("View Map"):
|
||||||
hud.maximise_minimap(Game.level)
|
hud.maximise_minimap()
|
||||||
#Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
#Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||||
if Input.is_action_just_released("View Map"):
|
if Input.is_action_just_released("View Map"):
|
||||||
hud.minimize_minimap(self)
|
hud.minimize_minimap()
|
||||||
#Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
#Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
check_left_hand_valid()
|
check_left_hand_valid()
|
||||||
|
|
||||||
@ -222,6 +223,9 @@ func _unhandled_input(event: InputEvent) -> void:
|
|||||||
if event.is_action_pressed("Pause"):
|
if event.is_action_pressed("Pause"):
|
||||||
var menu: PauseMenu = pause_menu_scene.instantiate() as PauseMenu
|
var menu: PauseMenu = pause_menu_scene.instantiate() as PauseMenu
|
||||||
pause()
|
pause()
|
||||||
|
menu.game_manager = game_manager
|
||||||
|
menu.quit_to_desktop_pressed.connect(game_manager.quit_to_desktop)
|
||||||
|
menu.quit_to_main_menu_pressed.connect(game_manager.scene_switch_main_menu)
|
||||||
menu.closed.connect(unpause)
|
menu.closed.connect(unpause)
|
||||||
hud.add_child(menu)
|
hud.add_child(menu)
|
||||||
|
|
||||||
|
178
PCs/hero.tscn
@ -7,7 +7,7 @@
|
|||||||
[ext_resource type="PackedScene" uid="uid://buvgdem68wtev" path="res://Scenes/Menus/PauseMenu/pause_menu.tscn" id="3_avnsx"]
|
[ext_resource type="PackedScene" uid="uid://buvgdem68wtev" path="res://Scenes/Menus/PauseMenu/pause_menu.tscn" id="3_avnsx"]
|
||||||
[ext_resource type="Script" uid="uid://cij76at0nbs1v" path="res://PCs/view_movement.gd" id="4_mhexa"]
|
[ext_resource type="Script" uid="uid://cij76at0nbs1v" path="res://PCs/view_movement.gd" id="4_mhexa"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dixtx38u4jhd7" path="res://Scenes/UI/card_hand.tscn" id="4_mwtvp"]
|
[ext_resource type="PackedScene" uid="uid://dixtx38u4jhd7" path="res://Scenes/UI/card_hand.tscn" id="4_mwtvp"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dqt1ggtkpkuhs" path="res://Scenes/gauntlet.tscn" id="5_jlxb3"]
|
[ext_resource type="PackedScene" uid="uid://dqt1ggtkpkuhs" path="res://PCs/PathEditTool/path_edit_tool.tscn" id="5_jlxb3"]
|
||||||
[ext_resource type="Script" uid="uid://do24iuot0j7d7" path="res://Scripts/inventory.gd" id="6_cf5ap"]
|
[ext_resource type="Script" uid="uid://do24iuot0j7d7" path="res://Scripts/inventory.gd" id="6_cf5ap"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cjqxkraykhxxk" path="res://Classes/Engineer/red.png" id="6_yyp8i"]
|
[ext_resource type="Texture2D" uid="uid://cjqxkraykhxxk" path="res://Classes/Engineer/red.png" id="6_yyp8i"]
|
||||||
[ext_resource type="Script" uid="uid://b6kjrl7ae1mi0" path="res://PCs/hud.gd" id="8_yl6ka"]
|
[ext_resource type="Script" uid="uid://b6kjrl7ae1mi0" path="res://PCs/hud.gd" id="8_yl6ka"]
|
||||||
@ -20,13 +20,14 @@
|
|||||||
[ext_resource type="Texture2D" uid="uid://chhmkmlfrobhu" path="res://Assets/Textures/bubble.png" id="15_q3yot"]
|
[ext_resource type="Texture2D" uid="uid://chhmkmlfrobhu" path="res://Assets/Textures/bubble.png" id="15_q3yot"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cqnapc8cscl7i" path="res://Assets/Textures/border.png" id="16_x1xjr"]
|
[ext_resource type="Texture2D" uid="uid://cqnapc8cscl7i" path="res://Assets/Textures/border.png" id="16_x1xjr"]
|
||||||
[ext_resource type="PackedScene" uid="uid://chnj376d3lcjd" path="res://Scenes/UI/pickup_notification.tscn" id="17_oyeww"]
|
[ext_resource type="PackedScene" uid="uid://chnj376d3lcjd" path="res://Scenes/UI/pickup_notification.tscn" id="17_oyeww"]
|
||||||
[ext_resource type="PackedScene" uid="uid://d17c77pqsi8oy" path="res://enemy_card_ui.tscn" id="18_dfkac"]
|
[ext_resource type="PackedScene" uid="uid://d17c77pqsi8oy" path="res://UI/EnemyCard/enemy_card_ui.tscn" id="18_dfkac"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cvjcu3hofahr6" path="res://Assets/Textures/place_slot.png" id="18_okmpi"]
|
[ext_resource type="Texture2D" uid="uid://cvjcu3hofahr6" path="res://Assets/Textures/place_slot.png" id="18_okmpi"]
|
||||||
[ext_resource type="Script" uid="uid://b5wle8f6rv3e7" path="res://PCs/player_movement.gd" id="20_cfhw8"]
|
[ext_resource type="Script" uid="uid://b5wle8f6rv3e7" path="res://PCs/player_movement.gd" id="20_cfhw8"]
|
||||||
[ext_resource type="Shader" uid="uid://dhtylicctk3g4" path="res://UI/crosshair.gdshader" id="20_gxpgc"]
|
|
||||||
[ext_resource type="AudioStream" uid="uid://csu2hce4bfoki" path="res://Audio/cardPlace1.ogg" id="24_8ch4w"]
|
[ext_resource type="AudioStream" uid="uid://csu2hce4bfoki" path="res://Audio/cardPlace1.ogg" id="24_8ch4w"]
|
||||||
[ext_resource type="AudioStream" uid="uid://dxq8b77wa41os" path="res://Audio/cardPlace2.ogg" id="25_awl6m"]
|
[ext_resource type="AudioStream" uid="uid://dxq8b77wa41os" path="res://Audio/cardPlace2.ogg" id="25_awl6m"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bs2mskoyvyehv" path="res://Assets/Textures/crosshair159.png" id="25_l7gpx"]
|
||||||
[ext_resource type="AudioStream" uid="uid://bxripx3suub1v" path="res://Audio/cardPlace3.ogg" id="26_7tm07"]
|
[ext_resource type="AudioStream" uid="uid://bxripx3suub1v" path="res://Audio/cardPlace3.ogg" id="26_7tm07"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://0x80ptif1diq" path="res://Assets/Textures/hand_small_point.png" id="26_dfkac"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c2id8hjico4w8" path="res://energy_bar.tscn" id="27_14ugt"]
|
[ext_resource type="PackedScene" uid="uid://c2id8hjico4w8" path="res://energy_bar.tscn" id="27_14ugt"]
|
||||||
[ext_resource type="AudioStream" uid="uid://k1lsqkvohjpa" path="res://Audio/cardPlace4.ogg" id="27_xvxs8"]
|
[ext_resource type="AudioStream" uid="uid://k1lsqkvohjpa" path="res://Audio/cardPlace4.ogg" id="27_xvxs8"]
|
||||||
[ext_resource type="AudioStream" uid="uid://bn8lkvy5wibvo" path="res://Audio/cardSlide1.ogg" id="28_1thk8"]
|
[ext_resource type="AudioStream" uid="uid://bn8lkvy5wibvo" path="res://Audio/cardSlide1.ogg" id="28_1thk8"]
|
||||||
@ -94,21 +95,6 @@ viewport_path = NodePath("FirstPersonViewport")
|
|||||||
[sub_resource type="ViewportTexture" id="ViewportTexture_574jy"]
|
[sub_resource type="ViewportTexture" id="ViewportTexture_574jy"]
|
||||||
viewport_path = NodePath("MiniMapViewport")
|
viewport_path = NodePath("MiniMapViewport")
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lg5jo"]
|
|
||||||
shader = ExtResource("20_gxpgc")
|
|
||||||
shader_parameter/center_enabled = true
|
|
||||||
shader_parameter/legs_enabled = true
|
|
||||||
shader_parameter/inverted = false
|
|
||||||
shader_parameter/color_id = 0
|
|
||||||
shader_parameter/color_0 = Vector4(1, 0, 0, 0.95)
|
|
||||||
shader_parameter/color_1 = Vector4(1, 0, 0, 1)
|
|
||||||
shader_parameter/color_2 = Vector4(0, 0, 1, 1)
|
|
||||||
shader_parameter/center_radius = 0.002
|
|
||||||
shader_parameter/width = 0.002
|
|
||||||
shader_parameter/len = 0.012
|
|
||||||
shader_parameter/spacing = 0.008
|
|
||||||
shader_parameter/spread = 1.0
|
|
||||||
|
|
||||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_tsiqi"]
|
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_tsiqi"]
|
||||||
properties/0/path = NodePath(".:position")
|
properties/0/path = NodePath(".:position")
|
||||||
properties/0/spawn = true
|
properties/0/spawn = true
|
||||||
@ -382,19 +368,18 @@ max_look_down_angle = 80.0
|
|||||||
max_look_up_angle = 80.0
|
max_look_up_angle = 80.0
|
||||||
enable_jumping = true
|
enable_jumping = true
|
||||||
|
|
||||||
[node name="HUD" type="CanvasLayer" parent="." node_paths=PackedStringArray("player", "wave_count", "lives_count", "currency_count", "minimap_outline", "crosshair", "minimap", "minimap_cam", "minimap_viewport", "fps_label", "hover_text", "enemy_sprites", "enemy_counts", "wave_start_label", "place_icon", "swap_icon", "place_text", "swap_text", "new_energy_bar")]
|
[node name="HUD" type="CanvasLayer" parent="." node_paths=PackedStringArray("player", "wave_count", "lives_count", "currency_count", "minimap_outline", "minimap", "minimap_cam", "minimap_viewport", "fps_label", "hover_text", "enemy_sprites", "enemy_counts", "wave_start_label", "place_icon", "swap_icon", "place_text", "swap_text", "new_energy_bar")]
|
||||||
script = ExtResource("8_yl6ka")
|
script = ExtResource("8_yl6ka")
|
||||||
player = NodePath("..")
|
player = NodePath("..")
|
||||||
wave_count = NodePath("WaveCount")
|
wave_count = NodePath("EnemyTracker/WaveCount")
|
||||||
lives_count = NodePath("LivesCount")
|
lives_count = NodePath("LivesBar/LivesCount")
|
||||||
currency_count = NodePath("CurrencyCount")
|
currency_count = NodePath("Minimap/CurrencyCount")
|
||||||
minimap_outline = NodePath("MinimapBorder")
|
minimap_outline = NodePath("Minimap/MinimapBorder")
|
||||||
crosshair = NodePath("Crosshair")
|
|
||||||
minimap = NodePath("Minimap")
|
minimap = NodePath("Minimap")
|
||||||
minimap_cam = NodePath("../MiniMapViewport/Camera3D")
|
minimap_cam = NodePath("../MiniMapViewport/Camera3D")
|
||||||
minimap_viewport = NodePath("../MiniMapViewport")
|
minimap_viewport = NodePath("../MiniMapViewport")
|
||||||
fps_label = NodePath("FPSCounter")
|
fps_label = NodePath("FPSCounter")
|
||||||
hover_text = NodePath("RichTextLabel2")
|
hover_text = NodePath("InteractLabel")
|
||||||
enemy_sprites = [NodePath("EnemyTracker/TextureRect"), NodePath("EnemyTracker/TextureRect2"), NodePath("EnemyTracker/TextureRect3"), NodePath("EnemyTracker/TextureRect4"), NodePath("EnemyTracker/TextureRect5")]
|
enemy_sprites = [NodePath("EnemyTracker/TextureRect"), NodePath("EnemyTracker/TextureRect2"), NodePath("EnemyTracker/TextureRect3"), NodePath("EnemyTracker/TextureRect4"), NodePath("EnemyTracker/TextureRect5")]
|
||||||
enemy_counts = [NodePath("EnemyTracker/TextureRect/Label"), NodePath("EnemyTracker/TextureRect2/Label2"), NodePath("EnemyTracker/TextureRect3/Label3"), NodePath("EnemyTracker/TextureRect4/Label4"), NodePath("EnemyTracker/TextureRect5/Label5")]
|
enemy_counts = [NodePath("EnemyTracker/TextureRect/Label"), NodePath("EnemyTracker/TextureRect2/Label2"), NodePath("EnemyTracker/TextureRect3/Label3"), NodePath("EnemyTracker/TextureRect4/Label4"), NodePath("EnemyTracker/TextureRect5/Label5")]
|
||||||
pickup_notif_scene = ExtResource("17_oyeww")
|
pickup_notif_scene = ExtResource("17_oyeww")
|
||||||
@ -481,6 +466,35 @@ grow_horizontal = 0
|
|||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
texture = SubResource("ViewportTexture_574jy")
|
texture = SubResource("ViewportTexture_574jy")
|
||||||
|
|
||||||
|
[node name="MinimapBorder" type="TextureRect" parent="HUD/Minimap"]
|
||||||
|
texture_filter = 1
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 1
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
offset_left = -259.0
|
||||||
|
offset_top = -3.0
|
||||||
|
offset_right = 3.0
|
||||||
|
offset_bottom = 333.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
mouse_filter = 2
|
||||||
|
texture = ExtResource("16_x1xjr")
|
||||||
|
|
||||||
|
[node name="CurrencyCount" type="Label" parent="HUD/Minimap"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 1
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
offset_left = -61.0
|
||||||
|
offset_top = 260.0
|
||||||
|
offset_bottom = 318.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
theme_override_colors/font_color = Color(0.988235, 0.909804, 0.65098, 1)
|
||||||
|
theme_override_font_sizes/font_size = 37
|
||||||
|
text = "20"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="FPSCounter" type="Label" parent="HUD"]
|
[node name="FPSCounter" type="Label" parent="HUD"]
|
||||||
anchors_preset = 1
|
anchors_preset = 1
|
||||||
anchor_left = 1.0
|
anchor_left = 1.0
|
||||||
@ -505,31 +519,17 @@ grow_vertical = 1
|
|||||||
scale = Vector2(3, 3)
|
scale = Vector2(3, 3)
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="LivesCount" type="Label" parent="HUD"]
|
[node name="LivesCount" type="Label" parent="HUD/LivesBar"]
|
||||||
offset_left = -2.24
|
layout_mode = 0
|
||||||
offset_top = 23.28
|
offset_right = 79.0
|
||||||
offset_right = 102.76
|
offset_bottom = 70.0
|
||||||
offset_bottom = 112.28
|
scale = Vector2(0.33, 0.33)
|
||||||
theme_override_colors/font_color = Color(0.65098, 0.227451, 0.243137, 1)
|
theme_override_colors/font_color = Color(0.65098, 0.227451, 0.243137, 1)
|
||||||
theme_override_font_sizes/font_size = 37
|
theme_override_font_sizes/font_size = 37
|
||||||
text = "120
|
text = "120"
|
||||||
"
|
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="MinimapBorder" type="TextureRect" parent="HUD"]
|
|
||||||
texture_filter = 1
|
|
||||||
anchors_preset = 1
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
offset_left = -262.0
|
|
||||||
offset_top = 37.0
|
|
||||||
offset_right = -37.0
|
|
||||||
offset_bottom = 336.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
mouse_filter = 2
|
|
||||||
texture = ExtResource("16_x1xjr")
|
|
||||||
|
|
||||||
[node name="EnemyTracker" type="TextureRect" parent="HUD"]
|
[node name="EnemyTracker" type="TextureRect" parent="HUD"]
|
||||||
texture_filter = 1
|
texture_filter = 1
|
||||||
anchors_preset = 5
|
anchors_preset = 5
|
||||||
@ -652,22 +652,23 @@ text = "999"
|
|||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="CurrencyCount" type="Label" parent="HUD"]
|
[node name="WaveCount" type="Label" parent="HUD/EnemyTracker"]
|
||||||
anchors_preset = 1
|
layout_mode = 1
|
||||||
anchor_left = 1.0
|
anchors_preset = 5
|
||||||
anchor_right = 1.0
|
anchor_left = 0.5
|
||||||
offset_left = -101.0
|
anchor_right = 0.5
|
||||||
offset_top = 300.0
|
offset_left = -30.0
|
||||||
offset_right = -40.0
|
offset_top = 59.0
|
||||||
offset_bottom = 54.0
|
offset_right = 30.0
|
||||||
grow_horizontal = 0
|
offset_bottom = 87.0
|
||||||
theme_override_colors/font_color = Color(0.988235, 0.909804, 0.65098, 1)
|
grow_horizontal = 2
|
||||||
theme_override_font_sizes/font_size = 37
|
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||||
text = "20"
|
theme_override_font_sizes/font_size = 18
|
||||||
|
text = "1"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="RichTextLabel2" type="RichTextLabel" parent="HUD"]
|
[node name="InteractLabel" type="RichTextLabel" parent="HUD"]
|
||||||
anchors_preset = 8
|
anchors_preset = 8
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_top = 0.5
|
anchor_top = 0.5
|
||||||
@ -687,30 +688,6 @@ bbcode_enabled = true
|
|||||||
text = "[center]Press Button To do thing"
|
text = "[center]Press Button To do thing"
|
||||||
scroll_active = false
|
scroll_active = false
|
||||||
|
|
||||||
[node name="WaveCount" type="Label" parent="HUD"]
|
|
||||||
anchors_preset = 5
|
|
||||||
anchor_left = 0.5
|
|
||||||
anchor_right = 0.5
|
|
||||||
offset_left = -30.0
|
|
||||||
offset_top = 81.0
|
|
||||||
offset_right = 30.0
|
|
||||||
offset_bottom = 109.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
|
||||||
theme_override_font_sizes/font_size = 18
|
|
||||||
text = "1"
|
|
||||||
horizontal_alignment = 1
|
|
||||||
vertical_alignment = 1
|
|
||||||
|
|
||||||
[node name="Crosshair" type="ColorRect" parent="HUD"]
|
|
||||||
material = SubResource("ShaderMaterial_lg5jo")
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
mouse_filter = 2
|
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="HUD"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="HUD"]
|
||||||
anchors_preset = 4
|
anchors_preset = 4
|
||||||
anchor_top = 0.5
|
anchor_top = 0.5
|
||||||
@ -757,8 +734,45 @@ grow_horizontal = 2
|
|||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
|
||||||
[node name="EnergyBar" parent="HUD" instance=ExtResource("27_14ugt")]
|
[node name="EnergyBar" parent="HUD" instance=ExtResource("27_14ugt")]
|
||||||
|
visible = false
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="TextureRect" type="TextureRect" parent="HUD"]
|
||||||
|
modulate = Color(0.54324, 0.193653, 0.15885, 0.9)
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = -20.0
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 20.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
texture = ExtResource("25_l7gpx")
|
||||||
|
expand_mode = 3
|
||||||
|
stretch_mode = 5
|
||||||
|
|
||||||
|
[node name="TextureRect2" type="TextureRect" parent="HUD"]
|
||||||
|
visible = false
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = -20.0
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 20.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
texture = ExtResource("26_dfkac")
|
||||||
|
expand_mode = 3
|
||||||
|
stretch_mode = 5
|
||||||
|
|
||||||
[node name="WeaponSwapTimer" type="Timer" parent="."]
|
[node name="WeaponSwapTimer" type="Timer" parent="."]
|
||||||
wait_time = 0.4
|
wait_time = 0.4
|
||||||
one_shot = true
|
one_shot = true
|
||||||
|
26
PCs/hud.gd
@ -12,7 +12,6 @@ var last_lives_count: int = 120
|
|||||||
@export var minimap_viewport: SubViewport
|
@export var minimap_viewport: SubViewport
|
||||||
@export var fps_label: Label
|
@export var fps_label: Label
|
||||||
@export var hover_text: RichTextLabel
|
@export var hover_text: RichTextLabel
|
||||||
var minimap_anchor: Node3D
|
|
||||||
var enemy_names: Array[String]
|
var enemy_names: Array[String]
|
||||||
@export var enemy_sprites: Array[TextureRect]
|
@export var enemy_sprites: Array[TextureRect]
|
||||||
@export var enemy_counts: Array[Label]
|
@export var enemy_counts: Array[Label]
|
||||||
@ -25,6 +24,7 @@ var enemy_names: Array[String]
|
|||||||
@export var enemy_card_scene: PackedScene
|
@export var enemy_card_scene: PackedScene
|
||||||
@export var new_energy_bar: EnergyBar
|
@export var new_energy_bar: EnergyBar
|
||||||
|
|
||||||
|
var map_anchor: Node3D
|
||||||
var audio_guard: bool = false
|
var audio_guard: bool = false
|
||||||
var cards: Array[EnemyCardUI] = []
|
var cards: Array[EnemyCardUI] = []
|
||||||
|
|
||||||
@ -93,12 +93,16 @@ func tween_label(x: float) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func set_hover_text(text: String) -> void:
|
func set_hover_text(text: String) -> void:
|
||||||
|
$TextureRect2.visible = true
|
||||||
|
$TextureRect.visible = false
|
||||||
hover_text.text = parse_action_tag(text)
|
hover_text.text = parse_action_tag(text)
|
||||||
hover_text.set_visible(true)
|
hover_text.visible = true
|
||||||
|
|
||||||
|
|
||||||
func unset_hover_text() -> void:
|
func unset_hover_text() -> void:
|
||||||
hover_text.set_visible(false)
|
hover_text.visible = false
|
||||||
|
$TextureRect2.visible = false
|
||||||
|
$TextureRect.visible = true
|
||||||
|
|
||||||
|
|
||||||
func set_wave_count(value: int) -> void:
|
func set_wave_count(value: int) -> void:
|
||||||
@ -125,8 +129,12 @@ func set_upcoming_wave(value: Dictionary) -> void:
|
|||||||
var frame_count: int = 0
|
var frame_count: int = 0
|
||||||
enemy_names = []
|
enemy_names = []
|
||||||
var wave: Dictionary = {}
|
var wave: Dictionary = {}
|
||||||
for index: int in value:
|
for key: String in value:
|
||||||
wave[Data.enemies[index]] = value[index]
|
var new_enemy: Enemy
|
||||||
|
for enemy: Enemy in player.game_manager.level.enemy_pool:
|
||||||
|
if enemy.title == key:
|
||||||
|
new_enemy = enemy
|
||||||
|
wave[new_enemy] = value[key]
|
||||||
for x: int in enemy_sprites.size():
|
for x: int in enemy_sprites.size():
|
||||||
enemy_sprites[x].set_visible(false)
|
enemy_sprites[x].set_visible(false)
|
||||||
enemy_counts[x].set_visible(false)
|
enemy_counts[x].set_visible(false)
|
||||||
@ -161,8 +169,8 @@ func set_weapon_energy(value: int, energy_type: Data.EnergyType) -> void:
|
|||||||
audio_guard = false
|
audio_guard = false
|
||||||
|
|
||||||
|
|
||||||
func maximise_minimap(anchor: Node3D) -> void:
|
func maximise_minimap() -> void:
|
||||||
minimap_cam.anchor = anchor
|
minimap_cam.anchor = map_anchor
|
||||||
minimap.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
minimap.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||||
minimap.offset_bottom = -40
|
minimap.offset_bottom = -40
|
||||||
minimap.offset_top = 40
|
minimap.offset_top = 40
|
||||||
@ -174,8 +182,8 @@ func maximise_minimap(anchor: Node3D) -> void:
|
|||||||
currency_count.set_visible(false)
|
currency_count.set_visible(false)
|
||||||
|
|
||||||
|
|
||||||
func minimize_minimap(anchor: Node3D) -> void:
|
func minimize_minimap() -> void:
|
||||||
minimap_cam.anchor = anchor
|
minimap_cam.anchor = player
|
||||||
minimap.set_anchors_and_offsets_preset(Control.PRESET_TOP_RIGHT)
|
minimap.set_anchors_and_offsets_preset(Control.PRESET_TOP_RIGHT)
|
||||||
minimap.offset_right = -40
|
minimap.offset_right = -40
|
||||||
minimap.offset_top = 40
|
minimap.offset_top = 40
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
[gd_resource type="Resource" script_class="Enemy" load_steps=5 format=3 uid="uid://dsgkwh3opyqtx"]
|
[gd_resource type="Resource" script_class="Enemy" load_steps=6 format=3 uid="uid://dsgkwh3opyqtx"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://chhmkmlfrobhu" path="res://Assets/Textures/bubble.png" id="1_57rr1"]
|
[ext_resource type="Texture2D" uid="uid://chhmkmlfrobhu" path="res://Assets/Textures/bubble.png" id="1_57rr1"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ta47gpiwloxm" path="res://Assets/Textures/dead_bubble.png" id="1_ioqxi"]
|
[ext_resource type="Texture2D" uid="uid://ta47gpiwloxm" path="res://Assets/Textures/dead_bubble.png" id="1_ioqxi"]
|
||||||
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_wjbfx"]
|
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_wjbfx"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bjo2q6vca5qlv" path="res://Worlds/GreenPlanet/Enemies/air_enemy.tscn" id="3_86skx"]
|
||||||
[ext_resource type="Texture2D" uid="uid://d0vafwv4lhjji" path="res://Assets/TextureAtlases/bubble.tres" id="3_homny"]
|
[ext_resource type="Texture2D" uid="uid://d0vafwv4lhjji" path="res://Assets/TextureAtlases/bubble.tres" id="3_homny"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_wjbfx")
|
script = ExtResource("1_wjbfx")
|
||||||
title = "bubble"
|
title = "bubble"
|
||||||
target_type = 2
|
target_type = 2
|
||||||
|
scene = ExtResource("3_86skx")
|
||||||
icon = ExtResource("1_57rr1")
|
icon = ExtResource("1_57rr1")
|
||||||
death_sprite = ExtResource("1_ioqxi")
|
death_sprite = ExtResource("1_ioqxi")
|
||||||
sprite = ExtResource("3_homny")
|
sprite = ExtResource("3_homny")
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
[gd_resource type="Resource" script_class="Enemy" load_steps=5 format=3 uid="uid://bffhb5krs5elm"]
|
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://b1lwaxw62yp3p" path="res://Assets/Textures/dead_spike.png" id="1_1js8q"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://duywsy7jmh4u" path="res://Assets/Textures/spike.png" id="1_22o7e"]
|
|
||||||
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_q5r05"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://sybn6bjbj5fh" path="res://Assets/TextureAtlases/spike.tres" id="3_tbb38"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1_q5r05")
|
|
||||||
title = "spike"
|
|
||||||
target_type = 2
|
|
||||||
icon = ExtResource("1_22o7e")
|
|
||||||
death_sprite = ExtResource("1_1js8q")
|
|
||||||
sprite = ExtResource("3_tbb38")
|
|
||||||
spawn_power = 6
|
|
||||||
health = 120
|
|
||||||
penalty = 7
|
|
||||||
movement_speed = 1.0
|
|
||||||
spawn_cooldown = 1.0
|
|
||||||
common_group = 3
|
|
||||||
common_cost = 2
|
|
||||||
uncommon_group = 6
|
|
||||||
uncommon_cost = 3
|
|
||||||
rare_group = 10
|
|
||||||
rare_cost = 4
|
|
||||||
epic_group = 16
|
|
||||||
epic_cost = 5
|
|
||||||
legendary_group = 25
|
|
||||||
legendary_cost = 6
|
|
@ -1,14 +1,16 @@
|
|||||||
[gd_resource type="Resource" script_class="Enemy" load_steps=5 format=3 uid="uid://boik1gnpl4v0a"]
|
[gd_resource type="Resource" script_class="Enemy" load_steps=6 format=3 uid="uid://boik1gnpl4v0a"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cde0voyrwnqkl" path="res://Assets/Textures/icon_eye_dog_boss.png" id="1_2o720"]
|
[ext_resource type="Texture2D" uid="uid://cde0voyrwnqkl" path="res://Assets/Textures/icon_eye_dog_boss.png" id="1_2o720"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bp3njt3h0qfbg" path="res://Assets/Textures/dead_eye_dog_boss.png" id="1_5xm32"]
|
[ext_resource type="Texture2D" uid="uid://bp3njt3h0qfbg" path="res://Assets/Textures/dead_eye_dog_boss.png" id="1_5xm32"]
|
||||||
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_euaab"]
|
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_euaab"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ff3cys53p37j" path="res://Assets/TextureAtlases/dog_fast_boss.tres" id="2_1m62w"]
|
[ext_resource type="Texture2D" uid="uid://ff3cys53p37j" path="res://Assets/TextureAtlases/dog_fast_boss.tres" id="2_1m62w"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b0nady5xm88bo" path="res://Worlds/GreenPlanet/Enemies/land_enemy.tscn" id="3_g83md"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_euaab")
|
script = ExtResource("1_euaab")
|
||||||
title = "boss dog"
|
title = "boss dog"
|
||||||
target_type = 1
|
target_type = 1
|
||||||
|
scene = ExtResource("3_g83md")
|
||||||
icon = ExtResource("1_2o720")
|
icon = ExtResource("1_2o720")
|
||||||
death_sprite = ExtResource("1_5xm32")
|
death_sprite = ExtResource("1_5xm32")
|
||||||
sprite = ExtResource("2_1m62w")
|
sprite = ExtResource("2_1m62w")
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
[gd_resource type="Resource" script_class="Enemy" load_steps=5 format=3 uid="uid://cvehqh4tt28g7"]
|
[gd_resource type="Resource" script_class="Enemy" load_steps=6 format=3 uid="uid://cvehqh4tt28g7"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_k5sd1"]
|
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_k5sd1"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cv5p03aw78vwd" path="res://Assets/Textures/icon_eye_dog_fast.png" id="1_xgen5"]
|
[ext_resource type="Texture2D" uid="uid://cv5p03aw78vwd" path="res://Assets/Textures/icon_eye_dog_fast.png" id="1_xgen5"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dgdofekr7ow73" path="res://Assets/Textures/dead_eye_dog_fast.png" id="1_yj87d"]
|
[ext_resource type="Texture2D" uid="uid://dgdofekr7ow73" path="res://Assets/Textures/dead_eye_dog_fast.png" id="1_yj87d"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dd212gh03wloa" path="res://Assets/TextureAtlases/dog_fast.tres" id="2_mkbm6"]
|
[ext_resource type="Texture2D" uid="uid://dd212gh03wloa" path="res://Assets/TextureAtlases/dog_fast.tres" id="2_mkbm6"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b0nady5xm88bo" path="res://Worlds/GreenPlanet/Enemies/land_enemy.tscn" id="3_e3fq0"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_k5sd1")
|
script = ExtResource("1_k5sd1")
|
||||||
title = "fast dog"
|
title = "fast dog"
|
||||||
target_type = 1
|
target_type = 1
|
||||||
|
scene = ExtResource("3_e3fq0")
|
||||||
icon = ExtResource("1_xgen5")
|
icon = ExtResource("1_xgen5")
|
||||||
death_sprite = ExtResource("1_yj87d")
|
death_sprite = ExtResource("1_yj87d")
|
||||||
sprite = ExtResource("2_mkbm6")
|
sprite = ExtResource("2_mkbm6")
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
[gd_resource type="Resource" script_class="Enemy" load_steps=5 format=3 uid="uid://dxi17xvdlhkvc"]
|
[gd_resource type="Resource" script_class="Enemy" load_steps=6 format=3 uid="uid://dxi17xvdlhkvc"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://08n5jvq5tptf" path="res://Assets/Textures/icon_eye_dog_heavy.png" id="1_lck53"]
|
[ext_resource type="Texture2D" uid="uid://08n5jvq5tptf" path="res://Assets/Textures/icon_eye_dog_heavy.png" id="1_lck53"]
|
||||||
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_q48il"]
|
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="1_q48il"]
|
||||||
[ext_resource type="Texture2D" uid="uid://e7lahg40lq8a" path="res://Assets/Textures/dead_eye_dog_heavy.png" id="1_qveaa"]
|
[ext_resource type="Texture2D" uid="uid://e7lahg40lq8a" path="res://Assets/Textures/dead_eye_dog_heavy.png" id="1_qveaa"]
|
||||||
[ext_resource type="Texture2D" uid="uid://c0543ucoalwmi" path="res://Assets/TextureAtlases/dog_fast_heavy.tres" id="2_7nc4x"]
|
[ext_resource type="Texture2D" uid="uid://c0543ucoalwmi" path="res://Assets/TextureAtlases/dog_fast_heavy.tres" id="2_7nc4x"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b0nady5xm88bo" path="res://Worlds/GreenPlanet/Enemies/land_enemy.tscn" id="3_t3gih"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_q48il")
|
script = ExtResource("1_q48il")
|
||||||
title = "heavy dog"
|
title = "heavy dog"
|
||||||
target_type = 1
|
target_type = 1
|
||||||
|
scene = ExtResource("3_t3gih")
|
||||||
icon = ExtResource("1_lck53")
|
icon = ExtResource("1_lck53")
|
||||||
death_sprite = ExtResource("1_qveaa")
|
death_sprite = ExtResource("1_qveaa")
|
||||||
sprite = ExtResource("2_7nc4x")
|
sprite = ExtResource("2_7nc4x")
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
[gd_resource type="Resource" script_class="Enemy" load_steps=6 format=3 uid="uid://btudmfd7wfwec"]
|
[gd_resource type="Resource" script_class="Enemy" load_steps=7 format=3 uid="uid://btudmfd7wfwec"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://bl16mvx4xaxeb" path="res://Assets/Textures/dead_leapfrog.png" id="1_aa1x4"]
|
[ext_resource type="Texture2D" uid="uid://bl16mvx4xaxeb" path="res://Assets/Textures/dead_leapfrog.png" id="1_aa1x4"]
|
||||||
[ext_resource type="Texture2D" uid="uid://3ywtwfpuuknr" path="res://Assets/Textures/leapfrog.png" id="2_pj3v3"]
|
[ext_resource type="Texture2D" uid="uid://3ywtwfpuuknr" path="res://Assets/Textures/leapfrog.png" id="2_pj3v3"]
|
||||||
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="3_i5ry5"]
|
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="3_i5ry5"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cmneu5o0m02l8" path="res://Worlds/GreenPlanet/Enemies/leaping_enemy.tscn" id="3_pj3v3"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cb66pspr16scy" path="res://Assets/Textures/leapfrog_2.png" id="4_i5ry5"]
|
[ext_resource type="Texture2D" uid="uid://cb66pspr16scy" path="res://Assets/Textures/leapfrog_2.png" id="4_i5ry5"]
|
||||||
|
|
||||||
[sub_resource type="AtlasTexture" id="AtlasTexture_n6kdu"]
|
[sub_resource type="AtlasTexture" id="AtlasTexture_n6kdu"]
|
||||||
@ -15,6 +16,7 @@ resource_local_to_scene = true
|
|||||||
script = ExtResource("3_i5ry5")
|
script = ExtResource("3_i5ry5")
|
||||||
title = "Leapdog"
|
title = "Leapdog"
|
||||||
target_type = 1
|
target_type = 1
|
||||||
|
scene = ExtResource("3_pj3v3")
|
||||||
icon = ExtResource("2_pj3v3")
|
icon = ExtResource("2_pj3v3")
|
||||||
death_sprite = ExtResource("1_aa1x4")
|
death_sprite = ExtResource("1_aa1x4")
|
||||||
sprite = SubResource("AtlasTexture_n6kdu")
|
sprite = SubResource("AtlasTexture_n6kdu")
|
||||||
|
@ -22,7 +22,7 @@ func generate_rarity() -> int:
|
|||||||
for rarity: String in Data.Rarity:
|
for rarity: String in Data.Rarity:
|
||||||
weight_total += Data.rarity_weights[rarity]
|
weight_total += Data.rarity_weights[rarity]
|
||||||
|
|
||||||
var generated_rarity: int = Game.randi_in_range(4 * cards_generated, 0, weight_total)
|
var generated_rarity: int = NoiseRandom.randi_in_range(4 * cards_generated, 0, weight_total)
|
||||||
cards_generated += 1
|
cards_generated += 1
|
||||||
var decided_rarity: int = 0
|
var decided_rarity: int = 0
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ func randomize_cards(faction: Card.Faction) -> void:
|
|||||||
decided_rarity -= 1
|
decided_rarity -= 1
|
||||||
var card: Card
|
var card: Card
|
||||||
if card_array.size() > 0:
|
if card_array.size() > 0:
|
||||||
card = card_array[Game.randi_in_range(132 * cards_generated, 0, card_array.size() - 1)]
|
card = card_array[NoiseRandom.randi_in_range(132 * cards_generated, 0, card_array.size() - 1)]
|
||||||
cards_generated += 1
|
cards_generated += 1
|
||||||
card_array.erase(card)
|
card_array.erase(card)
|
||||||
var item: CardItem = reply_player.hero_class.card_item.instantiate() as CardItem
|
var item: CardItem = reply_player.hero_class.card_item.instantiate() as CardItem
|
||||||
|
@ -9,21 +9,20 @@ class_name GameEndScreen extends PanelContainer
|
|||||||
@export var total_losses_label: Label
|
@export var total_losses_label: Label
|
||||||
@export var undefeated_enemies: VBoxContainer
|
@export var undefeated_enemies: VBoxContainer
|
||||||
|
|
||||||
|
var game_manager: GameManager
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
var wins: int = Data.save_data.twenty_game_history.count(true)
|
winrate_label.text = "Your 20-game winrate is now: " + str(Data.save_data.winrate) + "%!"
|
||||||
var games: int = Data.save_data.twenty_game_history.size()
|
|
||||||
var winrate: int = int((float(wins) / float(games)) * 100.0)
|
|
||||||
winrate_label.text = "Your 20-game winrate is now: " + str(winrate) + "%!"
|
|
||||||
total_games_label.text = "Total games: " + str(Data.save_data.wins + Data.save_data.losses)
|
total_games_label.text = "Total games: " + str(Data.save_data.wins + Data.save_data.losses)
|
||||||
total_wins_label.text = "Total wins: " + str(Data.save_data.wins)
|
total_wins_label.text = "Total wins: " + str(Data.save_data.wins)
|
||||||
total_losses_label.text = "Total losses: " + str(Data.save_data.losses)
|
total_losses_label.text = "Total losses: " + str(Data.save_data.losses)
|
||||||
for wave_key: int in Game.stats.enemies_undefeated:
|
for wave_key: int in game_manager.stats.enemies_undefeated:
|
||||||
var spawned_box: EnemyBox = box.instantiate() as EnemyBox
|
var spawned_box: EnemyBox = box.instantiate() as EnemyBox
|
||||||
undefeated_enemies.add_child(spawned_box)
|
undefeated_enemies.add_child(spawned_box)
|
||||||
spawned_box.set_wave(wave_key)
|
spawned_box.set_wave(wave_key)
|
||||||
for enemy_key: Enemy in Game.stats.enemies_undefeated[wave_key]:
|
for enemy_key: Enemy in game_manager.stats.enemies_undefeated[wave_key]:
|
||||||
spawned_box.add_enemy_tag(enemy_key, Game.stats.enemies_undefeated[wave_key][enemy_key])
|
spawned_box.add_enemy_tag(enemy_key, game_manager.stats.enemies_undefeated[wave_key][enemy_key])
|
||||||
|
|
||||||
|
|
||||||
func set_outcome_message(message: String) -> void:
|
func set_outcome_message(message: String) -> void:
|
||||||
@ -31,15 +30,15 @@ func set_outcome_message(message: String) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _on_quit_button_pressed() -> void:
|
func _on_quit_button_pressed() -> void:
|
||||||
Game.scene_switch_main_menu()
|
game_manager.scene_switch_main_menu()
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
|
|
||||||
func _on_play_button_pressed() -> void:
|
func _on_play_button_pressed() -> void:
|
||||||
if Game.gamemode.daily == false and !Game.gamemode.seeded:
|
if game_manager.gamemode.daily == false and !game_manager.gamemode.seeded:
|
||||||
Game.gamemode.rng_seed = randi()
|
game_manager.gamemode.rng_seed = randi()
|
||||||
Game.setup()
|
game_manager.setup()
|
||||||
Game.start()
|
game_manager.start()
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
class_name MainMenu extends Control
|
class_name MainMenu extends Control
|
||||||
|
|
||||||
|
signal singleplayer_game_requested
|
||||||
|
signal multiplayer_game_requested
|
||||||
|
|
||||||
@export var bg_level: Level
|
@export var bg_level: Level
|
||||||
@export var game_select_menu: Control
|
@export var game_select_menu: Control
|
||||||
@export var main_controls: Control
|
@export var main_controls: Control
|
||||||
@ -7,6 +10,7 @@ class_name MainMenu extends Control
|
|||||||
@export var profile_controls: Control
|
@export var profile_controls: Control
|
||||||
@export var mods_controls: ModMenu
|
@export var mods_controls: ModMenu
|
||||||
|
|
||||||
|
var game: GameManager
|
||||||
var gamemode: GameMode = GameMode.new()
|
var gamemode: GameMode = GameMode.new()
|
||||||
|
|
||||||
var confirmation_popup_scene: PackedScene = preload("res://Scenes/Menus/confirmation_popup.tscn")
|
var confirmation_popup_scene: PackedScene = preload("res://Scenes/Menus/confirmation_popup.tscn")
|
||||||
@ -19,18 +23,18 @@ var temp_data: SaveData
|
|||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
$ProfileEditor/VBoxContainer/HBoxContainer/DisplayName.text = Data.player_profile.display_name
|
$ProfileEditor/VBoxContainer/HBoxContainer/DisplayName.text = Data.player_profile.display_name
|
||||||
load_stats(Data.save_data)
|
load_stats(Data.save_data)
|
||||||
bg_level.a_star_graph_3d.make_grid()
|
#bg_level.a_star_graph_3d.make_grid()
|
||||||
bg_level.a_star_graph_3d.find_path()
|
#bg_level.a_star_graph_3d.find_path()
|
||||||
bg_level.a_star_graph_3d.build_random_maze(70)
|
#bg_level.a_star_graph_3d.build_random_maze(70)
|
||||||
bg_level.a_star_graph_3d.place_random_towers(30)
|
#bg_level.a_star_graph_3d.place_random_towers(30)
|
||||||
bg_level.a_star_graph_3d.disable_all_tower_frames()
|
#bg_level.a_star_graph_3d.disable_all_tower_frames()
|
||||||
Game.level = bg_level
|
#Game.level = bg_level
|
||||||
WaveManager.generate_wave(WaveManager.calculate_spawn_power(50, 4), bg_level.enemy_pool, bg_level.enemy_spawns)
|
#WaveManager.generate_wave(WaveManager.calculate_spawn_power(50, 4), bg_level.enemy_pool, bg_level.enemy_spawns)
|
||||||
for spawn: EnemySpawner in bg_level.enemy_spawns:
|
#for spawn: EnemySpawner in bg_level.enemy_spawns:
|
||||||
spawn.enemy_died_callback = enemy_died
|
# spawn.enemy_died_callback = enemy_died
|
||||||
spawn.enemy_reached_goal_callback = damage_goal
|
# spawn.enemy_reached_goal_callback = damage_goal
|
||||||
spawn.enemy_spawned.connect(increase_enemy_count)
|
# spawn.enemy_spawned.connect(increase_enemy_count)
|
||||||
spawn.spawn_wave()
|
# spawn.spawn_wave()
|
||||||
|
|
||||||
|
|
||||||
#these exist purely to make the enemies that spawn on the main menu happy
|
#these exist purely to make the enemies that spawn on the main menu happy
|
||||||
@ -67,6 +71,7 @@ func quit_game(confirmation: bool) -> void:
|
|||||||
|
|
||||||
func _on_options_button_pressed() -> void:
|
func _on_options_button_pressed() -> void:
|
||||||
var menu: OptionsMenu = options_menu_scene.instantiate()
|
var menu: OptionsMenu = options_menu_scene.instantiate()
|
||||||
|
menu.game_manager = game
|
||||||
add_child(menu)
|
add_child(menu)
|
||||||
|
|
||||||
|
|
||||||
@ -75,12 +80,11 @@ func _on_button_mouse_entered() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func start_game() -> void:
|
func start_game() -> void:
|
||||||
Game.level = null
|
game.gamemode = gamemode
|
||||||
Game.gamemode = gamemode
|
if !gamemode.multiplayer:
|
||||||
if gamemode.multiplayer:
|
singleplayer_game_requested.emit()
|
||||||
Game.scene_switch_to_multiplayer_lobby()
|
|
||||||
else:
|
else:
|
||||||
Game.scene_switch_to_singleplayer_lobby()
|
multiplayer_game_requested.emit()
|
||||||
|
|
||||||
|
|
||||||
func _on_play_button_pressed() -> void:
|
func _on_play_button_pressed() -> void:
|
||||||
@ -122,7 +126,7 @@ func _on_standard_button_pressed() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _on_daily_button_pressed() -> void:
|
func _on_daily_button_pressed() -> void:
|
||||||
gamemode.seed = hash(Time.get_date_string_from_system(true))
|
gamemode.rng_seed = hash(Time.get_date_string_from_system(true))
|
||||||
gamemode.endless = false
|
gamemode.endless = false
|
||||||
gamemode.daily = true
|
gamemode.daily = true
|
||||||
start_game()
|
start_game()
|
||||||
@ -144,7 +148,7 @@ func _on_changelog_button_pressed() -> void:
|
|||||||
func load_stats(stats: SaveData) -> void:
|
func load_stats(stats: SaveData) -> void:
|
||||||
$ProfileManager/VBoxContainer/Stats/Wins/Label2.text = str(stats.wins)
|
$ProfileManager/VBoxContainer/Stats/Wins/Label2.text = str(stats.wins)
|
||||||
$ProfileManager/VBoxContainer/Stats/Losses/Label2.text = str(stats.losses)
|
$ProfileManager/VBoxContainer/Stats/Losses/Label2.text = str(stats.losses)
|
||||||
$ProfileManager/VBoxContainer/Stats/Winrate/Label2.text = str(int(stats.wins / 20.0))
|
$ProfileManager/VBoxContainer/Stats/Winrate/Label2.text = str(stats.winrate) + "%"
|
||||||
$ProfileManager/VBoxContainer/Stats/EngineerCardsBought/Label2.text = str(stats.engineer_cards_bought)
|
$ProfileManager/VBoxContainer/Stats/EngineerCardsBought/Label2.text = str(stats.engineer_cards_bought)
|
||||||
$ProfileManager/VBoxContainer/Stats/MageCardsBought/Label2.text = str(stats.mage_cards_bought)
|
$ProfileManager/VBoxContainer/Stats/MageCardsBought/Label2.text = str(stats.mage_cards_bought)
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
[ext_resource type="Theme" uid="uid://b6a0ip4p72tgx" path="res://UI/new_theme.tres" id="1_p1cib"]
|
[ext_resource type="Theme" uid="uid://b6a0ip4p72tgx" path="res://UI/new_theme.tres" id="1_p1cib"]
|
||||||
[ext_resource type="Script" uid="uid://ci8vq73u23viy" path="res://Scenes/Menus/MainMenu/main_menu.gd" id="2_ivytu"]
|
[ext_resource type="Script" uid="uid://ci8vq73u23viy" path="res://Scenes/Menus/MainMenu/main_menu.gd" id="2_ivytu"]
|
||||||
[ext_resource type="Texture2D" uid="uid://lvvnrb5jugum" path="res://Assets/Textures/logo_title.png" id="3_8jkeb"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://y1qa1g3ic8sp" path="res://Worlds/GreenPlanet/Levels/first_level.tscn" id="3_l8r4a"]
|
[ext_resource type="PackedScene" uid="uid://y1qa1g3ic8sp" path="res://Worlds/GreenPlanet/Levels/first_level.tscn" id="3_l8r4a"]
|
||||||
[ext_resource type="AudioStream" uid="uid://cp6ph4ra7u5rk" path="res://Scenes/UI/drop_003.ogg" id="5_cwn2i"]
|
[ext_resource type="AudioStream" uid="uid://cp6ph4ra7u5rk" path="res://Scenes/UI/drop_003.ogg" id="5_cwn2i"]
|
||||||
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="5_u514r"]
|
[ext_resource type="Script" uid="uid://cbwxa2a4hfcy4" path="res://Scripts/Resources/enemy.gd" id="5_u514r"]
|
||||||
@ -13,12 +12,13 @@
|
|||||||
[ext_resource type="Resource" uid="uid://dxi17xvdlhkvc" path="res://Resources/Enemies/dog_heavy.tres" id="10_day26"]
|
[ext_resource type="Resource" uid="uid://dxi17xvdlhkvc" path="res://Resources/Enemies/dog_heavy.tres" id="10_day26"]
|
||||||
[ext_resource type="Resource" uid="uid://boik1gnpl4v0a" path="res://Resources/Enemies/dog_boss.tres" id="11_1mes0"]
|
[ext_resource type="Resource" uid="uid://boik1gnpl4v0a" path="res://Resources/Enemies/dog_boss.tres" id="11_1mes0"]
|
||||||
[ext_resource type="Resource" uid="uid://dsgkwh3opyqtx" path="res://Resources/Enemies/airenemy.tres" id="12_5vny5"]
|
[ext_resource type="Resource" uid="uid://dsgkwh3opyqtx" path="res://Resources/Enemies/airenemy.tres" id="12_5vny5"]
|
||||||
[ext_resource type="Resource" uid="uid://bffhb5krs5elm" path="res://Resources/Enemies/airenemy2.tres" id="13_xb7gj"]
|
[ext_resource type="Resource" uid="uid://bffhb5krs5elm" path="res://Enemies/Crystalisk/airenemy2.tres" id="13_xb7gj"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cr1ucbuw3iotp" path="res://Assets/Textures/first_win_achievements.png" id="15_74epv"]
|
[ext_resource type="Texture2D" uid="uid://cr1ucbuw3iotp" path="res://Assets/Textures/first_win_achievements.png" id="15_74epv"]
|
||||||
[ext_resource type="Script" uid="uid://cjr0pbqisd51v" path="res://Scenes/Menus/MainMenu/achievements_menu.gd" id="15_sv1gy"]
|
[ext_resource type="Script" uid="uid://cjr0pbqisd51v" path="res://Scenes/Menus/MainMenu/achievements_menu.gd" id="15_sv1gy"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cpa1hl36xfplg" path="res://Assets/Textures/first_scroll_seen.png" id="16_sv1gy"]
|
[ext_resource type="Texture2D" uid="uid://cpa1hl36xfplg" path="res://Assets/Textures/first_scroll_seen.png" id="16_sv1gy"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ctbi3gm1me1t5" path="res://Assets/Textures/unlock_mage_achievement.png" id="17_6t4jd"]
|
[ext_resource type="Texture2D" uid="uid://ctbi3gm1me1t5" path="res://Assets/Textures/unlock_mage_achievement.png" id="17_6t4jd"]
|
||||||
[ext_resource type="Script" uid="uid://cxrm2naq75jo1" path="res://mod_menu.gd" id="19_6t4jd"]
|
[ext_resource type="Script" uid="uid://cxrm2naq75jo1" path="res://mod_menu.gd" id="19_6t4jd"]
|
||||||
|
[ext_resource type="FontFile" uid="uid://c3hwdjscf2hnk" path="res://Assets/Fonts/OpenType (.otf)/Kaph-Regular.otf" id="20_y5bw6"]
|
||||||
|
|
||||||
[sub_resource type="ViewportTexture" id="ViewportTexture_5u75i"]
|
[sub_resource type="ViewportTexture" id="ViewportTexture_5u75i"]
|
||||||
viewport_path = NodePath("SubViewport")
|
viewport_path = NodePath("SubViewport")
|
||||||
@ -94,29 +94,33 @@ grow_horizontal = 2
|
|||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
texture = SubResource("ViewportTexture_5u75i")
|
texture = SubResource("ViewportTexture_5u75i")
|
||||||
|
|
||||||
[node name="TextureRect2" type="TextureRect" parent="."]
|
[node name="TitleLabel" type="Label" parent="."]
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 5
|
|
||||||
anchor_left = 0.5
|
|
||||||
anchor_right = 0.5
|
|
||||||
offset_left = -627.0
|
|
||||||
offset_top = 73.0
|
|
||||||
offset_right = 1293.0
|
|
||||||
offset_bottom = 1153.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
scale = Vector2(0.67, 0.67)
|
|
||||||
texture = ExtResource("3_8jkeb")
|
|
||||||
expand_mode = 1
|
|
||||||
|
|
||||||
[node name="MainControls" type="VBoxContainer" parent="."]
|
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = -1
|
anchors_preset = -1
|
||||||
anchor_top = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 0.5
|
||||||
offset_left = 130.0
|
grow_horizontal = 2
|
||||||
offset_top = -188.0
|
theme_override_colors/font_color = Color(0.8, 0.5644, 0.344, 1)
|
||||||
offset_right = 143.0
|
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
|
||||||
offset_bottom = -80.0
|
theme_override_constants/line_spacing = -35
|
||||||
|
theme_override_constants/outline_size = 55
|
||||||
|
theme_override_fonts/font = ExtResource("20_y5bw6")
|
||||||
|
theme_override_font_sizes/font_size = 146
|
||||||
|
text = "decked
|
||||||
|
out
|
||||||
|
defense"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
|
||||||
|
[node name="MainControls" type="HBoxContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = -1
|
||||||
|
anchor_left = 0.05
|
||||||
|
anchor_top = 0.95
|
||||||
|
anchor_right = 0.95
|
||||||
|
anchor_bottom = 0.95
|
||||||
|
offset_top = -60.0
|
||||||
|
grow_horizontal = 2
|
||||||
grow_vertical = 0
|
grow_vertical = 0
|
||||||
|
|
||||||
[node name="PlayButton" type="Button" parent="MainControls"]
|
[node name="PlayButton" type="Button" parent="MainControls"]
|
||||||
@ -125,6 +129,7 @@ text = "Play"
|
|||||||
|
|
||||||
[node name="MultiplayerButton" type="Button" parent="MainControls"]
|
[node name="MultiplayerButton" type="Button" parent="MainControls"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
disabled = true
|
||||||
text = "Multiplayer"
|
text = "Multiplayer"
|
||||||
|
|
||||||
[node name="ModsButton" type="Button" parent="MainControls"]
|
[node name="ModsButton" type="Button" parent="MainControls"]
|
||||||
@ -144,14 +149,12 @@ text = "Quit
|
|||||||
[node name="ProfileEditor" type="PanelContainer" parent="."]
|
[node name="ProfileEditor" type="PanelContainer" parent="."]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = -1
|
anchors_preset = -1
|
||||||
anchor_left = 1.0
|
anchor_left = 0.97
|
||||||
anchor_top = 1.0
|
anchor_top = 0.95
|
||||||
anchor_right = 1.0
|
anchor_right = 0.97
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 0.95
|
||||||
offset_left = -429.0
|
offset_left = -421.0
|
||||||
offset_top = -140.0
|
offset_top = -150.0
|
||||||
offset_right = -55.0
|
|
||||||
offset_bottom = -40.0
|
|
||||||
grow_horizontal = 0
|
grow_horizontal = 0
|
||||||
grow_vertical = 0
|
grow_vertical = 0
|
||||||
|
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
class_name PauseMenu extends Control
|
class_name PauseMenu extends Control
|
||||||
|
|
||||||
signal closed()
|
signal closed
|
||||||
|
signal quit_to_main_menu_pressed
|
||||||
|
signal quit_to_desktop_pressed
|
||||||
|
|
||||||
var options_menu_scene: PackedScene = preload("res://Scenes/Menus/options_menu.tscn")
|
var options_menu_scene: PackedScene = preload("res://Scenes/Menus/options_menu.tscn")
|
||||||
var confirmation_popup_scene: PackedScene = preload("res://Scenes/Menus/confirmation_popup.tscn")
|
var confirmation_popup_scene: PackedScene = preload("res://Scenes/Menus/confirmation_popup.tscn")
|
||||||
|
var game_manager: GameManager
|
||||||
|
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
func _unhandled_input(event: InputEvent) -> void:
|
||||||
@ -19,6 +22,7 @@ func _on_resume_pressed() -> void:
|
|||||||
|
|
||||||
func _on_options_pressed() -> void:
|
func _on_options_pressed() -> void:
|
||||||
var menu: OptionsMenu = options_menu_scene.instantiate()
|
var menu: OptionsMenu = options_menu_scene.instantiate()
|
||||||
|
menu.game_manager = game_manager
|
||||||
add_child(menu)
|
add_child(menu)
|
||||||
|
|
||||||
|
|
||||||
@ -31,7 +35,7 @@ func _on_quit_to_main_menu_pressed() -> void:
|
|||||||
|
|
||||||
func return_to_menu(confirmation: bool) -> void:
|
func return_to_menu(confirmation: bool) -> void:
|
||||||
if confirmation:
|
if confirmation:
|
||||||
Game.scene_switch_main_menu()
|
quit_to_main_menu_pressed.emit()
|
||||||
|
|
||||||
|
|
||||||
func _on_quit_to_desktop_pressed() -> void:
|
func _on_quit_to_desktop_pressed() -> void:
|
||||||
@ -43,7 +47,7 @@ func _on_quit_to_desktop_pressed() -> void:
|
|||||||
|
|
||||||
func quit_game(confirmation: bool) -> void:
|
func quit_game(confirmation: bool) -> void:
|
||||||
if confirmation:
|
if confirmation:
|
||||||
Game.quit_to_desktop()
|
quit_to_desktop_pressed.emit()
|
||||||
|
|
||||||
|
|
||||||
func _on_button_mouse_entered() -> void:
|
func _on_button_mouse_entered() -> void:
|
||||||
|
@ -42,7 +42,7 @@ func randomize_cards() -> void:
|
|||||||
var chosen_card: Card = null
|
var chosen_card: Card = null
|
||||||
for x: int in 3:
|
for x: int in 3:
|
||||||
if cheap_cards.size() > 0:
|
if cheap_cards.size() > 0:
|
||||||
chosen_card = cheap_cards[Game.randi_in_range(12 * cards_generated, 0, cheap_cards.size() - 1)]
|
chosen_card = cheap_cards[NoiseRandom.randi_in_range(12 * cards_generated, 0, cheap_cards.size() - 1)]
|
||||||
cards_generated += 1
|
cards_generated += 1
|
||||||
if chosen_card != null:
|
if chosen_card != null:
|
||||||
cards[x].set_card(chosen_card)
|
cards[x].set_card(chosen_card)
|
||||||
@ -53,9 +53,9 @@ func randomize_cards() -> void:
|
|||||||
Data.save_data.saw_mage_card_in_shop()
|
Data.save_data.saw_mage_card_in_shop()
|
||||||
for x: int in 2:
|
for x: int in 2:
|
||||||
if medium_cards.size() > 0:
|
if medium_cards.size() > 0:
|
||||||
chosen_card = medium_cards[Game.randi_in_range(9 * cards_generated, 0, medium_cards.size() - 1)]
|
chosen_card = medium_cards[NoiseRandom.randi_in_range(9 * cards_generated, 0, medium_cards.size() - 1)]
|
||||||
elif cheap_cards.size() > 0:
|
elif cheap_cards.size() > 0:
|
||||||
chosen_card = cheap_cards[Game.randi_in_range(9 * cards_generated, 0, cheap_cards.size() - 1)]
|
chosen_card = cheap_cards[NoiseRandom.randi_in_range(9 * cards_generated, 0, cheap_cards.size() - 1)]
|
||||||
cards_generated += 1
|
cards_generated += 1
|
||||||
if chosen_card != null:
|
if chosen_card != null:
|
||||||
cards[x+3].set_card(chosen_card)
|
cards[x+3].set_card(chosen_card)
|
||||||
@ -66,11 +66,11 @@ func randomize_cards() -> void:
|
|||||||
Data.save_data.saw_mage_card_in_shop()
|
Data.save_data.saw_mage_card_in_shop()
|
||||||
for x: int in 1:
|
for x: int in 1:
|
||||||
if pricey_cards.size() > 0:
|
if pricey_cards.size() > 0:
|
||||||
chosen_card = pricey_cards[Game.randi_in_range(50 * cards_generated, 0, pricey_cards.size() - 1)]
|
chosen_card = pricey_cards[NoiseRandom.randi_in_range(50 * cards_generated, 0, pricey_cards.size() - 1)]
|
||||||
elif medium_cards.size() > 0:
|
elif medium_cards.size() > 0:
|
||||||
chosen_card = medium_cards[Game.randi_in_range(50 * cards_generated, 0, medium_cards.size() - 1)]
|
chosen_card = medium_cards[NoiseRandom.randi_in_range(50 * cards_generated, 0, medium_cards.size() - 1)]
|
||||||
elif cheap_cards.size() > 0:
|
elif cheap_cards.size() > 0:
|
||||||
chosen_card = cheap_cards[Game.randi_in_range(50 * cards_generated, 0, cheap_cards.size() - 1)]
|
chosen_card = cheap_cards[NoiseRandom.randi_in_range(50 * cards_generated, 0, cheap_cards.size() - 1)]
|
||||||
cards_generated += 1
|
cards_generated += 1
|
||||||
if chosen_card != null:
|
if chosen_card != null:
|
||||||
cards[x+5].set_card(chosen_card)
|
cards[x+5].set_card(chosen_card)
|
||||||
|
@ -9,7 +9,6 @@ texture = ExtResource("1_kau30")
|
|||||||
|
|
||||||
[sub_resource type="VisualShaderNodeTexture2DParameter" id="VisualShaderNodeTexture2DParameter_hqcdo"]
|
[sub_resource type="VisualShaderNodeTexture2DParameter" id="VisualShaderNodeTexture2DParameter_hqcdo"]
|
||||||
parameter_name = "Texture2DParameter"
|
parameter_name = "Texture2DParameter"
|
||||||
qualifier = 2
|
|
||||||
texture_type = 1
|
texture_type = 1
|
||||||
texture_filter = 1
|
texture_filter = 1
|
||||||
|
|
||||||
@ -17,7 +16,6 @@ texture_filter = 1
|
|||||||
output_port_for_preview = 0
|
output_port_for_preview = 0
|
||||||
expanded_output_ports = [0]
|
expanded_output_ports = [0]
|
||||||
parameter_name = "Color"
|
parameter_name = "Color"
|
||||||
qualifier = 2
|
|
||||||
default_value_enabled = true
|
default_value_enabled = true
|
||||||
default_value = Color(0, 1, 0, 0.752941)
|
default_value = Color(0, 1, 0, 0.752941)
|
||||||
|
|
||||||
@ -51,7 +49,6 @@ op_type = 2
|
|||||||
|
|
||||||
[sub_resource type="VisualShaderNodeFloatParameter" id="VisualShaderNodeFloatParameter_8utgl"]
|
[sub_resource type="VisualShaderNodeFloatParameter" id="VisualShaderNodeFloatParameter_8utgl"]
|
||||||
parameter_name = "Float"
|
parameter_name = "Float"
|
||||||
qualifier = 2
|
|
||||||
default_value_enabled = true
|
default_value_enabled = true
|
||||||
default_value = 1.0
|
default_value = 1.0
|
||||||
|
|
||||||
@ -80,8 +77,8 @@ render_mode blend_mix, depth_draw_always, cull_back, diffuse_lambert, specular_s
|
|||||||
|
|
||||||
uniform sampler2D Texture2DParameter : source_color, filter_nearest;
|
uniform sampler2D Texture2DParameter : source_color, filter_nearest;
|
||||||
uniform sampler2D tex_frg_7;
|
uniform sampler2D tex_frg_7;
|
||||||
instance uniform float Float = 1.0;
|
uniform float Float = 1.0;
|
||||||
instance uniform vec4 Color : source_color = vec4(0.000000, 1.000000, 0.000000, 0.752941);
|
uniform vec4 Color : source_color = vec4(0.000000, 1.000000, 0.000000, 0.752941);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -150,6 +147,8 @@ void fragment() {
|
|||||||
"
|
"
|
||||||
modes/depth_draw = 1
|
modes/depth_draw = 1
|
||||||
flags/depth_prepass_alpha = true
|
flags/depth_prepass_alpha = true
|
||||||
|
preview_params/Texture2DParameter = "Resource(\"res://Scenes/TowerBase/funboxtex.png\")"
|
||||||
|
preview_params/Float = "1.0"
|
||||||
nodes/fragment/0/position = Vector2(1220, 280)
|
nodes/fragment/0/position = Vector2(1220, 280)
|
||||||
nodes/fragment/2/node = SubResource("VisualShaderNodeInput_nxokf")
|
nodes/fragment/2/node = SubResource("VisualShaderNodeInput_nxokf")
|
||||||
nodes/fragment/2/position = Vector2(-580, 180)
|
nodes/fragment/2/position = Vector2(-580, 180)
|
||||||
@ -162,11 +161,11 @@ nodes/fragment/8/position = Vector2(-60, 340)
|
|||||||
nodes/fragment/9/node = SubResource("VisualShaderNodeFloatFunc_h0gpf")
|
nodes/fragment/9/node = SubResource("VisualShaderNodeFloatFunc_h0gpf")
|
||||||
nodes/fragment/9/position = Vector2(140, 360)
|
nodes/fragment/9/position = Vector2(140, 360)
|
||||||
nodes/fragment/13/node = SubResource("VisualShaderNodeTexture_ugjxq")
|
nodes/fragment/13/node = SubResource("VisualShaderNodeTexture_ugjxq")
|
||||||
nodes/fragment/13/position = Vector2(260, 140)
|
nodes/fragment/13/position = Vector2(260, 120)
|
||||||
nodes/fragment/14/node = SubResource("VisualShaderNodeTexture2DParameter_hqcdo")
|
nodes/fragment/14/node = SubResource("VisualShaderNodeTexture2DParameter_hqcdo")
|
||||||
nodes/fragment/14/position = Vector2(-60, 0)
|
nodes/fragment/14/position = Vector2(-60, -240)
|
||||||
nodes/fragment/15/node = SubResource("VisualShaderNodeColorParameter_rwgpq")
|
nodes/fragment/15/node = SubResource("VisualShaderNodeColorParameter_rwgpq")
|
||||||
nodes/fragment/15/position = Vector2(40, 940)
|
nodes/fragment/15/position = Vector2(20, 1040)
|
||||||
nodes/fragment/18/node = SubResource("VisualShaderNodeVectorOp_g2jnk")
|
nodes/fragment/18/node = SubResource("VisualShaderNodeVectorOp_g2jnk")
|
||||||
nodes/fragment/18/position = Vector2(500, 340)
|
nodes/fragment/18/position = Vector2(500, 340)
|
||||||
nodes/fragment/19/node = SubResource("VisualShaderNodeVectorOp_ddxtc")
|
nodes/fragment/19/node = SubResource("VisualShaderNodeVectorOp_ddxtc")
|
||||||
|
@ -33,15 +33,19 @@ animation/remove_immutable_tracks=true
|
|||||||
animation/import_rest_as_RESET=false
|
animation/import_rest_as_RESET=false
|
||||||
import_script/path=""
|
import_script/path=""
|
||||||
_subresources={
|
_subresources={
|
||||||
|
"materials": {
|
||||||
|
"Material": {
|
||||||
|
"use_external/enabled": true,
|
||||||
|
"use_external/path": "uid://dsi0ofa74tfc4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"meshes": {
|
"meshes": {
|
||||||
"funbox_Cube_001": {
|
"funbox_Cube_001": {
|
||||||
"generate/lightmap_uv": 0,
|
"generate/lightmap_uv": 0,
|
||||||
"generate/lods": 0,
|
"generate/lods": 0,
|
||||||
"generate/shadow_meshes": 0,
|
"generate/shadow_meshes": 0,
|
||||||
"lods/normal_merge_angle": 60.0,
|
"lods/normal_merge_angle": 60.0,
|
||||||
"lods/normal_split_angle": 25.0,
|
"save_to_file/enabled": true,
|
||||||
"save_to_file/enabled": false,
|
|
||||||
"save_to_file/make_streamable": "",
|
|
||||||
"save_to_file/path": "res://textmesh.res"
|
"save_to_file/path": "res://textmesh.res"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
Scenes/TowerBase/new_shader_material.tres
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://bi0grduhgdma4"]
|
||||||
|
|
||||||
|
[ext_resource type="Shader" uid="uid://dsi0ofa74tfc4" path="res://Scenes/TowerBase/dissolve.tres" id="1_id1v3"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://bmor4v4j7krgh" path="res://Scenes/TowerBase/funboxtex.png" id="2_8kmo6"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
resource_local_to_scene = true
|
||||||
|
render_priority = 0
|
||||||
|
shader = ExtResource("1_id1v3")
|
||||||
|
shader_parameter/Texture2DParameter = ExtResource("2_8kmo6")
|
||||||
|
shader_parameter/Float = 1.0
|
||||||
|
shader_parameter/Color = Color(0, 1, 0, 0.752941)
|
59
Scenes/TowerBase/tower_base.gd
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
class_name TowerBase extends StaticBody3D
|
||||||
|
|
||||||
|
@export var inventory: Inventory
|
||||||
|
@export var block: Node3D
|
||||||
|
@export var collider: CollisionShape3D
|
||||||
|
@export var minimap_icon: Sprite3D
|
||||||
|
|
||||||
|
var game_manager: GameManager
|
||||||
|
var owner_id: int
|
||||||
|
var point: FlowNode
|
||||||
|
var tower: Tower = null
|
||||||
|
var has_card: bool :
|
||||||
|
set(_value):
|
||||||
|
return
|
||||||
|
get:
|
||||||
|
return inventory.size != 0
|
||||||
|
|
||||||
|
|
||||||
|
func set_color(color: Color) -> void:
|
||||||
|
$MeshInstance3D.material_override.set("shader_parameter/Color", color)
|
||||||
|
|
||||||
|
|
||||||
|
func set_float(value: float) -> void:
|
||||||
|
$MeshInstance3D.material_override.set("shader_parameter/Float", value)
|
||||||
|
|
||||||
|
|
||||||
|
func add_card(card: Card, caller_id: int) -> void:
|
||||||
|
networked_spawn_tower.rpc(Data.cards.find(card), caller_id)
|
||||||
|
|
||||||
|
|
||||||
|
func remove_card() -> void:
|
||||||
|
networked_remove_tower.rpc()
|
||||||
|
|
||||||
|
|
||||||
|
func toggle_collision() -> void:
|
||||||
|
collider.disabled = !collider.disabled
|
||||||
|
|
||||||
|
|
||||||
|
@rpc("reliable", "call_local", "any_peer")
|
||||||
|
func networked_spawn_tower(card_index: int, caller_id: int) -> void:
|
||||||
|
var card: Card = Data.cards[card_index]
|
||||||
|
inventory.add(card)
|
||||||
|
tower = inventory.contents.keys()[0].turret_scene.instantiate() as Tower
|
||||||
|
tower.stats = inventory.contents.keys()[0].tower_stats
|
||||||
|
tower.name = "tower"
|
||||||
|
tower.base_name = name
|
||||||
|
tower.owner_id = caller_id
|
||||||
|
tower.position = Vector3(0, 1.2, 0)
|
||||||
|
minimap_icon.modulate = Color.RED
|
||||||
|
add_child(tower)
|
||||||
|
|
||||||
|
|
||||||
|
@rpc("reliable", "call_local", "any_peer")
|
||||||
|
func networked_remove_tower() -> void:
|
||||||
|
game_manager.connected_players_nodes[tower.owner_id].add_card(inventory.remove_at(0))
|
||||||
|
game_manager.connected_players_nodes[tower.owner_id].unready_self()
|
||||||
|
tower.queue_free()
|
||||||
|
tower = null
|
||||||
|
minimap_icon.modulate = Color.GREEN
|
@ -1,56 +1,33 @@
|
|||||||
[gd_scene load_steps=10 format=3 uid="uid://ddbbwx0yy16lh"]
|
[gd_scene load_steps=7 format=3 uid="uid://ddbbwx0yy16lh"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://si58bm4r7r2i" path="res://Scripts/tower_base.gd" id="1_kalmg"]
|
[ext_resource type="Script" uid="uid://si58bm4r7r2i" path="res://Scenes/TowerBase/tower_base.gd" id="1_kalmg"]
|
||||||
[ext_resource type="Script" uid="uid://do24iuot0j7d7" path="res://Scripts/inventory.gd" id="2_m0oxx"]
|
[ext_resource type="Script" uid="uid://do24iuot0j7d7" path="res://Scripts/inventory.gd" id="2_m0oxx"]
|
||||||
[ext_resource type="ArrayMesh" uid="uid://cr83c74ys8rll" path="res://Scenes/TowerBase/textmesh.res" id="3_ly30x"]
|
[ext_resource type="Material" uid="uid://bi0grduhgdma4" path="res://Scenes/TowerBase/new_shader_material.tres" id="3_ueedj"]
|
||||||
|
[ext_resource type="ArrayMesh" uid="uid://cm5xjp442ew0y" path="res://textmesh.res" id="4_8j8ue"]
|
||||||
[ext_resource type="Texture2D" uid="uid://ba85u6i558x4w" path="res://Assets/Textures/minimap_node.png" id="4_lbvtm"]
|
[ext_resource type="Texture2D" uid="uid://ba85u6i558x4w" path="res://Assets/Textures/minimap_node.png" id="4_lbvtm"]
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_lc72v"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_lc72v"]
|
||||||
size = Vector3(1.1, 1.1, 1.1)
|
size = Vector3(1.381, 1.377, 1.381)
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_o3uwr"]
|
[node name="TowerBase" type="StaticBody3D" node_paths=PackedStringArray("inventory", "block", "collider", "minimap_icon") groups=["TowerBases"]]
|
||||||
albedo_color = Color(0.462745, 0.439216, 0.415686, 1)
|
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1i074"]
|
|
||||||
albedo_color = Color(0.462745, 0.439216, 0.415686, 1)
|
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_jt61s"]
|
|
||||||
albedo_color = Color(0.462745, 0.439216, 0.415686, 1)
|
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_t32n1"]
|
|
||||||
albedo_color = Color(0.462745, 0.439216, 0.415686, 1)
|
|
||||||
|
|
||||||
[node name="Node3D" type="StaticBody3D" node_paths=PackedStringArray("inventory", "block", "collider", "minimap_icon", "north_icon", "south_icon", "east_icon", "west_icon", "north_mesh", "south_mesh", "east_mesh", "west_mesh", "north_collider", "south_collider", "east_collider", "west_collider") groups=["TowerBases"]]
|
|
||||||
collision_layer = 17
|
collision_layer = 17
|
||||||
script = ExtResource("1_kalmg")
|
script = ExtResource("1_kalmg")
|
||||||
inventory = NodePath("Inventory")
|
inventory = NodePath("Inventory")
|
||||||
block = NodePath("MeshInstance3D")
|
block = NodePath("MeshInstance3D")
|
||||||
collider = NodePath("CollisionShape3D")
|
collider = NodePath("CollisionShape3D")
|
||||||
minimap_icon = NodePath("MinimapIcon")
|
minimap_icon = NodePath("MinimapIcon")
|
||||||
north_icon = NodePath("North/NorthMinimapIcon")
|
|
||||||
south_icon = NodePath("South/SouthMinimapIcon")
|
|
||||||
east_icon = NodePath("East/EastMinimapIcon")
|
|
||||||
west_icon = NodePath("West/WestMinimapIcon")
|
|
||||||
north_mesh = NodePath("North")
|
|
||||||
south_mesh = NodePath("South")
|
|
||||||
east_mesh = NodePath("East")
|
|
||||||
west_mesh = NodePath("West")
|
|
||||||
north_collider = NodePath("CollisionShape3D2")
|
|
||||||
south_collider = NodePath("CollisionShape3D3")
|
|
||||||
east_collider = NodePath("CollisionShape3D5")
|
|
||||||
west_collider = NodePath("CollisionShape3D4")
|
|
||||||
|
|
||||||
[node name="Inventory" type="Node" parent="."]
|
[node name="Inventory" type="Node" parent="."]
|
||||||
script = ExtResource("2_m0oxx")
|
script = ExtResource("2_m0oxx")
|
||||||
max_size = 1
|
max_size = 1
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.688315, 0.00199121)
|
||||||
shape = SubResource("BoxShape3D_lc72v")
|
shape = SubResource("BoxShape3D_lc72v")
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, 0)
|
material_override = ExtResource("3_ueedj")
|
||||||
mesh = ExtResource("3_ly30x")
|
mesh = ExtResource("4_8j8ue")
|
||||||
|
|
||||||
[node name="MinimapIcon" type="Sprite3D" parent="."]
|
[node name="MinimapIcon" type="Sprite3D" parent="."]
|
||||||
transform = Transform3D(3.5, 0, 0, 0, -1.5299e-07, 3.5, 0, -3.5, -1.5299e-07, 0, 1.5, 0)
|
transform = Transform3D(3.5, 0, 0, 0, -1.5299e-07, 3.5, 0, -3.5, -1.5299e-07, 0, 1.5, 0)
|
||||||
@ -58,79 +35,3 @@ layers = 4
|
|||||||
modulate = Color(0, 1, 0, 1)
|
modulate = Color(0, 1, 0, 1)
|
||||||
texture_filter = 0
|
texture_filter = 0
|
||||||
texture = ExtResource("4_lbvtm")
|
texture = ExtResource("4_lbvtm")
|
||||||
|
|
||||||
[node name="North" type="CSGBox3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0.45, 0)
|
|
||||||
visible = false
|
|
||||||
size = Vector3(1, 0.9, 0.5)
|
|
||||||
material = SubResource("StandardMaterial3D_o3uwr")
|
|
||||||
|
|
||||||
[node name="NorthMinimapIcon" type="Sprite3D" parent="North"]
|
|
||||||
transform = Transform3D(3.5, 0, 0, 0, -6.7097e-08, 3.5, 0, -1.535, -1.5299e-07, 0.0251597, 1, 0)
|
|
||||||
layers = 4
|
|
||||||
modulate = Color(0, 1, 0, 1)
|
|
||||||
texture_filter = 0
|
|
||||||
texture = ExtResource("4_lbvtm")
|
|
||||||
|
|
||||||
[node name="CollisionShape3D2" type="CollisionShape3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0.55, 0)
|
|
||||||
visible = false
|
|
||||||
shape = SubResource("BoxShape3D_lc72v")
|
|
||||||
disabled = true
|
|
||||||
|
|
||||||
[node name="South" type="CSGBox3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.45, 0)
|
|
||||||
visible = false
|
|
||||||
size = Vector3(1, 0.9, 0.5)
|
|
||||||
material = SubResource("StandardMaterial3D_1i074")
|
|
||||||
|
|
||||||
[node name="SouthMinimapIcon" type="Sprite3D" parent="South"]
|
|
||||||
transform = Transform3D(3.5, 0, 0, 0, -6.7097e-08, 3.5, 0, -1.535, -1.5299e-07, -0.0251607, 1, 0)
|
|
||||||
layers = 4
|
|
||||||
modulate = Color(0, 1, 0, 1)
|
|
||||||
texture_filter = 0
|
|
||||||
texture = ExtResource("4_lbvtm")
|
|
||||||
|
|
||||||
[node name="CollisionShape3D3" type="CollisionShape3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.55, 0)
|
|
||||||
visible = false
|
|
||||||
shape = SubResource("BoxShape3D_lc72v")
|
|
||||||
disabled = true
|
|
||||||
|
|
||||||
[node name="East" type="CSGBox3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.45, -0.5)
|
|
||||||
visible = false
|
|
||||||
size = Vector3(0.5, 0.9, 1)
|
|
||||||
material = SubResource("StandardMaterial3D_jt61s")
|
|
||||||
|
|
||||||
[node name="EastMinimapIcon" type="Sprite3D" parent="East"]
|
|
||||||
transform = Transform3D(1.535, 0, 0, 0, -1.5299e-07, 3.5, 0, -3.5, -1.5299e-07, 0, 1, 0.0248078)
|
|
||||||
layers = 4
|
|
||||||
modulate = Color(0, 1, 0, 1)
|
|
||||||
texture_filter = 0
|
|
||||||
texture = ExtResource("4_lbvtm")
|
|
||||||
|
|
||||||
[node name="CollisionShape3D5" type="CollisionShape3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, -0.5)
|
|
||||||
visible = false
|
|
||||||
shape = SubResource("BoxShape3D_lc72v")
|
|
||||||
disabled = true
|
|
||||||
|
|
||||||
[node name="West" type="CSGBox3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.45, 0.5)
|
|
||||||
visible = false
|
|
||||||
size = Vector3(0.5, 0.9, 1)
|
|
||||||
material = SubResource("StandardMaterial3D_t32n1")
|
|
||||||
|
|
||||||
[node name="WestMinimapIcon" type="Sprite3D" parent="West"]
|
|
||||||
transform = Transform3D(1.535, 0, 0, 0, -1.5299e-07, 3.5, 0, -3.5, -1.5299e-07, 0, 1, -0.0252527)
|
|
||||||
layers = 4
|
|
||||||
modulate = Color(0, 1, 0, 1)
|
|
||||||
texture_filter = 0
|
|
||||||
texture = ExtResource("4_lbvtm")
|
|
||||||
|
|
||||||
[node name="CollisionShape3D4" type="CollisionShape3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, 0.5)
|
|
||||||
visible = false
|
|
||||||
shape = SubResource("BoxShape3D_lc72v")
|
|
||||||
disabled = true
|
|
||||||
|
@ -17,27 +17,27 @@ albedo_color = Color(0.356863, 0.87451, 0.94902, 1)
|
|||||||
[node name="Node3D" type="Node3D"]
|
[node name="Node3D" type="Node3D"]
|
||||||
|
|
||||||
[node name="CSGBox3D2" type="CSGBox3D" parent="."]
|
[node name="CSGBox3D2" type="CSGBox3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.02, 0.475)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.02, 0.625)
|
||||||
size = Vector3(1, 0.04, 0.05)
|
size = Vector3(1.25, 0.04, 0.05)
|
||||||
material = SubResource("StandardMaterial3D_xt3aj")
|
material = SubResource("StandardMaterial3D_xt3aj")
|
||||||
|
|
||||||
[node name="CSGBox3D3" type="CSGBox3D" parent="."]
|
[node name="CSGBox3D3" type="CSGBox3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.02, -0.475)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.02, -0.625)
|
||||||
size = Vector3(1, 0.04, 0.05)
|
size = Vector3(1.25, 0.04, 0.05)
|
||||||
material = SubResource("StandardMaterial3D_gbm1j")
|
material = SubResource("StandardMaterial3D_gbm1j")
|
||||||
|
|
||||||
[node name="CSGBox3D4" type="CSGBox3D" parent="."]
|
[node name="CSGBox3D4" type="CSGBox3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.475, 0.02, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.625, 0.02, 0)
|
||||||
size = Vector3(0.05, 0.04, 1)
|
size = Vector3(0.05, 0.04, 1.3)
|
||||||
material = SubResource("StandardMaterial3D_18qg8")
|
material = SubResource("StandardMaterial3D_18qg8")
|
||||||
|
|
||||||
[node name="CSGBox3D5" type="CSGBox3D" parent="."]
|
[node name="CSGBox3D5" type="CSGBox3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.475, 0.02, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.625, 0.02, 0)
|
||||||
size = Vector3(0.05, 0.04, 1)
|
size = Vector3(0.05, 0.04, 1.3)
|
||||||
material = SubResource("StandardMaterial3D_ip8b2")
|
material = SubResource("StandardMaterial3D_ip8b2")
|
||||||
|
|
||||||
[node name="Sprite3D" type="Sprite3D" parent="."]
|
[node name="Sprite3D" type="Sprite3D" parent="."]
|
||||||
transform = Transform3D(3.5, 0, 0, 0, -1.5299e-07, 3.5, 0, -3.5, -1.5299e-07, 0, 0, 0)
|
transform = Transform3D(4, 0, 0, 0, -1.74846e-07, 4, 0, -4, -1.74846e-07, 0, 0, 0)
|
||||||
layers = 4
|
layers = 4
|
||||||
texture_filter = 0
|
texture_filter = 0
|
||||||
texture = ExtResource("1_phew5")
|
texture = ExtResource("1_phew5")
|
||||||
|
@ -11,9 +11,9 @@ func apply_effect(effect: Effect, targets: Array[EnemyController]) -> void:
|
|||||||
if targets.has(enemy):
|
if targets.has(enemy):
|
||||||
enemy.apply_effect(effect)
|
enemy.apply_effect(effect)
|
||||||
if Data.preferences.display_tower_damage_indicators and effect.damage > 0:
|
if Data.preferences.display_tower_damage_indicators and effect.damage > 0:
|
||||||
spawn_damage_indicator(effect.damage, enemy.sprite.global_position)
|
spawn_damage_indicator(effect.damage, enemy.d_n.global_position)
|
||||||
else:
|
else:
|
||||||
for enemy: EnemyController in targets:
|
for enemy: EnemyController in targets:
|
||||||
enemy.apply_effect(effect)
|
enemy.apply_effect(effect)
|
||||||
if Data.preferences.display_tower_damage_indicators and effect.damage > 0:
|
if Data.preferences.display_tower_damage_indicators and effect.damage > 0:
|
||||||
spawn_damage_indicator(effect.damage, enemy.sprite.global_position)
|
spawn_damage_indicator(effect.damage, enemy.d_n.global_position)
|
||||||
|
@ -5,4 +5,4 @@ func apply_effect(effect: Effect, targets: Array[EnemyController]) -> void:
|
|||||||
for enemy: EnemyController in targets:
|
for enemy: EnemyController in targets:
|
||||||
enemy.apply_effect(effect)
|
enemy.apply_effect(effect)
|
||||||
if Data.preferences.display_tower_damage_indicators and effect.damage > 0:
|
if Data.preferences.display_tower_damage_indicators and effect.damage > 0:
|
||||||
spawn_damage_indicator(effect.damage, enemy.sprite.global_position)
|
spawn_damage_indicator(effect.damage, enemy.d_n.global_position)
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
class_name EnemyMovement extends Node
|
class_name EnemyMovement extends Node
|
||||||
|
|
||||||
@export var character: CharacterBody3D
|
@export var character: EnemyController
|
||||||
|
|
||||||
var astar: AStarGraph3D
|
|
||||||
var distance_remaining: float = 0.0
|
var distance_remaining: float = 0.0
|
||||||
|
var speed: float = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
#TODO: make deterministic random
|
||||||
|
var variance: float = randf_range(-1.0, 1.0)
|
||||||
|
var variance_max: float = 0.03 # Enemy speed can vary by 3% from their base speed
|
||||||
|
speed = character.stats.movement_speed + (variance * variance_max)
|
||||||
|
@ -10,6 +10,7 @@ class_name LeapingController extends PathingController
|
|||||||
@export var souths: Sprite3D
|
@export var souths: Sprite3D
|
||||||
@export var box: CSGBox3D
|
@export var box: CSGBox3D
|
||||||
@export var tol: Label
|
@export var tol: Label
|
||||||
|
@export var jump_distance: float = 4.0
|
||||||
|
|
||||||
var tolerance: float = 50.0
|
var tolerance: float = 50.0
|
||||||
var jumping: bool = false
|
var jumping: bool = false
|
||||||
@ -21,20 +22,19 @@ func _process(delta: float) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
if !path or jumping:
|
if !next_node or jumping:
|
||||||
return
|
return
|
||||||
var distance_travelled: float = (character.stats.movement_speed * clampf(character.movement_speed_penalty, 0.0, 1.0)) * delta
|
walk(delta)
|
||||||
distance_remaining -= distance_travelled
|
consider_leap(Vector3.FORWARD)
|
||||||
path_progress += distance_travelled
|
consider_leap(Vector3.LEFT)
|
||||||
var sample: Transform3D = path.sample_baked_with_rotation(path_progress, true)
|
consider_leap(Vector3.BACK)
|
||||||
character.global_position = sample.origin
|
consider_leap(Vector3.RIGHT)
|
||||||
character.look_at(character.global_position + -sample.basis.z)
|
#var closest_point: int = astar.astar.get_closest_point(character.global_position, false)
|
||||||
var closest_point: int = astar.astar.get_closest_point(character.global_position, false)
|
#box.global_position = astar.astar.get_point_position(closest_point)
|
||||||
box.global_position = astar.astar.get_point_position(closest_point)
|
#var east: int = astar.get_east_point(closest_point)
|
||||||
var east: int = astar.get_east_point(closest_point)
|
#var west: int = astar.get_west_point(closest_point)
|
||||||
var west: int = astar.get_west_point(closest_point)
|
#var north: int = astar.get_north_point(closest_point)
|
||||||
var north: int = astar.get_north_point(closest_point)
|
#var south: int = astar.get_south_point(closest_point)
|
||||||
var south: int = astar.get_south_point(closest_point)
|
|
||||||
#if east >= 0 and astar.astar.is_point_disabled(east):
|
#if east >= 0 and astar.astar.is_point_disabled(east):
|
||||||
#eastl.text = "fuck no"
|
#eastl.text = "fuck no"
|
||||||
#else:
|
#else:
|
||||||
@ -51,95 +51,117 @@ func _physics_process(delta: float) -> void:
|
|||||||
#southl.text = "fuck no"
|
#southl.text = "fuck no"
|
||||||
#else:
|
#else:
|
||||||
#southl.text = "yeah"
|
#southl.text = "yeah"
|
||||||
norths.global_position = character.global_position + Vector3(-1.0, 1.0, 0.0)
|
#norths.global_position = character.global_position + Vector3(-1.0, 1.0, 0.0)
|
||||||
souths.global_position = character.global_position + Vector3(1.0, 1.0, 0.0)
|
#souths.global_position = character.global_position + Vector3(1.0, 1.0, 0.0)
|
||||||
easts.global_position = character.global_position + Vector3(0.0, 1.0, -1.0)
|
#easts.global_position = character.global_position + Vector3(0.0, 1.0, -1.0)
|
||||||
wests.global_position = character.global_position + Vector3(0.0, 1.0, 1.0)
|
#wests.global_position = character.global_position + Vector3(0.0, 1.0, 1.0)
|
||||||
if east >= 0:
|
|
||||||
if astar.astar.is_point_disabled(east):
|
|
||||||
var further_point: int = astar.get_east_point(east)
|
|
||||||
if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
#if east >= 0:
|
||||||
var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(0.0, 0.0, -4.0))
|
#if astar.astar.is_point_disabled(east):
|
||||||
var current_offset: float = path.get_closest_offset(character.global_position)
|
#var further_point: int = astar.get_east_point(east)
|
||||||
var gain: float = expected_offset - current_offset
|
#if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||||
|
#var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(0.0, 0.0, -4.0))
|
||||||
|
#var current_offset: float = path.get_closest_offset(character.global_position)
|
||||||
|
#var gain: float = expected_offset - current_offset
|
||||||
|
#if gain >= tolerance:
|
||||||
|
#distance_remaining -= gain
|
||||||
|
##path_progress += gain
|
||||||
|
#leap(Vector3(0.0, 0.0, -4.0))
|
||||||
|
#eastl.text = str(gain)
|
||||||
|
##easts.visible = true
|
||||||
|
#else:
|
||||||
|
#eastl.text = "cant"
|
||||||
|
#else:
|
||||||
|
#eastl.text = "clear"
|
||||||
|
#else:
|
||||||
|
#eastl.text = "invalid"
|
||||||
|
#if west >= 0:
|
||||||
|
#if astar.astar.is_point_disabled(west):
|
||||||
|
#var further_point: int = astar.get_west_point(west)
|
||||||
|
#if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||||
|
#var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(0.0, 0.0, 4.0))
|
||||||
|
#var current_offset: float = path.get_closest_offset(character.global_position)
|
||||||
|
#var gain: float = expected_offset - current_offset
|
||||||
|
#if gain >= tolerance:
|
||||||
|
#distance_remaining -= gain
|
||||||
|
##path_progress += gain
|
||||||
|
#leap(Vector3(0.0, 0.0, 4.0))
|
||||||
|
#westl.text = str(gain)
|
||||||
|
##wests.visible = true
|
||||||
|
#else:
|
||||||
|
#westl.text = "cant"
|
||||||
|
#else:
|
||||||
|
#westl.text = "clear"
|
||||||
|
#else:
|
||||||
|
#westl.text = "invalid"
|
||||||
|
#if north >= 0:
|
||||||
|
#if astar.astar.is_point_disabled(north):
|
||||||
|
#var further_point: int = astar.get_north_point(north)
|
||||||
|
#if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||||
|
#var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(-4.0, 0.0, 0.0))
|
||||||
|
#var current_offset: float = path.get_closest_offset(character.global_position)
|
||||||
|
#var gain: float = expected_offset - current_offset
|
||||||
|
#if gain >= tolerance:
|
||||||
|
#distance_remaining -= gain
|
||||||
|
##path_progress += gain
|
||||||
|
#leap(Vector3(-4.0, 0.0, 0.0))
|
||||||
|
#northl.text = str(gain)
|
||||||
|
##norths.visible = true
|
||||||
|
#else:
|
||||||
|
#northl.text = "cant"
|
||||||
|
#else:
|
||||||
|
#northl.text = "clear"
|
||||||
|
#else:
|
||||||
|
#northl.text = "invalid"
|
||||||
|
#if south >= 0:
|
||||||
|
#if astar.astar.is_point_disabled(south):
|
||||||
|
#var further_point: int = astar.get_south_point(south)
|
||||||
|
#if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
||||||
|
#var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(4.0, 0.0, 0.0))
|
||||||
|
#var current_offset: float = path.get_closest_offset(character.global_position)
|
||||||
|
#var gain: float = expected_offset - current_offset
|
||||||
|
#if gain >= tolerance:
|
||||||
|
#distance_remaining -= gain
|
||||||
|
##path_progress += gain
|
||||||
|
#leap(Vector3(4.0, 0.0, 0.0))
|
||||||
|
#southl.text = str(gain)
|
||||||
|
##souths.visible = true
|
||||||
|
#else:
|
||||||
|
#southl.text = "cant"
|
||||||
|
#else:
|
||||||
|
#southl.text = "clear"
|
||||||
|
#else:
|
||||||
|
#southl.text = "invalid"
|
||||||
|
|
||||||
|
|
||||||
|
func consider_leap(direction: Vector3) -> void:
|
||||||
|
var node: FlowNode = check_jump(character.global_position + (direction * jump_distance))
|
||||||
|
if node:
|
||||||
|
var expected_distance_remaining: float = calculate_distance_to_goal(node)
|
||||||
|
expected_distance_remaining += (character.global_position + (direction * jump_distance)).distance_to(node.global_position)
|
||||||
|
var gain: float = distance_remaining - expected_distance_remaining
|
||||||
if gain >= tolerance:
|
if gain >= tolerance:
|
||||||
distance_remaining -= gain
|
distance_remaining -= gain
|
||||||
path_progress += gain
|
leap(direction * jump_distance)
|
||||||
leap(Vector3(0.0, 0.0, -4.0))
|
next_node = node
|
||||||
eastl.text = str(gain)
|
|
||||||
#easts.visible = true
|
|
||||||
else:
|
|
||||||
eastl.text = "cant"
|
|
||||||
else:
|
|
||||||
eastl.text = "clear"
|
|
||||||
else:
|
|
||||||
eastl.text = "invalid"
|
|
||||||
if west >= 0:
|
|
||||||
if astar.astar.is_point_disabled(west):
|
|
||||||
var further_point: int = astar.get_west_point(west)
|
|
||||||
if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
|
||||||
var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(0.0, 0.0, 4.0))
|
|
||||||
var current_offset: float = path.get_closest_offset(character.global_position)
|
|
||||||
var gain: float = expected_offset - current_offset
|
|
||||||
if gain >= tolerance:
|
|
||||||
distance_remaining -= gain
|
|
||||||
path_progress += gain
|
|
||||||
leap(Vector3(0.0, 0.0, 4.0))
|
|
||||||
westl.text = str(gain)
|
|
||||||
#wests.visible = true
|
|
||||||
else:
|
|
||||||
westl.text = "cant"
|
|
||||||
else:
|
|
||||||
westl.text = "clear"
|
|
||||||
else:
|
|
||||||
westl.text = "invalid"
|
|
||||||
if north >= 0:
|
|
||||||
if astar.astar.is_point_disabled(north):
|
|
||||||
var further_point: int = astar.get_north_point(north)
|
|
||||||
if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
|
||||||
var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(-4.0, 0.0, 0.0))
|
|
||||||
var current_offset: float = path.get_closest_offset(character.global_position)
|
|
||||||
var gain: float = expected_offset - current_offset
|
|
||||||
if gain >= tolerance:
|
|
||||||
distance_remaining -= gain
|
|
||||||
path_progress += gain
|
|
||||||
leap(Vector3(-4.0, 0.0, 0.0))
|
|
||||||
northl.text = str(gain)
|
|
||||||
#norths.visible = true
|
|
||||||
else:
|
|
||||||
northl.text = "cant"
|
|
||||||
else:
|
|
||||||
northl.text = "clear"
|
|
||||||
else:
|
|
||||||
northl.text = "invalid"
|
|
||||||
if south >= 0:
|
|
||||||
if astar.astar.is_point_disabled(south):
|
|
||||||
var further_point: int = astar.get_south_point(south)
|
|
||||||
if further_point >= 0 and !astar.astar.is_point_disabled(further_point):
|
|
||||||
var expected_offset: float = path.get_closest_offset(character.global_position + Vector3(4.0, 0.0, 0.0))
|
|
||||||
var current_offset: float = path.get_closest_offset(character.global_position)
|
|
||||||
var gain: float = expected_offset - current_offset
|
|
||||||
if gain >= tolerance:
|
|
||||||
distance_remaining -= gain
|
|
||||||
path_progress += gain
|
|
||||||
leap(Vector3(4.0, 0.0, 0.0))
|
|
||||||
southl.text = str(gain)
|
|
||||||
#souths.visible = true
|
|
||||||
else:
|
|
||||||
southl.text = "cant"
|
|
||||||
else:
|
|
||||||
southl.text = "clear"
|
|
||||||
else:
|
|
||||||
southl.text = "invalid"
|
|
||||||
|
|
||||||
|
|
||||||
func finish_jump() -> void:
|
func finish_jump() -> void:
|
||||||
jumping = false
|
jumping = false
|
||||||
|
|
||||||
|
|
||||||
|
func check_jump(destination: Vector3) -> FlowNode:
|
||||||
|
var closest_point: FlowNode = flow_field.get_closest_traversable_point(destination)
|
||||||
|
if !closest_point.best_path or closest_point.global_position.distance_to(destination) > 1.2:
|
||||||
|
return null
|
||||||
|
return closest_point.best_path
|
||||||
|
|
||||||
|
|
||||||
func leap(to_point: Vector3) -> void:
|
func leap(to_point: Vector3) -> void:
|
||||||
jumping = true
|
jumping = true
|
||||||
var tween: Tween = create_tween()
|
var tween: Tween = create_tween()
|
||||||
tween.tween_property(character, "global_position", character.global_position + (to_point / 2.0) + Vector3.UP, 0.5)
|
tween.tween_property(character, "global_position", character.global_position + (to_point / 2.0) + Vector3.UP, 0.3)
|
||||||
tween.tween_property(character, "global_position", character.global_position + to_point, 0.5)
|
tween.tween_property(character, "global_position", character.global_position + to_point, 0.3)
|
||||||
tween.tween_callback(finish_jump)
|
tween.tween_callback(finish_jump)
|
||||||
|
@ -1,21 +1,61 @@
|
|||||||
class_name PathingController extends EnemyMovement
|
class_name PathingController extends EnemyMovement
|
||||||
|
|
||||||
var path: Curve3D
|
#var path: Curve3D
|
||||||
var path_progress: float = 0.0
|
#var path_progress: float = 0.0
|
||||||
|
var flow_field: FlowField
|
||||||
|
var next_node: FlowNode :
|
||||||
|
get():
|
||||||
|
return next_node
|
||||||
|
set(value):
|
||||||
|
next_node = value
|
||||||
|
var found_point: bool = false
|
||||||
|
while !found_point:
|
||||||
|
#TODO: make deterministic random
|
||||||
|
var x: float = randf_range(-1, 1)
|
||||||
|
var y: float = randf_range(-1, 1)
|
||||||
|
if Vector3(next_node.global_position.x + x, next_node.global_position.y, next_node.global_position.z + y).distance_to(next_node.global_position) <= 1.0:
|
||||||
|
found_point = true
|
||||||
|
next_pos = Vector3(next_node.global_position.x + x, next_node.global_position.y, next_node.global_position.z + y)
|
||||||
|
var next_pos: Vector3
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
if path:
|
super._ready()
|
||||||
distance_remaining = path.get_baked_length()
|
#if path:
|
||||||
|
# distance_remaining = path.get_baked_length()
|
||||||
|
next_node = flow_field.get_closest_traversable_point(character.global_position)
|
||||||
|
distance_remaining += calculate_distance_to_goal(next_node)
|
||||||
|
|
||||||
|
|
||||||
|
func calculate_distance_to_goal(node: FlowNode) -> float:
|
||||||
|
var distance: float = 0.0
|
||||||
|
distance += character.global_position.distance_to(node.global_position)
|
||||||
|
if node.best_path:
|
||||||
|
var then_next_node: FlowNode = node.best_path
|
||||||
|
distance += node.global_position.distance_to(then_next_node.global_position)
|
||||||
|
while then_next_node.best_path:
|
||||||
|
distance += then_next_node.global_position.distance_to(then_next_node.best_path.global_position)
|
||||||
|
then_next_node = then_next_node.best_path
|
||||||
|
return distance
|
||||||
|
|
||||||
|
|
||||||
|
func walk(delta: float) -> void:
|
||||||
|
var distance_travelled: float = (speed * clampf(speed, 0.0, 1.0)) * delta
|
||||||
|
distance_remaining -= distance_travelled
|
||||||
|
character.global_position = character.global_position.move_toward(next_pos, distance_travelled)
|
||||||
|
character.look_at(next_pos)
|
||||||
|
if character.global_position.distance_to(next_pos) <= 0.05:
|
||||||
|
next_node = next_node.best_path
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
if !path:
|
#if !path:
|
||||||
|
# return
|
||||||
|
if !next_node:
|
||||||
return
|
return
|
||||||
var distance_travelled: float = (character.stats.movement_speed * clampf(character.movement_speed_penalty, 0.0, 1.0)) * delta
|
walk(delta)
|
||||||
distance_remaining -= distance_travelled
|
#path_progress += distance_travelled
|
||||||
path_progress += distance_travelled
|
#var sample: Transform3D = path.sample_baked_with_rotation(path_progress, true)
|
||||||
var sample: Transform3D = path.sample_baked_with_rotation(path_progress, true)
|
#character.global_position = sample.origin
|
||||||
character.global_position = sample.origin
|
#character.look_at(character.global_position + -sample.basis.z)
|
||||||
character.look_at(character.global_position + -sample.basis.z)
|
#var closest_point: Vector3 = path.get_closest_point(character.global_position)
|
||||||
var closest_point: Vector3 = path.get_closest_point(character.global_position)
|
|
||||||
|
@ -36,13 +36,13 @@ func hit(target: CharacterBody3D) -> void:
|
|||||||
target.apply_effect(effect)
|
target.apply_effect(effect)
|
||||||
if owner_id == 0:
|
if owner_id == 0:
|
||||||
if Data.preferences.display_tower_damage_indicators:
|
if Data.preferences.display_tower_damage_indicators:
|
||||||
spawn_damage_indicator(target.sprite.global_position)
|
spawn_damage_indicator(target.d_n.global_position)
|
||||||
if owner_id == multiplayer.get_unique_id():
|
if owner_id == multiplayer.get_unique_id():
|
||||||
if Data.preferences.display_self_damage_indicators:
|
if Data.preferences.display_self_damage_indicators:
|
||||||
spawn_damage_indicator(target.sprite.global_position)
|
spawn_damage_indicator(target.d_n.global_position)
|
||||||
if owner_id != 0 and owner_id != multiplayer.get_unique_id():
|
if owner_id != 0 and owner_id != multiplayer.get_unique_id():
|
||||||
if Data.preferences.display_party_damage_indicators:
|
if Data.preferences.display_party_damage_indicators:
|
||||||
spawn_damage_indicator(target.sprite.global_position)
|
spawn_damage_indicator(target.d_n.global_position)
|
||||||
|
|
||||||
|
|
||||||
@rpc("reliable")
|
@rpc("reliable")
|
||||||
|
@ -2,6 +2,7 @@ class_name Enemy extends Resource
|
|||||||
|
|
||||||
@export var title: String = "dog"
|
@export var title: String = "dog"
|
||||||
@export var target_type: Data.EnemyType
|
@export var target_type: Data.EnemyType
|
||||||
|
@export var scene: PackedScene
|
||||||
@export var icon: Texture
|
@export var icon: Texture
|
||||||
@export var death_sprite: Texture
|
@export var death_sprite: Texture
|
||||||
@export var sprite: AtlasTexture
|
@export var sprite: AtlasTexture
|
||||||
|
@ -6,6 +6,11 @@ var save_slot: int = 0
|
|||||||
var twenty_game_history: Array[bool] = []
|
var twenty_game_history: Array[bool] = []
|
||||||
var wins: int = 0
|
var wins: int = 0
|
||||||
var losses: int = 0
|
var losses: int = 0
|
||||||
|
var winrate: int :
|
||||||
|
get():
|
||||||
|
return int((float(twenty_game_history.count(true)) / float(twenty_game_history.size())) * 100.0)
|
||||||
|
set(_value):
|
||||||
|
return
|
||||||
|
|
||||||
#Engineer
|
#Engineer
|
||||||
var engineer_cards_bought: int = 0
|
var engineer_cards_bought: int = 0
|
||||||
|
@ -37,4 +37,4 @@ func networked_hit(target_path: String, target_hitbox_path: String) -> void:
|
|||||||
var target_hitbox: Hitbox = get_tree().root.get_node(target_hitbox_path) as Hitbox
|
var target_hitbox: Hitbox = get_tree().root.get_node(target_hitbox_path) as Hitbox
|
||||||
hit(target, target_hitbox)
|
hit(target, target_hitbox)
|
||||||
if Data.preferences.display_party_damage_indicators:
|
if Data.preferences.display_party_damage_indicators:
|
||||||
spawn_damage_indicator(target.sprite.global_position)
|
spawn_damage_indicator(target.d_n.global_position)
|
||||||
|
@ -30,7 +30,7 @@ func shoot() -> void:
|
|||||||
if target_hitbox is Hitbox:
|
if target_hitbox is Hitbox:
|
||||||
hit(target, target_hitbox)
|
hit(target, target_hitbox)
|
||||||
if Data.preferences.display_self_damage_indicators:
|
if Data.preferences.display_self_damage_indicators:
|
||||||
spawn_damage_indicator(target.sprite.global_position)
|
spawn_damage_indicator(target.d_n.global_position)
|
||||||
networked_hit.rpc(get_tree().root.get_path_to(target), get_tree().root.get_path_to(target_hitbox))
|
networked_hit.rpc(get_tree().root.get_path_to(target), get_tree().root.get_path_to(target_hitbox))
|
||||||
|
|
||||||
|
|
||||||
@ -51,4 +51,4 @@ func networked_hit(target_path: String, target_hitbox_path: String) -> void:
|
|||||||
var target_hitbox: Hitbox = get_tree().root.get_node(target_hitbox_path) as Hitbox
|
var target_hitbox: Hitbox = get_tree().root.get_node(target_hitbox_path) as Hitbox
|
||||||
hit(target, target_hitbox)
|
hit(target, target_hitbox)
|
||||||
if Data.preferences.display_party_damage_indicators:
|
if Data.preferences.display_party_damage_indicators:
|
||||||
spawn_damage_indicator(target.sprite.global_position)
|
spawn_damage_indicator(target.d_n.global_position)
|
||||||
|
@ -1,265 +0,0 @@
|
|||||||
class_name AStarGraph3D extends Node3D
|
|
||||||
|
|
||||||
@export var grid_size: Vector2i = Vector2i(15, 7)
|
|
||||||
@export var point_gap: float = 2.0
|
|
||||||
var non_build_locations: Array = []
|
|
||||||
var astar: AStar3D = AStar3D.new()
|
|
||||||
|
|
||||||
#TODO generalize this better
|
|
||||||
@export var end: Node3D
|
|
||||||
@export var spawners: Array[EnemySpawner]
|
|
||||||
@export var tower_path: Node
|
|
||||||
var tower_base_scene: PackedScene = load("res://Scenes/TowerBase/tower_base.tscn")
|
|
||||||
var tower_frame_scene: PackedScene = load("res://Scenes/tower_frame.tscn")
|
|
||||||
var tower_bases: Array = []
|
|
||||||
var tower_base_ids: Dictionary = {}
|
|
||||||
var tower_frames: Array = []
|
|
||||||
var wall_id: int = 0
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
for spawner: EnemySpawner in spawners:
|
|
||||||
spawner.astar = self
|
|
||||||
|
|
||||||
|
|
||||||
func toggle_point(point_id: int, caller_id: int) -> void:
|
|
||||||
networked_toggle_point.rpc(point_id, caller_id)
|
|
||||||
|
|
||||||
|
|
||||||
func remove_wall(wall: TowerBase) -> void:
|
|
||||||
networked_remove_wall.rpc(wall.point_id)
|
|
||||||
toggle_point(wall.point_id, multiplayer.get_unique_id())
|
|
||||||
|
|
||||||
|
|
||||||
func point_is_build_location(point_id: int) -> bool:
|
|
||||||
return !non_build_locations.has(point_id)
|
|
||||||
|
|
||||||
|
|
||||||
func test_path_if_point_toggled(point_id: int) -> bool:
|
|
||||||
if astar.is_point_disabled(point_id):
|
|
||||||
astar.set_point_disabled(point_id, false)
|
|
||||||
else:
|
|
||||||
astar.set_point_disabled(point_id, true)
|
|
||||||
var result: bool = find_path()
|
|
||||||
if astar.is_point_disabled(point_id):
|
|
||||||
astar.set_point_disabled(point_id, false)
|
|
||||||
else:
|
|
||||||
astar.set_point_disabled(point_id, true)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
@rpc("reliable", "any_peer", "call_local")
|
|
||||||
func networked_toggle_point(point_id: int, caller_id: int) -> void:
|
|
||||||
if astar.is_point_disabled(point_id):
|
|
||||||
astar.set_point_disabled(point_id, false)
|
|
||||||
else:
|
|
||||||
astar.set_point_disabled(point_id, true)
|
|
||||||
find_path()
|
|
||||||
enable_non_path_tower_frames()
|
|
||||||
if is_multiplayer_authority() and astar.is_point_disabled(point_id):
|
|
||||||
networked_spawn_wall.rpc(astar.get_point_position(point_id), wall_id, caller_id)
|
|
||||||
wall_id += 1
|
|
||||||
|
|
||||||
|
|
||||||
func get_north_point(point_id: int) -> int:
|
|
||||||
var x: int = floori(float(point_id) / float(grid_size.y))
|
|
||||||
var y: int = point_id % grid_size.y
|
|
||||||
if x - 1 >= 0: #if the north point id could possibly exist as a neighbor
|
|
||||||
return (x - 1) * grid_size.y + y
|
|
||||||
return -1
|
|
||||||
|
|
||||||
|
|
||||||
func get_south_point(point_id: int) -> int:
|
|
||||||
var x: int = floori(float(point_id) / float(grid_size.y))
|
|
||||||
var y: int = point_id % grid_size.y
|
|
||||||
if x + 1 <= grid_size.x - 1: #if the south point id could possibly exist as a neighbor
|
|
||||||
return (x + 1) * grid_size.y + y
|
|
||||||
return -1
|
|
||||||
|
|
||||||
|
|
||||||
func get_west_point(point_id: int) -> int:
|
|
||||||
var x: int = floori(float(point_id) / float(grid_size.y))
|
|
||||||
var y: int = point_id % grid_size.y
|
|
||||||
if y + 1 <= grid_size.y - 1: #if the east point id could possibly exist as a neighbor
|
|
||||||
return x * grid_size.y + y + 1
|
|
||||||
return -1
|
|
||||||
|
|
||||||
|
|
||||||
func get_east_point(point_id: int) -> int:
|
|
||||||
var x: int = floori(float(point_id) / float(grid_size.y))
|
|
||||||
var y: int = point_id % grid_size.y
|
|
||||||
if y - 1 >= 0: #if the west point id could possibly exist as a neighbor
|
|
||||||
return x * grid_size.y + y - 1
|
|
||||||
return -1
|
|
||||||
|
|
||||||
|
|
||||||
func count_valid_neighbours(point_id: int) -> int:
|
|
||||||
if !point_id:
|
|
||||||
return 0
|
|
||||||
var valid_neighbours: int = 0
|
|
||||||
var north_point: int = get_north_point(point_id)
|
|
||||||
var south_point: int = get_south_point(point_id)
|
|
||||||
var east_point: int = get_east_point(point_id)
|
|
||||||
var west_point: int = get_west_point(point_id)
|
|
||||||
|
|
||||||
if north_point and !astar.is_point_disabled(north_point):
|
|
||||||
valid_neighbours += 1
|
|
||||||
else: #add the spawn point which is always valid
|
|
||||||
valid_neighbours += 1
|
|
||||||
|
|
||||||
if south_point and !astar.is_point_disabled(south_point):
|
|
||||||
valid_neighbours += 1
|
|
||||||
else: #add the goal point which is always valid
|
|
||||||
valid_neighbours += 1
|
|
||||||
|
|
||||||
if east_point and !astar.is_point_disabled(east_point):
|
|
||||||
valid_neighbours += 1
|
|
||||||
|
|
||||||
if west_point and !astar.is_point_disabled(west_point):
|
|
||||||
valid_neighbours += 1
|
|
||||||
return valid_neighbours
|
|
||||||
|
|
||||||
|
|
||||||
func disable_all_tower_frames() -> void:
|
|
||||||
for frame: Node3D in tower_frames:
|
|
||||||
frame.set_visible(false)
|
|
||||||
|
|
||||||
|
|
||||||
func enable_non_path_tower_frames() -> void:
|
|
||||||
for frame: Node3D in tower_frames:
|
|
||||||
if !astar.is_point_disabled(tower_frames.find(frame)):
|
|
||||||
frame.set_visible(true)
|
|
||||||
disable_path_tower_frames()
|
|
||||||
|
|
||||||
|
|
||||||
func disable_path_tower_frames() -> void:
|
|
||||||
for id: int in astar.get_id_path(astar.get_point_count() - 2, astar.get_point_count() - 1):
|
|
||||||
if id < (grid_size.x * grid_size.y) and !test_path_if_point_toggled(id):
|
|
||||||
tower_frames[id].set_visible(false)
|
|
||||||
|
|
||||||
|
|
||||||
@rpc("reliable", "call_local")
|
|
||||||
func networked_spawn_wall(pos: Vector3, name_id: int, caller_id: int) -> void:
|
|
||||||
var base: TowerBase = tower_base_scene.instantiate() as TowerBase
|
|
||||||
base.position = pos
|
|
||||||
base.name = "Wall" + str(name_id)
|
|
||||||
base.owner_id = caller_id
|
|
||||||
var point_id: int = astar.get_closest_point(pos, true)
|
|
||||||
base.point_id = point_id
|
|
||||||
tower_base_ids[point_id] = base
|
|
||||||
tower_bases.append(base)
|
|
||||||
tower_path.add_child(base)
|
|
||||||
var north_point: int = get_north_point(point_id)
|
|
||||||
var south_point: int = get_south_point(point_id)
|
|
||||||
var east_point: int = get_east_point(point_id)
|
|
||||||
var west_point: int = get_west_point(point_id)
|
|
||||||
if north_point >= 0 and tower_base_ids.has(north_point) and astar.is_point_disabled(north_point):
|
|
||||||
base.set_north_wall(true)
|
|
||||||
tower_base_ids[north_point].set_south_wall(true)
|
|
||||||
if south_point >= 0 and tower_base_ids.has(south_point) and astar.is_point_disabled(south_point):
|
|
||||||
base.set_south_wall(true)
|
|
||||||
tower_base_ids[south_point].set_north_wall(true)
|
|
||||||
if east_point >= 0 and tower_base_ids.has(east_point) and astar.is_point_disabled(east_point):
|
|
||||||
base.set_east_wall(true)
|
|
||||||
tower_base_ids[east_point].set_west_wall(true)
|
|
||||||
if west_point >= 0 and tower_base_ids.has(west_point) and astar.is_point_disabled(west_point):
|
|
||||||
base.set_west_wall(true)
|
|
||||||
tower_base_ids[west_point].set_east_wall(true)
|
|
||||||
|
|
||||||
|
|
||||||
@rpc("reliable", "call_local", "any_peer")
|
|
||||||
func networked_remove_wall(new_wall_id: int) -> void:
|
|
||||||
var wall: TowerBase = tower_base_ids[new_wall_id]
|
|
||||||
Game.connected_players_nodes[wall.owner_id].currency += Data.wall_cost
|
|
||||||
Game.connected_players_nodes[wall.owner_id].unready_self()
|
|
||||||
tower_bases.erase(wall)
|
|
||||||
tower_base_ids.erase(new_wall_id)
|
|
||||||
wall.queue_free()
|
|
||||||
var north_point: int = get_north_point(new_wall_id)
|
|
||||||
var south_point: int = get_south_point(new_wall_id)
|
|
||||||
var east_point: int = get_east_point(new_wall_id)
|
|
||||||
var west_point: int = get_west_point(new_wall_id)
|
|
||||||
if north_point >= 0 and tower_base_ids.has(north_point) and astar.is_point_disabled(north_point):
|
|
||||||
tower_base_ids[north_point].set_south_wall(false)
|
|
||||||
if south_point >= 0 and tower_base_ids.has(south_point) and astar.is_point_disabled(south_point):
|
|
||||||
tower_base_ids[south_point].set_north_wall(false)
|
|
||||||
if east_point >= 0 and tower_base_ids.has(east_point) and astar.is_point_disabled(east_point):
|
|
||||||
tower_base_ids[east_point].set_west_wall(false)
|
|
||||||
if west_point >= 0 and tower_base_ids.has(west_point) and astar.is_point_disabled(west_point):
|
|
||||||
tower_base_ids[west_point].set_east_wall(false)
|
|
||||||
|
|
||||||
|
|
||||||
func build_random_maze(block_limit: int) -> void:
|
|
||||||
var untested_point_ids: Array = []
|
|
||||||
for index: int in (grid_size.x * grid_size.y):
|
|
||||||
untested_point_ids.append(index)
|
|
||||||
if block_limit <= 0 or block_limit > untested_point_ids.size():
|
|
||||||
block_limit = untested_point_ids.size()
|
|
||||||
for index: int in block_limit:
|
|
||||||
var random_point: int = untested_point_ids.pick_random()
|
|
||||||
untested_point_ids.erase(random_point)
|
|
||||||
if test_path_if_point_toggled(random_point):
|
|
||||||
networked_toggle_point.rpc(random_point, multiplayer.get_unique_id())
|
|
||||||
|
|
||||||
|
|
||||||
func place_random_towers(tower_limit: int) -> void:
|
|
||||||
var untowered_bases: Array = tower_bases.duplicate()
|
|
||||||
if tower_limit <= 0 or tower_limit > untowered_bases.size():
|
|
||||||
tower_limit = untowered_bases.size()
|
|
||||||
for index: int in tower_limit:
|
|
||||||
var random_base: TowerBase = untowered_bases.pick_random() as TowerBase
|
|
||||||
untowered_bases.erase(random_base)
|
|
||||||
random_base.add_card(Data.cards.pick_random(), multiplayer.get_unique_id())
|
|
||||||
|
|
||||||
|
|
||||||
func find_path() -> bool:
|
|
||||||
for spawn: EnemySpawner in spawners:
|
|
||||||
var path: PackedVector3Array = astar.get_point_path(spawn.astar_point_id, astar.get_point_count() - 1)
|
|
||||||
if !path.is_empty():
|
|
||||||
var curve: Curve3D = Curve3D.new()
|
|
||||||
for point: Vector3 in path:
|
|
||||||
curve.add_point(point)
|
|
||||||
spawn.path.global_position = Vector3.ZERO
|
|
||||||
spawn.path.curve = curve
|
|
||||||
else:
|
|
||||||
return false
|
|
||||||
spawners[0].path.spawn_visualizer_points()
|
|
||||||
return true
|
|
||||||
|
|
||||||
|
|
||||||
func make_grid() -> void:
|
|
||||||
for x: int in grid_size.x:
|
|
||||||
for y: int in grid_size.y:
|
|
||||||
var point_position: Vector3 = Vector3((x - floori(grid_size.x / 2.0)) * point_gap, 0.5, (y - floori(grid_size.y / 2.0)) * point_gap)
|
|
||||||
astar.add_point(int(x * grid_size.y + y), point_position)
|
|
||||||
var frame: Node3D = tower_frame_scene.instantiate()
|
|
||||||
frame.position = point_position
|
|
||||||
tower_frames.append(frame)
|
|
||||||
add_child(frame)
|
|
||||||
|
|
||||||
for x: int in grid_size.x:
|
|
||||||
for y: int in grid_size.y:
|
|
||||||
var point_id: int = grid_size.y * x + y
|
|
||||||
if x > 0:
|
|
||||||
var north_point_id: int = grid_size.y * (x - 1) + y
|
|
||||||
astar.connect_points(point_id, north_point_id, false)
|
|
||||||
if x < grid_size.x - 1:
|
|
||||||
var south_point_id: int = grid_size.y * (x + 1) + y
|
|
||||||
astar.connect_points(point_id, south_point_id, false)
|
|
||||||
if y > 0:
|
|
||||||
var east_point_id: int = grid_size.y * x + (y - 1)
|
|
||||||
astar.connect_points(point_id, east_point_id, false)
|
|
||||||
if y < grid_size.y - 1:
|
|
||||||
var west_point_id: int = grid_size.y * x + (y + 1)
|
|
||||||
astar.connect_points(point_id, west_point_id, false)
|
|
||||||
|
|
||||||
for spawn: EnemySpawner in spawners:
|
|
||||||
non_build_locations.append(astar.get_point_count())
|
|
||||||
spawn.astar_point_id = astar.get_point_count()
|
|
||||||
astar.add_point(astar.get_point_count(), spawn.global_position)
|
|
||||||
for x: int in grid_size.y:
|
|
||||||
astar.connect_points(int(astar.get_point_count() - 1), x)
|
|
||||||
non_build_locations.append(astar.get_point_count())
|
|
||||||
astar.add_point(astar.get_point_count(), end.global_position)
|
|
||||||
for x: int in grid_size.y:
|
|
||||||
astar.connect_points(astar.get_point_count() - 1, int(grid_size.y * (grid_size.x - 1) + x))
|
|
@ -1 +0,0 @@
|
|||||||
uid://u404brdoaku
|
|
@ -14,6 +14,7 @@ var color: Color = Color.TOMATO
|
|||||||
var fading: bool = true
|
var fading: bool = true
|
||||||
var time_to_fade: float = 2.0
|
var time_to_fade: float = 2.0
|
||||||
var time_since_started_fading: float = 2.0
|
var time_since_started_fading: float = 2.0
|
||||||
|
var game_manager: GameManager
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
@ -43,7 +44,7 @@ func _input(event: InputEvent) -> void:
|
|||||||
text_selected = false
|
text_selected = false
|
||||||
if input_line.text.length() != 0:
|
if input_line.text.length() != 0:
|
||||||
if input_line.text.begins_with("/"):
|
if input_line.text.begins_with("/"):
|
||||||
Game.parse_command(input_line.text, multiplayer.get_unique_id())
|
game_manager.parse_command(input_line.text, multiplayer.get_unique_id())
|
||||||
else:
|
else:
|
||||||
append_message.rpc(username, color, input_line.text)
|
append_message.rpc(username, color, input_line.text)
|
||||||
input_line.clear()
|
input_line.clear()
|
||||||
|
@ -4,7 +4,7 @@ class_name CinematicCamManager extends Node3D
|
|||||||
@export var cameras: Array[Camera3D]
|
@export var cameras: Array[Camera3D]
|
||||||
@export var pan_speed: float = 1.0
|
@export var pan_speed: float = 1.0
|
||||||
var current_cam: int = 0
|
var current_cam: int = 0
|
||||||
var does_its_thing: bool = true
|
@export var does_its_thing: bool = true
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
@ -2,7 +2,6 @@ extends Node
|
|||||||
|
|
||||||
var characters: Array[HeroClass]
|
var characters: Array[HeroClass]
|
||||||
var cards: Array[Card]
|
var cards: Array[Card]
|
||||||
var enemies: Array[Enemy]
|
|
||||||
#var keymaps: Array[PlayerKeymap]
|
#var keymaps: Array[PlayerKeymap]
|
||||||
var mods: Dictionary[String, String]
|
var mods: Dictionary[String, String]
|
||||||
var graphics: PlayerGraphicsSettings
|
var graphics: PlayerGraphicsSettings
|
||||||
@ -13,14 +12,14 @@ var save_data: SaveData
|
|||||||
var keymap_data: KeymapData
|
var keymap_data: KeymapData
|
||||||
|
|
||||||
const DEFAULT_SERVER_PORT: int = 58008
|
const DEFAULT_SERVER_PORT: int = 58008
|
||||||
|
|
||||||
var wall_cost: int = 1
|
|
||||||
var printer_cost: int = 15
|
|
||||||
enum EnergyType {UNDEFINED = 0, DISCRETE = 1, CONTINUOUS = 2}
|
enum EnergyType {UNDEFINED = 0, DISCRETE = 1, CONTINUOUS = 2}
|
||||||
enum TargetType {UNDEFINED = 0, LAND = 1, AIR = 2, BOTH = 3}
|
enum TargetType {UNDEFINED = 0, LAND = 1, AIR = 2, BOTH = 3}
|
||||||
enum EnemyType {UNDEFINED = 0, LAND = 1, AIR = 2}
|
enum EnemyType {UNDEFINED = 0, LAND = 1, AIR = 2}
|
||||||
enum Rarity {COMMON = 0, UNCOMMON = 1, RARE = 2, EPIC = 3, LEGENDARY = 4}
|
enum Rarity {COMMON = 0, UNCOMMON = 1, RARE = 2, EPIC = 3, LEGENDARY = 4}
|
||||||
var rarity_weights: Dictionary = {
|
|
||||||
|
static var wall_cost: int = 1
|
||||||
|
static var printer_cost: int = 15
|
||||||
|
static var rarity_weights: Dictionary = {
|
||||||
"COMMON" = 50,
|
"COMMON" = 50,
|
||||||
"UNCOMMON" = 30,
|
"UNCOMMON" = 30,
|
||||||
"RARE" = 10,
|
"RARE" = 10,
|
||||||
@ -114,11 +113,3 @@ func _ready() -> void:
|
|||||||
|
|
||||||
load_classes()
|
load_classes()
|
||||||
load_cards("res://Cards")
|
load_cards("res://Cards")
|
||||||
|
|
||||||
enemies.append(preload("res://Resources/Enemies/dog.tres"))
|
|
||||||
enemies.append(preload("res://Resources/Enemies/dog_fast.tres"))
|
|
||||||
enemies.append(preload("res://Resources/Enemies/dog_heavy.tres"))
|
|
||||||
enemies.append(preload("res://Resources/Enemies/dog_boss.tres"))
|
|
||||||
enemies.append(preload("res://Resources/Enemies/airenemy.tres"))
|
|
||||||
enemies.append(preload("res://Resources/Enemies/airenemy2.tres"))
|
|
||||||
enemies.append(preload("res://Resources/Enemies/leapfrog.tres"))
|
|
||||||
|
@ -1,178 +0,0 @@
|
|||||||
class_name EditTool extends Node3D
|
|
||||||
|
|
||||||
@export var hero: Hero
|
|
||||||
@export var inventory: Inventory
|
|
||||||
@export var ray: RayCast3D
|
|
||||||
@export var wall_preview: TowerBase
|
|
||||||
@export var progress_bar: TextureProgressBar
|
|
||||||
|
|
||||||
var enabled: bool = true
|
|
||||||
var point_id: int = -1
|
|
||||||
var obstacle_last_point: int = -1
|
|
||||||
var valid_point: bool = false
|
|
||||||
var is_looking_at_tower_base: bool = false
|
|
||||||
var tower_preview: Tower
|
|
||||||
var last_tower_base: TowerBase
|
|
||||||
var last_collider: Object
|
|
||||||
var last_card: Card
|
|
||||||
var ray_collider: Object
|
|
||||||
var ray_point: Vector3
|
|
||||||
|
|
||||||
var interact_key_held: bool = false
|
|
||||||
var interacted_once: bool = false
|
|
||||||
var interact_held_time: float = 0.0
|
|
||||||
var interact_hold_time: float = 0.4
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
var c: Color = Color.GREEN
|
|
||||||
c.a = 0.8
|
|
||||||
wall_preview.set_color(c)
|
|
||||||
wall_preview.set_float(0.0)
|
|
||||||
wall_preview.toggle_collision()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if !enabled:
|
|
||||||
ray_collider = null
|
|
||||||
wall_preview.set_visible(false)
|
|
||||||
if is_instance_valid(last_collider):
|
|
||||||
Game.level.a_star_graph_3d.tower_base_ids[last_collider.point_id].set_float(1.0)
|
|
||||||
last_collider = null
|
|
||||||
return
|
|
||||||
|
|
||||||
if interact_key_held and !interacted_once and valid_point and hero.currency >= Data.wall_cost and ray.is_colliding() and Game.level.a_star_graph_3d.point_is_build_location(point_id):
|
|
||||||
interact_held_time += delta
|
|
||||||
set_progress_percent(interact_held_time / interact_hold_time)
|
|
||||||
wall_preview.set_float(interact_held_time / interact_hold_time)
|
|
||||||
if interact_held_time >= interact_hold_time:
|
|
||||||
set_progress_percent(0)
|
|
||||||
interacted_once = true
|
|
||||||
build_wall()
|
|
||||||
if interact_key_held and !interacted_once and last_collider and ray.is_colliding():
|
|
||||||
interact_held_time += delta
|
|
||||||
set_progress_percent(interact_held_time / interact_hold_time)
|
|
||||||
if interact_held_time >= interact_hold_time:
|
|
||||||
set_progress_percent(0)
|
|
||||||
interacted_once = true
|
|
||||||
refund_wall(last_collider)
|
|
||||||
if !interact_key_held:
|
|
||||||
interact_held_time = 0.0
|
|
||||||
interacted_once = false
|
|
||||||
set_progress_percent(0)
|
|
||||||
wall_preview.set_float(0.0)
|
|
||||||
|
|
||||||
point_id = -1
|
|
||||||
if !interacted_once and ray.is_colliding():
|
|
||||||
if !interact_key_held:
|
|
||||||
wall_preview.set_visible(true)
|
|
||||||
ray_collider = ray.get_collider()
|
|
||||||
ray_point = ray.get_collision_point()
|
|
||||||
|
|
||||||
is_looking_at_tower_base = ray_collider is TowerBase
|
|
||||||
if is_looking_at_tower_base:
|
|
||||||
valid_point = false
|
|
||||||
point_id = ray_collider.point_id
|
|
||||||
if obstacle_last_point != point_id:
|
|
||||||
obstacle_last_point = point_id
|
|
||||||
if is_instance_valid(last_collider):
|
|
||||||
Game.level.a_star_graph_3d.tower_base_ids[last_collider.point_id].set_float(1.0)
|
|
||||||
last_collider = null
|
|
||||||
if tower_preview:
|
|
||||||
delete_tower_preview()
|
|
||||||
wall_preview.set_visible(false)
|
|
||||||
last_collider = ray_collider
|
|
||||||
ray_collider.set_color(Color.RED)
|
|
||||||
ray_collider.set_float(0.0)
|
|
||||||
if inventory.contents.size() > 0 and !ray_collider.has_card:
|
|
||||||
if ray_collider != last_tower_base or inventory.selected_item != last_card:
|
|
||||||
spawn_tower_preview()
|
|
||||||
elif Game.level:
|
|
||||||
if is_instance_valid(last_collider):
|
|
||||||
Game.level.a_star_graph_3d.tower_base_ids[last_collider.point_id].set_float(1.0)
|
|
||||||
last_collider = null
|
|
||||||
if tower_preview:
|
|
||||||
delete_tower_preview()
|
|
||||||
point_id = Game.level.a_star_graph_3d.astar.get_closest_point(ray_point)
|
|
||||||
if !Game.level.a_star_graph_3d.point_is_build_location(point_id) or hero.currency < Data.wall_cost:
|
|
||||||
wall_preview.set_visible(false)
|
|
||||||
else:
|
|
||||||
var point_position: Vector3 = Game.level.a_star_graph_3d.astar.get_point_position(point_id)
|
|
||||||
wall_preview.global_position = point_position
|
|
||||||
wall_preview.global_rotation = Vector3.ZERO
|
|
||||||
if obstacle_last_point != point_id:
|
|
||||||
obstacle_last_point = point_id
|
|
||||||
if Game.level.a_star_graph_3d.test_path_if_point_toggled(point_id):
|
|
||||||
var c: Color = Color.GREEN
|
|
||||||
c.a = 0.8
|
|
||||||
wall_preview.set_color(c)
|
|
||||||
wall_preview.set_float(0.0)
|
|
||||||
valid_point = true
|
|
||||||
else:
|
|
||||||
#build_preview_material.albedo_color = Color.RED
|
|
||||||
#build_preview_material.albedo_color.a = 0.8
|
|
||||||
valid_point = false
|
|
||||||
else:
|
|
||||||
ray_collider = null
|
|
||||||
is_looking_at_tower_base = false
|
|
||||||
delete_tower_preview()
|
|
||||||
wall_preview.set_visible(false)
|
|
||||||
if !valid_point:
|
|
||||||
wall_preview.set_visible(false)
|
|
||||||
|
|
||||||
|
|
||||||
func spawn_tower_preview() -> void:
|
|
||||||
delete_tower_preview()
|
|
||||||
last_tower_base = ray_collider
|
|
||||||
var card: Card = inventory.contents.keys()[hero.inventory_selected_index]
|
|
||||||
last_card = card
|
|
||||||
tower_preview = card.turret_scene.instantiate() as Tower
|
|
||||||
tower_preview.stats = card.tower_stats
|
|
||||||
tower_preview.position = Vector3.UP
|
|
||||||
tower_preview.preview_range(true)
|
|
||||||
ray_collider.add_child(tower_preview)
|
|
||||||
|
|
||||||
|
|
||||||
func delete_tower_preview() -> void:
|
|
||||||
last_tower_base = null
|
|
||||||
last_card = null
|
|
||||||
if is_instance_valid(tower_preview):
|
|
||||||
tower_preview.queue_free()
|
|
||||||
tower_preview = null
|
|
||||||
|
|
||||||
|
|
||||||
func interact() -> void:
|
|
||||||
if ray_collider is TowerBase:
|
|
||||||
var tower_base: TowerBase = ray_collider as TowerBase
|
|
||||||
put_card_in_tower_base(tower_base)
|
|
||||||
|
|
||||||
|
|
||||||
func build_wall() -> void:
|
|
||||||
if point_id >= 0 and valid_point and hero.currency >= Data.wall_cost:
|
|
||||||
hero.currency -= Data.wall_cost
|
|
||||||
Game.level.a_star_graph_3d.toggle_point(point_id, multiplayer.get_unique_id())
|
|
||||||
wall_preview.set_visible(false)
|
|
||||||
|
|
||||||
|
|
||||||
func refund_wall(wall: TowerBase) -> void:
|
|
||||||
if !is_instance_valid(wall):
|
|
||||||
return
|
|
||||||
last_collider = null
|
|
||||||
if wall.has_card:
|
|
||||||
wall.remove_card()
|
|
||||||
Game.level.a_star_graph_3d.remove_wall(wall)
|
|
||||||
|
|
||||||
|
|
||||||
func put_card_in_tower_base(tower_base: TowerBase) -> void:
|
|
||||||
if tower_base.has_card:
|
|
||||||
tower_base.remove_card()
|
|
||||||
elif inventory.size > 0:
|
|
||||||
var card: Card = inventory.remove_at(hero.inventory_selected_index)
|
|
||||||
if !inventory.contents.has(card):
|
|
||||||
hero.decrement_selected()
|
|
||||||
tower_base.add_card(card, multiplayer.get_unique_id())
|
|
||||||
hero.place_card_audio.play()
|
|
||||||
|
|
||||||
|
|
||||||
func set_progress_percent(value: float) -> void:
|
|
||||||
progress_bar.value = progress_bar.max_value * value
|
|
@ -6,13 +6,12 @@ signal enemy_spawned()
|
|||||||
@export var leap_enemy_scene: PackedScene
|
@export var leap_enemy_scene: PackedScene
|
||||||
@export var air_enemy_scene: PackedScene
|
@export var air_enemy_scene: PackedScene
|
||||||
@export var path: VisualizedPath
|
@export var path: VisualizedPath
|
||||||
var astar: AStarGraph3D
|
@export var flow_field: FlowField
|
||||||
@export var own_id: int = 0
|
@export var own_id: int = 0
|
||||||
@export var type: Data.EnemyType
|
@export var type: Data.EnemyType
|
||||||
@export var dest: Node3D
|
@export var dest: Node3D
|
||||||
@export var enemy_path: Node
|
@export var enemy_path: Node
|
||||||
|
|
||||||
var astar_point_id: int = 0
|
|
||||||
var enemy_died_callback: Callable
|
var enemy_died_callback: Callable
|
||||||
var enemy_reached_goal_callback: Callable
|
var enemy_reached_goal_callback: Callable
|
||||||
var current_wave: Array[EnemyCard]
|
var current_wave: Array[EnemyCard]
|
||||||
@ -22,6 +21,13 @@ var enemies_spawned: Dictionary = {}
|
|||||||
var enemies_to_spawn: int = 0
|
var enemies_to_spawn: int = 0
|
||||||
var done_spawning: bool = true
|
var done_spawning: bool = true
|
||||||
var enemy_id: int = 0
|
var enemy_id: int = 0
|
||||||
|
var new_path: Path3D
|
||||||
|
var path_polygon: PackedScene = preload("res://path_polygon.tscn")
|
||||||
|
var game_manager: GameManager
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
create_path()
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
@ -29,56 +35,90 @@ func _process(delta: float) -> void:
|
|||||||
done_spawning = true
|
done_spawning = true
|
||||||
return
|
return
|
||||||
|
|
||||||
for x: Enemy in enemy_spawn_timers:
|
for enemy: Enemy in enemy_spawn_timers:
|
||||||
if enemies_spawned[x] == enemy_types_to_spawn[x]:
|
if enemies_spawned[enemy] == enemy_types_to_spawn[enemy]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
var enemy_stats: Enemy = x
|
enemy_spawn_timers[enemy] += delta
|
||||||
enemy_spawn_timers[x] += delta
|
|
||||||
|
|
||||||
if enemy_spawn_timers[x] >= enemy_stats.spawn_cooldown:
|
if enemy_spawn_timers[enemy] >= enemy.spawn_cooldown:
|
||||||
if is_multiplayer_authority():
|
if is_multiplayer_authority():
|
||||||
if type == Data.EnemyType.LAND:
|
if type == Data.EnemyType.LAND:
|
||||||
networked_spawn_land_enemy.rpc(Data.enemies.find(enemy_stats), own_id, enemy_id)
|
networked_spawn_land_enemy.rpc(enemy.title, own_id, enemy_id)
|
||||||
if type == Data.EnemyType.AIR:
|
if type == Data.EnemyType.AIR:
|
||||||
var radius: float = 10.0
|
var radius: float = 10.0
|
||||||
var random_dir: Vector3 = Vector3(randf_range(-1, 1), randf_range(-1, 1), randf_range(-1, 1))
|
var random_dir: Vector3 = Vector3(randf_range(-1, 1), randf_range(-1, 1), randf_range(-1, 1))
|
||||||
var random_pos: Vector3 = randf_range(0, radius) * random_dir.normalized()
|
var random_pos: Vector3 = randf_range(0, radius) * random_dir.normalized()
|
||||||
networked_spawn_air_enemy.rpc(Data.enemies.find(enemy_stats), random_pos, own_id, enemy_id)
|
networked_spawn_air_enemy.rpc(enemy.title, random_pos, own_id, enemy_id)
|
||||||
|
|
||||||
enemy_spawn_timers[x] -= enemy_stats.spawn_cooldown
|
enemy_spawn_timers[enemy] -= enemy.spawn_cooldown
|
||||||
enemy_spawned.emit()
|
enemy_spawned.emit()
|
||||||
enemy_id += 1
|
enemy_id += 1
|
||||||
enemies_spawned[x] += 1
|
enemies_spawned[enemy] += 1
|
||||||
enemies_to_spawn -= 1
|
enemies_to_spawn -= 1
|
||||||
|
|
||||||
|
|
||||||
#TODO: not sure enemies need all this info over the network
|
#TODO: not sure enemies need all this info over the network
|
||||||
#TODO: generalize enemy scene selection, i.e. store the scenes in the enemy
|
|
||||||
#card like towers do
|
|
||||||
@rpc("reliable", "call_local")
|
@rpc("reliable", "call_local")
|
||||||
func networked_spawn_land_enemy(enemy_stats: int, id1: int, id2: int) -> void:
|
func networked_spawn_land_enemy(enemy_stats: String, id1: int, id2: int) -> void:
|
||||||
|
var e_stats: Enemy = null
|
||||||
|
for enemy: Enemy in game_manager.level.enemy_pool:
|
||||||
|
if enemy.title == enemy_stats:
|
||||||
|
e_stats = enemy
|
||||||
var enemy: EnemyController
|
var enemy: EnemyController
|
||||||
if enemy_stats != 6:
|
enemy = e_stats.scene.instantiate()
|
||||||
enemy = land_enemy_scene.instantiate() as EnemyController
|
enemy.corpse_root = game_manager.level.corpses
|
||||||
else:
|
|
||||||
enemy = leap_enemy_scene.instantiate() as EnemyController
|
|
||||||
enemy.name = str(id1) + str(id2)
|
enemy.name = str(id1) + str(id2)
|
||||||
enemy.stats = Data.enemies[enemy_stats]
|
enemy.stats = e_stats
|
||||||
enemy.died.connect(enemy_died_callback)
|
enemy.died.connect(enemy_died_callback)
|
||||||
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
||||||
enemy.movement_controller.path = path.curve
|
#enemy.movement_controller.path = path.curve
|
||||||
enemy.movement_controller.astar = astar
|
#enemy.movement_controller.astar = astar
|
||||||
|
enemy.movement_controller.flow_field = flow_field
|
||||||
enemy.position = global_position
|
enemy.position = global_position
|
||||||
enemy_path.add_child(enemy)
|
enemy_path.add_child(enemy)
|
||||||
|
|
||||||
|
|
||||||
|
func create_path() -> void:
|
||||||
|
if type != Data.EnemyType.LAND:
|
||||||
|
return
|
||||||
|
new_path = Path3D.new()
|
||||||
|
new_path.curve = Curve3D.new()
|
||||||
|
add_child(new_path)
|
||||||
|
var polygon: CSGPolygon3D = path_polygon.instantiate()
|
||||||
|
new_path.add_child(polygon)
|
||||||
|
polygon.mode = CSGPolygon3D.MODE_PATH
|
||||||
|
polygon.path_node = new_path.get_path()
|
||||||
|
new_path.global_position = Vector3.ZERO
|
||||||
|
update_path()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func update_path() -> void:
|
||||||
|
if type != Data.EnemyType.LAND:
|
||||||
|
return
|
||||||
|
new_path.curve.add_point(global_position + Vector3(0, 0.5, 0))
|
||||||
|
new_path.curve = Curve3D.new()
|
||||||
|
var node: FlowNode = flow_field.get_closest_traversable_point(global_position)
|
||||||
|
new_path.curve.add_point(node.global_position + Vector3(0, 0.5, 0))
|
||||||
|
while node.best_path:
|
||||||
|
node = node.best_path
|
||||||
|
new_path.curve.add_point(node.global_position + Vector3(0, 0.5, 0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@rpc("reliable", "call_local")
|
@rpc("reliable", "call_local")
|
||||||
func networked_spawn_air_enemy(enemy_stats: int, pos: Vector3, id1: int, id2: int) -> void:
|
func networked_spawn_air_enemy(enemy_stats: String, pos: Vector3, id1: int, id2: int) -> void:
|
||||||
var enemy: EnemyController = air_enemy_scene.instantiate() as EnemyController
|
var e_stats: Enemy = null
|
||||||
|
for enemy: Enemy in game_manager.level.enemy_pool:
|
||||||
|
if enemy.title == enemy_stats:
|
||||||
|
e_stats = enemy
|
||||||
|
var enemy: EnemyController
|
||||||
|
enemy = e_stats.scene.instantiate()
|
||||||
|
enemy.corpse_root = game_manager.level.corpses
|
||||||
enemy.name = str(id1) + str(id2)
|
enemy.name = str(id1) + str(id2)
|
||||||
enemy.position = pos + global_position
|
enemy.position = pos + global_position
|
||||||
enemy.stats = Data.enemies[enemy_stats]
|
enemy.stats = e_stats
|
||||||
enemy.died.connect(enemy_died_callback)
|
enemy.died.connect(enemy_died_callback)
|
||||||
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
enemy.reached_goal.connect(enemy_reached_goal_callback)
|
||||||
enemy.movement_controller.goal = dest
|
enemy.movement_controller.goal = dest
|
||||||
|
155
Scripts/flow_field_tool.gd
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
class_name FlowFieldTool extends Node
|
||||||
|
|
||||||
|
@export var flow_field: FlowField
|
||||||
|
@export var raycast: RayCast3D
|
||||||
|
@export var project_raycast: RayCast3D
|
||||||
|
@export var camera: Camera3D
|
||||||
|
@export var camera_pivot: Node3D
|
||||||
|
@export var position_field: HBoxContainer
|
||||||
|
@export var x_field: LineEdit
|
||||||
|
@export var y_field: LineEdit
|
||||||
|
@export var z_field: LineEdit
|
||||||
|
@export var x_size_field: LineEdit
|
||||||
|
@export var y_size_field: LineEdit
|
||||||
|
@export var gap_field: LineEdit
|
||||||
|
|
||||||
|
var hover: FlowNode = null
|
||||||
|
var selected: Array[FlowNode] = []
|
||||||
|
var vector_dirty: bool = false
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
camera.make_current()
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
if raycast.is_colliding() and (!hover or hover != raycast.get_collider()):
|
||||||
|
hover = raycast.get_collider()
|
||||||
|
if hover and !raycast.is_colliding():
|
||||||
|
hover = null
|
||||||
|
if selected.size() == 1 and vector_dirty:
|
||||||
|
position_field.visible = true
|
||||||
|
x_field.text = str(selected[0].global_position.x)
|
||||||
|
y_field.text = str(selected[0].global_position.y)
|
||||||
|
z_field.text = str(selected[0].global_position.z)
|
||||||
|
vector_dirty = false
|
||||||
|
elif selected.size() != 1:
|
||||||
|
position_field.visible = false
|
||||||
|
|
||||||
|
for node: FlowNode in flow_field.nodes:
|
||||||
|
if node.traversable and node.buildable:
|
||||||
|
node.set_color(Color.WEB_GRAY)
|
||||||
|
elif node.traversable and !node.buildable:
|
||||||
|
node.set_color(Color.CORAL)
|
||||||
|
else:
|
||||||
|
node.set_color(Color.BLACK)
|
||||||
|
if flow_field.goals.has(node):
|
||||||
|
node.set_color(Color.BLUE)
|
||||||
|
if flow_field.starts.has(node):
|
||||||
|
node.set_color(Color.PINK)
|
||||||
|
if selected.has(node):
|
||||||
|
node.set_color(Color.GREEN)
|
||||||
|
if node == hover:
|
||||||
|
node.set_color(Color.RED)
|
||||||
|
|
||||||
|
var y: float = Input.get_axis("Move Forward", "Move Backward")
|
||||||
|
var x: float = Input.get_axis("Move Left", "Move Right")
|
||||||
|
camera_pivot.position += Vector3(x, 0, y) * delta * 10
|
||||||
|
|
||||||
|
|
||||||
|
func _unhandled_input(event: InputEvent) -> void:
|
||||||
|
if event is InputEventMouseMotion:
|
||||||
|
var from: Vector3 = camera.project_ray_origin(event.position)
|
||||||
|
var to: Vector3 = camera.project_local_ray_normal(event.position)
|
||||||
|
raycast.global_position = from
|
||||||
|
raycast.target_position = to * 1000.0
|
||||||
|
if event is InputEventMouseButton and event.button_index == 1 and hover:
|
||||||
|
if !selected.has(hover):
|
||||||
|
selected.append(hover)
|
||||||
|
vector_dirty = true
|
||||||
|
if event is InputEventMouseButton and event.button_index == 2 and selected.size() > 0:
|
||||||
|
selected = []
|
||||||
|
|
||||||
|
|
||||||
|
func _on_x_field_changed(text: String) -> void:
|
||||||
|
selected[0].global_position.x = float(text)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_y_field_changed(text: String) -> void:
|
||||||
|
selected[0].global_position.y = float(text)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_z_field_changed(text: String) -> void:
|
||||||
|
selected[0].global_position.z = float(text)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_create_button_pressed() -> void:
|
||||||
|
flow_field.create_node()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_generate_grid_button_pressed() -> void:
|
||||||
|
flow_field.create_grid(int(x_size_field.text), int(y_size_field.text), float(gap_field.text))
|
||||||
|
selected.append_array(flow_field.nodes)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_calculate_button_pressed() -> void:
|
||||||
|
flow_field.calculate()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_connect_button_pressed() -> void:
|
||||||
|
flow_field.connect_many_nodes(selected[0], selected.slice(1, selected.size()))
|
||||||
|
|
||||||
|
|
||||||
|
func _on_mark_goal_button_pressed() -> void:
|
||||||
|
flow_field.toggle_goal(selected)
|
||||||
|
selected = []
|
||||||
|
vector_dirty = true
|
||||||
|
|
||||||
|
|
||||||
|
func _on_mark_start_button_pressed() -> void:
|
||||||
|
flow_field.toggle_start(selected)
|
||||||
|
selected = []
|
||||||
|
vector_dirty = true
|
||||||
|
|
||||||
|
|
||||||
|
func _on_extrude_button_pressed() -> void:
|
||||||
|
if selected.size() == 1:
|
||||||
|
var node: FlowNode = flow_field.create_node(selected[0].position)
|
||||||
|
node.add_connection(selected[0])
|
||||||
|
selected[0].add_connection(node)
|
||||||
|
selected[0].set_color(Color.WEB_GRAY)
|
||||||
|
selected = []
|
||||||
|
selected.append(node)
|
||||||
|
vector_dirty = true
|
||||||
|
|
||||||
|
|
||||||
|
func _on_toggle_traversable_button_pressed() -> void:
|
||||||
|
for node: FlowNode in selected:
|
||||||
|
if !flow_field.toggle_traversable(node):
|
||||||
|
flow_field.toggle_traversable(node)
|
||||||
|
selected = []
|
||||||
|
return
|
||||||
|
selected = []
|
||||||
|
|
||||||
|
|
||||||
|
func _on_toggle_buildable_button_pressed() -> void:
|
||||||
|
for node: FlowNode in selected:
|
||||||
|
flow_field.toggle_buildable(node)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_finalize_button_pressed() -> void:
|
||||||
|
var packed_scene: PackedScene = PackedScene.new()
|
||||||
|
packed_scene.pack(flow_field)
|
||||||
|
ResourceSaver.save(packed_scene, "res://flow_field_tool_output.tscn")
|
||||||
|
|
||||||
|
#TODO: This doesnt work as you'd expect because of physics frames
|
||||||
|
func _on_project_downwards_button_pressed() -> void:
|
||||||
|
for node: FlowNode in selected:
|
||||||
|
project_raycast.global_position = node.global_position + Vector3.UP
|
||||||
|
project_raycast.target_position = Vector3.DOWN * 100.0
|
||||||
|
await get_tree().physics_frame
|
||||||
|
await get_tree().physics_frame
|
||||||
|
await get_tree().physics_frame
|
||||||
|
await get_tree().physics_frame
|
||||||
|
if project_raycast.is_colliding():
|
||||||
|
node.global_position = project_raycast.get_collision_point()
|
1
Scripts/flow_field_tool.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://05c5q1v2nv8p
|
@ -1,8 +1,10 @@
|
|||||||
class_name FlowNode extends StaticBody3D
|
class_name FlowNode extends StaticBody3D
|
||||||
|
|
||||||
var connections: Array[FlowNode]
|
@export var connections: Array[FlowNode]
|
||||||
var visualisers: Array[CSGBox3D]
|
@export var visualisers: Array[Node3D]
|
||||||
var traversable: bool = true
|
var visual_scene: PackedScene = preload("res://cube2.tscn")
|
||||||
|
@export var traversable: bool = true
|
||||||
|
@export var buildable: bool = true
|
||||||
var best_path: FlowNode :
|
var best_path: FlowNode :
|
||||||
get():
|
get():
|
||||||
return best_path
|
return best_path
|
||||||
@ -12,33 +14,44 @@ var best_path: FlowNode :
|
|||||||
set_connector_color(best_path, Color.DARK_GREEN)
|
set_connector_color(best_path, Color.DARK_GREEN)
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
visualisers = []
|
||||||
|
for node: FlowNode in connections:
|
||||||
|
var visual: Node3D = visual_scene.instantiate()
|
||||||
|
add_child(visual)
|
||||||
|
visual.owner = self
|
||||||
|
visualisers.append(visual)
|
||||||
|
set_connector_color(node, Color.WEB_GRAY)
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
|
if visible:
|
||||||
for i: int in connections.size():
|
for i: int in connections.size():
|
||||||
var distance: float = global_position.distance_to(connections[i].global_position)
|
var distance: float = global_position.distance_to(connections[i].global_position)
|
||||||
visualisers[i].size = Vector3(0.3, 0.3, 1.0 * (distance / 2.0))
|
visualisers[i].scale = Vector3(0.3, 0.3, 1.0 * (distance / 2.0))
|
||||||
visualisers[i].position = to_local(connections[i].global_position) / 4.0
|
visualisers[i].position = to_local(connections[i].global_position) / 4.0
|
||||||
if distance >= 0.05:
|
if distance >= 0.05:
|
||||||
visualisers[i].look_at(connections[i].global_position)
|
visualisers[i].look_at(connections[i].global_position)
|
||||||
|
|
||||||
|
|
||||||
func set_color(new_color: Color) -> void:
|
func set_color(new_color: Color) -> void:
|
||||||
$CSGSphere3D.material.albedo_color = new_color
|
$flow_node/Sphere.material_override.albedo_color = new_color
|
||||||
|
|
||||||
|
|
||||||
func set_connector_color(node: FlowNode, new_color: Color) -> void:
|
func set_connector_color(node: FlowNode, new_color: Color) -> void:
|
||||||
|
if visible:
|
||||||
var i: int = connections.find(node)
|
var i: int = connections.find(node)
|
||||||
visualisers[i].material.albedo_color = new_color
|
visualisers[i].get_child(0).material_override.albedo_color = new_color
|
||||||
|
|
||||||
|
|
||||||
func add_connection(node: FlowNode) -> void:
|
func add_connection(node: FlowNode) -> void:
|
||||||
if !connections.has(node):
|
if !connections.has(node):
|
||||||
var visual: CSGBox3D = CSGBox3D.new()
|
var visual: Node3D = visual_scene.instantiate()
|
||||||
visual.material = StandardMaterial3D.new()
|
|
||||||
visual.material.resource_local_to_scene = true
|
|
||||||
visual.material.albedo_color = Color.DARK_GRAY
|
|
||||||
add_child(visual)
|
add_child(visual)
|
||||||
|
visual.owner = self
|
||||||
connections.append(node)
|
connections.append(node)
|
||||||
visualisers.append(visual)
|
visualisers.append(visual)
|
||||||
|
set_connector_color(node, Color.WEB_GRAY)
|
||||||
|
|
||||||
|
|
||||||
func remove_connection(node: FlowNode) -> void:
|
func remove_connection(node: FlowNode) -> void:
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
|
class_name GameManager
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
signal wave_started(wave_number: int)
|
signal wave_started(wave_number: int)
|
||||||
signal wave_finished(wave_number: int)
|
signal wave_finished(wave_number: int)
|
||||||
signal base_took_damage(remaining_health: int)
|
signal base_took_damage(remaining_health: int)
|
||||||
signal rng_seeded
|
|
||||||
signal game_setup
|
signal game_setup
|
||||||
signal game_started
|
signal game_started
|
||||||
signal lost_game
|
signal lost_game
|
||||||
signal won_game
|
signal won_game
|
||||||
|
signal rng_seeded
|
||||||
|
signal switch_to_single_player
|
||||||
|
signal switch_to_multi_player
|
||||||
|
signal switch_to_main_menu
|
||||||
|
|
||||||
var level_scene: PackedScene = load("res://Worlds/GreenPlanet/Levels/first_level.tscn")
|
var level_scene: PackedScene = load("res://Worlds/GreenPlanet/Levels/first_level.tscn")
|
||||||
var player_scene: PackedScene = load("res://PCs/hero.tscn")
|
var player_scene: PackedScene = load("res://PCs/hero.tscn")
|
||||||
var main_menu_scene_path: String = "res://Scenes/Menus/MainMenu/main_menu.tscn"
|
|
||||||
var multiplayer_lobby_scene_path: String = "res://Scenes/Menus/multiplayer_lobby.tscn"
|
|
||||||
var singleplayer_lobby_scene_path: String = "res://Scenes/Menus/singleplayer_lobby.tscn"
|
|
||||||
var game_end_scene: PackedScene = load("res://Scenes/Menus/GameEndScreen/game_end_screen.tscn")
|
var game_end_scene: PackedScene = load("res://Scenes/Menus/GameEndScreen/game_end_screen.tscn")
|
||||||
var connected_players_nodes: Dictionary = {}
|
var connected_players_nodes: Dictionary = {}
|
||||||
var game_active: bool = false
|
var game_active: bool = false
|
||||||
@ -29,7 +30,7 @@ var wave_limit: int = 20
|
|||||||
var starting_cash: int = 25
|
var starting_cash: int = 25
|
||||||
var shop_chance: float = 0.0
|
var shop_chance: float = 0.0
|
||||||
var stats: RoundStats
|
var stats: RoundStats
|
||||||
var rng: FastNoiseLite
|
|
||||||
|
|
||||||
#TODO: Create a reference to some generic Lobby object that wraps the multiplayer players list stuff
|
#TODO: Create a reference to some generic Lobby object that wraps the multiplayer players list stuff
|
||||||
var connected_player_profiles: Dictionary = {}
|
var connected_player_profiles: Dictionary = {}
|
||||||
@ -39,25 +40,17 @@ func _ready() -> void:
|
|||||||
UILayer = CanvasLayer.new()
|
UILayer = CanvasLayer.new()
|
||||||
UILayer.layer = 2
|
UILayer.layer = 2
|
||||||
get_tree().root.add_child.call_deferred(UILayer)
|
get_tree().root.add_child.call_deferred(UILayer)
|
||||||
|
var version_label: Label = Label.new()
|
||||||
|
var version: String = ProjectSettings.get_setting("application/config/version")
|
||||||
@rpc("reliable", "call_local")
|
version_label.text = "WORK IN PROGRESS | ALPHA - VERSION " + version + " | PLAYTEST"
|
||||||
func set_seed(value: int) -> void:
|
version_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||||
rng = FastNoiseLite.new()
|
version_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
rng.noise_type = FastNoiseLite.TYPE_VALUE
|
version_label.add_theme_font_size_override("font_size", 18)
|
||||||
rng.frequency = 30
|
version_label.add_theme_color_override("font_color", Color(0.85, 0.85, 0.85, 0.7))
|
||||||
rng.fractal_octaves = 2
|
version_label.set_anchors_preset(Control.PRESET_TOP_WIDE)
|
||||||
rng.fractal_gain = 0.1
|
UILayer.add_child(version_label)
|
||||||
rng.seed = value
|
Input.set_custom_mouse_cursor(load("res://Assets/Textures/cursor_none.png"), Input.CURSOR_ARROW, Vector2(9, 6))
|
||||||
rng_seeded.emit()
|
Input.set_custom_mouse_cursor(load("res://Assets/Textures/bracket_b_vertical.png"), Input.CURSOR_IBEAM, Vector2(16, 16))
|
||||||
|
|
||||||
|
|
||||||
func randi_in_range(sample: float, output_start: int, output_end: int) -> int:
|
|
||||||
return floori(remap(rng.get_noise_1d(sample), -1.0, 1.0, float(output_start), float(output_end + 1)))
|
|
||||||
|
|
||||||
|
|
||||||
func randf_in_range(sample: float, output_start: float, output_end: float) -> float:
|
|
||||||
return remap(rng.get_noise_1d(sample), -1.0, 1.0, output_start, output_end)
|
|
||||||
|
|
||||||
|
|
||||||
func parse_command(text: String, peer_id: int) -> void:
|
func parse_command(text: String, peer_id: int) -> void:
|
||||||
@ -99,7 +92,7 @@ func parse_command(text: String, peer_id: int) -> void:
|
|||||||
else:
|
else:
|
||||||
chatbox.append_message("SERVER", Color.TOMATO, "Unable to set wave")
|
chatbox.append_message("SERVER", Color.TOMATO, "Unable to set wave")
|
||||||
elif text.substr(1, 4) == "seed":
|
elif text.substr(1, 4) == "seed":
|
||||||
chatbox.append_message("SERVER", Color.TOMATO, str(rng.seed))
|
chatbox.append_message("SERVER", Color.TOMATO, str(NoiseRandom.noise.seed))
|
||||||
# if text.substr(1, 17) == "show tower ranges":
|
# if text.substr(1, 17) == "show tower ranges":
|
||||||
# pass
|
# pass
|
||||||
# if text.substr(1, 20) = "show gauntlet ranges":
|
# if text.substr(1, 20) = "show gauntlet ranges":
|
||||||
@ -117,8 +110,10 @@ func networked_set_wave(wave_number: int) -> void:
|
|||||||
|
|
||||||
func spawn_level() -> void:
|
func spawn_level() -> void:
|
||||||
level = level_scene.instantiate() as Level
|
level = level_scene.instantiate() as Level
|
||||||
|
level.game_manager = self
|
||||||
for x: EnemySpawner in level.enemy_spawns:
|
for x: EnemySpawner in level.enemy_spawns:
|
||||||
#x.path = level.a_star_graph_3d.visualized_path
|
#x.path = level.a_star_graph_3d.visualized_path
|
||||||
|
x.game_manager = self
|
||||||
x.enemy_died_callback = enemy_died
|
x.enemy_died_callback = enemy_died
|
||||||
x.enemy_reached_goal_callback = damage_goal
|
x.enemy_reached_goal_callback = damage_goal
|
||||||
x.enemy_spawned.connect(increase_enemy_count)
|
x.enemy_spawned.connect(increase_enemy_count)
|
||||||
@ -132,6 +127,9 @@ func spawn_players() -> void:
|
|||||||
for peer_id: int in player_array:
|
for peer_id: int in player_array:
|
||||||
var player: Hero = player_scene.instantiate() as Hero
|
var player: Hero = player_scene.instantiate() as Hero
|
||||||
player.name = str(peer_id)
|
player.name = str(peer_id)
|
||||||
|
player.game_manager = self
|
||||||
|
player.edit_tool.level = level
|
||||||
|
player.hud.map_anchor = level
|
||||||
player.player_name_tag.text = connected_player_profiles[peer_id].display_name
|
player.player_name_tag.text = connected_player_profiles[peer_id].display_name
|
||||||
player.position = level.player_spawns[p_i].global_position
|
player.position = level.player_spawns[p_i].global_position
|
||||||
player.profile = connected_player_profiles[peer_id]
|
player.profile = connected_player_profiles[peer_id]
|
||||||
@ -169,10 +167,12 @@ func ready_player(player_ready_true: bool) -> void:
|
|||||||
func spawn_enemy_wave() -> void:
|
func spawn_enemy_wave() -> void:
|
||||||
level.shop.close()
|
level.shop.close()
|
||||||
wave += 1
|
wave += 1
|
||||||
level.a_star_graph_3d.find_path()
|
level.disable_all_tower_frames()
|
||||||
level.a_star_graph_3d.disable_all_tower_frames()
|
#level.a_star_graph_3d.find_path()
|
||||||
|
#level.a_star_graph_3d.disable_all_tower_frames()
|
||||||
|
level.flow_field.calculate()
|
||||||
for spawn: EnemySpawner in level.enemy_spawns:
|
for spawn: EnemySpawner in level.enemy_spawns:
|
||||||
spawn.path.disable_visualization()
|
#spawn.path.disable_visualization()
|
||||||
spawn.spawn_wave()
|
spawn.spawn_wave()
|
||||||
wave_started.emit(wave)
|
wave_started.emit(wave)
|
||||||
|
|
||||||
@ -248,13 +248,14 @@ func end_wave() -> void:
|
|||||||
connected_players_nodes[peer_id].unready_self()
|
connected_players_nodes[peer_id].unready_self()
|
||||||
for spawn: EnemySpawner in level.enemy_spawns:
|
for spawn: EnemySpawner in level.enemy_spawns:
|
||||||
spawn.path.enable_visualization()
|
spawn.path.enable_visualization()
|
||||||
level.a_star_graph_3d.enable_non_path_tower_frames()
|
#level.a_star_graph_3d.enable_non_path_tower_frames()
|
||||||
|
level.enable_non_path_tower_frames()
|
||||||
if is_multiplayer_authority():
|
if is_multiplayer_authority():
|
||||||
if randf_in_range(23 * wave, 0.0, 1.0) <= shop_chance:
|
if NoiseRandom.randf_in_range(23 * wave, 0.0, 1.0) <= shop_chance:
|
||||||
networked_spawn_shop.rpc()
|
networked_spawn_shop.rpc()
|
||||||
shop_chance = 0.0
|
shop_chance = 0.0
|
||||||
else:
|
else:
|
||||||
shop_chance += 0.07
|
shop_chance += 0.09
|
||||||
wave_finished.emit(wave)
|
wave_finished.emit(wave)
|
||||||
set_upcoming_wave()
|
set_upcoming_wave()
|
||||||
|
|
||||||
@ -291,6 +292,12 @@ func setup() -> void:
|
|||||||
game_setup.emit()
|
game_setup.emit()
|
||||||
|
|
||||||
|
|
||||||
|
@rpc("reliable", "call_local")
|
||||||
|
func set_seed(value: int) -> void:
|
||||||
|
NoiseRandom.set_seed(value)
|
||||||
|
rng_seeded.emit()
|
||||||
|
|
||||||
|
|
||||||
func start() -> void:
|
func start() -> void:
|
||||||
if is_multiplayer_authority():
|
if is_multiplayer_authority():
|
||||||
set_seed.rpc(gamemode.rng_seed)
|
set_seed.rpc(gamemode.rng_seed)
|
||||||
@ -304,15 +311,18 @@ func start() -> void:
|
|||||||
|
|
||||||
#Relies on rng having been seeded
|
#Relies on rng having been seeded
|
||||||
set_upcoming_wave()
|
set_upcoming_wave()
|
||||||
level.a_star_graph_3d.make_grid()
|
level.flow_field.calculate()
|
||||||
|
level.enemy_spawns[0].update_path()
|
||||||
|
#level.a_star_graph_3d.make_grid()
|
||||||
level.generate_obstacles()
|
level.generate_obstacles()
|
||||||
level.a_star_graph_3d.disable_all_tower_frames()
|
level.enable_non_path_tower_frames()
|
||||||
level.a_star_graph_3d.enable_non_path_tower_frames()
|
#level.a_star_graph_3d.disable_all_tower_frames()
|
||||||
level.a_star_graph_3d.find_path()
|
#level.a_star_graph_3d.enable_non_path_tower_frames()z
|
||||||
|
#level.a_star_graph_3d.find_path()
|
||||||
|
|
||||||
#Start game
|
#Start game
|
||||||
game_active = true
|
game_active = true
|
||||||
chatbox.append_message("SERVER", Color.TOMATO, "Started with seed: " + str(rng.seed))
|
chatbox.append_message("SERVER", Color.TOMATO, "Started with seed: " + str(NoiseRandom.noise.seed))
|
||||||
game_started.emit()
|
game_started.emit()
|
||||||
#print("started game with seed: " + str(gamemode.rng_seed))
|
#print("started game with seed: " + str(gamemode.rng_seed))
|
||||||
|
|
||||||
@ -324,6 +334,7 @@ func end(outcome: bool) -> void:
|
|||||||
Data.save_data.add_game_outcome(outcome)
|
Data.save_data.add_game_outcome(outcome)
|
||||||
Data.save_data.save_to_disc()
|
Data.save_data.save_to_disc()
|
||||||
var menu: GameEndScreen = game_end_scene.instantiate() as GameEndScreen
|
var menu: GameEndScreen = game_end_scene.instantiate() as GameEndScreen
|
||||||
|
menu.game_manager = self
|
||||||
match outcome:
|
match outcome:
|
||||||
false:
|
false:
|
||||||
menu.set_outcome_message("You lost...")
|
menu.set_outcome_message("You lost...")
|
||||||
@ -349,12 +360,15 @@ func scene_switch_main_menu() -> void:
|
|||||||
connected_players_nodes.clear()
|
connected_players_nodes.clear()
|
||||||
multiplayer.multiplayer_peer.close()
|
multiplayer.multiplayer_peer.close()
|
||||||
multiplayer.multiplayer_peer = null
|
multiplayer.multiplayer_peer = null
|
||||||
get_tree().change_scene_to_file(main_menu_scene_path)
|
switch_to_main_menu.emit()
|
||||||
|
#get_tree().change_scene_to_file(main_menu_scene_path)
|
||||||
|
|
||||||
|
|
||||||
func scene_switch_to_multiplayer_lobby() -> void:
|
func scene_switch_to_multiplayer_lobby() -> void:
|
||||||
get_tree().change_scene_to_file(multiplayer_lobby_scene_path)
|
switch_to_multi_player.emit()
|
||||||
|
#get_tree().change_scene_to_file(multiplayer_lobby_scene_path)
|
||||||
|
|
||||||
|
|
||||||
func scene_switch_to_singleplayer_lobby() -> void:
|
func scene_switch_to_singleplayer_lobby() -> void:
|
||||||
get_tree().change_scene_to_file(singleplayer_lobby_scene_path)
|
switch_to_single_player.emit()
|
||||||
|
#get_tree().change_scene_to_file(singleplayer_lobby_scene_path)
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
class_name Hitbox extends CollisionShape3D
|
class_name Hitbox extends CollisionShape3D
|
||||||
|
|
||||||
|
@export var critical_zone: bool = false
|
||||||
|
|
||||||
signal took_damage(amount: int)
|
signal took_damage(amount: int)
|
||||||
|
|
||||||
|
|
||||||
func damage(amount: int) -> void:
|
func damage(amount: int) -> void:
|
||||||
took_damage.emit(amount)
|
took_damage.emit(amount * 1.5 if critical_zone else amount)
|
||||||
|