mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 08:35:34 +00:00
305 lines
11 KiB
GDScript
305 lines
11 KiB
GDScript
@tool
|
|
extends BaseCreatorDialog
|
|
|
|
signal enemy_data_confirmed(enemy_data: Dictionary)
|
|
|
|
# UI elements
|
|
var _enemy_name_edit: LineEdit
|
|
var _enemy_key_edit: LineEdit
|
|
var _prefab_path_edit: LineEdit
|
|
var _is_3d_check: CheckBox
|
|
|
|
var _icon_sprite_picker: EditorResourcePicker
|
|
var _icon_sprite_preview: TextureRect
|
|
var _selected_icon_sprite: Texture2D = null
|
|
|
|
var _max_health_spin: SpinBox
|
|
var _movement_speed_spin: SpinBox
|
|
var _player_detection_range_spin: SpinBox
|
|
var _view_range_spin: SpinBox
|
|
var _alarm_react_range_spin: SpinBox
|
|
var _player_disengage_range_spin: SpinBox
|
|
var _strafe_speed_spin: SpinBox
|
|
var _max_strafe_distance_spin: SpinBox
|
|
var _min_strafe_distance_spin: SpinBox
|
|
var _response_time_spin: SpinBox
|
|
var _motivation_reward_spin: SpinBox
|
|
var _predict_player_check: CheckBox
|
|
|
|
var _weapon_picker: EditorResourcePicker
|
|
var _selected_weapon: Resource = null
|
|
|
|
func _configure_window() -> void:
|
|
size = settings.get("enemy_dialog_size") if settings else Vector2i(750, 950)
|
|
transient = false
|
|
exclusive = false
|
|
unresizable = false
|
|
|
|
func _update_title() -> void:
|
|
var action_text = "Duplicate" if not prefill_data.is_empty() else "Create New"
|
|
title = action_text + " Enemy"
|
|
|
|
func _get_saved_position() -> Vector2i:
|
|
if settings:
|
|
var pos = settings.get("enemy_dialog_position")
|
|
return pos if pos else Vector2i.ZERO
|
|
return Vector2i.ZERO
|
|
|
|
func _save_dialog_size() -> void:
|
|
if settings:
|
|
settings.set("enemy_dialog_size", size)
|
|
settings.call("save_settings")
|
|
|
|
func _save_dialog_position() -> void:
|
|
if settings:
|
|
settings.set("enemy_dialog_position", position)
|
|
settings.call("save_settings")
|
|
|
|
func _build_content(container: VBoxContainer) -> void:
|
|
_build_basic_info_section(container)
|
|
_build_combat_stats_section(container)
|
|
_build_ai_settings_section(container)
|
|
_build_graphics_section(container)
|
|
|
|
func _build_basic_info_section(content_vbox: VBoxContainer) -> void:
|
|
content_vbox.add_child(_create_section_label("Basic Information"))
|
|
|
|
var name_input = _create_input("Enemy Name:")
|
|
content_vbox.add_child(name_input["container"])
|
|
_enemy_name_edit = name_input["edit"]
|
|
|
|
var key_input = _create_input("Enemy Key:")
|
|
content_vbox.add_child(key_input["container"])
|
|
_enemy_key_edit = key_input["edit"]
|
|
|
|
var prefab_input = _create_input("Prefab Path:")
|
|
content_vbox.add_child(prefab_input["container"])
|
|
_prefab_path_edit = prefab_input["edit"]
|
|
|
|
_is_3d_check = CheckBox.new()
|
|
_is_3d_check.text = "Is 3D"
|
|
_is_3d_check.button_pressed = true
|
|
content_vbox.add_child(_is_3d_check)
|
|
|
|
content_vbox.add_child(HSeparator.new())
|
|
|
|
func _build_combat_stats_section(content_vbox: VBoxContainer) -> void:
|
|
content_vbox.add_child(_create_section_label("Combat Stats"))
|
|
|
|
var health_spin = _create_spinbox("Max Health:", 6.0, 0.1, 10000.0, 0.5)
|
|
content_vbox.add_child(health_spin["container"])
|
|
_max_health_spin = health_spin["spinbox"]
|
|
|
|
var movement_spin = _create_spinbox("Movement Speed:", 1.5, 0.0, 1000.0, 0.1)
|
|
content_vbox.add_child(movement_spin["container"])
|
|
_movement_speed_spin = movement_spin["spinbox"]
|
|
|
|
var motivation_spin = _create_spinbox("Motivation Reward:", 4.0, 0.0, 1000.0, 0.5)
|
|
content_vbox.add_child(motivation_spin["container"])
|
|
_motivation_reward_spin = motivation_spin["spinbox"]
|
|
|
|
# Weapon picker
|
|
var weapon_hbox = HBoxContainer.new()
|
|
content_vbox.add_child(weapon_hbox)
|
|
|
|
var weapon_label = Label.new()
|
|
weapon_label.text = "Weapon:"
|
|
weapon_label.custom_minimum_size = Vector2(120, 0)
|
|
weapon_hbox.add_child(weapon_label)
|
|
|
|
_weapon_picker = EditorResourcePicker.new()
|
|
_weapon_picker.base_type = "Resource"
|
|
_weapon_picker.editable = true
|
|
_weapon_picker.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
_weapon_picker.resource_changed.connect(_on_weapon_resource_changed)
|
|
weapon_hbox.add_child(_weapon_picker)
|
|
|
|
content_vbox.add_child(HSeparator.new())
|
|
|
|
func _build_ai_settings_section(content_vbox: VBoxContainer) -> void:
|
|
content_vbox.add_child(_create_section_label("AI Settings"))
|
|
|
|
var detect_spin = _create_spinbox("Player Detection Range:", 12.0, 0.0, 1000.0, 1.0)
|
|
content_vbox.add_child(detect_spin["container"])
|
|
_player_detection_range_spin = detect_spin["spinbox"]
|
|
|
|
var view_spin = _create_spinbox("View Range:", 8.0, 0.0, 1000.0, 1.0)
|
|
content_vbox.add_child(view_spin["container"])
|
|
_view_range_spin = view_spin["spinbox"]
|
|
|
|
var alarm_spin = _create_spinbox("Alarm React Range:", 20.0, 0.0, 1000.0, 1.0)
|
|
content_vbox.add_child(alarm_spin["container"])
|
|
_alarm_react_range_spin = alarm_spin["spinbox"]
|
|
|
|
var disengage_spin = _create_spinbox("Player Disengage Range:", 15.0, 0.0, 1000.0, 1.0)
|
|
content_vbox.add_child(disengage_spin["container"])
|
|
_player_disengage_range_spin = disengage_spin["spinbox"]
|
|
|
|
var strafe_spin = _create_spinbox("Strafe Speed:", 0.0, 0.0, 1000.0, 0.1)
|
|
content_vbox.add_child(strafe_spin["container"])
|
|
_strafe_speed_spin = strafe_spin["spinbox"]
|
|
|
|
var max_strafe_spin = _create_spinbox("Max Strafe Distance:", 0.0, 0.0, 1000.0, 1.0)
|
|
content_vbox.add_child(max_strafe_spin["container"])
|
|
_max_strafe_distance_spin = max_strafe_spin["spinbox"]
|
|
|
|
var min_strafe_spin = _create_spinbox("Min Strafe Distance:", 0.0, 0.0, 1000.0, 1.0)
|
|
content_vbox.add_child(min_strafe_spin["container"])
|
|
_min_strafe_distance_spin = min_strafe_spin["spinbox"]
|
|
|
|
var response_spin = _create_spinbox("Response Time:", 0.5, 0.0, 10.0, 0.1)
|
|
content_vbox.add_child(response_spin["container"])
|
|
_response_time_spin = response_spin["spinbox"]
|
|
|
|
_predict_player_check = CheckBox.new()
|
|
_predict_player_check.text = "Predict Player"
|
|
_predict_player_check.button_pressed = false
|
|
content_vbox.add_child(_predict_player_check)
|
|
|
|
content_vbox.add_child(HSeparator.new())
|
|
|
|
func _build_graphics_section(content_vbox: VBoxContainer) -> void:
|
|
content_vbox.add_child(_create_section_label("Graphics"))
|
|
|
|
var icon_label = Label.new()
|
|
icon_label.text = "Icon Sprite (IconSprite)"
|
|
content_vbox.add_child(icon_label)
|
|
|
|
var icon_container = HBoxContainer.new()
|
|
icon_container.add_theme_constant_override("separation", 8)
|
|
content_vbox.add_child(icon_container)
|
|
|
|
var left_vbox = VBoxContainer.new()
|
|
left_vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
left_vbox.add_theme_constant_override("separation", 4)
|
|
icon_container.add_child(left_vbox)
|
|
|
|
var picker_hbox = HBoxContainer.new()
|
|
picker_hbox.add_theme_constant_override("separation", 4)
|
|
left_vbox.add_child(picker_hbox)
|
|
|
|
var picker_label = Label.new()
|
|
picker_label.text = "Icon Sprite:"
|
|
picker_label.custom_minimum_size = Vector2(120, 0)
|
|
picker_hbox.add_child(picker_label)
|
|
|
|
_icon_sprite_picker = EditorResourcePicker.new()
|
|
_icon_sprite_picker.base_type = "Texture2D"
|
|
_icon_sprite_picker.editable = true
|
|
_icon_sprite_picker.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
_icon_sprite_picker.resource_changed.connect(_on_icon_sprite_resource_changed)
|
|
picker_hbox.add_child(_icon_sprite_picker)
|
|
|
|
var preview_container = PanelContainer.new()
|
|
preview_container.custom_minimum_size = Vector2(64, 64)
|
|
icon_container.add_child(preview_container)
|
|
|
|
_icon_sprite_preview = TextureRect.new()
|
|
_icon_sprite_preview.custom_minimum_size = Vector2(64, 64)
|
|
_icon_sprite_preview.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
|
|
_icon_sprite_preview.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
|
preview_container.add_child(_icon_sprite_preview)
|
|
|
|
func _on_icon_sprite_resource_changed(resource: Resource) -> void:
|
|
_selected_icon_sprite = resource
|
|
if resource and resource is Texture2D:
|
|
_icon_sprite_preview.texture = resource
|
|
else:
|
|
_icon_sprite_preview.texture = null
|
|
|
|
func _on_weapon_resource_changed(resource: Resource) -> void:
|
|
_selected_weapon = resource
|
|
|
|
func _set_default_values() -> void:
|
|
if settings:
|
|
_prefab_path_edit.text = settings.get("default_enemy_prefab_3d")
|
|
|
|
func _apply_prefill_data() -> void:
|
|
if prefill_data.is_empty():
|
|
_set_default_values()
|
|
return
|
|
|
|
if prefill_data.has("enemy_name"):
|
|
_enemy_name_edit.text = str(prefill_data["enemy_name"])
|
|
if prefill_data.has("enemy_key"):
|
|
_enemy_key_edit.text = str(prefill_data["enemy_key"])
|
|
if prefill_data.has("prefab_path"):
|
|
_prefab_path_edit.text = str(prefill_data["prefab_path"])
|
|
if prefill_data.has("is_3d"):
|
|
_is_3d_check.button_pressed = bool(prefill_data["is_3d"])
|
|
|
|
if prefill_data.has("max_health"):
|
|
_max_health_spin.value = float(prefill_data["max_health"])
|
|
if prefill_data.has("movement_speed"):
|
|
_movement_speed_spin.value = float(prefill_data["movement_speed"])
|
|
if prefill_data.has("motivation_reward"):
|
|
_motivation_reward_spin.value = float(prefill_data["motivation_reward"])
|
|
if prefill_data.has("weapon_resource"):
|
|
_selected_weapon = prefill_data["weapon_resource"]
|
|
_weapon_picker.edited_resource = _selected_weapon
|
|
|
|
if prefill_data.has("player_detection_range"):
|
|
_player_detection_range_spin.value = float(prefill_data["player_detection_range"])
|
|
if prefill_data.has("view_range"):
|
|
_view_range_spin.value = float(prefill_data["view_range"])
|
|
if prefill_data.has("alarm_react_range"):
|
|
_alarm_react_range_spin.value = float(prefill_data["alarm_react_range"])
|
|
if prefill_data.has("player_disengage_range"):
|
|
_player_disengage_range_spin.value = float(prefill_data["player_disengage_range"])
|
|
if prefill_data.has("strafe_speed"):
|
|
_strafe_speed_spin.value = float(prefill_data["strafe_speed"])
|
|
if prefill_data.has("max_strafe_distance"):
|
|
_max_strafe_distance_spin.value = float(prefill_data["max_strafe_distance"])
|
|
if prefill_data.has("min_strafe_distance"):
|
|
_min_strafe_distance_spin.value = float(prefill_data["min_strafe_distance"])
|
|
if prefill_data.has("response_time"):
|
|
_response_time_spin.value = float(prefill_data["response_time"])
|
|
if prefill_data.has("predict_player"):
|
|
_predict_player_check.button_pressed = bool(prefill_data["predict_player"])
|
|
|
|
if prefill_data.has("icon_sprite") and prefill_data["icon_sprite"] != null:
|
|
_selected_icon_sprite = prefill_data["icon_sprite"]
|
|
_icon_sprite_preview.texture = _selected_icon_sprite
|
|
_icon_sprite_picker.edited_resource = _selected_icon_sprite
|
|
|
|
func _on_create_pressed() -> void:
|
|
var enemy_name = _enemy_name_edit.text.strip_edges()
|
|
var enemy_key = _enemy_key_edit.text.strip_edges()
|
|
var prefab_path = _prefab_path_edit.text.strip_edges()
|
|
|
|
if enemy_name.is_empty():
|
|
_show_error("Enemy name cannot be empty!")
|
|
return
|
|
|
|
if enemy_key.is_empty():
|
|
_show_error("Enemy key cannot be empty!")
|
|
return
|
|
|
|
if prefab_path.is_empty():
|
|
_show_error("Prefab path cannot be empty!")
|
|
return
|
|
|
|
var enemy_data = {
|
|
"enemy_name": enemy_name,
|
|
"enemy_key": enemy_key,
|
|
"prefab_path": prefab_path,
|
|
"is_3d": _is_3d_check.button_pressed,
|
|
"max_health": _max_health_spin.value,
|
|
"movement_speed": _movement_speed_spin.value,
|
|
"motivation_reward": _motivation_reward_spin.value,
|
|
"weapon_resource": _selected_weapon,
|
|
"player_detection_range": _player_detection_range_spin.value,
|
|
"view_range": _view_range_spin.value,
|
|
"alarm_react_range": _alarm_react_range_spin.value,
|
|
"player_disengage_range": _player_disengage_range_spin.value,
|
|
"strafe_speed": _strafe_speed_spin.value,
|
|
"max_strafe_distance": _max_strafe_distance_spin.value,
|
|
"min_strafe_distance": _min_strafe_distance_spin.value,
|
|
"response_time": _response_time_spin.value,
|
|
"predict_player": _predict_player_check.button_pressed,
|
|
"icon_sprite": _selected_icon_sprite
|
|
}
|
|
|
|
_save_dialog_size_and_position()
|
|
enemy_data_confirmed.emit(enemy_data)
|
|
queue_free()
|