You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
5.7 KiB
GDScript

1 year ago
@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
1 year ago
@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)
1 year ago
@export var enemy_nums: Array[LevelEnemy]
1 year ago
@onready var grid_block_material: Material = load("res://render/material/grid_block.tres") as Material
1 year ago
var level_area_cfg: LevelAreaCfg #运行时设置
var character_spots: Array[ChacacterSpot] #运行时设置
1 year ago
var character_born_spots: Array[ChacacterBornSpot] #运行时设置
1 year ago
var level_active_spots: Array[LevelActiveSpot] #运行时设置
1 year ago
var enemy_cfgs: Array[CharacterCfg] #运行时设置
class ChacacterSpot:
var pos: Vector3
var cfg: CharacterCfg
1 year ago
1 year ago
class ChacacterBornSpot:
var pos: Vector3
var type: int
1 year ago
class LevelActiveSpot:
var pos: Vector3
var scene: PackedScene
1 year ago
1 year ago
1 year ago
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
1 year ago
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 not grid_block_material:
return
1 year ago
if is_focus:
grid_block_material.set_shader_parameter("is_focus_"+key, true)
1 year ago
grid_block_material.set_shader_parameter("focus_min_"+key, pos_min() - Vector3.ONE * 0.32)
grid_block_material.set_shader_parameter("focus_max_"+key, pos_max() + Vector3.ONE * 0.32)
1 year ago
else:
grid_block_material.set_shader_parameter("is_focus_"+key, false)
1 year ago
func get_level_size() -> Vector2:
1 year ago
var level_range: CSGBox3D = $LevelRange as CSGBox3D
var level_size: Vector3 = level_range.size
return Vector2(level_size.x, level_size.z)
1 year ago
func get_level_pos() -> Vector2:
1 year ago
var pos: Vector3 = get_global_position()
return Vector2(pos.x, pos.z)
1 year ago
1 year ago
func set_level_range_visible(value: bool) -> void:
1 year ago
var level_range: CSGBox3D = $LevelRange as CSGBox3D
1 year ago
level_range.visible = value
func init_character_spots(level_character: GridMap) -> void:
character_spots = []
1 year ago
character_born_spots = []
level_active_spots = []
enemy_cfgs = []
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()
1 year ago
for x in range(id_min.x, id_max.x):
for y in range(id_min.y, id_max.y):
for z in range(id_min.z, id_max.z):
var pos: Vector3i = Vector3i(x, y, z)
1 year ago
var float_pos: Vector3 = Util.get_level_float_pos(pos) + Vector3(0.32, 0, 0.32)
var item_id: int = level_character.get_cell_item(pos)
if item_id == GridMap.INVALID_CELL_ITEM:
continue
1 year ago
var item_name: String = mesh_library.get_item_name(item_id)
if item_name.begins_with("cp_"):
var character_born_spot = ChacacterBornSpot.new()
character_born_spot.pos = float_pos
character_born_spots.append(character_born_spot)
elif item_name.begins_with("c_"):
var character_name: String = item_name.trim_prefix("c_")
1 year ago
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)
1 year ago
elif item_name.begins_with("a_"):
var scene_name: String = item_name.trim_prefix("a_")
1 year ago
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)
1 year ago
for enemy_num: LevelEnemy in enemy_nums:
for i in enemy_num.num:
enemy_cfgs.append(enemy_num.cfg)
func get_character_spots() -> Array[ChacacterSpot]:
return character_spots
1 year ago
func get_character_born_spots() -> Array[ChacacterBornSpot]:
return character_born_spots
func get_enemy_cfgs() -> Array[CharacterCfg]:
return enemy_cfgs
1 year ago
func get_level_active_spots() -> Array[LevelActiveSpot]:
return level_active_spots
func pos_min() -> Vector3:
1 year ago
return get_global_position()
func pos_max() -> Vector3:
var level_range: CSGBox3D = $LevelRange as CSGBox3D
var level_size: Vector3 = level_range.size
1 year ago
return get_global_position() + level_size
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