diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/SCsub | 1 | ||||
-rw-r--r-- | core/bind/core_bind.cpp | 5 | ||||
-rw-r--r-- | core/bind/core_bind.h | 1 | ||||
-rw-r--r-- | core/color.h | 4 | ||||
-rw-r--r-- | core/func_ref.cpp | 10 | ||||
-rw-r--r-- | core/func_ref.h | 1 | ||||
-rw-r--r-- | core/input/input_map.cpp | 4 | ||||
-rw-r--r-- | core/io/file_access_zip.h | 2 | ||||
-rw-r--r-- | core/io/resource_format_binary.cpp | 7 | ||||
-rw-r--r-- | core/io/resource_importer.cpp | 3 | ||||
-rw-r--r-- | core/list.h | 40 | ||||
-rw-r--r-- | core/math/basis.cpp | 21 | ||||
-rw-r--r-- | core/math/basis.h | 5 | ||||
-rw-r--r-- | core/math/math_funcs.h | 19 | ||||
-rw-r--r-- | core/math/quat.h | 4 | ||||
-rw-r--r-- | core/math/random_pcg.h | 5 | ||||
-rw-r--r-- | core/math/vector2.h | 30 | ||||
-rw-r--r-- | core/message_queue.h | 3 | ||||
-rw-r--r-- | core/object.h | 2 | ||||
-rw-r--r-- | core/os/os.cpp | 4 | ||||
-rw-r--r-- | core/os/os.h | 2 | ||||
-rw-r--r-- | core/project_settings.cpp | 2 | ||||
-rw-r--r-- | core/project_settings.h | 1 | ||||
-rw-r--r-- | core/register_core_types.cpp | 2 | ||||
-rw-r--r-- | core/script_language.cpp | 8 | ||||
-rw-r--r-- | core/translation_po.h | 2 | ||||
-rw-r--r-- | core/ustring.cpp | 46 | ||||
-rw-r--r-- | core/variant_call.cpp | 4 | ||||
-rw-r--r-- | core/variant_op.cpp | 63 | ||||
-rw-r--r-- | core/variant_parser.cpp | 4 |
30 files changed, 210 insertions, 95 deletions
diff --git a/core/SCsub b/core/SCsub index 16ee49d003..59fe63b4b3 100644 --- a/core/SCsub +++ b/core/SCsub @@ -121,6 +121,7 @@ if env["builtin_zstd"]: "compress/zstdmt_compress.c", "compress/zstd_compress_literals.c", "compress/zstd_compress_sequences.c", + "compress/zstd_compress_superblock.c", "decompress/huf_decompress.c", "decompress/zstd_ddict.c", "decompress/zstd_decompress_block.c", diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 489ff762c9..c68222c767 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -519,10 +519,6 @@ uint64_t _OS::get_ticks_usec() const { return OS::get_singleton()->get_ticks_usec(); } -uint32_t _OS::get_splash_tick_msec() const { - return OS::get_singleton()->get_splash_tick_msec(); -} - bool _OS::can_use_threads() const { return OS::get_singleton()->can_use_threads(); } @@ -730,7 +726,6 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("delay_msec", "msec"), &_OS::delay_msec); ClassDB::bind_method(D_METHOD("get_ticks_msec"), &_OS::get_ticks_msec); ClassDB::bind_method(D_METHOD("get_ticks_usec"), &_OS::get_ticks_usec); - ClassDB::bind_method(D_METHOD("get_splash_tick_msec"), &_OS::get_splash_tick_msec); ClassDB::bind_method(D_METHOD("get_locale"), &_OS::get_locale); ClassDB::bind_method(D_METHOD("get_model_name"), &_OS::get_model_name); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index a59fcda60c..5c9520d7fe 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -208,7 +208,6 @@ public: void delay_msec(uint32_t p_msec) const; uint32_t get_ticks_msec() const; uint64_t get_ticks_usec() const; - uint32_t get_splash_tick_msec() const; bool can_use_threads() const; diff --git a/core/color.h b/core/color.h index 096e97e9ae..2dbbc52905 100644 --- a/core/color.h +++ b/core/color.h @@ -234,4 +234,8 @@ bool Color::operator<(const Color &p_color) const { } } +_FORCE_INLINE_ Color operator*(const real_t &p_real, const Color &p_color) { + return p_color * p_real; +} + #endif // COLOR_H diff --git a/core/func_ref.cpp b/core/func_ref.cpp index 4427d94d2a..7e062f16d0 100644 --- a/core/func_ref.cpp +++ b/core/func_ref.cpp @@ -64,6 +64,10 @@ void FuncRef::set_function(const StringName &p_func) { function = p_func; } +StringName FuncRef::get_function() { + return function; +} + bool FuncRef::is_valid() const { if (id.is_null()) { return false; @@ -88,6 +92,10 @@ void FuncRef::_bind_methods() { ClassDB::bind_method(D_METHOD("call_funcv", "arg_array"), &FuncRef::call_funcv); ClassDB::bind_method(D_METHOD("set_instance", "instance"), &FuncRef::set_instance); - ClassDB::bind_method(D_METHOD("set_function", "name"), &FuncRef::set_function); ClassDB::bind_method(D_METHOD("is_valid"), &FuncRef::is_valid); + + ClassDB::bind_method(D_METHOD("set_function", "name"), &FuncRef::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &FuncRef::get_function); + + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "function"), "set_function", "get_function"); } diff --git a/core/func_ref.h b/core/func_ref.h index 6b0b22bab5..75b84e705e 100644 --- a/core/func_ref.h +++ b/core/func_ref.h @@ -46,6 +46,7 @@ public: Variant call_funcv(const Array &p_args); void set_instance(Object *p_obj); void set_function(const StringName &p_func); + StringName get_function(); bool is_valid() const; FuncRef() {} diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index ac032b7d10..6319ffc8f1 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -95,6 +95,8 @@ List<StringName> InputMap::get_actions() const { } List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength) const { + ERR_FAIL_COND_V(!p_event.is_valid(), nullptr); + for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) { const Ref<InputEvent> e = E->get(); @@ -126,7 +128,7 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object."); ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'."); if (_find_event(input_map[p_action], p_event)) { - return; //already gots + return; // Already addded. } input_map[p_action].inputs.push_back(p_event); diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index 2cce24e878..c251b3c424 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -79,7 +79,7 @@ public: }; class FileAccessZip : public FileAccess { - unzFile zfile; + unzFile zfile = nullptr; unz_file_info64 file_info; mutable bool at_eof; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 5097f6d98b..21de7835ce 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -863,7 +863,8 @@ void ResourceLoaderBinary::open(FileAccess *p_f) { if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { f->close(); - ERR_FAIL_MSG("File format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path + "."); + ERR_FAIL_MSG(vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).", + local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH)); } type = get_unicode_string(); @@ -1136,7 +1137,9 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { memdelete(f); memdelete(fw); - ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "File format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path + "."); + ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, + vformat("File '%s' can't be loaded, as it uses a format version (%d) or engine version (%d.%d) which are not supported by your engine version (%s).", + local_path, ver_format, ver_major, ver_minor, VERSION_BRANCH)); } // Since we're not actually converting the file contents, leave the version diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 9ed159bd20..4d980bcf1a 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -31,6 +31,7 @@ #include "resource_importer.h" #include "core/os/os.h" +#include "core/project_settings.h" #include "core/variant_parser.h" bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceImporter> &p_a, const Ref<ResourceImporter> &p_b) const { @@ -374,7 +375,7 @@ Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const St } String ResourceFormatImporter::get_import_base_path(const String &p_for_file) const { - return "res://.import/" + p_for_file.get_file() + "-" + p_for_file.md5_text(); + return ProjectSettings::IMPORTED_FILES_PATH.plus_file(p_for_file.get_file() + "-" + p_for_file.md5_text()); } bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const { diff --git a/core/list.h b/core/list.h index f850db5241..1cef3c484d 100644 --- a/core/list.h +++ b/core/list.h @@ -395,28 +395,38 @@ public: ERR_FAIL_COND(p_A->data != _data); ERR_FAIL_COND(p_B->data != _data); + if (p_A == p_B) { + return; + } Element *A_prev = p_A->prev_ptr; Element *A_next = p_A->next_ptr; + Element *B_prev = p_B->prev_ptr; + Element *B_next = p_B->next_ptr; - p_A->next_ptr = p_B->next_ptr; - p_A->prev_ptr = p_B->prev_ptr; - - p_B->next_ptr = A_next; - p_B->prev_ptr = A_prev; - - if (p_A->prev_ptr) { - p_A->prev_ptr->next_ptr = p_A; + if (A_prev) { + A_prev->next_ptr = p_B; + } else { + _data->first = p_B; } - if (p_A->next_ptr) { - p_A->next_ptr->prev_ptr = p_A; + if (B_prev) { + B_prev->next_ptr = p_A; + } else { + _data->first = p_A; } - - if (p_B->prev_ptr) { - p_B->prev_ptr->next_ptr = p_B; + if (A_next) { + A_next->prev_ptr = p_B; + } else { + _data->last = p_B; } - if (p_B->next_ptr) { - p_B->next_ptr->prev_ptr = p_B; + if (B_next) { + B_next->prev_ptr = p_A; + } else { + _data->last = p_A; } + p_A->prev_ptr = A_next == p_B ? p_B : B_prev; + p_A->next_ptr = B_next == p_A ? p_B : B_next; + p_B->prev_ptr = B_next == p_A ? p_A : A_prev; + p_B->next_ptr = A_next == p_B ? p_A : A_next; } /** * copy the list diff --git a/core/math/basis.cpp b/core/math/basis.cpp index dd38e25bb1..a712ae7e3e 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -113,19 +113,22 @@ bool Basis::is_rotation() const { return Math::is_equal_approx(determinant(), 1, UNIT_EPSILON) && is_orthogonal(); } +#ifdef MATH_CHECKS +// This method is only used once, in diagonalize. If it's desired elsewhere, feel free to remove the #ifdef. bool Basis::is_symmetric() const { - if (!Math::is_equal_approx_ratio(elements[0][1], elements[1][0], UNIT_EPSILON)) { + if (!Math::is_equal_approx(elements[0][1], elements[1][0])) { return false; } - if (!Math::is_equal_approx_ratio(elements[0][2], elements[2][0], UNIT_EPSILON)) { + if (!Math::is_equal_approx(elements[0][2], elements[2][0])) { return false; } - if (!Math::is_equal_approx_ratio(elements[1][2], elements[2][1], UNIT_EPSILON)) { + if (!Math::is_equal_approx(elements[1][2], elements[2][1])) { return false; } return true; } +#endif Basis Basis::diagonalize() { //NOTE: only implemented for symmetric matrices @@ -737,18 +740,6 @@ bool Basis::is_equal_approx(const Basis &p_basis) const { return elements[0].is_equal_approx(p_basis.elements[0]) && elements[1].is_equal_approx(p_basis.elements[1]) && elements[2].is_equal_approx(p_basis.elements[2]); } -bool Basis::is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon) const { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (!Math::is_equal_approx_ratio(a.elements[i][j], b.elements[i][j], p_epsilon)) { - return false; - } - } - } - - return true; -} - bool Basis::operator==(const Basis &p_matrix) const { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { diff --git a/core/math/basis.h b/core/math/basis.h index a86937ceb4..2584f1ff48 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -146,9 +146,6 @@ public: } bool is_equal_approx(const Basis &p_basis) const; - // TODO: Break compatibility in 4.0 by getting rid of this so that it's only an instance method. See also TODO in variant_call.cpp - bool is_equal_approx(const Basis &a, const Basis &b) const { return a.is_equal_approx(b); } - bool is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon = UNIT_EPSILON) const; bool operator==(const Basis &p_matrix) const; bool operator!=(const Basis &p_matrix) const; @@ -238,7 +235,9 @@ public: void orthonormalize(); Basis orthonormalized() const; +#ifdef MATH_CHECKS bool is_symmetric() const; +#endif Basis diagonalize(); operator Quat() const { return get_quat(); } diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 9f8d4da5b3..f83ee44f4a 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -46,7 +46,8 @@ class Math { public: Math() {} // useless to instance - static const uint64_t RANDOM_MAX = 0xFFFFFFFF; + // Not using 'RANDOM_MAX' to avoid conflict with system headers on some OSes (at least NetBSD). + static const uint64_t RANDOM_32BIT_MAX = 0xFFFFFFFF; static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); } static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); } @@ -283,25 +284,13 @@ public: static void randomize(); static uint32_t rand_from_seed(uint64_t *seed); static uint32_t rand(); - static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_MAX; } - static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_MAX; } + static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_32BIT_MAX; } + static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_32BIT_MAX; } static double random(double from, double to); static float random(float from, float to); static real_t random(int from, int to) { return (real_t)random((real_t)from, (real_t)to); } - static _ALWAYS_INLINE_ bool is_equal_approx_ratio(real_t a, real_t b, real_t epsilon = CMP_EPSILON, real_t min_epsilon = CMP_EPSILON) { - // this is an approximate way to check that numbers are close, as a ratio of their average size - // helps compare approximate numbers that may be very big or very small - real_t diff = abs(a - b); - if (diff == 0.0 || diff < min_epsilon) { - return true; - } - real_t avg_size = (abs(a) + abs(b)) / 2.0; - diff /= avg_size; - return diff < epsilon; - } - static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b) { // Check for exact equality first, required to handle "infinity" values. if (a == b) { diff --git a/core/math/quat.h b/core/math/quat.h index 8619ea3c5c..3152b7d233 100644 --- a/core/math/quat.h +++ b/core/math/quat.h @@ -224,4 +224,8 @@ bool Quat::operator!=(const Quat &p_quat) const { return x != p_quat.x || y != p_quat.y || z != p_quat.z || w != p_quat.w; } +_FORCE_INLINE_ Quat operator*(const real_t &p_real, const Quat &p_quat) { + return p_quat * p_real; +} + #endif // QUAT_H diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h index 8fd5a056fa..09b13ab74d 100644 --- a/core/math/random_pcg.h +++ b/core/math/random_pcg.h @@ -31,12 +31,12 @@ #ifndef RANDOM_PCG_H #define RANDOM_PCG_H -#include <math.h> - #include "core/math/math_defs.h" #include "thirdparty/misc/pcg.h" +#include <math.h> + #if defined(__GNUC__) #define CLZ32(x) __builtin_clz(x) #elif defined(_MSC_VER) @@ -67,7 +67,6 @@ class RandomPCG { public: static const uint64_t DEFAULT_SEED = 12047754176567800795U; static const uint64_t DEFAULT_INC = PCG_DEFAULT_INC_64; - static const uint64_t RANDOM_MAX = 0xFFFFFFFF; RandomPCG(uint64_t p_seed = DEFAULT_SEED, uint64_t p_inc = DEFAULT_INC); diff --git a/core/math/vector2.h b/core/math/vector2.h index 0966d3392f..f41bcc15bc 100644 --- a/core/math/vector2.h +++ b/core/math/vector2.h @@ -150,7 +150,19 @@ _FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) return p_vec - *this * (dot(p_vec) - p_d); } -_FORCE_INLINE_ Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) { +_FORCE_INLINE_ Vector2 operator*(float p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector2 operator*(double p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector2 operator*(int32_t p_scalar, const Vector2 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector2 operator*(int64_t p_scalar, const Vector2 &p_vec) { return p_vec * p_scalar; } @@ -304,6 +316,22 @@ struct Vector2i { } }; +_FORCE_INLINE_ Vector2i operator*(const int32_t &p_scalar, const Vector2i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector2i operator*(const int64_t &p_scalar, const Vector2i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector2i operator*(const float &p_scalar, const Vector2i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector2i operator*(const double &p_scalar, const Vector2i &p_vector) { + return p_vector * p_scalar; +} + typedef Vector2i Size2i; typedef Vector2i Point2i; diff --git a/core/message_queue.h b/core/message_queue.h index 7d13e26208..710a605371 100644 --- a/core/message_queue.h +++ b/core/message_queue.h @@ -38,8 +38,7 @@ class MessageQueue { _THREAD_SAFE_CLASS_ enum { - - DEFAULT_QUEUE_SIZE_KB = 1024 + DEFAULT_QUEUE_SIZE_KB = 4096 }; enum { diff --git a/core/object.h b/core/object.h index f9a12da8f6..12ef600dfc 100644 --- a/core/object.h +++ b/core/object.h @@ -658,7 +658,7 @@ public: Variant call(const StringName &p_name, VARIANT_ARG_LIST); // C++ helper void notification(int p_notification, bool p_reversed = false); - String to_string(); + virtual String to_string(); //used mainly by script, get and set all INCLUDING string virtual Variant getvar(const Variant &p_key, bool *r_valid = nullptr) const; diff --git a/core/os/os.cpp b/core/os/os.cpp index dc8bd5ee69..3a398316bd 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -80,10 +80,6 @@ String OS::get_iso_date_time(bool local) const { timezone; } -uint64_t OS::get_splash_tick_msec() const { - return _msec_splash; -} - double OS::get_unix_time() const { return 0; } diff --git a/core/os/os.h b/core/os/os.h index 8e5c0c26e0..4c1d930107 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -52,7 +52,6 @@ class OS { bool _verbose_stdout = false; bool _debug_stdout = false; String _local_clipboard; - uint64_t _msec_splash; bool _no_window = false; int _exit_code = 0; int _orientation; @@ -220,7 +219,6 @@ public: virtual uint64_t get_ticks_usec() const = 0; uint32_t get_ticks_msec() const; - uint64_t get_splash_tick_msec() const; virtual bool is_userfs_persistent() const { return true; } diff --git a/core/project_settings.cpp b/core/project_settings.cpp index efe13e740d..90f56694c2 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -53,6 +53,8 @@ String ProjectSettings::get_resource_path() const { return resource_path; } +const String ProjectSettings::IMPORTED_FILES_PATH("res://.godot/imported"); + String ProjectSettings::localize_path(const String &p_path) const { if (resource_path == "") { return p_path; //not initialized yet diff --git a/core/project_settings.h b/core/project_settings.h index 29b2406dd2..6cbb02d30e 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -41,6 +41,7 @@ class ProjectSettings : public Object { public: typedef Map<String, Variant> CustomMap; + static const String IMPORTED_FILES_PATH; enum { //properties that are not for built in values begin from this value, so builtin ones are displayed first diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 4f094dd6c6..a2b3f75bea 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -232,7 +232,7 @@ void register_core_types() { } void register_core_settings() { - //since in register core types, globals may not e present + // Since in register core types, globals may not be present. GLOBAL_DEF("network/limits/tcp/connect_timeout_seconds", (30)); ProjectSettings::get_singleton()->set_custom_property_info("network/limits/tcp/connect_timeout_seconds", PropertyInfo(Variant::INT, "network/limits/tcp/connect_timeout_seconds", PROPERTY_HINT_RANGE, "1,1800,1")); GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16)); diff --git a/core/script_language.cpp b/core/script_language.cpp index b63aeb952c..d535c54dea 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -275,7 +275,13 @@ void ScriptServer::save_global_classes() { gcarr.push_back(d); } - ProjectSettings::get_singleton()->set("_global_script_classes", gcarr); + if (gcarr.empty()) { + if (ProjectSettings::get_singleton()->has_setting("_global_script_classes")) { + ProjectSettings::get_singleton()->clear("_global_script_classes"); + } + } else { + ProjectSettings::get_singleton()->set("_global_script_classes", gcarr); + } ProjectSettings::get_singleton()->save(); } diff --git a/core/translation_po.h b/core/translation_po.h index 730635f63d..88830210ef 100644 --- a/core/translation_po.h +++ b/core/translation_po.h @@ -42,7 +42,7 @@ class TranslationPO : public Translation { // TLDR: Maps context to a list of source strings and translated strings. In PO terms, maps msgctxt to a list of msgid and msgstr. // The first key corresponds to context, and the second key (of the contained HashMap) corresponds to source string. // The value Vector<StringName> in the second map stores the translated strings. Index 0, 1, 2 matches msgstr[0], msgstr[1], msgstr[2]... in the case of plurals. - // Otherwise index 0 mathes to msgstr in a singular translation. + // Otherwise index 0 matches to msgstr in a singular translation. // Strings without context have "" as first key. HashMap<StringName, HashMap<StringName, Vector<StringName>>> translation_map; diff --git a/core/ustring.cpp b/core/ustring.cpp index d5afbc2b47..e382ef3746 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -787,29 +787,46 @@ signed char String::naturalnocasecmp_to(const String &p_str) const { if (!*that_str) { return 1; } else if (IS_DIGIT(*this_str)) { - int64_t this_int, that_int; - if (!IS_DIGIT(*that_str)) { return -1; } - /* Compare the numbers */ - this_int = to_int(this_str, -1, true); - that_int = to_int(that_str, -1, true); - - if (this_int < that_int) { - return -1; - } else if (this_int > that_int) { - return 1; - } + // Keep ptrs to start of numerical sequences + const char32_t *this_substr = this_str; + const char32_t *that_substr = that_str; - /* Skip */ + // Compare lengths of both numerical sequences, ignoring leading zeros while (IS_DIGIT(*this_str)) { this_str++; } while (IS_DIGIT(*that_str)) { that_str++; } + while (*this_substr == '0') { + this_substr++; + } + while (*that_substr == '0') { + that_substr++; + } + int this_len = this_str - this_substr; + int that_len = that_str - that_substr; + + if (this_len < that_len) { + return -1; + } else if (this_len > that_len) { + return 1; + } + + // If lengths equal, compare lexicographically + while (this_substr != this_str && that_substr != that_str) { + if (*this_substr < *that_substr) { + return -1; + } else if (*this_substr > *that_substr) { + return 1; + } + this_substr++; + that_substr++; + } } else if (IS_DIGIT(*that_str)) { return 1; } else { @@ -4484,11 +4501,12 @@ String String::sprintf(const Array &values, bool *error) const { int number_len = str.length(); // Padding. + int pad_chars_count = (value < 0 || show_sign) ? min_chars - 1 : min_chars; String pad_char = pad_with_zeroes ? String("0") : String(" "); if (left_justified) { - str = str.rpad(min_chars, pad_char); + str = str.rpad(pad_chars_count, pad_char); } else { - str = str.lpad(min_chars, pad_char); + str = str.lpad(pad_chars_count, pad_char); } // Sign. diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 0ebb2f04a1..5fd970c8e1 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -1035,7 +1035,7 @@ struct _VariantCall { VCALL_PTR0R(Basis, get_orthogonal_index); VCALL_PTR0R(Basis, orthonormalized); VCALL_PTR2R(Basis, slerp); - VCALL_PTR2R(Basis, is_equal_approx); // TODO: Break compatibility in 4.0 to change this to an instance method (a.is_equal_approx(b) as VCALL_PTR1R) for consistency. + VCALL_PTR1R(Basis, is_equal_approx); VCALL_PTR0R(Basis, get_rotation_quat); VCALL_PTR0R(Transform, inverse); @@ -2356,7 +2356,7 @@ void register_variant_methods() { ADDFUNC1R(BASIS, VECTOR3, Basis, xform_inv, VECTOR3, "v", varray()); ADDFUNC0R(BASIS, INT, Basis, get_orthogonal_index, varray()); ADDFUNC2R(BASIS, BASIS, Basis, slerp, BASIS, "b", FLOAT, "t", varray()); - ADDFUNC2R(BASIS, BOOL, Basis, is_equal_approx, BASIS, "b", FLOAT, "epsilon", varray(CMP_EPSILON)); // TODO: Replace in 4.0, see other TODO. + ADDFUNC1R(BASIS, BOOL, Basis, is_equal_approx, BASIS, "b", varray()); ADDFUNC0R(BASIS, QUAT, Basis, get_rotation_quat, varray()); ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, inverse, varray()); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index ec4eea05bf..533b056f91 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -1031,6 +1031,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, case FLOAT: { _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._float); } + case INT: { + _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._int); + } default: _RETURN_FAIL; } @@ -1062,8 +1065,64 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, } } - DEFAULT_OP_NUM_VEC(math, OP_MULTIPLY, INT, *, _int); - DEFAULT_OP_NUM_VEC(math, OP_MULTIPLY, FLOAT, *, _float); + CASE_TYPE(math, OP_MULTIPLY, INT) { + if (p_b.type == INT) { + _RETURN(p_a._data._int * p_b._data._int); + } + if (p_b.type == FLOAT) { + _RETURN(p_a._data._int * p_b._data._float); + } + if (p_b.type == VECTOR2) { + _RETURN(p_a._data._int * *reinterpret_cast<const Vector2 *>(p_b._data._mem)); + } + if (p_b.type == VECTOR3) { + _RETURN(p_a._data._int * *reinterpret_cast<const Vector3 *>(p_b._data._mem)); + } + if (p_b.type == VECTOR2I) { + _RETURN(p_a._data._int * *reinterpret_cast<const Vector2i *>(p_b._data._mem)); + } + if (p_b.type == VECTOR3I) { + _RETURN(p_a._data._int * *reinterpret_cast<const Vector3i *>(p_b._data._mem)); + } + if (p_b.type == QUAT) { + _RETURN(p_a._data._int * *reinterpret_cast<const Quat *>(p_b._data._mem)); + } + if (p_b.type == COLOR) { + _RETURN(p_a._data._int * *reinterpret_cast<const Color *>(p_b._data._mem)); + } + + _RETURN_FAIL + } + + CASE_TYPE(math, OP_MULTIPLY, FLOAT) { + if (p_b.type == INT) { + _RETURN(p_a._data._float * p_b._data._int); + } + if (p_b.type == FLOAT) { + _RETURN(p_a._data._float * p_b._data._float); + } + if (p_b.type == VECTOR2) { + _RETURN(p_a._data._float * *reinterpret_cast<const Vector2 *>(p_b._data._mem)); + } + if (p_b.type == VECTOR3) { + _RETURN(p_a._data._float * *reinterpret_cast<const Vector3 *>(p_b._data._mem)); + } + if (p_b.type == VECTOR2I) { + _RETURN(p_a._data._float * *reinterpret_cast<const Vector2i *>(p_b._data._mem)); + } + if (p_b.type == VECTOR3I) { + _RETURN(p_a._data._float * *reinterpret_cast<const Vector3i *>(p_b._data._mem)); + } + if (p_b.type == QUAT) { + _RETURN(p_a._data._float * *reinterpret_cast<const Quat *>(p_b._data._mem)); + } + if (p_b.type == COLOR) { + _RETURN(p_a._data._float * *reinterpret_cast<const Color *>(p_b._data._mem)); + } + + _RETURN_FAIL + } + DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR2, *, Vector2); DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR2I, *, Vector2i); DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR3, *, Vector3); diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 3c4fed68fb..04cd4c1b9b 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -1608,10 +1608,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); if (E->next()) { p_store_string_func(p_store_string_ud, ",\n"); + } else { + p_store_string_func(p_store_string_ud, "\n"); } } - p_store_string_func(p_store_string_ud, "\n}"); + p_store_string_func(p_store_string_ud, "}"); } break; case Variant::ARRAY: { |