Merge pull request #33569 from akien-mga/3.1
Assorted cherry-picks from the master branch for Godot 3.1.2 [4th batch]
This commit is contained in:
commit
7f6e2c5037
|
@ -165,7 +165,7 @@ License: FTL
|
|||
|
||||
Files: ./thirdparty/glad/
|
||||
Comment: glad
|
||||
Copyright: 2013-2018, David Herberth
|
||||
Copyright: 2013-2019, David Herberth
|
||||
License: Expat
|
||||
|
||||
Files: ./thirdparty/jpeg_compressor/
|
||||
|
@ -321,7 +321,7 @@ License: BSD-3-clause
|
|||
Files: ./thirdparty/misc/stb_truetype.h
|
||||
./thirdparty/misc/stb_vorbis.c
|
||||
Comment: stb libraries
|
||||
Copyright: 2007-2017, Sean Barrett
|
||||
Copyright: 2007-2019, Sean Barrett
|
||||
License: public-domain
|
||||
|
||||
Files: ./thirdparty/misc/triangulator.cpp
|
||||
|
@ -350,8 +350,8 @@ License: BSD-3-clause
|
|||
|
||||
Files: ./thirdparty/pcre2/
|
||||
Comment: PCRE2
|
||||
Copyright: 1997-2018, University of Cambridge,
|
||||
2009-2018, Zoltan Herczeg
|
||||
Copyright: 1997-2019, University of Cambridge,
|
||||
2009-2019, Zoltan Herczeg
|
||||
License: BSD-3-clause
|
||||
|
||||
Files: ./thirdparty/pvrtccompressor/
|
||||
|
@ -371,7 +371,7 @@ License: Expat
|
|||
|
||||
Files: ./thirdparty/tinyexr/
|
||||
Comment: TinyEXR
|
||||
Copyright: 2014-2018, Syoyo Fujita
|
||||
Copyright: 2014-2019, Syoyo Fujita
|
||||
2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC
|
||||
License: BSD-3-clause
|
||||
|
||||
|
|
|
@ -121,6 +121,8 @@ if env['builtin_zstd']:
|
|||
"compress/zstd_ldm.c",
|
||||
"compress/zstd_opt.c",
|
||||
"compress/zstdmt_compress.c",
|
||||
"compress/zstd_compress_literals.c",
|
||||
"compress/zstd_compress_sequences.c",
|
||||
"decompress/huf_decompress.c",
|
||||
"decompress/zstd_ddict.c",
|
||||
"decompress/zstd_decompress_block.c",
|
||||
|
|
|
@ -346,6 +346,12 @@ Error HTTPClient::poll() {
|
|||
} else {
|
||||
// We are already handshaking, which means we can use your already active SSL connection
|
||||
ssl = static_cast<Ref<StreamPeerSSL> >(connection);
|
||||
if (ssl.is_null()) {
|
||||
close();
|
||||
status = STATUS_SSL_HANDSHAKE_ERROR;
|
||||
return ERR_CANT_CONNECT;
|
||||
}
|
||||
|
||||
ssl->poll(); // Try to finish the handshake
|
||||
}
|
||||
|
||||
|
|
|
@ -1230,11 +1230,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
|||
buf += 4;
|
||||
PoolVector<uint8_t>::Read r = data.read();
|
||||
copymem(buf, &r[0], datalen * datasize);
|
||||
buf += datalen * datasize;
|
||||
}
|
||||
|
||||
r_len += 4 + datalen * datasize;
|
||||
while (r_len % 4)
|
||||
while (r_len % 4) {
|
||||
r_len++;
|
||||
if (buf)
|
||||
*(buf++) = 0;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Variant::POOL_INT_ARRAY: {
|
||||
|
|
|
@ -283,8 +283,9 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
|
|||
rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_name);
|
||||
}
|
||||
|
||||
ERR_EXPLAIN("RPC '" + String(p_name) + "' is not allowed from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
|
||||
ERR_FAIL_COND(!_can_call_mode(p_node, rpc_mode, p_from));
|
||||
bool can_call = _can_call_mode(p_node, rpc_mode, p_from);
|
||||
ERR_EXPLAIN("RPC '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
|
||||
ERR_FAIL_COND(!can_call);
|
||||
|
||||
int argc = p_packet[p_offset];
|
||||
Vector<Variant> args;
|
||||
|
@ -332,8 +333,9 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p
|
|||
rset_mode = p_node->get_script_instance()->get_rset_mode(p_name);
|
||||
}
|
||||
|
||||
ERR_EXPLAIN("RSET '" + String(p_name) + "' is not allowed from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
|
||||
ERR_FAIL_COND(!_can_call_mode(p_node, rset_mode, p_from));
|
||||
bool can_call = _can_call_mode(p_node, rset_mode, p_from);
|
||||
ERR_EXPLAIN("RSET '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
|
||||
ERR_FAIL_COND(!can_call);
|
||||
|
||||
Variant value;
|
||||
Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset, NULL, allow_object_decoding || network_peer->is_object_decoding_allowed());
|
||||
|
|
|
@ -702,9 +702,11 @@ public:
|
|||
/* if we can assume that the line segment starts outside the circle (e.g. for continuous time collision detection) then the following can be skipped and we can just return the equivalent of res1 */
|
||||
sqrtterm = Math::sqrt(sqrtterm);
|
||||
real_t res1 = (-b - sqrtterm) / (2 * a);
|
||||
//real_t res2 = ( -b + sqrtterm ) / (2 * a);
|
||||
real_t res2 = (-b + sqrtterm) / (2 * a);
|
||||
|
||||
return (res1 >= 0 && res1 <= 1) ? res1 : -1;
|
||||
if (res1 >= 0 && res1 <= 1) return res1;
|
||||
if (res2 >= 0 && res2 <= 1) return res2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline Vector<Vector3> clip_polygon(const Vector<Vector3> &polygon, const Plane &p_plane) {
|
||||
|
|
|
@ -218,12 +218,8 @@ Vector3 Vector3::linear_interpolate(const Vector3 &p_b, real_t p_t) const {
|
|||
}
|
||||
|
||||
Vector3 Vector3::slerp(const Vector3 &p_b, real_t p_t) const {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V(!is_normalized(), Vector3());
|
||||
#endif
|
||||
|
||||
real_t theta = angle_to(p_b);
|
||||
return rotated(cross(p_b), theta * p_t);
|
||||
return rotated(cross(p_b).normalized(), theta * p_t);
|
||||
}
|
||||
|
||||
real_t Vector3::distance_to(const Vector3 &p_b) const {
|
||||
|
|
|
@ -302,10 +302,6 @@ void MessageQueue::flush() {
|
|||
|
||||
_call_function(target, message->target, args, message->args, message->type & FLAG_SHOW_ERROR);
|
||||
|
||||
for (int i = 0; i < message->args; i++) {
|
||||
args[i].~Variant();
|
||||
}
|
||||
|
||||
} break;
|
||||
case TYPE_NOTIFICATION: {
|
||||
|
||||
|
@ -319,11 +315,17 @@ void MessageQueue::flush() {
|
|||
// messages don't expect a return value
|
||||
target->set(message->target, *arg);
|
||||
|
||||
arg->~Variant();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
|
||||
Variant *args = (Variant *)(message + 1);
|
||||
for (int i = 0; i < message->args; i++) {
|
||||
args[i].~Variant();
|
||||
}
|
||||
}
|
||||
|
||||
message->~Message();
|
||||
|
||||
_THREAD_SAFE_LOCK_
|
||||
|
|
|
@ -608,18 +608,16 @@ Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) co
|
|||
}
|
||||
bool valid = false;
|
||||
|
||||
Variant current_value = get(p_names[0]);
|
||||
Variant current_value = get(p_names[0], &valid);
|
||||
for (int i = 1; i < p_names.size(); i++) {
|
||||
current_value = current_value.get_named(p_names[i], &valid);
|
||||
|
||||
if (!valid) {
|
||||
if (r_valid)
|
||||
*r_valid = false;
|
||||
return Variant();
|
||||
}
|
||||
if (!valid)
|
||||
break;
|
||||
}
|
||||
if (r_valid)
|
||||
*r_valid = true;
|
||||
*r_valid = valid;
|
||||
|
||||
return current_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -779,8 +779,13 @@ public:
|
|||
static int get_object_count();
|
||||
|
||||
_FORCE_INLINE_ static bool instance_validate(Object *p_ptr) {
|
||||
rw_lock->read_lock();
|
||||
|
||||
return instance_checks.has(p_ptr);
|
||||
bool exists = instance_checks.has(p_ptr);
|
||||
|
||||
rw_lock->read_unlock();
|
||||
|
||||
return exists;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ void Input::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("action_press", "action", "strength"), &Input::action_press, DEFVAL(1.f));
|
||||
ClassDB::bind_method(D_METHOD("action_release", "action"), &Input::action_release);
|
||||
ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Input::set_default_cursor_shape, DEFVAL(CURSOR_ARROW));
|
||||
ClassDB::bind_method(D_METHOD("get_current_cursor_shape"), &Input::get_current_cursor_shape);
|
||||
ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
|
||||
ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
|
||||
ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input);
|
||||
|
|
|
@ -122,10 +122,10 @@ public:
|
|||
virtual bool is_emulating_touch_from_mouse() const = 0;
|
||||
virtual bool is_emulating_mouse_from_touch() const = 0;
|
||||
|
||||
virtual CursorShape get_default_cursor_shape() = 0;
|
||||
virtual CursorShape get_default_cursor_shape() const = 0;
|
||||
virtual void set_default_cursor_shape(CursorShape p_shape) = 0;
|
||||
virtual CursorShape get_current_cursor_shape() const = 0;
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) = 0;
|
||||
virtual void set_mouse_in_window(bool p_in_window) = 0;
|
||||
|
||||
virtual String get_joy_button_string(int p_button) = 0;
|
||||
virtual String get_joy_axis_string(int p_axis) = 0;
|
||||
|
|
|
@ -717,8 +717,17 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *
|
|||
bool pressed = same_direction ? Math::abs(jm->get_axis_value()) >= p_deadzone : false;
|
||||
if (p_pressed != NULL)
|
||||
*p_pressed = pressed;
|
||||
if (p_strength != NULL)
|
||||
*p_strength = pressed ? CLAMP(Math::inverse_lerp(p_deadzone, 1.0f, Math::abs(jm->get_axis_value())), 0.0f, 1.0f) : 0.0f;
|
||||
if (p_strength != NULL) {
|
||||
if (pressed) {
|
||||
if (p_deadzone == 1.0f) {
|
||||
*p_strength = 1.0f;
|
||||
} else {
|
||||
*p_strength = CLAMP(Math::inverse_lerp(p_deadzone, 1.0f, Math::abs(jm->get_axis_value())), 0.0f, 1.0f);
|
||||
}
|
||||
} else {
|
||||
*p_strength = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
|
|
@ -225,6 +225,16 @@ int OS::get_virtual_keyboard_height() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void OS::set_cursor_shape(CursorShape p_shape) {
|
||||
}
|
||||
|
||||
OS::CursorShape OS::get_cursor_shape() const {
|
||||
return CURSOR_ARROW;
|
||||
}
|
||||
|
||||
void OS::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
}
|
||||
|
||||
void OS::print_all_resources(String p_to_file) {
|
||||
|
||||
ERR_FAIL_COND(p_to_file != "" && _OSPRF);
|
||||
|
|
|
@ -378,8 +378,9 @@ public:
|
|||
// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
|
||||
virtual int get_virtual_keyboard_height() const;
|
||||
|
||||
virtual void set_cursor_shape(CursorShape p_shape) = 0;
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) = 0;
|
||||
virtual void set_cursor_shape(CursorShape p_shape);
|
||||
virtual CursorShape get_cursor_shape() const;
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
|
||||
|
||||
virtual bool get_swap_ok_cancel() { return false; }
|
||||
virtual void dump_memory_to_file(const char *p_file);
|
||||
|
|
|
@ -179,6 +179,7 @@ static const char *locale_list[] = {
|
|||
"ff_SN", // Fulah (Senegal)
|
||||
"fi", // Finnish
|
||||
"fi_FI", // Finnish (Finland)
|
||||
"fil", // Filipino
|
||||
"fil_PH", // Filipino (Philippines)
|
||||
"fo_FO", // Faroese (Faroe Islands)
|
||||
"fr", // French
|
||||
|
@ -227,6 +228,7 @@ static const char *locale_list[] = {
|
|||
"ja", // Japanese
|
||||
"ja_JP", // Japanese (Japan)
|
||||
"kab_DZ", // Kabyle (Algeria)
|
||||
"ka", // Georgian
|
||||
"ka_GE", // Georgian (Georgia)
|
||||
"kk_KZ", // Kazakh (Kazakhstan)
|
||||
"kl_GL", // Kalaallisut (Greenland)
|
||||
|
@ -257,10 +259,12 @@ static const char *locale_list[] = {
|
|||
"mg_MG", // Malagasy (Madagascar)
|
||||
"mh_MH", // Marshallese (Marshall Islands)
|
||||
"mhr_RU", // Eastern Mari (Russia)
|
||||
"mi_NZ", // Maori (New Zealand)
|
||||
"mi", // Māori
|
||||
"mi_NZ", // Māori (New Zealand)
|
||||
"miq_NI", // Mískito (Nicaragua)
|
||||
"mk", // Macedonian
|
||||
"mk_MK", // Macedonian (Macedonia)
|
||||
"ml", // Malayalam
|
||||
"ml_IN", // Malayalam (India)
|
||||
"mni_IN", // Manipuri (India)
|
||||
"mn_MN", // Mongolian (Mongolia)
|
||||
|
@ -326,6 +330,7 @@ static const char *locale_list[] = {
|
|||
"sgs_LT", // Samogitian (Lithuania)
|
||||
"shs_CA", // Shuswap (Canada)
|
||||
"sid_ET", // Sidamo (Ethiopia)
|
||||
"si", // Sinhala
|
||||
"si_LK", // Sinhala (Sri Lanka)
|
||||
"sk", // Slovak
|
||||
"sk_SK", // Slovak (Slovakia)
|
||||
|
@ -343,6 +348,7 @@ static const char *locale_list[] = {
|
|||
"sq_MK", // Albanian (Macedonia)
|
||||
"sr", // Serbian
|
||||
"sr_Cyrl", // Serbian (Cyrillic)
|
||||
"sr_Latn", // Serbian (Latin)
|
||||
"sr_ME", // Serbian (Montenegro)
|
||||
"sr_RS", // Serbian (Serbia)
|
||||
"ss_ZA", // Swati (South Africa)
|
||||
|
@ -357,6 +363,7 @@ static const char *locale_list[] = {
|
|||
"ta_IN", // Tamil (India)
|
||||
"ta_LK", // Tamil (Sri Lanka)
|
||||
"tcy_IN", // Tulu (India)
|
||||
"te", // Telugu
|
||||
"te_IN", // Telugu (India)
|
||||
"tg_TJ", // Tajik (Tajikistan)
|
||||
"the_NP", // Chitwania Tharu (Nepal)
|
||||
|
@ -540,6 +547,7 @@ static const char *locale_names[] = {
|
|||
"Fulah (Senegal)",
|
||||
"Finnish",
|
||||
"Finnish (Finland)",
|
||||
"Filipino",
|
||||
"Filipino (Philippines)",
|
||||
"Faroese (Faroe Islands)",
|
||||
"French",
|
||||
|
@ -588,6 +596,7 @@ static const char *locale_names[] = {
|
|||
"Japanese",
|
||||
"Japanese (Japan)",
|
||||
"Kabyle (Algeria)",
|
||||
"Georgian",
|
||||
"Georgian (Georgia)",
|
||||
"Kazakh (Kazakhstan)",
|
||||
"Kalaallisut (Greenland)",
|
||||
|
@ -618,10 +627,12 @@ static const char *locale_names[] = {
|
|||
"Malagasy (Madagascar)",
|
||||
"Marshallese (Marshall Islands)",
|
||||
"Eastern Mari (Russia)",
|
||||
"Maori (New Zealand)",
|
||||
"Māori",
|
||||
"Māori (New Zealand)",
|
||||
"Mískito (Nicaragua)",
|
||||
"Macedonian",
|
||||
"Macedonian (Macedonia)",
|
||||
"Malayalam",
|
||||
"Malayalam (India)",
|
||||
"Manipuri (India)",
|
||||
"Mongolian (Mongolia)",
|
||||
|
@ -687,6 +698,7 @@ static const char *locale_names[] = {
|
|||
"Samogitian (Lithuania)",
|
||||
"Shuswap (Canada)",
|
||||
"Sidamo (Ethiopia)",
|
||||
"Sinhala",
|
||||
"Sinhala (Sri Lanka)",
|
||||
"Slovak",
|
||||
"Slovak (Slovakia)",
|
||||
|
@ -704,6 +716,7 @@ static const char *locale_names[] = {
|
|||
"Albanian (Macedonia)",
|
||||
"Serbian",
|
||||
"Serbian (Cyrillic)",
|
||||
"Serbian (Latin)",
|
||||
"Serbian (Montenegro)",
|
||||
"Serbian (Serbia)",
|
||||
"Swati (South Africa)",
|
||||
|
@ -718,6 +731,7 @@ static const char *locale_names[] = {
|
|||
"Tamil (India)",
|
||||
"Tamil (Sri Lanka)",
|
||||
"Tulu (India)",
|
||||
"Telugu",
|
||||
"Telugu (India)",
|
||||
"Tajik (Tajikistan)",
|
||||
"Chitwania Tharu (Nepal)",
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="_export_end" qualifiers="virtual">
|
||||
<return type="void">
|
||||
</return>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="_export_file" qualifiers="virtual">
|
||||
<return type="void">
|
||||
</return>
|
||||
|
|
|
@ -214,14 +214,19 @@
|
|||
Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set animation offset properties.
|
||||
</constant>
|
||||
<constant name="PARAM_MAX" value="12" enum="Parameter">
|
||||
Represents the size of the [enum Parameter] enum.
|
||||
</constant>
|
||||
<constant name="FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="Flags">
|
||||
Use with [method set_flag] to set [member flag_align_y].
|
||||
</constant>
|
||||
<constant name="FLAG_ROTATE_Y" value="1" enum="Flags">
|
||||
Use with [method set_flag] to set [member flag_rotate_y]
|
||||
Use with [method set_flag] to set [member flag_rotate_y].
|
||||
</constant>
|
||||
<constant name="FLAG_DISABLE_Z" value="2" enum="Flags">
|
||||
Use with [method set_flag] to set [member flag_disable_z].
|
||||
</constant>
|
||||
<constant name="FLAG_MAX" value="3" enum="Flags">
|
||||
Represents the size of the [enum Flags] enum.
|
||||
</constant>
|
||||
<constant name="EMISSION_SHAPE_POINT" value="0" enum="EmissionShape">
|
||||
All particles will be emitted from a single point.
|
||||
|
|
|
@ -321,6 +321,12 @@
|
|||
<constant name="HALF_OFFSET_DISABLED" value="2" enum="HalfOffset">
|
||||
Half offset disabled.
|
||||
</constant>
|
||||
<constant name="HALF_OFFSET_NEGATIVE_X" value="3" enum="HalfOffset">
|
||||
Half offset on the X coordinate (negative).
|
||||
</constant>
|
||||
<constant name="HALF_OFFSET_NEGATIVE_Y" value="4" enum="HalfOffset">
|
||||
Half offset on the Y coordinate (negative).
|
||||
</constant>
|
||||
<constant name="TILE_ORIGIN_TOP_LEFT" value="0" enum="TileOrigin">
|
||||
Tile origin at its top-left corner.
|
||||
</constant>
|
||||
|
|
|
@ -1110,8 +1110,8 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
|
|||
|
||||
LightInstance *li = light_instance_owner.getornull(e->instance->light_instances[i]);
|
||||
|
||||
if (li->light_index >= render_light_instance_count) {
|
||||
continue; // too many
|
||||
if (li->light_index >= render_light_instance_count || render_light_instances[li->light_index] != li) {
|
||||
continue; // too many or light_index did not correspond to the light instances to be rendered
|
||||
}
|
||||
|
||||
if (copy) {
|
||||
|
|
|
@ -2354,7 +2354,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
|
|||
|
||||
if (p_depth_pass) {
|
||||
|
||||
if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) || p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER || p_material->shader->spatial.no_depth_test)
|
||||
if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) || p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER || p_material->shader->spatial.no_depth_test || p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_OFF)
|
||||
return; //bye
|
||||
|
||||
if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
|
||||
|
|
|
@ -191,6 +191,14 @@ Error AudioDriverPulseAudio::init_device() {
|
|||
spec.format = PA_SAMPLE_S16LE;
|
||||
spec.channels = pa_map.channels;
|
||||
spec.rate = mix_rate;
|
||||
pa_map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
|
||||
pa_map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
pa_map.map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
|
||||
pa_map.map[3] = PA_CHANNEL_POSITION_LFE;
|
||||
pa_map.map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
|
||||
pa_map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
|
||||
pa_map.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
|
||||
pa_map.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
|
||||
|
||||
pa_str = pa_stream_new(pa_ctx, "Sound", &spec, &pa_map);
|
||||
if (pa_str == NULL) {
|
||||
|
|
|
@ -544,7 +544,7 @@ public:
|
|||
|
||||
if (use_fps && animation->get_step() > 0) {
|
||||
float max_frame = animation->get_length() / animation->get_step();
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "frame", PROPERTY_HINT_RANGE, "0," + rtos(max_frame) + ",0.01"));
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "frame", PROPERTY_HINT_RANGE, "0," + rtos(max_frame) + ",1"));
|
||||
} else {
|
||||
p_list->push_back(PropertyInfo(Variant::REAL, "time", PROPERTY_HINT_RANGE, "0," + rtos(animation->get_length()) + ",0.01"));
|
||||
}
|
||||
|
@ -1205,7 +1205,9 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
|
|||
////////////////////////////////////
|
||||
|
||||
void AnimationTrackEdit::_notification(int p_what) {
|
||||
|
||||
if (p_what == NOTIFICATION_DRAW) {
|
||||
|
||||
if (animation.is_null())
|
||||
return;
|
||||
ERR_FAIL_INDEX(track, animation->get_track_count());
|
||||
|
@ -1241,20 +1243,15 @@ void AnimationTrackEdit::_notification(int p_what) {
|
|||
int ofs = in_group ? check->get_width() : 0; //not the best reference for margin but..
|
||||
|
||||
check_rect = Rect2(Point2(ofs, int(get_size().height - check->get_height()) / 2), check->get_size());
|
||||
|
||||
draw_texture(check, check_rect.position);
|
||||
|
||||
ofs += check->get_width() + hsep;
|
||||
|
||||
Ref<Texture> type_icon = type_icons[animation->track_get_type(track)];
|
||||
|
||||
draw_texture(type_icon, Point2(ofs, int(get_size().height - type_icon->get_height()) / 2));
|
||||
ofs += type_icon->get_width() + hsep;
|
||||
|
||||
NodePath path = animation->track_get_path(track);
|
||||
|
||||
Node *node = NULL;
|
||||
|
||||
if (root && root->has_node(path)) {
|
||||
node = root->get_node(path);
|
||||
}
|
||||
|
@ -1319,12 +1316,11 @@ void AnimationTrackEdit::_notification(int p_what) {
|
|||
draw_line(Point2(limit, 0), Point2(limit, get_size().height), linecolor, Math::round(EDSCALE));
|
||||
}
|
||||
|
||||
// KEYFAMES //
|
||||
// KEYFRAMES //
|
||||
|
||||
draw_bg(limit, get_size().width - timeline->get_buttons_width());
|
||||
|
||||
{
|
||||
|
||||
float scale = timeline->get_zoom_scale();
|
||||
int limit_end = get_size().width - timeline->get_buttons_width();
|
||||
|
||||
|
@ -1353,6 +1349,7 @@ void AnimationTrackEdit::_notification(int p_what) {
|
|||
draw_fg(limit, get_size().width - timeline->get_buttons_width());
|
||||
|
||||
// BUTTONS //
|
||||
|
||||
{
|
||||
|
||||
Ref<Texture> wrap_icon[2] = {
|
||||
|
@ -1577,7 +1574,18 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
|
|||
if (p_x < p_clip_left || p_x > p_clip_right)
|
||||
return;
|
||||
|
||||
Vector2 ofs(p_x - type_icon->get_width() / 2, int(get_size().height - type_icon->get_height()) / 2);
|
||||
Ref<Texture> icon_to_draw = p_selected ? selected_icon : type_icon;
|
||||
|
||||
// Override type icon for invalid value keys, unless selected.
|
||||
if (!p_selected && animation->track_get_type(track) == Animation::TYPE_VALUE) {
|
||||
const Variant &v = animation->track_get_key_value(track, p_index);
|
||||
Variant::Type valid_type = Variant::NIL;
|
||||
if (!_is_value_key_valid(v, valid_type)) {
|
||||
icon_to_draw = get_icon("KeyInvalid", "EditorIcons");
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 ofs(p_x - icon_to_draw->get_width() / 2, int(get_size().height - icon_to_draw->get_height()) / 2);
|
||||
|
||||
if (animation->track_get_type(track) == Animation::TYPE_METHOD) {
|
||||
Ref<Font> font = get_font("font", "Label");
|
||||
|
@ -1601,16 +1609,13 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
|
|||
}
|
||||
text += ")";
|
||||
|
||||
int limit = MAX(0, p_clip_right - p_x - type_icon->get_width());
|
||||
int limit = MAX(0, p_clip_right - p_x - icon_to_draw->get_width());
|
||||
if (limit > 0) {
|
||||
draw_string(font, Vector2(p_x + type_icon->get_width(), int(get_size().height - font->get_height()) / 2 + font->get_ascent()), text, color, limit);
|
||||
draw_string(font, Vector2(p_x + icon_to_draw->get_width(), int(get_size().height - font->get_height()) / 2 + font->get_ascent()), text, color, limit);
|
||||
}
|
||||
}
|
||||
if (p_selected) {
|
||||
draw_texture(selected_icon, ofs);
|
||||
} else {
|
||||
draw_texture(type_icon, ofs);
|
||||
}
|
||||
|
||||
draw_texture(icon_to_draw, ofs);
|
||||
}
|
||||
|
||||
//helper
|
||||
|
@ -1775,6 +1780,27 @@ void AnimationTrackEdit::_path_entered(const String &p_text) {
|
|||
undo_redo->commit_action();
|
||||
}
|
||||
|
||||
bool AnimationTrackEdit::_is_value_key_valid(const Variant &p_key_value, Variant::Type &r_valid_type) const {
|
||||
|
||||
RES res;
|
||||
Vector<StringName> leftover_path;
|
||||
Node *node = root->get_node_and_resource(animation->track_get_path(track), res, leftover_path);
|
||||
|
||||
Object *obj = NULL;
|
||||
if (res.is_valid()) {
|
||||
obj = res.ptr();
|
||||
} else if (node) {
|
||||
obj = node;
|
||||
}
|
||||
|
||||
bool prop_exists = false;
|
||||
if (obj) {
|
||||
r_valid_type = obj->get_static_property_type_indexed(leftover_path, &prop_exists);
|
||||
}
|
||||
|
||||
return (!prop_exists || Variant::can_convert(p_key_value.get_type(), r_valid_type));
|
||||
}
|
||||
|
||||
String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
|
||||
|
||||
if (check_rect.has_point(p_pos)) {
|
||||
|
@ -1845,29 +1871,10 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
|
|||
} break;
|
||||
case Animation::TYPE_VALUE: {
|
||||
|
||||
Variant v = animation->track_get_key_value(track, key_idx);
|
||||
//text+="value: "+String(v)+"\n";
|
||||
|
||||
bool prop_exists = false;
|
||||
Variant::Type valid_type = Variant::NIL;
|
||||
Object *obj = NULL;
|
||||
|
||||
RES res;
|
||||
Vector<StringName> leftover_path;
|
||||
Node *node = root->get_node_and_resource(animation->track_get_path(track), res, leftover_path);
|
||||
|
||||
if (res.is_valid()) {
|
||||
obj = res.ptr();
|
||||
} else if (node) {
|
||||
obj = node;
|
||||
}
|
||||
|
||||
if (obj) {
|
||||
valid_type = obj->get_static_property_type_indexed(leftover_path, &prop_exists);
|
||||
}
|
||||
|
||||
const Variant &v = animation->track_get_key_value(track, key_idx);
|
||||
text += "Type: " + Variant::get_type_name(v.get_type()) + "\n";
|
||||
if (prop_exists && !Variant::can_convert(v.get_type(), valid_type)) {
|
||||
Variant::Type valid_type = Variant::NIL;
|
||||
if (!_is_value_key_valid(v, valid_type)) {
|
||||
text += "Value: " + String(v) + " (Invalid, expected type: " + Variant::get_type_name(valid_type) + ")\n";
|
||||
} else {
|
||||
text += "Value: " + String(v) + "\n";
|
||||
|
@ -4122,6 +4129,7 @@ void AnimationTrackEditor::_update_key_edit() {
|
|||
key_edit = memnew(AnimationTrackKeyEdit);
|
||||
key_edit->animation = animation;
|
||||
key_edit->track = selection.front()->key().track;
|
||||
key_edit->use_fps = timeline->is_using_fps();
|
||||
|
||||
float ofs = animation->track_get_key_time(key_edit->track, selection.front()->key().key);
|
||||
key_edit->key_ofs = ofs;
|
||||
|
|
|
@ -31,6 +31,11 @@
|
|||
#ifndef ANIMATION_TRACK_EDITOR_H
|
||||
#define ANIMATION_TRACK_EDITOR_H
|
||||
|
||||
#include "editor/editor_data.h"
|
||||
#include "editor/editor_spin_slider.h"
|
||||
#include "editor/property_editor.h"
|
||||
#include "editor/property_selector.h"
|
||||
#include "scene/animation/animation_cache.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/file_dialog.h"
|
||||
#include "scene/gui/menu_button.h"
|
||||
|
@ -40,12 +45,6 @@
|
|||
#include "scene/gui/tab_container.h"
|
||||
#include "scene/gui/texture_rect.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
|
||||
#include "editor/property_selector.h"
|
||||
#include "editor_data.h"
|
||||
#include "editor_spin_slider.h"
|
||||
#include "property_editor.h"
|
||||
#include "scene/animation/animation_cache.h"
|
||||
#include "scene/resources/animation.h"
|
||||
#include "scene_tree_editor.h"
|
||||
|
||||
|
@ -175,8 +174,9 @@ class AnimationTrackEdit : public Control {
|
|||
|
||||
void _path_entered(const String &p_text);
|
||||
void _play_position_draw();
|
||||
mutable int dropping_at;
|
||||
bool _is_value_key_valid(const Variant &p_key_value, Variant::Type &r_valid_type) const;
|
||||
|
||||
mutable int dropping_at;
|
||||
float insert_at_pos;
|
||||
bool moving_selection_attempt;
|
||||
int select_single_attempt;
|
||||
|
|
|
@ -772,7 +772,7 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
|
|||
}
|
||||
}
|
||||
|
||||
if (!info.is_singleton && !info.in_editor) {
|
||||
if (!info.is_singleton && !info.in_editor && info.node != NULL) {
|
||||
memdelete(info.node);
|
||||
info.node = NULL;
|
||||
}
|
||||
|
|
|
@ -560,6 +560,7 @@ void EditorData::move_edited_scene_index(int p_idx, int p_to_idx) {
|
|||
ERR_FAIL_INDEX(p_to_idx, edited_scene.size());
|
||||
SWAP(edited_scene.write[p_idx], edited_scene.write[p_to_idx]);
|
||||
}
|
||||
|
||||
void EditorData::remove_scene(int p_idx) {
|
||||
ERR_FAIL_INDEX(p_idx, edited_scene.size());
|
||||
if (edited_scene[p_idx].root) {
|
||||
|
|
|
@ -611,6 +611,7 @@ void EditorExportPlugin::_bind_methods() {
|
|||
|
||||
BIND_VMETHOD(MethodInfo("_export_file", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "type"), PropertyInfo(Variant::POOL_STRING_ARRAY, "features")));
|
||||
BIND_VMETHOD(MethodInfo("_export_begin", PropertyInfo(Variant::POOL_STRING_ARRAY, "features"), PropertyInfo(Variant::BOOL, "is_debug"), PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "flags")));
|
||||
BIND_VMETHOD(MethodInfo("_export_end"));
|
||||
}
|
||||
|
||||
EditorExportPlugin::EditorExportPlugin() {
|
||||
|
|
|
@ -175,8 +175,9 @@ String EditorHelp::_fix_constant(const String &p_constant) const {
|
|||
if (p_constant.strip_edges() == "2147483647") {
|
||||
return "0x7FFFFFFF";
|
||||
}
|
||||
|
||||
if (p_constant.strip_edges() == "1048575") {
|
||||
return "0xfffff";
|
||||
return "0xFFFFF";
|
||||
}
|
||||
|
||||
return p_constant;
|
||||
|
|
|
@ -504,6 +504,7 @@ void EditorNode::_fs_changed() {
|
|||
void EditorNode::_resources_reimported(const Vector<String> &p_resources) {
|
||||
|
||||
List<String> scenes; //will load later
|
||||
int current_tab = scene_tabs->get_current_tab();
|
||||
|
||||
for (int i = 0; i < p_resources.size(); i++) {
|
||||
String file_type = ResourceLoader::get_resource_type(p_resources[i]);
|
||||
|
@ -526,6 +527,8 @@ void EditorNode::_resources_reimported(const Vector<String> &p_resources) {
|
|||
for (List<String>::Element *E = scenes.front(); E; E = E->next()) {
|
||||
reload_scene(E->get());
|
||||
}
|
||||
|
||||
scene_tabs->set_current_tab(current_tab);
|
||||
}
|
||||
|
||||
void EditorNode::_sources_changed(bool p_exist) {
|
||||
|
@ -1189,6 +1192,17 @@ void EditorNode::save_all_scenes() {
|
|||
_save_all_scenes();
|
||||
}
|
||||
|
||||
void EditorNode::save_scene_list(Vector<String> p_scene_filenames) {
|
||||
|
||||
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
|
||||
Node *scene = editor_data.get_edited_scene_root(i);
|
||||
|
||||
if (scene && (p_scene_filenames.find(scene->get_filename()) >= 0)) {
|
||||
_save_scene(scene->get_filename(), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorNode::restart_editor() {
|
||||
|
||||
exiting = true;
|
||||
|
@ -2744,7 +2758,7 @@ bool EditorNode::is_addon_plugin_enabled(const String &p_addon) const {
|
|||
return plugin_addons.has(p_addon);
|
||||
}
|
||||
|
||||
void EditorNode::_remove_edited_scene() {
|
||||
void EditorNode::_remove_edited_scene(bool p_change_tab) {
|
||||
int new_index = editor_data.get_edited_scene();
|
||||
int old_index = new_index;
|
||||
|
||||
|
@ -2760,18 +2774,19 @@ void EditorNode::_remove_edited_scene() {
|
|||
if (editor_data.get_scene_path(old_index) != String()) {
|
||||
ScriptEditor::get_singleton()->close_builtin_scripts_from_scene(editor_data.get_scene_path(old_index));
|
||||
}
|
||||
_scene_tab_changed(new_index);
|
||||
|
||||
if (p_change_tab) _scene_tab_changed(new_index);
|
||||
editor_data.remove_scene(old_index);
|
||||
editor_data.get_undo_redo().clear_history(false);
|
||||
_update_title();
|
||||
_update_scene_tabs();
|
||||
}
|
||||
|
||||
void EditorNode::_remove_scene(int index) {
|
||||
void EditorNode::_remove_scene(int index, bool p_change_tab) {
|
||||
|
||||
if (editor_data.get_edited_scene() == index) {
|
||||
//Scene to remove is current scene
|
||||
_remove_edited_scene();
|
||||
_remove_edited_scene(p_change_tab);
|
||||
} else {
|
||||
//Scene to remove is not active scene
|
||||
editor_data.remove_scene(index);
|
||||
|
@ -4023,6 +4038,14 @@ bool EditorNode::has_scenes_in_session() {
|
|||
return !scenes.empty();
|
||||
}
|
||||
|
||||
int EditorNode::get_current_tab() {
|
||||
return scene_tabs->get_current_tab();
|
||||
}
|
||||
|
||||
void EditorNode::set_current_tab(int p_tab) {
|
||||
scene_tabs->set_current_tab(p_tab);
|
||||
}
|
||||
|
||||
void EditorNode::_update_layouts_menu() {
|
||||
|
||||
editor_layouts->clear();
|
||||
|
@ -4612,8 +4635,7 @@ void EditorNode::reload_scene(const String &p_path) {
|
|||
|
||||
if (scene_idx == -1) {
|
||||
if (get_edited_scene()) {
|
||||
//scene is not open, so at it might be instanced, just refresh, set tab to itself and it will reload
|
||||
set_current_scene(current_tab);
|
||||
//scene is not open, so at it might be instanced. We'll refresh the whole scene later.
|
||||
editor_data.get_undo_redo().clear_history();
|
||||
}
|
||||
return;
|
||||
|
@ -4623,17 +4645,19 @@ void EditorNode::reload_scene(const String &p_path) {
|
|||
editor_data.apply_changes_in_editors();
|
||||
_set_scene_metadata(p_path);
|
||||
}
|
||||
//remove scene
|
||||
_remove_scene(scene_idx);
|
||||
//reload scene
|
||||
|
||||
//remove scene
|
||||
_remove_scene(scene_idx, false);
|
||||
|
||||
//reload scene
|
||||
load_scene(p_path, true, false, true, true);
|
||||
|
||||
//adjust index so tab is back a the previous position
|
||||
editor_data.move_edited_scene_to_index(scene_idx);
|
||||
get_undo_redo()->clear_history();
|
||||
|
||||
//recover the tab
|
||||
scene_tabs->set_current_tab(current_tab);
|
||||
_scene_tab_changed(current_tab);
|
||||
}
|
||||
|
||||
int EditorNode::plugin_init_callback_count = 0;
|
||||
|
@ -5440,7 +5464,7 @@ EditorNode::EditorNode() {
|
|||
p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true);
|
||||
p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Z), EDIT_REDO, true);
|
||||
p->add_separator();
|
||||
p->add_item(TTR("Revert Scene"), EDIT_REVERT);
|
||||
p->add_shortcut(ED_SHORTCUT("editor/revert_scene", TTR("Revert Scene")), EDIT_REVERT);
|
||||
|
||||
recent_scenes = memnew(PopupMenu);
|
||||
recent_scenes->set_name("RecentScenes");
|
||||
|
@ -5460,10 +5484,10 @@ EditorNode::EditorNode() {
|
|||
|
||||
p = project_menu->get_popup();
|
||||
p->set_hide_on_window_lose_focus(true);
|
||||
p->add_item(TTR("Project Settings"), RUN_SETTINGS);
|
||||
p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings")), RUN_SETTINGS);
|
||||
p->add_separator();
|
||||
p->connect("id_pressed", this, "_menu_option");
|
||||
p->add_item(TTR("Export"), FILE_EXPORT_PROJECT);
|
||||
p->add_shortcut(ED_SHORTCUT("editor/export", TTR("Export")), FILE_EXPORT_PROJECT);
|
||||
|
||||
plugin_config_dialog = memnew(PluginConfigDialog);
|
||||
plugin_config_dialog->connect("plugin_ready", this, "_on_plugin_ready");
|
||||
|
@ -5474,10 +5498,10 @@ EditorNode::EditorNode() {
|
|||
tool_menu->connect("index_pressed", this, "_tool_menu_option");
|
||||
p->add_child(tool_menu);
|
||||
p->add_submenu_item(TTR("Tools"), "Tools");
|
||||
tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
|
||||
tool_menu->add_shortcut(ED_SHORTCUT("editor/orphan_resource_explorer", TTR("Orphan Resource Explorer")), TOOLS_ORPHAN_RESOURCES);
|
||||
p->add_separator();
|
||||
|
||||
p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
|
||||
p->add_shortcut(ED_SHORTCUT("editor/open_project_data_folder", TTR("Open Project Data Folder")), RUN_PROJECT_DATA_FOLDER);
|
||||
p->add_separator();
|
||||
|
||||
#ifdef OSX_ENABLED
|
||||
|
@ -5501,21 +5525,21 @@ EditorNode::EditorNode() {
|
|||
p = debug_menu->get_popup();
|
||||
p->set_hide_on_window_lose_focus(true);
|
||||
p->set_hide_on_item_selection(false);
|
||||
p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG);
|
||||
p->add_check_shortcut(ED_SHORTCUT("editor/deploy_with_remote_debug", TTR("Deploy with Remote Debug")), RUN_DEPLOY_REMOTE_DEBUG);
|
||||
p->set_item_tooltip(p->get_item_count() - 1, TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged."));
|
||||
p->add_check_item(TTR("Small Deploy with Network FS"), RUN_FILE_SERVER);
|
||||
p->add_check_shortcut(ED_SHORTCUT("editor/small_deploy_with_network_fs", TTR("Small Deploy with Network FS")), RUN_FILE_SERVER);
|
||||
p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is enabled, export or deploy will produce a minimal executable.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploy will use the USB cable for faster performance. This option speeds up testing for games with a large footprint."));
|
||||
p->add_separator();
|
||||
p->add_check_item(TTR("Visible Collision Shapes"), RUN_DEBUG_COLLISONS);
|
||||
p->add_check_shortcut(ED_SHORTCUT("editor/visible_collision_shapes", TTR("Visible Collision Shapes")), RUN_DEBUG_COLLISONS);
|
||||
p->set_item_tooltip(p->get_item_count() - 1, TTR("Collision shapes and raycast nodes (for 2D and 3D) will be visible on the running game if this option is turned on."));
|
||||
p->add_check_item(TTR("Visible Navigation"), RUN_DEBUG_NAVIGATION);
|
||||
p->add_check_shortcut(ED_SHORTCUT("editor/visible_navigation", TTR("Visible Navigation")), RUN_DEBUG_NAVIGATION);
|
||||
p->set_item_tooltip(p->get_item_count() - 1, TTR("Navigation meshes and polygons will be visible on the running game if this option is turned on."));
|
||||
p->add_separator();
|
||||
//those are now on by default, since they are harmless
|
||||
p->add_check_item(TTR("Sync Scene Changes"), RUN_LIVE_DEBUG);
|
||||
p->add_check_shortcut(ED_SHORTCUT("editor/sync_scene_changes", TTR("Sync Scene Changes")), RUN_LIVE_DEBUG);
|
||||
p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any changes made to the scene in the editor will be replicated in the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
|
||||
p->set_item_checked(p->get_item_count() - 1, true);
|
||||
p->add_check_item(TTR("Sync Script Changes"), RUN_RELOAD_SCRIPTS);
|
||||
p->add_check_shortcut(ED_SHORTCUT("editor/sync_script_changes", TTR("Sync Script Changes")), RUN_RELOAD_SCRIPTS);
|
||||
p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any script that is saved will be reloaded on the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
|
||||
p->set_item_checked(p->get_item_count() - 1, true);
|
||||
p->connect("id_pressed", this, "_menu_option");
|
||||
|
@ -5531,7 +5555,7 @@ EditorNode::EditorNode() {
|
|||
|
||||
p = settings_menu->get_popup();
|
||||
p->set_hide_on_window_lose_focus(true);
|
||||
p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES);
|
||||
p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings")), SETTINGS_PREFERENCES);
|
||||
p->add_separator();
|
||||
|
||||
editor_layouts = memnew(PopupMenu);
|
||||
|
@ -5571,12 +5595,12 @@ EditorNode::EditorNode() {
|
|||
p->connect("id_pressed", this, "_menu_option");
|
||||
p->add_icon_shortcut(gui_base->get_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search"), KEY_F4), HELP_SEARCH);
|
||||
p->add_separator();
|
||||
p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Online Docs"), HELP_DOCS);
|
||||
p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Q&A"), HELP_QA);
|
||||
p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Issue Tracker"), HELP_ISSUES);
|
||||
p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Community"), HELP_COMMUNITY);
|
||||
p->add_icon_shortcut(gui_base->get_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/online_docs", TTR("Online Docs")), HELP_DOCS);
|
||||
p->add_icon_shortcut(gui_base->get_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/q&a", TTR("Q&A")), HELP_QA);
|
||||
p->add_icon_shortcut(gui_base->get_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/issue_tracker", TTR("Issue Tracker")), HELP_ISSUES);
|
||||
p->add_icon_shortcut(gui_base->get_icon("Instance", "EditorIcons"), ED_SHORTCUT("editor/community", TTR("Community")), HELP_COMMUNITY);
|
||||
p->add_separator();
|
||||
p->add_icon_item(gui_base->get_icon("Godot", "EditorIcons"), TTR("About"), HELP_ABOUT);
|
||||
p->add_icon_shortcut(gui_base->get_icon("Godot", "EditorIcons"), ED_SHORTCUT("editor/about", TTR("About")), HELP_ABOUT);
|
||||
|
||||
HBoxContainer *play_hb = memnew(HBoxContainer);
|
||||
menu_hb->add_child(play_hb);
|
||||
|
|
|
@ -499,8 +499,8 @@ private:
|
|||
static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog);
|
||||
|
||||
void _cleanup_scene();
|
||||
void _remove_edited_scene();
|
||||
void _remove_scene(int index);
|
||||
void _remove_edited_scene(bool p_change_tab = true);
|
||||
void _remove_scene(int index, bool p_change_tab = true);
|
||||
bool _find_and_save_resource(RES p_res, Map<RES, bool> &processed, int32_t flags);
|
||||
bool _find_and_save_edited_subresources(Object *obj, Map<RES, bool> &processed, int32_t flags);
|
||||
void _save_edited_subresources(Node *scene, Map<RES, bool> &processed, int32_t flags);
|
||||
|
@ -615,6 +615,12 @@ protected:
|
|||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
protected:
|
||||
friend class FileSystemDock;
|
||||
|
||||
int get_current_tab();
|
||||
void set_current_tab(int p_tab);
|
||||
|
||||
public:
|
||||
bool call_build();
|
||||
|
||||
|
@ -786,6 +792,7 @@ public:
|
|||
void remove_tool_menu_item(const String &p_name);
|
||||
|
||||
void save_all_scenes();
|
||||
void save_scene_list(Vector<String> p_scene_filenames);
|
||||
void restart_editor();
|
||||
|
||||
void dim_editor(bool p_dimming);
|
||||
|
|
|
@ -2289,6 +2289,16 @@ void EditorPropertyResource::_update_menu_items() {
|
|||
E = E->next();
|
||||
}
|
||||
|
||||
List<StringName> global_classes;
|
||||
ScriptServer::get_global_class_list(&global_classes);
|
||||
E = global_classes.front();
|
||||
while (E) {
|
||||
if (EditorNode::get_editor_data().script_class_is_parent(E->get(), base_type)) {
|
||||
valid_inheritors.insert(E->get());
|
||||
}
|
||||
E = E->next();
|
||||
}
|
||||
|
||||
for (Set<String>::Element *F = valid_inheritors.front(); F; F = F->next()) {
|
||||
String t = F->get();
|
||||
|
||||
|
@ -2305,7 +2315,7 @@ void EditorPropertyResource::_update_menu_items() {
|
|||
}
|
||||
}
|
||||
|
||||
if (!is_custom_resource && !ClassDB::can_instance(t))
|
||||
if (!is_custom_resource && !(ScriptServer::is_global_class(t) || ClassDB::can_instance(t)))
|
||||
continue;
|
||||
|
||||
inheritors_array.push_back(t);
|
||||
|
|
|
@ -268,6 +268,11 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
|||
String host_lang = OS::get_singleton()->get_locale();
|
||||
host_lang = TranslationServer::standardize_locale(host_lang);
|
||||
|
||||
// Some locales are not properly supported currently in Godot due to lack of font shaping
|
||||
// (e.g. Arabic or Hindi), so even though we have work in progress translations for them,
|
||||
// we skip them as they don't render properly. (GH-28577)
|
||||
const Vector<String> locales_to_skip = String("ar,bn,fa,he,hi,ml,si,ta,te,ur").split(",");
|
||||
|
||||
String best;
|
||||
|
||||
EditorTranslationList *etl = _editor_translations;
|
||||
|
@ -275,6 +280,15 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
|||
while (etl->data) {
|
||||
|
||||
const String &locale = etl->lang;
|
||||
|
||||
// Skip locales which we can't render properly (see above comment).
|
||||
// Test against language code without regional variants (e.g. ur_PK).
|
||||
String lang_code = locale.get_slice("_", 0);
|
||||
if (locales_to_skip.find(lang_code) != -1) {
|
||||
etl++;
|
||||
continue;
|
||||
}
|
||||
|
||||
lang_hint += ",";
|
||||
lang_hint += locale;
|
||||
|
||||
|
@ -543,6 +557,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
|||
_initial_set("editors/2d/bone_outline_size", 2);
|
||||
_initial_set("editors/2d/keep_margins_when_changing_anchors", false);
|
||||
_initial_set("editors/2d/viewport_border_color", Color(0.4, 0.4, 1.0, 0.4));
|
||||
_initial_set("editors/2d/constrain_editor_view", true);
|
||||
_initial_set("editors/2d/warped_mouse_panning", true);
|
||||
_initial_set("editors/2d/simple_spacebar_panning", false);
|
||||
_initial_set("editors/2d/scroll_to_pan", false);
|
||||
|
|
|
@ -1167,6 +1167,21 @@ void FileSystemDock::_update_favorites_list_after_move(const Map<String, String>
|
|||
EditorSettings::get_singleton()->set_favorites(new_favorites);
|
||||
}
|
||||
|
||||
void FileSystemDock::_save_scenes_after_move(const Map<String, String> &p_renames) const {
|
||||
Vector<String> remaps;
|
||||
_find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), p_renames, remaps);
|
||||
Vector<String> new_filenames;
|
||||
|
||||
for (int i = 0; i < remaps.size(); ++i) {
|
||||
String file = p_renames.has(remaps[i]) ? p_renames[remaps[i]] : remaps[i];
|
||||
if (ResourceLoader::get_resource_type(file) == "PackedScene") {
|
||||
new_filenames.push_back(file);
|
||||
}
|
||||
}
|
||||
|
||||
editor->save_scene_list(new_filenames);
|
||||
}
|
||||
|
||||
void FileSystemDock::_make_dir_confirm() {
|
||||
String dir_name = make_dir_dialog_text->get_text().strip_edges();
|
||||
|
||||
|
@ -1241,14 +1256,21 @@ void FileSystemDock::_rename_operation_confirm() {
|
|||
Map<String, String> file_renames;
|
||||
Map<String, String> folder_renames;
|
||||
_try_move_item(to_rename, new_path, file_renames, folder_renames);
|
||||
|
||||
int current_tab = editor->get_current_tab();
|
||||
|
||||
_update_dependencies_after_move(file_renames);
|
||||
_update_resource_paths_after_move(file_renames);
|
||||
_update_project_settings_after_move(file_renames);
|
||||
_update_favorites_list_after_move(file_renames, folder_renames);
|
||||
|
||||
//Rescan everything
|
||||
editor->set_current_tab(current_tab);
|
||||
|
||||
print_verbose("FileSystem: calling rescan.");
|
||||
_rescan();
|
||||
|
||||
print_verbose("FileSystem: saving moved scenes.");
|
||||
_save_scenes_after_move(file_renames);
|
||||
}
|
||||
|
||||
void FileSystemDock::_duplicate_operation_confirm() {
|
||||
|
@ -1334,13 +1356,20 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw
|
|||
}
|
||||
|
||||
if (is_moved) {
|
||||
int current_tab = editor->get_current_tab();
|
||||
|
||||
_update_dependencies_after_move(file_renames);
|
||||
_update_resource_paths_after_move(file_renames);
|
||||
_update_project_settings_after_move(file_renames);
|
||||
_update_favorites_list_after_move(file_renames, folder_renames);
|
||||
|
||||
editor->set_current_tab(current_tab);
|
||||
|
||||
print_verbose("FileSystem: calling rescan.");
|
||||
_rescan();
|
||||
|
||||
print_verbose("FileSystem: saving moved scenes.");
|
||||
_save_scenes_after_move(file_renames);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -201,6 +201,7 @@ private:
|
|||
void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const;
|
||||
void _update_dependencies_after_move(const Map<String, String> &p_renames) const;
|
||||
void _update_resource_paths_after_move(const Map<String, String> &p_renames) const;
|
||||
void _save_scenes_after_move(const Map<String, String> &p_renames) const;
|
||||
void _update_favorites_list_after_move(const Map<String, String> &p_files_renames, const Map<String, String> &p_folders_renames) const;
|
||||
void _update_project_settings_after_move(const Map<String, String> &p_folders_renames) const;
|
||||
|
||||
|
|
|
@ -751,7 +751,6 @@ void FindInFilesPanel::_on_replace_text_changed(String text) {
|
|||
void FindInFilesPanel::_on_replace_all_clicked() {
|
||||
|
||||
String replace_text = get_replace_text();
|
||||
ERR_FAIL_COND(replace_text.empty());
|
||||
|
||||
PoolStringArray modified_files;
|
||||
|
||||
|
@ -887,7 +886,7 @@ String FindInFilesPanel::get_replace_text() {
|
|||
void FindInFilesPanel::update_replace_buttons() {
|
||||
|
||||
String text = get_replace_text();
|
||||
bool disabled = text.empty() || _finder->is_searching();
|
||||
bool disabled = _finder->is_searching();
|
||||
|
||||
_replace_all_button->set_disabled(disabled);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="128"
|
||||
height="128"
|
||||
version="1.1"
|
||||
viewBox="0 0 128 128"
|
||||
id="svg6"
|
||||
sodipodi:docname="icon_gizmo_c_p_u_particles.svg"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1606"
|
||||
inkscape:window-height="821"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.6074563"
|
||||
inkscape:cx="101.29539"
|
||||
inkscape:cy="83.191634"
|
||||
inkscape:window-x="295"
|
||||
inkscape:window-y="81"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg6"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<path
|
||||
style="display:inline;opacity:1;fill:#f7f5cf;fill-opacity:1;stroke:#b4b4b4;stroke-width:2.56380486;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 35.503779,1.2819066 c -3.570424,0 -6.435164,2.9483368 -6.435164,6.6019028 v 4.3900146 c 0,0.889114 0.169457,1.726301 0.478513,2.49893 H 19.465369 c -3.570424,0 -6.435167,2.931453 -6.435167,6.585021 v 7.969562 c -0.341543,-0.0568 -0.648813,-0.202614 -1.006525,-0.202614 H 7.7335674 c -3.5704232,0 -6.451665,2.948338 -6.451665,6.601904 v 3.224972 c 0,3.653568 2.8812418,6.585016 6.451665,6.585016 h 4.2901096 c 0.358169,0 0.664563,-0.14568 1.006525,-0.202618 V 83.83104 C 12.688659,83.77398 12.381388,83.628424 12.023677,83.628424 H 7.7335674 c -3.5704232,0 -6.451665,2.948332 -6.451665,6.601908 v 3.224971 c 0,3.653575 2.8812418,6.585017 6.451665,6.585017 h 4.2901096 c 0.358169,0 0.664563,-0.145692 1.006525,-0.202612 v 9.725542 c 0,3.6536 2.864743,6.60193 6.435167,6.60193 h 9.603246 v 3.951 c 0,3.65357 2.86474,6.60192 6.435164,6.60192 h 3.15158 c 3.57042,0 6.451663,-2.94836 6.451663,-6.60192 v -3.95104 h 37.224955 v 3.951 c 0,3.65358 2.86474,6.60193 6.435166,6.60193 h 3.151583 c 3.570418,0 6.451653,-2.94836 6.451653,-6.60193 v -3.951 h 10.725281 c 3.57043,0 6.45166,-2.94833 6.45166,-6.60191 v -9.607372 c 0.14985,0.0105 0.27643,0.0846 0.42899,0.0846 h 4.29014 c 3.5704,0 6.45165,-2.931432 6.45165,-6.585011 v -3.224992 c 0,-3.653565 -2.88125,-6.601906 -6.45165,-6.601906 h -4.29014 c -0.15231,0 -0.27938,0.07348 -0.42899,0.08472 V 45.452198 c 0.14985,0.01042 0.27643,0.08445 0.42899,0.08445 h 4.29014 c 3.5704,0 6.45165,-2.931451 6.45165,-6.585023 v -3.224986 c 0,-3.653566 -2.88125,-6.601906 -6.45165,-6.601906 h -4.29014 c -0.15231,0 -0.27938,0.07392 -0.42899,0.08446 v -7.851429 c 0,-3.653567 -2.88123,-6.585019 -6.45166,-6.585021 H 97.875379 c 0.309043,-0.772641 0.494982,-1.609791 0.494982,-2.498929 V 7.8838054 c 0,-3.6535651 -2.881246,-6.601903 -6.451662,-6.601903 h -3.15158 c -3.570428,0 -6.435167,2.9483379 -6.435167,6.601903 V 12.27382 c 0,0.889115 0.16948,1.726301 0.478507,2.49893 H 44.612011 c 0.309083,-0.772642 0.495011,-1.609792 0.495011,-2.49893 V 7.8838054 c 0,-3.6535651 -2.881243,-6.601903 -6.451663,-6.601903 z"
|
||||
id="path4542"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:1;fill:#b4b4b4;fill-opacity:1;stroke-width:8.54601765"
|
||||
d="M 62.861474,21.661698 A 27.707285,31.502779 0 0 1 90.004671,47.07312 18.471523,18.901669 0 0 1 105.96058,65.764449 18.471523,18.901669 0 0 1 87.480108,84.658396 H 38.226348 A 18.471523,18.901669 0 0 1 19.762375,65.764449 18.471523,18.901669 0 0 1 35.685283,47.056234 27.707285,31.502779 0 0 1 62.861474,21.661698 Z"
|
||||
id="path4540"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:1;fill:#b4b4b4;fill-opacity:1;stroke-width:8.54601765"
|
||||
d="m 38.226348,90.956369 a 6.1571744,6.3005562 0 0 1 6.154657,6.297979 6.1571744,6.3005562 0 0 1 -6.154657,6.314882 6.1571744,6.3005562 0 0 1 -6.154657,-6.314882 6.1571744,6.3005562 0 0 1 6.154657,-6.297979 z"
|
||||
id="path4538"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:1;fill:#b4b4b4;fill-opacity:1;stroke-width:8.54601765"
|
||||
d="m 87.480108,90.956369 a 6.1571744,6.3005562 0 0 1 6.171159,6.297979 6.1571744,6.3005562 0 0 1 -6.171159,6.314882 6.1571744,6.3005562 0 0 1 -6.154656,-6.314882 6.1571744,6.3005562 0 0 1 6.154656,-6.297979 z"
|
||||
id="path4536"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:1;fill:#b4b4b4;fill-opacity:1;stroke-width:8.54601765"
|
||||
d="m 62.861474,97.254348 a 6.1571744,6.3005562 0 0 1 6.154662,6.314882 6.1571744,6.3005562 0 0 1 -6.154662,6.29797 6.1571744,6.3005562 0 0 1 -6.154651,-6.29797 6.1571744,6.3005562 0 0 1 6.154651,-6.314882 z"
|
||||
id="rect822"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
transform="translate(-0.35794507,-5.5049216)" />
|
||||
</svg>
|
After Width: | Height: | Size: 5.4 KiB |
|
@ -1,5 +0,0 @@
|
|||
<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(0 -1044.4)">
|
||||
<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#fff"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 253 B |
|
@ -2087,22 +2087,23 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
|
|||
animation->add_track(Animation::TYPE_VALUE);
|
||||
animation->track_set_path(track_idx, node_path);
|
||||
|
||||
if (track.weight_tracks[i].interpolation <= GLTFAnimation::INTERP_STEP) {
|
||||
animation->track_set_interpolation_type(track_idx, track.weight_tracks[i].interpolation == GLTFAnimation::INTERP_STEP ? Animation::INTERPOLATION_NEAREST : Animation::INTERPOLATION_NEAREST);
|
||||
// Only LINEAR and STEP (NEAREST) can be supported out of the box by Godot's Animation,
|
||||
// the other modes have to be baked.
|
||||
GLTFAnimation::Interpolation gltf_interp = track.weight_tracks[i].interpolation;
|
||||
if (gltf_interp == GLTFAnimation::INTERP_LINEAR || gltf_interp == GLTFAnimation::INTERP_STEP) {
|
||||
animation->track_set_interpolation_type(track_idx, gltf_interp == GLTFAnimation::INTERP_STEP ? Animation::INTERPOLATION_NEAREST : Animation::INTERPOLATION_LINEAR);
|
||||
for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
|
||||
float t = track.weight_tracks[i].times[j];
|
||||
float w = track.weight_tracks[i].values[j];
|
||||
animation->track_insert_key(track_idx, t, w);
|
||||
}
|
||||
} else {
|
||||
//must bake, apologies.
|
||||
// CATMULLROMSPLINE or CUBIC_SPLINE have to be baked, apologies.
|
||||
float increment = 1.0 / float(bake_fps);
|
||||
float time = 0.0;
|
||||
|
||||
bool last = false;
|
||||
while (true) {
|
||||
|
||||
_interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, track.weight_tracks[i].interpolation);
|
||||
_interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, gltf_interp);
|
||||
if (last) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1094,7 +1094,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
|
|||
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), ""));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "animation/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), animations_out ? true : false));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "animation/storage", PROPERTY_HINT_ENUM, "Built-In,Files", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), animations_out ? true : false));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/keep_custom_tracks"), animations_out ? true : false));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/optimizer/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
|
||||
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_linear_error"), 0.05));
|
||||
|
|
|
@ -1430,6 +1430,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
|
|||
new_state["show_rulers"] = false;
|
||||
new_state["show_guides"] = false;
|
||||
new_state["show_helpers"] = false;
|
||||
new_state["show_zoom_control"] = false;
|
||||
// TODO: Save/restore only affected entries
|
||||
CanvasItemEditor::get_singleton()->set_state(new_state);
|
||||
}
|
||||
|
@ -1482,7 +1483,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
|
|||
if (valid) {
|
||||
player->seek(pos, true);
|
||||
get_tree()->flush_transform_notifications(); // Needed for transforms of Spatials
|
||||
values_backup.update_skeletons(); // Needed for Skeletons
|
||||
values_backup.update_skeletons(); // Needed for Skeletons (2D & 3D)
|
||||
|
||||
VS::get_singleton()->viewport_set_active(onion.captures[cidx], true);
|
||||
VS::get_singleton()->viewport_set_parent_viewport(root_vp, onion.captures[cidx]);
|
||||
|
|
|
@ -726,6 +726,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
|
|||
|
||||
image_data = cached_data;
|
||||
file->close();
|
||||
memdelete(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -800,6 +801,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
|
|||
if (file) {
|
||||
file->store_line(new_etag);
|
||||
file->close();
|
||||
memdelete(file);
|
||||
}
|
||||
|
||||
int len = p_data.size();
|
||||
|
@ -809,6 +811,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
|
|||
file->store_32(len);
|
||||
file->store_buffer(r.ptr(), len);
|
||||
file->close();
|
||||
memdelete(file);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -848,6 +851,7 @@ void EditorAssetLibrary::_update_image_queue() {
|
|||
if (file) {
|
||||
headers.push_back("If-None-Match: " + file->get_line());
|
||||
file->close();
|
||||
memdelete(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3547,18 +3547,19 @@ void CanvasItemEditor::_update_scrollbars() {
|
|||
// Constraints the view offset and updates the scrollbars
|
||||
Point2 begin = canvas_item_rect.position;
|
||||
Point2 end = canvas_item_rect.position + canvas_item_rect.size - local_rect.size / zoom;
|
||||
bool constrain_editor_view = bool(EditorSettings::get_singleton()->get("editors/2d/constrain_editor_view"));
|
||||
|
||||
if (canvas_item_rect.size.height <= (local_rect.size.y / zoom)) {
|
||||
if (ABS(begin.y - previous_update_view_offset.y) < ABS(begin.y - view_offset.y)) {
|
||||
if (constrain_editor_view && ABS(begin.y - previous_update_view_offset.y) < ABS(begin.y - view_offset.y)) {
|
||||
view_offset.y = previous_update_view_offset.y;
|
||||
}
|
||||
|
||||
v_scroll->hide();
|
||||
} else {
|
||||
if (view_offset.y > end.y && view_offset.y > previous_update_view_offset.y) {
|
||||
if (constrain_editor_view && view_offset.y > end.y && view_offset.y > previous_update_view_offset.y) {
|
||||
view_offset.y = MAX(end.y, previous_update_view_offset.y);
|
||||
}
|
||||
if (view_offset.y < begin.y && view_offset.y < previous_update_view_offset.y) {
|
||||
if (constrain_editor_view && view_offset.y < begin.y && view_offset.y < previous_update_view_offset.y) {
|
||||
view_offset.y = MIN(begin.y, previous_update_view_offset.y);
|
||||
}
|
||||
|
||||
|
@ -3569,16 +3570,16 @@ void CanvasItemEditor::_update_scrollbars() {
|
|||
}
|
||||
|
||||
if (canvas_item_rect.size.width <= (local_rect.size.x / zoom)) {
|
||||
if (ABS(begin.x - previous_update_view_offset.x) < ABS(begin.x - view_offset.x)) {
|
||||
if (constrain_editor_view && ABS(begin.x - previous_update_view_offset.x) < ABS(begin.x - view_offset.x)) {
|
||||
view_offset.x = previous_update_view_offset.x;
|
||||
}
|
||||
|
||||
h_scroll->hide();
|
||||
} else {
|
||||
if (view_offset.x > end.x && view_offset.x > previous_update_view_offset.x) {
|
||||
if (constrain_editor_view && view_offset.x > end.x && view_offset.x > previous_update_view_offset.x) {
|
||||
view_offset.x = MAX(end.x, previous_update_view_offset.x);
|
||||
}
|
||||
if (view_offset.x < begin.x && view_offset.x < previous_update_view_offset.x) {
|
||||
if (constrain_editor_view && view_offset.x < begin.x && view_offset.x < previous_update_view_offset.x) {
|
||||
view_offset.x = MIN(begin.x, previous_update_view_offset.x);
|
||||
}
|
||||
|
||||
|
@ -3903,6 +3904,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
|
|||
show_rulers = !show_rulers;
|
||||
int idx = view_menu->get_popup()->get_item_index(SHOW_RULERS);
|
||||
view_menu->get_popup()->set_item_checked(idx, show_rulers);
|
||||
_update_scrollbars();
|
||||
viewport->update();
|
||||
} break;
|
||||
case SHOW_GUIDES: {
|
||||
|
@ -4371,6 +4373,7 @@ Dictionary CanvasItemEditor::get_state() const {
|
|||
state["show_rulers"] = show_rulers;
|
||||
state["show_guides"] = show_guides;
|
||||
state["show_helpers"] = show_helpers;
|
||||
state["show_zoom_control"] = zoom_hb->is_visible();
|
||||
state["show_edit_locks"] = show_edit_locks;
|
||||
state["snap_rotation"] = snap_rotation;
|
||||
state["snap_relative"] = snap_relative;
|
||||
|
@ -4381,6 +4384,7 @@ Dictionary CanvasItemEditor::get_state() const {
|
|||
|
||||
void CanvasItemEditor::set_state(const Dictionary &p_state) {
|
||||
|
||||
bool update_scrollbars = false;
|
||||
Dictionary state = p_state;
|
||||
if (state.has("zoom")) {
|
||||
zoom = p_state["zoom"];
|
||||
|
@ -4389,7 +4393,7 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
|
|||
if (state.has("ofs")) {
|
||||
view_offset = p_state["ofs"];
|
||||
previous_update_view_offset = view_offset;
|
||||
_update_scrollbars();
|
||||
update_scrollbars = true;
|
||||
}
|
||||
|
||||
if (state.has("grid_offset")) {
|
||||
|
@ -4477,6 +4481,7 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
|
|||
show_rulers = state["show_rulers"];
|
||||
int idx = view_menu->get_popup()->get_item_index(SHOW_RULERS);
|
||||
view_menu->get_popup()->set_item_checked(idx, show_rulers);
|
||||
update_scrollbars = true;
|
||||
}
|
||||
|
||||
if (state.has("show_guides")) {
|
||||
|
@ -4497,6 +4502,11 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
|
|||
view_menu->get_popup()->set_item_checked(idx, show_edit_locks);
|
||||
}
|
||||
|
||||
if (state.has("show_zoom_control")) {
|
||||
// This one is not user-controllable, but instrumentable
|
||||
zoom_hb->set_visible(state["show_zoom_control"]);
|
||||
}
|
||||
|
||||
if (state.has("snap_rotation")) {
|
||||
snap_rotation = state["snap_rotation"];
|
||||
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
|
||||
|
@ -4521,6 +4531,9 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
|
|||
skeleton_menu->get_popup()->set_item_checked(idx, skeleton_show_bones);
|
||||
}
|
||||
|
||||
if (update_scrollbars) {
|
||||
_update_scrollbars();
|
||||
}
|
||||
viewport->update();
|
||||
}
|
||||
|
||||
|
|
|
@ -1906,10 +1906,11 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
|
|||
String flags = EditorSettings::get_singleton()->get("text_editor/external/exec_flags");
|
||||
|
||||
List<String> args;
|
||||
bool has_file_flag = false;
|
||||
String script_path = ProjectSettings::get_singleton()->globalize_path(p_resource->get_path());
|
||||
|
||||
if (flags.size()) {
|
||||
String project_path = ProjectSettings::get_singleton()->get_resource_path();
|
||||
String script_path = ProjectSettings::get_singleton()->globalize_path(p_resource->get_path());
|
||||
|
||||
flags = flags.replacen("{line}", itos(p_line > 0 ? p_line : 0));
|
||||
flags = flags.replacen("{col}", itos(p_col));
|
||||
|
@ -1931,6 +1932,9 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
|
|||
} else if (flags[i] == '\0' || (!inside_quotes && flags[i] == ' ')) {
|
||||
|
||||
String arg = flags.substr(from, num_chars);
|
||||
if (arg.find("{file}") != -1) {
|
||||
has_file_flag = true;
|
||||
}
|
||||
|
||||
// do path replacement here, else there will be issues with spaces and quotes
|
||||
arg = arg.replacen("{project}", project_path);
|
||||
|
@ -1945,6 +1949,11 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
|
|||
}
|
||||
}
|
||||
|
||||
// Default to passing script path if no {file} flag is specified.
|
||||
if (!has_file_flag) {
|
||||
args.push_back(script_path);
|
||||
}
|
||||
|
||||
Error err = OS::get_singleton()->execute(path, args, false);
|
||||
if (err == OK)
|
||||
return false;
|
||||
|
@ -3331,7 +3340,8 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
|
|||
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/list_script_names_as", PROPERTY_HINT_ENUM, "Name,Parent Directory And Name,Full Path"));
|
||||
EDITOR_DEF("text_editor/open_scripts/list_script_names_as", 0);
|
||||
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "text_editor/external/exec_path", PROPERTY_HINT_GLOBAL_FILE));
|
||||
EDITOR_DEF("text_editor/external/exec_flags", "");
|
||||
EDITOR_DEF("text_editor/external/exec_flags", "{file}");
|
||||
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "text_editor/external/exec_flags", PROPERTY_HINT_PLACEHOLDER_TEXT, "Call flags with placeholders: {project}, {file}, {col}, {line}."));
|
||||
|
||||
ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T);
|
||||
ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Files"));
|
||||
|
|
|
@ -165,7 +165,7 @@ void ScriptTextEditor::_load_theme_settings() {
|
|||
text_edit->add_color_override("safe_line_number_color", safe_line_number_color);
|
||||
text_edit->add_color_override("caret_color", caret_color);
|
||||
text_edit->add_color_override("caret_background_color", caret_background_color);
|
||||
text_edit->add_color_override("font_selected_color", text_selected_color);
|
||||
text_edit->add_color_override("font_color_selected", text_selected_color);
|
||||
text_edit->add_color_override("selection_color", selection_color);
|
||||
text_edit->add_color_override("brace_mismatch_color", brace_mismatch_color);
|
||||
text_edit->add_color_override("current_line_color", current_line_color);
|
||||
|
@ -1329,7 +1329,9 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
|
|||
|
||||
if (has_color) {
|
||||
String line = tx->get_line(row);
|
||||
color_line = row;
|
||||
color_position.x = row;
|
||||
color_position.y = col;
|
||||
|
||||
int begin = 0;
|
||||
int end = 0;
|
||||
bool valid = false;
|
||||
|
@ -1369,10 +1371,15 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
|
|||
new_args = String("(" + rtos(p_color.r) + ", " + rtos(p_color.g) + ", " + rtos(p_color.b) + ", " + rtos(p_color.a) + ")");
|
||||
}
|
||||
|
||||
String line = code_editor->get_text_edit()->get_line(color_line);
|
||||
String new_line = line.replace(color_args, new_args);
|
||||
String line = code_editor->get_text_edit()->get_line(color_position.x);
|
||||
int color_args_pos = line.find(color_args, color_position.y);
|
||||
String line_with_replaced_args = line;
|
||||
line_with_replaced_args.erase(color_args_pos, color_args.length());
|
||||
line_with_replaced_args = line_with_replaced_args.insert(color_args_pos, new_args);
|
||||
|
||||
color_args = new_args;
|
||||
code_editor->get_text_edit()->set_line(color_line, new_line);
|
||||
code_editor->get_text_edit()->set_line(color_position.x, line_with_replaced_args);
|
||||
code_editor->get_text_edit()->update();
|
||||
}
|
||||
|
||||
void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition) {
|
||||
|
@ -1465,6 +1472,7 @@ ScriptTextEditor::ScriptTextEditor() {
|
|||
color_panel = memnew(PopupPanel);
|
||||
add_child(color_panel);
|
||||
color_picker = memnew(ColorPicker);
|
||||
color_picker->set_deferred_mode(true);
|
||||
color_panel->add_child(color_picker);
|
||||
color_picker->connect("color_changed", this, "_color_changed");
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ class ScriptTextEditor : public ScriptEditorBase {
|
|||
|
||||
PopupPanel *color_panel;
|
||||
ColorPicker *color_picker;
|
||||
int color_line;
|
||||
Vector2 color_position;
|
||||
String color_args;
|
||||
|
||||
void _update_member_keywords();
|
||||
|
|
|
@ -102,7 +102,7 @@ void ShaderTextEditor::_load_theme_settings() {
|
|||
get_text_edit()->add_color_override("line_number_color", line_number_color);
|
||||
get_text_edit()->add_color_override("caret_color", caret_color);
|
||||
get_text_edit()->add_color_override("caret_background_color", caret_background_color);
|
||||
get_text_edit()->add_color_override("font_selected_color", text_selected_color);
|
||||
get_text_edit()->add_color_override("font_color_selected", text_selected_color);
|
||||
get_text_edit()->add_color_override("selection_color", selection_color);
|
||||
get_text_edit()->add_color_override("brace_mismatch_color", brace_mismatch_color);
|
||||
get_text_edit()->add_color_override("current_line_color", current_line_color);
|
||||
|
@ -346,6 +346,9 @@ void ShaderEditor::_menu_option(int p_option) {
|
|||
|
||||
goto_line_dialog->popup_find_line(shader_editor->get_text_edit());
|
||||
} break;
|
||||
case HELP_DOCS: {
|
||||
OS::get_singleton()->shell_open("https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/index.html");
|
||||
} break;
|
||||
}
|
||||
if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) {
|
||||
shader_editor->get_text_edit()->call_deferred("grab_focus");
|
||||
|
@ -577,10 +580,17 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
|
|||
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
|
||||
search_menu->get_popup()->connect("id_pressed", this, "_menu_option");
|
||||
|
||||
help_menu = memnew(MenuButton);
|
||||
help_menu->set_text(TTR("Help"));
|
||||
help_menu->set_switch_on_hover(true);
|
||||
help_menu->get_popup()->add_icon_item(p_node->get_gui_base()->get_icon("Instance", "EditorIcons"), TTR("Online Docs"), HELP_DOCS);
|
||||
help_menu->get_popup()->connect("id_pressed", this, "_menu_option");
|
||||
|
||||
add_child(main_container);
|
||||
main_container->add_child(hbc);
|
||||
hbc->add_child(search_menu);
|
||||
hbc->add_child(edit_menu);
|
||||
hbc->add_child(help_menu);
|
||||
hbc->add_style_override("panel", p_node->get_gui_base()->get_stylebox("ScriptEditorPanel", "EditorStyles"));
|
||||
main_container->add_child(shader_editor);
|
||||
|
||||
|
|
|
@ -88,12 +88,12 @@ class ShaderEditor : public PanelContainer {
|
|||
SEARCH_FIND_PREV,
|
||||
SEARCH_REPLACE,
|
||||
SEARCH_GOTO_LINE,
|
||||
|
||||
HELP_DOCS,
|
||||
};
|
||||
|
||||
MenuButton *edit_menu;
|
||||
MenuButton *search_menu;
|
||||
MenuButton *settings_menu;
|
||||
MenuButton *help_menu;
|
||||
PopupMenu *context_menu;
|
||||
uint64_t idle;
|
||||
|
||||
|
|
|
@ -5323,6 +5323,7 @@ void SpatialEditor::_register_all_gizmos() {
|
|||
add_gizmo_plugin(Ref<VehicleWheelSpatialGizmoPlugin>(memnew(VehicleWheelSpatialGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<VisibilityNotifierGizmoPlugin>(memnew(VisibilityNotifierGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<ParticlesGizmoPlugin>(memnew(ParticlesGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<CPUParticlesGizmoPlugin>(memnew(CPUParticlesGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin)));
|
||||
add_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin)));
|
||||
|
|
|
@ -115,7 +115,7 @@ void TextEditor::_load_theme_settings() {
|
|||
text_edit->add_color_override("line_number_color", line_number_color);
|
||||
text_edit->add_color_override("caret_color", caret_color);
|
||||
text_edit->add_color_override("caret_background_color", caret_background_color);
|
||||
text_edit->add_color_override("font_selected_color", text_selected_color);
|
||||
text_edit->add_color_override("font_color_selected", text_selected_color);
|
||||
text_edit->add_color_override("selection_color", selection_color);
|
||||
text_edit->add_color_override("brace_mismatch_color", brace_mismatch_color);
|
||||
text_edit->add_color_override("current_line_color", current_line_color);
|
||||
|
|
|
@ -878,11 +878,9 @@ ThemeEditor::ThemeEditor() {
|
|||
void ThemeEditorPlugin::edit(Object *p_node) {
|
||||
|
||||
if (Object::cast_to<Theme>(p_node)) {
|
||||
theme_editor->show();
|
||||
theme_editor->edit(Object::cast_to<Theme>(p_node));
|
||||
} else {
|
||||
theme_editor->edit(Ref<Theme>());
|
||||
theme_editor->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -897,11 +895,11 @@ void ThemeEditorPlugin::make_visible(bool p_visible) {
|
|||
theme_editor->set_process(true);
|
||||
button->show();
|
||||
editor->make_bottom_panel_item_visible(theme_editor);
|
||||
|
||||
} else {
|
||||
theme_editor->set_process(false);
|
||||
if (theme_editor->is_visible_in_tree())
|
||||
editor->hide_bottom_panel();
|
||||
|
||||
button->hide();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,6 +363,8 @@ void TileMapEditor::_update_palette() {
|
|||
|
||||
// Update the palette
|
||||
Vector<int> selected = get_selected_tiles();
|
||||
int selected_single = palette->get_current();
|
||||
int selected_manual = manual_palette->get_current();
|
||||
palette->clear();
|
||||
manual_palette->clear();
|
||||
manual_palette->hide();
|
||||
|
@ -470,7 +472,7 @@ void TileMapEditor::_update_palette() {
|
|||
if (selected.get(0) != TileMap::INVALID_CELL) {
|
||||
set_selected_tiles(selected);
|
||||
sel_tile = selected.get(Math::rand() % selected.size());
|
||||
} else {
|
||||
} else if (palette->get_item_count() > 0) {
|
||||
palette->select(0);
|
||||
}
|
||||
|
||||
|
@ -511,9 +513,10 @@ void TileMapEditor::_update_palette() {
|
|||
|
||||
if (manual_palette->get_item_count() > 0) {
|
||||
// Only show the manual palette if at least tile exists in it
|
||||
int selected2 = manual_palette->get_current();
|
||||
if (selected2 == -1) selected2 = 0;
|
||||
manual_palette->set_current(selected2);
|
||||
if (selected_manual == -1 || selected_single != palette->get_current())
|
||||
selected_manual = 0;
|
||||
if (selected_manual < manual_palette->get_item_count())
|
||||
manual_palette->set_current(selected_manual);
|
||||
manual_palette->show();
|
||||
}
|
||||
|
||||
|
@ -1434,9 +1437,9 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
|||
aabb.expand_to(node->world_to_map(xform_inv.xform(screen_size)));
|
||||
Rect2i si = aabb.grow(1.0);
|
||||
|
||||
if (node->get_half_offset() != TileMap::HALF_OFFSET_X) {
|
||||
if (node->get_half_offset() != TileMap::HALF_OFFSET_X && node->get_half_offset() != TileMap::HALF_OFFSET_NEGATIVE_X) {
|
||||
|
||||
int max_lines = 2000; //avoid crash if size too smal
|
||||
int max_lines = 2000; //avoid crash if size too small
|
||||
|
||||
for (int i = (si.position.x) - 1; i <= (si.position.x + si.size.x); i++) {
|
||||
|
||||
|
@ -1450,7 +1453,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
|||
}
|
||||
} else {
|
||||
|
||||
int max_lines = 10000; //avoid crash if size too smal
|
||||
int max_lines = 10000; //avoid crash if size too small
|
||||
|
||||
for (int i = (si.position.x) - 1; i <= (si.position.x + si.size.x); i++) {
|
||||
|
||||
|
@ -1458,7 +1461,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
|||
|
||||
Vector2 ofs;
|
||||
if (ABS(j) & 1) {
|
||||
ofs = cell_xf[0] * 0.5;
|
||||
ofs = cell_xf[0] * (node->get_half_offset() == TileMap::HALF_OFFSET_X ? 0.5 : -0.5);
|
||||
}
|
||||
|
||||
Vector2 from = xform.xform(node->map_to_world(Vector2(i, j), true) + ofs);
|
||||
|
@ -1477,7 +1480,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
|||
|
||||
int max_lines = 10000; //avoid crash if size too smal
|
||||
|
||||
if (node->get_half_offset() != TileMap::HALF_OFFSET_Y) {
|
||||
if (node->get_half_offset() != TileMap::HALF_OFFSET_Y && node->get_half_offset() != TileMap::HALF_OFFSET_NEGATIVE_Y) {
|
||||
|
||||
for (int i = (si.position.y) - 1; i <= (si.position.y + si.size.y); i++) {
|
||||
|
||||
|
@ -1498,7 +1501,7 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
|||
|
||||
Vector2 ofs;
|
||||
if (ABS(j) & 1) {
|
||||
ofs = cell_xf[1] * 0.5;
|
||||
ofs = cell_xf[1] * (node->get_half_offset() == TileMap::HALF_OFFSET_Y ? 0.5 : -0.5);
|
||||
}
|
||||
|
||||
Vector2 from = xform.xform(node->map_to_world(Vector2(j, i), true) + ofs);
|
||||
|
@ -1539,8 +1542,12 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
|||
for (int i = 0; i < 4; i++) {
|
||||
if (node->get_half_offset() == TileMap::HALF_OFFSET_X && ABS(over_tile.y) & 1)
|
||||
endpoints[i] += cell_xf[0] * 0.5;
|
||||
if (node->get_half_offset() == TileMap::HALF_OFFSET_NEGATIVE_X && ABS(over_tile.y) & 1)
|
||||
endpoints[i] += cell_xf[0] * -0.5;
|
||||
if (node->get_half_offset() == TileMap::HALF_OFFSET_Y && ABS(over_tile.x) & 1)
|
||||
endpoints[i] += cell_xf[1] * 0.5;
|
||||
if (node->get_half_offset() == TileMap::HALF_OFFSET_NEGATIVE_Y && ABS(over_tile.x) & 1)
|
||||
endpoints[i] += cell_xf[1] * -0.5;
|
||||
endpoints[i] = xform.xform(endpoints[i]);
|
||||
}
|
||||
Color col;
|
||||
|
|
|
@ -1609,40 +1609,28 @@ void ProjectManager::_show_project(const String &p_path) {
|
|||
OS::get_singleton()->shell_open(String("file://") + p_path);
|
||||
}
|
||||
|
||||
void ProjectManager::_scan_dir(DirAccess *da, float pos, float total, List<String> *r_projects) {
|
||||
|
||||
List<String> subdirs;
|
||||
void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) {
|
||||
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
da->change_dir(path);
|
||||
da->list_dir_begin();
|
||||
String n = da->get_next();
|
||||
while (n != String()) {
|
||||
if (da->current_is_dir() && !n.begins_with(".")) {
|
||||
subdirs.push_front(n);
|
||||
_scan_dir(da->get_current_dir().plus_file(n), r_projects);
|
||||
} else if (n == "project.godot") {
|
||||
r_projects->push_back(da->get_current_dir());
|
||||
}
|
||||
n = da->get_next();
|
||||
}
|
||||
da->list_dir_end();
|
||||
int m = 0;
|
||||
for (List<String>::Element *E = subdirs.front(); E; E = E->next()) {
|
||||
|
||||
da->change_dir(E->get());
|
||||
|
||||
float slice = total / subdirs.size();
|
||||
_scan_dir(da, pos + slice * m, slice, r_projects);
|
||||
da->change_dir("..");
|
||||
m++;
|
||||
}
|
||||
memdelete(da);
|
||||
}
|
||||
|
||||
void ProjectManager::_scan_begin(const String &p_base) {
|
||||
|
||||
print_line("Scanning projects at: " + p_base);
|
||||
List<String> projects;
|
||||
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
da->change_dir(p_base);
|
||||
_scan_dir(da, 0, 1, &projects);
|
||||
memdelete(da);
|
||||
_scan_dir(p_base, &projects);
|
||||
print_line("Found " + itos(projects.size()) + " projects.");
|
||||
|
||||
for (List<String>::Element *E = projects.front(); E; E = E->next()) {
|
||||
|
|
|
@ -102,7 +102,7 @@ class ProjectManager : public Control {
|
|||
void _on_project_created(const String &dir);
|
||||
void _on_projects_updated();
|
||||
void _update_scroll_position(const String &dir);
|
||||
void _scan_dir(DirAccess *da, float pos, float total, List<String> *r_projects);
|
||||
void _scan_dir(const String &path, List<String> *r_projects);
|
||||
|
||||
void _install_project(const String &p_zip_path, const String &p_title);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "scene/3d/baked_lightmap.h"
|
||||
#include "scene/3d/collision_polygon.h"
|
||||
#include "scene/3d/collision_shape.h"
|
||||
#include "scene/3d/cpu_particles.h"
|
||||
#include "scene/3d/gi_probe.h"
|
||||
#include "scene/3d/light.h"
|
||||
#include "scene/3d/listener.h"
|
||||
|
@ -571,9 +572,11 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point,
|
|||
|
||||
Transform orig_camera_transform = p_camera->get_camera_transform();
|
||||
|
||||
if (orig_camera_transform.origin.distance_squared_to(t.origin) > 0.01) {
|
||||
if (orig_camera_transform.origin.distance_squared_to(t.origin) > 0.01 &&
|
||||
ABS(orig_camera_transform.basis.get_axis(Vector3::AXIS_Z).dot(Vector3(0, 1, 0))) < 0.99) {
|
||||
p_camera->look_at(t.origin, Vector3(0, 1, 0));
|
||||
}
|
||||
|
||||
Vector3 c0 = t.xform(Vector3(selectable_icon_size, selectable_icon_size, 0) * scale);
|
||||
Vector3 c1 = t.xform(Vector3(-selectable_icon_size, -selectable_icon_size, 0) * scale);
|
||||
|
||||
|
@ -582,7 +585,7 @@ bool EditorSpatialGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point,
|
|||
|
||||
p_camera->set_global_transform(orig_camera_transform);
|
||||
|
||||
Rect2 rect(p0, p1 - p0);
|
||||
Rect2 rect(p0, (p1 - p0).abs());
|
||||
|
||||
rect.set_position(center - rect.get_size() / 2.0);
|
||||
|
||||
|
@ -2373,6 +2376,33 @@ void VisibilityNotifierGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
|
|||
|
||||
////
|
||||
|
||||
CPUParticlesGizmoPlugin::CPUParticlesGizmoPlugin() {
|
||||
create_icon_material("particles_icon", SpatialEditor::get_singleton()->get_icon("GizmoCPUParticles", "EditorIcons"));
|
||||
}
|
||||
|
||||
bool CPUParticlesGizmoPlugin::has_gizmo(Spatial *p_spatial) {
|
||||
return Object::cast_to<CPUParticles>(p_spatial) != NULL;
|
||||
}
|
||||
|
||||
String CPUParticlesGizmoPlugin::get_name() const {
|
||||
return "CPUParticles";
|
||||
}
|
||||
|
||||
int CPUParticlesGizmoPlugin::get_priority() const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CPUParticlesGizmoPlugin::is_selectable_when_hidden() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPUParticlesGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
|
||||
Ref<Material> icon = get_material("particles_icon", p_gizmo);
|
||||
p_gizmo->add_unscaled_billboard(icon, 0.05);
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
ParticlesGizmoPlugin::ParticlesGizmoPlugin() {
|
||||
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particles", Color(0.8, 0.7, 0.4));
|
||||
create_material("particles_material", gizmo_color);
|
||||
|
|
|
@ -249,6 +249,18 @@ public:
|
|||
VisibilityNotifierGizmoPlugin();
|
||||
};
|
||||
|
||||
class CPUParticlesGizmoPlugin : public EditorSpatialGizmoPlugin {
|
||||
GDCLASS(CPUParticlesGizmoPlugin, EditorSpatialGizmoPlugin);
|
||||
|
||||
public:
|
||||
bool has_gizmo(Spatial *p_spatial);
|
||||
String get_name() const;
|
||||
int get_priority() const;
|
||||
bool is_selectable_when_hidden() const;
|
||||
void redraw(EditorSpatialGizmo *p_gizmo);
|
||||
CPUParticlesGizmoPlugin();
|
||||
};
|
||||
|
||||
class ParticlesGizmoPlugin : public EditorSpatialGizmoPlugin {
|
||||
|
||||
GDCLASS(ParticlesGizmoPlugin, EditorSpatialGizmoPlugin);
|
||||
|
|
|
@ -627,7 +627,8 @@ bool InputDefault::is_emulating_mouse_from_touch() const {
|
|||
return emulate_mouse_from_touch;
|
||||
}
|
||||
|
||||
Input::CursorShape InputDefault::get_default_cursor_shape() {
|
||||
Input::CursorShape InputDefault::get_default_cursor_shape() const {
|
||||
|
||||
return default_shape;
|
||||
}
|
||||
|
||||
|
@ -646,6 +647,11 @@ void InputDefault::set_default_cursor_shape(CursorShape p_shape) {
|
|||
parse_input_event(mm);
|
||||
}
|
||||
|
||||
Input::CursorShape InputDefault::get_current_cursor_shape() const {
|
||||
|
||||
return (Input::CursorShape)OS::get_singleton()->get_cursor_shape();
|
||||
}
|
||||
|
||||
void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
return;
|
||||
|
@ -653,21 +659,6 @@ void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_sh
|
|||
OS::get_singleton()->set_custom_mouse_cursor(p_cursor, (OS::CursorShape)p_shape, p_hotspot);
|
||||
}
|
||||
|
||||
void InputDefault::set_mouse_in_window(bool p_in_window) {
|
||||
/* no longer supported, leaving this for reference to anyone who might want to implement hardware cursors
|
||||
if (custom_cursor.is_valid()) {
|
||||
|
||||
if (p_in_window) {
|
||||
set_mouse_mode(MOUSE_MODE_HIDDEN);
|
||||
VisualServer::get_singleton()->cursor_set_visible(true);
|
||||
} else {
|
||||
set_mouse_mode(MOUSE_MODE_VISIBLE);
|
||||
VisualServer::get_singleton()->cursor_set_visible(false);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void InputDefault::accumulate_input_event(const Ref<InputEvent> &p_event) {
|
||||
ERR_FAIL_COND(p_event.is_null());
|
||||
|
||||
|
|
|
@ -243,10 +243,10 @@ public:
|
|||
void set_emulate_mouse_from_touch(bool p_emulate);
|
||||
virtual bool is_emulating_mouse_from_touch() const;
|
||||
|
||||
virtual CursorShape get_default_cursor_shape();
|
||||
virtual CursorShape get_default_cursor_shape() const;
|
||||
virtual void set_default_cursor_shape(CursorShape p_shape);
|
||||
virtual CursorShape get_current_cursor_shape() const;
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
|
||||
virtual void set_mouse_in_window(bool p_in_window);
|
||||
|
||||
void parse_mapping(String p_mapping);
|
||||
void joy_button(int p_device, int p_button, bool p_pressed);
|
||||
|
|
|
@ -204,7 +204,8 @@ void finalize_physics() {
|
|||
|
||||
void Main::print_help(const char *p_binary) {
|
||||
|
||||
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - https://godotengine.org");
|
||||
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
|
||||
OS::get_singleton()->print("Free and open source software under the terms of the MIT license.\n");
|
||||
OS::get_singleton()->print("(c) 2007-2019 Juan Linietsky, Ariel Manzur.\n");
|
||||
OS::get_singleton()->print("(c) 2014-2019 Godot Engine contributors.\n");
|
||||
OS::get_singleton()->print("\n");
|
||||
|
@ -1087,6 +1088,9 @@ error:
|
|||
|
||||
Error Main::setup2(Thread::ID p_main_tid_override) {
|
||||
|
||||
// Print engine name and version
|
||||
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
|
||||
|
||||
if (p_main_tid_override) {
|
||||
Thread::_main_thread_id = p_main_tid_override;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ def update_version(module_version_string=""):
|
|||
f.write("#define VERSION_BUILD \"" + str(build_name) + "\"\n")
|
||||
f.write("#define VERSION_MODULE_CONFIG \"" + str(version.module_config) + module_version_string + "\"\n")
|
||||
f.write("#define VERSION_YEAR " + str(version.year) + "\n")
|
||||
f.write("#define VERSION_WEBSITE \"" + str(version.website) + "\"\n")
|
||||
f.close()
|
||||
|
||||
# NOTE: It is safe to generate this file here, since this is still executed serially
|
||||
|
|
|
@ -162,8 +162,13 @@ $GODOT_HEAD_INCLUDE
|
|||
requestAnimationFrame(animate);
|
||||
|
||||
function adjustCanvasDimensions() {
|
||||
canvas.width = innerWidth;
|
||||
canvas.height = innerHeight;
|
||||
var scale = window.devicePixelRatio || 1;
|
||||
var width = window.innerWidth;
|
||||
var height = window.innerHeight;
|
||||
canvas.width = width * scale;
|
||||
canvas.height = height * scale;
|
||||
canvas.style.width = width + "px";
|
||||
canvas.style.height = height + "px";
|
||||
}
|
||||
animationCallbacks.push(adjustCanvasDimensions);
|
||||
adjustCanvasDimensions();
|
||||
|
|
|
@ -2060,6 +2060,9 @@ CSGBrush *CSGPolygon::_build_brush() {
|
|||
for (int i = 0; i <= splits; i++) {
|
||||
|
||||
float ofs = i * path_interval;
|
||||
if (ofs > bl) {
|
||||
ofs = bl;
|
||||
}
|
||||
if (i == splits && path_joined) {
|
||||
ofs = 0.0;
|
||||
}
|
||||
|
|
|
@ -243,7 +243,7 @@ void GDNativeLibrary::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_symbol_prefix", "symbol_prefix"), &GDNativeLibrary::set_symbol_prefix);
|
||||
ClassDB::bind_method(D_METHOD("set_reloadable", "reloadable"), &GDNativeLibrary::set_reloadable);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "config_file", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile"), "set_config_file", "get_config_file");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "config_file", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile", 0), "set_config_file", "get_config_file");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "load_once"), "set_load_once", "should_load_once");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "singleton"), "set_singleton", "is_singleton");
|
||||
|
|
|
@ -99,16 +99,20 @@ public:
|
|||
}
|
||||
|
||||
_FORCE_INLINE_ void set_load_once(bool p_load_once) {
|
||||
config_file->set_value("general", "load_once", p_load_once);
|
||||
load_once = p_load_once;
|
||||
}
|
||||
_FORCE_INLINE_ void set_singleton(bool p_singleton) {
|
||||
config_file->set_value("general", "singleton", p_singleton);
|
||||
singleton = p_singleton;
|
||||
}
|
||||
_FORCE_INLINE_ void set_symbol_prefix(String p_symbol_prefix) {
|
||||
config_file->set_value("general", "symbol_prefix", p_symbol_prefix);
|
||||
symbol_prefix = p_symbol_prefix;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void set_reloadable(bool p_reloadable) {
|
||||
config_file->set_value("general", "reloadable", p_reloadable);
|
||||
reloadable = p_reloadable;
|
||||
}
|
||||
|
||||
|
|
|
@ -518,7 +518,7 @@ void GDAPI godot_variant_evaluate(godot_variant_operator p_op, const godot_varia
|
|||
const Variant *a = (const Variant *)p_a;
|
||||
const Variant *b = (const Variant *)p_b;
|
||||
Variant *ret = (Variant *)r_ret;
|
||||
Variant::evaluate(op, a, b, *ret, *r_valid);
|
||||
Variant::evaluate(op, *a, *b, *ret, *r_valid);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1309,7 +1309,7 @@ void NativeScriptLanguage::unregister_binding_functions(int p_idx) {
|
|||
for (Set<Vector<void *> *>::Element *E = binding_instances.front(); E; E = E->next()) {
|
||||
Vector<void *> &binding_data = *E->get();
|
||||
|
||||
if (binding_data[p_idx] && binding_functions[p_idx].second.free_instance_binding_data)
|
||||
if (p_idx < binding_data.size() && binding_data[p_idx] && binding_functions[p_idx].second.free_instance_binding_data)
|
||||
binding_functions[p_idx].second.free_instance_binding_data(binding_functions[p_idx].second.data, binding_data[p_idx]);
|
||||
}
|
||||
|
||||
|
@ -1345,7 +1345,7 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec
|
|||
|
||||
if (!(*binding_data)[p_idx]) {
|
||||
|
||||
const void *global_type_tag = global_type_tags[p_idx].get(p_object->get_class_name());
|
||||
const void *global_type_tag = get_global_type_tag(p_idx, p_object->get_class_name());
|
||||
|
||||
// no binding data yet, soooooo alloc new one \o/
|
||||
(*binding_data).write[p_idx] = binding_functions[p_idx].second.alloc_instance_binding_data(binding_functions[p_idx].second.data, global_type_tag, (godot_object *)p_object);
|
||||
|
@ -1454,6 +1454,9 @@ const void *NativeScriptLanguage::get_global_type_tag(int p_idx, StringName p_cl
|
|||
|
||||
const HashMap<StringName, const void *> &tags = global_type_tags[p_idx];
|
||||
|
||||
if (!tags.has(p_class_name))
|
||||
return NULL;
|
||||
|
||||
const void *tag = tags.get(p_class_name);
|
||||
|
||||
return tag;
|
||||
|
|
|
@ -1945,6 +1945,10 @@ String GDScriptWarning::get_message() const {
|
|||
CHECK_SYMBOLS(1);
|
||||
return "The local variable '" + symbols[0] + "' is declared but never used in the block.";
|
||||
} break;
|
||||
case SHADOWED_VARIABLE: {
|
||||
CHECK_SYMBOLS(2);
|
||||
return "The local variable '" + symbols[0] + "' is shadowing an already defined variable at line " + symbols[1] + ".";
|
||||
} break;
|
||||
case UNUSED_CLASS_VARIABLE: {
|
||||
CHECK_SYMBOLS(1);
|
||||
return "The class variable '" + symbols[0] + "' is declared but never used in the script.";
|
||||
|
@ -2048,6 +2052,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) {
|
|||
"UNASSIGNED_VARIABLE",
|
||||
"UNASSIGNED_VARIABLE_OP_ASSIGN",
|
||||
"UNUSED_VARIABLE",
|
||||
"SHADOWED_VARIABLE",
|
||||
"UNUSED_CLASS_VARIABLE",
|
||||
"UNUSED_ARGUMENT",
|
||||
"UNREACHABLE_CODE",
|
||||
|
@ -2129,6 +2134,7 @@ GDScriptLanguage::GDScriptLanguage() {
|
|||
#ifdef DEBUG_ENABLED
|
||||
GLOBAL_DEF("debug/gdscript/warnings/enable", true);
|
||||
GLOBAL_DEF("debug/gdscript/warnings/treat_warnings_as_errors", false);
|
||||
GLOBAL_DEF("debug/gdscript/warnings/exclude_addons", true);
|
||||
GLOBAL_DEF("debug/gdscript/completion/autocomplete_setters_and_getters", false);
|
||||
for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
|
||||
String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower();
|
||||
|
|
|
@ -273,6 +273,7 @@ struct GDScriptWarning {
|
|||
UNASSIGNED_VARIABLE, // Variable used but never assigned
|
||||
UNASSIGNED_VARIABLE_OP_ASSIGN, // Variable never assigned but used in an assignment operation (+=, *=, etc)
|
||||
UNUSED_VARIABLE, // Local variable is declared but never used
|
||||
SHADOWED_VARIABLE, // Variable name shadowed by other variable
|
||||
UNUSED_CLASS_VARIABLE, // Class variable is declared but never used in the file
|
||||
UNUSED_ARGUMENT, // Function argument is never used
|
||||
UNREACHABLE_CODE, // Code after a return statement
|
||||
|
|
|
@ -133,35 +133,13 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
|
|||
return NULL;
|
||||
}
|
||||
|
||||
String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const {
|
||||
|
||||
String err_text;
|
||||
|
||||
if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
|
||||
int errorarg = p_err.argument;
|
||||
err_text = "Invalid type in " + p_where + ". Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(p_err.expected) + ".";
|
||||
} else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
|
||||
err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments.";
|
||||
} else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
|
||||
err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments.";
|
||||
} else if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
|
||||
err_text = "Invalid call. Nonexistent " + p_where + ".";
|
||||
} else if (p_err.error == Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
|
||||
err_text = "Attempt to call " + p_where + " on a null instance.";
|
||||
} else {
|
||||
err_text = "Bug, call error: #" + itos(p_err.error);
|
||||
}
|
||||
|
||||
return err_text;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
static String _get_var_type(const Variant *p_type) {
|
||||
static String _get_var_type(const Variant *p_var) {
|
||||
|
||||
String basestr;
|
||||
|
||||
if (p_type->get_type() == Variant::OBJECT) {
|
||||
Object *bobj = *p_type;
|
||||
if (p_var->get_type() == Variant::OBJECT) {
|
||||
Object *bobj = *p_var;
|
||||
if (!bobj) {
|
||||
basestr = "null instance";
|
||||
} else {
|
||||
|
@ -176,12 +154,42 @@ static String _get_var_type(const Variant *p_type) {
|
|||
}
|
||||
|
||||
} else {
|
||||
basestr = Variant::get_type_name(p_type->get_type());
|
||||
basestr = Variant::get_type_name(p_var->get_type());
|
||||
}
|
||||
|
||||
return basestr;
|
||||
}
|
||||
#endif
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const {
|
||||
|
||||
String err_text;
|
||||
|
||||
if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
|
||||
int errorarg = p_err.argument;
|
||||
// Handle the Object to Object case separately as we don't have further class details.
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (p_err.expected == Variant::OBJECT && argptrs[errorarg]->get_type() == p_err.expected) {
|
||||
err_text = "Invalid type in " + p_where + ". The Object-derived class of argument " + itos(errorarg + 1) + " (" + _get_var_type(argptrs[errorarg]) + ") is not a subclass of the expected argument class.";
|
||||
} else
|
||||
#endif // DEBUG_ENABLED
|
||||
{
|
||||
err_text = "Invalid type in " + p_where + ". Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(p_err.expected) + ".";
|
||||
}
|
||||
} else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
|
||||
err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments.";
|
||||
} else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
|
||||
err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments.";
|
||||
} else if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
|
||||
err_text = "Invalid call. Nonexistent " + p_where + ".";
|
||||
} else if (p_err.error == Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
|
||||
err_text = "Attempt to call " + p_where + " on a null instance.";
|
||||
} else {
|
||||
err_text = "Bug, call error: #" + itos(p_err.error);
|
||||
}
|
||||
|
||||
return err_text;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define OPCODES_TABLE \
|
||||
|
|
|
@ -5238,6 +5238,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) {
|
|||
if (base_script.is_valid()) {
|
||||
|
||||
String ident = base;
|
||||
Ref<GDScript> find_subclass = base_script;
|
||||
|
||||
for (int i = extend_iter; i < p_class->extends_class.size(); i++) {
|
||||
|
||||
|
@ -5247,7 +5248,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) {
|
|||
|
||||
if (base_script->get_subclasses().has(subclass)) {
|
||||
|
||||
base_script = base_script->get_subclasses()[subclass];
|
||||
find_subclass = base_script->get_subclasses()[subclass];
|
||||
} else if (base_script->get_constants().has(subclass)) {
|
||||
|
||||
Ref<GDScript> new_base_class = base_script->get_constants()[subclass];
|
||||
|
@ -5255,7 +5256,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) {
|
|||
_set_error("Constant is not a class: " + ident, p_class->line);
|
||||
return;
|
||||
}
|
||||
base_script = new_base_class;
|
||||
find_subclass = new_base_class;
|
||||
} else {
|
||||
|
||||
_set_error("Could not find subclass: " + ident, p_class->line);
|
||||
|
@ -5263,7 +5264,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) {
|
|||
}
|
||||
}
|
||||
|
||||
script = base_script;
|
||||
script = find_subclass;
|
||||
|
||||
} else if (!base_class) {
|
||||
|
||||
|
@ -7661,6 +7662,11 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) {
|
|||
if (p_function->arguments_usage[i] == 0 && !p_function->arguments[i].operator String().begins_with("_")) {
|
||||
_add_warning(GDScriptWarning::UNUSED_ARGUMENT, p_function->line, p_function->name, p_function->arguments[i].operator String());
|
||||
}
|
||||
for (int j = 0; j < current_class->variables.size(); j++) {
|
||||
if (current_class->variables[j].identifier == p_function->arguments[i]) {
|
||||
_add_warning(GDScriptWarning::SHADOWED_VARIABLE, p_function->line, p_function->arguments[i], itos(current_class->variables[j].line));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
|
@ -7734,6 +7740,17 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) {
|
|||
p_function->return_type.has_type = false;
|
||||
p_function->return_type.may_yield = true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
for (Map<StringName, LocalVarNode *>::Element *E = p_function->body->variables.front(); E; E = E->next()) {
|
||||
LocalVarNode *lv = E->get();
|
||||
for (int i = 0; i < current_class->variables.size(); i++) {
|
||||
if (current_class->variables[i].identifier == lv->name) {
|
||||
_add_warning(GDScriptWarning::SHADOWED_VARIABLE, lv->line, lv->name, itos(current_class->variables[i].line));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) {
|
||||
|
@ -8163,6 +8180,9 @@ void GDScriptParser::_add_warning(int p_code, int p_line, const String &p_symbol
|
|||
}
|
||||
|
||||
void GDScriptParser::_add_warning(int p_code, int p_line, const Vector<String> &p_symbols) {
|
||||
if (GLOBAL_GET("debug/gdscript/warnings/exclude_addons").booleanize() && base_path.begins_with("res://addons/")) {
|
||||
return;
|
||||
}
|
||||
if (tokenizer->is_ignoring_warnings() || !GLOBAL_GET("debug/gdscript/warnings/enable").booleanize()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -120,8 +120,8 @@ def configure(env):
|
|||
else:
|
||||
env.Append(LINKFLAGS=os.path.join(mono_lib_path, mono_static_lib_name + lib_suffix))
|
||||
|
||||
env.Append(LIBS='psapi')
|
||||
env.Append(LIBS='version')
|
||||
env.Append(LIBS=['psapi'])
|
||||
env.Append(LIBS=['version'])
|
||||
else:
|
||||
mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib')
|
||||
|
||||
|
@ -131,7 +131,7 @@ def configure(env):
|
|||
if env.msvc:
|
||||
env.Append(LINKFLAGS=mono_lib_name + Environment()['LIBSUFFIX'])
|
||||
else:
|
||||
env.Append(LIBS=mono_lib_name)
|
||||
env.Append(LIBS=[mono_lib_name])
|
||||
|
||||
mono_bin_path = os.path.join(mono_root, 'bin')
|
||||
|
||||
|
|
|
@ -919,7 +919,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
|||
}
|
||||
#endif
|
||||
|
||||
void CSharpLanguage::project_assembly_loaded() {
|
||||
void CSharpLanguage::_load_scripts_metadata() {
|
||||
|
||||
scripts_metadata.clear();
|
||||
|
||||
|
@ -953,6 +953,7 @@ void CSharpLanguage::project_assembly_loaded() {
|
|||
}
|
||||
|
||||
scripts_metadata = old_dict_var.operator Dictionary();
|
||||
scripts_metadata_invalidated = false;
|
||||
|
||||
print_verbose("Successfully loaded scripts metadata");
|
||||
} else {
|
||||
|
@ -1024,11 +1025,13 @@ bool CSharpLanguage::debug_break(const String &p_error, bool p_allow_continue) {
|
|||
}
|
||||
}
|
||||
|
||||
void CSharpLanguage::_uninitialize_script_bindings() {
|
||||
void CSharpLanguage::_on_scripts_domain_unloaded() {
|
||||
for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) {
|
||||
CSharpScriptBinding &script_binding = E->value();
|
||||
script_binding.inited = false;
|
||||
}
|
||||
|
||||
scripts_metadata_invalidated = true;
|
||||
}
|
||||
|
||||
void CSharpLanguage::set_language_index(int p_idx) {
|
||||
|
@ -1086,6 +1089,8 @@ CSharpLanguage::CSharpLanguage() {
|
|||
#endif
|
||||
|
||||
lang_idx = -1;
|
||||
|
||||
scripts_metadata_invalidated = true;
|
||||
}
|
||||
|
||||
CSharpLanguage::~CSharpLanguage() {
|
||||
|
|
|
@ -309,14 +309,17 @@ class CSharpLanguage : public ScriptLanguage {
|
|||
int lang_idx;
|
||||
|
||||
Dictionary scripts_metadata;
|
||||
bool scripts_metadata_invalidated;
|
||||
|
||||
// For debug_break and debug_break_parse
|
||||
int _debug_parse_err_line;
|
||||
String _debug_parse_err_file;
|
||||
String _debug_error;
|
||||
|
||||
void _load_scripts_metadata();
|
||||
|
||||
friend class GDMono;
|
||||
void _uninitialize_script_bindings();
|
||||
void _on_scripts_domain_unloaded();
|
||||
|
||||
public:
|
||||
StringNameCache string_names;
|
||||
|
@ -341,9 +344,15 @@ public:
|
|||
void reload_assemblies(bool p_soft_reload);
|
||||
#endif
|
||||
|
||||
void project_assembly_loaded();
|
||||
_FORCE_INLINE_ Dictionary get_scripts_metadata_or_nothing() {
|
||||
return scripts_metadata_invalidated ? Dictionary() : scripts_metadata;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ const Dictionary &get_scripts_metadata() { return scripts_metadata; }
|
||||
_FORCE_INLINE_ const Dictionary &get_scripts_metadata() {
|
||||
if (scripts_metadata_invalidated)
|
||||
_load_scripts_metadata();
|
||||
return scripts_metadata;
|
||||
}
|
||||
|
||||
virtual String get_name() const;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="@C#" category="Core" version="3.1.1">
|
||||
<class name="@C#" category="Core" version="3.1.2">
|
||||
<brief_description>
|
||||
</brief_description>
|
||||
<description>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="CSharpScript" inherits="Script" category="Core" version="3.1.1">
|
||||
<class name="CSharpScript" inherits="Script" category="Core" version="3.1.2">
|
||||
<brief_description>
|
||||
</brief_description>
|
||||
<description>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="GodotSharp" inherits="Object" category="Core" version="3.1.1">
|
||||
<class name="GodotSharp" inherits="Object" category="Core" version="3.1.2">
|
||||
<brief_description>
|
||||
</brief_description>
|
||||
<description>
|
||||
|
|
|
@ -158,7 +158,7 @@ Error generate_scripts_metadata(const String &p_project_path, const String &p_ou
|
|||
PoolStringArray project_files = GDMonoMarshal::mono_array_to_PoolStringArray(ret);
|
||||
PoolStringArray::Read r = project_files.read();
|
||||
|
||||
Dictionary old_dict = CSharpLanguage::get_singleton()->get_scripts_metadata();
|
||||
Dictionary old_dict = CSharpLanguage::get_singleton()->get_scripts_metadata_or_nothing();
|
||||
Dictionary new_dict;
|
||||
|
||||
for (int i = 0; i < project_files.size(); i++) {
|
||||
|
|
|
@ -121,25 +121,28 @@ void gdmono_debug_init() {
|
|||
|
||||
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
|
||||
|
||||
CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8();
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
int da_port = GLOBAL_DEF("mono/debugger_agent/port", 23685);
|
||||
bool da_suspend = GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false);
|
||||
int da_timeout = GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (Engine::get_singleton()->is_editor_hint() ||
|
||||
ProjectSettings::get_singleton()->get_resource_path().empty() ||
|
||||
Main::is_project_manager()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8();
|
||||
|
||||
if (da_args.length() == 0) {
|
||||
da_args = String("--debugger-agent=transport=dt_socket,address=127.0.0.1:" + itos(da_port) +
|
||||
",embedding=1,server=y,suspend=" + (da_suspend ? "y,timeout=" + itos(da_timeout) : "n"))
|
||||
.utf8();
|
||||
}
|
||||
#else
|
||||
if (da_args.length() == 0)
|
||||
return; // Exported games don't use the project settings to setup the debugger agent
|
||||
#endif
|
||||
|
||||
// --debugger-agent=help
|
||||
const char *options[] = {
|
||||
|
@ -665,8 +668,6 @@ bool GDMono::_load_project_assembly() {
|
|||
|
||||
if (success) {
|
||||
mono_assembly_set_main(project_assembly->get_assembly());
|
||||
|
||||
CSharpLanguage::get_singleton()->project_assembly_loaded();
|
||||
} else {
|
||||
if (OS::get_singleton()->is_stdout_verbose())
|
||||
print_error("Mono: Failed to load project assembly");
|
||||
|
@ -873,7 +874,7 @@ Error GDMono::reload_scripts_domain() {
|
|||
}
|
||||
}
|
||||
|
||||
CSharpLanguage::get_singleton()->_uninitialize_script_bindings();
|
||||
CSharpLanguage::get_singleton()->_on_scripts_domain_unloaded();
|
||||
|
||||
Error err = _load_scripts_domain();
|
||||
if (err != OK) {
|
||||
|
|
|
@ -33,6 +33,7 @@ if env['builtin_pcre2']:
|
|||
"pcre2_newline.c",
|
||||
"pcre2_ord2utf.c",
|
||||
"pcre2_pattern_info.c",
|
||||
"pcre2_script_run.c",
|
||||
"pcre2_serialize.c",
|
||||
"pcre2_string_utils.c",
|
||||
"pcre2_study.c",
|
||||
|
|
|
@ -266,8 +266,8 @@ void AudioStreamOGGVorbis::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamOGGVorbis::get_loop_offset);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_loop", "has_loop");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "loop_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_loop_offset", "get_loop_offset");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "loop_offset"), "set_loop_offset", "get_loop_offset");
|
||||
}
|
||||
|
||||
AudioStreamOGGVorbis::AudioStreamOGGVorbis() {
|
||||
|
|
|
@ -23,10 +23,11 @@ if env['builtin_miniupnpc']:
|
|||
"portlistingparse.c",
|
||||
"upnpreplyparse.c",
|
||||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
thirdparty_sources = [thirdparty_dir + "miniupnpc/" + file for file in thirdparty_sources]
|
||||
|
||||
env_upnp.Append(CPPPATH=[thirdparty_dir])
|
||||
env_upnp.Append(CPPFLAGS=["-DMINIUPNP_STATICLIB"])
|
||||
env_upnp.Append(CPPFLAGS=["-DMINIUPNPC_SET_SOCKET_TIMEOUT"])
|
||||
|
||||
env_thirdparty = env_upnp.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
|
|
|
@ -45,15 +45,7 @@ bool VisualScriptNode::is_breakpoint() const {
|
|||
return breakpoint;
|
||||
}
|
||||
|
||||
void VisualScriptNode::_notification(int p_what) {
|
||||
|
||||
if (p_what == NOTIFICATION_POSTINITIALIZE) {
|
||||
validate_input_default_values();
|
||||
}
|
||||
}
|
||||
|
||||
void VisualScriptNode::ports_changed_notify() {
|
||||
validate_input_default_values();
|
||||
emit_signal("ports_changed");
|
||||
}
|
||||
|
||||
|
@ -272,11 +264,7 @@ void VisualScript::_node_ports_changed(int p_id) {
|
|||
Function &func = functions[function];
|
||||
Ref<VisualScriptNode> vsn = func.nodes[p_id].node;
|
||||
|
||||
if (OS::get_singleton()->get_main_loop() &&
|
||||
Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop()) &&
|
||||
Engine::get_singleton()->is_editor_hint()) {
|
||||
vsn->validate_input_default_values(); //force validate default values when editing on editor
|
||||
}
|
||||
vsn->validate_input_default_values();
|
||||
|
||||
//must revalidate all the functions
|
||||
|
||||
|
@ -352,6 +340,7 @@ void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<Visual
|
|||
Ref<VisualScriptNode> vsn = p_node;
|
||||
vsn->connect("ports_changed", this, "_node_ports_changed", varray(p_id));
|
||||
vsn->scripts_used.insert(this);
|
||||
vsn->validate_input_default_values(); // Validate when fully loaded
|
||||
|
||||
func.nodes[p_id] = nd;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@ class VisualScriptNode : public Resource {
|
|||
void validate_input_default_values();
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
void ports_changed_notify();
|
||||
static void _bind_methods();
|
||||
|
||||
|
|
|
@ -2040,7 +2040,7 @@ void VisualScriptEditor::set_edit_state(const Variant &p_state) {
|
|||
|
||||
Dictionary d = p_state;
|
||||
if (d.has("function")) {
|
||||
edited_func = p_state;
|
||||
edited_func = d["function"];
|
||||
selected = edited_func;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,4 +28,4 @@ with open_utf8('register_platform_apis.gen.cpp', 'w') as f:
|
|||
platform_sources.append('register_platform_apis.gen.cpp')
|
||||
|
||||
lib = env.add_library('platform', platform_sources)
|
||||
env.Prepend(LIBS=lib)
|
||||
env.Prepend(LIBS=[lib])
|
||||
|
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
$$GRADLE_REPOSITORY_URLS$$
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.4.2'
|
||||
$$GRADLE_CLASSPATH$$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Third party libraries
|
||||
# Third-party libraries
|
||||
|
||||
This file list third-party libraries used in the Android source folder,
|
||||
with their provenance and, when relevant, modifications made to those files.
|
||||
|
||||
## Google's vending library
|
||||
|
||||
|
@ -7,12 +9,13 @@
|
|||
- Version: git (eb57657, 2018) with modifications
|
||||
- License: Apache 2.0
|
||||
|
||||
Overwrite all files under `com/google/android/vending`
|
||||
Overwrite all files under `com/google/android/vending`.
|
||||
|
||||
### Modify some files to avoid compile error and lint warning
|
||||
Modify those files to avoid compile error and lint warning:
|
||||
|
||||
#### com/google/android/vending/licensing/util/Base64.java
|
||||
```
|
||||
- `com/google/android/vending/licensing/util/Base64.java`
|
||||
|
||||
```diff
|
||||
@@ -338,7 +338,8 @@ public class Base64 {
|
||||
e += 4;
|
||||
}
|
||||
|
@ -24,8 +27,9 @@ Overwrite all files under `com/google/android/vending`
|
|||
}
|
||||
```
|
||||
|
||||
#### com/google/android/vending/licensing/LicenseChecker.java
|
||||
```
|
||||
- `com/google/android/vending/licensing/LicenseChecker.java`
|
||||
|
||||
```diff
|
||||
@@ -29,8 +29,8 @@ import android.os.RemoteException;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.util.Log;
|
||||
|
@ -37,11 +41,3 @@ Overwrite all files under `com/google/android/vending`
|
|||
import com.google.android.vending.licensing.util.Base64;
|
||||
import com.google.android.vending.licensing.util.Base64DecoderException;
|
||||
```
|
||||
```
|
||||
@@ -287,13 +287,15 @@ public class LicenseChecker implements ServiceConnection {
|
||||
if (logResponse) {
|
||||
- String android_id = Secure.getString(mContext.getContentResolver(),
|
||||
- Secure.ANDROID_ID);
|
||||
+ String android_id = Secure.ANDROID_ID;
|
||||
Date date = new Date();
|
||||
```
|
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -746,7 +746,8 @@ public abstract class DownloaderService extends CustomIntentService implements I
|
|||
public void run() {
|
||||
setServiceRunning(true);
|
||||
mNotification.onDownloadStateChanged(IDownloaderClient.STATE_FETCHING_URL);
|
||||
String deviceId = Secure.ANDROID_ID;
|
||||
String deviceId = Secure.getString(mContext.getContentResolver(),
|
||||
Secure.ANDROID_ID);
|
||||
|
||||
final APKExpansionPolicy aep = new APKExpansionPolicy(mContext,
|
||||
new AESObfuscator(getSALT(), mContext.getPackageName(), deviceId));
|
||||
|
|
|
@ -287,7 +287,8 @@ public class LicenseChecker implements ServiceConnection {
|
|||
}
|
||||
|
||||
if (logResponse) {
|
||||
String android_id = Secure.ANDROID_ID;
|
||||
String android_id = Secure.getString(mContext.getContentResolver(),
|
||||
Secure.ANDROID_ID);
|
||||
Date date = new Date();
|
||||
Log.d(TAG, "Server Failure: " + stringError);
|
||||
Log.d(TAG, "Android ID: " + android_id);
|
||||
|
|
|
@ -287,14 +287,6 @@ bool OS_Android::can_draw() const {
|
|||
return true; //always?
|
||||
}
|
||||
|
||||
void OS_Android::set_cursor_shape(CursorShape p_shape) {
|
||||
|
||||
//android really really really has no mouse.. how amazing..
|
||||
}
|
||||
|
||||
void OS_Android::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
}
|
||||
|
||||
void OS_Android::main_loop_begin() {
|
||||
|
||||
if (main_loop)
|
||||
|
|
|
@ -187,9 +187,6 @@ public:
|
|||
|
||||
virtual bool can_draw() const;
|
||||
|
||||
virtual void set_cursor_shape(CursorShape p_shape);
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
|
||||
|
||||
void main_loop_begin();
|
||||
bool main_loop_iterate();
|
||||
void main_loop_request_go_back();
|
||||
|
|
|
@ -203,6 +203,10 @@ void OS_Haiku::set_cursor_shape(CursorShape p_shape) {
|
|||
//ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED");
|
||||
}
|
||||
|
||||
OS::CursorShape OS_Haiku::get_cursor_shape() const {
|
||||
// TODO: implement get_cursor_shape
|
||||
}
|
||||
|
||||
void OS_Haiku::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
// TODO
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ public:
|
|||
virtual Point2 get_mouse_position() const;
|
||||
virtual int get_mouse_button_state() const;
|
||||
virtual void set_cursor_shape(CursorShape p_shape);
|
||||
virtual CursorShape get_cursor_shape() const;
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
|
||||
|
||||
virtual int get_screen_count() const;
|
||||
|
|
|
@ -491,17 +491,11 @@ void OSIPhone::set_keep_screen_on(bool p_enabled) {
|
|||
_set_keep_screen_on(p_enabled);
|
||||
};
|
||||
|
||||
void OSIPhone::set_cursor_shape(CursorShape p_shape){
|
||||
|
||||
};
|
||||
|
||||
String OSIPhone::get_user_data_dir() const {
|
||||
|
||||
return data_dir;
|
||||
};
|
||||
|
||||
void OSIPhone::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot){};
|
||||
|
||||
String OSIPhone::get_name() {
|
||||
|
||||
return "iOS";
|
||||
|
|
|
@ -167,9 +167,6 @@ public:
|
|||
virtual void hide_virtual_keyboard();
|
||||
virtual int get_virtual_keyboard_height() const;
|
||||
|
||||
virtual void set_cursor_shape(CursorShape p_shape);
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
|
||||
|
||||
virtual Size2 get_window_size() const;
|
||||
virtual Rect2 get_window_safe_area() const;
|
||||
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
|
||||
- (void)didReceiveMemoryWarning;
|
||||
|
||||
- (void)viewDidLoad;
|
||||
|
||||
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures;
|
||||
|
||||
- (BOOL)prefersStatusBarHidden;
|
||||
|
||||
@end
|
||||
|
|
|
@ -83,6 +83,18 @@ int add_cmdline(int p_argc, char **p_args) {
|
|||
printf("*********** did receive memory warning!\n");
|
||||
};
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
if (@available(iOS 11.0, *)) {
|
||||
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures {
|
||||
return UIRectEdgeAll;
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotate {
|
||||
switch (OS::get_singleton()->get_screen_orientation()) {
|
||||
case OS::SCREEN_SENSOR:
|
||||
|
|
|
@ -70,6 +70,20 @@ static bool is_canvas_focused() {
|
|||
/* clang-format on */
|
||||
}
|
||||
|
||||
static Point2 correct_canvas_position(int x, int y) {
|
||||
int canvas_width;
|
||||
int canvas_height;
|
||||
emscripten_get_canvas_element_size(NULL, &canvas_width, &canvas_height);
|
||||
|
||||
double element_width;
|
||||
double element_height;
|
||||
emscripten_get_element_css_size(NULL, &element_width, &element_height);
|
||||
|
||||
x = (int)(canvas_width / element_width * x);
|
||||
y = (int)(canvas_height / element_height * y);
|
||||
return Point2(x, y);
|
||||
}
|
||||
|
||||
static bool cursor_inside_canvas = true;
|
||||
|
||||
EM_BOOL OS_JavaScript::fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data) {
|
||||
|
@ -285,7 +299,7 @@ EM_BOOL OS_JavaScript::mouse_button_callback(int p_event_type, const EmscriptenM
|
|||
Ref<InputEventMouseButton> ev;
|
||||
ev.instance();
|
||||
ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_MOUSEDOWN);
|
||||
ev->set_position(Point2(p_event->canvasX, p_event->canvasY));
|
||||
ev->set_position(correct_canvas_position(p_event->canvasX, p_event->canvasY));
|
||||
ev->set_global_position(ev->get_position());
|
||||
dom2godot_mod(p_event, ev);
|
||||
switch (p_event->button) {
|
||||
|
@ -349,7 +363,7 @@ EM_BOOL OS_JavaScript::mousemove_callback(int p_event_type, const EmscriptenMous
|
|||
OS_JavaScript *os = get_singleton();
|
||||
|
||||
int input_mask = os->input->get_mouse_button_mask();
|
||||
Point2 pos = Point2(p_event->canvasX, p_event->canvasY);
|
||||
Point2 pos = correct_canvas_position(p_event->canvasX, p_event->canvasY);
|
||||
// For motion outside the canvas, only read mouse movement if dragging
|
||||
// started inside the canvas; imitating desktop app behaviour.
|
||||
if (!cursor_inside_canvas && !input_mask)
|
||||
|
@ -666,7 +680,7 @@ EM_BOOL OS_JavaScript::touch_press_callback(int p_event_type, const EmscriptenTo
|
|||
if (!touch.isChanged)
|
||||
continue;
|
||||
ev->set_index(touch.identifier);
|
||||
ev->set_position(Point2(touch.canvasX, touch.canvasY));
|
||||
ev->set_position(correct_canvas_position(touch.canvasX, touch.canvasY));
|
||||
os->touches[i] = ev->get_position();
|
||||
ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
|
||||
|
||||
|
@ -691,7 +705,7 @@ EM_BOOL OS_JavaScript::touchmove_callback(int p_event_type, const EmscriptenTouc
|
|||
if (!touch.isChanged)
|
||||
continue;
|
||||
ev->set_index(touch.identifier);
|
||||
ev->set_position(Point2(touch.canvasX, touch.canvasY));
|
||||
ev->set_position(correct_canvas_position(touch.canvasX, touch.canvasY));
|
||||
Point2 &prev = os->touches[i];
|
||||
ev->set_relative(ev->get_position() - prev);
|
||||
prev = ev->get_position();
|
||||
|
|
|
@ -172,6 +172,7 @@ public:
|
|||
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
|
||||
|
||||
virtual void set_cursor_shape(CursorShape p_shape);
|
||||
virtual CursorShape get_cursor_shape() const;
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
|
||||
|
||||
virtual void set_mouse_show(bool p_show);
|
||||
|
|
|
@ -714,8 +714,6 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
|
|||
|
||||
if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED)
|
||||
OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
|
||||
if (OS_OSX::singleton->input)
|
||||
OS_OSX::singleton->input->set_mouse_in_window(false);
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(NSEvent *)event {
|
||||
|
@ -723,8 +721,6 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
|
|||
return;
|
||||
if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED)
|
||||
OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
|
||||
if (OS_OSX::singleton->input)
|
||||
OS_OSX::singleton->input->set_mouse_in_window(true);
|
||||
|
||||
OS::CursorShape p_shape = OS_OSX::singleton->cursor_shape;
|
||||
OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX;
|
||||
|
@ -1700,6 +1696,11 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) {
|
|||
cursor_shape = p_shape;
|
||||
}
|
||||
|
||||
OS::CursorShape OS_OSX::get_cursor_shape() const {
|
||||
|
||||
return cursor_shape;
|
||||
}
|
||||
|
||||
void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
if (p_cursor.is_valid()) {
|
||||
Ref<Texture> texture = p_cursor;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue