class_name Stage extends Node2D var item_pool: Array = [] var reserved_item_positions: Array = [] @export var item_pool_max_size := 3 func get_world_boundaries() -> Dictionary: #Dictionary[Vector2, float] return { Vector2.LEFT: 0.0, Vector2.RIGHT: 0.0, Vector2.UP: 0.0, Vector2.DOWN: 0.0, } func has_win_condition() -> bool: return false func set_mobile_controls(): var mobile_controls: MobileControls = get_node("%MobileControls") if OS.has_feature("android"): mobile_controls.enable() var player: Player = get_node("%Player") player.camera.limit_bottom += mobile_controls.size.y get_window().content_scale_size = Vector2i( ProjectSettings.get_setting("display/window/size/viewport_width"), ProjectSettings.get_setting("display/window/size/viewport_height") + mobile_controls.size.y ) func _on_tick_timer_timeout() -> void: if randf() > 0.9 and item_pool.size() < item_pool_max_size: var item_scene: PackedScene = [ load("res://item/shoe.tscn"), load("res://item/crown.tscn"), ].pick_random() var item: Item = item_scene.instantiate() var map: TileMapLayer = get_tree().get_first_node_in_group("tilemap") var size_x := map.get_used_rect().position.x + map.get_used_rect().size.x var size_y := map.get_used_rect().position.y + map.get_used_rect().size.y var start_x: int = max(map.get_used_rect().position.x, range(size_x).pick_random()) var start_y: int = max(map.get_used_rect().position.y, range(size_y).pick_random()) var get_map_position = func() -> Vector2i: for x in range(start_x, size_x): for y in range(start_y, size_y): var data = map.get_cell_tile_data(Vector2(x, y)) if not data: return Vector2i(x, y) return Vector2i.ZERO # find appropriate position var map_position = get_map_position.call() if reserved_item_positions.has(map_position) or map_position == Vector2i.ZERO: $TickTimer.start() return var local_position = map.map_to_local(map_position) var _was_shifted := false var collide_top = map.get_cell_tile_data(map.get_neighbor_cell(map_position, TileSet.CELL_NEIGHBOR_TOP_SIDE)) var collide_bottom = map.get_cell_tile_data(map.get_neighbor_cell(map_position, TileSet.CELL_NEIGHBOR_BOTTOM_SIDE)) var collide_right = map.get_cell_tile_data(map.get_neighbor_cell(map_position, TileSet.CELL_NEIGHBOR_RIGHT_SIDE)) if collide_top: local_position += Vector2(0, map.tile_set.tile_size.y / 2) _was_shifted = true if collide_bottom: local_position += Vector2(0, -map.tile_set.tile_size.y / 2) _was_shifted = true if collide_right: local_position += Vector2(-map.tile_set.tile_size.x, 0) _was_shifted = true if not collide_top and not collide_right: if map.get_cell_tile_data(map.get_neighbor_cell(map_position, TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER)): local_position += Vector2(-map.tile_set.tile_size.x, map.tile_set.tile_size.y / 2) _was_shifted = true #if not was_shifted: local_position += Vector2(map.tile_set.tile_size.x / 2, 0) item.position = local_position add_child(item) var get_reserved_positions = func() -> Array[Vector2i]: var rp := [] as Array[Vector2i] for x in range(0, 3): for y in range(0, 3): rp.append(Vector2i(x, y)) rp.append(Vector2i(-x, y)) rp.append(Vector2i(x, -y)) rp.append(Vector2i(-x, -y)) return rp item.tree_exiting.connect(func(): item_pool.erase(item) for v in get_reserved_positions.call(): reserved_item_positions.erase(map_position + v) ) item_pool.append(item) for v in get_reserved_positions.call(): reserved_item_positions.append(map_position + v) # restart timer $TickTimer.start()