diff --git a/asset_dev/particles/health.xcf b/asset_dev/particles/health.xcf new file mode 100644 index 0000000..bf3d239 Binary files /dev/null and b/asset_dev/particles/health.xcf differ diff --git a/asset_dev/soda/Soda.png b/asset_dev/soda/Soda.png new file mode 100644 index 0000000..1837195 --- /dev/null +++ b/asset_dev/soda/Soda.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8d49e8e292361cdaada3c9797d3cd881042c029c08a7269a806422c923b2864 +size 6878 diff --git a/asset_dev/soda/Soda.xcf b/asset_dev/soda/Soda.xcf new file mode 100644 index 0000000..cdb1942 Binary files /dev/null and b/asset_dev/soda/Soda.xcf differ diff --git a/asset_dev/soda/soda.blend b/asset_dev/soda/soda.blend new file mode 100644 index 0000000..c0d4a07 --- /dev/null +++ b/asset_dev/soda/soda.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38612113a074a86d86ffc05f586617c78a66fa693e5d8065dc165d58a2b8c41b +size 917260 diff --git a/asset_dev/soda/soda.blend1 b/asset_dev/soda/soda.blend1 new file mode 100644 index 0000000..c7bc65b Binary files /dev/null and b/asset_dev/soda/soda.blend1 differ diff --git a/assets/models/items/soda/Soda.png b/assets/models/items/soda/Soda.png new file mode 100644 index 0000000..1837195 --- /dev/null +++ b/assets/models/items/soda/Soda.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8d49e8e292361cdaada3c9797d3cd881042c029c08a7269a806422c923b2864 +size 6878 diff --git a/assets/models/items/soda/Soda.png.import b/assets/models/items/soda/Soda.png.import new file mode 100644 index 0000000..e8efdc7 --- /dev/null +++ b/assets/models/items/soda/Soda.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dboi03l4xicib" +path="res://.godot/imported/Soda.png-de28f19d7b13e19defdbdcc490a1e11e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/models/items/soda/Soda.png" +dest_files=["res://.godot/imported/Soda.png-de28f19d7b13e19defdbdcc490a1e11e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/assets/models/items/soda/soda.bin b/assets/models/items/soda/soda.bin new file mode 100644 index 0000000..2d816a9 Binary files /dev/null and b/assets/models/items/soda/soda.bin differ diff --git a/assets/models/items/soda/soda.gltf b/assets/models/items/soda/soda.gltf new file mode 100644 index 0000000..7dbdf65 --- /dev/null +++ b/assets/models/items/soda/soda.gltf @@ -0,0 +1,138 @@ +{ + "asset":{ + "generator":"Khronos glTF Blender I/O v4.2.60", + "version":"2.0" + }, + "scene":0, + "scenes":[ + { + "name":"Scene", + "nodes":[ + 0 + ] + } + ], + "nodes":[ + { + "mesh":0, + "name":"Soda" + } + ], + "materials":[ + { + "alphaMode":"BLEND", + "doubleSided":true, + "name":"Soda", + "pbrMetallicRoughness":{ + "baseColorTexture":{ + "index":0 + }, + "metallicFactor":0, + "roughnessFactor":0.5 + } + } + ], + "meshes":[ + { + "name":"Cylinder", + "primitives":[ + { + "attributes":{ + "POSITION":0, + "NORMAL":1, + "TEXCOORD_0":2 + }, + "indices":3, + "material":0 + } + ] + } + ], + "textures":[ + { + "sampler":0, + "source":0 + } + ], + "images":[ + { + "mimeType":"image/png", + "name":"Soda", + "uri":"Soda.png" + } + ], + "accessors":[ + { + "bufferView":0, + "componentType":5126, + "count":42, + "max":[ + 0.19498558342456818, + 0.25, + 0.18019376695156097 + ], + "min":[ + -0.19498558342456818, + -0.25, + -0.20000000298023224 + ], + "type":"VEC3" + }, + { + "bufferView":1, + "componentType":5126, + "count":42, + "type":"VEC3" + }, + { + "bufferView":2, + "componentType":5126, + "count":42, + "type":"VEC2" + }, + { + "bufferView":3, + "componentType":5123, + "count":72, + "type":"SCALAR" + } + ], + "bufferViews":[ + { + "buffer":0, + "byteLength":504, + "byteOffset":0, + "target":34962 + }, + { + "buffer":0, + "byteLength":504, + "byteOffset":504, + "target":34962 + }, + { + "buffer":0, + "byteLength":336, + "byteOffset":1008, + "target":34962 + }, + { + "buffer":0, + "byteLength":144, + "byteOffset":1344, + "target":34963 + } + ], + "samplers":[ + { + "magFilter":9728, + "minFilter":9984 + } + ], + "buffers":[ + { + "byteLength":1488, + "uri":"soda.bin" + } + ] +} diff --git a/assets/models/items/soda/soda.gltf.import b/assets/models/items/soda/soda.gltf.import new file mode 100644 index 0000000..dce1025 --- /dev/null +++ b/assets/models/items/soda/soda.gltf.import @@ -0,0 +1,36 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://sr234l6v26ta" +path="res://.godot/imported/soda.gltf-2170d63a99b0c523c4e3c0057027d256.scn" + +[deps] + +source_file="res://assets/models/items/soda/soda.gltf" +dest_files=["res://.godot/imported/soda.gltf-2170d63a99b0c523c4e3c0057027d256.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +_subresources={} +gltf/naming_version=1 +gltf/embedded_image_handling=1 diff --git a/assets/sprites/particles/health.png b/assets/sprites/particles/health.png new file mode 100644 index 0000000..eed5290 --- /dev/null +++ b/assets/sprites/particles/health.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:633b86448a19b51fb6a54a8f334a1662b3a30ef35f1d092e2b98d3ccd627b8a5 +size 742 diff --git a/assets/sprites/particles/health.png.import b/assets/sprites/particles/health.png.import new file mode 100644 index 0000000..e435362 --- /dev/null +++ b/assets/sprites/particles/health.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://y07v10c8r1s6" +path="res://.godot/imported/health.png-c53c1eca35551099e5d2579b37f41427.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/sprites/particles/health.png" +dest_files=["res://.godot/imported/health.png-c53c1eca35551099e5d2579b37f41427.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/levels/debug_level/debug_level.tscn b/levels/debug_level/debug_level.tscn index d4fadbf..332a85f 100644 --- a/levels/debug_level/debug_level.tscn +++ b/levels/debug_level/debug_level.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=65 format=3 uid="uid://bm2o3mex10v11"] +[gd_scene load_steps=66 format=3 uid="uid://bm2o3mex10v11"] [ext_resource type="Terrain3DAssets" uid="uid://cwl34gstabgrx" path="res://levels/debug_level/terrain_assets.res" id="1_5smdk"] [ext_resource type="Shader" path="res://src/shaders/psx_water.gdshader" id="6_0efu4"] @@ -8,6 +8,7 @@ [ext_resource type="Script" path="res://src/world/ball_zone/ball_zone.gd" id="9_jwlau"] [ext_resource type="PackedScene" uid="uid://dagh38vap4t1d" path="res://src/props/scenery/city/concrete_building_1.tscn" id="10_lf15j"] [ext_resource type="PackedScene" uid="uid://cjubxs7peir5k" path="res://src/props/scenery/city/kana_signboard.tscn" id="11_evxup"] +[ext_resource type="PackedScene" uid="uid://1ud01tasevho" path="res://src/items/health/health_item.tscn" id="12_jiuxh"] [ext_resource type="PackedScene" uid="uid://di7aql54lksn7" path="res://src/props/scenery/trees/palm_tree/palm_tree.tscn" id="12_sswxf"] [ext_resource type="PackedScene" uid="uid://cjne55s85x7jy" path="res://src/items/extra_ball/brick_item.tscn" id="12_tj0lh"] [ext_resource type="PackedScene" uid="uid://c7l58wuuahn7w" path="res://src/props/flag/flag.tscn" id="13_6jtao"] @@ -395,6 +396,14 @@ amount = 5 spawn_on_ready = true spawn_turns = 1 +[node name="HealthSpawner" type="Marker3D" parent="Course/TestSpawners"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.651, 1, 7.92) +script = ExtResource("8_5kaye") +item = ExtResource("12_jiuxh") +amount = 25 +spawn_on_ready = true +spawn_turns = 1 + [node name="PlayerSpawn1" type="Marker3D" parent="Course" groups=["PlayerSpawn"]] transform = Transform3D(-0.842697, 0, -0.538388, 0, 1, 0, 0.538388, 0, -0.842697, 212.717, 4, 294.073) diff --git a/src/items/health/health_item.gd b/src/items/health/health_item.gd new file mode 100644 index 0000000..093781c --- /dev/null +++ b/src/items/health/health_item.gd @@ -0,0 +1,9 @@ +extends Item +## Item which restores life when picked up. + + +func _collect(player: WorldPlayer) -> void: + player.heal(amount) + + player.shot_setup.hud.peek_life_bar() + player.shot_setup.hud.life_particles.emit_spatial(amount, global_position) diff --git a/src/items/health/health_item.tscn b/src/items/health/health_item.tscn new file mode 100644 index 0000000..ec6a3db --- /dev/null +++ b/src/items/health/health_item.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=6 format=3 uid="uid://1ud01tasevho"] + +[ext_resource type="PackedScene" uid="uid://comd88yp45mnb" path="res://src/items/item/item.tscn" id="1_bb232"] +[ext_resource type="PackedScene" uid="uid://sr234l6v26ta" path="res://assets/models/items/soda/soda.gltf" id="2_bsxys"] +[ext_resource type="Script" path="res://src/items/health/health_item.gd" id="2_rwv0k"] +[ext_resource type="Texture2D" uid="uid://dboi03l4xicib" path="res://assets/models/items/soda/Soda.png" id="3_7jrce"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_6ujhj"] +albedo_texture = ExtResource("3_7jrce") +texture_filter = 2 + +[node name="HealthItem" instance=ExtResource("1_bb232")] +script = ExtResource("2_rwv0k") + +[node name="Pivot" parent="Pivot/Octahedron/ItemMeshContainer" index="0"] +transform = Transform3D(0.99863, 0.052336, 0, -0.052336, 0.99863, 0, 0, 0, 1, 0, 0, 0) + +[node name="soda" parent="Pivot/Octahedron/ItemMeshContainer/Pivot" index="1" instance=ExtResource("2_bsxys")] +transform = Transform3D(1.15911, -0.310583, 0, 0.3, 1.11962, 0.310583, -0.0803848, -0.3, 1.15911, 0, 0, 0) + +[node name="Soda" parent="Pivot/Octahedron/ItemMeshContainer/Pivot/soda" index="0"] +surface_material_override/0 = SubResource("StandardMaterial3D_6ujhj") + +[editable path="Pivot/Octahedron"] +[editable path="Pivot/Octahedron/ItemMeshContainer/Pivot/soda"] diff --git a/src/player/world_player.gd b/src/player/world_player.gd index c35f6e9..84faacb 100644 --- a/src/player/world_player.gd +++ b/src/player/world_player.gd @@ -5,7 +5,9 @@ signal on_life_changed(new_value: float) signal on_balls_changed(type: GameBall.Type, new_value: int) signal on_death(player: WorldPlayer) -@export_range(0, 100) var life: float = 100.0: +const MAX_LIFE := 100.0 + +@export_range(0, MAX_LIFE) var life: float = MAX_LIFE: set(value): if value != life: life = value @@ -89,6 +91,12 @@ func prev_ball(type: GameBall.Type) -> GameBall.Type: return keys[j] +## Restore life up to the MAX_LIFE cap. +## If the player's life is greater than or equal to MAX_LIFE, they will not be healed. +func heal(amount: float) -> void: + life += minf(amount, maxf(MAX_LIFE - life, 0)) + + func die() -> void: on_death.emit(self) diff --git a/src/ui/decorations/hud_particles/hud_particles.gd b/src/ui/decorations/hud_particles/hud_particles.gd index d6f2823..54a5493 100644 --- a/src/ui/decorations/hud_particles/hud_particles.gd +++ b/src/ui/decorations/hud_particles/hud_particles.gd @@ -17,6 +17,8 @@ func emit_at_location(_amount: int, source_location: Vector2) -> void: ## Emit the given number of particles from the screen location of the given point in 3D space. func emit_spatial(_amount: int, source_location: Vector3) -> void: - var screen_location := get_viewport().get_camera_3d().unproject_position(source_location) + var screen_location := ( + get_viewport().get_camera_3d().unproject_position(source_location) - global_position + ) # TODO: what to do if this is outside the viewport? emit_at_location(_amount, screen_location) diff --git a/src/ui/shot_hud/shot_hud.gd b/src/ui/shot_hud/shot_hud.gd index f9a4989..97e81e4 100644 --- a/src/ui/shot_hud/shot_hud.gd +++ b/src/ui/shot_hud/shot_hud.gd @@ -13,6 +13,7 @@ var player: WorldPlayer @onready var power_bar: TextureProgressBar = %PowerBar @onready var curve_bar: CurveBar = %CurveBar @onready var life_bar: TextureProgressBar = %LifeBar +@onready var life_particles: HUDParticles = %LifeParticles @onready var club_selector: ClubSelector = %ClubSelector @onready var ball_selector: BallSelector = %BallSelector diff --git a/src/ui/shot_hud/shot_hud.tscn b/src/ui/shot_hud/shot_hud.tscn index b0a8564..77e644c 100644 --- a/src/ui/shot_hud/shot_hud.tscn +++ b/src/ui/shot_hud/shot_hud.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=44 format=3 uid="uid://c4ifdiohng830"] +[gd_scene load_steps=45 format=3 uid="uid://c4ifdiohng830"] [ext_resource type="Script" path="res://src/ui/shot_hud/shot_hud.gd" id="1_x5b4c"] [ext_resource type="Shader" path="res://src/shaders/canvas_retro.gdshader" id="1_ybxxp"] @@ -15,6 +15,7 @@ [ext_resource type="PackedScene" uid="uid://dfh0bv7lwewj5" path="res://src/ui/decorations/hud_particles/hud_particles.tscn" id="11_ie5ih"] [ext_resource type="Texture2D" uid="uid://dtsdecae83ah3" path="res://assets/sprites/particles/ball.png" id="12_fdbqt"] [ext_resource type="PackedScene" uid="uid://b47goj32i6sdh" path="res://src/ui/elements/input_prompt/input_prompt.tscn" id="14_ik4gg"] +[ext_resource type="Texture2D" uid="uid://y07v10c8r1s6" path="res://assets/sprites/particles/health.png" id="15_eyqdi"] [sub_resource type="Animation" id="Animation_2gt87"] resource_name = "RESET" @@ -798,6 +799,20 @@ script = ExtResource("3_6groq") unique_name_in_owner = true layout_mode = 1 +[node name="ParticleContainer" type="Control" parent="SouthWest/VBoxContainer/MarginContainer/LifeBarRumbler/LifeBar"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="LifeParticles" parent="SouthWest/VBoxContainer/MarginContainer/LifeBarRumbler/LifeBar/ParticleContainer" instance=ExtResource("11_ie5ih")] +unique_name_in_owner = true +texture = ExtResource("15_eyqdi") + [node name="SWAnimation" type="AnimationPlayer" parent="SouthWest"] unique_name_in_owner = true root_node = NodePath("../..")