Compare commits

...

47 Commits

Author SHA1 Message Date
Nikolay Fedorov 912bffd59a Merge branch 'exp' of https://git.nfedorov.dev/DragonSpirit/KickSurvivors into exp 2026-04-23 17:45:50 +03:00
Nikolay Fedorov a2e710575e import new gnomes 2026-04-23 17:45:17 +03:00
Georgiy Gorin 31cab204ad Правки 2 2026-04-23 17:40:24 +03:00
Georgiy Gorin 3a3edc54a4 По хуйне 2026-04-23 17:34:24 +03:00
DragonSpirit 05f46021b8 add recepies list 2026-04-23 17:29:43 +03:00
Georgiy Gorin 5f589c8c89 Железо добавлено 2026-04-23 17:20:24 +03:00
DragonSpirit c8aba822bf remove coloring when item grabbed 2026-04-23 17:20:14 +03:00
DragonSpirit 23177b9079 increase hud text 2026-04-23 17:18:07 +03:00
Georgiy Gorin 86b837dded Боты добавил 2026-04-23 17:16:41 +03:00
DragonSpirit a835ae5755 fix tutorial images 2026-04-23 17:14:15 +03:00
DragonSpirit d20360c8f3 apply boot material 2026-04-23 17:11:45 +03:00
DragonSpirit fb3b653604 fix boot animation 2026-04-23 17:08:14 +03:00
Nikolay Fedorov 6b7294dfd8 add boot animation 2026-04-23 17:06:10 +03:00
Nikolay Fedorov 82af31501d add boots 2026-04-23 16:52:12 +03:00
Georgiy Gorin 0d9890c370 Баланс + картинки 3 босс, конец игры 2026-04-23 16:51:43 +03:00
Nikolay Fedorov d36a2cf9ec fix props 2026-04-23 16:28:34 +03:00
Georgiy Gorin e185d2e1fd Merge branch 'exp' of https://git.nfedorov.dev/DragonSpirit/KickSurvivors into exp 2026-04-23 16:27:03 +03:00
DragonSpirit 7d6d96e499 shield on spacebar 2026-04-23 16:18:35 +03:00
DragonSpirit 3c2afefc95 spawn settings 2026-04-23 16:17:40 +03:00
Georgiy Gorin 34a9b6b18f Нью баланс 2026-04-23 16:11:34 +03:00
DragonSpirit 9acbc49084 difficulity 2026-04-23 16:05:25 +03:00
Nikolay Fedorov 3542c328c0 fix export shield tutor 2026-04-23 15:59:14 +03:00
DragonSpirit f37c27887e upgrade mesh merge 2026-04-23 15:52:36 +03:00
DragonSpirit 20eaa513c3 fix stick and rock spawn 2026-04-23 15:42:14 +03:00
DragonSpirit 3974d7416d boss phase 2026-04-23 15:38:45 +03:00
Nikolay Fedorov 5d843f94f7 change kick to lmb 2026-04-23 15:36:17 +03:00
Nikolay Fedorov 8e7ff9ae83 rollback huge hit 2026-04-23 15:28:18 +03:00
Nikolay Fedorov d5194139e8 fix player movement on tutorial show 2026-04-23 15:17:39 +03:00
Nikolay Fedorov 7b355c5d0b Merge branch 'exp' of https://git.nfedorov.dev/DragonSpirit/KickSurvivors into exp 2026-04-23 14:59:23 +03:00
DragonSpirit af15c477b9 add hit and merge vfx 2026-04-23 14:59:14 +03:00
DragonSpirit dce433e068 add hit and merge vfx 2026-04-23 14:57:14 +03:00
DragonSpirit 5d9b0ce738 add kickable tooltips 2026-04-23 14:44:21 +03:00
DragonSpirit 5f61c26563 ui items slots 2026-04-23 14:40:55 +03:00
DragonSpirit 65ba9d2960 fix tutorial 2026-04-23 14:35:59 +03:00
Georgiy Gorin f6f451cffb Жоска наговнякал полный сетап моба 2026-04-23 14:25:58 +03:00
DragonSpirit 271c99ae13 tutorial 2026-04-23 13:55:06 +03:00
DragonSpirit dde4a6431e add tooltip on enemies, update enemy type on merge 2026-04-23 13:47:31 +03:00
Georgiy Gorin d7368e7fa7 Balance update 2026-04-23 13:09:23 +03:00
DragonSpirit 9981ed1ae3 fix metal plate pickup 2026-04-23 13:08:44 +03:00
DragonSpirit e956c4353c fix near enemy kick, fix huge kick on low tier 2026-04-23 11:48:00 +03:00
DragonSpirit 1b3732ea0f do not throw stick into player 2026-04-23 11:43:33 +03:00
DragonSpirit 52d0b00655 fix enemy aligning, add sticks respawn 2026-04-23 11:42:17 +03:00
DragonSpirit c9489321ae add shields and tiers on ui 2026-04-23 11:36:01 +03:00
DragonSpirit bec9389bb8 add animations 2026-04-23 11:23:43 +03:00
Nikolay Fedorov c7f0d9e176 update player scene 2026-04-23 11:00:08 +03:00
Georgiy Gorin 7beb9ffbac Exp updated collisions and tougness tier 2026-04-23 10:10:40 +03:00
DragonSpirit cdb0ffd6a5 exp 2026-04-23 00:51:28 +03:00
106 changed files with 101684 additions and 12770 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ccbdsbteef3cs"
path="res://.godot/imported/LoseGame.jpeg-bea62e54d6bb932d2fc0c97398854ad4.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/LoseGame.jpeg"
dest_files=["res://.godot/imported/LoseGame.jpeg-bea62e54d6bb932d2fc0c97398854ad4.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c335dn481ctxu"
path="res://.godot/imported/ThirdLevelEnemy.jpeg-283cc2c1ead2d9769e11fd7206d21703.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/ThirdLevelEnemy.jpeg"
dest_files=["res://.godot/imported/ThirdLevelEnemy.jpeg-283cc2c1ead2d9769e11fd7206d21703.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dcwymnn6xf05c"
path="res://.godot/imported/Tutorial_LeatherArmor.jpeg-da671d8566606a993a070058c18b5a5b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/Tutorial_LeatherArmor.jpeg"
dest_files=["res://.godot/imported/Tutorial_LeatherArmor.jpeg-da671d8566606a993a070058c18b5a5b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://tg6gtoufojyb"
path="res://.godot/imported/Tutorial_LeatherBoots.jpeg-83a29df86efb4f59432b80ca2f2fd7eb.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/Tutorial_LeatherBoots.jpeg"
dest_files=["res://.godot/imported/Tutorial_LeatherBoots.jpeg-83a29df86efb4f59432b80ca2f2fd7eb.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://q86mtqd0if14"
path="res://.godot/imported/Tutorial_StartGame.jpeg-8531e3fdc81134418a0a0e59efc0b95d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/Tutorial_StartGame.jpeg"
dest_files=["res://.godot/imported/Tutorial_StartGame.jpeg-8531e3fdc81134418a0a0e59efc0b95d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://baeea1yfs0cnn"
path="res://.godot/imported/Tutorial_Shield.jpeg-6b96e6b9716aced42153397e827ce868.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/Tutorial_Shield.jpeg"
dest_files=["res://.godot/imported/Tutorial_Shield.jpeg-6b96e6b9716aced42153397e827ce868.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cqo3yiuu4kwdk"
path="res://.godot/imported/VictoryScreen.jpeg-36aa76d727e7a226d71b97af302cccc0.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/VictoryScreen.jpeg"
dest_files=["res://.godot/imported/VictoryScreen.jpeg-36aa76d727e7a226d71b97af302cccc0.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
+20857
View File
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://caurrbclp30ly"
path="res://.godot/imported/armor.obj-af01c4b492188328bde6fd5b9ed2eed0.mesh"
[deps]
files=["res://.godot/imported/armor.obj-af01c4b492188328bde6fd5b9ed2eed0.mesh"]
source_file="res://assets/armor.obj"
dest_files=["res://.godot/imported/armor.obj-af01c4b492188328bde6fd5b9ed2eed0.mesh", "res://.godot/imported/armor.obj-af01c4b492188328bde6fd5b9ed2eed0.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://w5fnj0g3j6ms"
path="res://.godot/imported/armor.png-7969b140c50e154aedeaeb60a071ac9b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/armor.png"
dest_files=["res://.godot/imported/armor.png-7969b140c50e154aedeaeb60a071ac9b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
BIN
View File
Binary file not shown.
+42
View File
@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://cniw0ypfvjw61"
path="res://.godot/imported/boot.glb-d1c29f9ff7f48815266f56a7be3dd896.scn"
[deps]
source_file="res://assets/boot.glb"
dest_files=["res://.godot/imported/boot.glb-d1c29f9ff7f48815266f56a7be3dd896.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
+18661
View File
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://jls6i8ov73ld"
path="res://.godot/imported/boot.obj-e334fc0955e7dcb45c6e02ac806a59e8.mesh"
[deps]
files=["res://.godot/imported/boot.obj-e334fc0955e7dcb45c6e02ac806a59e8.mesh"]
source_file="res://assets/boot.obj"
dest_files=["res://.godot/imported/boot.obj-e334fc0955e7dcb45c6e02ac806a59e8.mesh", "res://.godot/imported/boot.obj-e334fc0955e7dcb45c6e02ac806a59e8.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

+41
View File
@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b85nk7r6dkenp"
path.s3tc="res://.godot/imported/boot1.png-351fe0276d90e80dc572c41c781fc909.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/boot1.png"
dest_files=["res://.godot/imported/boot1.png-351fe0276d90e80dc572c41c781fc909.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

+41
View File
@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ce4g8nblils0e"
path.s3tc="res://.godot/imported/boot2.png-a3406216bcaf3ad03e199064a129c36e.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/boot2.png"
dest_files=["res://.godot/imported/boot2.png-a3406216bcaf3ad03e199064a129c36e.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

+41
View File
@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bqpntq4rf2q7s"
path.s3tc="res://.godot/imported/boot3.png-d7aa5373b9b2c6ad231646d4daea89b4.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/boot3.png"
dest_files=["res://.godot/imported/boot3.png-d7aa5373b9b2c6ad231646d4daea89b4.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
BIN
View File
Binary file not shown.
+42
View File
@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://bpmi0k5uuwef4"
path="res://.godot/imported/gnome1.glb-48274b613f374ee33041724d50181ae2.scn"
[deps]
source_file="res://assets/gnome1.glb"
dest_files=["res://.godot/imported/gnome1.glb-48274b613f374ee33041724d50181ae2.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
+16982
View File
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://bwoh5cyhk1tvx"
path="res://.godot/imported/gnome1.obj-3c2c126ceccc265716f51fdf5f468dcf.mesh"
[deps]
files=["res://.godot/imported/gnome1.obj-3c2c126ceccc265716f51fdf5f468dcf.mesh"]
source_file="res://assets/gnome1.obj"
dest_files=["res://.godot/imported/gnome1.obj-3c2c126ceccc265716f51fdf5f468dcf.mesh", "res://.godot/imported/gnome1.obj-3c2c126ceccc265716f51fdf5f468dcf.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

+41
View File
@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cu3g76pfo5msw"
path.s3tc="res://.godot/imported/gnome1.png-2233fedc9a63fc34690b63fb81a732de.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/gnome1.png"
dest_files=["res://.godot/imported/gnome1.png-2233fedc9a63fc34690b63fb81a732de.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
BIN
View File
Binary file not shown.
+42
View File
@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://cqtr8862yg1pw"
path="res://.godot/imported/gnome2.glb-ed506cf1ac0ccb2d264457e28d22df82.scn"
[deps]
source_file="res://assets/gnome2.glb"
dest_files=["res://.godot/imported/gnome2.glb-ed506cf1ac0ccb2d264457e28d22df82.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
+17161
View File
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://dx4huc0nh1b4u"
path="res://.godot/imported/gnome2.obj-fd55585fee29d1908e34d48f742f0315.mesh"
[deps]
files=["res://.godot/imported/gnome2.obj-fd55585fee29d1908e34d48f742f0315.mesh"]
source_file="res://assets/gnome2.obj"
dest_files=["res://.godot/imported/gnome2.obj-fd55585fee29d1908e34d48f742f0315.mesh", "res://.godot/imported/gnome2.obj-fd55585fee29d1908e34d48f742f0315.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

+41
View File
@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://5l5wflgoofrd"
path.s3tc="res://.godot/imported/gnome2.png-d8c1a3eb7530d4f2929868991bf60044.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/gnome2.png"
dest_files=["res://.godot/imported/gnome2.png-d8c1a3eb7530d4f2929868991bf60044.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
BIN
View File
Binary file not shown.
+42
View File
@@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://d38xq7m2ov1ig"
path="res://.godot/imported/gnome3.glb-60a565f65ec090ccf38c4f1b4928e113.scn"
[deps]
source_file="res://assets/gnome3.glb"
dest_files=["res://.godot/imported/gnome3.glb-60a565f65ec090ccf38c4f1b4928e113.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
+16839
View File
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://dkxr5amwv7i0p"
path="res://.godot/imported/gnome3.obj-ff8c62c7c2be5bf0c9d9db251dfcc714.mesh"
[deps]
files=["res://.godot/imported/gnome3.obj-ff8c62c7c2be5bf0c9d9db251dfcc714.mesh"]
source_file="res://assets/gnome3.obj"
dest_files=["res://.godot/imported/gnome3.obj-ff8c62c7c2be5bf0c9d9db251dfcc714.mesh", "res://.godot/imported/gnome3.obj-ff8c62c7c2be5bf0c9d9db251dfcc714.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

+41
View File
@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://baqjuo2utnor2"
path.s3tc="res://.godot/imported/gnome3.png-49c96522ff8f4e952cebf9b5596c03d1.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/gnome3.png"
dest_files=["res://.godot/imported/gnome3.png-49c96522ff8f4e952cebf9b5596c03d1.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://dwb4g8t8oeycp"
path="res://.godot/imported/stone_big.obj-27b6517edbc7f72b68da44e569ddc192.mesh"
[deps]
files=["res://.godot/imported/stone_big.obj-27b6517edbc7f72b68da44e569ddc192.mesh"]
source_file="res://assets/meshes/stone_big.obj"
dest_files=["res://.godot/imported/stone_big.obj-27b6517edbc7f72b68da44e569ddc192.mesh", "res://.godot/imported/stone_big.obj-27b6517edbc7f72b68da44e569ddc192.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://c06flbdipxqac"
path="res://.godot/imported/stone_small.obj-9c7a28c51451d957607ab126de71ab59.mesh"
[deps]
files=["res://.godot/imported/stone_small.obj-9c7a28c51451d957607ab126de71ab59.mesh"]
source_file="res://assets/meshes/stone_small.obj"
dest_files=["res://.godot/imported/stone_small.obj-9c7a28c51451d957607ab126de71ab59.mesh", "res://.godot/imported/stone_small.obj-9c7a28c51451d957607ab126de71ab59.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false
+206
View File
@@ -0,0 +1,206 @@
# Blender 4.2.9 LTS
# www.blender.org
o metal_item
v -0.000455 0.025430 0.375746
v -0.019059 0.025407 0.394395
v -0.011318 0.009290 0.383589
v -0.075059 0.208979 0.300395
v -0.099042 0.225119 0.294986
v -0.093682 0.209002 0.319026
v -0.361011 0.009290 0.383589
v -0.353269 0.025407 0.394395
v -0.371873 0.025430 0.375746
v -0.297269 0.208979 0.300395
v -0.278646 0.209002 0.319026
v -0.273286 0.225119 0.294986
v -0.000455 0.025430 -0.378701
v -0.011318 0.009290 -0.386544
v -0.019059 0.025407 -0.397351
v -0.075059 0.208979 -0.303350
v -0.093682 0.209002 -0.321981
v -0.099042 0.225119 -0.297942
v -0.361011 0.009290 -0.386544
v -0.371873 0.025430 -0.378701
v -0.353269 0.025407 -0.397350
v -0.297269 0.208979 -0.303350
v -0.273286 0.225119 -0.297942
v -0.278646 0.209002 -0.321981
v 0.374544 0.025430 0.375746
v 0.355940 0.025407 0.394395
v 0.363682 0.009290 0.383589
v 0.299940 0.208979 0.300395
v 0.275957 0.225119 0.294986
v 0.281317 0.209002 0.319026
v 0.013989 0.009290 0.383589
v 0.021730 0.025407 0.394395
v 0.003126 0.025430 0.375746
v 0.077730 0.208979 0.300395
v 0.096353 0.209002 0.319026
v 0.101713 0.225119 0.294986
v 0.374544 0.025430 -0.378701
v 0.363682 0.009290 -0.386544
v 0.355940 0.025407 -0.397351
v 0.299940 0.208979 -0.303350
v 0.281317 0.209002 -0.321981
v 0.275957 0.225119 -0.297942
v 0.013989 0.009290 -0.386544
v 0.003126 0.025430 -0.378701
v 0.021730 0.025407 -0.397350
v 0.077730 0.208979 -0.303350
v 0.101713 0.225119 -0.297942
v 0.096353 0.209002 -0.321981
v 0.182543 0.234038 0.301050
v 0.163938 0.234015 0.316007
v 0.171680 0.217897 0.307340
v 0.107939 0.417586 0.240620
v 0.083956 0.433727 0.236282
v 0.089316 0.417609 0.255561
v -0.178013 0.217897 0.307340
v -0.170271 0.234015 0.316007
v -0.188875 0.234038 0.301050
v -0.114271 0.417586 0.240620
v -0.095648 0.417609 0.255561
v -0.090288 0.433727 0.236282
v 0.182543 0.234038 -0.304005
v 0.171680 0.217897 -0.310296
v 0.163938 0.234015 -0.318962
v 0.107939 0.417586 -0.243575
v 0.089316 0.417609 -0.258517
v 0.083956 0.433727 -0.239238
v -0.178013 0.217897 -0.310296
v -0.188875 0.234038 -0.304005
v -0.170271 0.234015 -0.318962
v -0.114271 0.417586 -0.243575
v -0.090288 0.433727 -0.239238
v -0.095648 0.417609 -0.258517
vn -0.0000 -1.0000 -0.0001
vn 0.0001 -1.0000 -0.0000
vn -0.0000 -1.0000 0.0001
vn -0.0001 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vn -0.0000 1.0000 0.0001
vn -0.0000 1.0000 -0.0001
vn -0.0000 0.3798 -0.9251
vn -0.0000 0.3797 -0.9251
vn -0.0000 0.3798 0.9251
vn -0.0000 0.3797 0.9251
vn -0.9264 0.3766 -0.0000
vn -0.9264 0.3765 -0.0000
vn 0.9390 0.0074 0.3439
vn 0.7239 0.6390 0.2600
vn 0.9390 0.0074 -0.3439
vn 0.7239 0.6390 -0.2600
vn -0.9390 0.0074 0.3439
vn -0.7239 0.6390 0.2600
vn -0.7239 0.6390 -0.2600
vn -0.9390 0.0074 -0.3439
vn 0.9264 0.3766 -0.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 0.3127 -0.9499
vn -0.0000 0.3128 -0.9498
vn -0.0000 0.3127 0.9499
vn -0.0000 0.3128 0.9498
vn -0.9264 0.3765 0.0001
vn -0.9264 0.3766 -0.0001
vn 0.9264 0.3765 -0.0000
vt 0.734770 0.428017
vt 0.734335 0.435070
vt 0.734335 0.435070
vt 0.726011 0.434850
vt 0.726420 0.428380
vt 0.726420 0.428380
vt 0.726011 0.434850
vt 0.733716 0.435018
vt 0.726630 0.434915
vt 0.727047 0.428304
vt 0.734145 0.428079
vt 0.733716 0.435018
vt 0.734144 0.428079
vt 0.726630 0.434915
vt 0.733690 0.435427
vt 0.726594 0.435491
vt 0.726594 0.435491
vt 0.733690 0.435427
vt 0.734169 0.427670
vt 0.727084 0.427728
vt 0.734169 0.427670
vt 0.727084 0.427728
s 1
f 3/1/1 7/2/2 19/3/3 14/1/4
f 12/4/5 5/5/6 18/6/5 23/7/7
f 21/8/8 24/9/8 17/10/9 15/11/8
f 8/12/10 2/13/10 6/10/10 11/14/11
f 9/15/12 10/16/13 22/17/13 20/18/12
f 1/19/14 2/13/10 3/1/1
f 4/20/15 5/5/6 6/10/10
f 7/2/2 8/12/10 9/15/12
f 10/16/13 11/14/11 12/4/5
f 13/21/16 14/1/4 15/11/8
f 16/22/17 17/10/9 18/6/5
f 19/3/3 20/18/12 21/8/8
f 22/17/13 23/7/7 24/9/8
f 1/19/14 4/20/15 6/10/10 2/13/10
f 7/2/2 3/1/1 2/13/10 8/12/10
f 10/16/13 9/15/12 8/12/10 11/14/11
f 11/14/11 6/10/10 5/5/6 12/4/5
f 15/11/8 17/10/9 16/22/17 13/21/16
f 21/8/8 15/11/8 14/1/4 19/3/3
f 24/9/8 21/8/8 20/18/12 22/17/13
f 23/7/7 18/6/5 17/10/9 24/9/8
f 9/15/12 20/18/12 19/3/3 7/2/2
f 13/21/16 1/19/14 3/1/1 14/1/4
f 12/4/5 23/7/7 22/17/13 10/16/13
f 18/6/5 5/5/6 4/20/15 16/22/17
f 4/20/15 1/19/14 13/21/16 16/22/17
f 27/1/1 31/2/2 43/3/3 38/1/4
f 36/4/5 29/5/6 42/6/5 47/7/7
f 45/8/8 48/9/8 41/10/9 39/11/8
f 32/12/10 26/13/10 30/10/10 35/14/11
f 33/15/18 34/16/19 46/17/20 44/18/21
f 25/19/22 26/13/10 27/1/1
f 28/20/22 29/5/6 30/10/10
f 31/2/2 32/12/10 33/15/18
f 34/16/19 35/14/11 36/4/5
f 37/21/22 38/1/4 39/11/8
f 40/22/22 41/10/9 42/6/5
f 43/3/3 44/18/21 45/8/8
f 46/17/20 47/7/7 48/9/8
f 25/19/22 28/20/22 30/10/10 26/13/10
f 31/2/2 27/1/1 26/13/10 32/12/10
f 34/16/19 33/15/18 32/12/10 35/14/11
f 35/14/11 30/10/10 29/5/6 36/4/5
f 39/11/8 41/10/9 40/22/22 37/21/22
f 45/8/8 39/11/8 38/1/4 43/3/3
f 48/9/8 45/8/8 44/18/21 46/17/20
f 47/7/7 42/6/5 41/10/9 48/9/8
f 33/15/18 44/18/21 43/3/3 31/2/2
f 37/21/22 25/19/22 27/1/1 38/1/4
f 36/4/5 47/7/7 46/17/20 34/16/19
f 42/6/5 29/5/6 28/20/22 40/22/22
f 28/20/22 25/19/22 37/21/22 40/22/22
f 51/1/23 55/2/2 67/3/23 62/1/4
f 60/4/5 53/5/6 66/6/5 71/7/7
f 69/8/24 72/9/25 65/10/25 63/11/24
f 56/12/26 50/13/26 54/10/27 59/14/27
f 57/15/13 58/16/28 70/17/12 68/18/29
f 49/19/30 50/13/26 51/1/23
f 52/20/22 53/5/6 54/10/27
f 55/2/2 56/12/26 57/15/13
f 58/16/28 59/14/27 60/4/5
f 61/21/22 62/1/4 63/11/24
f 64/22/22 65/10/25 66/6/5
f 67/3/23 68/18/29 69/8/24
f 70/17/12 71/7/7 72/9/25
f 49/19/30 52/20/22 54/10/27 50/13/26
f 55/2/2 51/1/23 50/13/26 56/12/26
f 58/16/28 57/15/13 56/12/26 59/14/27
f 59/14/27 54/10/27 53/5/6 60/4/5
f 63/11/24 65/10/25 64/22/22 61/21/22
f 69/8/24 63/11/24 62/1/4 67/3/23
f 72/9/25 69/8/24 68/18/29 70/17/12
f 71/7/7 66/6/5 65/10/25 72/9/25
f 57/15/13 68/18/29 67/3/23 55/2/2
f 61/21/22 49/19/30 51/1/23 62/1/4
f 60/4/5 71/7/7 70/17/12 58/16/28
f 66/6/5 53/5/6 52/20/22 64/22/22
f 52/20/22 49/19/30 61/21/22 64/22/22
+25
View File
@@ -0,0 +1,25 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://2r4vjjli71xm"
path="res://.godot/imported/metal_item.obj-a4cb4f3f6e92689b191537ec00614f65.mesh"
[deps]
files=["res://.godot/imported/metal_item.obj-a4cb4f3f6e92689b191537ec00614f65.mesh"]
source_file="res://assets/metal_item.obj"
dest_files=["res://.godot/imported/metal_item.obj-a4cb4f3f6e92689b191537ec00614f65.mesh", "res://.godot/imported/metal_item.obj-a4cb4f3f6e92689b191537ec00614f65.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false
Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

+41
View File
@@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c2k7wyt7ngfgv"
path.s3tc="res://.godot/imported/player_man.png-3e0a4cc36eb1a6978c391c5bc2af439e.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/player_man.png"
dest_files=["res://.godot/imported/player_man.png-3e0a4cc36eb1a6978c391c5bc2af439e.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0
-12548
View File
File diff suppressed because it is too large Load Diff
-25
View File
@@ -1,25 +0,0 @@
[remap]
importer="wavefront_obj"
importer_version=1
type="Mesh"
uid="uid://dnm1mgo7pkojl"
path="res://.godot/imported/temp.obj-bd08f73c102326544e2e3889f01d337d.mesh"
[deps]
files=["res://.godot/imported/temp.obj-bd08f73c102326544e2e3889f01d337d.mesh"]
source_file="res://assets/temp.obj"
dest_files=["res://.godot/imported/temp.obj-bd08f73c102326544e2e3889f01d337d.mesh", "res://.godot/imported/temp.obj-bd08f73c102326544e2e3889f01d337d.mesh"]
[params]
generate_tangents=true
generate_lods=true
generate_shadow_mesh=true
generate_lightmap_uv2=false
generate_lightmap_uv2_texel_size=0.2
scale_mesh=Vector3(1, 1, 1)
offset_mesh=Vector3(0, 0, 0)
force_disable_mesh_compression=false
+71
View File
@@ -0,0 +1,71 @@
[preset.0]
name="Windows Desktop"
platform="Windows Desktop"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter="*jpeg"
exclude_filter=""
export_path="../Kick/KickSurvivors.exe"
patches=PackedStringArray()
patch_delta_encoding=false
patch_delta_compression_level_zstd=19
patch_delta_min_reduction=0.1
patch_delta_include_filters="*"
patch_delta_exclude_filters=""
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.0.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
shader_baker/enabled=false
binary_format/architecture="x86_64"
codesign/enable=false
codesign/timestamp=true
codesign/timestamp_server_url=""
codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=true
application/icon=""
application/console_wrapper_icon=""
application/icon_interpolation=4
application/file_version=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
application/export_angle=0
application/export_d3d12=0
application/d3d12_agility_sdk_multiarch=true
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
Start-ScheduledTask -TaskName godot_remote_debug
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
Remove-Item -Recurse -Force '{temp_dir}'"
+1 -1
View File
@@ -15,6 +15,6 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true
[application]
config/name="KickSurvivors"
run/main_scene="res://scenes/Main.tscn"
run/main_scene="res://scenes/MainMenu.tscn"
config/features=PackedStringArray("4.6", "Forward Plus")
config/icon="res://icon.svg"
+12 -15
View File
@@ -1,29 +1,26 @@
[gd_scene format=3 uid="uid://cayybawvw26cm"]
[ext_resource type="Script" path="res://scripts/EnchantedSphere.gd" id="1_sphere"]
[sub_resource type="SphereMesh" id="SphereMesh_1"]
radius = 0.28
height = 0.56
[ext_resource type="Script" uid="uid://c4d11cs4fcqib" path="res://scripts/EnchantedSphere.gd" id="1_sphere"]
[ext_resource type="Texture2D" uid="uid://bqpntq4rf2q7s" path="res://assets/boot3.png" id="2_gp14g"]
[ext_resource type="ArrayMesh" uid="uid://jls6i8ov73ld" path="res://assets/boot.obj" id="3_d6vog"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.8, 0.3, 1.0, 1)
albedo_texture = ExtResource("2_gp14g")
emission_enabled = true
emission = Color(0.6, 0.1, 1.0, 1)
emission = Color(0.6, 0.1, 1, 1)
emission_energy_multiplier = 3.0
[node name="EnchantedSphere" type="Node3D"]
[node name="EnchantedSphere" type="Node3D" unique_id=879211768]
script = ExtResource("1_sphere")
[node name="SphereMesh" type="MeshInstance3D" parent="."]
mesh = SubResource("SphereMesh_1")
[node name="SphereMesh" type="MeshInstance3D" parent="." unique_id=905498826]
material_override = SubResource("StandardMaterial3D_1")
mesh = ExtResource("3_d6vog")
[node name="Tooltip" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0)
[node name="Tooltip" type="Label3D" parent="." unique_id=947504755]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3280884, 0)
billboard = 1
double_sided = true
text = "[E] Enchanted Sphere
text = "[E] Enchanted Boots
+1 Tier"
font_size = 32
font_size = 56
outline_size = 6
+109 -8
View File
File diff suppressed because one or more lines are too long
+5 -7
View File
@@ -1,6 +1,7 @@
[gd_scene format=3 uid="uid://g7iron5etp8u"]
[ext_resource type="Script" uid="uid://0wdmbocpe2ir" path="res://scripts/Iron.gd" id="1_iron"]
[ext_resource type="ArrayMesh" uid="uid://2r4vjjli71xm" path="res://assets/metal_item.obj" id="2_53umh"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.55, 0.58, 0.62, 1)
@@ -8,20 +9,17 @@ metallic = 0.7
metallic_specular = 0.8
roughness = 0.4
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.38, 0.22, 0.5)
[sub_resource type="BoxShape3D" id="BoxShape3D_1"]
size = Vector3(0.38, 0.22, 0.5)
size = Vector3(1.3992603, 0.58835024, 0.49035645)
[node name="Iron" type="CharacterBody3D" unique_id=611454609]
script = ExtResource("1_iron")
[node name="IronMesh" type="MeshInstance3D" parent="." unique_id=1832879739]
transform = Transform3D(3.5611715, 0, 0, 0, 2.7614622, 0, 0, 0, 1, 0, 0.2, 0)
transform = Transform3D(1.8825685, 0, 0, 0, 1.0460571, 0, 0, 0, 0.64741147, 0, -0.0042432398, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = SubResource("BoxMesh_1")
mesh = ExtResource("2_53umh")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=665808333]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.2, 0)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00068727136, 0.22091705, -0.0048217773)
shape = SubResource("BoxShape3D_1")
+26
View File
@@ -0,0 +1,26 @@
[gd_scene format=3 uid="uid://1uwmdnvgyaii"]
[ext_resource type="Script" path="res://scripts/IronShield.gd" id="1_ishield"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.55, 0.58, 0.62, 1)
roughness = 0.4
metallic = 0.7
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.55, 0.7, 0.1)
[node name="IronShield" type="Node3D"]
script = ExtResource("1_ishield")
[node name="ShieldMesh" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.35, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = SubResource("BoxMesh_1")
[node name="Tooltip" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3, 0)
billboard = 1
text = "[E] Iron Shield
Tier 2 | Hold Shift to block"
outline_size = 6
+5 -7
View File
@@ -1,25 +1,23 @@
[gd_scene format=3 uid="uid://d4leath8bvq2r"]
[ext_resource type="Script" uid="uid://dndcs6xc7m08x" path="res://scripts/Leather.gd" id="1_leather"]
[ext_resource type="ArrayMesh" uid="uid://cjrhycju6l7v6" path="res://assets/leather.obj" id="2_b7gx8"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.62, 0.38, 0.2, 1)
roughness = 0.85
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.5, 0.06, 0.35)
[sub_resource type="BoxShape3D" id="BoxShape3D_1"]
size = Vector3(0.5, 0.06, 0.35)
size = Vector3(0.7527008, 0.108486325, 0.6336487)
[node name="Leather" type="CharacterBody3D" unique_id=267529517]
script = ExtResource("1_leather")
[node name="LeatherMesh" type="MeshInstance3D" parent="." unique_id=2045837180]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0)
transform = Transform3D(1.5, 0, 0, 0, 1.812, 0, 0, 0, 1.784, 0, 0.12694196, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = SubResource("BoxMesh_1")
mesh = ExtResource("2_b7gx8")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1940111930]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00071039796, 0.12997423, 0.0029245168)
shape = SubResource("BoxShape3D_1")
+24
View File
@@ -0,0 +1,24 @@
[gd_scene format=3 uid="uid://bidrinpjiyb2x"]
[ext_resource type="Script" uid="uid://b80k2b1icwlbm" path="res://scripts/LeatherArmor.gd" id="1_leatha"]
[ext_resource type="ArrayMesh" uid="uid://caurrbclp30ly" path="res://assets/armor.obj" id="2_dji1h"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.55, 0.32, 0.14, 1)
roughness = 0.8
[node name="LeatherArmor" type="Node3D" unique_id=1218398814]
script = ExtResource("1_leatha")
[node name="ArmorMesh" type="MeshInstance3D" parent="." unique_id=1757935253]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.3858314, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = ExtResource("2_dji1h")
[node name="Tooltip" type="Label3D" parent="." unique_id=1322485403]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.7649657, 0)
billboard = 1
text = "[E] Leather Armor
+1 Toughness"
font_size = 56
outline_size = 6
+10 -12
View File
@@ -1,27 +1,25 @@
[gd_scene format=3 uid="uid://cbvs3rvwslsd2"]
[ext_resource type="Script" path="res://scripts/LeatherBoots.gd" id="1_boots"]
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.4, 0.2, 0.55)
[ext_resource type="Script" uid="uid://d0j8nw7eynmk8" path="res://scripts/LeatherBoots.gd" id="1_boots"]
[ext_resource type="Texture2D" uid="uid://b85nk7r6dkenp" path="res://assets/boot1.png" id="2_ky34n"]
[ext_resource type="ArrayMesh" uid="uid://jls6i8ov73ld" path="res://assets/boot.obj" id="3_7iwdw"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.45, 0.25, 0.10, 1)
roughness = 0.8
albedo_color = Color(0.45, 0.25, 0.1, 1)
albedo_texture = ExtResource("2_ky34n")
metallic = 0.1
roughness = 0.8
[node name="LeatherBoots" type="Node3D"]
[node name="LeatherBoots" type="Node3D" unique_id=2009442467]
script = ExtResource("1_boots")
[node name="BootsMesh" type="MeshInstance3D" parent="."]
mesh = SubResource("BoxMesh_1")
[node name="BootsMesh" type="MeshInstance3D" parent="." unique_id=1801555312]
material_override = SubResource("StandardMaterial3D_1")
mesh = ExtResource("3_7iwdw")
[node name="Tooltip" type="Label3D" parent="."]
[node name="Tooltip" type="Label3D" parent="." unique_id=1833908896]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8, 0)
billboard = 1
double_sided = true
text = "[E] Leather Boots
+10 Move Speed"
font_size = 32
outline_size = 6
+13 -13
View File
@@ -78,21 +78,21 @@ size = Vector3(0.6, 1, 0.6)
[sub_resource type="BoxShape3D" id="BoxShape3D_forge"]
size = Vector3(2, 1.8, 2)
[sub_resource type="BoxMesh" id="BoxMesh_etable"]
size = Vector3(1.4, 0.9, 1.4)
[sub_resource type="BoxMesh" id="BoxMesh_ebook"]
size = Vector3(0.7, 0.12, 0.5)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_etable"]
albedo_color = Color(0.12, 0.08, 0.22, 1)
roughness = 0.6
metallic = 0.2
roughness = 0.6
[sub_resource type="BoxMesh" id="BoxMesh_etable"]
size = Vector3(1.4, 0.9, 1.4)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ebook"]
albedo_color = Color(0.55, 0.08, 0.08, 1)
roughness = 0.9
[sub_resource type="BoxMesh" id="BoxMesh_ebook"]
size = Vector3(0.7, 0.12, 0.5)
[sub_resource type="BoxShape3D" id="BoxShape3D_etable"]
size = Vector3(1.4, 0.9, 1.4)
@@ -261,18 +261,18 @@ mesh = SubResource("BoxMesh_chimney")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Forge" unique_id=726531191]
shape = SubResource("BoxShape3D_forge")
[node name="EnchantingTable" type="StaticBody3D" parent="."]
[node name="EnchantingTable" type="StaticBody3D" parent="." unique_id=242813005]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8, 0.45, -8)
metadata/is_enchanting_table = true
[node name="TableMesh" type="MeshInstance3D" parent="EnchantingTable"]
mesh = SubResource("BoxMesh_etable")
[node name="TableMesh" type="MeshInstance3D" parent="EnchantingTable" unique_id=1719378953]
material_override = SubResource("StandardMaterial3D_etable")
mesh = SubResource("BoxMesh_etable")
[node name="BookMesh" type="MeshInstance3D" parent="EnchantingTable"]
[node name="BookMesh" type="MeshInstance3D" parent="EnchantingTable" unique_id=444214832]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.51, 0)
mesh = SubResource("BoxMesh_ebook")
material_override = SubResource("StandardMaterial3D_ebook")
mesh = SubResource("BoxMesh_ebook")
[node name="CollisionShape3D" type="CollisionShape3D" parent="EnchantingTable"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="EnchantingTable" unique_id=352273224]
shape = SubResource("BoxShape3D_etable")
+8
View File
@@ -0,0 +1,8 @@
[gd_scene format=3 uid="uid://mainmenu2024"]
[ext_resource type="Script" path="res://scripts/MainMenu.gd" id="1_menu"]
[node name="MainMenu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource("1_menu")
+13 -13
View File
@@ -1,28 +1,28 @@
[gd_scene format=3 uid="uid://h8armor4fura"]
[ext_resource type="Script" path="res://scripts/MetalArmor.gd" id="1_armor"]
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.55, 0.7, 0.25)
[ext_resource type="Script" uid="uid://cqp1ucyvnno7i" path="res://scripts/MetalArmor.gd" id="1_armor"]
[ext_resource type="Texture2D" uid="uid://ce4g8nblils0e" path="res://assets/boot2.png" id="2_ocond"]
[ext_resource type="ArrayMesh" uid="uid://caurrbclp30ly" path="res://assets/armor.obj" id="3_ocond"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.55, 0.60, 0.68, 1)
roughness = 0.3
albedo_color = Color(0.55, 0.6, 0.68, 1)
albedo_texture = ExtResource("2_ocond")
metallic = 0.85
metallic_specular = 1.0
roughness = 0.3
[node name="MetalArmor" type="Node3D"]
[node name="MetalArmor" type="Node3D" unique_id=1379243712]
script = ExtResource("1_armor")
[node name="ArmorMesh" type="MeshInstance3D" parent="."]
mesh = SubResource("BoxMesh_1")
[node name="ArmorMesh" type="MeshInstance3D" parent="." unique_id=1340618559]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.3499111, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = ExtResource("3_ocond")
[node name="Tooltip" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, 0)
[node name="Tooltip" type="Label3D" parent="." unique_id=748491675]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.9431921, 0)
billboard = 1
double_sided = true
text = "[E] Metal Armor
+1 Tier"
font_size = 32
font_size = 56
outline_size = 6
+35
View File
@@ -0,0 +1,35 @@
[gd_scene format=3 uid="uid://dbvt3pkrej5nq"]
[ext_resource type="Script" uid="uid://sfq4iq0btm0g" path="res://scripts/MetalPlate.gd" id="1_plate"]
[ext_resource type="Texture2D" uid="uid://ce4g8nblils0e" path="res://assets/boot2.png" id="2_quvug"]
[ext_resource type="ArrayMesh" uid="uid://jls6i8ov73ld" path="res://assets/boot.obj" id="3_2i44a"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.6, 0.65, 0.72, 1)
albedo_texture = ExtResource("2_quvug")
metallic = 0.8
metallic_specular = 0.9
roughness = 0.35
[sub_resource type="BoxShape3D" id="BoxShape3D_1"]
size = Vector3(1.0203736, 0.124472655, 1.4775146)
[node name="MetalPlate" type="CharacterBody3D" unique_id=1872011585]
script = ExtResource("1_plate")
[node name="PlateMesh" type="MeshInstance3D" parent="." unique_id=436086498]
transform = Transform3D(1.8395851, 0, 0, 0, 1.5228686, 0, 0, 0, 2.050398, 0, 0.16620824, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = ExtResource("3_2i44a")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1642999883]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.005560264, 0.16739155, 0.003918484)
shape = SubResource("BoxShape3D_1")
[node name="Tooltip" type="Label3D" parent="." unique_id=59052869]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.425037, 0)
billboard = 1
text = "[E] Armored Boots
+1 Kick Tier"
font_size = 56
outline_size = 6
+27
View File
@@ -0,0 +1,27 @@
[gd_scene format=3 uid="uid://cjhyinmjh0c3y"]
[ext_resource type="Script" uid="uid://sklquy2lyugo" path="res://scripts/PlateArmor.gd" id="1_platea"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.58, 0.62, 0.7, 1)
metallic = 0.85
metallic_specular = 1.0
roughness = 0.3
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.58, 0.72, 0.24)
[node name="PlateArmor" type="Node3D" unique_id=1607276475]
script = ExtResource("1_platea")
[node name="ArmorMesh" type="MeshInstance3D" parent="." unique_id=65147838]
transform = Transform3D(2.0554285, 0, 0, 0, 2.3875203, 0, 0, 0, 4.207259, 0, 0.7950885, -0.16405308)
material_override = SubResource("StandardMaterial3D_1")
mesh = SubResource("BoxMesh_1")
[node name="Tooltip" type="Label3D" parent="." unique_id=2013488670]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.9503746, 0)
billboard = 1
text = "[E] Plate Armor
+1 Toughness"
outline_size = 6
+137 -12
View File
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -8,16 +8,16 @@ albedo_color = Color(0.45, 0.38, 0.3, 1)
metallic = 0.05
[sub_resource type="SphereShape3D" id="SphereShape3D_1"]
radius = 0.25
radius = 0.40034008
[node name="Rock" type="CharacterBody3D" unique_id=1267213194]
script = ExtResource("1_rock")
[node name="RockMesh" type="MeshInstance3D" parent="." unique_id=918783711]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, 0)
transform = Transform3D(1.6, 0, 0, 0, 1.6, 0, 0, 0, 1.6, 0, 0.25, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = ExtResource("2_wmx41")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=2017780451]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, 0)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.033173382, 0.43890864, 0)
shape = SubResource("SphereShape3D_1")
+4 -4
View File
@@ -8,17 +8,17 @@ albedo_color = Color(0.55, 0.38, 0.18, 1)
roughness = 0.95
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1"]
radius = 0.07
height = 0.65
radius = 0.15673828
height = 1.6220214
[node name="Stick" type="CharacterBody3D" unique_id=1893805391]
script = ExtResource("1_stick")
[node name="StickMesh" type="MeshInstance3D" parent="." unique_id=1850002866]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.32, 0)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.16618532, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = ExtResource("2_urm7b")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=653008437]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.32, 0)
transform = Transform3D(1, 0, 0, 0, 0.025374386, 0.999678, 0, -0.999678, 0.025374386, 0.005088806, 0.15728158, 0.109485604)
shape = SubResource("CapsuleShape3D_1")
+25
View File
@@ -0,0 +1,25 @@
[gd_scene format=3 uid="uid://hk7p5sjjxa1w"]
[ext_resource type="Script" uid="uid://cmvl3td1h7qb8" path="res://scripts/StickArmor.gd" id="1_sticka"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.48, 0.32, 0.14, 1)
roughness = 0.9
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.45, 0.55, 0.2)
[node name="StickArmor" type="Node3D" unique_id=1550651822]
script = ExtResource("1_sticka")
[node name="ArmorMesh" type="MeshInstance3D" parent="." unique_id=564243580]
transform = Transform3D(3.1221292, 0, 0, 0, 2.4342613, 0, 0, 0, 1, 0, 0.38186997, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = SubResource("BoxMesh_1")
[node name="Tooltip" type="Label3D" parent="." unique_id=243955258]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.072116256, 1.3135526, 0)
billboard = 1
text = "[E] Stick Armor
+1 Toughness"
outline_size = 6
+25
View File
@@ -0,0 +1,25 @@
[gd_scene format=3 uid="uid://bayxgoeu4qxqe"]
[ext_resource type="Script" path="res://scripts/WoodenShield.gd" id="1_wshield"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.55, 0.38, 0.18, 1)
roughness = 0.85
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.5, 0.65, 0.12)
[node name="WoodenShield" type="Node3D"]
script = ExtResource("1_wshield")
[node name="ShieldMesh" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.35, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = SubResource("BoxMesh_1")
[node name="Tooltip" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3, 0)
billboard = 1
text = "[E] Wooden Shield
Tier 1 | Hold Shift to block"
outline_size = 6
+21 -2
View File
@@ -10,7 +10,8 @@ const WALL_BOUNCE := 0.4
const WALL_SELF_DMG := 0.4
var kickable_type: String = "boulder"
var tier: int = 2
var kick_tier: int = 0
var toughness_tier: int = 2
var state: State = State.IDLE
var fly_vel: Vector3 = Vector3.ZERO
var health: float = 150.0
@@ -19,6 +20,7 @@ var damage_modifier: float = 1.8
@onready var mesh_node: MeshInstance3D = $BoulderMesh
var boulder_mat: StandardMaterial3D
var _tooltip: Label3D
const COLOR_IDLE := Color(0.32, 0.28, 0.22)
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
@@ -27,6 +29,23 @@ func _ready() -> void:
add_to_group("kickable")
boulder_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
mesh_node.material_override = boulder_mat
_tooltip = Label3D.new()
_tooltip.text = "Boulder\nRock+Rock\nVery heavy. High damage"
_tooltip.billboard = BaseMaterial3D.BILLBOARD_ENABLED
_tooltip.font_size = 56
_tooltip.outline_size = 6
_tooltip.position = Vector3(0, 1.4, 0)
_tooltip.modulate = Color(1.0, 0.95, 0.8)
_tooltip.visible = false
add_child(_tooltip)
func _process(_delta: float) -> void:
if dead or state != State.IDLE:
_tooltip.visible = false
return
var players := get_tree().get_nodes_in_group("player")
_tooltip.visible = not players.is_empty() and \
(players[0] as Node3D).global_position.distance_to(global_position) < 2.5
func apply_collision_damage(dmg: float) -> void:
_take_damage(dmg)
@@ -64,7 +83,7 @@ func _fly(delta: float) -> void:
handled = true
break
elif col3d.is_in_group("player"):
col3d.call("take_damage", int(speed_now * damage_modifier))
col3d.call("take_damage", int(speed_now * damage_modifier), toughness_tier)
fly_vel *= 0.3
handled = true
break
+104 -23
View File
@@ -16,7 +16,8 @@ static var first_iron_spawned: bool = false
static var first_essence_spawned: bool = false
var kickable_type: String = ""
var tier: int = 1
var kick_tier: int = 1
var toughness_tier: int = 1
var move_speed: float = 3.0
var health: int = 30
var damage_to_player: int = 8
@@ -44,7 +45,11 @@ var merge_partner: Node = null
var is_upgrading: bool = false
@onready var mesh_node: MeshInstance3D = $BodyMesh
#@onready var mesh_node1: MeshInstance3D = $BodyMesh1
#@onready var mesh_node2: MeshInstance3D = $BodyMesh2
var mat: StandardMaterial3D
var type_label: Label3D
var COLOR_CHASE = Color(1.0, 0.28, 0.18)
var COLOR_FLY = Color(1.0, 0.85, 0.1)
@@ -54,10 +59,28 @@ const CONTACT_CD = 0.7
const AIR_FRICTION = 0.86
func _ready() -> void:
process_mode = Node.PROCESS_MODE_PAUSABLE
add_to_group("enemies")
mat = mesh_node.material_override.duplicate() as StandardMaterial3D
mesh_node.material_override = mat
#mesh_node1.set_visible(false)
#mesh_node2.set_visible(false)
COLOR_CHASE = mat.albedo_color
type_label = Label3D.new()
type_label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
type_label.position = Vector3(0, 1.6, 0)
type_label.font_size = 28
type_label.outline_size = 5
type_label.modulate = Color.WHITE
add_child(type_label)
func _update_label() -> void:
if type_label == null:
return
var stars := ""
for i in range(enemy_level - 1):
stars += ""
type_label.text = enemy_type + (" " + stars if stars != "" else "")
func setup(type: String, wave: int) -> void:
enemy_type = type
@@ -66,31 +89,53 @@ func setup(type: String, wave: int) -> void:
match type:
"slime":
move_speed = 2.8 + wave * 0.12
health = 28 + wave * 4
health = 40 + wave * 4
score_value = 10
damage_to_player = 8
enemy_level = 1
"bat":
move_speed = 5.5 + wave * 0.15
health = 14 + wave * 2
score_value = 15
move_speed = 5 + wave * 0.15
health = 100 + wave * 2
score_value = 20
damage_to_player = 6
base_scale = 0.7
mesh_node.scale = Vector3(0.7, 0.7, 0.7)
COLOR_CHASE = Color(0.6, 0.2, 0.8)
mat.albedo_color = COLOR_CHASE
enemy_level = 2
#mesh_node.set_visible(false)
#mesh_node1.set_visible(true)
"ogre":
move_speed = 1.8 + wave * 0.08
health = 80 + wave * 12
score_value = 25
move_speed = 3 + wave * 0.08
health = 200 + wave * 12
score_value = 50
damage_to_player = 18
base_scale = 1.5
mesh_node.scale = Vector3(1.5, 1.5, 1.5)
COLOR_CHASE = Color(0.3, 0.7, 0.3)
mat.albedo_color = COLOR_CHASE
enemy_level = 3
tier = enemy_level
#mesh_node1.set_visible(false)
#mesh_node2.set_visible(true)
kick_tier = enemy_level
toughness_tier = enemy_level
_update_label()
_apply_mesh(enemy_level)
func _apply_mesh(level: int) -> void:
var idx := clampi(level, 1, 3)
var mesh_res := load("res://assets/gnome%d.obj" % idx) as Mesh
if mesh_res == null:
return
var new_mat := StandardMaterial3D.new()
var tex := load("res://assets/gnome%d.png" % idx) as Texture2D
if tex != null:
new_mat.albedo_texture = tex
new_mat.albedo_color = Color.WHITE
mesh_node.mesh = mesh_res
mesh_node.material_override = new_mat
mat = new_mat
COLOR_CHASE = Color.WHITE
func _physics_process(delta: float) -> void:
match state:
@@ -112,13 +157,31 @@ func _chase(delta: float) -> void:
contact_timer = CONTACT_CD
if target.has_method("take_damage"):
target.take_damage(damage_to_player)
FX.hit_spark(target.global_position + Vector3(0, 0.5, 0), get_parent(), Color(0.95, 0.18, 0.08))
#if randf() < 0.3:
var knock_dir := diff.normalized() if dist > 0.01 else -global_transform.basis.z
knock_dir.y = 0.0
target.call("receive_kick", knock_dir, 12.0 + kick_tier * 10.0)
if enemy_kick_timer <= 0.0:
_try_enemy_kick()
var sep := Vector3.ZERO
for e in get_tree().get_nodes_in_group("enemies"):
if e == self:
continue
var en := e as Node3D
if en == null:
continue
var away := global_position - en.global_position
away.y = 0.0
var away_dist := away.length()
if away_dist < 2.2 and away_dist > 0.01:
sep += away.normalized() * (2.2 - away_dist)
if dist > 0.05:
var dir := diff.normalized()
velocity.x = dir.x * move_speed
velocity.z = dir.z * move_speed
rotation.y = lerp_angle(rotation.y, atan2(dir.x, dir.z), 8.0 * delta)
var move_dir := (dir + sep * 0.6).normalized()
velocity.x = move_dir.x * move_speed
velocity.z = move_dir.z * move_speed
rotation.y = lerp_angle(rotation.y, atan2(move_dir.x, move_dir.z), 8.0 * delta)
velocity.y = 0.0
move_and_slide()
@@ -138,25 +201,31 @@ func _try_enemy_kick() -> void:
var k := node as Node3D
if k == null or not is_instance_valid(k):
continue
#if k.get("kickable_type") == "stick":
#continue
var kfv = k.get("fly_vel")
if kfv != null and Vector2((kfv as Vector3).x, (kfv as Vector3).z).length() > 15.0:
continue
var d := (k.global_position - global_position)
d.y = 0.0
if d.length() < nearest_dist:
nearest_dist = d.length()
nearest_kickable = k
if nearest_kickable != null:
nearest_kickable.call("receive_kick", kick_dir, 35.0 + tier * 8.0)
nearest_kickable.call("receive_kick", kick_dir, 35.0 + kick_tier * 8.0)
FX.hit_spark(nearest_kickable.global_position + Vector3(0, 0.4, 0), get_parent(), Color(1.0, 0.72, 0.1))
kickable_kick_timer = KICKABLE_KICK_COOLDOWN
return
# 2. Kick lower-tier enemy nearest to player direction
if tier > 0:
# 2. Kick lower-toughness enemy nearest to player direction
if kick_tier > 0:
var nearest_enemy: Node3D = null
var nearest_enemy_dist := ENEMY_KICK_RANGE
for node in get_tree().get_nodes_in_group("enemies"):
var en := node as Node3D
if en == null or en == self or not is_instance_valid(en):
continue
if (en.get("tier") if en.get("tier") != null else 0) >= tier:
if (en.get("toughness_tier") if en.get("toughness_tier") != null else 0) >= kick_tier:
continue
var d := (en.global_position - global_position)
d.y = 0.0
@@ -164,15 +233,19 @@ func _try_enemy_kick() -> void:
nearest_enemy_dist = d.length()
nearest_enemy = en
if nearest_enemy != null:
nearest_enemy.call("receive_kick", kick_dir, 40.0 + tier * 10.0)
nearest_enemy.call("receive_kick", kick_dir, 40.0 + kick_tier * 10.0)
enemy_kick_timer = ENEMY_KICK_COOLDOWN
return
# 3. Kick player directly if lower tier and in range
if tier > 0 and to_player.length() < ENEMY_KICK_RANGE:
var player_tier: int = target.get("tier") if target.get("tier") != null else 0
if player_tier < tier:
target.call("receive_kick", kick_dir, 35.0 + tier * 8.0)
# 3. Kick player directly if lower toughness and in range
#if kick_tier > 0 and to_player.length() < ENEMY_KICK_RANGE:
if to_player.length() < ENEMY_KICK_RANGE:
var player_toughness: int = target.get("toughness_tier") if target.get("toughness_tier") != null else 0
if player_toughness < kick_tier:
# light kick
# target.call("receive_kick", kick_dir, 12.0 + kick_tier * 10.0)
target.call("receive_kick", kick_dir, 35.0 + kick_tier * 8.0)
FX.hit_spark(target.global_position + Vector3(0, 0.5, 0), get_parent(), Color(0.95, 0.18, 0.08))
enemy_kick_timer = ENEMY_KICK_COOLDOWN
func _fly(delta: float) -> void:
@@ -265,14 +338,22 @@ func _start_merge(other: Node) -> void:
tw.tween_property(other, "global_position", global_position, 0.2)
tw.tween_callback(_on_merge_complete)
static func _next_enemy_type(current: String) -> String:
match current:
"slime": return "bat"
"bat": return "ogre"
_: return "titan"
func _on_merge_complete() -> void:
var merge_pos := global_position
var merge_type := enemy_type
var merge_type := _next_enemy_type(enemy_type)
var new_level: int = enemy_level + 1
var new_wave: int = wave_num
var par := get_parent()
if is_instance_valid(merge_partner):
merge_pos = (global_position + merge_partner.global_position) / 2.0
merge_partner.queue_free()
FX.merge_smoke(merge_pos + Vector3(0, 0.3, 0), par)
queue_free()
emit_signal("merged", true)
var tree := get_tree()
+20 -1
View File
@@ -12,7 +12,8 @@ const WALL_BOUNCE := 0.6
const WALL_SELF_DMG := 0.0
var kickable_type: String = "essence"
var tier: int = 3
var kick_tier: int = 0
var toughness_tier: int = 3
var state: State = State.IDLE
var fly_vel: Vector3 = Vector3.ZERO
var health: float = 999.0
@@ -21,6 +22,7 @@ var damage_modifier: float = 0.0
@onready var mesh_node: MeshInstance3D = $EssenceMesh
var essence_mat: StandardMaterial3D
var _tooltip: Label3D
func _ready() -> void:
add_to_group("kickable")
@@ -29,6 +31,23 @@ func _ready() -> void:
var tw := create_tween().set_loops()
tw.tween_property(self, "position:y", 0.35, 0.6)
tw.tween_property(self, "position:y", 0.15, 0.6)
_tooltip = Label3D.new()
_tooltip.text = "Magic Essence\nKick into\nEnchanting Table → Sphere"
_tooltip.billboard = BaseMaterial3D.BILLBOARD_ENABLED
_tooltip.font_size = 56
_tooltip.outline_size = 6
_tooltip.position = Vector3(0, 1.2, 0)
_tooltip.modulate = Color(0.85, 0.7, 1.0)
_tooltip.visible = false
add_child(_tooltip)
func _process(_delta: float) -> void:
if dead or state != State.IDLE:
_tooltip.visible = false
return
var players := get_tree().get_nodes_in_group("player")
_tooltip.visible = not players.is_empty() and \
(players[0] as Node3D).global_position.distance_to(global_position) < 2.5
func apply_collision_damage(_dmg: float) -> void:
pass
+51
View File
@@ -0,0 +1,51 @@
class_name FX
# Small burst of colored spheres flying outward from impact point.
static func hit_spark(pos: Vector3, parent: Node, color: Color = Color(1.0, 0.72, 0.1)) -> void:
const COUNT := 8
for i in range(COUNT):
var m := MeshInstance3D.new()
var sphere := SphereMesh.new()
sphere.radius = 0.12
sphere.height = 0.24
sphere.radial_segments = 4
sphere.rings = 2
var mat := StandardMaterial3D.new()
mat.albedo_color = color
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
m.material_override = mat
m.mesh = sphere
parent.add_child(m)
m.global_position = pos
var angle := TAU * float(i) / float(COUNT) + randf() * 0.6
var dist := randf_range(0.7, 1.8)
var end := pos + Vector3(cos(angle) * dist, randf_range(0.3, 1.3), sin(angle) * dist)
var tw := m.create_tween().set_parallel(true)
tw.tween_property(m, "global_position", end, 0.28)
tw.tween_property(m, "scale", Vector3(0.05, 0.05, 0.05), 0.28)
tw.tween_method(func(a: float): mat.albedo_color.a = a, 1.0, 0.0, 0.28)
tw.chain().tween_callback(m.queue_free)
# Expanding smoke sphere for merges.
static func merge_smoke(pos: Vector3, parent: Node) -> void:
var m := MeshInstance3D.new()
var sphere := SphereMesh.new()
sphere.radius = 0.4
sphere.height = 0.8
var mat := StandardMaterial3D.new()
mat.albedo_color = Color(0.90, 0.90, 0.90, 0.85)
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
mat.cull_mode = BaseMaterial3D.CULL_DISABLED
m.material_override = mat
m.mesh = sphere
parent.add_child(m)
m.global_position = pos
var tw := m.create_tween().set_parallel(true)
tw.tween_property(m, "scale", Vector3(5.5, 3.5, 5.5), 0.55)
tw.tween_method(func(a: float): mat.albedo_color.a = a, 0.85, 0.0, 0.55)
tw.chain().tween_callback(m.queue_free)
+1
View File
@@ -0,0 +1 @@
uid://dqx8r64rkj7j
+11
View File
@@ -0,0 +1,11 @@
class_name GameSettings
## "immortal" — no damage, tier-based kick force
## "survival" — takes damage, fixed kick force
static var difficulty: String = "immortal"
## enemy spawn interval in seconds
static var enemy_spawn_interval: float = 6.0
## item (rock/stick) respawn delay in seconds
static var item_respawn_delay: float = 10.0
+1
View File
@@ -0,0 +1 @@
uid://deu62njwuhjd3
+24 -5
View File
@@ -1,6 +1,6 @@
extends CharacterBody3D
const METAL_ARMOR_SCENE := preload("res://scenes/MetalArmor.tscn")
const METAL_PLATE_SCENE := preload("res://scenes/MetalPlate.tscn")
signal destroyed
@@ -12,15 +12,17 @@ const WALL_BOUNCE := 0.45
const WALL_SELF_DMG := 0.5
var kickable_type: String = "iron"
var tier: int = 2
var kick_tier: int = 0
var toughness_tier: int = 2
var state: State = State.IDLE
var fly_vel: Vector3 = Vector3.ZERO
var health: float = 80.0
var health: float = 400.0
var dead: bool = false
var damage_modifier: float = 0.9
@onready var mesh_node: MeshInstance3D = $IronMesh
var iron_mat: StandardMaterial3D
var _tooltip: Label3D
const COLOR_IDLE := Color(0.55, 0.58, 0.62)
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
@@ -29,6 +31,23 @@ func _ready() -> void:
add_to_group("kickable")
iron_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
mesh_node.material_override = iron_mat
_tooltip = Label3D.new()
_tooltip.text = "Iron\nHeavy weapon\n+Leather → Iron Shield\nForge → Metal Plate"
_tooltip.billboard = BaseMaterial3D.BILLBOARD_ENABLED
_tooltip.font_size = 56
_tooltip.outline_size = 6
_tooltip.position = Vector3(0, 1.1, 0)
_tooltip.modulate = Color(1.0, 0.95, 0.8)
_tooltip.visible = false
add_child(_tooltip)
func _process(_delta: float) -> void:
if dead or state != State.IDLE:
_tooltip.visible = false
return
var players := get_tree().get_nodes_in_group("player")
_tooltip.visible = not players.is_empty() and \
(players[0] as Node3D).global_position.distance_to(global_position) < 2.5
func apply_collision_damage(dmg: float) -> void:
_take_damage(dmg)
@@ -69,7 +88,7 @@ func _fly(delta: float) -> void:
handled = true
break
elif col3d.is_in_group("player"):
col3d.call("take_damage", int(speed_now * damage_modifier))
col3d.call("take_damage", int(speed_now * damage_modifier), toughness_tier)
fly_vel *= 0.3
handled = true
break
@@ -110,7 +129,7 @@ func _hit_forge(forge: Node3D) -> void:
queue_free()
if parent == null:
return
var armor := METAL_ARMOR_SCENE.instantiate() as Node3D
var armor := METAL_PLATE_SCENE.instantiate() as Node3D
parent.add_child(armor)
armor.global_position = spawn_pos
+26
View File
@@ -0,0 +1,26 @@
extends Node3D
@onready var tooltip: Label3D = $Tooltip
func _ready() -> void:
add_to_group("interactable")
tooltip.visible = false
var tw := create_tween().set_loops()
tw.tween_property(self, "position:y", 0.45, 0.65)
tw.tween_property(self, "position:y", 0.2, 0.65)
func _process(delta: float) -> void:
rotation.y += delta * 1.1
var players := get_tree().get_nodes_in_group("player")
if players.is_empty():
tooltip.visible = false
return
var p := players[0] as Node3D
tooltip.visible = p != null and global_position.distance_to(p.global_position) < 2.5
func interact(player: Node) -> void:
if player.call("apply_iron_shield"):
queue_free()
var mains := get_tree().get_nodes_in_group("main")
if not mains.is_empty():
mains[0].call("show_tutorial", "Tutorial_Shield")
+1
View File
@@ -0,0 +1 @@
uid://bcvyiisb5ugtn
+6
View File
@@ -52,6 +52,11 @@ static func resolve(owner: Node3D, other: Node3D, owner_vel: Vector3) -> bool:
static func _execute_recipe(a: Node3D, b: Node3D, recipe: Dictionary) -> void:
var pos := (a.global_position + b.global_position) * 0.5
var parent := a.get_parent()
# Emit before freeing so respawn counters in Main decrement correctly.
if a.has_signal("destroyed"):
a.emit_signal("destroyed")
if b.has_signal("destroyed"):
b.emit_signal("destroyed")
a.queue_free()
b.queue_free()
var scene: PackedScene = load(recipe["result_scene"])
@@ -60,3 +65,4 @@ static func _execute_recipe(a: Node3D, b: Node3D, recipe: Dictionary) -> void:
var result := scene.instantiate() as Node3D
parent.add_child(result)
result.global_position = pos
FX.merge_smoke(pos + Vector3(0, 0.3, 0), parent)
+20 -1
View File
@@ -7,15 +7,34 @@ const MIN_SPEED := 0.3
const WALL_BOUNCE := 0.7
var kickable_type: String = "leather"
var tier: int = 1
var kick_tier: int = 0
var toughness_tier: int = 1
var state: State = State.IDLE
var fly_vel: Vector3 = Vector3.ZERO
var damage_modifier: float = 0.0
@onready var mesh_node: MeshInstance3D = $LeatherMesh
var _tooltip: Label3D
func _ready() -> void:
add_to_group("kickable")
_tooltip = Label3D.new()
_tooltip.text = "Leather\n+Stick → Boots\n+Rock → Leather Armor\n+Iron → Iron Shield"
_tooltip.billboard = BaseMaterial3D.BILLBOARD_ENABLED
_tooltip.font_size = 56
_tooltip.outline_size = 6
_tooltip.position = Vector3(0, 1.0, 0)
_tooltip.modulate = Color(1.0, 0.95, 0.8)
_tooltip.visible = false
add_child(_tooltip)
func _process(_delta: float) -> void:
if state != State.IDLE:
_tooltip.visible = false
return
var players := get_tree().get_nodes_in_group("player")
_tooltip.visible = not players.is_empty() and \
(players[0] as Node3D).global_position.distance_to(global_position) < 2.5
func apply_collision_damage(_dmg: float) -> void:
pass
+26
View File
@@ -0,0 +1,26 @@
extends Node3D
@onready var tooltip: Label3D = $Tooltip
func _ready() -> void:
add_to_group("interactable")
tooltip.visible = false
var tw := create_tween().set_loops()
tw.tween_property(self, "position:y", 0.45, 0.65)
tw.tween_property(self, "position:y", 0.2, 0.65)
func _process(delta: float) -> void:
rotation.y += delta * 1.1
var players := get_tree().get_nodes_in_group("player")
if players.is_empty():
tooltip.visible = false
return
var p := players[0] as Node3D
tooltip.visible = p != null and global_position.distance_to(p.global_position) < 2.5
func interact(player: Node) -> void:
if player.call("apply_leather_armor"):
queue_free()
var mains := get_tree().get_nodes_in_group("main")
if not mains.is_empty():
mains[0].call("show_tutorial", "Tutorial_LeatherArmor")
+1
View File
@@ -0,0 +1 @@
uid://b80k2b1icwlbm
+5 -2
View File
@@ -12,7 +12,7 @@ func _ready() -> void:
tw.tween_property(self, "position:y", 0.1, 0.7)
func _process(delta: float) -> void:
rotation.y += delta * 1.2
#rotation.y += delta * 1.2
var players := get_tree().get_nodes_in_group("player")
if players.is_empty():
tooltip.visible = false
@@ -21,5 +21,8 @@ func _process(delta: float) -> void:
tooltip.visible = p != null and global_position.distance_to(p.global_position) < 2.5
func interact(player: Node) -> void:
player.call("apply_upgrade_boots", 10.0, tier)
player.call("apply_upgrade_boots", 2.0, tier)
queue_free()
var mains := get_tree().get_nodes_in_group("main")
if not mains.is_empty():
mains[0].call("show_tutorial", "Tutorial_LeatherBoots")
+583 -28
View File
@@ -10,7 +10,7 @@ const CAM_DIST := 8.0
const MOUSE_SENS := 0.18
const PITCH_MIN := 5.0
const PITCH_MAX := 70.0
const SPAWN_TIME := 10
const SPAWN_TIME := 5
var arena_size: float = 14.0
var cam_yaw: float = 0.0
@@ -27,10 +27,20 @@ var kills_for_next: int = 10
var game_active: bool = false
var upgrading: bool = false
# Tutorial
var tutorial_canvas: CanvasLayer
var tutorial_image: TextureRect
var tutorial_hint: Label
var tutorial_hint_ready: bool = false
var tutorial_active: bool = false
var tutorial_on_dismiss: Callable = Callable()
var shown_tutorials: Dictionary = {}
# UI nodes
var canvas: CanvasLayer
var score_label: Label
var wave_label: Label
var tier_label: Label
var hp_bar: ColorRect
var hp_bar_bg: ColorRect
var progress_bar: ColorRect
@@ -38,18 +48,35 @@ var progress_bg: ColorRect
var upgrade_panel: Panel
var gameover_panel: Panel
# Equipment slots
var equip_fills: Array[ColorRect] = []
var equip_labels: Array[Label] = []
var _equip_prev_tiers: Array[int] = [-1, -1, -1]
# Boss phase
var boss_active: bool = false
var first_boss_spawned: bool = false
var boss_timer: float = 90.0
var portal_node: Node3D = null
var boss_timer_label: Label
var boss_hint_label: Label
var win_panel: Panel
func _ready() -> void:
_spawn_level()
_create_camera()
_create_ui()
_create_tutorial_overlay()
_spawn_player()
_spawn_rocks()
_spawn_sticks()
_start_game()
add_to_group("main")
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
show_tutorial("Tutorial_StartGame", _start_game)
func _input(event: InputEvent) -> void:
if tutorial_active:
return
var motion := event as InputEventMouseMotion
if motion != null and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
cam_yaw -= motion.relative.x * MOUSE_SENS
@@ -92,6 +119,29 @@ func _process(delta: float) -> void:
camera.look_at(look_at_pos, Vector3.UP)
if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
player.set_aim_direction(deg_to_rad(cam_yaw))
_update_tier_label()
if boss_active:
boss_timer = max(0.0, boss_timer - delta)
var mins := int(boss_timer) / 60
var secs := int(boss_timer) % 60
boss_timer_label.text = "%d:%02d" % [mins, secs]
if boss_timer <= 10.0:
boss_timer_label.add_theme_color_override("font_color", Color(1.0, 0.2, 0.2))
if boss_timer <= 0.0:
_trigger_time_up()
return
if is_instance_valid(portal_node):
var area := portal_node.get_node_or_null("PortalArea") as Area3D
if area != null:
for body in area.get_overlapping_bodies():
if body.get("enemy_level") == 3:
var fv = body.get("fly_vel")
if fv != null:
var spd := Vector2((fv as Vector3).x, (fv as Vector3).z).length()
if spd >= 25.0:
_trigger_win()
return
# ─── Rocks ────────────────────────────────────────────────────────────────────
@@ -99,18 +149,39 @@ var rocks_on_field: int = 0
var rocks_pending: int = 0
func _get_rock_limit() -> int:
return mini(2 + (wave + 1) / 2, 7)
return mini(3 + (wave + 1) / 2, 7)
func _spawn_rocks() -> void:
var limit := _get_rock_limit()
for i in range(limit):
_spawn_single_rock()
var sticks_on_field: int = 0
var sticks_pending: int = 0
const STICK_LIMIT := 3
func _spawn_sticks() -> void:
for i in range(2):
var stick := STICK_SCENE.instantiate()
stick.position = _safe_item_position()
add_child(stick)
for i in range(STICK_LIMIT):
_spawn_single_stick()
func _spawn_single_stick() -> void:
var stick := STICK_SCENE.instantiate()
stick.position = _safe_item_position()
add_child(stick)
stick.connect("destroyed", _on_stick_destroyed)
sticks_on_field += 1
func _on_stick_destroyed() -> void:
sticks_on_field = maxi(0, sticks_on_field - 1)
if not game_active:
return
if sticks_on_field + sticks_pending < STICK_LIMIT:
sticks_pending += 1
await get_tree().create_timer(GameSettings.item_respawn_delay).timeout
sticks_pending -= 1
if game_active:
_spawn_single_stick()
func _spawn_single_rock() -> void:
var rock := ROCK_SCENE.instantiate()
@@ -143,7 +214,7 @@ func _on_rock_destroyed() -> void:
return
if rocks_on_field + rocks_pending < _get_rock_limit():
rocks_pending += 1
await get_tree().create_timer(20.0).timeout
await get_tree().create_timer(GameSettings.item_respawn_delay).timeout
rocks_pending -= 1
if game_active:
_spawn_single_rock()
@@ -174,7 +245,7 @@ func _start_game() -> void:
Enemy.first_iron_spawned = false
Enemy.first_essence_spawned = false
_update_labels()
spawn_timer.wait_time = 1.4
spawn_timer.wait_time = GameSettings.enemy_spawn_interval
spawn_timer.connect("timeout", _on_spawn_timer)
spawn_timer.start()
@@ -182,7 +253,7 @@ func _on_spawn_timer() -> void:
if not game_active or upgrading:
return
_spawn_enemy()
spawn_timer.wait_time = SPAWN_TIME # max(0.25, 1.4 - wave * 0.07)
spawn_timer.wait_time = GameSettings.enemy_spawn_interval
func _spawn_enemy() -> void:
var enemy := ENEMY_SCENE.instantiate() as CharacterBody3D
@@ -197,6 +268,9 @@ func _spawn_enemy() -> void:
enemy.target = player
enemy.connect("died", _on_enemy_died)
enemy.connect("merged", _on_enemy_merged)
if type == "ogre" and not first_boss_spawned:
first_boss_spawned = true
_start_boss_phase()
# Spawn at random edge
var side := randi() % 4
@@ -230,7 +304,10 @@ func _spawn_upgraded_enemy(pos: Vector3, type: String, level: int, w: int) -> Ch
enemy.setup(type, w)
enemy.target = player
enemy.enemy_level = level
enemy.tier = level
enemy.kick_tier = level
enemy.toughness_tier = level
enemy.call("_update_label")
enemy.call("_apply_mesh", level)
enemy.global_position = pos
enemy.connect("died", _on_enemy_died)
enemy.connect("merged", _on_enemy_merged)
@@ -243,11 +320,9 @@ func _spawn_upgraded_enemy(pos: Vector3, type: String, level: int, w: int) -> Ch
var old_size: Vector3 = s3d.size
col_shape.shape = BoxShape3D.new()
(col_shape.shape as BoxShape3D).size = old_size * s
var color := Color(1.0, 1.0, 0.5) if level > 2 else Color(1.0, 0.9, 0.3)
tw.tween_property(enemy.mat, "albedo_color", color, 0.25)
#var bs := scale
#tw.tween_property(enemy.mesh_node, "scale", Vector3(bs * 1.6, bs * 0.25, bs * 1.6), 0.07)
#tw.tween_property(enemy.mesh_node, "scale", Vector3(bs, bs, bs), 0.22)
if level >= 3 and not first_boss_spawned:
first_boss_spawned = true
_start_boss_phase()
return enemy
func _on_enemy_merged(_upgrade: bool) -> void:
@@ -255,6 +330,12 @@ func _on_enemy_merged(_upgrade: bool) -> void:
func _on_player_died() -> void:
game_active = false
if boss_active:
boss_active = false
boss_timer_label.visible = false
boss_hint_label.visible = false
if is_instance_valid(portal_node):
portal_node.queue_free()
spawn_timer.stop()
_show_gameover()
@@ -311,6 +392,215 @@ func _restart() -> void:
get_tree().paused = false
get_tree().reload_current_scene()
# ─── Boss phase ───────────────────────────────────────────────────────────────
func _start_boss_phase() -> void:
if boss_active or not game_active:
return
boss_active = true
boss_timer = 120.0
boss_timer_label.visible = true
boss_hint_label.visible = true
_spawn_portal()
func _spawn_portal() -> void:
portal_node = Node3D.new()
add_child(portal_node)
var player_pos := player.global_position if is_instance_valid(player) else Vector3.ZERO
var best_pos := Vector3(arena_size - 1.5, 0.0, 0.0)
var best_dist := 0.0
for _i in range(16):
var angle := randf() * TAU
var cand := Vector3(cos(angle), 0.0, sin(angle)) * (arena_size - 1.5)
var d := cand.distance_to(player_pos)
if d > best_dist:
best_dist = d
best_pos = cand
portal_node.global_position = best_pos
var light := OmniLight3D.new()
light.light_color = Color(0.5, 0.1, 1.0)
light.omni_range = 7.0
light.light_energy = 3.0
light.position.y = 1.0
portal_node.add_child(light)
var ring := MeshInstance3D.new()
var torus := TorusMesh.new()
torus.inner_radius = 1.0
torus.outer_radius = 1.65
var ring_mat := StandardMaterial3D.new()
ring_mat.albedo_color = Color(0.55, 0.1, 1.0)
ring_mat.emission_enabled = true
ring_mat.emission = Color(0.6, 0.2, 1.0)
ring_mat.emission_energy = 3.5
ring_mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
torus.material = ring_mat
ring.mesh = torus
ring.position.y = 0.05
portal_node.add_child(ring)
ring.create_tween().set_loops().tween_property(ring, "rotation:y", TAU, 2.5)
var disc := MeshInstance3D.new()
var disc_mesh := CylinderMesh.new()
disc_mesh.top_radius = 1.0
disc_mesh.bottom_radius = 1.0
disc_mesh.height = 0.05
var disc_mat := StandardMaterial3D.new()
disc_mat.albedo_color = Color(0.25, 0.0, 0.7, 0.65)
disc_mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
disc_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
disc_mat.emission_enabled = true
disc_mat.emission = Color(0.4, 0.1, 1.0)
disc_mat.emission_energy = 1.5
disc_mesh.material = disc_mat
disc.mesh = disc_mesh
disc.position.y = 0.03
portal_node.add_child(disc)
var tw_pulse := portal_node.create_tween().set_loops()
tw_pulse.tween_method(func(e: float): disc_mat.emission_energy = e, 0.8, 3.0, 0.7)
tw_pulse.tween_method(func(e: float): disc_mat.emission_energy = e, 3.0, 0.8, 0.7)
var area := Area3D.new()
area.name = "PortalArea"
var col := CollisionShape3D.new()
var cyl := CylinderShape3D.new()
cyl.radius = 1.8
cyl.height = 3.0
col.shape = cyl
col.position.y = 1.5
area.add_child(col)
portal_node.add_child(area)
var lbl := Label3D.new()
lbl.text = "PORTAL\nPush Ogre Here"
lbl.position = Vector3(0, 2.6, 0)
lbl.billboard = BaseMaterial3D.BILLBOARD_ENABLED
lbl.font_size = 34
lbl.outline_size = 6
lbl.modulate = Color(0.85, 0.55, 1.0)
lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
portal_node.add_child(lbl)
FX.merge_smoke(best_pos + Vector3(0, 0.5, 0), self)
func _trigger_win() -> void:
if not boss_active:
return
boss_active = false
game_active = false
spawn_timer.stop()
boss_timer_label.visible = false
boss_hint_label.visible = false
if is_instance_valid(portal_node):
portal_node.queue_free()
get_tree().paused = true
win_panel.visible = true
(win_panel.get_node("VBox/ScoreLabel") as Label).text = "Score: %d\nWave: %d" % [score, wave]
func _trigger_time_up() -> void:
if not boss_active:
return
boss_active = false
game_active = false
spawn_timer.stop()
boss_timer_label.visible = false
boss_hint_label.visible = false
if is_instance_valid(portal_node):
portal_node.queue_free()
_show_gameover()
# ─── Tutorial ─────────────────────────────────────────────────────────────────
func _create_tutorial_overlay() -> void:
tutorial_canvas = CanvasLayer.new()
tutorial_canvas.process_mode = Node.PROCESS_MODE_ALWAYS
tutorial_canvas.visible = false
add_child(tutorial_canvas)
var bg := ColorRect.new()
bg.color = Color(0.0, 0.0, 0.0, 0.78)
bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
tutorial_canvas.add_child(bg)
tutorial_image = TextureRect.new()
tutorial_image.anchor_left = 0.02
tutorial_image.anchor_right = 0.98
tutorial_image.anchor_top = 0.02
tutorial_image.anchor_bottom = 0.91
tutorial_image.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
tutorial_image.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
tutorial_canvas.add_child(tutorial_image)
tutorial_hint = Label.new()
tutorial_hint.anchor_left = 0.5
tutorial_hint.anchor_right = 0.5
tutorial_hint.anchor_top = 0.93
tutorial_hint.offset_left = -280
tutorial_hint.offset_right = 280
tutorial_hint.text = "Нажмите ЛКМ чтобы продолжить"
tutorial_hint.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
tutorial_hint.add_theme_font_size_override("font_size", 22)
tutorial_hint.add_theme_color_override("font_color", Color.WHITE)
tutorial_hint.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.9))
tutorial_hint.add_theme_constant_override("shadow_offset_x", 2)
tutorial_hint.add_theme_constant_override("shadow_offset_y", 2)
tutorial_hint.visible = false
tutorial_canvas.add_child(tutorial_hint)
var click_cap := Control.new()
click_cap.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
click_cap.mouse_filter = Control.MOUSE_FILTER_STOP
click_cap.process_mode = Node.PROCESS_MODE_ALWAYS
click_cap.connect("gui_input", _on_tutorial_input)
tutorial_canvas.add_child(click_cap)
func _on_tutorial_input(event: InputEvent) -> void:
if not tutorial_hint_ready:
return
var mb := event as InputEventMouseButton
if mb != null and mb.button_index == MOUSE_BUTTON_LEFT and mb.pressed:
_dismiss_tutorial()
func _set_enemies_paused(paused: bool) -> void:
var mode := Node.PROCESS_MODE_DISABLED if paused else Node.PROCESS_MODE_PAUSABLE
for e in get_tree().get_nodes_in_group("enemies"):
(e as Node).process_mode = mode
spawn_timer.paused = paused
func _set_player_paused(paused: bool) -> void:
var mode := Node.PROCESS_MODE_DISABLED if paused else Node.PROCESS_MODE_PAUSABLE
for e in get_tree().get_nodes_in_group("player"):
(e as Node).process_mode = mode
func show_tutorial(key: String, on_dismiss: Callable = Callable()) -> void:
if shown_tutorials.get(key, false):
if on_dismiss.is_valid():
on_dismiss.call()
return
shown_tutorials[key] = true
var path := "res://assets/%s.jpeg" % key
tutorial_image.texture = load(path) if ResourceLoader.exists(path) else null
tutorial_on_dismiss = on_dismiss
tutorial_hint_ready = false
tutorial_hint.visible = false
tutorial_canvas.visible = true
tutorial_active = true
_set_enemies_paused(true)
_set_player_paused(true)
await get_tree().create_timer(3.0).timeout
tutorial_hint.visible = true
tutorial_hint_ready = true
func _dismiss_tutorial() -> void:
tutorial_canvas.visible = false
tutorial_active = false
_set_enemies_paused(false)
_set_player_paused(false)
if tutorial_on_dismiss.is_valid():
tutorial_on_dismiss.call()
# ─── UI ───────────────────────────────────────────────────────────────────────
func _create_ui() -> void:
@@ -321,22 +611,108 @@ func _create_ui() -> void:
_make_hud()
_make_upgrade_panel()
_make_gameover_panel()
_make_boss_ui()
_make_win_panel()
func _make_hud() -> void:
# Score
score_label = _label(Vector2(12, 10), "Score: 0", 22)
# Wave
wave_label = _label(Vector2(12, 38), "Wave: 1", 22)
score_label = _label(Vector2(16, 12), "Score: 0", 30)
wave_label = _label(Vector2(16, 50), "Wave: 1", 30)
_make_recipe_panel()
# HP bar
_label(Vector2(12, 68), "HP", 16)
hp_bar_bg = _crect(Vector2(12, 88), Vector2(200, 16), Color(0.25, 0.04, 0.04))
hp_bar = _crect(Vector2(12, 88), Vector2(200, 16), Color(0.9, 0.15, 0.15))
func _make_recipe_panel() -> void:
const INGREDIENT_NAMES := {
"rock": "Rock",
"stick": "Stick",
"leather": "Leather",
"iron": "Iron",
"metal_plate":"Iron Plate",
}
const RESULT_NAMES := {
"LeatherBoots": "Leather Boots",
"Boulder": "Boulder",
"StickArmor": "Stick Armor",
"LeatherArmor": "Leather Armor",
"PlateArmor": "Plate Armor",
"WoodenShield": "Wooden Shield",
"IronShield": "Iron Shield",
"MetalArmor": "Metal Armor",
}
# Kill progress toward next upgrade
_label(Vector2(12, 110), "Next upgrade", 16)
progress_bg = _crect(Vector2(12, 130), Vector2(200, 10), Color(0.1, 0.1, 0.25))
progress_bar = _crect(Vector2(12, 130), Vector2(0, 10), Color(0.4, 0.8, 1.0))
const PAD_H := 10
const PAD_V := 8
const SEP := 4
const TITLE_H := 22
const ROW_H := 20
var n := MergeRecipes._list.size()
var content_h := TITLE_H + SEP + n * ROW_H + (n - 1) * SEP
var panel_h := content_h + PAD_V * 2 + 10
const PANEL_W := 260
var panel := Panel.new()
var sb := StyleBoxFlat.new()
sb.bg_color = Color(0.0, 0.0, 0.0, 0.55)
sb.corner_radius_top_left = 6
sb.corner_radius_top_right = 6
sb.corner_radius_bottom_left = 6
sb.corner_radius_bottom_right = 6
panel.add_theme_stylebox_override("panel", sb)
panel.anchor_left = 1.0
panel.anchor_right = 1.0
panel.anchor_top = 0.0
panel.anchor_bottom = 0.0
panel.offset_left = -(PANEL_W + 10)
panel.offset_right = -10
panel.offset_top = 10
panel.offset_bottom = 10 + panel_h
canvas.add_child(panel)
var margin := MarginContainer.new()
margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
margin.add_theme_constant_override("margin_left", PAD_H)
margin.add_theme_constant_override("margin_right", PAD_H)
margin.add_theme_constant_override("margin_top", PAD_V)
margin.add_theme_constant_override("margin_bottom", PAD_V)
panel.add_child(margin)
var vbox := VBoxContainer.new()
vbox.add_theme_constant_override("separation", SEP)
margin.add_child(vbox)
var title := Label.new()
title.text = "Рецепты"
title.add_theme_font_size_override("font_size", 17)
title.add_theme_color_override("font_color", Color(1.0, 0.9, 0.5))
title.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.8))
title.add_theme_constant_override("shadow_offset_x", 1)
title.add_theme_constant_override("shadow_offset_y", 1)
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vbox.add_child(title)
for recipe in MergeRecipes._list:
var a: String = INGREDIENT_NAMES.get(recipe["ingredients"][0], recipe["ingredients"][0])
var b: String = INGREDIENT_NAMES.get(recipe["ingredients"][1], recipe["ingredients"][1])
var scene_name: String = (recipe["result_scene"] as String).get_file().get_basename()
var result: String = RESULT_NAMES.get(scene_name, scene_name)
var row := Label.new()
row.text = "%s + %s%s" % [a, b, result]
row.add_theme_font_size_override("font_size", 15)
row.add_theme_color_override("font_color", Color.WHITE)
row.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.8))
row.add_theme_constant_override("shadow_offset_x", 1)
row.add_theme_constant_override("shadow_offset_y", 1)
vbox.add_child(row)
_label(Vector2(16, 92), "HP", 20)
hp_bar_bg = _crect(Vector2(16, 118), Vector2(260, 20), Color(0.25, 0.04, 0.04))
hp_bar = _crect(Vector2(16, 118), Vector2(260, 20), Color(0.9, 0.15, 0.15))
_label(Vector2(16, 146), "Next upgrade", 20)
progress_bg = _crect(Vector2(16, 172), Vector2(260, 14), Color(0.1, 0.1, 0.25))
progress_bar = _crect(Vector2(16, 172), Vector2(0, 14), Color(0.4, 0.8, 1.0))
tier_label = _label(Vector2(16, 194), "", 20)
_make_equipment_slots()
func _make_upgrade_panel() -> void:
upgrade_panel = Panel.new()
@@ -417,6 +793,175 @@ func _make_gameover_panel() -> void:
restart_btn.connect("pressed", _restart)
vbox.add_child(restart_btn)
func _make_boss_ui() -> void:
boss_timer_label = Label.new()
boss_timer_label.anchor_left = 0.5
boss_timer_label.anchor_right = 0.5
boss_timer_label.anchor_top = 0.0
boss_timer_label.offset_left = -80
boss_timer_label.offset_right = 80
boss_timer_label.offset_top = 8
boss_timer_label.offset_bottom = 54
boss_timer_label.text = "1:30"
boss_timer_label.add_theme_font_size_override("font_size", 38)
boss_timer_label.add_theme_color_override("font_color", Color(0.8, 0.3, 1.0))
boss_timer_label.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.9))
boss_timer_label.add_theme_constant_override("shadow_offset_x", 2)
boss_timer_label.add_theme_constant_override("shadow_offset_y", 2)
boss_timer_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
boss_timer_label.visible = false
canvas.add_child(boss_timer_label)
boss_hint_label = Label.new()
boss_hint_label.anchor_left = 0.5
boss_hint_label.anchor_right = 0.5
boss_hint_label.anchor_top = 0.0
boss_hint_label.offset_left = -220
boss_hint_label.offset_right = 220
boss_hint_label.offset_top = 54
boss_hint_label.offset_bottom = 80
boss_hint_label.text = "Push the Ogre into the Portal!"
boss_hint_label.add_theme_font_size_override("font_size", 17)
boss_hint_label.add_theme_color_override("font_color", Color(0.85, 0.7, 1.0))
boss_hint_label.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.8))
boss_hint_label.add_theme_constant_override("shadow_offset_x", 1)
boss_hint_label.add_theme_constant_override("shadow_offset_y", 1)
boss_hint_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
boss_hint_label.visible = false
canvas.add_child(boss_hint_label)
func _make_win_panel() -> void:
win_panel = Panel.new()
win_panel.process_mode = Node.PROCESS_MODE_ALWAYS
win_panel.visible = false
canvas.add_child(win_panel)
win_panel.anchor_left = 0.5
win_panel.anchor_right = 0.5
win_panel.anchor_top = 0.5
win_panel.anchor_bottom = 0.5
win_panel.offset_left = -200.0
win_panel.offset_right = 200.0
win_panel.offset_top = -140.0
win_panel.offset_bottom = 140.0
var vbox2 := VBoxContainer.new()
vbox2.name = "VBox"
vbox2.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
vbox2.alignment = BoxContainer.ALIGNMENT_CENTER
vbox2.add_theme_constant_override("separation", 16)
win_panel.add_child(vbox2)
var title2 := Label.new()
title2.text = "VICTORY!"
title2.add_theme_font_size_override("font_size", 42)
title2.add_theme_color_override("font_color", Color(1.0, 0.85, 0.1))
title2.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vbox2.add_child(title2)
var score_lbl2 := Label.new()
score_lbl2.name = "ScoreLabel"
score_lbl2.add_theme_font_size_override("font_size", 20)
score_lbl2.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vbox2.add_child(score_lbl2)
var btn2 := Button.new()
btn2.text = "Play Again"
btn2.add_theme_font_size_override("font_size", 18)
btn2.process_mode = Node.PROCESS_MODE_ALWAYS
btn2.connect("pressed", _restart)
vbox2.add_child(btn2)
# ─── Equipment slots ──────────────────────────────────────────────────────────
const _EQUIP_SLOT_SIZE := 64
const _EQUIP_SLOT_GAP := 10
const _EQUIP_SLOT_PAD := 3
const _EQUIP_START_X := 16
const _EQUIP_START_Y := 228
const _EQUIP_EMPTY_COL := Color(0.10, 0.10, 0.16)
const _EQUIP_BORDER_COL := Color(0.30, 0.30, 0.42)
# [slot_index][tier] = [fill_color, label_text]
const _EQUIP_DATA := [
[ # shield
[Color(0.10, 0.10, 0.16), ""],
[Color(0.55, 0.38, 0.18), "Wood\nShield"],
[Color(0.55, 0.58, 0.62), "Iron\nShield"],
],
[ # armor (toughness_tier)
[Color(0.10, 0.10, 0.16), ""],
[Color(0.76, 0.47, 0.18), "Leather\nArmor"],
[Color(0.58, 0.68, 1.00), "Metal\nArmor"],
],
[ # boots (kick_tier)
[Color(0.10, 0.10, 0.16), ""],
[Color(0.76, 0.47, 0.18), "Leather\nBoots"],
[Color(0.58, 0.68, 1.00), "Plate\nBoots"],
[Color(0.75, 0.18, 1.00), "Magic\nBoots"],
],
]
func _make_equipment_slots() -> void:
var titles := ["Shield", "Armor", "Boots"]
for i in range(3):
var x := _EQUIP_START_X + i * (_EQUIP_SLOT_SIZE + _EQUIP_SLOT_GAP)
var y := _EQUIP_START_Y
var title := _label(Vector2(x, y), titles[i], 16)
title.size.x = _EQUIP_SLOT_SIZE
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
var border := ColorRect.new()
border.position = Vector2(x, y + 22)
border.size = Vector2(_EQUIP_SLOT_SIZE, _EQUIP_SLOT_SIZE)
border.color = _EQUIP_BORDER_COL
canvas.add_child(border)
var fill := ColorRect.new()
fill.position = Vector2(x + _EQUIP_SLOT_PAD, y + 22 + _EQUIP_SLOT_PAD)
fill.size = Vector2(_EQUIP_SLOT_SIZE - _EQUIP_SLOT_PAD * 2, _EQUIP_SLOT_SIZE - _EQUIP_SLOT_PAD * 2)
fill.color = _EQUIP_EMPTY_COL
canvas.add_child(fill)
equip_fills.append(fill)
var lbl := Label.new()
lbl.position = fill.position
lbl.size = fill.size
lbl.text = ""
lbl.add_theme_font_size_override("font_size", 14)
lbl.add_theme_color_override("font_color", Color.WHITE)
lbl.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.85))
lbl.add_theme_constant_override("shadow_offset_x", 1)
lbl.add_theme_constant_override("shadow_offset_y", 1)
lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
lbl.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
lbl.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
canvas.add_child(lbl)
equip_labels.append(lbl)
func _update_equipment_slots() -> void:
if not is_instance_valid(player):
return
var tiers := [
player.get("shield_tier") as int,
player.get("toughness_tier") as int,
player.get("kick_tier") as int,
]
for i in range(3):
var tier: int = tiers[i]
if tier == _equip_prev_tiers[i]:
continue
_equip_prev_tiers[i] = tier
var data: Array = _EQUIP_DATA[i]
var entry: Array = data[clampi(tier, 0, data.size() - 1)]
equip_fills[i].color = entry[0] as Color
equip_labels[i].text = entry[1] as String
if tier > 0:
var tw := create_tween()
tw.tween_property(equip_fills[i], "color", Color.WHITE, 0.06)
tw.tween_property(equip_fills[i], "color", entry[0] as Color, 0.22)
# ─── UI helpers ───────────────────────────────────────────────────────────────
func _label(pos: Vector2, text: String, size: int) -> Label:
@@ -446,3 +991,13 @@ func _update_labels() -> void:
func _update_progress() -> void:
var t := float(kills) / float(kills_for_next)
progress_bar.size.x = 200.0 * t
func _update_tier_label() -> void:
if not is_instance_valid(player):
return
var kt: int = player.get("kick_tier")
var tt: int = player.get("toughness_tier")
var st: int = player.get("shield_tier")
var shield_str := "-" if st == 0 else str(st)
tier_label.text = "Kick: %d Tough: %d Shield: %s" % [kt, tt, shield_str]
_update_equipment_slots()
+243
View File
@@ -0,0 +1,243 @@
extends Control
static var volume: float = 100.0
var settings_panel: Panel
var difficulty_panel: Panel
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
_build_ui()
_apply_volume(volume)
func _build_ui() -> void:
var bg := ColorRect.new()
bg.color = Color(0.06, 0.04, 0.10)
bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
add_child(bg)
var title := Label.new()
title.text = "KickSurvivors"
title.add_theme_font_size_override("font_size", 52)
title.add_theme_color_override("font_color", Color.WHITE)
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
title.anchor_left = 0.5
title.anchor_right = 0.5
title.anchor_top = 0.0
title.offset_left = -200
title.offset_right = 200
title.offset_top = 110
add_child(title)
var vbox := VBoxContainer.new()
vbox.add_theme_constant_override("separation", 14)
vbox.anchor_left = 0.5
vbox.anchor_right = 0.5
vbox.anchor_top = 0.5
vbox.anchor_bottom = 0.5
vbox.offset_left = -110
vbox.offset_right = 110
vbox.offset_top = -90
vbox.offset_bottom = 90
add_child(vbox)
vbox.add_child(_btn("Играть", _on_play))
vbox.add_child(_btn("Настройки", _on_settings))
vbox.add_child(_btn("Выход", _on_exit))
_build_settings_panel()
_build_difficulty_panel()
func _big_btn(text: String, width: float, cb: Callable) -> Button:
var b := _btn(text, cb)
b.custom_minimum_size = Vector2(width, 72)
b.add_theme_font_size_override("font_size", 18)
return b
func _btn(text: String, cb: Callable) -> Button:
var b := Button.new()
b.text = text
b.custom_minimum_size = Vector2(220, 54)
b.add_theme_font_size_override("font_size", 20)
for state in ["normal", "hover", "pressed", "focus", "disabled"]:
var sb := StyleBoxFlat.new()
sb.bg_color = Color(0.18, 0.13, 0.30) if state == "normal" else (
Color(0.28, 0.20, 0.46) if state == "hover" else
Color(0.12, 0.09, 0.22))
sb.border_width_left = 1
sb.border_width_right = 1
sb.border_width_top = 1
sb.border_width_bottom = 1
sb.border_color = Color(0.50, 0.38, 0.75)
sb.corner_radius_top_left = 6
sb.corner_radius_top_right = 6
sb.corner_radius_bottom_left = 6
sb.corner_radius_bottom_right = 6
sb.content_margin_left = 20
sb.content_margin_right = 20
sb.content_margin_top = 12
sb.content_margin_bottom = 12
b.add_theme_stylebox_override(state, sb)
b.connect("pressed", cb)
return b
static func _make_opaque_panel() -> Panel:
var p := Panel.new()
var sb := StyleBoxFlat.new()
sb.bg_color = Color(0.08, 0.06, 0.14)
sb.border_width_left = 2
sb.border_width_right = 2
sb.border_width_top = 2
sb.border_width_bottom = 2
sb.border_color = Color(0.35, 0.28, 0.55)
sb.corner_radius_top_left = 8
sb.corner_radius_top_right = 8
sb.corner_radius_bottom_left = 8
sb.corner_radius_bottom_right = 8
sb.content_margin_left = 24
sb.content_margin_right = 24
sb.content_margin_top = 20
sb.content_margin_bottom = 20
p.add_theme_stylebox_override("panel", sb)
return p
func _build_settings_panel() -> void:
settings_panel = _make_opaque_panel()
settings_panel.visible = false
settings_panel.anchor_left = 0.5
settings_panel.anchor_right = 0.5
settings_panel.anchor_top = 0.5
settings_panel.anchor_bottom = 0.5
settings_panel.offset_left = -200
settings_panel.offset_right = 200
settings_panel.offset_top = -130
settings_panel.offset_bottom = 130
add_child(settings_panel)
var vbox := VBoxContainer.new()
vbox.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
vbox.alignment = BoxContainer.ALIGNMENT_CENTER
vbox.add_theme_constant_override("separation", 18)
settings_panel.add_child(vbox)
var lbl := Label.new()
lbl.text = "Настройки"
lbl.add_theme_font_size_override("font_size", 26)
lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vbox.add_child(lbl)
var vol_lbl := Label.new()
vol_lbl.name = "VolumeLabel"
vol_lbl.text = "Громкость: %d" % int(volume)
vol_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vbox.add_child(vol_lbl)
var slider := HSlider.new()
slider.min_value = 0
slider.max_value = 100
slider.step = 1
slider.value = volume
slider.custom_minimum_size = Vector2(320, 32)
slider.connect("value_changed", func(v: float) -> void:
volume = v
vol_lbl.text = "Громкость: %d" % int(v)
_apply_volume(v)
)
vbox.add_child(slider)
vbox.add_child(_btn("Назад", func(): settings_panel.visible = false))
func _apply_volume(v: float) -> void:
var db := linear_to_db(v / 100.0) if v > 0.0 else -80.0
AudioServer.set_bus_volume_db(0, db)
func _build_difficulty_panel() -> void:
difficulty_panel = _make_opaque_panel()
difficulty_panel.visible = false
difficulty_panel.anchor_left = 0.5
difficulty_panel.anchor_right = 0.5
difficulty_panel.anchor_top = 0.5
difficulty_panel.anchor_bottom = 0.5
difficulty_panel.offset_left = -310
difficulty_panel.offset_right = 310
difficulty_panel.offset_top = -240
difficulty_panel.offset_bottom = 240
add_child(difficulty_panel)
var margin := MarginContainer.new()
margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
margin.add_theme_constant_override("margin_left", 24)
margin.add_theme_constant_override("margin_right", 24)
margin.add_theme_constant_override("margin_top", 20)
margin.add_theme_constant_override("margin_bottom", 20)
difficulty_panel.add_child(margin)
var vbox := VBoxContainer.new()
vbox.alignment = BoxContainer.ALIGNMENT_CENTER
vbox.add_theme_constant_override("separation", 16)
margin.add_child(vbox)
var title := Label.new()
title.text = "Выберите сложность"
title.add_theme_font_size_override("font_size", 26)
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vbox.add_child(title)
vbox.add_child(_big_btn("Бессмертный\nНет урона · тир пинков от мелких врагов", 540, func() -> void:
GameSettings.difficulty = "immortal"
get_tree().change_scene_to_file("res://scenes/Main.tscn")
))
vbox.add_child(_big_btn("Выживание\nПолучаешь урон · фиксированная сила пинка", 540, func() -> void:
GameSettings.difficulty = "survival"
get_tree().change_scene_to_file("res://scenes/Main.tscn")
))
# Spawn speed row
var spawn_lbl := Label.new()
spawn_lbl.text = "Скорость спавна:"
spawn_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
spawn_lbl.add_theme_font_size_override("font_size", 16)
spawn_lbl.add_theme_color_override("font_color", Color(0.85, 0.78, 1.0))
vbox.add_child(spawn_lbl)
var hbox := HBoxContainer.new()
hbox.alignment = BoxContainer.ALIGNMENT_CENTER
hbox.add_theme_constant_override("separation", 10)
vbox.add_child(hbox)
var spawn_options := [
["Медленно", 10.0, 15.0],
["Нормально", 8.0, 15.0],
["Быстро", 6.0, 10.0],
]
var spawn_btns: Array[Button] = []
for opt in spawn_options:
var sb_btn := _btn(opt[0] as String, Callable())
sb_btn.custom_minimum_size = Vector2(110, 40)
sb_btn.add_theme_font_size_override("font_size", 15)
var enemy_iv: float = opt[1]
var item_iv: float = opt[2]
sb_btn.connect("pressed", func() -> void:
GameSettings.enemy_spawn_interval = enemy_iv
GameSettings.item_respawn_delay = item_iv
for b in spawn_btns:
b.modulate = Color(1, 1, 1)
sb_btn.modulate = Color(0.7, 1.0, 0.5)
)
hbox.add_child(sb_btn)
spawn_btns.append(sb_btn)
# default: normal
spawn_btns[1].modulate = Color(0.7, 1.0, 0.5)
vbox.add_child(_btn("Назад", func(): difficulty_panel.visible = false))
func _on_play() -> void:
difficulty_panel.visible = true
func _on_settings() -> void:
settings_panel.visible = true
func _on_exit() -> void:
get_tree().quit()
+1
View File
@@ -0,0 +1 @@
uid://on1o20vpycgm
+25
View File
@@ -13,6 +13,31 @@ static var _list: Array[Dictionary] = [
"result_scene": "res://scenes/Boulder.tscn",
"speed_threshold": 18.0,
},
{
"ingredients": ["stick", "stick"],
"result_scene": "res://scenes/StickArmor.tscn",
"speed_threshold": 18.0,
},
{
"ingredients": ["leather", "rock"],
"result_scene": "res://scenes/LeatherArmor.tscn",
"speed_threshold": 18.0,
},
{
"ingredients": ["leather", "metal_plate"],
"result_scene": "res://scenes/PlateArmor.tscn",
"speed_threshold": 18.0,
},
{
"ingredients": ["rock", "stick"],
"result_scene": "res://scenes/WoodenShield.tscn",
"speed_threshold": 18.0,
},
{
"ingredients": ["iron", "leather"],
"result_scene": "res://scenes/IronShield.tscn",
"speed_threshold": 18.0,
},
]
static func find(type_a: String, type_b: String, speed: float) -> Dictionary:
+1 -1
View File
@@ -10,7 +10,7 @@ func _ready() -> void:
tw.tween_property(self, "position:y", 0.2, 0.7)
func _process(delta: float) -> void:
rotation.y += delta * 1.4
#rotation.y += delta * 1.4
var players := get_tree().get_nodes_in_group("player")
if players.is_empty():
tooltip.visible = false
+148
View File
@@ -0,0 +1,148 @@
extends CharacterBody3D
signal destroyed
enum State { IDLE, FLYING }
const AIR_FRICTION := 0.86
const MIN_SPEED := 0.5
const WALL_BOUNCE := 0.45
const WALL_SELF_DMG := 0.4
var kickable_type: String = "metal_plate"
var kick_tier: int = 0
var toughness_tier: int = 2
var state: State = State.IDLE
var fly_vel: Vector3 = Vector3.ZERO
var health: float = 1200.0
var dead: bool = false
var damage_modifier: float = 1.2
@onready var mesh_node: MeshInstance3D = $PlateMesh
@onready var tooltip: Label3D = $Tooltip
var plate_mat: StandardMaterial3D
const COLOR_IDLE := Color(0.6, 0.65, 0.72)
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
func _ready() -> void:
add_to_group("kickable")
add_to_group("interactable")
plate_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
mesh_node.material_override = plate_mat
tooltip.visible = false
func _process(_delta: float) -> void:
if dead:
tooltip.visible = false
return
var players := get_tree().get_nodes_in_group("player")
if players.is_empty():
tooltip.visible = false
return
var p := players[0] as Node3D
tooltip.visible = p != null and global_position.distance_to(p.global_position) < 2.5
func interact(player: Node) -> void:
if dead:
return
player.call("apply_upgrade_armor")
dead = true
set_physics_process(false)
tooltip.visible = false
remove_from_group("interactable")
remove_from_group("kickable")
var tw := create_tween()
tw.tween_property(self, "scale", Vector3(1.4, 0.1, 1.4), 0.15)
tw.tween_property(self, "scale", Vector3(0.0, 0.0, 0.0), 0.1)
tw.tween_callback(queue_free)
func apply_collision_damage(dmg: float) -> void:
_take_damage(dmg)
func receive_kick(direction: Vector3, force: float) -> void:
fly_vel = direction * force
fly_vel.y = 0.0
state = State.FLYING
func _physics_process(delta: float) -> void:
if state == State.IDLE:
return
_fly(delta)
func _fly(delta: float) -> void:
var speed_now := Vector2(fly_vel.x, fly_vel.z).length()
velocity = fly_vel
velocity.y = 0.0
move_and_slide()
var handled := false
for i in get_slide_collision_count():
var col := get_slide_collision(i)
var col3d := col.get_collider() as Node3D
if col3d == null:
continue
if col3d.has_meta("is_wall"):
var normal := col.get_normal()
normal.y = 0.0
if normal.length() > 0.01:
fly_vel = fly_vel.bounce(normal.normalized()) * WALL_BOUNCE
else:
fly_vel = Vector3.ZERO
_take_damage(speed_now * WALL_SELF_DMG)
handled = true
break
elif col3d.is_in_group("player"):
col3d.call("take_damage", int(speed_now * damage_modifier), toughness_tier)
fly_vel *= 0.3
handled = true
break
elif col3d.is_in_group("enemies") or col3d.is_in_group("kickable"):
if col3d == self:
continue
KickSystem.resolve(self, col3d, fly_vel)
if not dead and is_instance_valid(col3d):
var kick_dir := col3d.global_position - global_position
kick_dir.y = 0.0
if kick_dir.length() > 0.01:
col3d.call("receive_kick", kick_dir.normalized(), speed_now * 0.5)
fly_vel *= 0.45
handled = true
break
if not handled:
fly_vel = velocity
fly_vel.y = 0.0
fly_vel *= pow(AIR_FRICTION, delta * 60.0)
if Vector2(fly_vel.x, fly_vel.z).length() < MIN_SPEED:
fly_vel = Vector3.ZERO
velocity = Vector3.ZERO
state = State.IDLE
mesh_node.rotation.y += delta * speed_now * 0.25
func _take_damage(dmg: float) -> void:
if dead:
return
health -= dmg
_flash()
if health <= 0.0:
_die()
func _die() -> void:
dead = true
state = State.IDLE
set_physics_process(false)
emit_signal("destroyed")
var tw := create_tween()
tw.tween_property(self, "scale", Vector3(1.8, 0.1, 1.8), 0.12)
tw.tween_property(self, "scale", Vector3(0.0, 0.0, 0.0), 0.1)
tw.tween_callback(queue_free)
func _flash() -> void:
var tw := create_tween()
tw.tween_property(plate_mat, "albedo_color", COLOR_IMPACT, 0.04)
var target_color := COLOR_IDLE.lerp(Color.RED, clampf(1.0 - health / 120.0, 0.0, 0.6))
tw.tween_property(plate_mat, "albedo_color", target_color, 0.18)
+1
View File
@@ -0,0 +1 @@
uid://sfq4iq0btm0g
+23
View File
@@ -0,0 +1,23 @@
extends Node3D
@onready var tooltip: Label3D = $Tooltip
func _ready() -> void:
add_to_group("interactable")
tooltip.visible = false
var tw := create_tween().set_loops()
tw.tween_property(self, "position:y", 0.45, 0.65)
tw.tween_property(self, "position:y", 0.2, 0.65)
func _process(delta: float) -> void:
rotation.y += delta * 1.1
var players := get_tree().get_nodes_in_group("player")
if players.is_empty():
tooltip.visible = false
return
var p := players[0] as Node3D
tooltip.visible = p != null and global_position.distance_to(p.global_position) < 2.5
func interact(player: Node) -> void:
if player.call("apply_plate_armor"):
queue_free()
+1
View File
@@ -0,0 +1 @@
uid://sklquy2lyugo
+105 -35
View File
@@ -8,10 +8,18 @@ signal health_changed(current: int, maximum: int)
@export var kick_force: float = 60.0
@export var kick_cooldown: float = 0.6
@export var kick_angle: float = 60.0
@export var max_health: int = 100
@export var max_health: int = 300
var health: int = max_health
var tier: int = 0
var kick_tier: int = 0
var toughness_tier: int = 0
var has_stick_armor: bool = false
var has_leather_armor: bool = false
var has_plate_armor: bool = false
var has_wooden_shield: bool = false
var has_iron_shield: bool = false
var shield_tier: int = 0
var is_shielding: bool = false
var kick_timer: float = 0.0
var invincible_timer: float = 0.0
var is_alive: bool = true
@@ -20,8 +28,10 @@ var last_move_dir: Vector3 = Vector3.FORWARD
var _aim_yaw: float = 0.0
var _is_aiming: bool = false
@onready var mesh_node: MeshInstance3D = $BodyMesh
@onready var mesh_node: MeshInstance3D = $player_man
@onready var mesh_node_boot: MeshInstance3D = $boot
@onready var indicator_node: MeshInstance3D = $KickIndicator
@onready var anim_player: AnimationPlayer = $AnimationPlayer2
var player_mat: StandardMaterial3D
var indicator_mat: StandardMaterial3D
@@ -31,10 +41,25 @@ const BASE_COLOR := Color(0.2, 0.55, 1.0)
func _ready() -> void:
add_to_group("player")
player_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
mesh_node.material_override = player_mat
player_mat = mesh_node.get_surface_override_material(0).duplicate() as StandardMaterial3D
mesh_node.set_surface_override_material(0, player_mat)
mesh_node_boot.visible = false
_setup_indicator()
func _apply_boot_mesh(tier: int) -> void:
if tier <= 0:
mesh_node_boot.visible = false
return
mesh_node_boot.visible = true
var tex := load("res://assets/boot%d.png" % tier) as Texture2D
if tex == null:
return
var mat := mesh_node_boot.get_surface_override_material(0)
if mat == null:
mat = StandardMaterial3D.new()
mesh_node_boot.set_surface_override_material(0, mat)
(mat as StandardMaterial3D).albedo_texture = tex
func _setup_indicator() -> void:
indicator_node.position.y = 0.02
indicator_node.mesh = _make_kick_arc_mesh()
@@ -76,13 +101,15 @@ func _input(event: InputEvent) -> void:
func _physics_process(delta: float) -> void:
if not is_alive:
return
is_shielding = shield_tier > 0 and Input.is_key_pressed(KEY_SPACE)
_handle_movement(delta)
_handle_kick(delta)
_handle_iframes(delta)
if Input.is_action_just_pressed("ui_accept") and kick_timer <= 0.0:
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) and kick_timer <= 0.0:
_do_kick()
func _handle_movement(delta: float) -> void:
var effective_speed := move_speed * (0.2 if is_shielding else 1.0)
var input_x: float = (
float(Input.is_key_pressed(KEY_D) or Input.is_key_pressed(KEY_RIGHT)) -
float(Input.is_key_pressed(KEY_A) or Input.is_key_pressed(KEY_LEFT))
@@ -102,15 +129,15 @@ func _handle_movement(delta: float) -> void:
var move := cam_fwd * (-input_z) + cam_right * input_x
if move.length() > 0.01:
move = move.normalized()
velocity.x = move.x * move_speed
velocity.z = move.z * move_speed
velocity.x = move.x * effective_speed
velocity.z = move.z * effective_speed
last_move_dir = move
if not _is_aiming:
var target_y: float = atan2(-move.x, -move.z)
rotation.y = lerp_angle(rotation.y, target_y, 16.0 * delta)
else:
velocity.x = move_toward(velocity.x, 0.0, move_speed * 12.0 * delta)
velocity.z = move_toward(velocity.z, 0.0, move_speed * 12.0 * delta)
velocity.x = move_toward(velocity.x, 0.0, effective_speed * 12.0 * delta)
velocity.z = move_toward(velocity.z, 0.0, effective_speed * 12.0 * delta)
if _is_aiming:
rotation.y = lerp_angle(rotation.y, _aim_yaw, 14.0 * delta)
_is_aiming = false
@@ -132,6 +159,7 @@ func _handle_iframes(delta: float) -> void:
func _do_kick() -> void:
kick_timer = kick_cooldown
_play_kick_blend()
var forward := -global_transform.basis.z
forward.y = 0.0
forward = forward.normalized() if forward.length() > 0.01 else Vector3(0.0, 0.0, -1.0)
@@ -147,9 +175,9 @@ func _do_kick() -> void:
var diff := en.global_position - global_position
diff.y = 0.0
var dist := diff.length()
if dist < 0.1 or dist > kick_range:
if dist < 0.01 or dist > kick_range:
continue
if (diff / dist).dot(forward) >= half_cos:
if dist < 1.0 or (diff / dist).dot(forward) >= half_cos:
candidates.append(en)
candidate_dists.append(dist)
@@ -165,10 +193,12 @@ func _do_kick() -> void:
var best_diff := best.global_position - global_position
best_diff.y = 0.0
var best_dir := best_diff.normalized()
var obj_tier: int = best.get("tier") if best.get("tier") != null else 0
var diff_tier := tier - obj_tier
var obj_toughness: int = best.get("toughness_tier") if best.get("toughness_tier") != null else 0
var diff_tier := kick_tier - obj_toughness
var force: float
if diff_tier < 0:
if GameSettings.difficulty == "immortal":
force = 50.0
elif diff_tier < 0:
force = 15.0
elif diff_tier == 0:
force = 50.0
@@ -177,6 +207,7 @@ func _do_kick() -> void:
else:
force = 80.0
best.call("receive_kick", best_dir, force)
FX.hit_spark(best.global_position + Vector3(0, 0.4, 0), get_parent())
_squish_effect()
func _try_interact() -> void:
@@ -197,6 +228,14 @@ func set_aim_direction(yaw_rad: float) -> void:
_aim_yaw = yaw_rad
_is_aiming = true
func _play_kick_blend() -> void:
var tw := create_tween().set_parallel(true)
tw.tween_method(func(v: float): mesh_node.set_blend_shape_value(0, v), 0.0, 1.0, 0.12)
tw.tween_method(func(v: float): mesh_node_boot.set_blend_shape_value(0, v), 0.0, 1.0, 0.12)
tw.chain()
tw.tween_method(func(v: float): mesh_node.set_blend_shape_value(0, v), 1.0, 0.0, 0.28)
tw.tween_method(func(v: float): mesh_node_boot.set_blend_shape_value(0, v), 1.0, 0.0, 0.28)
func _squish_effect() -> void:
var tw := create_tween()
tw.tween_property(mesh_node, "scale", Vector3(1.3, 0.55, 1.3), 0.07)
@@ -208,18 +247,22 @@ func receive_kick(direction: Vector3, force: float) -> void:
velocity.x = direction.x * force
velocity.z = direction.z * force
invincible_timer = IFRAMES_DURATION * 0.5
_squish_effect()
func take_damage(amount: int) -> void:
func take_damage(amount: int, attacker_toughness: int = 0) -> void:
if GameSettings.difficulty == "immortal":
return
if not is_alive or invincible_timer > 0.0:
return
invincible_timer = IFRAMES_DURATION
#health = max(0, health - amount)
#emit_signal("health_changed", health, max_health)
#var tw := create_tween()
#tw.tween_property(player_mat, "albedo_color", Color.RED, 0.08)
#tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.25)
#if health <= 0:
#_die()
if is_shielding and shield_tier > 0:
var diff := shield_tier - attacker_toughness
var mod: float = 0.15 if diff >= 2 else (0.30 if diff == 1 else 0.50)
amount = int(amount * mod)
health = min(health - amount, max_health)
emit_signal("health_changed", health, max_health)
_squish_effect()
func heal(amount: int) -> void:
if not is_alive:
@@ -250,20 +293,47 @@ func apply_upgrade(id: String) -> void:
emit_signal("health_changed", health, max_health)
func apply_upgrade_boots(speed_bonus: float, _tier: int) -> void:
tier += _tier
kick_tier += 1
move_speed += speed_bonus
var tw := create_tween()
tw.tween_property(player_mat, "albedo_color", Color(1.0, 0.85, 0.2), 0.1)
tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.4)
_apply_boot_mesh(kick_tier)
func apply_upgrade_armor() -> void:
tier += 1
var tw := create_tween()
tw.tween_property(player_mat, "albedo_color", Color(0.7, 0.8, 1.0), 0.1)
tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.5)
kick_tier += 1
func apply_upgrade_enchant() -> void:
tier += 1
var tw := create_tween()
tw.tween_property(player_mat, "albedo_color", Color(0.8, 0.2, 1.0), 0.1)
tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.6)
kick_tier += 1
func apply_stick_armor() -> bool:
if has_stick_armor:
return false
has_stick_armor = true
toughness_tier += 1
return true
func apply_leather_armor() -> bool:
if has_leather_armor:
return false
has_leather_armor = true
toughness_tier += 1
return true
func apply_plate_armor() -> bool:
if has_plate_armor:
return false
has_plate_armor = true
toughness_tier += 1
return true
func apply_wooden_shield() -> bool:
if has_wooden_shield:
return false
has_wooden_shield = true
shield_tier = max(shield_tier, 1)
return true
func apply_iron_shield() -> bool:
if has_iron_shield:
return false
has_iron_shield = true
shield_tier = max(shield_tier, 2)
return true

Some files were not shown because too many files have changed in this diff Show More