Compare commits
45 Commits
main
...
31cab204ad
| Author | SHA1 | Date | |
|---|---|---|---|
| 31cab204ad | |||
| 3a3edc54a4 | |||
| 05f46021b8 | |||
| 5f589c8c89 | |||
| c8aba822bf | |||
| 23177b9079 | |||
| 86b837dded | |||
| a835ae5755 | |||
| d20360c8f3 | |||
| fb3b653604 | |||
| 6b7294dfd8 | |||
| 82af31501d | |||
| 0d9890c370 | |||
| d36a2cf9ec | |||
| e185d2e1fd | |||
| 7d6d96e499 | |||
| 3c2afefc95 | |||
| 34a9b6b18f | |||
| 9acbc49084 | |||
| 3542c328c0 | |||
| f37c27887e | |||
| 20eaa513c3 | |||
| 3974d7416d | |||
| 5d843f94f7 | |||
| 8e7ff9ae83 | |||
| d5194139e8 | |||
| 7b355c5d0b | |||
| af15c477b9 | |||
| dce433e068 | |||
| 5d9b0ce738 | |||
| 5f61c26563 | |||
| 65ba9d2960 | |||
| f6f451cffb | |||
| 271c99ae13 | |||
| dde4a6431e | |||
| d7368e7fa7 | |||
| 9981ed1ae3 | |||
| e956c4353c | |||
| 1b3732ea0f | |||
| 52d0b00655 | |||
| c9489321ae | |||
| bec9389bb8 | |||
| c7f0d9e176 | |||
| 7beb9ffbac | |||
| cdb0ffd6a5 |
|
After Width: | Height: | Size: 230 KiB |
@@ -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
|
||||||
|
After Width: | Height: | Size: 424 KiB |
@@ -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
|
||||||
|
After Width: | Height: | Size: 177 KiB |
@@ -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
|
||||||
|
After Width: | Height: | Size: 405 KiB |
@@ -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
|
||||||
|
After Width: | Height: | Size: 324 KiB |
@@ -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
|
||||||
|
After Width: | Height: | Size: 56 KiB |
@@ -0,0 +1,40 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://baeea1yfs0cnn"
|
||||||
|
path="res://.godot/imported/Tutorial_shield.jpeg-d9b563c9ca34dc1a19e82a0ec964c1b9.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/Tutorial_shield.jpeg"
|
||||||
|
dest_files=["res://.godot/imported/Tutorial_shield.jpeg-d9b563c9ca34dc1a19e82a0ec964c1b9.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
|
||||||
|
After Width: | Height: | Size: 231 KiB |
@@ -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
|
||||||
@@ -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
|
||||||
|
After Width: | Height: | Size: 43 KiB |
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
After Width: | Height: | Size: 115 KiB |
@@ -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
|
||||||
|
After Width: | Height: | Size: 126 KiB |
@@ -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
|
||||||
|
After Width: | Height: | Size: 120 KiB |
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
After Width: | Height: | Size: 72 KiB |
@@ -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
|
||||||
@@ -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
|
||||||
|
After Width: | Height: | Size: 107 KiB |
@@ -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
|
||||||
@@ -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
|
||||||
|
After Width: | Height: | Size: 117 KiB |
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
After Width: | Height: | Size: 273 KiB |
@@ -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
|
||||||
@@ -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
|
|
||||||
@@ -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}'"
|
||||||
@@ -15,6 +15,6 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="KickSurvivors"
|
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/features=PackedStringArray("4.6", "Forward Plus")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|||||||
@@ -1,29 +1,26 @@
|
|||||||
[gd_scene format=3 uid="uid://cayybawvw26cm"]
|
[gd_scene format=3 uid="uid://cayybawvw26cm"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://scripts/EnchantedSphere.gd" id="1_sphere"]
|
[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"]
|
||||||
[sub_resource type="SphereMesh" id="SphereMesh_1"]
|
[ext_resource type="ArrayMesh" uid="uid://jls6i8ov73ld" path="res://assets/boot.obj" id="3_d6vog"]
|
||||||
radius = 0.28
|
|
||||||
height = 0.56
|
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
|
[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_enabled = true
|
||||||
emission = Color(0.6, 0.1, 1.0, 1)
|
emission = Color(0.6, 0.1, 1, 1)
|
||||||
emission_energy_multiplier = 3.0
|
emission_energy_multiplier = 3.0
|
||||||
|
|
||||||
[node name="EnchantedSphere" type="Node3D"]
|
[node name="EnchantedSphere" type="Node3D" unique_id=879211768]
|
||||||
script = ExtResource("1_sphere")
|
script = ExtResource("1_sphere")
|
||||||
|
|
||||||
[node name="SphereMesh" type="MeshInstance3D" parent="."]
|
[node name="SphereMesh" type="MeshInstance3D" parent="." unique_id=905498826]
|
||||||
mesh = SubResource("SphereMesh_1")
|
|
||||||
material_override = SubResource("StandardMaterial3D_1")
|
material_override = SubResource("StandardMaterial3D_1")
|
||||||
|
mesh = ExtResource("3_d6vog")
|
||||||
|
|
||||||
[node name="Tooltip" type="Label3D" parent="."]
|
[node name="Tooltip" type="Label3D" parent="." unique_id=947504755]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3280884, 0)
|
||||||
billboard = 1
|
billboard = 1
|
||||||
double_sided = true
|
text = "[E] Enchanted Boots
|
||||||
text = "[E] Enchanted Sphere
|
|
||||||
+1 Tier"
|
+1 Tier"
|
||||||
font_size = 32
|
font_size = 56
|
||||||
outline_size = 6
|
outline_size = 6
|
||||||
|
|||||||
@@ -1,22 +1,47 @@
|
|||||||
[gd_scene format=3 uid="uid://cxk2mn5oab341"]
|
[gd_scene format=3 uid="uid://cxk2mn5oab341"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ujlvt8u71hg1" path="res://scripts/Enemy.gd" id="1_enemy"]
|
[ext_resource type="Script" uid="uid://ujlvt8u71hg1" path="res://scripts/Enemy.gd" id="1_enemy"]
|
||||||
[ext_resource type="ArrayMesh" uid="uid://dw74ofxlfq4tq" path="res://assets/gnome.obj" id="2_55jtl"]
|
[ext_resource type="Texture2D" uid="uid://cu3g76pfo5msw" path="res://assets/gnome1.png" id="2_mpr68"]
|
||||||
|
[ext_resource type="ArrayMesh" uid="uid://bwoh5cyhk1tvx" path="res://assets/gnome1.obj" id="3_ft8do"]
|
||||||
|
[ext_resource type="ArrayMesh" uid="uid://dx4huc0nh1b4u" path="res://assets/gnome2.obj" id="4_iwav8"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://5l5wflgoofrd" path="res://assets/gnome2.png" id="5_1i2q2"]
|
||||||
|
[ext_resource type="ArrayMesh" uid="uid://dkxr5amwv7i0p" path="res://assets/gnome3.obj" id="6_ly5gv"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://baqjuo2utnor2" path="res://assets/gnome3.png" id="7_82o86"]
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
|
||||||
albedo_color = Color(1, 0.28, 0.18, 1)
|
albedo_texture = ExtResource("2_mpr68")
|
||||||
roughness = 0.8
|
roughness = 0.8
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_1"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_1"]
|
||||||
size = Vector3(0.85, 0.85, 0.85)
|
size = Vector3(0.85, 0.85, 0.85)
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1gqeq"]
|
||||||
|
albedo_texture = ExtResource("5_1i2q2")
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_isvm2"]
|
||||||
|
albedo_texture = ExtResource("7_82o86")
|
||||||
|
|
||||||
[node name="Enemy" type="CharacterBody3D" unique_id=1639801124]
|
[node name="Enemy" type="CharacterBody3D" unique_id=1639801124]
|
||||||
script = ExtResource("1_enemy")
|
script = ExtResource("1_enemy")
|
||||||
|
|
||||||
[node name="BodyMesh" type="MeshInstance3D" parent="." unique_id=68242945]
|
[node name="BodyMesh" type="MeshInstance3D" parent="." unique_id=68242945]
|
||||||
material_override = SubResource("StandardMaterial3D_1")
|
material_override = SubResource("StandardMaterial3D_1")
|
||||||
mesh = ExtResource("2_55jtl")
|
mesh = ExtResource("3_ft8do")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=379819225]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=379819225]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.425, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.425, 0)
|
||||||
shape = SubResource("BoxShape3D_1")
|
shape = SubResource("BoxShape3D_1")
|
||||||
|
|
||||||
|
[node name="BodyMesh1" type="MeshInstance3D" parent="." unique_id=7037801]
|
||||||
|
visible = false
|
||||||
|
material_override = SubResource("StandardMaterial3D_1")
|
||||||
|
mesh = ExtResource("4_iwav8")
|
||||||
|
skeleton = NodePath("../BodyMesh")
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_1gqeq")
|
||||||
|
|
||||||
|
[node name="BodyMesh2" type="MeshInstance3D" parent="." unique_id=299444928]
|
||||||
|
visible = false
|
||||||
|
material_override = SubResource("StandardMaterial3D_1")
|
||||||
|
mesh = ExtResource("6_ly5gv")
|
||||||
|
skeleton = NodePath("../BodyMesh1")
|
||||||
|
surface_material_override/0 = SubResource("StandardMaterial3D_isvm2")
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
[gd_scene format=3 uid="uid://g7iron5etp8u"]
|
[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="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"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
|
||||||
albedo_color = Color(0.55, 0.58, 0.62, 1)
|
albedo_color = Color(0.55, 0.58, 0.62, 1)
|
||||||
@@ -8,20 +9,17 @@ metallic = 0.7
|
|||||||
metallic_specular = 0.8
|
metallic_specular = 0.8
|
||||||
roughness = 0.4
|
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"]
|
[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]
|
[node name="Iron" type="CharacterBody3D" unique_id=611454609]
|
||||||
script = ExtResource("1_iron")
|
script = ExtResource("1_iron")
|
||||||
|
|
||||||
[node name="IronMesh" type="MeshInstance3D" parent="." unique_id=1832879739]
|
[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")
|
material_override = SubResource("StandardMaterial3D_1")
|
||||||
mesh = SubResource("BoxMesh_1")
|
mesh = ExtResource("2_53umh")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=665808333]
|
[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")
|
shape = SubResource("BoxShape3D_1")
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -1,25 +1,23 @@
|
|||||||
[gd_scene format=3 uid="uid://d4leath8bvq2r"]
|
[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="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"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
|
||||||
albedo_color = Color(0.62, 0.38, 0.2, 1)
|
albedo_color = Color(0.62, 0.38, 0.2, 1)
|
||||||
roughness = 0.85
|
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"]
|
[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]
|
[node name="Leather" type="CharacterBody3D" unique_id=267529517]
|
||||||
script = ExtResource("1_leather")
|
script = ExtResource("1_leather")
|
||||||
|
|
||||||
[node name="LeatherMesh" type="MeshInstance3D" parent="." unique_id=2045837180]
|
[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")
|
material_override = SubResource("StandardMaterial3D_1")
|
||||||
mesh = SubResource("BoxMesh_1")
|
mesh = ExtResource("2_b7gx8")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1940111930]
|
[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")
|
shape = SubResource("BoxShape3D_1")
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -1,27 +1,25 @@
|
|||||||
[gd_scene format=3 uid="uid://cbvs3rvwslsd2"]
|
[gd_scene format=3 uid="uid://cbvs3rvwslsd2"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://scripts/LeatherBoots.gd" id="1_boots"]
|
[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"]
|
||||||
[sub_resource type="BoxMesh" id="BoxMesh_1"]
|
[ext_resource type="ArrayMesh" uid="uid://jls6i8ov73ld" path="res://assets/boot.obj" id="3_7iwdw"]
|
||||||
size = Vector3(0.4, 0.2, 0.55)
|
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
|
||||||
albedo_color = Color(0.45, 0.25, 0.10, 1)
|
albedo_color = Color(0.45, 0.25, 0.1, 1)
|
||||||
roughness = 0.8
|
albedo_texture = ExtResource("2_ky34n")
|
||||||
metallic = 0.1
|
metallic = 0.1
|
||||||
|
roughness = 0.8
|
||||||
|
|
||||||
[node name="LeatherBoots" type="Node3D"]
|
[node name="LeatherBoots" type="Node3D" unique_id=2009442467]
|
||||||
script = ExtResource("1_boots")
|
script = ExtResource("1_boots")
|
||||||
|
|
||||||
[node name="BootsMesh" type="MeshInstance3D" parent="."]
|
[node name="BootsMesh" type="MeshInstance3D" parent="." unique_id=1801555312]
|
||||||
mesh = SubResource("BoxMesh_1")
|
|
||||||
material_override = SubResource("StandardMaterial3D_1")
|
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)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8, 0)
|
||||||
billboard = 1
|
billboard = 1
|
||||||
double_sided = true
|
|
||||||
text = "[E] Leather Boots
|
text = "[E] Leather Boots
|
||||||
+10 Move Speed"
|
+10 Move Speed"
|
||||||
font_size = 32
|
|
||||||
outline_size = 6
|
outline_size = 6
|
||||||
|
|||||||
@@ -78,21 +78,21 @@ size = Vector3(0.6, 1, 0.6)
|
|||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_forge"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_forge"]
|
||||||
size = Vector3(2, 1.8, 2)
|
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"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_etable"]
|
||||||
albedo_color = Color(0.12, 0.08, 0.22, 1)
|
albedo_color = Color(0.12, 0.08, 0.22, 1)
|
||||||
roughness = 0.6
|
|
||||||
metallic = 0.2
|
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"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ebook"]
|
||||||
albedo_color = Color(0.55, 0.08, 0.08, 1)
|
albedo_color = Color(0.55, 0.08, 0.08, 1)
|
||||||
roughness = 0.9
|
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"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_etable"]
|
||||||
size = Vector3(1.4, 0.9, 1.4)
|
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]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Forge" unique_id=726531191]
|
||||||
shape = SubResource("BoxShape3D_forge")
|
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)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -8, 0.45, -8)
|
||||||
metadata/is_enchanting_table = true
|
metadata/is_enchanting_table = true
|
||||||
|
|
||||||
[node name="TableMesh" type="MeshInstance3D" parent="EnchantingTable"]
|
[node name="TableMesh" type="MeshInstance3D" parent="EnchantingTable" unique_id=1719378953]
|
||||||
mesh = SubResource("BoxMesh_etable")
|
|
||||||
material_override = SubResource("StandardMaterial3D_etable")
|
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)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.51, 0)
|
||||||
mesh = SubResource("BoxMesh_ebook")
|
|
||||||
material_override = SubResource("StandardMaterial3D_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")
|
shape = SubResource("BoxShape3D_etable")
|
||||||
|
|||||||
@@ -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")
|
||||||
@@ -1,28 +1,28 @@
|
|||||||
[gd_scene format=3 uid="uid://h8armor4fura"]
|
[gd_scene format=3 uid="uid://h8armor4fura"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://scripts/MetalArmor.gd" id="1_armor"]
|
[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"]
|
||||||
[sub_resource type="BoxMesh" id="BoxMesh_1"]
|
[ext_resource type="ArrayMesh" uid="uid://caurrbclp30ly" path="res://assets/armor.obj" id="3_ocond"]
|
||||||
size = Vector3(0.55, 0.7, 0.25)
|
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
|
||||||
albedo_color = Color(0.55, 0.60, 0.68, 1)
|
albedo_color = Color(0.55, 0.6, 0.68, 1)
|
||||||
roughness = 0.3
|
albedo_texture = ExtResource("2_ocond")
|
||||||
metallic = 0.85
|
metallic = 0.85
|
||||||
metallic_specular = 1.0
|
metallic_specular = 1.0
|
||||||
|
roughness = 0.3
|
||||||
|
|
||||||
[node name="MetalArmor" type="Node3D"]
|
[node name="MetalArmor" type="Node3D" unique_id=1379243712]
|
||||||
script = ExtResource("1_armor")
|
script = ExtResource("1_armor")
|
||||||
|
|
||||||
[node name="ArmorMesh" type="MeshInstance3D" parent="."]
|
[node name="ArmorMesh" type="MeshInstance3D" parent="." unique_id=1340618559]
|
||||||
mesh = SubResource("BoxMesh_1")
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.3499111, 0)
|
||||||
material_override = SubResource("StandardMaterial3D_1")
|
material_override = SubResource("StandardMaterial3D_1")
|
||||||
|
mesh = ExtResource("3_ocond")
|
||||||
|
|
||||||
[node name="Tooltip" type="Label3D" parent="."]
|
[node name="Tooltip" type="Label3D" parent="." unique_id=748491675]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.9431921, 0)
|
||||||
billboard = 1
|
billboard = 1
|
||||||
double_sided = true
|
|
||||||
text = "[E] Metal Armor
|
text = "[E] Metal Armor
|
||||||
+1 Tier"
|
+1 Tier"
|
||||||
font_size = 32
|
font_size = 56
|
||||||
outline_size = 6
|
outline_size = 6
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -8,16 +8,16 @@ albedo_color = Color(0.45, 0.38, 0.3, 1)
|
|||||||
metallic = 0.05
|
metallic = 0.05
|
||||||
|
|
||||||
[sub_resource type="SphereShape3D" id="SphereShape3D_1"]
|
[sub_resource type="SphereShape3D" id="SphereShape3D_1"]
|
||||||
radius = 0.25
|
radius = 0.40034008
|
||||||
|
|
||||||
[node name="Rock" type="CharacterBody3D" unique_id=1267213194]
|
[node name="Rock" type="CharacterBody3D" unique_id=1267213194]
|
||||||
script = ExtResource("1_rock")
|
script = ExtResource("1_rock")
|
||||||
|
|
||||||
[node name="RockMesh" type="MeshInstance3D" parent="." unique_id=918783711]
|
[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")
|
material_override = SubResource("StandardMaterial3D_1")
|
||||||
mesh = ExtResource("2_wmx41")
|
mesh = ExtResource("2_wmx41")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=2017780451]
|
[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")
|
shape = SubResource("SphereShape3D_1")
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ albedo_color = Color(0.55, 0.38, 0.18, 1)
|
|||||||
roughness = 0.95
|
roughness = 0.95
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1"]
|
||||||
radius = 0.07
|
radius = 0.15673828
|
||||||
height = 0.65
|
height = 1.6220214
|
||||||
|
|
||||||
[node name="Stick" type="CharacterBody3D" unique_id=1893805391]
|
[node name="Stick" type="CharacterBody3D" unique_id=1893805391]
|
||||||
script = ExtResource("1_stick")
|
script = ExtResource("1_stick")
|
||||||
|
|
||||||
[node name="StickMesh" type="MeshInstance3D" parent="." unique_id=1850002866]
|
[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")
|
material_override = SubResource("StandardMaterial3D_1")
|
||||||
mesh = ExtResource("2_urm7b")
|
mesh = ExtResource("2_urm7b")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=653008437]
|
[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")
|
shape = SubResource("CapsuleShape3D_1")
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -10,7 +10,8 @@ const WALL_BOUNCE := 0.4
|
|||||||
const WALL_SELF_DMG := 0.4
|
const WALL_SELF_DMG := 0.4
|
||||||
|
|
||||||
var kickable_type: String = "boulder"
|
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 state: State = State.IDLE
|
||||||
var fly_vel: Vector3 = Vector3.ZERO
|
var fly_vel: Vector3 = Vector3.ZERO
|
||||||
var health: float = 150.0
|
var health: float = 150.0
|
||||||
@@ -19,6 +20,7 @@ var damage_modifier: float = 1.8
|
|||||||
|
|
||||||
@onready var mesh_node: MeshInstance3D = $BoulderMesh
|
@onready var mesh_node: MeshInstance3D = $BoulderMesh
|
||||||
var boulder_mat: StandardMaterial3D
|
var boulder_mat: StandardMaterial3D
|
||||||
|
var _tooltip: Label3D
|
||||||
|
|
||||||
const COLOR_IDLE := Color(0.32, 0.28, 0.22)
|
const COLOR_IDLE := Color(0.32, 0.28, 0.22)
|
||||||
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
|
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
|
||||||
@@ -27,6 +29,23 @@ func _ready() -> void:
|
|||||||
add_to_group("kickable")
|
add_to_group("kickable")
|
||||||
boulder_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
boulder_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
||||||
mesh_node.material_override = boulder_mat
|
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:
|
func apply_collision_damage(dmg: float) -> void:
|
||||||
_take_damage(dmg)
|
_take_damage(dmg)
|
||||||
@@ -64,7 +83,7 @@ func _fly(delta: float) -> void:
|
|||||||
handled = true
|
handled = true
|
||||||
break
|
break
|
||||||
elif col3d.is_in_group("player"):
|
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
|
fly_vel *= 0.3
|
||||||
handled = true
|
handled = true
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ static var first_iron_spawned: bool = false
|
|||||||
static var first_essence_spawned: bool = false
|
static var first_essence_spawned: bool = false
|
||||||
|
|
||||||
var kickable_type: String = ""
|
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 move_speed: float = 3.0
|
||||||
var health: int = 30
|
var health: int = 30
|
||||||
var damage_to_player: int = 8
|
var damage_to_player: int = 8
|
||||||
@@ -44,7 +45,11 @@ var merge_partner: Node = null
|
|||||||
var is_upgrading: bool = false
|
var is_upgrading: bool = false
|
||||||
|
|
||||||
@onready var mesh_node: MeshInstance3D = $BodyMesh
|
@onready var mesh_node: MeshInstance3D = $BodyMesh
|
||||||
|
#@onready var mesh_node1: MeshInstance3D = $BodyMesh1
|
||||||
|
#@onready var mesh_node2: MeshInstance3D = $BodyMesh2
|
||||||
var mat: StandardMaterial3D
|
var mat: StandardMaterial3D
|
||||||
|
var type_label: Label3D
|
||||||
|
|
||||||
|
|
||||||
var COLOR_CHASE = Color(1.0, 0.28, 0.18)
|
var COLOR_CHASE = Color(1.0, 0.28, 0.18)
|
||||||
var COLOR_FLY = Color(1.0, 0.85, 0.1)
|
var COLOR_FLY = Color(1.0, 0.85, 0.1)
|
||||||
@@ -54,10 +59,28 @@ const CONTACT_CD = 0.7
|
|||||||
const AIR_FRICTION = 0.86
|
const AIR_FRICTION = 0.86
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
process_mode = Node.PROCESS_MODE_PAUSABLE
|
||||||
add_to_group("enemies")
|
add_to_group("enemies")
|
||||||
mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
||||||
mesh_node.material_override = mat
|
mesh_node.material_override = mat
|
||||||
|
#mesh_node1.set_visible(false)
|
||||||
|
#mesh_node2.set_visible(false)
|
||||||
COLOR_CHASE = mat.albedo_color
|
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:
|
func setup(type: String, wave: int) -> void:
|
||||||
enemy_type = type
|
enemy_type = type
|
||||||
@@ -66,31 +89,53 @@ func setup(type: String, wave: int) -> void:
|
|||||||
match type:
|
match type:
|
||||||
"slime":
|
"slime":
|
||||||
move_speed = 2.8 + wave * 0.12
|
move_speed = 2.8 + wave * 0.12
|
||||||
health = 28 + wave * 4
|
health = 40 + wave * 4
|
||||||
score_value = 10
|
score_value = 10
|
||||||
damage_to_player = 8
|
damage_to_player = 8
|
||||||
enemy_level = 1
|
enemy_level = 1
|
||||||
"bat":
|
"bat":
|
||||||
move_speed = 5.5 + wave * 0.15
|
move_speed = 5 + wave * 0.15
|
||||||
health = 14 + wave * 2
|
health = 100 + wave * 2
|
||||||
score_value = 15
|
score_value = 20
|
||||||
damage_to_player = 6
|
damage_to_player = 6
|
||||||
base_scale = 0.7
|
base_scale = 0.7
|
||||||
mesh_node.scale = Vector3(0.7, 0.7, 0.7)
|
mesh_node.scale = Vector3(0.7, 0.7, 0.7)
|
||||||
COLOR_CHASE = Color(0.6, 0.2, 0.8)
|
COLOR_CHASE = Color(0.6, 0.2, 0.8)
|
||||||
mat.albedo_color = COLOR_CHASE
|
mat.albedo_color = COLOR_CHASE
|
||||||
enemy_level = 2
|
enemy_level = 2
|
||||||
|
#mesh_node.set_visible(false)
|
||||||
|
#mesh_node1.set_visible(true)
|
||||||
"ogre":
|
"ogre":
|
||||||
move_speed = 1.8 + wave * 0.08
|
move_speed = 3 + wave * 0.08
|
||||||
health = 80 + wave * 12
|
health = 200 + wave * 12
|
||||||
score_value = 25
|
score_value = 50
|
||||||
damage_to_player = 18
|
damage_to_player = 18
|
||||||
base_scale = 1.5
|
base_scale = 1.5
|
||||||
mesh_node.scale = Vector3(1.5, 1.5, 1.5)
|
mesh_node.scale = Vector3(1.5, 1.5, 1.5)
|
||||||
COLOR_CHASE = Color(0.3, 0.7, 0.3)
|
COLOR_CHASE = Color(0.3, 0.7, 0.3)
|
||||||
mat.albedo_color = COLOR_CHASE
|
mat.albedo_color = COLOR_CHASE
|
||||||
enemy_level = 3
|
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:
|
func _physics_process(delta: float) -> void:
|
||||||
match state:
|
match state:
|
||||||
@@ -112,13 +157,31 @@ func _chase(delta: float) -> void:
|
|||||||
contact_timer = CONTACT_CD
|
contact_timer = CONTACT_CD
|
||||||
if target.has_method("take_damage"):
|
if target.has_method("take_damage"):
|
||||||
target.take_damage(damage_to_player)
|
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:
|
if enemy_kick_timer <= 0.0:
|
||||||
_try_enemy_kick()
|
_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:
|
if dist > 0.05:
|
||||||
var dir := diff.normalized()
|
var dir := diff.normalized()
|
||||||
velocity.x = dir.x * move_speed
|
var move_dir := (dir + sep * 0.6).normalized()
|
||||||
velocity.z = dir.z * move_speed
|
velocity.x = move_dir.x * move_speed
|
||||||
rotation.y = lerp_angle(rotation.y, atan2(dir.x, dir.z), 8.0 * delta)
|
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
|
velocity.y = 0.0
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
|
|
||||||
@@ -138,25 +201,31 @@ func _try_enemy_kick() -> void:
|
|||||||
var k := node as Node3D
|
var k := node as Node3D
|
||||||
if k == null or not is_instance_valid(k):
|
if k == null or not is_instance_valid(k):
|
||||||
continue
|
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)
|
var d := (k.global_position - global_position)
|
||||||
d.y = 0.0
|
d.y = 0.0
|
||||||
if d.length() < nearest_dist:
|
if d.length() < nearest_dist:
|
||||||
nearest_dist = d.length()
|
nearest_dist = d.length()
|
||||||
nearest_kickable = k
|
nearest_kickable = k
|
||||||
if nearest_kickable != null:
|
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
|
kickable_kick_timer = KICKABLE_KICK_COOLDOWN
|
||||||
return
|
return
|
||||||
|
|
||||||
# 2. Kick lower-tier enemy nearest to player direction
|
# 2. Kick lower-toughness enemy nearest to player direction
|
||||||
if tier > 0:
|
if kick_tier > 0:
|
||||||
var nearest_enemy: Node3D = null
|
var nearest_enemy: Node3D = null
|
||||||
var nearest_enemy_dist := ENEMY_KICK_RANGE
|
var nearest_enemy_dist := ENEMY_KICK_RANGE
|
||||||
for node in get_tree().get_nodes_in_group("enemies"):
|
for node in get_tree().get_nodes_in_group("enemies"):
|
||||||
var en := node as Node3D
|
var en := node as Node3D
|
||||||
if en == null or en == self or not is_instance_valid(en):
|
if en == null or en == self or not is_instance_valid(en):
|
||||||
continue
|
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
|
continue
|
||||||
var d := (en.global_position - global_position)
|
var d := (en.global_position - global_position)
|
||||||
d.y = 0.0
|
d.y = 0.0
|
||||||
@@ -164,15 +233,19 @@ func _try_enemy_kick() -> void:
|
|||||||
nearest_enemy_dist = d.length()
|
nearest_enemy_dist = d.length()
|
||||||
nearest_enemy = en
|
nearest_enemy = en
|
||||||
if nearest_enemy != null:
|
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
|
enemy_kick_timer = ENEMY_KICK_COOLDOWN
|
||||||
return
|
return
|
||||||
|
|
||||||
# 3. Kick player directly if lower tier and in range
|
# 3. Kick player directly if lower toughness and in range
|
||||||
if tier > 0 and to_player.length() < ENEMY_KICK_RANGE:
|
#if kick_tier > 0 and to_player.length() < ENEMY_KICK_RANGE:
|
||||||
var player_tier: int = target.get("tier") if target.get("tier") != null else 0
|
if to_player.length() < ENEMY_KICK_RANGE:
|
||||||
if player_tier < tier:
|
var player_toughness: int = target.get("toughness_tier") if target.get("toughness_tier") != null else 0
|
||||||
target.call("receive_kick", kick_dir, 35.0 + tier * 8.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
|
enemy_kick_timer = ENEMY_KICK_COOLDOWN
|
||||||
|
|
||||||
func _fly(delta: float) -> void:
|
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_property(other, "global_position", global_position, 0.2)
|
||||||
tw.tween_callback(_on_merge_complete)
|
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:
|
func _on_merge_complete() -> void:
|
||||||
var merge_pos := global_position
|
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_level: int = enemy_level + 1
|
||||||
var new_wave: int = wave_num
|
var new_wave: int = wave_num
|
||||||
|
var par := get_parent()
|
||||||
if is_instance_valid(merge_partner):
|
if is_instance_valid(merge_partner):
|
||||||
merge_pos = (global_position + merge_partner.global_position) / 2.0
|
merge_pos = (global_position + merge_partner.global_position) / 2.0
|
||||||
merge_partner.queue_free()
|
merge_partner.queue_free()
|
||||||
|
FX.merge_smoke(merge_pos + Vector3(0, 0.3, 0), par)
|
||||||
queue_free()
|
queue_free()
|
||||||
emit_signal("merged", true)
|
emit_signal("merged", true)
|
||||||
var tree := get_tree()
|
var tree := get_tree()
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ const WALL_BOUNCE := 0.6
|
|||||||
const WALL_SELF_DMG := 0.0
|
const WALL_SELF_DMG := 0.0
|
||||||
|
|
||||||
var kickable_type: String = "essence"
|
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 state: State = State.IDLE
|
||||||
var fly_vel: Vector3 = Vector3.ZERO
|
var fly_vel: Vector3 = Vector3.ZERO
|
||||||
var health: float = 999.0
|
var health: float = 999.0
|
||||||
@@ -21,6 +22,7 @@ var damage_modifier: float = 0.0
|
|||||||
|
|
||||||
@onready var mesh_node: MeshInstance3D = $EssenceMesh
|
@onready var mesh_node: MeshInstance3D = $EssenceMesh
|
||||||
var essence_mat: StandardMaterial3D
|
var essence_mat: StandardMaterial3D
|
||||||
|
var _tooltip: Label3D
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
add_to_group("kickable")
|
add_to_group("kickable")
|
||||||
@@ -29,6 +31,23 @@ func _ready() -> void:
|
|||||||
var tw := create_tween().set_loops()
|
var tw := create_tween().set_loops()
|
||||||
tw.tween_property(self, "position:y", 0.35, 0.6)
|
tw.tween_property(self, "position:y", 0.35, 0.6)
|
||||||
tw.tween_property(self, "position:y", 0.15, 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:
|
func apply_collision_damage(_dmg: float) -> void:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dqx8r64rkj7j
|
||||||
@@ -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
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://deu62njwuhjd3
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
extends CharacterBody3D
|
extends CharacterBody3D
|
||||||
|
|
||||||
const METAL_ARMOR_SCENE := preload("res://scenes/MetalArmor.tscn")
|
const METAL_PLATE_SCENE := preload("res://scenes/MetalPlate.tscn")
|
||||||
|
|
||||||
signal destroyed
|
signal destroyed
|
||||||
|
|
||||||
@@ -12,15 +12,17 @@ const WALL_BOUNCE := 0.45
|
|||||||
const WALL_SELF_DMG := 0.5
|
const WALL_SELF_DMG := 0.5
|
||||||
|
|
||||||
var kickable_type: String = "iron"
|
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 state: State = State.IDLE
|
||||||
var fly_vel: Vector3 = Vector3.ZERO
|
var fly_vel: Vector3 = Vector3.ZERO
|
||||||
var health: float = 80.0
|
var health: float = 400.0
|
||||||
var dead: bool = false
|
var dead: bool = false
|
||||||
var damage_modifier: float = 0.9
|
var damage_modifier: float = 0.9
|
||||||
|
|
||||||
@onready var mesh_node: MeshInstance3D = $IronMesh
|
@onready var mesh_node: MeshInstance3D = $IronMesh
|
||||||
var iron_mat: StandardMaterial3D
|
var iron_mat: StandardMaterial3D
|
||||||
|
var _tooltip: Label3D
|
||||||
|
|
||||||
const COLOR_IDLE := Color(0.55, 0.58, 0.62)
|
const COLOR_IDLE := Color(0.55, 0.58, 0.62)
|
||||||
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
|
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
|
||||||
@@ -29,6 +31,23 @@ func _ready() -> void:
|
|||||||
add_to_group("kickable")
|
add_to_group("kickable")
|
||||||
iron_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
iron_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
||||||
mesh_node.material_override = iron_mat
|
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:
|
func apply_collision_damage(dmg: float) -> void:
|
||||||
_take_damage(dmg)
|
_take_damage(dmg)
|
||||||
@@ -69,7 +88,7 @@ func _fly(delta: float) -> void:
|
|||||||
handled = true
|
handled = true
|
||||||
break
|
break
|
||||||
elif col3d.is_in_group("player"):
|
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
|
fly_vel *= 0.3
|
||||||
handled = true
|
handled = true
|
||||||
break
|
break
|
||||||
@@ -110,7 +129,7 @@ func _hit_forge(forge: Node3D) -> void:
|
|||||||
queue_free()
|
queue_free()
|
||||||
if parent == null:
|
if parent == null:
|
||||||
return
|
return
|
||||||
var armor := METAL_ARMOR_SCENE.instantiate() as Node3D
|
var armor := METAL_PLATE_SCENE.instantiate() as Node3D
|
||||||
parent.add_child(armor)
|
parent.add_child(armor)
|
||||||
armor.global_position = spawn_pos
|
armor.global_position = spawn_pos
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bcvyiisb5ugtn
|
||||||
@@ -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:
|
static func _execute_recipe(a: Node3D, b: Node3D, recipe: Dictionary) -> void:
|
||||||
var pos := (a.global_position + b.global_position) * 0.5
|
var pos := (a.global_position + b.global_position) * 0.5
|
||||||
var parent := a.get_parent()
|
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()
|
a.queue_free()
|
||||||
b.queue_free()
|
b.queue_free()
|
||||||
var scene: PackedScene = load(recipe["result_scene"])
|
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
|
var result := scene.instantiate() as Node3D
|
||||||
parent.add_child(result)
|
parent.add_child(result)
|
||||||
result.global_position = pos
|
result.global_position = pos
|
||||||
|
FX.merge_smoke(pos + Vector3(0, 0.3, 0), parent)
|
||||||
|
|||||||
@@ -7,15 +7,34 @@ const MIN_SPEED := 0.3
|
|||||||
const WALL_BOUNCE := 0.7
|
const WALL_BOUNCE := 0.7
|
||||||
|
|
||||||
var kickable_type: String = "leather"
|
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 state: State = State.IDLE
|
||||||
var fly_vel: Vector3 = Vector3.ZERO
|
var fly_vel: Vector3 = Vector3.ZERO
|
||||||
var damage_modifier: float = 0.0
|
var damage_modifier: float = 0.0
|
||||||
|
|
||||||
@onready var mesh_node: MeshInstance3D = $LeatherMesh
|
@onready var mesh_node: MeshInstance3D = $LeatherMesh
|
||||||
|
var _tooltip: Label3D
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
add_to_group("kickable")
|
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:
|
func apply_collision_damage(_dmg: float) -> void:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -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")
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://b80k2b1icwlbm
|
||||||
@@ -12,7 +12,7 @@ func _ready() -> void:
|
|||||||
tw.tween_property(self, "position:y", 0.1, 0.7)
|
tw.tween_property(self, "position:y", 0.1, 0.7)
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
rotation.y += delta * 1.2
|
#rotation.y += delta * 1.2
|
||||||
var players := get_tree().get_nodes_in_group("player")
|
var players := get_tree().get_nodes_in_group("player")
|
||||||
if players.is_empty():
|
if players.is_empty():
|
||||||
tooltip.visible = false
|
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
|
tooltip.visible = p != null and global_position.distance_to(p.global_position) < 2.5
|
||||||
|
|
||||||
func interact(player: Node) -> void:
|
func interact(player: Node) -> void:
|
||||||
player.call("apply_upgrade_boots", 10.0, tier)
|
player.call("apply_upgrade_boots", 2.0, tier)
|
||||||
queue_free()
|
queue_free()
|
||||||
|
var mains := get_tree().get_nodes_in_group("main")
|
||||||
|
if not mains.is_empty():
|
||||||
|
mains[0].call("show_tutorial", "Tutorial_LeatherBoots")
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const CAM_DIST := 8.0
|
|||||||
const MOUSE_SENS := 0.18
|
const MOUSE_SENS := 0.18
|
||||||
const PITCH_MIN := 5.0
|
const PITCH_MIN := 5.0
|
||||||
const PITCH_MAX := 70.0
|
const PITCH_MAX := 70.0
|
||||||
const SPAWN_TIME := 10
|
const SPAWN_TIME := 5
|
||||||
|
|
||||||
var arena_size: float = 14.0
|
var arena_size: float = 14.0
|
||||||
var cam_yaw: float = 0.0
|
var cam_yaw: float = 0.0
|
||||||
@@ -27,10 +27,20 @@ var kills_for_next: int = 10
|
|||||||
var game_active: bool = false
|
var game_active: bool = false
|
||||||
var upgrading: 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
|
# UI nodes
|
||||||
var canvas: CanvasLayer
|
var canvas: CanvasLayer
|
||||||
var score_label: Label
|
var score_label: Label
|
||||||
var wave_label: Label
|
var wave_label: Label
|
||||||
|
var tier_label: Label
|
||||||
var hp_bar: ColorRect
|
var hp_bar: ColorRect
|
||||||
var hp_bar_bg: ColorRect
|
var hp_bar_bg: ColorRect
|
||||||
var progress_bar: ColorRect
|
var progress_bar: ColorRect
|
||||||
@@ -38,18 +48,35 @@ var progress_bg: ColorRect
|
|||||||
var upgrade_panel: Panel
|
var upgrade_panel: Panel
|
||||||
var gameover_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:
|
func _ready() -> void:
|
||||||
_spawn_level()
|
_spawn_level()
|
||||||
_create_camera()
|
_create_camera()
|
||||||
_create_ui()
|
_create_ui()
|
||||||
|
_create_tutorial_overlay()
|
||||||
_spawn_player()
|
_spawn_player()
|
||||||
_spawn_rocks()
|
_spawn_rocks()
|
||||||
_spawn_sticks()
|
_spawn_sticks()
|
||||||
_start_game()
|
|
||||||
add_to_group("main")
|
add_to_group("main")
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
|
show_tutorial("Tutorial_StartGame", _start_game)
|
||||||
|
|
||||||
func _input(event: InputEvent) -> void:
|
func _input(event: InputEvent) -> void:
|
||||||
|
if tutorial_active:
|
||||||
|
return
|
||||||
var motion := event as InputEventMouseMotion
|
var motion := event as InputEventMouseMotion
|
||||||
if motion != null and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
if motion != null and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||||
cam_yaw -= motion.relative.x * MOUSE_SENS
|
cam_yaw -= motion.relative.x * MOUSE_SENS
|
||||||
@@ -92,6 +119,29 @@ func _process(delta: float) -> void:
|
|||||||
camera.look_at(look_at_pos, Vector3.UP)
|
camera.look_at(look_at_pos, Vector3.UP)
|
||||||
if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
|
if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
|
||||||
player.set_aim_direction(deg_to_rad(cam_yaw))
|
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 ────────────────────────────────────────────────────────────────────
|
# ─── Rocks ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -99,18 +149,39 @@ var rocks_on_field: int = 0
|
|||||||
var rocks_pending: int = 0
|
var rocks_pending: int = 0
|
||||||
|
|
||||||
func _get_rock_limit() -> int:
|
func _get_rock_limit() -> int:
|
||||||
return mini(2 + (wave + 1) / 2, 7)
|
return mini(3 + (wave + 1) / 2, 7)
|
||||||
|
|
||||||
func _spawn_rocks() -> void:
|
func _spawn_rocks() -> void:
|
||||||
var limit := _get_rock_limit()
|
var limit := _get_rock_limit()
|
||||||
for i in range(limit):
|
for i in range(limit):
|
||||||
_spawn_single_rock()
|
_spawn_single_rock()
|
||||||
|
|
||||||
|
var sticks_on_field: int = 0
|
||||||
|
var sticks_pending: int = 0
|
||||||
|
const STICK_LIMIT := 3
|
||||||
|
|
||||||
func _spawn_sticks() -> void:
|
func _spawn_sticks() -> void:
|
||||||
for i in range(2):
|
for i in range(STICK_LIMIT):
|
||||||
var stick := STICK_SCENE.instantiate()
|
_spawn_single_stick()
|
||||||
stick.position = _safe_item_position()
|
|
||||||
add_child(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:
|
func _spawn_single_rock() -> void:
|
||||||
var rock := ROCK_SCENE.instantiate()
|
var rock := ROCK_SCENE.instantiate()
|
||||||
@@ -143,7 +214,7 @@ func _on_rock_destroyed() -> void:
|
|||||||
return
|
return
|
||||||
if rocks_on_field + rocks_pending < _get_rock_limit():
|
if rocks_on_field + rocks_pending < _get_rock_limit():
|
||||||
rocks_pending += 1
|
rocks_pending += 1
|
||||||
await get_tree().create_timer(20.0).timeout
|
await get_tree().create_timer(GameSettings.item_respawn_delay).timeout
|
||||||
rocks_pending -= 1
|
rocks_pending -= 1
|
||||||
if game_active:
|
if game_active:
|
||||||
_spawn_single_rock()
|
_spawn_single_rock()
|
||||||
@@ -174,7 +245,7 @@ func _start_game() -> void:
|
|||||||
Enemy.first_iron_spawned = false
|
Enemy.first_iron_spawned = false
|
||||||
Enemy.first_essence_spawned = false
|
Enemy.first_essence_spawned = false
|
||||||
_update_labels()
|
_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.connect("timeout", _on_spawn_timer)
|
||||||
spawn_timer.start()
|
spawn_timer.start()
|
||||||
|
|
||||||
@@ -182,7 +253,7 @@ func _on_spawn_timer() -> void:
|
|||||||
if not game_active or upgrading:
|
if not game_active or upgrading:
|
||||||
return
|
return
|
||||||
_spawn_enemy()
|
_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:
|
func _spawn_enemy() -> void:
|
||||||
var enemy := ENEMY_SCENE.instantiate() as CharacterBody3D
|
var enemy := ENEMY_SCENE.instantiate() as CharacterBody3D
|
||||||
@@ -197,6 +268,9 @@ func _spawn_enemy() -> void:
|
|||||||
enemy.target = player
|
enemy.target = player
|
||||||
enemy.connect("died", _on_enemy_died)
|
enemy.connect("died", _on_enemy_died)
|
||||||
enemy.connect("merged", _on_enemy_merged)
|
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
|
# Spawn at random edge
|
||||||
var side := randi() % 4
|
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.setup(type, w)
|
||||||
enemy.target = player
|
enemy.target = player
|
||||||
enemy.enemy_level = level
|
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.global_position = pos
|
||||||
enemy.connect("died", _on_enemy_died)
|
enemy.connect("died", _on_enemy_died)
|
||||||
enemy.connect("merged", _on_enemy_merged)
|
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
|
var old_size: Vector3 = s3d.size
|
||||||
col_shape.shape = BoxShape3D.new()
|
col_shape.shape = BoxShape3D.new()
|
||||||
(col_shape.shape as BoxShape3D).size = old_size * s
|
(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)
|
if level >= 3 and not first_boss_spawned:
|
||||||
tw.tween_property(enemy.mat, "albedo_color", color, 0.25)
|
first_boss_spawned = true
|
||||||
#var bs := scale
|
_start_boss_phase()
|
||||||
#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)
|
|
||||||
return enemy
|
return enemy
|
||||||
|
|
||||||
func _on_enemy_merged(_upgrade: bool) -> void:
|
func _on_enemy_merged(_upgrade: bool) -> void:
|
||||||
@@ -255,6 +330,12 @@ func _on_enemy_merged(_upgrade: bool) -> void:
|
|||||||
|
|
||||||
func _on_player_died() -> void:
|
func _on_player_died() -> void:
|
||||||
game_active = false
|
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()
|
spawn_timer.stop()
|
||||||
_show_gameover()
|
_show_gameover()
|
||||||
|
|
||||||
@@ -311,6 +392,215 @@ func _restart() -> void:
|
|||||||
get_tree().paused = false
|
get_tree().paused = false
|
||||||
get_tree().reload_current_scene()
|
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 ───────────────────────────────────────────────────────────────────────
|
# ─── UI ───────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func _create_ui() -> void:
|
func _create_ui() -> void:
|
||||||
@@ -321,22 +611,108 @@ func _create_ui() -> void:
|
|||||||
_make_hud()
|
_make_hud()
|
||||||
_make_upgrade_panel()
|
_make_upgrade_panel()
|
||||||
_make_gameover_panel()
|
_make_gameover_panel()
|
||||||
|
_make_boss_ui()
|
||||||
|
_make_win_panel()
|
||||||
|
|
||||||
func _make_hud() -> void:
|
func _make_hud() -> void:
|
||||||
# Score
|
score_label = _label(Vector2(16, 12), "Score: 0", 30)
|
||||||
score_label = _label(Vector2(12, 10), "Score: 0", 22)
|
wave_label = _label(Vector2(16, 50), "Wave: 1", 30)
|
||||||
# Wave
|
_make_recipe_panel()
|
||||||
wave_label = _label(Vector2(12, 38), "Wave: 1", 22)
|
|
||||||
|
|
||||||
# HP bar
|
func _make_recipe_panel() -> void:
|
||||||
_label(Vector2(12, 68), "HP", 16)
|
const INGREDIENT_NAMES := {
|
||||||
hp_bar_bg = _crect(Vector2(12, 88), Vector2(200, 16), Color(0.25, 0.04, 0.04))
|
"rock": "Rock",
|
||||||
hp_bar = _crect(Vector2(12, 88), Vector2(200, 16), Color(0.9, 0.15, 0.15))
|
"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
|
const PAD_H := 10
|
||||||
_label(Vector2(12, 110), "Next upgrade", 16)
|
const PAD_V := 8
|
||||||
progress_bg = _crect(Vector2(12, 130), Vector2(200, 10), Color(0.1, 0.1, 0.25))
|
const SEP := 4
|
||||||
progress_bar = _crect(Vector2(12, 130), Vector2(0, 10), Color(0.4, 0.8, 1.0))
|
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:
|
func _make_upgrade_panel() -> void:
|
||||||
upgrade_panel = Panel.new()
|
upgrade_panel = Panel.new()
|
||||||
@@ -417,6 +793,175 @@ func _make_gameover_panel() -> void:
|
|||||||
restart_btn.connect("pressed", _restart)
|
restart_btn.connect("pressed", _restart)
|
||||||
vbox.add_child(restart_btn)
|
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 ───────────────────────────────────────────────────────────────
|
# ─── UI helpers ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func _label(pos: Vector2, text: String, size: int) -> Label:
|
func _label(pos: Vector2, text: String, size: int) -> Label:
|
||||||
@@ -446,3 +991,13 @@ func _update_labels() -> void:
|
|||||||
func _update_progress() -> void:
|
func _update_progress() -> void:
|
||||||
var t := float(kills) / float(kills_for_next)
|
var t := float(kills) / float(kills_for_next)
|
||||||
progress_bar.size.x = 200.0 * t
|
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()
|
||||||
|
|||||||
@@ -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()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://on1o20vpycgm
|
||||||
@@ -13,6 +13,31 @@ static var _list: Array[Dictionary] = [
|
|||||||
"result_scene": "res://scenes/Boulder.tscn",
|
"result_scene": "res://scenes/Boulder.tscn",
|
||||||
"speed_threshold": 18.0,
|
"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:
|
static func find(type_a: String, type_b: String, speed: float) -> Dictionary:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ func _ready() -> void:
|
|||||||
tw.tween_property(self, "position:y", 0.2, 0.7)
|
tw.tween_property(self, "position:y", 0.2, 0.7)
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
rotation.y += delta * 1.4
|
#rotation.y += delta * 1.4
|
||||||
var players := get_tree().get_nodes_in_group("player")
|
var players := get_tree().get_nodes_in_group("player")
|
||||||
if players.is_empty():
|
if players.is_empty():
|
||||||
tooltip.visible = false
|
tooltip.visible = false
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://sfq4iq0btm0g
|
||||||
@@ -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()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://sklquy2lyugo
|
||||||
@@ -8,10 +8,18 @@ signal health_changed(current: int, maximum: int)
|
|||||||
@export var kick_force: float = 60.0
|
@export var kick_force: float = 60.0
|
||||||
@export var kick_cooldown: float = 0.6
|
@export var kick_cooldown: float = 0.6
|
||||||
@export var kick_angle: float = 60.0
|
@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 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 kick_timer: float = 0.0
|
||||||
var invincible_timer: float = 0.0
|
var invincible_timer: float = 0.0
|
||||||
var is_alive: bool = true
|
var is_alive: bool = true
|
||||||
@@ -20,8 +28,10 @@ var last_move_dir: Vector3 = Vector3.FORWARD
|
|||||||
var _aim_yaw: float = 0.0
|
var _aim_yaw: float = 0.0
|
||||||
var _is_aiming: bool = false
|
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 indicator_node: MeshInstance3D = $KickIndicator
|
||||||
|
@onready var anim_player: AnimationPlayer = $AnimationPlayer2
|
||||||
|
|
||||||
var player_mat: StandardMaterial3D
|
var player_mat: StandardMaterial3D
|
||||||
var indicator_mat: StandardMaterial3D
|
var indicator_mat: StandardMaterial3D
|
||||||
@@ -31,10 +41,25 @@ const BASE_COLOR := Color(0.2, 0.55, 1.0)
|
|||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
add_to_group("player")
|
add_to_group("player")
|
||||||
player_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
player_mat = mesh_node.get_surface_override_material(0).duplicate() as StandardMaterial3D
|
||||||
mesh_node.material_override = player_mat
|
mesh_node.set_surface_override_material(0, player_mat)
|
||||||
|
mesh_node_boot.visible = false
|
||||||
_setup_indicator()
|
_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:
|
func _setup_indicator() -> void:
|
||||||
indicator_node.position.y = 0.02
|
indicator_node.position.y = 0.02
|
||||||
indicator_node.mesh = _make_kick_arc_mesh()
|
indicator_node.mesh = _make_kick_arc_mesh()
|
||||||
@@ -76,13 +101,15 @@ func _input(event: InputEvent) -> void:
|
|||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
if not is_alive:
|
if not is_alive:
|
||||||
return
|
return
|
||||||
|
is_shielding = shield_tier > 0 and Input.is_key_pressed(KEY_SPACE)
|
||||||
_handle_movement(delta)
|
_handle_movement(delta)
|
||||||
_handle_kick(delta)
|
_handle_kick(delta)
|
||||||
_handle_iframes(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()
|
_do_kick()
|
||||||
|
|
||||||
func _handle_movement(delta: float) -> void:
|
func _handle_movement(delta: float) -> void:
|
||||||
|
var effective_speed := move_speed * (0.2 if is_shielding else 1.0)
|
||||||
var input_x: float = (
|
var input_x: float = (
|
||||||
float(Input.is_key_pressed(KEY_D) or Input.is_key_pressed(KEY_RIGHT)) -
|
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))
|
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
|
var move := cam_fwd * (-input_z) + cam_right * input_x
|
||||||
if move.length() > 0.01:
|
if move.length() > 0.01:
|
||||||
move = move.normalized()
|
move = move.normalized()
|
||||||
velocity.x = move.x * move_speed
|
velocity.x = move.x * effective_speed
|
||||||
velocity.z = move.z * move_speed
|
velocity.z = move.z * effective_speed
|
||||||
last_move_dir = move
|
last_move_dir = move
|
||||||
if not _is_aiming:
|
if not _is_aiming:
|
||||||
var target_y: float = atan2(-move.x, -move.z)
|
var target_y: float = atan2(-move.x, -move.z)
|
||||||
rotation.y = lerp_angle(rotation.y, target_y, 16.0 * delta)
|
rotation.y = lerp_angle(rotation.y, target_y, 16.0 * delta)
|
||||||
else:
|
else:
|
||||||
velocity.x = move_toward(velocity.x, 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, move_speed * 12.0 * delta)
|
velocity.z = move_toward(velocity.z, 0.0, effective_speed * 12.0 * delta)
|
||||||
if _is_aiming:
|
if _is_aiming:
|
||||||
rotation.y = lerp_angle(rotation.y, _aim_yaw, 14.0 * delta)
|
rotation.y = lerp_angle(rotation.y, _aim_yaw, 14.0 * delta)
|
||||||
_is_aiming = false
|
_is_aiming = false
|
||||||
@@ -132,6 +159,7 @@ func _handle_iframes(delta: float) -> void:
|
|||||||
|
|
||||||
func _do_kick() -> void:
|
func _do_kick() -> void:
|
||||||
kick_timer = kick_cooldown
|
kick_timer = kick_cooldown
|
||||||
|
_play_kick_blend()
|
||||||
var forward := -global_transform.basis.z
|
var forward := -global_transform.basis.z
|
||||||
forward.y = 0.0
|
forward.y = 0.0
|
||||||
forward = forward.normalized() if forward.length() > 0.01 else Vector3(0.0, 0.0, -1.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
|
var diff := en.global_position - global_position
|
||||||
diff.y = 0.0
|
diff.y = 0.0
|
||||||
var dist := diff.length()
|
var dist := diff.length()
|
||||||
if dist < 0.1 or dist > kick_range:
|
if dist < 0.01 or dist > kick_range:
|
||||||
continue
|
continue
|
||||||
if (diff / dist).dot(forward) >= half_cos:
|
if dist < 1.0 or (diff / dist).dot(forward) >= half_cos:
|
||||||
candidates.append(en)
|
candidates.append(en)
|
||||||
candidate_dists.append(dist)
|
candidate_dists.append(dist)
|
||||||
|
|
||||||
@@ -165,10 +193,12 @@ func _do_kick() -> void:
|
|||||||
var best_diff := best.global_position - global_position
|
var best_diff := best.global_position - global_position
|
||||||
best_diff.y = 0.0
|
best_diff.y = 0.0
|
||||||
var best_dir := best_diff.normalized()
|
var best_dir := best_diff.normalized()
|
||||||
var obj_tier: int = best.get("tier") if best.get("tier") != null else 0
|
var obj_toughness: int = best.get("toughness_tier") if best.get("toughness_tier") != null else 0
|
||||||
var diff_tier := tier - obj_tier
|
var diff_tier := kick_tier - obj_toughness
|
||||||
var force: float
|
var force: float
|
||||||
if diff_tier < 0:
|
if GameSettings.difficulty == "immortal":
|
||||||
|
force = 50.0
|
||||||
|
elif diff_tier < 0:
|
||||||
force = 15.0
|
force = 15.0
|
||||||
elif diff_tier == 0:
|
elif diff_tier == 0:
|
||||||
force = 50.0
|
force = 50.0
|
||||||
@@ -177,6 +207,7 @@ func _do_kick() -> void:
|
|||||||
else:
|
else:
|
||||||
force = 80.0
|
force = 80.0
|
||||||
best.call("receive_kick", best_dir, force)
|
best.call("receive_kick", best_dir, force)
|
||||||
|
FX.hit_spark(best.global_position + Vector3(0, 0.4, 0), get_parent())
|
||||||
_squish_effect()
|
_squish_effect()
|
||||||
|
|
||||||
func _try_interact() -> void:
|
func _try_interact() -> void:
|
||||||
@@ -197,6 +228,14 @@ func set_aim_direction(yaw_rad: float) -> void:
|
|||||||
_aim_yaw = yaw_rad
|
_aim_yaw = yaw_rad
|
||||||
_is_aiming = true
|
_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:
|
func _squish_effect() -> void:
|
||||||
var tw := create_tween()
|
var tw := create_tween()
|
||||||
tw.tween_property(mesh_node, "scale", Vector3(1.3, 0.55, 1.3), 0.07)
|
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.x = direction.x * force
|
||||||
velocity.z = direction.z * force
|
velocity.z = direction.z * force
|
||||||
invincible_timer = IFRAMES_DURATION * 0.5
|
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:
|
if not is_alive or invincible_timer > 0.0:
|
||||||
return
|
return
|
||||||
invincible_timer = IFRAMES_DURATION
|
invincible_timer = IFRAMES_DURATION
|
||||||
#health = max(0, health - amount)
|
if is_shielding and shield_tier > 0:
|
||||||
#emit_signal("health_changed", health, max_health)
|
var diff := shield_tier - attacker_toughness
|
||||||
#var tw := create_tween()
|
var mod: float = 0.15 if diff >= 2 else (0.30 if diff == 1 else 0.50)
|
||||||
#tw.tween_property(player_mat, "albedo_color", Color.RED, 0.08)
|
amount = int(amount * mod)
|
||||||
#tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.25)
|
|
||||||
#if health <= 0:
|
health = min(health - amount, max_health)
|
||||||
#_die()
|
emit_signal("health_changed", health, max_health)
|
||||||
|
_squish_effect()
|
||||||
|
|
||||||
func heal(amount: int) -> void:
|
func heal(amount: int) -> void:
|
||||||
if not is_alive:
|
if not is_alive:
|
||||||
@@ -250,20 +293,47 @@ func apply_upgrade(id: String) -> void:
|
|||||||
emit_signal("health_changed", health, max_health)
|
emit_signal("health_changed", health, max_health)
|
||||||
|
|
||||||
func apply_upgrade_boots(speed_bonus: float, _tier: int) -> void:
|
func apply_upgrade_boots(speed_bonus: float, _tier: int) -> void:
|
||||||
tier += _tier
|
kick_tier += 1
|
||||||
move_speed += speed_bonus
|
move_speed += speed_bonus
|
||||||
var tw := create_tween()
|
_apply_boot_mesh(kick_tier)
|
||||||
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)
|
|
||||||
|
|
||||||
func apply_upgrade_armor() -> void:
|
func apply_upgrade_armor() -> void:
|
||||||
tier += 1
|
kick_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)
|
|
||||||
|
|
||||||
func apply_upgrade_enchant() -> void:
|
func apply_upgrade_enchant() -> void:
|
||||||
tier += 1
|
kick_tier += 1
|
||||||
var tw := create_tween()
|
|
||||||
tw.tween_property(player_mat, "albedo_color", Color(0.8, 0.2, 1.0), 0.1)
|
func apply_stick_armor() -> bool:
|
||||||
tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.6)
|
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
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ const WALL_BOUNCE := 0.5
|
|||||||
const WALL_SELF_DMG := 0.6
|
const WALL_SELF_DMG := 0.6
|
||||||
|
|
||||||
var kickable_type: String = "rock"
|
var kickable_type: String = "rock"
|
||||||
var tier: int = 0
|
var kick_tier: int = 0
|
||||||
|
var toughness_tier: int = 0
|
||||||
var state: State = State.IDLE
|
var state: State = State.IDLE
|
||||||
var fly_vel: Vector3 = Vector3.ZERO
|
var fly_vel: Vector3 = Vector3.ZERO
|
||||||
var health: float = 60.0
|
var health: float = 60.0
|
||||||
@@ -19,6 +20,7 @@ var damage_modifier: float = 1.25
|
|||||||
|
|
||||||
@onready var mesh_node: MeshInstance3D = $RockMesh
|
@onready var mesh_node: MeshInstance3D = $RockMesh
|
||||||
var rock_mat: StandardMaterial3D
|
var rock_mat: StandardMaterial3D
|
||||||
|
var _tooltip: Label3D
|
||||||
|
|
||||||
const COLOR_IDLE := Color(0.45, 0.38, 0.30)
|
const COLOR_IDLE := Color(0.45, 0.38, 0.30)
|
||||||
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
|
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
|
||||||
@@ -27,6 +29,23 @@ func _ready() -> void:
|
|||||||
add_to_group("kickable")
|
add_to_group("kickable")
|
||||||
rock_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
rock_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
||||||
mesh_node.material_override = rock_mat
|
mesh_node.material_override = rock_mat
|
||||||
|
_tooltip = Label3D.new()
|
||||||
|
_tooltip.text = "Rock\n+Rock → Boulder\n+Stick → Wood Shield"
|
||||||
|
_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 can_merge_with(_other: Node3D, _speed: float) -> bool:
|
func can_merge_with(_other: Node3D, _speed: float) -> bool:
|
||||||
return false
|
return false
|
||||||
@@ -67,7 +86,7 @@ func _fly(delta: float) -> void:
|
|||||||
handled = true
|
handled = true
|
||||||
break
|
break
|
||||||
elif col3d.is_in_group("player"):
|
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
|
fly_vel *= 0.3
|
||||||
handled = true
|
handled = true
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ const WALL_BOUNCE := 0.5
|
|||||||
const WALL_SELF_DMG := 0.5
|
const WALL_SELF_DMG := 0.5
|
||||||
|
|
||||||
var kickable_type: String = "stick"
|
var kickable_type: String = "stick"
|
||||||
var tier: int = 0
|
var kick_tier: int = 0
|
||||||
|
var toughness_tier: int = 0
|
||||||
var state: State = State.IDLE
|
var state: State = State.IDLE
|
||||||
var fly_vel: Vector3 = Vector3.ZERO
|
var fly_vel: Vector3 = Vector3.ZERO
|
||||||
var health: float = 40.0
|
var health: float = 40.0
|
||||||
@@ -19,6 +20,7 @@ var damage_modifier: float = 0.6
|
|||||||
|
|
||||||
@onready var mesh_node: MeshInstance3D = $StickMesh
|
@onready var mesh_node: MeshInstance3D = $StickMesh
|
||||||
var stick_mat: StandardMaterial3D
|
var stick_mat: StandardMaterial3D
|
||||||
|
var _tooltip: Label3D
|
||||||
|
|
||||||
const COLOR_IDLE := Color(0.55, 0.38, 0.18)
|
const COLOR_IDLE := Color(0.55, 0.38, 0.18)
|
||||||
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
|
const COLOR_IMPACT := Color(1.0, 1.0, 1.0)
|
||||||
@@ -27,6 +29,23 @@ func _ready() -> void:
|
|||||||
add_to_group("kickable")
|
add_to_group("kickable")
|
||||||
stick_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
stick_mat = mesh_node.material_override.duplicate() as StandardMaterial3D
|
||||||
mesh_node.material_override = stick_mat
|
mesh_node.material_override = stick_mat
|
||||||
|
_tooltip = Label3D.new()
|
||||||
|
_tooltip.text = "Stick\n+Leather → Boots\n+Stick → Stick Armor\n+Rock → Wood Shield"
|
||||||
|
_tooltip.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
||||||
|
_tooltip.font_size = 56
|
||||||
|
_tooltip.outline_size = 6
|
||||||
|
_tooltip.position = Vector3(0, 1.2, 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:
|
func apply_collision_damage(dmg: float) -> void:
|
||||||
_take_damage(dmg)
|
_take_damage(dmg)
|
||||||
@@ -64,7 +83,7 @@ func _fly(delta: float) -> void:
|
|||||||
handled = true
|
handled = true
|
||||||
break
|
break
|
||||||
elif col3d.is_in_group("player"):
|
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
|
fly_vel *= 0.3
|
||||||
handled = true
|
handled = true
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -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_stick_armor"):
|
||||||
|
queue_free()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://cmvl3td1h7qb8
|
||||||