added nice smoke puffs to interactible objects

This commit is contained in:
2026-01-11 12:27:02 +01:00
parent 3adf6660bb
commit 37b0d61566
13 changed files with 566 additions and 30 deletions

View File

@@ -40,6 +40,9 @@ var initial_player_position = Vector2.ZERO # Position of player when first grabb
var object_blocked_by_wall = false # True if pushed object is blocked by a wall
var was_dragging_last_frame = false # Track if we were dragging last frame to detect start/stop
# Level complete state
var controls_disabled: bool = false # True when player has reached exit and controls should be disabled
# Being held state
var being_held_by: Node = null
var struggle_time: float = 0.0
@@ -57,6 +60,7 @@ var attack_cooldown: float = 0.0 # No cooldown - instant attacks!
var is_attacking: bool = false
var sword_slash_scene = preload("res://scenes/sword_slash.tscn") # Old rotating version (kept for reference)
var sword_projectile_scene = preload("res://scenes/sword_projectile.tscn") # New projectile version
var blood_scene = preload("res://scenes/blood_clot.tscn")
# Simulated Z-axis for height (when thrown)
var position_z: float = 0.0
@@ -737,6 +741,11 @@ func _physics_process(delta):
if is_dead:
return
# Skip input if controls are disabled (e.g., when player reached exit)
if controls_disabled:
velocity = velocity.lerp(Vector2.ZERO, delta * 8.0) # Slow down movement
return
# Handle knockback timer
if is_knocked_back:
knockback_time += delta
@@ -2186,6 +2195,19 @@ func _die():
# Play death sound effect
if sfx_die:
for i in 12:
var angle = randf_range(0, TAU)
var speed = randf_range(50, 100)
var initial_velocityZ = randf_range(50, 90)
var b = blood_scene.instantiate() as CharacterBody2D
b.scale = Vector2(randf_range(0.3, 2), randf_range(0.3, 2))
b.global_position = global_position
# Set initial velocities from the synchronized data
var direction = Vector2.from_angle(angle)
b.velocity = direction * speed
b.velocityZ = initial_velocityZ
get_parent().call_deferred("add_child", b)
sfx_die.play()
# Play DIE animation
@@ -2419,20 +2441,26 @@ func add_coins(amount: int):
# Sync coins to client if this is server-side coin collection
# (e.g., when loot is collected on server, sync to client)
if multiplayer.has_multiplayer_peer() and multiplayer.is_server() and not is_multiplayer_authority() and can_send_rpcs and is_inside_tree():
# Server is adding coins to a client's player - sync to the client
var peer_id = get_multiplayer_authority()
if peer_id != 0:
_sync_stats_update.rpc_id(peer_id, character_stats.kills, character_stats.coin)
if multiplayer.has_multiplayer_peer() and multiplayer.is_server() and can_send_rpcs and is_inside_tree():
# Server is adding coins to a player - sync to the client if it's a client player
var the_peer_id = get_multiplayer_authority()
# Only sync if this is a client player (not server's own player)
if the_peer_id != 0 and the_peer_id != multiplayer.get_unique_id():
print(name, " syncing stats to client peer_id=", the_peer_id, " kills=", character_stats.kills, " coins=", character_stats.coin)
_sync_stats_update.rpc_id(the_peer_id, character_stats.kills, character_stats.coin)
else:
coins += amount
print(name, " picked up ", amount, " coin(s)! Total coins: ", coins)
@rpc("authority", "reliable")
@rpc("any_peer", "reliable")
func _sync_stats_update(kills_count: int, coins_count: int):
# Client receives stats update from server (for kills and coins)
# Update local stats to match server
# Only process on client (not on server where the update originated)
if multiplayer.is_server():
return # Server ignores this (it's the sender)
if character_stats:
character_stats.kills = kills_count
character_stats.coin = coins_count