* animate slime faster
* show loot text above head much closer to head
This commit is contained in:
@@ -1,27 +1,23 @@
|
|||||||
[gd_scene format=3 uid="uid://floating_text"]
|
[gd_scene format=3 uid="uid://dhhejfqlmhv52"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://scripts/floating_text.gd" id="1"]
|
[ext_resource type="Script" uid="uid://dx5oym20rr2ei" path="res://scripts/floating_text.gd" id="1"]
|
||||||
[ext_resource type="FontFile" uid="uid://cbmcfue0ek0tk" path="res://assets/fonts/dmg_numbers.png" id="2_dmg_font"]
|
[ext_resource type="FontFile" uid="uid://cbmcfue0ek0tk" path="res://assets/fonts/dmg_numbers.png" id="2_dmg_font"]
|
||||||
|
|
||||||
[sub_resource type="Theme" id="Theme_floating_text"]
|
[sub_resource type="Theme" id="Theme_floating_text"]
|
||||||
default_font = ExtResource("2_dmg_font")
|
default_font = ExtResource("2_dmg_font")
|
||||||
default_font_size = 12
|
default_font_size = 12
|
||||||
|
|
||||||
[node name="FloatingText" type="Node2D"]
|
[node name="FloatingText" type="Node2D" unique_id=1350559946]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
|
|
||||||
[node name="ItemSprite" type="Sprite2D" parent="."]
|
[node name="ItemSprite" type="Sprite2D" parent="." unique_id=1657362510]
|
||||||
visible = false
|
visible = false
|
||||||
offset = Vector2(0, -20)
|
offset = Vector2(0, -8)
|
||||||
scale = Vector2(1, 1)
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="."]
|
[node name="Label" type="Label" parent="." unique_id=1387220833]
|
||||||
offset_right = 64.0
|
offset_right = 64.0
|
||||||
offset_bottom = 24.0
|
offset_bottom = 24.0
|
||||||
theme = SubResource("Theme_floating_text")
|
theme = SubResource("Theme_floating_text")
|
||||||
text = "+1 coin"
|
text = "+1 coin"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
outline_size = 2
|
|
||||||
outline_color = Color(0, 0, 0, 1)
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,14 +13,44 @@ var detection_range: float = 70.0 # Range to detect players (much smaller)
|
|||||||
|
|
||||||
# Jump mechanics
|
# Jump mechanics
|
||||||
var is_jumping: bool = false
|
var is_jumping: bool = false
|
||||||
var jump_anim_frames = [2, 3, 4, 5, 7, 2] # Jump animation sequence
|
|
||||||
var jump_anim_index: int = 0
|
|
||||||
|
|
||||||
# Animation frames
|
# Animation system (similar to player)
|
||||||
const FRAME_IDLE = 0
|
const ANIMATIONS = {
|
||||||
const FRAMES_MOVE = [0, 1, 2] # Slow move
|
"IDLE": {
|
||||||
const FRAMES_DAMAGE = [8, 9]
|
"frames": [0],
|
||||||
const FRAMES_DEATH = [8, 9, 10, 11, 12, 13, 14]
|
"frameDurations": [500],
|
||||||
|
"loop": true,
|
||||||
|
"nextAnimation": null
|
||||||
|
},
|
||||||
|
"MOVE": {
|
||||||
|
"frames": [0, 1, 2],
|
||||||
|
"frameDurations": [200, 200, 200],
|
||||||
|
"loop": true,
|
||||||
|
"nextAnimation": null
|
||||||
|
},
|
||||||
|
"JUMP": {
|
||||||
|
"frames": [2, 3, 4, 5, 7, 2],
|
||||||
|
"frameDurations": [100, 100, 100, 100, 100, 100],
|
||||||
|
"loop": false,
|
||||||
|
"nextAnimation": "MOVE"
|
||||||
|
},
|
||||||
|
"DAMAGE": {
|
||||||
|
"frames": [8, 9],
|
||||||
|
"frameDurations": [150, 150],
|
||||||
|
"loop": false,
|
||||||
|
"nextAnimation": "IDLE"
|
||||||
|
},
|
||||||
|
"DIE": {
|
||||||
|
"frames": [8, 9, 10, 11, 12, 13, 14],
|
||||||
|
"frameDurations": [70, 70, 70, 70, 70, 70, 200],
|
||||||
|
"loop": false,
|
||||||
|
"nextAnimation": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var current_animation = "IDLE"
|
||||||
|
var current_frame = 0
|
||||||
|
var time_since_last_frame = 0.0
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
super._ready()
|
super._ready()
|
||||||
@@ -71,7 +101,7 @@ func _ai_behavior(delta):
|
|||||||
|
|
||||||
func _idle_behavior(_delta):
|
func _idle_behavior(_delta):
|
||||||
velocity = Vector2.ZERO
|
velocity = Vector2.ZERO
|
||||||
anim_frame = FRAME_IDLE
|
_set_animation("IDLE")
|
||||||
|
|
||||||
# Check if player is nearby
|
# Check if player is nearby
|
||||||
if target_player:
|
if target_player:
|
||||||
@@ -94,6 +124,8 @@ func _idle_behavior(_delta):
|
|||||||
state_timer = move_duration
|
state_timer = move_duration
|
||||||
|
|
||||||
func _moving_behavior(_delta):
|
func _moving_behavior(_delta):
|
||||||
|
_set_animation("MOVE")
|
||||||
|
|
||||||
# Move slowly towards player
|
# Move slowly towards player
|
||||||
if target_player and is_instance_valid(target_player):
|
if target_player and is_instance_valid(target_player):
|
||||||
var direction = (target_player.global_position - global_position).normalized()
|
var direction = (target_player.global_position - global_position).normalized()
|
||||||
@@ -117,9 +149,8 @@ func _moving_behavior(_delta):
|
|||||||
func _start_jump():
|
func _start_jump():
|
||||||
state = SlimeState.JUMPING
|
state = SlimeState.JUMPING
|
||||||
is_jumping = true
|
is_jumping = true
|
||||||
jump_anim_index = 0
|
|
||||||
state_timer = 0.6 # Jump duration
|
state_timer = 0.6 # Jump duration
|
||||||
anim_time = 0.0
|
_set_animation("JUMP")
|
||||||
|
|
||||||
# Jump towards player if nearby
|
# Jump towards player if nearby
|
||||||
if target_player and is_instance_valid(target_player):
|
if target_player and is_instance_valid(target_player):
|
||||||
@@ -142,57 +173,46 @@ func _jumping_behavior(_delta):
|
|||||||
|
|
||||||
func _damaged_behavior(_delta):
|
func _damaged_behavior(_delta):
|
||||||
velocity = Vector2.ZERO
|
velocity = Vector2.ZERO
|
||||||
|
_set_animation("DAMAGE")
|
||||||
|
|
||||||
# Stay in damaged state briefly
|
# Stay in damaged state briefly
|
||||||
if state_timer <= 0:
|
if state_timer <= 0:
|
||||||
state = SlimeState.IDLE
|
state = SlimeState.IDLE
|
||||||
state_timer = idle_duration
|
state_timer = idle_duration
|
||||||
|
|
||||||
func _update_animation(delta):
|
func _set_animation(anim_name: String):
|
||||||
if state == SlimeState.DYING or state == SlimeState.DAMAGED:
|
if current_animation != anim_name:
|
||||||
return # Animation handled elsewhere
|
current_animation = anim_name
|
||||||
|
current_frame = 0
|
||||||
|
time_since_last_frame = 0.0
|
||||||
|
|
||||||
if state == SlimeState.IDLE:
|
func _update_animation(delta):
|
||||||
anim_frame = FRAME_IDLE
|
# Update animation frame timing
|
||||||
elif state == SlimeState.JUMPING:
|
time_since_last_frame += delta
|
||||||
# Animate jump sequence
|
if time_since_last_frame >= ANIMATIONS[current_animation]["frameDurations"][current_frame] / 1000.0:
|
||||||
anim_time += delta
|
current_frame += 1
|
||||||
if anim_time >= 0.1: # Fast jump animation
|
if current_frame >= len(ANIMATIONS[current_animation]["frames"]):
|
||||||
anim_time = 0.0
|
current_frame -= 1 # Prevent out of bounds
|
||||||
jump_anim_index += 1
|
if ANIMATIONS[current_animation]["loop"]:
|
||||||
if jump_anim_index < jump_anim_frames.size():
|
current_frame = 0
|
||||||
anim_frame = jump_anim_frames[jump_anim_index]
|
elif ANIMATIONS[current_animation]["nextAnimation"] != null:
|
||||||
elif state == SlimeState.MOVING:
|
current_frame = 0
|
||||||
# Animate slow move (frames 0, 1, 2)
|
current_animation = ANIMATIONS[current_animation]["nextAnimation"]
|
||||||
anim_time += delta
|
time_since_last_frame = 0.0
|
||||||
if anim_time >= anim_speed:
|
|
||||||
anim_time = 0.0
|
# Calculate frame index
|
||||||
var move_index = FRAMES_MOVE.find(anim_frame)
|
var frame_index = ANIMATIONS[current_animation]["frames"][current_frame]
|
||||||
if move_index == -1:
|
|
||||||
move_index = 0
|
|
||||||
else:
|
|
||||||
move_index = (move_index + 1) % FRAMES_MOVE.size()
|
|
||||||
anim_frame = FRAMES_MOVE[move_index]
|
|
||||||
|
|
||||||
# Set sprite frame (slime looks same in all directions)
|
# Set sprite frame (slime looks same in all directions)
|
||||||
if sprite:
|
if sprite:
|
||||||
sprite.frame = anim_frame
|
sprite.frame = frame_index
|
||||||
|
anim_frame = frame_index # Keep anim_frame updated for compatibility
|
||||||
|
|
||||||
func _on_take_damage():
|
func _on_take_damage():
|
||||||
# Play damage animation
|
# Play damage animation
|
||||||
state = SlimeState.DAMAGED
|
state = SlimeState.DAMAGED
|
||||||
state_timer = 0.3
|
state_timer = 0.3
|
||||||
anim_time = 0.0
|
_set_animation("DAMAGE")
|
||||||
|
|
||||||
# Animate damage frames
|
|
||||||
_play_damage_anim()
|
|
||||||
|
|
||||||
func _play_damage_anim():
|
|
||||||
for frame in FRAMES_DAMAGE:
|
|
||||||
anim_frame = frame
|
|
||||||
if sprite:
|
|
||||||
sprite.frame = frame
|
|
||||||
await get_tree().create_timer(0.1).timeout
|
|
||||||
|
|
||||||
func _die():
|
func _die():
|
||||||
if is_dead:
|
if is_dead:
|
||||||
@@ -204,6 +224,7 @@ func _die():
|
|||||||
# Set state before calling parent _die()
|
# Set state before calling parent _die()
|
||||||
state = SlimeState.DYING
|
state = SlimeState.DYING
|
||||||
velocity = Vector2.ZERO
|
velocity = Vector2.ZERO
|
||||||
|
_set_animation("DIE")
|
||||||
|
|
||||||
# Call parent _die() which handles death sync and _play_death_animation()
|
# Call parent _die() which handles death sync and _play_death_animation()
|
||||||
super._die()
|
super._die()
|
||||||
@@ -220,12 +241,13 @@ func _update_client_visuals():
|
|||||||
sprite.frame = anim_frame
|
sprite.frame = anim_frame
|
||||||
|
|
||||||
func _play_death_animation():
|
func _play_death_animation():
|
||||||
# Play death animation sequence
|
_set_animation("DIE")
|
||||||
for frame in FRAMES_DEATH:
|
|
||||||
anim_frame = frame
|
# Wait for death animation to complete
|
||||||
if sprite:
|
var total_duration = 0.0
|
||||||
sprite.frame = frame
|
for duration in ANIMATIONS["DIE"]["frameDurations"]:
|
||||||
await get_tree().create_timer(0.15).timeout
|
total_duration += duration / 1000.0
|
||||||
|
await get_tree().create_timer(total_duration).timeout
|
||||||
|
|
||||||
# Fade out
|
# Fade out
|
||||||
if sprite:
|
if sprite:
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ func setup(text_value: String, text_color: Color, show_time: float = 0.5, fade_t
|
|||||||
label.text = text
|
label.text = text
|
||||||
label.modulate = color
|
label.modulate = color
|
||||||
label.modulate.a = 1.0 # Start fully visible
|
label.modulate.a = 1.0 # Start fully visible
|
||||||
|
label.z_index = 10 # Render above other objects
|
||||||
|
|
||||||
# Setup item sprite if texture provided
|
# Setup item sprite if texture provided
|
||||||
if item_sprite and item_texture:
|
if item_sprite and item_texture:
|
||||||
@@ -32,9 +33,10 @@ func setup(text_value: String, text_color: Color, show_time: float = 0.5, fade_t
|
|||||||
item_sprite.frame = sprite_frame
|
item_sprite.frame = sprite_frame
|
||||||
item_sprite.modulate = Color.WHITE
|
item_sprite.modulate = Color.WHITE
|
||||||
item_sprite.modulate.a = 1.0
|
item_sprite.modulate.a = 1.0
|
||||||
|
item_sprite.z_index = 10 # Render above other objects
|
||||||
# Position sprite above label (if label exists) or centered
|
# Position sprite above label (if label exists) or centered
|
||||||
if label:
|
if label:
|
||||||
item_sprite.position = Vector2(0, -24) # Above the text (sprite is ~16px tall)
|
item_sprite.position = Vector2(0, -12) # Just above the text (sprite is ~16px tall)
|
||||||
else:
|
else:
|
||||||
item_sprite.position = Vector2(0, 0)
|
item_sprite.position = Vector2(0, 0)
|
||||||
|
|
||||||
@@ -96,4 +98,3 @@ func _animate_coin():
|
|||||||
await get_tree().create_timer(coin_frame_time).timeout
|
await get_tree().create_timer(coin_frame_time).timeout
|
||||||
if item_sprite and is_instance_valid(item_sprite) and item_sprite.visible:
|
if item_sprite and is_instance_valid(item_sprite) and item_sprite.visible:
|
||||||
item_sprite.frame = target_frame
|
item_sprite.frame = target_frame
|
||||||
|
|
||||||
|
|||||||
@@ -2634,9 +2634,10 @@ func _place_key_in_room(room: Dictionary):
|
|||||||
valid_positions.append(Vector2(world_x, world_y))
|
valid_positions.append(Vector2(world_x, world_y))
|
||||||
|
|
||||||
if valid_positions.size() > 0:
|
if valid_positions.size() > 0:
|
||||||
# Pick a random position
|
# Use deterministic seed for key placement (ensures same position on host and clients)
|
||||||
var rng = RandomNumberGenerator.new()
|
var rng = RandomNumberGenerator.new()
|
||||||
rng.randomize()
|
var key_seed = dungeon_seed + (room.x * 1000) + (room.y * 100) + 5000 # Offset to avoid collisions with other objects
|
||||||
|
rng.seed = key_seed
|
||||||
var key_pos = valid_positions[rng.randi() % valid_positions.size()]
|
var key_pos = valid_positions[rng.randi() % valid_positions.size()]
|
||||||
|
|
||||||
# Spawn key loot
|
# Spawn key loot
|
||||||
|
|||||||
@@ -530,21 +530,21 @@ func _open_chest(by_player: Node = null):
|
|||||||
by_player.heal(heal_amount)
|
by_player.heal(heal_amount)
|
||||||
# Show pickup notification with apple graphic
|
# Show pickup notification with apple graphic
|
||||||
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
_show_item_pickup_notification(by_player, "+" + str(int(heal_amount)) + " HP", selected_loot.color, items_texture, 20, 14, (8 * 20) + 11)
|
_show_item_pickup_notification(by_player, "+" + str(int(heal_amount)) + " HP", selected_loot.color, items_texture, 20, 14, (8 * 20) + 10)
|
||||||
"banana":
|
"banana":
|
||||||
var heal_amount = 20.0
|
var heal_amount = 20.0
|
||||||
if by_player.has_method("heal"):
|
if by_player.has_method("heal"):
|
||||||
by_player.heal(heal_amount)
|
by_player.heal(heal_amount)
|
||||||
# Show pickup notification with banana graphic
|
# Show pickup notification with banana graphic
|
||||||
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
_show_item_pickup_notification(by_player, "+" + str(int(heal_amount)) + " HP", selected_loot.color, items_texture, 20, 14, (8 * 20) + 12)
|
_show_item_pickup_notification(by_player, "+" + str(int(heal_amount)) + " HP", selected_loot.color, items_texture, 20, 14, (8 * 20) + 11)
|
||||||
"cherry":
|
"cherry":
|
||||||
var heal_amount = 20.0
|
var heal_amount = 20.0
|
||||||
if by_player.has_method("heal"):
|
if by_player.has_method("heal"):
|
||||||
by_player.heal(heal_amount)
|
by_player.heal(heal_amount)
|
||||||
# Show pickup notification with cherry graphic
|
# Show pickup notification with cherry graphic
|
||||||
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
_show_item_pickup_notification(by_player, "+" + str(int(heal_amount)) + " HP", selected_loot.color, items_texture, 20, 14, (8 * 20) + 13)
|
_show_item_pickup_notification(by_player, "+" + str(int(heal_amount)) + " HP", selected_loot.color, items_texture, 20, 14, (8 * 20) + 12)
|
||||||
"key":
|
"key":
|
||||||
if by_player.has_method("add_key"):
|
if by_player.has_method("add_key"):
|
||||||
by_player.add_key(1)
|
by_player.add_key(1)
|
||||||
@@ -562,7 +562,8 @@ func _open_chest(by_player: Node = null):
|
|||||||
|
|
||||||
# Sync chest opening visual to all clients (item already given on server)
|
# Sync chest opening visual to all clients (item already given on server)
|
||||||
if multiplayer.has_multiplayer_peer():
|
if multiplayer.has_multiplayer_peer():
|
||||||
_sync_chest_open.rpc(selected_loot.type if by_player else "coin")
|
var player_peer_id = by_player.get_multiplayer_authority() if by_player else 0
|
||||||
|
_sync_chest_open.rpc(selected_loot.type if by_player else "coin", player_peer_id)
|
||||||
|
|
||||||
@rpc("any_peer", "reliable")
|
@rpc("any_peer", "reliable")
|
||||||
func _request_chest_open(player_peer_id: int):
|
func _request_chest_open(player_peer_id: int):
|
||||||
@@ -593,7 +594,7 @@ func _request_chest_open(player_peer_id: int):
|
|||||||
_open_chest(player)
|
_open_chest(player)
|
||||||
|
|
||||||
@rpc("any_peer", "reliable")
|
@rpc("any_peer", "reliable")
|
||||||
func _sync_chest_open(_loot_type_str: String = "coin"):
|
func _sync_chest_open(loot_type_str: String = "coin", player_peer_id: int = 0):
|
||||||
# Sync chest opening to all clients (only visual - item already given on server)
|
# Sync chest opening to all clients (only visual - item already given on server)
|
||||||
if not is_chest_opened and sprite and chest_opened_frame >= 0:
|
if not is_chest_opened and sprite and chest_opened_frame >= 0:
|
||||||
is_chest_opened = true
|
is_chest_opened = true
|
||||||
@@ -603,6 +604,37 @@ func _sync_chest_open(_loot_type_str: String = "coin"):
|
|||||||
if has_node("SfxChestOpen"):
|
if has_node("SfxChestOpen"):
|
||||||
$SfxChestOpen.play()
|
$SfxChestOpen.play()
|
||||||
|
|
||||||
|
# Show pickup notification on client side
|
||||||
|
if player_peer_id > 0:
|
||||||
|
var players = get_tree().get_nodes_in_group("player")
|
||||||
|
var player = null
|
||||||
|
for p in players:
|
||||||
|
if p.get_multiplayer_authority() == player_peer_id:
|
||||||
|
player = p
|
||||||
|
break
|
||||||
|
|
||||||
|
if player and is_instance_valid(player):
|
||||||
|
# Show notification based on loot type (same as server)
|
||||||
|
match loot_type_str:
|
||||||
|
"coin":
|
||||||
|
var coin_texture = load("res://assets/gfx/pickups/gold_coin.png")
|
||||||
|
_show_item_pickup_notification(player, "+1 COIN", Color(1.0, 0.84, 0.0), coin_texture, 6, 1, 0)
|
||||||
|
"apple":
|
||||||
|
var heal_amount = 20.0
|
||||||
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
|
_show_item_pickup_notification(player, "+" + str(int(heal_amount)) + " HP", Color.GREEN, items_texture, 20, 14, (8 * 20) + 10)
|
||||||
|
"banana":
|
||||||
|
var heal_amount = 20.0
|
||||||
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
|
_show_item_pickup_notification(player, "+" + str(int(heal_amount)) + " HP", Color.YELLOW, items_texture, 20, 14, (8 * 20) + 11)
|
||||||
|
"cherry":
|
||||||
|
var heal_amount = 20.0
|
||||||
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
|
_show_item_pickup_notification(player, "+" + str(int(heal_amount)) + " HP", Color.RED, items_texture, 20, 14, (8 * 20) + 12)
|
||||||
|
"key":
|
||||||
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
|
_show_item_pickup_notification(player, "+1 KEY", Color.YELLOW, items_texture, 20, 14, (13 * 20) + 10)
|
||||||
|
|
||||||
func _show_item_pickup_notification(player: Node, text: String, text_color: Color, item_texture: Texture2D = null, sprite_hframes: int = 1, sprite_vframes: int = 1, sprite_frame: int = 0):
|
func _show_item_pickup_notification(player: Node, text: String, text_color: Color, item_texture: Texture2D = null, sprite_hframes: int = 1, sprite_vframes: int = 1, sprite_frame: int = 0):
|
||||||
# Show item graphic and text above player's head for 0.5s, then fade out over 0.5s
|
# Show item graphic and text above player's head for 0.5s, then fade out over 0.5s
|
||||||
var floating_text_scene = preload("res://scenes/floating_text.tscn")
|
var floating_text_scene = preload("res://scenes/floating_text.tscn")
|
||||||
@@ -611,7 +643,8 @@ func _show_item_pickup_notification(player: Node, text: String, text_color: Colo
|
|||||||
var parent = player.get_parent()
|
var parent = player.get_parent()
|
||||||
if parent:
|
if parent:
|
||||||
parent.add_child(floating_text)
|
parent.add_child(floating_text)
|
||||||
floating_text.global_position = player.global_position + Vector2(0, -20)
|
# Position at player.position.y - 20 (just above head)
|
||||||
|
floating_text.global_position = Vector2(player.global_position.x, player.global_position.y - 20)
|
||||||
floating_text.setup(text, text_color, 0.5, 0.5, item_texture, sprite_hframes, sprite_vframes, sprite_frame) # Show for 0.5s, fade over 0.5s
|
floating_text.setup(text, text_color, 0.5, 0.5, item_texture, sprite_hframes, sprite_vframes, sprite_frame) # Show for 0.5s, fade over 0.5s
|
||||||
|
|
||||||
func play_destroy_sound():
|
func play_destroy_sound():
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ func _process_pickup_on_server(player: Node):
|
|||||||
player.heal(heal_amount)
|
player.heal(heal_amount)
|
||||||
# Show floating text with item graphic and heal amount
|
# Show floating text with item graphic and heal amount
|
||||||
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
_show_floating_text(player, "+" + str(int(actual_heal)) + " HP", Color.GREEN, 0.5, 0.5, items_texture, 20, 14, (8 * 20) + 11)
|
_show_floating_text(player, "+" + str(int(actual_heal)) + " HP", Color.GREEN, 0.5, 0.5, items_texture, 20, 14, (8 * 20) + 10)
|
||||||
|
|
||||||
self.visible = false
|
self.visible = false
|
||||||
|
|
||||||
@@ -399,7 +399,7 @@ func _process_pickup_on_server(player: Node):
|
|||||||
player.heal(heal_amount)
|
player.heal(heal_amount)
|
||||||
# Show floating text with item graphic and heal amount
|
# Show floating text with item graphic and heal amount
|
||||||
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
_show_floating_text(player, "+" + str(int(actual_heal)) + " HP", Color.GREEN, 0.5, 0.5, items_texture, 20, 14, (8 * 20) + 12)
|
_show_floating_text(player, "+" + str(int(actual_heal)) + " HP", Color.GREEN, 0.5, 0.5, items_texture, 20, 14, (8 * 20) + 11)
|
||||||
|
|
||||||
self.visible = false
|
self.visible = false
|
||||||
|
|
||||||
@@ -417,7 +417,7 @@ func _process_pickup_on_server(player: Node):
|
|||||||
player.heal(heal_amount)
|
player.heal(heal_amount)
|
||||||
# Show floating text with item graphic and heal amount
|
# Show floating text with item graphic and heal amount
|
||||||
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||||
_show_floating_text(player, "+" + str(int(actual_heal)) + " HP", Color.GREEN, 0.5, 0.5, items_texture, 20, 14, (8 * 20) + 13)
|
_show_floating_text(player, "+" + str(int(actual_heal)) + " HP", Color.GREEN, 0.5, 0.5, items_texture, 20, 14, (8 * 20) + 12)
|
||||||
|
|
||||||
self.visible = false
|
self.visible = false
|
||||||
|
|
||||||
@@ -545,5 +545,5 @@ func _show_floating_text(player: Node, text: String, color: Color, show_time: fl
|
|||||||
var parent = player.get_parent()
|
var parent = player.get_parent()
|
||||||
if parent:
|
if parent:
|
||||||
parent.add_child(floating_text)
|
parent.add_child(floating_text)
|
||||||
floating_text.global_position = player.global_position + Vector2(0, -20)
|
floating_text.global_position = Vector2(player.global_position.x, player.global_position.y)
|
||||||
floating_text.setup(text, color, show_time, fade_time, item_texture, sprite_hframes, sprite_vframes, sprite_frame)
|
floating_text.setup(text, color, show_time, fade_time, item_texture, sprite_hframes, sprite_vframes, sprite_frame)
|
||||||
|
|||||||
@@ -2148,12 +2148,39 @@ func _die():
|
|||||||
is_dead = true # Ensure flag is set
|
is_dead = true # Ensure flag is set
|
||||||
velocity = Vector2.ZERO
|
velocity = Vector2.ZERO
|
||||||
is_knocked_back = false
|
is_knocked_back = false
|
||||||
is_lifting = false
|
|
||||||
is_pushing = false
|
|
||||||
held_object = null
|
|
||||||
|
|
||||||
# Don't force release - let them carry the corpse
|
# CRITICAL: Release any held object/player BEFORE dying to restore their collision layers
|
||||||
# We'll handle release during respawn
|
if held_object:
|
||||||
|
var released_obj = held_object
|
||||||
|
held_object = null
|
||||||
|
is_lifting = false
|
||||||
|
is_pushing = false
|
||||||
|
grab_offset = Vector2.ZERO
|
||||||
|
push_axis = Vector2.ZERO
|
||||||
|
|
||||||
|
# Re-enable collision for released object/player
|
||||||
|
if _is_box(released_obj):
|
||||||
|
released_obj.set_collision_layer_value(2, true)
|
||||||
|
released_obj.set_collision_mask_value(1, true)
|
||||||
|
released_obj.set_collision_mask_value(2, true)
|
||||||
|
if "is_being_held" in released_obj:
|
||||||
|
released_obj.is_being_held = false
|
||||||
|
if "held_by_player" in released_obj:
|
||||||
|
released_obj.held_by_player = null
|
||||||
|
elif _is_player(released_obj):
|
||||||
|
released_obj.set_collision_layer_value(1, true)
|
||||||
|
released_obj.set_collision_mask_value(1, true)
|
||||||
|
if released_obj.has_method("set_being_held"):
|
||||||
|
released_obj.set_being_held(false)
|
||||||
|
|
||||||
|
# Sync release to network
|
||||||
|
if multiplayer.has_multiplayer_peer() and is_multiplayer_authority() and can_send_rpcs and is_inside_tree():
|
||||||
|
_sync_release.rpc(released_obj.get_path())
|
||||||
|
|
||||||
|
print(name, " released ", released_obj.name, " on death")
|
||||||
|
else:
|
||||||
|
is_lifting = false
|
||||||
|
is_pushing = false
|
||||||
|
|
||||||
print(name, " died!")
|
print(name, " died!")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user