started working on fog darkness

This commit is contained in:
2026-01-13 00:16:08 +01:00
parent 82a70aa6a2
commit 89a41397d1
30 changed files with 1613 additions and 386 deletions

View File

@@ -7,6 +7,8 @@ var is_stuck = false
var stick_timer = 0.0
var initiated_by: Node2D = null
var player_owner: Node = null # Like sword_projectile
var hit_targets = {} # Track what we've already hit (Dictionary for O(1) lookup)
@onready var arrow_area = $ArrowArea # Assuming you have an Area2D node named ArrowArea
@onready var shadow = $Shadow # Assuming you have a Shadow node under the CharacterBody2D
@@ -14,7 +16,9 @@ var initiated_by: Node2D = null
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
arrow_area.set_deferred("monitoring", true)
#arrow_area.body_entered.connect(_on_body_entered)
# Connect area signals
if arrow_area:
arrow_area.body_entered.connect(_on_arrow_area_body_entered)
$SfxArrowFire.play()
call_deferred("_initialize_arrow")
@@ -49,10 +53,11 @@ func _initialize_arrow() -> void:
# Apply the scaling to the shadow
shadow.rotation = -(angle - PI / 2)
func shoot(shoot_direction: Vector2, start_pos: Vector2) -> void:
func shoot(shoot_direction: Vector2, start_pos: Vector2, owner_player: Node = null) -> void:
direction = shoot_direction.normalized()
global_position = start_pos
#position = start_pos
player_owner = owner_player
initiated_by = owner_player
# Called every frame. 'delta' is the e lapsed time since the previous frame.
func _process(delta: float) -> void:
@@ -76,94 +81,99 @@ func _physics_process(_delta: float) -> void:
func play_impact():
$SfxImpactSound.play()
# Called when the arrow hits a wall or another object
func _on_body_entered(body: Node) -> void:
if not is_stuck:
if body == initiated_by:
return
if body is CharacterBody2D and body.stats.is_invulnerable == false and body.stats.hp > 0: # hit an enemy
#if body is CharacterBody2D and body.collision_layer & (1 << 8) and body.taking_damage_timer <= 0 and body.stats.hp > 0: # Check if body is enemy (layer 9)
# Stop the arrow
velocity = Vector2.ZERO
is_stuck = true
stick_timer = 0.0
arrow_area.set_deferred("monitoring", false)
# Calculate the collision point - move arrow slightly back from its direction
var collision_normal = -direction # Opposite of arrow's direction
var offset_distance = 8 # Adjust this value based on your collision shape sizes
var stick_position = global_position + (collision_normal * offset_distance)
# Make arrow a child of the enemy to stick to it
var global_rot = global_rotation
get_parent().call_deferred("remove_child", self)
body.call_deferred("add_child", self)
self.set_deferred("global_position", stick_position)
self.set_deferred("global_rotation", global_rot)
#global_rotation = global_rot
body.call_deferred("take_damage", self, initiated_by)
self.call_deferred("play_impact") # need to play the sound on the next frame, because else it cuts it.
else:
$SfxImpactWall.play()
# Stop the arrow
velocity = Vector2.ZERO
is_stuck = true
stick_timer = 0.0
arrow_area.set_deferred("monitoring", false)
# You can optionally stick the arrow at the collision point if you want:
# position = body.position # Uncomment this if you want to "stick" it at the collision point
# Additional logic for handling interaction with walls or other objects
func _on_arrow_area_area_entered(area: Area2D) -> void:
if not is_stuck:
if area.get_parent() == initiated_by:
return
if area.get_parent() is CharacterBody2D and area.get_parent().stats.is_invulnerable == false and area.get_parent().stats.hp > 0: # hit an enemy
#if body is CharacterBody2D and body.collision_layer & (1 << 8) and body.taking_damage_timer <= 0 and body.stats.hp > 0: # Check if body is enemy (layer 9)
# Stop the arrow
velocity = Vector2.ZERO
is_stuck = true
stick_timer = 0.0
arrow_area.set_deferred("monitoring", false)
# Calculate the collision point - move arrow slightly back from its direction
var collision_normal = -direction # Opposite of arrow's direction
var offset_distance = 8 # Adjust this value based on your collision shape sizes
var stick_position = global_position + (collision_normal * offset_distance)
# Make arrow a child of the enemy to stick to it
var global_rot = global_rotation
get_parent().call_deferred("remove_child", self)
area.get_parent().call_deferred("add_child", self)
self.set_deferred("global_position", stick_position)
self.set_deferred("global_rotation", global_rot)
#global_rotation = global_rot
area.get_parent().call_deferred("take_damage", self, initiated_by)
self.call_deferred("play_impact") # need to play the sound on the next frame, because else it cuts it.
else:
$SfxImpactWall.play()
# Stop the arrow
velocity = Vector2.ZERO
is_stuck = true
stick_timer = 0.0
arrow_area.set_deferred("monitoring", false)
# You can optionally stick the arrow at the collision point if you want:
# position = body.position # Uncomment this if you want to "stick" it at the collision point
# Additional logic for handling interaction with walls or other objects
pass # Replace with function body.
# Called when the arrow hits a wall or another object (like sword_projectile)
func _on_arrow_area_body_entered(body: Node2D) -> void:
if not is_stuck:
if body == initiated_by:
if is_stuck:
return
# Don't hit the owner
if body == player_owner or body == initiated_by:
return
# Don't hit the same target twice
if body in hit_targets:
return
# CRITICAL: Only the projectile owner (authority) should deal damage
if player_owner and not player_owner.is_multiplayer_authority():
return # Only the authority (creator) of the projectile can deal damage
# Add to hit_targets IMMEDIATELY to prevent multiple hits
hit_targets[body] = true
# Deal damage to players
if body.is_in_group("player") and body.has_method("rpc_take_damage"):
play_impact()
var attacker_pos = player_owner.global_position if player_owner else global_position
var player_peer_id = body.get_multiplayer_authority()
if player_peer_id != 0:
if multiplayer.is_server() and player_peer_id == multiplayer.get_unique_id():
body.rpc_take_damage(20.0, attacker_pos) # TODO: Get actual damage from player
else:
body.rpc_take_damage.rpc_id(player_peer_id, 20.0, attacker_pos)
else:
body.rpc_take_damage.rpc(20.0, attacker_pos)
_stick_to_target(body)
return
# Deal damage to enemies
if body.is_in_group("enemy") and body.has_method("rpc_take_damage"):
var attacker_pos = player_owner.global_position if player_owner else global_position
var damage = 20.0 # TODO: Get actual damage from player
if player_owner and player_owner.character_stats:
damage = player_owner.character_stats.damage
# Check hit chance (based on player's DEX stat)
var hit_roll = randf()
var hit_chance = 0.95
if player_owner and player_owner.character_stats:
hit_chance = player_owner.character_stats.hit_chance
var is_miss = hit_roll >= hit_chance
if is_miss:
if body.has_method("_show_damage_number"):
body._show_damage_number(0.0, attacker_pos, false, true, false) # is_miss = true
_stick_to_target(body)
return
$SfxImpactWall.play()
# Stop the arrow
velocity = Vector2.ZERO
is_stuck = true
stick_timer = 0.0
arrow_area.set_deferred("monitoring", false)
pass # Replace with function body.
play_impact()
var enemy_peer_id = body.get_multiplayer_authority()
if enemy_peer_id != 0:
if multiplayer.is_server() and enemy_peer_id == multiplayer.get_unique_id():
body.rpc_take_damage(damage, attacker_pos, false)
else:
body.rpc_take_damage.rpc_id(enemy_peer_id, damage, attacker_pos, false)
else:
body.rpc_take_damage.rpc(damage, attacker_pos, false)
_stick_to_target(body)
return
# Hit wall or other object
$SfxImpactWall.play()
_stick_to_wall()
func _stick_to_target(target: Node2D):
# Stop the arrow
velocity = Vector2.ZERO
is_stuck = true
stick_timer = 0.0
arrow_area.set_deferred("monitoring", false)
# Calculate the collision point - move arrow slightly back from its direction
var collision_normal = -direction
var offset_distance = 8
var stick_position = global_position + (collision_normal * offset_distance)
# Make arrow a child of the target to stick to it
var global_rot = global_rotation
get_parent().call_deferred("remove_child", self)
target.call_deferred("add_child", self)
self.set_deferred("global_position", stick_position)
self.set_deferred("global_rotation", global_rot)
func _stick_to_wall():
# Stop the arrow
velocity = Vector2.ZERO
is_stuck = true
stick_timer = 0.0
arrow_area.set_deferred("monitoring", false)