From 251002ea7c669b78373e1044e61ce3ef273ca4fa Mon Sep 17 00:00:00 2001 From: siim Date: Tue, 25 Aug 2026 08:04:39 +0300 Subject: [PATCH] bull and bear flashing red when take damage --- Player.tscn | 3 +-- bear.gd | 44 ++++++++++++++++++++++++++++++++++++++++++++ player.gd | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/Player.tscn b/Player.tscn index ee4f79c..7a57b08 100644 --- a/Player.tscn +++ b/Player.tscn @@ -35,7 +35,7 @@ script = ExtResource("2_camera_iso") [node name="bull" parent="." unique_id=1386495166 instance=ExtResource("4_e80uo")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.655, 0.23) -[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1883464126) index="0" unique_id=72207798] +[node name="Skeleton3D" parent="bull/Armature" parent_id_path=PackedInt32Array(1386495166, 1942410469) index="0" unique_id=550138996] bones/0/position = Vector3(0, 0, 0.009963839) bones/0/rotation = Quaternion(-0.733504, -0.0036974847, 0.0013620416, -0.67967373) bones/0/scale = Vector3(1, 0.99999994, 0.99999994) @@ -56,7 +56,6 @@ bones/19/rotation = Quaternion(0.07793758, -0.2513099, 0.94914854, 0.1728764) bones/20/rotation = Quaternion(-0.3791731, -0.08821739, 0.07153107, 0.91832936) bones/22/position = Vector3(-0.0045358227, -0.0021376943, -0.004238624) bones/22/rotation = Quaternion(0.20629132, 0.46411392, 0.84344316, 0.17506008) -bones/22/scale = Vector3(1.0000001, 1.0000001, 1.0000001) bones/23/rotation = Quaternion(-0.7287124, 0.31838557, 0.209407, 0.5689971) bones/23/scale = Vector3(1.0000001, 1.0000002, 1.0000002) bones/24/rotation = Quaternion(0.71033937, -0.13944183, -0.049755, 0.6881123) diff --git a/bear.gd b/bear.gd index df80f51..57d7817 100644 --- a/bear.gd +++ b/bear.gd @@ -59,6 +59,10 @@ var _anim_smash: StringName = &"" # SMASH_HIT — overhead smash var _anim_leap: StringName = &"" # JUMP_SMASH — leap slam var _anim_death: StringName = &"" # DEATH — death +#take hit flashing +var _hit_flash_active := false +var _hit_flash_tween: Tween + const _ACCEL_FACTOR: float = 9.0 # Hard deceleration for planted states (wind-up / recovery / neutral settle) so the bear # never coasts across the ground with a stationary pose playing (no foot-sliding). @@ -117,6 +121,45 @@ func _ready() -> void: _setup_claws() _enter_neutral() +#take hit flashing +func _hit_flash() -> void: + if _mesh == null: + return + + if _hit_flash_tween: + _hit_flash_tween.kill() + + _hit_flash_active = true + + # Make the bear red + for child in _mesh.find_children("*", "MeshInstance3D", true, false): + var mesh := child as MeshInstance3D + if mesh: + mesh.material_overlay = _make_hit_overlay() + + # Flash for 0.1 sec, then remove + _hit_flash_tween = create_tween() + _hit_flash_tween.tween_interval(0.10) + _hit_flash_tween.tween_callback(_clear_hit_flash) + +func _make_hit_overlay() -> StandardMaterial3D: + var mat := StandardMaterial3D.new() + mat.albedo_color = Color(1.0, 0.05, 0.05, 1.0) + mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED + return mat + +func _clear_hit_flash() -> void: + if _mesh == null: + return + + for child in _mesh.find_children("*", "MeshInstance3D", true, false): + var mesh := child as MeshInstance3D + if mesh: + mesh.material_overlay = null + + _hit_flash_active = false + + # Bind a claw-slash emitter to each paw bone (hand_l / hand_r) via a BoneAttachment3D, so # a burst fired on a swipe hit erupts from that paw wherever the animation has it. @@ -698,6 +741,7 @@ func _take_hit(hit_dir: Vector3, strength: float) -> void: if _state == State.DEAD: return _hp -= 1 + _hit_flash() health_changed.emit(_hp, int(DP.f("bear_max_hp"))) hit_dir.y = 0.0 hit_dir = hit_dir.normalized() diff --git a/player.gd b/player.gd index 8fdda27..9d80aaa 100644 --- a/player.gd +++ b/player.gd @@ -81,6 +81,8 @@ var _charge_dust_ramp: Gradient = null const RigidSkin = preload("res://rigid_skin.gd") +var _hit_flash_tween: Tween + func _ready() -> void: add_to_group(&"player") @@ -1090,6 +1092,7 @@ func take_sword_hit(cause: String = "", hit_pos: Vector3 = Vector3.ZERO) -> void if _dead or _hit_iframes > 0.0: return _hp -= 1 + _hit_flash() _hit_iframes = DP.f("bull_hit_iframes") health_changed.emit(_hp, _max_hp) hit_taken.emit(cause) @@ -1150,3 +1153,36 @@ func _spawn_blood(hit_pos: Vector3) -> void: p.global_position = hit_pos p.restart() _free_after(p, 1.5) + + +#hit flashing +func _hit_flash() -> void: + var meshes := find_children("*", "MeshInstance3D", true, false) + + for node in meshes: + var mesh := node as MeshInstance3D + if mesh: + mesh.material_overlay = _make_hit_overlay() + + if _hit_flash_tween: + _hit_flash_tween.kill() + + _hit_flash_tween = create_tween() + _hit_flash_tween.tween_interval(0.08) + _hit_flash_tween.tween_callback(_clear_hit_flash) + + +func _make_hit_overlay() -> StandardMaterial3D: + var mat := StandardMaterial3D.new() + mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED + mat.albedo_color = Color(1.0, 0.03, 0.03, 1.0) + return mat + + +func _clear_hit_flash() -> void: + var meshes := find_children("*", "MeshInstance3D", true, false) + + for node in meshes: + var mesh := node as MeshInstance3D + if mesh: + mesh.material_overlay = null