@tool extends Node3D class_name LevelInstance @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 focus: bool: get: return false set(value): set_focus_from(false) set_focus_to(true) @export var cancel_focus: bool: get: return false set(value): set_focus_from(false) set_focus_to(false) @onready var grid_block_material: Material = load("res://render/material/grid_block.tres") as Material var level_area_cfg: LevelAreaCfg #运行时设置 var character_spots: Array[ChacacterSpot] #运行时设置 class ChacacterSpot: var pos: Vector3 var cfg: CharacterCfg 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 set_focus_from(is_focus: bool) -> void: _set_focus(is_focus, "from") func set_focus_to(is_focus: bool) -> void: _set_focus(is_focus, "to") func _set_focus(is_focus: bool, key: String) -> void: if is_focus: grid_block_material.set_shader_parameter("is_focus_"+key, true) grid_block_material.set_shader_parameter("focus_min_"+key, pos_min()) grid_block_material.set_shader_parameter("focus_max_"+key, pos_max()) else: grid_block_material.set_shader_parameter("is_focus_"+key, false) func 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 level_pos() -> Vector2: var pos: Vector3 = get_global_position() return Vector2(pos.x, pos.z) func set_level_range_visible(visible: bool) -> void: var level_range: CSGBox3D = $LevelRange as CSGBox3D level_range.visible = visible func init_character_spots(level_character: GridMap) -> void: character_spots = [] var id_min: Vector3i = Util.get_level_grid_pos(pos_min()) var id_max: Vector3i = Util.get_level_grid_pos(pos_max()) var mesh_library: MeshLibrary = level_character.get_mesh_library() 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_character.get_cell_item(pos) if item_id == GridMap.INVALID_CELL_ITEM: continue var name: String = mesh_library.get_item_name(item_id) if not name.begins_with("c_"): continue var character_name: String = name.trim_prefix("c_") 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 = Util.get_level_float_pos(pos) character_spots.append(character_spot) func get_character_spots() -> Array[ChacacterSpot]: return character_spots func pos_min() -> Vector3: return get_global_position() + Vector3(0.640001, 0.640001, 0.640001) func pos_max() -> Vector3: var level_range: CSGBox3D = $LevelRange as CSGBox3D var level_size: Vector3 = level_range.size return get_global_position() + level_size - Vector3(0.640001, 0.639999, 0.639999)