add shields and tiers on ui

This commit is contained in:
2026-04-23 11:36:01 +03:00
parent bec9389bb8
commit c9489321ae
14 changed files with 163 additions and 10 deletions
+26
View File
@@ -0,0 +1,26 @@
[gd_scene format=3 uid="uid://1uwmdnvgyaii"]
[ext_resource type="Script" path="res://scripts/IronShield.gd" id="1_ishield"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.55, 0.58, 0.62, 1)
roughness = 0.4
metallic = 0.7
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.55, 0.7, 0.1)
[node name="IronShield" type="Node3D"]
script = ExtResource("1_ishield")
[node name="ShieldMesh" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.35, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = SubResource("BoxMesh_1")
[node name="Tooltip" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3, 0)
billboard = 1
text = "[E] Iron Shield
Tier 2 | Hold Shift to block"
outline_size = 6
+25
View File
@@ -0,0 +1,25 @@
[gd_scene format=3 uid="uid://bayxgoeu4qxqe"]
[ext_resource type="Script" path="res://scripts/WoodenShield.gd" id="1_wshield"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.55, 0.38, 0.18, 1)
roughness = 0.85
[sub_resource type="BoxMesh" id="BoxMesh_1"]
size = Vector3(0.5, 0.65, 0.12)
[node name="WoodenShield" type="Node3D"]
script = ExtResource("1_wshield")
[node name="ShieldMesh" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.35, 0)
material_override = SubResource("StandardMaterial3D_1")
mesh = SubResource("BoxMesh_1")
[node name="Tooltip" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3, 0)
billboard = 1
text = "[E] Wooden Shield
Tier 1 | Hold Shift to block"
outline_size = 6
+1 -1
View File
@@ -65,7 +65,7 @@ func _fly(delta: float) -> void:
handled = true
break
elif col3d.is_in_group("player"):
col3d.call("take_damage", int(speed_now * damage_modifier))
col3d.call("take_damage", int(speed_now * damage_modifier), toughness_tier)
fly_vel *= 0.3
handled = true
break
+1 -1
View File
@@ -70,7 +70,7 @@ func _fly(delta: float) -> void:
handled = true
break
elif col3d.is_in_group("player"):
col3d.call("take_damage", int(speed_now * damage_modifier))
col3d.call("take_damage", int(speed_now * damage_modifier), toughness_tier)
fly_vel *= 0.3
handled = true
break
+23
View File
@@ -0,0 +1,23 @@
extends Node3D
@onready var tooltip: Label3D = $Tooltip
func _ready() -> void:
add_to_group("interactable")
tooltip.visible = false
var tw := create_tween().set_loops()
tw.tween_property(self, "position:y", 0.45, 0.65)
tw.tween_property(self, "position:y", 0.2, 0.65)
func _process(delta: float) -> void:
rotation.y += delta * 1.1
var players := get_tree().get_nodes_in_group("player")
if players.is_empty():
tooltip.visible = false
return
var p := players[0] as Node3D
tooltip.visible = p != null and global_position.distance_to(p.global_position) < 2.5
func interact(player: Node) -> void:
if player.call("apply_iron_shield"):
queue_free()
+1
View File
@@ -0,0 +1 @@
uid://bcvyiisb5ugtn
+14
View File
@@ -31,6 +31,7 @@ var upgrading: bool = false
var canvas: CanvasLayer
var score_label: Label
var wave_label: Label
var tier_label: Label
var hp_bar: ColorRect
var hp_bar_bg: ColorRect
var progress_bar: ColorRect
@@ -92,6 +93,7 @@ func _process(delta: float) -> void:
camera.look_at(look_at_pos, Vector3.UP)
if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
player.set_aim_direction(deg_to_rad(cam_yaw))
_update_tier_label()
# ─── Rocks ────────────────────────────────────────────────────────────────────
@@ -339,6 +341,9 @@ func _make_hud() -> void:
progress_bg = _crect(Vector2(12, 130), Vector2(200, 10), Color(0.1, 0.1, 0.25))
progress_bar = _crect(Vector2(12, 130), Vector2(0, 10), Color(0.4, 0.8, 1.0))
# Tier display
tier_label = _label(Vector2(12, 148), "", 17)
func _make_upgrade_panel() -> void:
upgrade_panel = Panel.new()
upgrade_panel.process_mode = Node.PROCESS_MODE_ALWAYS
@@ -447,3 +452,12 @@ func _update_labels() -> void:
func _update_progress() -> void:
var t := float(kills) / float(kills_for_next)
progress_bar.size.x = 200.0 * t
func _update_tier_label() -> void:
if not is_instance_valid(player):
return
var kt: int = player.get("kick_tier")
var tt: int = player.get("toughness_tier")
var st: int = player.get("shield_tier")
var shield_str := "-" if st == 0 else str(st)
tier_label.text = "Kick: %d Tough: %d Shield: %s" % [kt, tt, shield_str]
+10
View File
@@ -28,6 +28,16 @@ static var _list: Array[Dictionary] = [
"result_scene": "res://scenes/PlateArmor.tscn",
"speed_threshold": 18.0,
},
{
"ingredients": ["rock", "stick"],
"result_scene": "res://scenes/WoodenShield.tscn",
"speed_threshold": 18.0,
},
{
"ingredients": ["iron", "leather"],
"result_scene": "res://scenes/IronShield.tscn",
"speed_threshold": 18.0,
},
]
static func find(type_a: String, type_b: String, speed: float) -> Dictionary:
+1 -1
View File
@@ -65,7 +65,7 @@ func _fly(delta: float) -> void:
handled = true
break
elif col3d.is_in_group("player"):
col3d.call("take_damage", int(speed_now * damage_modifier))
col3d.call("take_damage", int(speed_now * damage_modifier), toughness_tier)
fly_vel *= 0.3
handled = true
break
+35 -5
View File
@@ -16,6 +16,10 @@ var toughness_tier: int = 0
var has_stick_armor: bool = false
var has_leather_armor: bool = false
var has_plate_armor: bool = false
var has_wooden_shield: bool = false
var has_iron_shield: bool = false
var shield_tier: int = 0
var is_shielding: bool = false
var kick_timer: float = 0.0
var invincible_timer: float = 0.0
var is_alive: bool = true
@@ -81,6 +85,7 @@ func _input(event: InputEvent) -> void:
func _physics_process(delta: float) -> void:
if not is_alive:
return
is_shielding = shield_tier > 0 and Input.is_key_pressed(KEY_SHIFT)
_handle_movement(delta)
_handle_kick(delta)
_handle_iframes(delta)
@@ -88,6 +93,7 @@ func _physics_process(delta: float) -> void:
_do_kick()
func _handle_movement(delta: float) -> void:
var effective_speed := move_speed * (0.2 if is_shielding else 1.0)
var input_x: float = (
float(Input.is_key_pressed(KEY_D) or Input.is_key_pressed(KEY_RIGHT)) -
float(Input.is_key_pressed(KEY_A) or Input.is_key_pressed(KEY_LEFT))
@@ -107,15 +113,15 @@ func _handle_movement(delta: float) -> void:
var move := cam_fwd * (-input_z) + cam_right * input_x
if move.length() > 0.01:
move = move.normalized()
velocity.x = move.x * move_speed
velocity.z = move.z * move_speed
velocity.x = move.x * effective_speed
velocity.z = move.z * effective_speed
last_move_dir = move
if not _is_aiming:
var target_y: float = atan2(-move.x, -move.z)
rotation.y = lerp_angle(rotation.y, target_y, 16.0 * delta)
else:
velocity.x = move_toward(velocity.x, 0.0, move_speed * 12.0 * delta)
velocity.z = move_toward(velocity.z, 0.0, move_speed * 12.0 * delta)
velocity.x = move_toward(velocity.x, 0.0, effective_speed * 12.0 * delta)
velocity.z = move_toward(velocity.z, 0.0, effective_speed * 12.0 * delta)
if _is_aiming:
rotation.y = lerp_angle(rotation.y, _aim_yaw, 14.0 * delta)
_is_aiming = false
@@ -221,10 +227,14 @@ func receive_kick(direction: Vector3, force: float) -> void:
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 not is_alive or invincible_timer > 0.0:
return
invincible_timer = IFRAMES_DURATION
if is_shielding and shield_tier > 0:
var diff := shield_tier - attacker_toughness
var mod: float = 0.15 if diff >= 2 else (0.30 if diff == 1 else 0.50)
amount = int(amount * mod)
_squish_effect()
func heal(amount: int) -> void:
@@ -303,3 +313,23 @@ func apply_plate_armor() -> bool:
tw.tween_property(player_mat, "albedo_color", Color(0.6, 0.7, 1.0), 0.1)
tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.5)
return true
func apply_wooden_shield() -> bool:
if has_wooden_shield:
return false
has_wooden_shield = true
shield_tier = max(shield_tier, 1)
var tw := create_tween()
tw.tween_property(player_mat, "albedo_color", Color(0.55, 0.38, 0.18), 0.1)
tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.4)
return true
func apply_iron_shield() -> bool:
if has_iron_shield:
return false
has_iron_shield = true
shield_tier = max(shield_tier, 2)
var tw := create_tween()
tw.tween_property(player_mat, "albedo_color", Color(0.55, 0.58, 0.62), 0.1)
tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.5)
return true
+1 -1
View File
@@ -68,7 +68,7 @@ func _fly(delta: float) -> void:
handled = true
break
elif col3d.is_in_group("player"):
col3d.call("take_damage", int(speed_now * damage_modifier))
col3d.call("take_damage", int(speed_now * damage_modifier), toughness_tier)
fly_vel *= 0.3
handled = true
break
+1 -1
View File
@@ -65,7 +65,7 @@ func _fly(delta: float) -> void:
handled = true
break
elif col3d.is_in_group("player"):
col3d.call("take_damage", int(speed_now * damage_modifier))
col3d.call("take_damage", int(speed_now * damage_modifier), toughness_tier)
fly_vel *= 0.3
handled = true
break
+23
View File
@@ -0,0 +1,23 @@
extends Node3D
@onready var tooltip: Label3D = $Tooltip
func _ready() -> void:
add_to_group("interactable")
tooltip.visible = false
var tw := create_tween().set_loops()
tw.tween_property(self, "position:y", 0.45, 0.65)
tw.tween_property(self, "position:y", 0.2, 0.65)
func _process(delta: float) -> void:
rotation.y += delta * 1.1
var players := get_tree().get_nodes_in_group("player")
if players.is_empty():
tooltip.visible = false
return
var p := players[0] as Node3D
tooltip.visible = p != null and global_position.distance_to(p.global_position) < 2.5
func interact(player: Node) -> void:
if player.call("apply_wooden_shield"):
queue_free()
+1
View File
@@ -0,0 +1 @@
uid://djbxvch3r5py5