From cdb0ffd6a5b3ddbcdf08fc9c56549b8aec084245 Mon Sep 17 00:00:00 2001 From: Nikolai Fedorov Date: Thu, 23 Apr 2026 00:51:28 +0300 Subject: [PATCH] exp --- scenes/LeatherArmor.tscn | 26 ++++++++ scenes/MetalPlate.tscn | 27 ++++++++ scenes/PlateArmor.tscn | 28 +++++++++ scenes/StickArmor.tscn | 26 ++++++++ scripts/Boulder.gd | 3 +- scripts/Enemy.gd | 26 ++++---- scripts/Essence.gd | 3 +- scripts/Iron.gd | 7 ++- scripts/Leather.gd | 3 +- scripts/LeatherArmor.gd | 23 +++++++ scripts/LeatherArmor.gd.uid | 1 + scripts/Main.gd | 3 +- scripts/MergeRecipes.gd | 17 ++++- scripts/MetalPlate.gd | 120 ++++++++++++++++++++++++++++++++++++ scripts/MetalPlate.gd.uid | 1 + scripts/PlateArmor.gd | 23 +++++++ scripts/PlateArmor.gd.uid | 1 + scripts/Player.gd | 46 ++++++++++++-- scripts/Rock.gd | 3 +- scripts/Stick.gd | 3 +- scripts/StickArmor.gd | 23 +++++++ scripts/StickArmor.gd.uid | 1 + 22 files changed, 386 insertions(+), 28 deletions(-) create mode 100644 scenes/LeatherArmor.tscn create mode 100644 scenes/MetalPlate.tscn create mode 100644 scenes/PlateArmor.tscn create mode 100644 scenes/StickArmor.tscn create mode 100644 scripts/LeatherArmor.gd create mode 100644 scripts/LeatherArmor.gd.uid create mode 100644 scripts/MetalPlate.gd create mode 100644 scripts/MetalPlate.gd.uid create mode 100644 scripts/PlateArmor.gd create mode 100644 scripts/PlateArmor.gd.uid create mode 100644 scripts/StickArmor.gd create mode 100644 scripts/StickArmor.gd.uid diff --git a/scenes/LeatherArmor.tscn b/scenes/LeatherArmor.tscn new file mode 100644 index 0000000..1c6653c --- /dev/null +++ b/scenes/LeatherArmor.tscn @@ -0,0 +1,26 @@ +[gd_scene format=3 uid="uid://bidrinpjiyb2x"] + +[ext_resource type="Script" path="res://scripts/LeatherArmor.gd" id="1_leatha"] + +[sub_resource type="BoxMesh" id="BoxMesh_1"] +size = Vector3(0.5, 0.6, 0.22) + +[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"] +script = ExtResource("1_leatha") + +[node name="ArmorMesh" type="MeshInstance3D" parent="."] +mesh = SubResource("BoxMesh_1") +material_override = SubResource("StandardMaterial3D_1") + +[node name="Tooltip" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, 0) +billboard = 1 +double_sided = true +text = "[E] Leather Armor ++1 Toughness" +font_size = 32 +outline_size = 6 diff --git a/scenes/MetalPlate.tscn b/scenes/MetalPlate.tscn new file mode 100644 index 0000000..9302278 --- /dev/null +++ b/scenes/MetalPlate.tscn @@ -0,0 +1,27 @@ +[gd_scene format=3 uid="uid://dbvt3pkrej5nq"] + +[ext_resource type="Script" path="res://scripts/MetalPlate.gd" id="1_plate"] + +[sub_resource type="BoxMesh" id="BoxMesh_1"] +size = Vector3(0.55, 0.08, 0.7) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"] +albedo_color = Color(0.6, 0.65, 0.72, 1) +roughness = 0.35 +metallic = 0.8 +metallic_specular = 0.9 + +[sub_resource type="BoxShape3D" id="BoxShape3D_1"] +size = Vector3(0.55, 0.08, 0.7) + +[node name="MetalPlate" type="CharacterBody3D"] +script = ExtResource("1_plate") + +[node name="PlateMesh" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0) +mesh = SubResource("BoxMesh_1") +material_override = SubResource("StandardMaterial3D_1") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0) +shape = SubResource("BoxShape3D_1") diff --git a/scenes/PlateArmor.tscn b/scenes/PlateArmor.tscn new file mode 100644 index 0000000..b40f106 --- /dev/null +++ b/scenes/PlateArmor.tscn @@ -0,0 +1,28 @@ +[gd_scene format=3 uid="uid://cjhyinmjh0c3y"] + +[ext_resource type="Script" path="res://scripts/PlateArmor.gd" id="1_platea"] + +[sub_resource type="BoxMesh" id="BoxMesh_1"] +size = Vector3(0.58, 0.72, 0.24) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"] +albedo_color = Color(0.58, 0.62, 0.70, 1) +roughness = 0.3 +metallic = 0.85 +metallic_specular = 1.0 + +[node name="PlateArmor" type="Node3D"] +script = ExtResource("1_platea") + +[node name="ArmorMesh" type="MeshInstance3D" parent="."] +mesh = SubResource("BoxMesh_1") +material_override = SubResource("StandardMaterial3D_1") + +[node name="Tooltip" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0) +billboard = 1 +double_sided = true +text = "[E] Plate Armor ++1 Toughness" +font_size = 32 +outline_size = 6 diff --git a/scenes/StickArmor.tscn b/scenes/StickArmor.tscn new file mode 100644 index 0000000..ebac00f --- /dev/null +++ b/scenes/StickArmor.tscn @@ -0,0 +1,26 @@ +[gd_scene format=3 uid="uid://hk7p5sjjxa1w"] + +[ext_resource type="Script" path="res://scripts/StickArmor.gd" id="1_sticka"] + +[sub_resource type="BoxMesh" id="BoxMesh_1"] +size = Vector3(0.45, 0.55, 0.2) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"] +albedo_color = Color(0.48, 0.32, 0.14, 1) +roughness = 0.9 + +[node name="StickArmor" type="Node3D"] +script = ExtResource("1_sticka") + +[node name="ArmorMesh" type="MeshInstance3D" parent="."] +mesh = SubResource("BoxMesh_1") +material_override = SubResource("StandardMaterial3D_1") + +[node name="Tooltip" type="Label3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, 0) +billboard = 1 +double_sided = true +text = "[E] Stick Armor ++1 Toughness" +font_size = 32 +outline_size = 6 diff --git a/scripts/Boulder.gd b/scripts/Boulder.gd index 2b2d3a6..bd8b74f 100644 --- a/scripts/Boulder.gd +++ b/scripts/Boulder.gd @@ -10,7 +10,8 @@ const WALL_BOUNCE := 0.4 const WALL_SELF_DMG := 0.4 var kickable_type: String = "boulder" -var tier: int = 2 +var kick_tier: int = 0 +var toughness_tier: int = 2 var state: State = State.IDLE var fly_vel: Vector3 = Vector3.ZERO var health: float = 150.0 diff --git a/scripts/Enemy.gd b/scripts/Enemy.gd index 886fc2b..30bc756 100644 --- a/scripts/Enemy.gd +++ b/scripts/Enemy.gd @@ -16,7 +16,8 @@ static var first_iron_spawned: bool = false static var first_essence_spawned: bool = false var kickable_type: String = "" -var tier: int = 1 +var kick_tier: int = 1 +var toughness_tier: int = 1 var move_speed: float = 3.0 var health: int = 30 var damage_to_player: int = 8 @@ -90,7 +91,8 @@ func setup(type: String, wave: int) -> void: COLOR_CHASE = Color(0.3, 0.7, 0.3) mat.albedo_color = COLOR_CHASE enemy_level = 3 - tier = enemy_level + kick_tier = enemy_level + toughness_tier = enemy_level func _physics_process(delta: float) -> void: match state: @@ -144,19 +146,19 @@ func _try_enemy_kick() -> void: nearest_dist = d.length() nearest_kickable = k if nearest_kickable != null: - nearest_kickable.call("receive_kick", kick_dir, 35.0 + tier * 8.0) + nearest_kickable.call("receive_kick", kick_dir, 35.0 + kick_tier * 8.0) kickable_kick_timer = KICKABLE_KICK_COOLDOWN return - # 2. Kick lower-tier enemy nearest to player direction - if tier > 0: + # 2. Kick lower-toughness enemy nearest to player direction + if kick_tier > 0: var nearest_enemy: Node3D = null var nearest_enemy_dist := ENEMY_KICK_RANGE for node in get_tree().get_nodes_in_group("enemies"): var en := node as Node3D if en == null or en == self or not is_instance_valid(en): continue - if (en.get("tier") if en.get("tier") != null else 0) >= tier: + if (en.get("toughness_tier") if en.get("toughness_tier") != null else 0) >= kick_tier: continue var d := (en.global_position - global_position) d.y = 0.0 @@ -164,15 +166,15 @@ func _try_enemy_kick() -> void: nearest_enemy_dist = d.length() nearest_enemy = en if nearest_enemy != null: - nearest_enemy.call("receive_kick", kick_dir, 40.0 + tier * 10.0) + nearest_enemy.call("receive_kick", kick_dir, 40.0 + kick_tier * 10.0) enemy_kick_timer = ENEMY_KICK_COOLDOWN return - # 3. Kick player directly if lower tier and in range - if tier > 0 and to_player.length() < ENEMY_KICK_RANGE: - var player_tier: int = target.get("tier") if target.get("tier") != null else 0 - if player_tier < tier: - target.call("receive_kick", kick_dir, 35.0 + tier * 8.0) + # 3. Kick player directly if lower toughness and in range + if kick_tier > 0 and to_player.length() < ENEMY_KICK_RANGE: + var player_toughness: int = target.get("toughness_tier") if target.get("toughness_tier") != null else 0 + if player_toughness < kick_tier: + target.call("receive_kick", kick_dir, 35.0 + kick_tier * 8.0) enemy_kick_timer = ENEMY_KICK_COOLDOWN func _fly(delta: float) -> void: diff --git a/scripts/Essence.gd b/scripts/Essence.gd index 993b19f..9aad95f 100644 --- a/scripts/Essence.gd +++ b/scripts/Essence.gd @@ -12,7 +12,8 @@ const WALL_BOUNCE := 0.6 const WALL_SELF_DMG := 0.0 var kickable_type: String = "essence" -var tier: int = 3 +var kick_tier: int = 0 +var toughness_tier: int = 3 var state: State = State.IDLE var fly_vel: Vector3 = Vector3.ZERO var health: float = 999.0 diff --git a/scripts/Iron.gd b/scripts/Iron.gd index 95170f6..492abc1 100644 --- a/scripts/Iron.gd +++ b/scripts/Iron.gd @@ -1,6 +1,6 @@ extends CharacterBody3D -const METAL_ARMOR_SCENE := preload("res://scenes/MetalArmor.tscn") +const METAL_PLATE_SCENE := preload("res://scenes/MetalPlate.tscn") signal destroyed @@ -12,7 +12,8 @@ const WALL_BOUNCE := 0.45 const WALL_SELF_DMG := 0.5 var kickable_type: String = "iron" -var tier: int = 2 +var kick_tier: int = 0 +var toughness_tier: int = 2 var state: State = State.IDLE var fly_vel: Vector3 = Vector3.ZERO var health: float = 80.0 @@ -110,7 +111,7 @@ func _hit_forge(forge: Node3D) -> void: queue_free() if parent == null: return - var armor := METAL_ARMOR_SCENE.instantiate() as Node3D + var armor := METAL_PLATE_SCENE.instantiate() as Node3D parent.add_child(armor) armor.global_position = spawn_pos diff --git a/scripts/Leather.gd b/scripts/Leather.gd index 6884bf5..a938c94 100644 --- a/scripts/Leather.gd +++ b/scripts/Leather.gd @@ -7,7 +7,8 @@ const MIN_SPEED := 0.3 const WALL_BOUNCE := 0.7 var kickable_type: String = "leather" -var tier: int = 1 +var kick_tier: int = 0 +var toughness_tier: int = 0 var state: State = State.IDLE var fly_vel: Vector3 = Vector3.ZERO var damage_modifier: float = 0.0 diff --git a/scripts/LeatherArmor.gd b/scripts/LeatherArmor.gd new file mode 100644 index 0000000..c793968 --- /dev/null +++ b/scripts/LeatherArmor.gd @@ -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_leather_armor"): + queue_free() diff --git a/scripts/LeatherArmor.gd.uid b/scripts/LeatherArmor.gd.uid new file mode 100644 index 0000000..894effc --- /dev/null +++ b/scripts/LeatherArmor.gd.uid @@ -0,0 +1 @@ +uid://b80k2b1icwlbm diff --git a/scripts/Main.gd b/scripts/Main.gd index c9edcac..0803414 100644 --- a/scripts/Main.gd +++ b/scripts/Main.gd @@ -230,7 +230,8 @@ func _spawn_upgraded_enemy(pos: Vector3, type: String, level: int, w: int) -> Ch enemy.setup(type, w) enemy.target = player enemy.enemy_level = level - enemy.tier = level + enemy.kick_tier = level + enemy.toughness_tier = level enemy.global_position = pos enemy.connect("died", _on_enemy_died) enemy.connect("merged", _on_enemy_merged) diff --git a/scripts/MergeRecipes.gd b/scripts/MergeRecipes.gd index 2d2095f..2574584 100644 --- a/scripts/MergeRecipes.gd +++ b/scripts/MergeRecipes.gd @@ -6,11 +6,26 @@ static var _list: Array[Dictionary] = [ { "ingredients": ["leather", "stick"], "result_scene": "res://scenes/LeatherBoots.tscn", - "speed_threshold": 18.0, + "speed_threshold": 0.5, }, { "ingredients": ["rock", "rock"], "result_scene": "res://scenes/Boulder.tscn", + "speed_threshold": 5.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, }, ] diff --git a/scripts/MetalPlate.gd b/scripts/MetalPlate.gd new file mode 100644 index 0000000..685cecb --- /dev/null +++ b/scripts/MetalPlate.gd @@ -0,0 +1,120 @@ +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 = 120.0 +var dead: bool = false +var damage_modifier: float = 1.2 + +@onready var mesh_node: MeshInstance3D = $PlateMesh +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") + plate_mat = mesh_node.material_override.duplicate() as StandardMaterial3D + mesh_node.material_override = plate_mat + +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)) + 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) diff --git a/scripts/MetalPlate.gd.uid b/scripts/MetalPlate.gd.uid new file mode 100644 index 0000000..d72fccc --- /dev/null +++ b/scripts/MetalPlate.gd.uid @@ -0,0 +1 @@ +uid://sfq4iq0btm0g diff --git a/scripts/PlateArmor.gd b/scripts/PlateArmor.gd new file mode 100644 index 0000000..0b88630 --- /dev/null +++ b/scripts/PlateArmor.gd @@ -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() diff --git a/scripts/PlateArmor.gd.uid b/scripts/PlateArmor.gd.uid new file mode 100644 index 0000000..0818a6c --- /dev/null +++ b/scripts/PlateArmor.gd.uid @@ -0,0 +1 @@ +uid://sklquy2lyugo diff --git a/scripts/Player.gd b/scripts/Player.gd index 6ccc194..1a70c33 100644 --- a/scripts/Player.gd +++ b/scripts/Player.gd @@ -11,7 +11,11 @@ signal health_changed(current: int, maximum: int) @export var max_health: int = 100 var health: int = max_health -var tier: int = 0 +var kick_tier: int = 1 +var toughness_tier: int = 0 +var has_stick_armor: bool = false +var has_leather_armor: bool = false +var has_plate_armor: bool = false var kick_timer: float = 0.0 var invincible_timer: float = 0.0 var is_alive: bool = true @@ -165,8 +169,8 @@ func _do_kick() -> void: var best_diff := best.global_position - global_position best_diff.y = 0.0 var best_dir := best_diff.normalized() - var obj_tier: int = best.get("tier") if best.get("tier") != null else 0 - var diff_tier := tier - obj_tier + var obj_toughness: int = best.get("toughness_tier") if best.get("toughness_tier") != null else 0 + var diff_tier := kick_tier - obj_toughness var force: float if diff_tier < 0: force = 15.0 @@ -250,20 +254,50 @@ func apply_upgrade(id: String) -> void: emit_signal("health_changed", health, max_health) func apply_upgrade_boots(speed_bonus: float, _tier: int) -> void: - tier += _tier + kick_tier += 1 move_speed += speed_bonus var tw := create_tween() tw.tween_property(player_mat, "albedo_color", Color(1.0, 0.85, 0.2), 0.1) tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.4) 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: - 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) tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.6) + +func apply_stick_armor() -> bool: + if has_stick_armor: + return false + has_stick_armor = true + toughness_tier += 1 + var tw := create_tween() + tw.tween_property(player_mat, "albedo_color", Color(0.7, 0.5, 0.2), 0.1) + tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.4) + return true + +func apply_leather_armor() -> bool: + if has_leather_armor: + return false + has_leather_armor = true + toughness_tier += 1 + var tw := create_tween() + tw.tween_property(player_mat, "albedo_color", Color(0.8, 0.5, 0.2), 0.1) + tw.tween_property(player_mat, "albedo_color", BASE_COLOR, 0.4) + return true + +func apply_plate_armor() -> bool: + if has_plate_armor: + return false + has_plate_armor = true + toughness_tier += 1 + var tw := create_tween() + 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 diff --git a/scripts/Rock.gd b/scripts/Rock.gd index 01ee075..12b975b 100644 --- a/scripts/Rock.gd +++ b/scripts/Rock.gd @@ -10,7 +10,8 @@ const WALL_BOUNCE := 0.5 const WALL_SELF_DMG := 0.6 var kickable_type: String = "rock" -var tier: int = 0 +var kick_tier: int = 0 +var toughness_tier: int = 1 var state: State = State.IDLE var fly_vel: Vector3 = Vector3.ZERO var health: float = 60.0 diff --git a/scripts/Stick.gd b/scripts/Stick.gd index 73192aa..ad66263 100644 --- a/scripts/Stick.gd +++ b/scripts/Stick.gd @@ -10,7 +10,8 @@ const WALL_BOUNCE := 0.5 const WALL_SELF_DMG := 0.5 var kickable_type: String = "stick" -var tier: int = 0 +var kick_tier: int = 0 +var toughness_tier: int = 1 var state: State = State.IDLE var fly_vel: Vector3 = Vector3.ZERO var health: float = 40.0 diff --git a/scripts/StickArmor.gd b/scripts/StickArmor.gd new file mode 100644 index 0000000..5005265 --- /dev/null +++ b/scripts/StickArmor.gd @@ -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() diff --git a/scripts/StickArmor.gd.uid b/scripts/StickArmor.gd.uid new file mode 100644 index 0000000..dfb3ef4 --- /dev/null +++ b/scripts/StickArmor.gd.uid @@ -0,0 +1 @@ +uid://cmvl3td1h7qb8