fixed finally webrtc
This commit is contained in:
@@ -499,7 +499,19 @@ func setup_pot():
|
||||
|
||||
var pot_frames = [1, 2, 3, 20, 21, 22, 58]
|
||||
if sprite:
|
||||
sprite.frame = pot_frames[randi() % pot_frames.size()]
|
||||
var box_seed = 0
|
||||
var game_world = get_tree().get_first_node_in_group("game_world")
|
||||
if game_world and "dungeon_seed" in game_world:
|
||||
box_seed = game_world.dungeon_seed
|
||||
# Add position and object_index to seed to make each box unique but deterministic
|
||||
box_seed += int(global_position.x) * 1000 + int(global_position.y)
|
||||
if has_meta("object_index"):
|
||||
box_seed += get_meta("object_index") * 10000
|
||||
|
||||
var rng = RandomNumberGenerator.new()
|
||||
rng.seed = box_seed
|
||||
var index = rng.randi() % pot_frames.size()
|
||||
sprite.frame = pot_frames[index]
|
||||
|
||||
func setup_liftable_barrel():
|
||||
object_type = "LiftableBarrel"
|
||||
@@ -511,7 +523,19 @@ func setup_liftable_barrel():
|
||||
|
||||
var barrel_frames = [4, 23]
|
||||
if sprite:
|
||||
sprite.frame = barrel_frames[randi() % barrel_frames.size()]
|
||||
var box_seed = 0
|
||||
var game_world = get_tree().get_first_node_in_group("game_world")
|
||||
if game_world and "dungeon_seed" in game_world:
|
||||
box_seed = game_world.dungeon_seed
|
||||
# Add position and object_index to seed to make each box unique but deterministic
|
||||
box_seed += int(global_position.x) * 1000 + int(global_position.y)
|
||||
if has_meta("object_index"):
|
||||
box_seed += get_meta("object_index") * 10000
|
||||
|
||||
var rng = RandomNumberGenerator.new()
|
||||
rng.seed = box_seed
|
||||
var index = rng.randi() % barrel_frames.size()
|
||||
sprite.frame = barrel_frames[index]
|
||||
|
||||
func setup_pushable_barrel():
|
||||
object_type = "PushableBarrel"
|
||||
@@ -607,9 +631,9 @@ func setup_pushable_high_box():
|
||||
# Use deterministic randomness based on dungeon seed and position
|
||||
# This ensures host and clients get the same chest variant
|
||||
var highbox_seed = 0
|
||||
var game_world = get_tree().get_first_node_in_group("game_world")
|
||||
if game_world and "dungeon_seed" in game_world:
|
||||
highbox_seed = game_world.dungeon_seed
|
||||
var world = get_tree().get_first_node_in_group("game_world")
|
||||
if world and "dungeon_seed" in world:
|
||||
highbox_seed = world.dungeon_seed
|
||||
# Add position to seed to make each chest unique but deterministic
|
||||
highbox_seed += int(global_position.x) * 1000 + int(global_position.y)
|
||||
|
||||
@@ -634,77 +658,103 @@ func _open_chest(by_player: Node = null):
|
||||
|
||||
# Track opened chest for syncing to new clients
|
||||
if multiplayer.has_multiplayer_peer() and multiplayer.is_server():
|
||||
var game_world = get_tree().get_first_node_in_group("game_world")
|
||||
if game_world and has_meta("object_index"):
|
||||
var world = get_tree().get_first_node_in_group("game_world")
|
||||
if world and has_meta("object_index"):
|
||||
var obj_index = get_meta("object_index")
|
||||
game_world.opened_chests[obj_index] = true
|
||||
world.opened_chests[obj_index] = true
|
||||
LogManager.log("Chest: Tracked opened chest with index " + str(obj_index), LogManager.CATEGORY_NETWORK)
|
||||
if sprite and chest_opened_frame >= 0:
|
||||
sprite.frame = chest_opened_frame
|
||||
|
||||
# Random loot type
|
||||
var loot_types = [
|
||||
{"type": "coin", "name": "Coin", "color": Color(1.0, 0.84, 0.0)},
|
||||
{"type": "apple", "name": "Apple", "color": Color.GREEN},
|
||||
{"type": "banana", "name": "Banana", "color": Color.YELLOW},
|
||||
{"type": "cherry", "name": "Cherry", "color": Color.RED},
|
||||
{"type": "key", "name": "Key", "color": Color.YELLOW}
|
||||
]
|
||||
var selected_loot = loot_types[randi() % loot_types.size()]
|
||||
# Get random item from entire item database (using chest rarity weights)
|
||||
# Use deterministic randomness based on dungeon seed and chest position
|
||||
var chest_seed = 0
|
||||
var game_world = get_tree().get_first_node_in_group("game_world")
|
||||
if game_world and "dungeon_seed" in game_world:
|
||||
chest_seed = game_world.dungeon_seed
|
||||
# Add position to seed to make each chest unique but deterministic
|
||||
chest_seed += int(global_position.x) * 1000 + int(global_position.y)
|
||||
|
||||
# Create deterministic RNG for this chest
|
||||
var chest_rng = RandomNumberGenerator.new()
|
||||
chest_rng.seed = chest_seed
|
||||
|
||||
# Get random item using deterministic RNG
|
||||
# We need to manually select by rarity since get_random_chest_item() uses global randi()
|
||||
var rarity_roll = chest_rng.randf()
|
||||
var rarity: ItemDatabase.ItemRarity
|
||||
if rarity_roll < 0.4:
|
||||
rarity = ItemDatabase.ItemRarity.COMMON
|
||||
elif rarity_roll < 0.75:
|
||||
rarity = ItemDatabase.ItemRarity.UNCOMMON
|
||||
elif rarity_roll < 0.95:
|
||||
rarity = ItemDatabase.ItemRarity.RARE
|
||||
else:
|
||||
rarity = ItemDatabase.ItemRarity.EPIC if chest_rng.randf() < 0.5 else ItemDatabase.ItemRarity.CONSUMABLE
|
||||
|
||||
# Get candidates for this rarity using deterministic RNG
|
||||
ItemDatabase._initialize()
|
||||
var candidates = []
|
||||
# Access static item_definitions directly
|
||||
for item_id in ItemDatabase.item_definitions.keys():
|
||||
var item_data = ItemDatabase.item_definitions[item_id]
|
||||
if item_data.has("rarity") and item_data["rarity"] == rarity:
|
||||
candidates.append(item_id)
|
||||
|
||||
# Fallback to common if no candidates
|
||||
if candidates.is_empty():
|
||||
for item_id in ItemDatabase.item_definitions.keys():
|
||||
var item_data = ItemDatabase.item_definitions[item_id]
|
||||
if item_data.has("rarity") and item_data["rarity"] == ItemDatabase.ItemRarity.COMMON:
|
||||
candidates.append(item_id)
|
||||
|
||||
# Select random item from candidates using deterministic RNG
|
||||
var random_item_id = candidates[chest_rng.randi() % candidates.size()] if not candidates.is_empty() else null
|
||||
var chest_item = ItemDatabase.create_item(random_item_id) if random_item_id else null
|
||||
|
||||
# CRITICAL: Instantly give item to player instead of spawning loot object
|
||||
if by_player and is_instance_valid(by_player) and by_player.is_in_group("player"):
|
||||
# Give item directly to player based on type
|
||||
match selected_loot.type:
|
||||
"coin":
|
||||
if by_player.has_method("add_coins"):
|
||||
by_player.add_coins(1)
|
||||
# Show pickup notification with coin graphic
|
||||
var coin_texture = load("res://assets/gfx/pickups/gold_coin.png")
|
||||
_show_item_pickup_notification(by_player, "+1 COIN", selected_loot.color, coin_texture, 6, 1, 0)
|
||||
"apple":
|
||||
var heal_amount = 20.0
|
||||
if by_player.has_method("heal"):
|
||||
by_player.heal(heal_amount)
|
||||
# Show pickup notification with apple graphic
|
||||
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) + 10)
|
||||
"banana":
|
||||
var heal_amount = 20.0
|
||||
if by_player.has_method("heal"):
|
||||
by_player.heal(heal_amount)
|
||||
# Show pickup notification with banana graphic
|
||||
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)
|
||||
"cherry":
|
||||
var heal_amount = 20.0
|
||||
if by_player.has_method("heal"):
|
||||
by_player.heal(heal_amount)
|
||||
# Show pickup notification with cherry graphic
|
||||
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)
|
||||
"key":
|
||||
if by_player.has_method("add_key"):
|
||||
by_player.add_key(1)
|
||||
# Show pickup notification with key graphic
|
||||
var items_texture = load("res://assets/gfx/pickups/items_n_shit.png")
|
||||
_show_item_pickup_notification(by_player, "+1 KEY", selected_loot.color, items_texture, 20, 14, (13 * 20) + 10)
|
||||
if by_player and is_instance_valid(by_player) and by_player.is_in_group("player") and chest_item:
|
||||
# Add item to player inventory
|
||||
if by_player.character_stats:
|
||||
by_player.character_stats.add_item(chest_item)
|
||||
|
||||
# Show pickup notification
|
||||
var items_texture = load(chest_item.spritePath) if chest_item.spritePath != "" else null
|
||||
var display_text = chest_item.item_name.to_upper()
|
||||
var item_color = Color.WHITE
|
||||
|
||||
# Determine color based on item type/rarity
|
||||
if chest_item.item_type == Item.ItemType.Restoration:
|
||||
item_color = Color.GREEN
|
||||
elif chest_item.item_type == Item.ItemType.Equippable:
|
||||
item_color = Color.CYAN # Cyan for equipment (matches loot pickup color)
|
||||
else:
|
||||
item_color = Color.WHITE
|
||||
|
||||
# Show notification with item sprite
|
||||
if items_texture:
|
||||
_show_item_pickup_notification(by_player, display_text, item_color, items_texture, chest_item.spriteFrames.x, chest_item.spriteFrames.y, chest_item.spriteFrame)
|
||||
else:
|
||||
# Fallback: just show text
|
||||
_show_item_pickup_notification(by_player, display_text, item_color, null, 0, 0, 0)
|
||||
|
||||
# Play chest open sound
|
||||
if has_node("SfxChestOpen"):
|
||||
$SfxChestOpen.play()
|
||||
|
||||
print(name, " opened by ", by_player.name, "! Item given: ", selected_loot.name)
|
||||
print(name, " opened by ", by_player.name, "! Item given: ", chest_item.item_name)
|
||||
|
||||
# Sync chest opening visual to all clients (item already given on server)
|
||||
if multiplayer.has_multiplayer_peer():
|
||||
var player_peer_id = by_player.get_multiplayer_authority() if by_player else 0
|
||||
var game_world = get_tree().get_first_node_in_group("game_world")
|
||||
# Reuse game_world from earlier in the function
|
||||
if game_world and game_world.has_method("_rpc_to_ready_peers"):
|
||||
var chest_name = name
|
||||
if has_meta("object_index"):
|
||||
chest_name = "InteractableObject_%d" % get_meta("object_index")
|
||||
game_world._rpc_to_ready_peers("_sync_chest_open_by_name", [chest_name, selected_loot.type if by_player else "coin", player_peer_id])
|
||||
# Sync chest open visual with item_data so clients can show the floating text
|
||||
var item_data = chest_item.save() if chest_item else {}
|
||||
game_world._rpc_to_ready_peers("_sync_chest_open_by_name", [chest_name, "item", player_peer_id, item_data])
|
||||
else:
|
||||
push_error("Chest: ERROR - No valid player to give item to!")
|
||||
|
||||
@@ -737,7 +787,7 @@ func _request_chest_open(player_peer_id: int):
|
||||
_open_chest(player)
|
||||
|
||||
@rpc("any_peer", "reliable")
|
||||
func _sync_chest_open(loot_type_str: String = "coin", player_peer_id: int = 0):
|
||||
func _sync_chest_open(loot_type_str: String = "coin", player_peer_id: int = 0, item_data: Dictionary = {}):
|
||||
# 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:
|
||||
is_chest_opened = true
|
||||
@@ -757,26 +807,43 @@ func _sync_chest_open(loot_type_str: String = "coin", player_peer_id: int = 0):
|
||||
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)
|
||||
# If item_data is provided, use it to show item notification
|
||||
if not item_data.is_empty():
|
||||
var chest_item = Item.new(item_data)
|
||||
var items_texture = load(chest_item.spritePath) if chest_item.spritePath != "" else null
|
||||
var display_text = chest_item.item_name.to_upper()
|
||||
var item_color = Color.WHITE
|
||||
|
||||
if chest_item.item_type == Item.ItemType.Restoration:
|
||||
item_color = Color.GREEN
|
||||
elif chest_item.item_type == Item.ItemType.Equippable:
|
||||
item_color = Color.CYAN # Cyan for equipment (matches loot pickup color)
|
||||
|
||||
if items_texture:
|
||||
_show_item_pickup_notification(player, display_text, item_color, items_texture, chest_item.spriteFrames.x, chest_item.spriteFrames.y, chest_item.spriteFrame)
|
||||
else:
|
||||
_show_item_pickup_notification(player, display_text, item_color, null, 0, 0, 0)
|
||||
else:
|
||||
# Fallback to old loot type system (for backwards compatibility)
|
||||
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):
|
||||
# Show item graphic and text above player's head for 0.5s, then fade out over 0.5s
|
||||
|
||||
Reference in New Issue
Block a user