fixat mer med traps och arrows och grejjer

This commit is contained in:
2026-01-22 01:03:01 +01:00
parent c0d229ee86
commit eaf86b39fa
20 changed files with 1589 additions and 194 deletions

View File

@@ -18,6 +18,7 @@ var held_by_player = null
var is_frozen: bool = false
var thrown_by_player = null # Track who threw this box
var is_broken: bool = false
var has_dealt_damage: bool = false # Track if this thrown object has already damaged something
# Physics for thrown objects
var throw_velocity: Vector2 = Vector2.ZERO
@@ -129,6 +130,7 @@ func _land():
is_being_held = false # Make sure it can be grabbed again
held_by_player = null
thrown_by_player = null # Clear who threw it
has_dealt_damage = false # Reset damage flag for next throw
# Re-enable collision when landing
set_collision_layer_value(2, true)
@@ -158,15 +160,20 @@ func _land():
func _handle_air_collision():
# Handle collision while airborne
# CRITICAL: Only allow ONE damage event per throw
if has_dealt_damage:
return
for i in get_slide_collision_count():
var collision = get_slide_collision(i)
var collider = collision.get_collider()
# Pot special case: break on wall collision
if object_type == "Pot" and _is_wall_collider(collider):
# Break on wall collision (pots and boxes)
if (object_type == "Pot" or object_type == "Box") and _is_wall_collider(collider):
# Only process on server to prevent duplicates
if not multiplayer.is_server():
continue
has_dealt_damage = true # Mark as dealt damage (wall hit counts)
if is_destroyable:
if multiplayer.has_multiplayer_peer():
var game_world = get_tree().get_first_node_in_group("game_world")
@@ -181,11 +188,15 @@ func _handle_air_collision():
if not multiplayer.is_server():
continue
# Damage enemy
has_dealt_damage = true # Mark as dealt damage - can't damage anything else now
# Damage enemy (pots deal less damage than boxes)
# Enemy's take_damage() already handles defense calculation
if collider.has_method("take_damage"):
var attacker_pos = thrown_by_player.global_position if thrown_by_player and is_instance_valid(thrown_by_player) else global_position
collider.take_damage(15.0, attacker_pos)
print(name, " hit enemy ", collider.name, "!")
var base_damage = 10.0 if object_type == "Pot" else 15.0
collider.take_damage(base_damage, attacker_pos)
print(name, " hit enemy ", collider.name, " with thrown object (", base_damage, " base damage, defense will reduce)!")
# Box breaks (only if destroyable)
if is_destroyable:
@@ -209,6 +220,8 @@ func _handle_air_collision():
if not multiplayer.is_server():
continue
has_dealt_damage = true # Mark as dealt damage - can't damage anything else now
# Hit a player! Break locally and sync to others (only if destroyable)
if is_destroyable:
# Sync break to OTHER clients via RPC BEFORE breaking locally
@@ -220,23 +233,25 @@ func _handle_air_collision():
_break_into_pieces()
# Damage and knockback player using RPC
# Damage and knockback player using RPC (pots deal less damage than boxes)
# Player's take_damage() already handles defense calculation
# Pass the thrower's position for accurate direction
if collider.has_method("rpc_take_damage"):
var attacker_pos = thrown_by_player.global_position if thrown_by_player and is_instance_valid(thrown_by_player) else global_position
var base_damage = 7.0 if object_type == "Pot" else 10.0
var player_peer_id = collider.get_multiplayer_authority()
if player_peer_id != 0:
# If target peer is the same as server (us), call directly
# rpc_id() might not execute locally when called to same peer
if multiplayer.is_server() and player_peer_id == multiplayer.get_unique_id():
# Call directly on the same peer
collider.rpc_take_damage(10.0, attacker_pos)
collider.rpc_take_damage(base_damage, attacker_pos)
else:
# Send RPC to remote peer
collider.rpc_take_damage.rpc_id(player_peer_id, 10.0, attacker_pos)
collider.rpc_take_damage.rpc_id(player_peer_id, base_damage, attacker_pos)
else:
# Fallback: broadcast if we can't get peer_id
collider.rpc_take_damage.rpc(10.0, attacker_pos)
collider.rpc_take_damage.rpc(base_damage, attacker_pos)
print(name, " hit player ", collider.name, "!")
return
@@ -245,6 +260,8 @@ func _handle_air_collision():
if not multiplayer.is_server():
continue
has_dealt_damage = true # Mark as dealt damage - can't damage anything else now
# Hit another box! Break both locally (only if destroyable)
if is_destroyable:
# Sync break to OTHER clients via RPC BEFORE breaking locally
@@ -416,6 +433,7 @@ func on_grabbed(by_player):
is_being_held = true
held_by_player = by_player
has_dealt_damage = false # Reset damage flag when picked up
print(name, " grabbed by ", by_player.name)
func on_lifted(by_player):
@@ -434,6 +452,7 @@ func on_released(by_player):
position_z = 0.0
velocity_z = 0.0
throw_velocity = Vector2.ZERO
has_dealt_damage = false # Reset damage flag when released
# Re-enable collision (in case it was disabled)
set_collision_layer_value(2, true)
@@ -459,6 +478,7 @@ func on_thrown(by_player, force: Vector2):
held_by_player = null
thrown_by_player = by_player # Remember who threw this
is_frozen = false
has_dealt_damage = false # Reset damage flag - this throw can deal damage to ONE target
# Set throw velocity (affected by weight) - increased for longer arc
throw_velocity = force / weight
@@ -495,7 +515,7 @@ func setup_pot():
can_be_pushed = true
is_destroyable = true
is_liftable = true
weight = 1.0
weight = 0.8 # Pots are very light and easy to throw far!
var pot_frames = [1, 2, 3, 20, 21, 22, 58]
if sprite:
@@ -554,7 +574,7 @@ func setup_box():
can_be_pushed = true
is_destroyable = true
is_liftable = true
weight = 1.0
weight = 1.5 # Boxes are heavier than pots
var box_frames = [7, 26]
if sprite: