cirnogodot/addons/weapon_creator/EnemyCreatorDialog.gd

305 lines
11 KiB
GDScript3
Raw Normal View History

@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()