add shields and tiers on ui
This commit is contained in:
@@ -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
|
||||||
@@ -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
@@ -65,7 +65,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
|
||||||
|
|||||||
+1
-1
@@ -70,7 +70,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_iron_shield"):
|
||||||
|
queue_free()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bcvyiisb5ugtn
|
||||||
@@ -31,6 +31,7 @@ var upgrading: bool = false
|
|||||||
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
|
||||||
@@ -92,6 +93,7 @@ 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()
|
||||||
|
|
||||||
# ─── Rocks ────────────────────────────────────────────────────────────────────
|
# ─── 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_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))
|
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:
|
func _make_upgrade_panel() -> void:
|
||||||
upgrade_panel = Panel.new()
|
upgrade_panel = Panel.new()
|
||||||
upgrade_panel.process_mode = Node.PROCESS_MODE_ALWAYS
|
upgrade_panel.process_mode = Node.PROCESS_MODE_ALWAYS
|
||||||
@@ -447,3 +452,12 @@ 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]
|
||||||
|
|||||||
@@ -28,6 +28,16 @@ static var _list: Array[Dictionary] = [
|
|||||||
"result_scene": "res://scenes/PlateArmor.tscn",
|
"result_scene": "res://scenes/PlateArmor.tscn",
|
||||||
"speed_threshold": 18.0,
|
"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:
|
||||||
|
|||||||
@@ -65,7 +65,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
|
||||||
|
|||||||
+35
-5
@@ -16,6 +16,10 @@ var toughness_tier: int = 0
|
|||||||
var has_stick_armor: bool = false
|
var has_stick_armor: bool = false
|
||||||
var has_leather_armor: bool = false
|
var has_leather_armor: bool = false
|
||||||
var has_plate_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
|
||||||
@@ -81,6 +85,7 @@ 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_SHIFT)
|
||||||
_handle_movement(delta)
|
_handle_movement(delta)
|
||||||
_handle_kick(delta)
|
_handle_kick(delta)
|
||||||
_handle_iframes(delta)
|
_handle_iframes(delta)
|
||||||
@@ -88,6 +93,7 @@ func _physics_process(delta: float) -> void:
|
|||||||
_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))
|
||||||
@@ -107,15 +113,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
|
||||||
@@ -221,10 +227,14 @@ func receive_kick(direction: Vector3, force: float) -> void:
|
|||||||
invincible_timer = IFRAMES_DURATION * 0.5
|
invincible_timer = IFRAMES_DURATION * 0.5
|
||||||
_squish_effect()
|
_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:
|
if not is_alive or invincible_timer > 0.0:
|
||||||
return
|
return
|
||||||
invincible_timer = IFRAMES_DURATION
|
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()
|
_squish_effect()
|
||||||
|
|
||||||
func heal(amount: int) -> void:
|
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", Color(0.6, 0.7, 1.0), 0.1)
|
||||||
tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.5)
|
tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.5)
|
||||||
return true
|
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
@@ -68,7 +68,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
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,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_wooden_shield"):
|
||||||
|
queue_free()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://djbxvch3r5py5
|
||||||
Reference in New Issue
Block a user