update scarcity

This commit is contained in:
2026-01-27 03:43:51 +08:00
parent d262bb8dc0
commit d71f5d67e3
7 changed files with 948 additions and 563 deletions
+38
View File
@@ -159,8 +159,46 @@ func _execute_grab(grid_pos: Vector2i, cell: Vector3i, item_id: int):
# 3f. Reset the UI for the player who acted
player.rpc("force_action_state_none")
# 4. Check if we need to respawn tiles (Scarcity Logic)
# "during no more tiles" -> Refill if floor is empty
_check_and_refill_grid_if_needed(server_gridmap)
return true
func _check_and_refill_grid_if_needed(server_gridmap: Node):
# Check if there are any items left on floor 1
var has_items = false
var item_list = server_gridmap.mesh_library.get_item_list() if server_gridmap.mesh_library else []
# We can't efficiently iterate all cells, but we can check usage via get_used_cells_by_item is too specific
# Iterating columns/rows is safe for this map size (10x10 usually)
for x in range(server_gridmap.columns):
for z in range(server_gridmap.rows):
var item = server_gridmap.get_cell_item(Vector3i(x, 1, z))
if item != -1:
has_items = true
break
if has_items:
break
if not has_items:
print("[PlayerboardManager] Floor 1 empty! Respawning tiles with Scarcity...")
# Call randomize_floor on floor 1
# Since Main owns gridmap, we can sync this or just do it server side (which we are)
server_gridmap.randomize_floor(1)
# We need to sync the ENTIRE floor to clients.
# EnhancedGridMap doesn't have a "Sync Floor" RPC built-in to Main, only single cells or array update.
# Main.gd has sync_grid_item which handles single cells.
# Ideally we'd loop and sync all, or add a method to Main to sync floor.
# Loop is okay for 10x10 (100 RPCs is a bit much but acceptable for a rare event).
var main = player.get_tree().get_root().get_node_or_null("Main")
if main:
for x in range(server_gridmap.columns):
for z in range(server_gridmap.rows):
var item = server_gridmap.get_cell_item(Vector3i(x, 1, z))
main.rpc("sync_grid_item", x, 1, z, item)
func bot_try_grab_item() -> bool:
if not enhanced_gridmap or player.action_points <= 0:
return false
+51
View File
@@ -0,0 +1,51 @@
extends Node
class_name ScarcityManager
# ScarcityManager - Handles weighted random, tile generation for gameplay balance
const TILES = [7, 8, 9, 10]
const SPECIAL_TILES = [11, 12, 13, 14]
# Weights (higher = more common)
# Standard tiles: Heart, Diamond, Star, Coin
const TILE_WEIGHTS = {
7: 100, # Heart
8: 100, # Diamond
9: 100, # Star
10: 100 # Coin
}
# Special tiles: Burn, Spawn, Freeze, Block, Invisible
const SPECIAL_WEIGHTS = {
11: 5,
12: 5,
13: 5,
14: 5
}
static func get_random_tile_id() -> int:
var rng = RandomNumberGenerator.new()
rng.randomize()
var total_weight = 0
var pool = {}
# Add standard tiles
for id in TILE_WEIGHTS:
pool[id] = TILE_WEIGHTS[id]
total_weight += TILE_WEIGHTS[id]
# Add special tiles
for id in SPECIAL_WEIGHTS:
pool[id] = SPECIAL_WEIGHTS[id]
total_weight += SPECIAL_WEIGHTS[id]
var roll = rng.randi_range(0, total_weight - 1)
var current = 0
for id in pool:
current += pool[id]
if roll < current:
return id
return 7 # Fallback to Heart