create_mod.gd 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. @tool
  2. extends Window
  3. signal mod_dir_created
  4. const DIR_NAME_DEFAULT_TEMPLATE = "default"
  5. const DIR_NAME_MINIMAL_TEMPLATE = "minimal"
  6. @onready var mod_tool_store: ModToolStore = get_node_or_null("/root/ModToolStore")
  7. @onready var mod_namespace: ModToolInterfaceInputString = $"%Namespace"
  8. @onready var mod_name: ModToolInterfaceInputString = $"%ModName"
  9. @onready var mod_id: ModToolInterfaceInputString = $"%ModId"
  10. @onready var mod_template: ModToolInterfaceInputOptions = $"%ModTemplate"
  11. func _ready() -> void:
  12. mod_namespace.show_error_if_not(false)
  13. mod_name.show_error_if_not(false)
  14. mod_id.show_error_if_not(false)
  15. func add_mod() -> void:
  16. # Validate mod-id
  17. if not mod_tool_store.manifest_data.is_mod_id_valid(mod_tool_store.name_mod_dir, mod_tool_store.name_mod_dir, "", true):
  18. ModToolUtils.output_error('Invalid name or namespace: "%s". You may only use letters, numbers, underscores and at least 3 characters for each.' % mod_tool_store.name_mod_dir)
  19. return
  20. # Check if mod dir exists
  21. if not _ModLoaderFile.dir_exists(mod_tool_store.path_mod_dir):
  22. # If not - create it
  23. var success := ModToolUtils.make_dir_recursive(mod_tool_store.path_mod_dir)
  24. if not success:
  25. return
  26. # Get Template files
  27. var template_paths := ModToolUtils.get_flat_view_dict(mod_tool_store.path_current_template_dir, "", [], false, true)
  28. # Copy current selected template dir files and folders to res://mods-unpacked
  29. for path in template_paths:
  30. var template_local_path := path.trim_prefix(mod_tool_store.path_current_template_dir) as String
  31. if _ModLoaderFile.file_exists(path):
  32. ModToolUtils.file_copy(path, mod_tool_store.path_mod_dir.path_join(template_local_path))
  33. else:
  34. ModToolUtils.make_dir_recursive(mod_tool_store.path_mod_dir.path_join(template_local_path))
  35. # Update FileSystem
  36. mod_tool_store.editor_file_system.scan()
  37. # Wait for the scan to finish
  38. await mod_tool_store.editor_file_system.filesystem_changed
  39. # Navigate to the new mod dir in the FileSystem pannel
  40. EditorInterface.get_file_system_dock().navigate_to_path(mod_tool_store.path_mod_dir.path_join("mod_main.gd"))
  41. # Output info
  42. ModToolUtils.output_info("Added base mod files to " + mod_tool_store.path_mod_dir)
  43. # Open mod_main.gd in the code editor
  44. var mod_main_script := load(mod_tool_store.path_mod_dir.path_join("mod_main.gd"))
  45. EditorInterface.edit_script(mod_main_script)
  46. EditorInterface.set_main_screen_editor("Script")
  47. # Split the new mod id
  48. var name_mod_dir_split: Array = mod_tool_store.name_mod_dir.split("-")
  49. # Update the namespace in the manifest
  50. mod_tool_store.manifest_data.mod_namespace = name_mod_dir_split[0]
  51. # Update the mod name in the manifest
  52. mod_tool_store.manifest_data.name = name_mod_dir_split[1]
  53. # Update manifest editor ui
  54. mod_tool_store.editor_plugin.tools_panel.manifest_editor.update_ui()
  55. # Open manifest editor
  56. mod_tool_store.editor_plugin.tools_panel.show_manifest_editor()
  57. # Save the manifest
  58. mod_tool_store.editor_plugin.tools_panel.manifest_editor.save_manifest()
  59. else:
  60. # If so - show error and ask if user wants to connect with the mod instead
  61. ModToolUtils.output_error("Mod directory at %s already exists." % mod_tool_store.path_mod_dir)
  62. # TODO: Ask user to connect with the mod instead
  63. return
  64. func clear_mod_id_input() -> void:
  65. mod_id.input_text = ""
  66. func get_template_options() -> Array[String]:
  67. var mod_template_options: Array[String] = []
  68. var template_dirs := _ModLoaderPath.get_dir_paths_in_dir(mod_tool_store.PATH_TEMPLATES_DIR)
  69. # Add the default templates
  70. mod_template_options.push_back(DIR_NAME_DEFAULT_TEMPLATE)
  71. mod_template_options.push_back(DIR_NAME_MINIMAL_TEMPLATE)
  72. for template_dir in template_dirs:
  73. var template_dir_name: String = template_dir.split("/")[-1]
  74. # Skip if its one of the default templates
  75. if (
  76. template_dir_name == DIR_NAME_DEFAULT_TEMPLATE or
  77. template_dir_name == DIR_NAME_MINIMAL_TEMPLATE
  78. ):
  79. continue
  80. # Add all the custom templates
  81. mod_template_options.push_back(template_dir_name)
  82. return mod_template_options
  83. func _on_Namespace_value_changed(new_value: String, input_node: ModToolInterfaceInputString) -> void:
  84. input_node.validate(mod_tool_store.manifest_data.is_name_or_namespace_valid(new_value, true))
  85. mod_id.input_text = "%s-%s" % [mod_namespace.get_input_value(), mod_name.get_input_value()]
  86. func _on_ModName_value_changed(new_value: String, input_node: ModToolInterfaceInputString) -> void:
  87. input_node.validate(mod_tool_store.manifest_data.is_name_or_namespace_valid(new_value, true))
  88. mod_id.input_text = "%s-%s" % [mod_namespace.get_input_value(), mod_name.get_input_value()]
  89. func _on_ModId_value_changed(new_value: String, input_node: ModToolInterfaceInputString) -> void:
  90. input_node.validate(mod_tool_store.manifest_data.is_mod_id_valid(new_value, new_value, "", true))
  91. mod_tool_store.name_mod_dir = new_value
  92. func _on_btn_create_mod_pressed() -> void:
  93. add_mod()
  94. emit_signal("mod_dir_created")
  95. func _on_CreateMod_about_to_show() -> void:
  96. # Reset Inputs
  97. mod_namespace.input_text = ""
  98. mod_name.input_text = ""
  99. # Reset Template
  100. mod_tool_store.path_current_template_dir = mod_tool_store.PATH_TEMPLATES_DIR + "default"
  101. # Get all Template options
  102. mod_template.input_options = get_template_options()
  103. func _on_ModTemplate_value_changed(new_value: String, input_node: ModToolInterfaceInputOptions) -> void:
  104. mod_tool_store.path_current_template_dir = mod_tool_store.PATH_TEMPLATES_DIR + new_value
  105. func _on_close_requested() -> void:
  106. hide()