From 61446a0bcde8a41e8bc23860908f3a56747cd4e9 Mon Sep 17 00:00:00 2001 From: Twirpytherobot Date: Sat, 15 Nov 2025 17:07:28 +0000 Subject: [PATCH] Block maybe --- level/resources/weapon_shield.tres | 4 ++- level/scripts/base_unit.gd | 10 +++++++- level/scripts/base_weapon.gd | 7 +++++ level/scripts/player.gd | 41 +++++++++++++++++++++++++++++- level/scripts/weapon_data.gd | 4 +++ project.godot | 5 ++++ 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/level/resources/weapon_shield.tres b/level/resources/weapon_shield.tres index 9416b06..06b7019 100644 --- a/level/resources/weapon_shield.tres +++ b/level/resources/weapon_shield.tres @@ -6,10 +6,12 @@ [resource] script = ExtResource("1") weapon_name = "Wooden Shield" -description = "A sturdy wooden shield. Can be used to bash enemies." +description = "A sturdy wooden shield. Can be used to bash enemies or block attacks." hand_type = 1 damage = 8.0 attack_range = 2.5 attack_cooldown = 0.8 +can_block = true +block_reduction = 0.7 mesh_scene = ExtResource("2") weight = 3.0 diff --git a/level/scripts/base_unit.gd b/level/scripts/base_unit.gd index c3556bd..9fd78bd 100644 --- a/level/scripts/base_unit.gd +++ b/level/scripts/base_unit.gd @@ -34,8 +34,16 @@ func take_damage(amount: float, attacker_id: int = -1): if is_dead: return + # Apply blocking reduction if applicable (duck typing - check if method exists) + var final_damage = amount + if has_method("get_block_reduction"): + var block_reduction = call("get_block_reduction") + if block_reduction > 0.0: + final_damage = amount * (1.0 - block_reduction) + print("Blocked! Damage reduced from ", amount, " to ", final_damage, " (", block_reduction * 100, "% reduction)") + var old_health = current_health - current_health = max(0, current_health - amount) + current_health = max(0, current_health - final_damage) # Broadcast health change to all clients rpc("sync_health", current_health) diff --git a/level/scripts/base_weapon.gd b/level/scripts/base_weapon.gd index 1f839f8..55daba8 100644 --- a/level/scripts/base_weapon.gd +++ b/level/scripts/base_weapon.gd @@ -103,3 +103,10 @@ func get_range() -> float: func get_cooldown() -> float: return weapon_data.attack_cooldown if weapon_data else 0.0 + +## Blocking functionality +func can_block() -> bool: + return weapon_data.can_block if weapon_data else false + +func get_block_reduction() -> float: + return weapon_data.block_reduction if weapon_data else 0.0 diff --git a/level/scripts/player.gd b/level/scripts/player.gd index 954365c..49fb1bc 100644 --- a/level/scripts/player.gd +++ b/level/scripts/player.gd @@ -36,6 +36,7 @@ var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") var equipped_weapon: BaseWeapon = null # Main hand weapon var equipped_offhand: BaseWeapon = null # Off-hand weapon var _nearby_weapons: Array[WorldWeapon] = [] +var is_blocking: bool = false # Attack system @export var attack_damage: float = 10.0 @@ -165,8 +166,14 @@ func _process(delta): if Input.is_action_just_pressed("dash") and _dash_cooldown_timer <= 0 and not is_dead and is_on_floor(): _perform_dash() + # Handle block input + if Input.is_action_pressed("block") and not is_dead: + _try_block() + else: + is_blocking = false + # Handle attack input - if Input.is_action_just_pressed("attack") and not is_dead and not _is_dashing: + if Input.is_action_just_pressed("attack") and not is_dead and not _is_dashing and not is_blocking: _perform_attack() # Handle weapon pickup/drop @@ -270,6 +277,38 @@ func set_mesh_texture(mesh_instance: MeshInstance3D, texture: CompressedTexture2 new_material.albedo_texture = texture mesh_instance.set_surface_override_material(0, new_material) +## Block system +func _try_block(): + # Check if we have a weapon that can block + var can_block_weapon = false + + if equipped_weapon and equipped_weapon.can_block(): + can_block_weapon = true + elif equipped_offhand and equipped_offhand.can_block(): + can_block_weapon = true + + is_blocking = can_block_weapon + + # Could add blocking animation here + # if is_blocking and _body: + # _body.play_block_animation() + +## Get block reduction amount (0.0 to 1.0) +func get_block_reduction() -> float: + if not is_blocking: + return 0.0 + + var reduction = 0.0 + + # Use the highest block reduction from equipped weapons + if equipped_weapon and equipped_weapon.can_block(): + reduction = max(reduction, equipped_weapon.get_block_reduction()) + + if equipped_offhand and equipped_offhand.can_block(): + reduction = max(reduction, equipped_offhand.get_block_reduction()) + + return reduction + ## Attack system func _perform_attack(): if not is_multiplayer_authority() or is_dead: diff --git a/level/scripts/weapon_data.gd b/level/scripts/weapon_data.gd index a9f6777..193e319 100644 --- a/level/scripts/weapon_data.gd +++ b/level/scripts/weapon_data.gd @@ -17,6 +17,10 @@ enum Hand { MAIN_HAND, OFF_HAND, TWO_HAND } @export var attack_cooldown: float = 0.5 @export var attack_animation: String = "Attack1" # Animation to play when attacking +@export_category("Defense Stats") +@export var can_block: bool = false +@export_range(0.0, 1.0) var block_reduction: float = 0.5 # Percentage of damage blocked (0.5 = 50%) + @export_category("Visual") @export var mesh_scene: PackedScene # The 3D mesh for this weapon @export var icon: Texture2D # Optional icon for UI diff --git a/project.godot b/project.godot index 49a8a8f..2a68113 100644 --- a/project.godot +++ b/project.godot @@ -83,6 +83,11 @@ pickup={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) ] } +block={ +"deadzone": 0.5, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":2,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +} [layer_names]