diff --git a/editor/editor_export_godot3.cpp b/editor/editor_export_godot3.cpp index 33b2aa25a4f2..d2798b4fce37 100644 --- a/editor/editor_export_godot3.cpp +++ b/editor/editor_export_godot3.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "editor_export_godot3.h" +#include "drivers/nrex/regex.h" #include "editor_node.h" #include "io/resource_format_binary.h" #include "io/resource_format_xml.h" @@ -1980,7 +1981,190 @@ void EditorExportGodot3::_save_config(const String &p_path) { f->close(); } -Error EditorExportGodot3::export_godot3(const String &p_path) { +Error EditorExportGodot3::_convert_script(const String &p_path, const String &p_target_path) { + + FileAccessRef src = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V(!src.operator->(), FAILED); + FileAccessRef dst = FileAccess::open(p_target_path, FileAccess::WRITE); + ERR_FAIL_COND_V(!dst.operator->(), FAILED); + + String http_var = ""; + + while (!src->eof_reached()) { + String line = src->get_line(); + + // Convert _fixed_process( => _physics_process( + RegEx regexp("(.*)_fixed_process\\((.*)"); + int res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + "_physics_process(" + regexp.get_capture(2); + } + regexp.clear(); + + // Convert RawArray() => PoolByteArray() + regexp.compile("(.*)RawArray\\(\\)(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + "PoolByteArray()" + regexp.get_capture(2); + } + regexp.clear(); + + // Convert Vector2Array() => PoolVector2Array() + regexp.compile("(.*)Vector2Array\\(\\)(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + "PoolVector2Array()" + regexp.get_capture(2); + } + regexp.clear(); + + // Convert ReferenceFrame => Control + regexp.compile("(.*)ReferenceFrame(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + "Control" + regexp.get_capture(2); + } + regexp.clear(); + + // Try to detect a HTTPClient object + regexp.compile("[ \t]*([a-zA-Z0-9_]*)[ ]*=[ ]*HTTPClient\\.new\\(\\)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 2) { + http_var = regexp.get_capture(1).strip_edges(); + } + regexp.clear(); + + if (http_var != "") { + // Convert .connect( => .connect_to_host( + regexp.compile("(.*)" + http_var + "\\.connect\\((.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + http_var + ".connect_to_host(" + regexp.get_capture(2); + } + regexp.clear(); + } + + int count; + int tries = 0; + do { + count = 0; + + // Convert _pos( => _position( + regexp.compile("(.*)_pos\\((.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + "_position(" + regexp.get_capture(2); + count++; + } + regexp.clear(); + + // Convert KEY_RETURN => KEY_ENTER + regexp.compile("(.*)KEY_RETURN(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + "KEY_ENTER" + regexp.get_capture(2); + count++; + } + regexp.clear(); + + // Convert .get_opacity() => .get_modulate().a + regexp.compile("(.*)\\.get_opacity\\(\\)(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + ".get_modulate().a" + regexp.get_capture(2); + count++; + } + regexp.clear(); + + // Convert .set_opacity(var) => .modulate.a = var + regexp.compile("([ \t]*)([a-zA-Z0-9_]*)[ ]*\\.set_opacity\\((.*)\\)(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 5) { + line = regexp.get_capture(1) + regexp.get_capture(2) + ".modulate.a = " + regexp.get_capture(3) + regexp.get_capture(4); + count++; + } + regexp.clear(); + + // Convert var.type == InputEvent.KEY => var is InputEventKey + regexp.compile("(.*)([a-zA-Z0-9_]*)\\.type == InputEvent.KEY(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 4) { + line = regexp.get_capture(1) + regexp.get_capture(2) + " is InputEventKey" + regexp.get_capture(3); + count++; + } + regexp.clear(); + + // Convert var.type == InputEvent.MOUSE_MOTION => var is InputEventMouseMotion + regexp.compile("(.*)([a-zA-Z0-9_]*)\\.type == InputEvent.MOUSE_MOTION(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 4) { + line = regexp.get_capture(1) + regexp.get_capture(2) + " is InputEventMouseMotion" + regexp.get_capture(3); + count++; + } + regexp.clear(); + + // Convert var.type == InputEvent.MOUSE_BUTTON => var is InputEventMouseButton + regexp.compile("(.*)([a-zA-Z0-9_]*)\\.type == InputEvent.MOUSE_BUTTON(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 4) { + line = regexp.get_capture(1) + regexp.get_capture(2) + " is InputEventMouseButton" + regexp.get_capture(3); + count++; + } + regexp.clear(); + + // Convert var.type == InputEvent.JOYSTICK_MOTION => var is InputEventJoypadMotion + regexp.compile("(.*)([a-zA-Z0-9_]*)\\.type == InputEvent.JOYSTICK_MOTION(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 4) { + line = regexp.get_capture(1) + regexp.get_capture(2) + " is InputEventJoypadMotion" + regexp.get_capture(3); + count++; + } + regexp.clear(); + + // Convert var.type == InputEvent.JOYSTICK_BUTTON => var is InputEventJoypadButton + regexp.compile("(.*)([a-zA-Z0-9_]*)\\.type == InputEvent.JOYSTICK_BUTTON(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 4) { + line = regexp.get_capture(1) + regexp.get_capture(2) + " is InputEventJoypadButton" + regexp.get_capture(3); + count++; + } + regexp.clear(); + + // Convert is_move_and_slide_on_floor() => is_on_floor() + regexp.compile("(.*)is_move_and_slide_on_floor\\(\\)(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + "is_on_floor()" + regexp.get_capture(2); + count++; + } + regexp.clear(); + + // Convert is_move_and_slide_on_ceiling() => is_on_ceiling() + regexp.compile("(.*)is_move_and_slide_on_ceiling\\(\\)(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + "is_on_ceiling()" + regexp.get_capture(2); + count++; + } + regexp.clear(); + + // Convert is_move_and_slide_on_wall() => is_on_wall() + regexp.compile("(.*)is_move_and_slide_on_wall\\(\\)(.*)"); + res = regexp.find(line); + if (res >= 0 && regexp.get_capture_count() == 3) { + line = regexp.get_capture(1) + "is_on_wall()" + regexp.get_capture(2); + count++; + } + regexp.clear(); + + } while (count >= 1 && tries++ < 10); + + dst->store_line(line); + } + + return OK; +} + +Error EditorExportGodot3::export_godot3(const String &p_path, bool convert_scripts) { List files; _find_files(EditorFileSystem::get_singleton()->get_filesystem(), &files); @@ -2076,34 +2260,36 @@ Error EditorExportGodot3::export_godot3(const String &p_path) { ExportData resource_data; + Error err; + bool cont = false; if (xml_extensions.has(extension)) { - Error err = ResourceLoader::get_export_data(path, resource_data); - if (err != OK) { - memdelete(directory); - ERR_FAIL_V(err); - } + + err = ResourceLoader::get_export_data(path, resource_data); } else if (text_extensions.has(extension)) { - Error err = ResourceLoader::get_export_data(path, resource_data); - if (err != OK) { - memdelete(directory); - ERR_FAIL_V(err); - } - } else if (binary_extensions.has(extension)) { - Error err = ResourceLoader::get_export_data(path, resource_data); - if (err != OK) { - memdelete(directory); - ERR_FAIL_V(err); - } + err = ResourceLoader::get_export_data(path, resource_data); + } else if (binary_extensions.has(extension)) { + err = ResourceLoader::get_export_data(path, resource_data); } else { - //single file, copy it - Error err = directory->copy(path, target_path); - if (err != OK) { - memdelete(directory); - ERR_FAIL_V(err); + + if (convert_scripts && extension == "gd") { + err = _convert_script(path, target_path); + } else { + //single file, copy it + err = directory->copy(path, target_path); } - continue; //no longer needed to do anything, just copied the file! + + cont = true; //no longer needed to do anything, just copied the file! + } + + if (err != OK) { + memdelete(directory); + ERR_FAIL_V(err); + } + + if (cont) { + continue; } if (resource_data.nodes.size() == 0 && resource_data.resources[resource_data.resources.size() - 1].type == "PackedScene") { diff --git a/editor/editor_export_godot3.h b/editor/editor_export_godot3.h index 127ce13528b4..e4795c56fbd2 100644 --- a/editor/editor_export_godot3.h +++ b/editor/editor_export_godot3.h @@ -87,10 +87,12 @@ class EditorExportGodot3 { void _unpack_packed_scene(ExportData &resource); void _pack_packed_scene(ExportData &resource); + Error _convert_script(const String &p_path, const String &p_target_path); + void _find_files(EditorFileSystemDirectory *p_dir, List *r_files); public: - Error export_godot3(const String &p_path); + Error export_godot3(const String &p_path, bool convert_scripts); EditorExportGodot3(); }; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 86e2cd256d01..be45f117f53d 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -5077,7 +5077,7 @@ void EditorNode::_bind_methods() { void EditorNode::_export_godot3_path(const String &p_path) { - Error err = export_godot3.export_godot3(p_path); + Error err = export_godot3.export_godot3(p_path, export_godot3_dialog_convert_scripts->is_pressed()); if (err != OK) { show_warning("Error exporting to Godot 3.0"); } @@ -6345,6 +6345,10 @@ EditorNode::EditorNode() { export_godot3_dialog = memnew(FileDialog); export_godot3_dialog->set_access(FileDialog::ACCESS_FILESYSTEM); export_godot3_dialog->set_mode(FileDialog::MODE_OPEN_DIR); + export_godot3_dialog_convert_scripts = memnew(CheckButton); + export_godot3_dialog_convert_scripts->set_text(TTR("Convert scripts (experimental)")); + export_godot3_dialog_convert_scripts->set_pressed(false); + export_godot3_dialog->get_vbox()->add_child(export_godot3_dialog_convert_scripts); gui_base->add_child(export_godot3_dialog); export_godot3_dialog->connect("dir_selected", this, "_export_godot3_path"); diff --git a/editor/editor_node.h b/editor/editor_node.h index a443675d9d5f..cd541471d7db 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -279,6 +279,7 @@ class EditorNode : public Node { EditorExportGodot3 export_godot3; FileDialog *export_godot3_dialog; + CheckButton *export_godot3_dialog_convert_scripts; CreateDialog *create_dialog;