|  |  |  | @tool | 
					
						
							|  |  |  | extends Node3D | 
					
						
							|  |  |  | class_name LevelInstance | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @export_tool_button("视野锁定", "Callable") | 
					
						
							|  |  |  | var view_focus_on: Callable = func() -> void: | 
					
						
							|  |  |  | 	grid_block_material.set_shader_parameter("is_focus", true) | 
					
						
							|  |  |  | 	debug_material.set_shader_parameter("is_hide", true) | 
					
						
							|  |  |  | 	set_focus_editor() | 
					
						
							|  |  |  | @export_tool_button("视野解锁", "Callable") | 
					
						
							|  |  |  | var view_focus_off: Callable = func() -> void: | 
					
						
							|  |  |  | 	grid_block_material.set_shader_parameter("is_focus", false) | 
					
						
							|  |  |  | 	debug_material.set_shader_parameter("is_hide", false) | 
					
						
							|  |  |  | 	set_focus() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @export var size: Vector3i = Vector3i.ONE: | 
					
						
							|  |  |  | 	set(value): | 
					
						
							|  |  |  | 		if (value.x < 1) or (value.y < 1) or (value.z < 1): | 
					
						
							|  |  |  | 			value = Vector3i.ONE | 
					
						
							|  |  |  | 		size = value | 
					
						
							|  |  |  | 		_on_size_change() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @export var is_force_battle: bool | 
					
						
							|  |  |  | @export var enemy_nums: Array[LevelEnemy] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @export_group("快速操作") | 
					
						
							|  |  |  | @export_tool_button("清空", "Callable") | 
					
						
							|  |  |  | var remove_all: Callable = func() -> void: | 
					
						
							|  |  |  | 	var level_main: GridMap = %LevelGridMain as GridMap | 
					
						
							|  |  |  | 	var id_min: Vector3i = Util.get_level_grid_pos2(pos_min()) | 
					
						
							|  |  |  | 	var id_max: Vector3i = Util.get_level_grid_pos2(pos_max()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for x in range(id_min.x, id_max.x + 1): | 
					
						
							|  |  |  | 		for y in range(id_min.y, id_max.y + 1): | 
					
						
							|  |  |  | 			for z in range(id_min.z, id_max.z + 1): | 
					
						
							|  |  |  | 				var pos: Vector3i = Vector3i(x, y, z) | 
					
						
							|  |  |  | 				level_main.set_cell_item(pos, GridMap.INVALID_CELL_ITEM) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @export_tool_button("快速创建", "Callable") | 
					
						
							|  |  |  | var quick_build: Callable = func() -> void: | 
					
						
							|  |  |  | 	var level_main: GridMap = %LevelGridMain as GridMap | 
					
						
							|  |  |  | 	var id_min: Vector3i = Util.get_level_grid_pos2(pos_min()) | 
					
						
							|  |  |  | 	var id_max: Vector3i = Util.get_level_grid_pos2(pos_max()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for x in range(id_min.x, id_max.x + 1): | 
					
						
							|  |  |  | 		for y in range(id_min.y, id_max.y + 1): | 
					
						
							|  |  |  | 			for z in range(id_min.z, id_max.z + 1): | 
					
						
							|  |  |  | 				var pos: Vector3i = Vector3i(x, y, z) | 
					
						
							|  |  |  | 				if x == id_min.x or x == id_max.x or y == id_min.y or z == id_min.z: | 
					
						
							|  |  |  | 					level_main.set_cell_item(pos, 2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @export_group("替换item_id") | 
					
						
							|  |  |  | @export var id_from: int = 0 | 
					
						
							|  |  |  | @export var id_to: int = 0 | 
					
						
							|  |  |  | @export_tool_button("替换", "Callable") | 
					
						
							|  |  |  | var replace_id: Callable = func() -> void: | 
					
						
							|  |  |  | 	var level_main: GridMap = %LevelGridMain as GridMap | 
					
						
							|  |  |  | 	var id_min: Vector3i = Util.get_level_grid_pos2(pos_min()) | 
					
						
							|  |  |  | 	var id_max: Vector3i = Util.get_level_grid_pos2(pos_max()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for x in range(id_min.x, id_max.x + 1): | 
					
						
							|  |  |  | 		for y in range(id_min.y, id_max.y + 1): | 
					
						
							|  |  |  | 			for z in range(id_min.z, id_max.z + 1): | 
					
						
							|  |  |  | 				var pos: Vector3i = Vector3i(x, y, z) | 
					
						
							|  |  |  | 				if level_main.get_cell_item(pos) == id_from: | 
					
						
							|  |  |  | 					level_main.set_cell_item(pos, id_to, level_main.get_cell_item_orientation(pos)) | 
					
						
							|  |  |  | @export_tool_button("打印item详情", "Callable") | 
					
						
							|  |  |  | var print_item: Callable = func() -> void: | 
					
						
							|  |  |  | 	var level_main: GridMap = %LevelGridMain as GridMap | 
					
						
							|  |  |  | 	var id_min: Vector3i = Util.get_level_grid_pos2(pos_min()) | 
					
						
							|  |  |  | 	var id_max: Vector3i = Util.get_level_grid_pos2(pos_max()) | 
					
						
							|  |  |  | 	var mesh_library: MeshLibrary = level_main.get_mesh_library() | 
					
						
							|  |  |  | 	var item_count_map: Dictionary = {} | 
					
						
							|  |  |  | 	for x in range(id_min.x, id_max.x + 1): | 
					
						
							|  |  |  | 		for y in range(id_min.y, id_max.y + 1): | 
					
						
							|  |  |  | 			for z in range(id_min.z, id_max.z + 1): | 
					
						
							|  |  |  | 				var pos: Vector3i = Vector3i(x, y, z) | 
					
						
							|  |  |  | 				var item_id: int = level_main.get_cell_item(pos) | 
					
						
							|  |  |  | 				if item_id != GridMap.INVALID_CELL_ITEM: | 
					
						
							|  |  |  | 					if item_count_map.has(item_id): | 
					
						
							|  |  |  | 						item_count_map[item_id] += 1 | 
					
						
							|  |  |  | 					else: | 
					
						
							|  |  |  | 						item_count_map[item_id] = 1 | 
					
						
							|  |  |  | 	for item_id: int in item_count_map: | 
					
						
							|  |  |  | 		print("[", item_id, "]", mesh_library.get_item_name(item_id), ":", item_count_map[item_id]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @onready var grid_block_material: Material = load("res://render/material/level_grid_block.tres") as Material | 
					
						
							|  |  |  | @onready var debug_material: Material = load("res://render/material/debug.tres") as Material | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #character | 
					
						
							|  |  |  | var level_area_cfg: LevelAreaCfg | 
					
						
							|  |  |  | var character_spots: Array[ChacacterSpot] | 
					
						
							|  |  |  | var character_born_spots: Array[ChacacterBornSpot] | 
					
						
							|  |  |  | var level_active_spots: Array[LevelActiveSpot] | 
					
						
							|  |  |  | var enemy_cfgs: Array[CharacterCfg] | 
					
						
							|  |  |  | #main | 
					
						
							|  |  |  | var mark_white_list: Array[Vector3i] | 
					
						
							|  |  |  | var mark_black_list: Array[Vector3i] | 
					
						
							|  |  |  | var grid_main_cache_cells: Array[GridMainCacheCellData] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ChacacterSpot: | 
					
						
							|  |  |  | 	var pos: Vector3 | 
					
						
							|  |  |  | 	var cfg: CharacterCfg | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ChacacterBornSpot: | 
					
						
							|  |  |  | 	var pos: Vector3 | 
					
						
							|  |  |  | 	var type: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class LevelActiveSpot: | 
					
						
							|  |  |  | 	var pos: Vector3 | 
					
						
							|  |  |  | 	var scene: PackedScene | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class GridMainCacheCellData: | 
					
						
							|  |  |  | 	var pos: Vector3i | 
					
						
							|  |  |  | 	var id: int | 
					
						
							|  |  |  | 	var orientation: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _on_size_change() -> void: | 
					
						
							|  |  |  | 	var level_range: CSGBox3D = $LevelRange as CSGBox3D | 
					
						
							|  |  |  | 	var size_basic: Vector3 = Setting.size_basic | 
					
						
							|  |  |  | 	level_range.size = Vector3(size.x * size_basic.x, size.y * size_basic.y, size.z * size_basic.z) | 
					
						
							|  |  |  | 	level_range.position = level_range.size / 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func get_level_size() -> Vector2: | 
					
						
							|  |  |  | 	var level_range: CSGBox3D = $LevelRange as CSGBox3D | 
					
						
							|  |  |  | 	var level_size: Vector3 = level_range.size | 
					
						
							|  |  |  | 	return Vector2(level_size.x, level_size.z) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func get_level_pos() -> Vector2: | 
					
						
							|  |  |  | 	var pos: Vector3 = get_global_position() | 
					
						
							|  |  |  | 	return Vector2(pos.x, pos.z) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func set_level_range_visible(value: bool) -> void: | 
					
						
							|  |  |  | 	var level_range: CSGBox3D = $LevelRange as CSGBox3D | 
					
						
							|  |  |  | 	level_range.visible = value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func set_focus_editor() -> void: | 
					
						
							|  |  |  | 	var level_range: CSGBox3D = $LevelRange as CSGBox3D | 
					
						
							|  |  |  | 	var level_size: Vector3 = level_range.size | 
					
						
							|  |  |  | 	var focus_min: Vector3 = get_global_position() | 
					
						
							|  |  |  | 	var focus_max: Vector3 = get_global_position() + level_size - Vector3.ONE * Setting.pixel_size * Setting.grid_pixel_size | 
					
						
							|  |  |  | 	grid_block_material.set_shader_parameter("focus_min", focus_min) | 
					
						
							|  |  |  | 	grid_block_material.set_shader_parameter("focus_max", focus_max) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func set_focus() -> void: | 
					
						
							|  |  |  | 	var level_range: CSGBox3D = $LevelRange as CSGBox3D | 
					
						
							|  |  |  | 	var level_size: Vector3 = level_range.size | 
					
						
							|  |  |  | 	var focus_min: Vector3 = get_global_position() | 
					
						
							|  |  |  | 	var focus_max: Vector3 = get_global_position() + level_size + Vector3.ONE * Setting.pixel_size * Setting.grid_pixel_size | 
					
						
							|  |  |  | 	var show_max: Vector3 = get_global_position() + level_size - Vector3.ONE * Setting.pixel_size * Setting.grid_pixel_size | 
					
						
							|  |  |  | 	grid_block_material.set_shader_parameter("focus_min", focus_min) | 
					
						
							|  |  |  | 	grid_block_material.set_shader_parameter("focus_max", focus_max) | 
					
						
							|  |  |  | 	grid_block_material.set_shader_parameter("target_level_top_y", show_max.y) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init_level_character() -> void: | 
					
						
							|  |  |  | 	var level_character: GridMap = %LevelGridCharacter as GridMap | 
					
						
							|  |  |  | 	character_spots = [] | 
					
						
							|  |  |  | 	character_born_spots = [] | 
					
						
							|  |  |  | 	level_active_spots = [] | 
					
						
							|  |  |  | 	enemy_cfgs = [] | 
					
						
							|  |  |  | 	var id_min: Vector3i = Util.get_level_grid_pos2(pos_min()) | 
					
						
							|  |  |  | 	var id_max: Vector3i = Util.get_level_grid_pos2(pos_max()) | 
					
						
							|  |  |  | 	var mesh_library: MeshLibrary = level_character.get_mesh_library() | 
					
						
							|  |  |  | 	var used_cells: Array[Vector3i] = level_character.get_used_cells() | 
					
						
							|  |  |  | 	for pos in used_cells: | 
					
						
							|  |  |  | 		if pos.x < id_min.x or pos.x > id_max.x: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		if pos.y < id_min.y or pos.y > id_max.y: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		if pos.z < id_min.z or pos.z > id_max.z: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		var float_pos: Vector3 = Util.get_level_float_pos2_floor(pos) | 
					
						
							|  |  |  | 		var item_id: int = level_character.get_cell_item(pos) | 
					
						
							|  |  |  | 		if item_id == GridMap.INVALID_CELL_ITEM: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		var item_name: String = mesh_library.get_item_name(item_id) | 
					
						
							|  |  |  | 		if item_name.begins_with("chara_spot_"): | 
					
						
							|  |  |  | 			var character_born_spot = ChacacterBornSpot.new() | 
					
						
							|  |  |  | 			character_born_spot.pos = float_pos | 
					
						
							|  |  |  | 			character_born_spots.append(character_born_spot) | 
					
						
							|  |  |  | 		elif item_name.begins_with("chara_enemy_"): | 
					
						
							|  |  |  | 			var character_name: String = item_name.trim_prefix("chara_enemy_") | 
					
						
							|  |  |  | 			var character_cfg: CharacterCfg = Util.get_character_cfg_by_name(character_name) | 
					
						
							|  |  |  | 			if not character_cfg: | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			var character_spot = ChacacterSpot.new() | 
					
						
							|  |  |  | 			character_spot.cfg = character_cfg | 
					
						
							|  |  |  | 			character_spot.pos = float_pos | 
					
						
							|  |  |  | 			character_spots.append(character_spot) | 
					
						
							|  |  |  | 		elif item_name.begins_with("chara_active_"): | 
					
						
							|  |  |  | 			var scene_name: String = item_name.trim_prefix("chara_active_") | 
					
						
							|  |  |  | 			var scene: PackedScene = Util.get_level_active_scene_by_name(scene_name) | 
					
						
							|  |  |  | 			if not scene: | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			var level_active_spot = LevelActiveSpot.new() | 
					
						
							|  |  |  | 			level_active_spot.scene = scene | 
					
						
							|  |  |  | 			level_active_spot.pos = float_pos | 
					
						
							|  |  |  | 			level_active_spots.append(level_active_spot) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for enemy_num: LevelEnemy in enemy_nums: | 
					
						
							|  |  |  | 		for i in enemy_num.num: | 
					
						
							|  |  |  | 			enemy_cfgs.append(enemy_num.cfg) | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | func init_level_main() -> void: | 
					
						
							|  |  |  | 	var level_main: GridMap = %LevelGridMain as GridMap | 
					
						
							|  |  |  | 	mark_white_list.clear() | 
					
						
							|  |  |  | 	mark_black_list.clear() | 
					
						
							|  |  |  | 	grid_main_cache_cells.clear() | 
					
						
							|  |  |  | 	var id_min: Vector3i = Util.get_level_grid_pos2(pos_min()) | 
					
						
							|  |  |  | 	var id_max: Vector3i = Util.get_level_grid_pos2(pos_max()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# 需要延申空气墙的黑块 | 
					
						
							|  |  |  | 	var air_wall_mark_black_list: Array[Vector3i] = [] | 
					
						
							|  |  |  | 	# 正前面黑块 | 
					
						
							|  |  |  | 	for x in range(id_min.x, id_max.x + 1): | 
					
						
							|  |  |  | 		var pos: Vector3i = Vector3i(x, id_min.y, id_max.z) | 
					
						
							|  |  |  | 		var has_link = false | 
					
						
							|  |  |  | 		var mark_black_list_check: Array[Vector3i] = [] | 
					
						
							|  |  |  | 		for y in range(id_min.y, id_max.y - 1): | 
					
						
							|  |  |  | 			var pos_check: Vector3i = Vector3i(x, y + 1, id_max.z) | 
					
						
							|  |  |  | 			if not check_grid(level_main, pos_check): | 
					
						
							|  |  |  | 				var pos_forward: Vector3i = Vector3i(x, y + 1, id_max.z + 1) | 
					
						
							|  |  |  | 				var float_pos_check: Vector3 = Util.get_level_float_pos2(pos_forward) | 
					
						
							|  |  |  | 				if Global.level_mgr.get_level_by_pos(float_pos_check): | 
					
						
							|  |  |  | 					if y + 1 < id_max.y: | 
					
						
							|  |  |  | 						air_wall_mark_black_list.append(pos_check + Vector3i(0, 1, 0)) | 
					
						
							|  |  |  | 					has_link = true | 
					
						
							|  |  |  | 					break | 
					
						
							|  |  |  | 			mark_black_list_check.append(Vector3i(x, y, id_max.z)) | 
					
						
							|  |  |  | 		if has_link: | 
					
						
							|  |  |  | 			pass | 
					
						
							|  |  |  | 			# for pos_check in mark_black_list_check: | 
					
						
							|  |  |  | 			# 	mark_black_list.append(pos_check) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			air_wall_mark_black_list.append(pos) | 
					
						
							|  |  |  | 			mark_black_list.append(pos) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# 左面黑块 | 
					
						
							|  |  |  | 	var black_y_max_left: int = id_max.y - 1 | 
					
						
							|  |  |  | 	for z in range(id_min.z + 1, id_max.z): | 
					
						
							|  |  |  | 		var has_link = false | 
					
						
							|  |  |  | 		var mark_black_list_check: Array[Vector3i] = [] | 
					
						
							|  |  |  | 		for y in range(id_min.y - 1, black_y_max_left): | 
					
						
							|  |  |  | 			var pos_check: Vector3i = Vector3i(id_min.x, y + 1, z) | 
					
						
							|  |  |  | 			if not check_grid(level_main, pos_check): | 
					
						
							|  |  |  | 				has_link = true | 
					
						
							|  |  |  | 				black_y_max_left = max(y, id_min.y) | 
					
						
							|  |  |  | 				if y + 1 < id_max.y: | 
					
						
							|  |  |  | 					air_wall_mark_black_list.append(pos_check + Vector3i(0, 1, 0)) | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			mark_black_list_check.append(pos_check) | 
					
						
							|  |  |  | 		if not has_link: | 
					
						
							|  |  |  | 			for pos_check in mark_black_list_check: | 
					
						
							|  |  |  | 				mark_black_list.append(pos_check) | 
					
						
							|  |  |  | 			var pos_check: Vector3i = Vector3i(id_min.x, black_y_max_left, z) | 
					
						
							|  |  |  | 			air_wall_mark_black_list.append(pos_check) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# 右边面黑块 | 
					
						
							|  |  |  | 	var black_y_max_right: int = id_max.y - 1 | 
					
						
							|  |  |  | 	for z in range(id_min.z + 1, id_max.z): | 
					
						
							|  |  |  | 		var has_link = false | 
					
						
							|  |  |  | 		var mark_black_list_check: Array[Vector3i] = [] | 
					
						
							|  |  |  | 		for y in range(id_min.y - 1, black_y_max_right): | 
					
						
							|  |  |  | 			var pos_check: Vector3i = Vector3i(id_max.x, y + 1, z) | 
					
						
							|  |  |  | 			if not check_grid(level_main, pos_check): | 
					
						
							|  |  |  | 				has_link = true | 
					
						
							|  |  |  | 				black_y_max_right = max(y, id_min.y) | 
					
						
							|  |  |  | 				if y + 1 < id_max.y: | 
					
						
							|  |  |  | 					air_wall_mark_black_list.append(pos_check + Vector3i(0, 1, 0)) | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			mark_black_list_check.append(pos_check) | 
					
						
							|  |  |  | 		if not has_link: | 
					
						
							|  |  |  | 			for pos_check in mark_black_list_check: | 
					
						
							|  |  |  | 				mark_black_list.append(pos_check) | 
					
						
							|  |  |  | 			var pos_check: Vector3i = Vector3i(id_max.x, black_y_max_right, z) | 
					
						
							|  |  |  | 			air_wall_mark_black_list.append(pos_check) | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 	# 黑块cache | 
					
						
							|  |  |  | 	for mark_black in mark_black_list: | 
					
						
							|  |  |  | 		add_grid_main_cache_cell(level_main, mark_black) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# 黑块延申空气墙 | 
					
						
							|  |  |  | 	for mark_black in air_wall_mark_black_list: | 
					
						
							|  |  |  | 		for y in range(mark_black.y + 1, id_max.y): | 
					
						
							|  |  |  | 			var pos: Vector3i = Vector3i(mark_black.x, y, mark_black.z) | 
					
						
							|  |  |  | 			add_grid_main_cache_cell(level_main, pos) | 
					
						
							|  |  |  | 			mark_white_list.append(pos) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# 顶面 | 
					
						
							|  |  |  | 	for x in range(id_min.x, id_max.x + 1): | 
					
						
							|  |  |  | 		for z in range(id_min.z, id_max.z + 1): | 
					
						
							|  |  |  | 			var pos: Vector3i = Vector3i(x, id_max.y, z) | 
					
						
							|  |  |  | 			var pos_up: Vector3i = Vector3i(x, id_max.y + 1, z) | 
					
						
							|  |  |  | 			var pos_down: Vector3i = Vector3i(x, id_max.y - 1, z) | 
					
						
							|  |  |  | 			var is_link = not check_grid(level_main, pos) and not check_grid(level_main, pos_up) and not check_grid(level_main, pos_down) | 
					
						
							|  |  |  | 			if is_link and not pos_down in mark_white_list: | 
					
						
							|  |  |  | 				var float_pos_check: Vector3 = Util.get_level_float_pos2(pos_up) | 
					
						
							|  |  |  | 				if Global.level_mgr.get_level_by_pos(float_pos_check): | 
					
						
							|  |  |  | 					continue | 
					
						
							|  |  |  | 			add_grid_main_cache_cell(level_main, pos) | 
					
						
							|  |  |  | 			if pos_down in mark_white_list: | 
					
						
							|  |  |  | 				mark_white_list.append(pos) | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				if check_grid(level_main, pos_down): | 
					
						
							|  |  |  | 					mark_black_list.append(pos) | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					mark_white_list.append(pos) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check_grid(level_main: GridMap, pos: Vector3i) -> bool: | 
					
						
							|  |  |  | 	var id: int = level_main.get_cell_item(pos) | 
					
						
							|  |  |  | 	return id != GridMap.INVALID_CELL_ITEM | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func add_grid_main_cache_cell(level_main: GridMap, pos: Vector3i) -> void: | 
					
						
							|  |  |  | 	var id: int = level_main.get_cell_item(pos) | 
					
						
							|  |  |  | 	if id == GridMap.INVALID_CELL_ITEM: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	var cache_data = GridMainCacheCellData.new() | 
					
						
							|  |  |  | 	cache_data.pos = pos | 
					
						
							|  |  |  | 	cache_data.id = id | 
					
						
							|  |  |  | 	cache_data.orientation = level_main.get_cell_item_orientation(pos) | 
					
						
							|  |  |  | 	grid_main_cache_cells.append(cache_data) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func set_replace(is_active: bool) -> void: | 
					
						
							|  |  |  | 	var level_main: GridMap = %LevelGridMain as GridMap | 
					
						
							|  |  |  | 	if is_active: | 
					
						
							|  |  |  | 		for pos in mark_white_list: | 
					
						
							|  |  |  | 			level_main.set_cell_item(pos, 0) | 
					
						
							|  |  |  | 		for pos in mark_black_list: | 
					
						
							|  |  |  | 			level_main.set_cell_item(pos, 1) | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		for pos in mark_white_list: | 
					
						
							|  |  |  | 			level_main.set_cell_item(pos, GridMap.INVALID_CELL_ITEM) | 
					
						
							|  |  |  | 		for pos in mark_black_list: | 
					
						
							|  |  |  | 			level_main.set_cell_item(pos, GridMap.INVALID_CELL_ITEM) | 
					
						
							|  |  |  | 		for cache_data in grid_main_cache_cells: | 
					
						
							|  |  |  | 			level_main.set_cell_item(cache_data.pos, cache_data.id, cache_data.orientation) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func get_character_spots() -> Array[ChacacterSpot]: | 
					
						
							|  |  |  | 	return character_spots | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func get_character_born_spots() -> Array[ChacacterBornSpot]: | 
					
						
							|  |  |  | 	return character_born_spots | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func get_enemy_cfgs() -> Array[CharacterCfg]: | 
					
						
							|  |  |  | 	return enemy_cfgs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func get_level_active_spots() -> Array[LevelActiveSpot]: | 
					
						
							|  |  |  | 	return level_active_spots | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func pos_min() -> Vector3: | 
					
						
							|  |  |  | 	return get_global_position() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func pos_max() -> Vector3: | 
					
						
							|  |  |  | 	var level_range: CSGBox3D = $LevelRange as CSGBox3D | 
					
						
							|  |  |  | 	var level_size: Vector3 = level_range.size | 
					
						
							|  |  |  | 	return get_global_position() + level_size | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func outter_pos_min() -> Vector3: | 
					
						
							|  |  |  | 	return pos_min() - Vector3(0.72, 0.72, 0.72) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func outter_pos_max() -> Vector3: | 
					
						
							|  |  |  | 	return pos_max() - Vector3(0.72, 0.72, 0.72) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func is_in_active_area(pos: Vector3) -> bool: | 
					
						
							|  |  |  | 	var active_pos_min: Vector3 = pos_min() + Vector3(0.96, 0, 0.96) | 
					
						
							|  |  |  | 	var active_pos_max: Vector3 = pos_max() - Vector3(0.96, 0, 0.96) | 
					
						
							|  |  |  | 	return pos.x >= active_pos_min.x and pos.x <= active_pos_max.x and \ | 
					
						
							|  |  |  | 	pos.z >= active_pos_min.z and pos.z <= active_pos_max.z and \ | 
					
						
							|  |  |  | 	pos.y >= active_pos_min.y and pos.y <= active_pos_max.y |