diff options
45 files changed, 774 insertions, 165 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index ab9c107d7a..cfd7677d6b 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -33,6 +33,7 @@ #include "geometry.h" #include "io/file_access_compressed.h" #include "io/file_access_encrypted.h" +#include "io/json.h" #include "io/marshalls.h" #include "os/keyboard.h" #include "os/os.h" @@ -2600,3 +2601,76 @@ _Engine *_Engine::singleton = NULL; _Engine::_Engine() { singleton = this; } + +void JSONParseResult::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_error"), &JSONParseResult::get_error); + ClassDB::bind_method(D_METHOD("get_error_string"), &JSONParseResult::get_error_string); + ClassDB::bind_method(D_METHOD("get_error_line"), &JSONParseResult::get_error_line); + ClassDB::bind_method(D_METHOD("get_result"), &JSONParseResult::get_result); + + ClassDB::bind_method(D_METHOD("set_error", "error"), &JSONParseResult::set_error); + ClassDB::bind_method(D_METHOD("set_error_string", "error_string"), &JSONParseResult::set_error_string); + ClassDB::bind_method(D_METHOD("set_error_line", "error_line"), &JSONParseResult::set_error_line); + ClassDB::bind_method(D_METHOD("set_result", "result"), &JSONParseResult::set_result); + + ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "error", PROPERTY_HINT_NONE, "Error", PROPERTY_USAGE_CLASS_IS_ENUM), "set_error", "get_error"); + ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "error_string"), "set_error_string", "get_error_string"); + ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "error_line"), "set_error_line", "get_error_line"); + ADD_PROPERTYNZ(PropertyInfo(Variant::NIL, "result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_result", "get_result"); +} + +void JSONParseResult::set_error(Error p_error) { + error = p_error; +} + +Error JSONParseResult::get_error() const { + return error; +} + +void JSONParseResult::set_error_string(const String &p_error_string) { + error_string = p_error_string; +} + +String JSONParseResult::get_error_string() const { + return error_string; +} + +void JSONParseResult::set_error_line(int p_error_line) { + error_line = p_error_line; +} + +int JSONParseResult::get_error_line() const { + return error_line; +} + +void JSONParseResult::set_result(const Variant &p_result) { + result = p_result; +} + +Variant JSONParseResult::get_result() const { + return result; +} + +void _JSON::_bind_methods() { + ClassDB::bind_method(D_METHOD("print", "value"), &_JSON::print); + ClassDB::bind_method(D_METHOD("parse", "json"), &_JSON::parse); +} + +String _JSON::print(const Variant &p_value) { + return JSON::print(p_value); +} + +Ref<JSONParseResult> _JSON::parse(const String &p_json) { + Ref<JSONParseResult> result; + result.instance(); + + result->error = JSON::parse(p_json, result->result, result->error_string, result->error_line); + + return result; +} + +_JSON *_JSON::singleton = NULL; + +_JSON::_JSON() { + singleton = this; +} diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index fc28ada0f8..721acf657f 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -669,4 +669,50 @@ public: _Engine(); }; +class _JSON; + +class JSONParseResult : public Reference { + GDCLASS(JSONParseResult, Reference) + + friend class _JSON; + + Error error; + String error_string; + int error_line; + + Variant result; + +protected: + static void _bind_methods(); + +public: + void set_error(Error p_error); + Error get_error() const; + + void set_error_string(const String &p_error_string); + String get_error_string() const; + + void set_error_line(int p_error_line); + int get_error_line() const; + + void set_result(const Variant &p_result); + Variant get_result() const; +}; + +class _JSON : public Object { + GDCLASS(_JSON, Object) + +protected: + static void _bind_methods(); + static _JSON *singleton; + +public: + static _JSON *get_singleton() { return singleton; } + + String print(const Variant &p_value); + Ref<JSONParseResult> parse(const String &p_json); + + _JSON(); +}; + #endif // CORE_BIND_H diff --git a/core/color.cpp b/core/color.cpp index 259a4988b1..dd8b13c047 100644 --- a/core/color.cpp +++ b/core/color.cpp @@ -400,3 +400,122 @@ Color::operator String() const { return rtos(r) + ", " + rtos(g) + ", " + rtos(b) + ", " + rtos(a); } + +Color Color::operator+(const Color &p_color) const { + + return Color( + CLAMP(r + p_color.r, 0.0, 1.0), + CLAMP(g + p_color.g, 0.0, 1.0), + CLAMP(b + p_color.b, 0.0, 1.0), + CLAMP(a + p_color.a, 0.0, 1.0)); +} + +void Color::operator+=(const Color &p_color) { + + r = CLAMP(r + p_color.r, 0.0, 1.0); + g = CLAMP(g + p_color.g, 0.0, 1.0); + b = CLAMP(b + p_color.b, 0.0, 1.0); + a = CLAMP(a + p_color.a, 0.0, 1.0); +} + +Color Color::operator-(const Color &p_color) const { + + return Color( + CLAMP(r - p_color.r, 0.0, 1.0), + CLAMP(g - p_color.g, 0.0, 1.0), + CLAMP(b - p_color.b, 0.0, 1.0), + CLAMP(a - p_color.a, 0.0, 1.0)); +} + +void Color::operator-=(const Color &p_color) { + + r = CLAMP(r - p_color.r, 0.0, 1.0); + g = CLAMP(g - p_color.g, 0.0, 1.0); + b = CLAMP(b - p_color.b, 0.0, 1.0); + a = CLAMP(a - p_color.a, 0.0, 1.0); +} + +Color Color::operator*(const Color &p_color) const { + + return Color( + CLAMP(r * p_color.r, 0.0, 1.0), + CLAMP(g * p_color.g, 0.0, 1.0), + CLAMP(b * p_color.b, 0.0, 1.0), + CLAMP(a * p_color.a, 0.0, 1.0)); +} + +Color Color::operator*(const real_t &rvalue) const { + + return Color( + CLAMP(r * rvalue, 0.0, 1.0), + CLAMP(g * rvalue, 0.0, 1.0), + CLAMP(b * rvalue, 0.0, 1.0), + CLAMP(a * rvalue, 0.0, 1.0)); +} + +void Color::operator*=(const Color &p_color) { + + r = CLAMP(r * p_color.r, 0.0, 1.0); + g = CLAMP(g * p_color.g, 0.0, 1.0); + b = CLAMP(b * p_color.b, 0.0, 1.0); + a = CLAMP(a * p_color.a, 0.0, 1.0); +} + +void Color::operator*=(const real_t &rvalue) { + + r = CLAMP(r * rvalue, 0.0, 1.0); + g = CLAMP(g * rvalue, 0.0, 1.0); + b = CLAMP(b * rvalue, 0.0, 1.0); + a = CLAMP(a * rvalue, 0.0, 1.0); +}; + +Color Color::operator/(const Color &p_color) const { + + return Color( + p_color.r == 0 ? 1 : CLAMP(r / p_color.r, 0.0, 1.0), + p_color.g == 0 ? 1 : CLAMP(g / p_color.g, 0.0, 1.0), + p_color.b == 0 ? 1 : CLAMP(b / p_color.b, 0.0, 1.0), + p_color.a == 0 ? 1 : CLAMP(a / p_color.a, 0.0, 1.0)); +} + +Color Color::operator/(const real_t &rvalue) const { + + if (rvalue == 0) return Color(1.0, 1.0, 1.0, 1.0); + return Color( + CLAMP(r / rvalue, 0.0, 1.0), + CLAMP(g / rvalue, 0.0, 1.0), + CLAMP(b / rvalue, 0.0, 1.0), + CLAMP(a / rvalue, 0.0, 1.0)); +} + +void Color::operator/=(const Color &p_color) { + + r = p_color.r == 0 ? 1 : CLAMP(r / p_color.r, 0.0, 1.0); + g = p_color.g == 0 ? 1 : CLAMP(g / p_color.g, 0.0, 1.0); + b = p_color.b == 0 ? 1 : CLAMP(b / p_color.b, 0.0, 1.0); + a = p_color.a == 0 ? 1 : CLAMP(a / p_color.a, 0.0, 1.0); +} + +void Color::operator/=(const real_t &rvalue) { + + if (rvalue == 0) { + r = 1.0; + g = 1.0; + b = 1.0; + a = 1.0; + } else { + r = CLAMP(r / rvalue, 0.0, 1.0); + g = CLAMP(g / rvalue, 0.0, 1.0); + b = CLAMP(b / rvalue, 0.0, 1.0); + a = CLAMP(a / rvalue, 0.0, 1.0); + } +}; + +Color Color::operator-() const { + + return Color( + CLAMP(1.0 - r, 0.0, 1.0), + CLAMP(1.0 - g, 0.0, 1.0), + CLAMP(1.0 - b, 0.0, 1.0), + CLAMP(1.0 - a, 0.0, 1.0)); +} diff --git a/core/color.h b/core/color.h index d3d5db09f9..972b6a1b33 100644 --- a/core/color.h +++ b/core/color.h @@ -67,6 +67,23 @@ struct Color { return components[idx]; } + Color operator+(const Color &p_color) const; + void operator+=(const Color &p_color); + + Color operator-() const; + Color operator-(const Color &p_color) const; + void operator-=(const Color &p_color); + + Color operator*(const Color &p_color) const; + Color operator*(const real_t &rvalue) const; + void operator*=(const Color &p_color); + void operator*=(const real_t &rvalue); + + Color operator/(const Color &p_color) const; + Color operator/(const real_t &rvalue) const; + void operator/=(const Color &p_color); + void operator/=(const real_t &rvalue); + void invert(); void contrast(); Color inverted() const; diff --git a/core/object.cpp b/core/object.cpp index 23e32a214a..b1770f1d7a 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -277,32 +277,32 @@ MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyIn MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name) : name(p_name), flags(METHOD_FLAG_NORMAL), + return_val(p_ret), id(0) { - return_val = p_ret; } MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1) : name(p_name), + return_val(p_ret), flags(METHOD_FLAG_NORMAL), id(0) { - return_val = p_ret; arguments.push_back(p_param1); } MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2) : name(p_name), + return_val(p_ret), flags(METHOD_FLAG_NORMAL), id(0) { - return_val = p_ret; arguments.push_back(p_param1); arguments.push_back(p_param2); } MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3) : name(p_name), + return_val(p_ret), flags(METHOD_FLAG_NORMAL), id(0) { - return_val = p_ret; arguments.push_back(p_param1); arguments.push_back(p_param2); arguments.push_back(p_param3); @@ -310,9 +310,9 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const Pr MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4) : name(p_name), + return_val(p_ret), flags(METHOD_FLAG_NORMAL), id(0) { - return_val = p_ret; arguments.push_back(p_param1); arguments.push_back(p_param2); arguments.push_back(p_param3); @@ -321,9 +321,9 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const Pr MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5) : name(p_name), + return_val(p_ret), flags(METHOD_FLAG_NORMAL), id(0) { - return_val = p_ret; arguments.push_back(p_param1); arguments.push_back(p_param2); arguments.push_back(p_param3); diff --git a/core/object.h b/core/object.h index 644e2b8270..3070439138 100644 --- a/core/object.h +++ b/core/object.h @@ -148,6 +148,7 @@ struct PropertyInfo { hint(PROPERTY_HINT_NONE), usage(PROPERTY_USAGE_DEFAULT) { } + PropertyInfo(Variant::Type p_type, const String p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const StringName &p_class_name = StringName()) : type(p_type), name(p_name), @@ -161,12 +162,12 @@ struct PropertyInfo { class_name = p_class_name; } } + PropertyInfo(const StringName &p_class_name) : type(Variant::OBJECT), + class_name(p_class_name), hint(PROPERTY_HINT_NONE), usage(PROPERTY_USAGE_DEFAULT) { - - class_name = p_class_name; } bool operator<(const PropertyInfo &p_info) const { diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 27c31127a4..0e34a3eea5 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -68,6 +68,7 @@ static _Engine *_engine = NULL; static _ClassDB *_classdb = NULL; static _Marshalls *_marshalls = NULL; static TranslationLoaderPO *resource_format_po = NULL; +static _JSON *_json = NULL; static IP *ip = NULL; @@ -162,6 +163,8 @@ void register_core_types() { ClassDB::register_class<AStar>(); ClassDB::register_class<EncodedObjectAsID>(); + ClassDB::register_class<JSONParseResult>(); + ip = IP::create(); _geometry = memnew(_Geometry); @@ -172,6 +175,7 @@ void register_core_types() { _engine = memnew(_Engine); _classdb = memnew(_ClassDB); _marshalls = memnew(_Marshalls); + _json = memnew(_JSON); } void register_core_settings() { @@ -193,6 +197,7 @@ void register_core_singletons() { ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("TranslationServer", TranslationServer::get_singleton())); ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Input", Input::get_singleton())); ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("InputMap", InputMap::get_singleton())); + ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JSON", _JSON::get_singleton())); } void unregister_core_types() { @@ -203,6 +208,7 @@ void unregister_core_types() { memdelete(_engine); memdelete(_classdb); memdelete(_marshalls); + memdelete(_json); memdelete(_geometry); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index b6e114b853..a11169eb8f 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -493,7 +493,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant & DEFAULT_OP_FAIL(BASIS); DEFAULT_OP_FAIL(TRANSFORM); - DEFAULT_OP_FAIL(COLOR); + DEFAULT_OP_LOCALMEM(+, COLOR, Color); DEFAULT_OP_FAIL(NODE_PATH); DEFAULT_OP_FAIL(_RID); @@ -549,7 +549,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant & DEFAULT_OP_FAIL(BASIS); DEFAULT_OP_FAIL(TRANSFORM); - DEFAULT_OP_FAIL(COLOR); + DEFAULT_OP_LOCALMEM(-, COLOR, Color); DEFAULT_OP_FAIL(NODE_PATH); DEFAULT_OP_FAIL(_RID); @@ -645,7 +645,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant & r_valid = false; return; } break; - DEFAULT_OP_FAIL(COLOR); + DEFAULT_OP_LOCALMEM_NUM(*, COLOR, Color); DEFAULT_OP_FAIL(NODE_PATH); DEFAULT_OP_FAIL(_RID); @@ -717,7 +717,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant & DEFAULT_OP_FAIL(BASIS); DEFAULT_OP_FAIL(TRANSFORM); - DEFAULT_OP_FAIL(COLOR); + DEFAULT_OP_LOCALMEM_NUM(/, COLOR, Color); DEFAULT_OP_FAIL(NODE_PATH); DEFAULT_OP_FAIL(_RID); @@ -797,7 +797,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant & DEFAULT_OP_FAIL(BASIS); DEFAULT_OP_FAIL(TRANSFORM); - DEFAULT_OP_FAIL(COLOR); + DEFAULT_OP_LOCALMEM_NEG(COLOR, Color); DEFAULT_OP_FAIL(NODE_PATH); DEFAULT_OP_FAIL(_RID); diff --git a/doc/classes/@GDScript.xml b/doc/classes/@GDScript.xml index 52df939fc5..511109e615 100644 --- a/doc/classes/@GDScript.xml +++ b/doc/classes/@GDScript.xml @@ -82,7 +82,7 @@ Returns the arc sine of 's' in radians. Use to get the angle of sine 's'. [codeblock] # s is 0.523599 or 30 degrees if converted with rad2deg(s) - s = asin(0.5) + s = asin(0.5) [/codeblock] </description> </method> @@ -92,6 +92,14 @@ <argument index="0" name="condition" type="bool"> </argument> <description> + Assert that the condition is true. If the condition is false a fatal error is generated and the program is halted. Useful for debugging to make sure a value is always true. + [codeblock] + # Speed should always be between 0 and 20 + speed = -10 + assert(speed < 20) # Is true and program continues + assert(speed >= 0) # Is false and program stops + assert(speed >= 0 && speed < 20) # Or combined + [/codeblock] </description> </method> <method name="atan"> @@ -100,6 +108,11 @@ <argument index="0" name="s" type="float"> </argument> <description> + Returns the arc tangent of 's' in radians. Use it to get the angle from an angle's tangent in trigonometry: [code]atan(tan(angle)) == angle[/code]. + The method cannot know in which quadrant the angle should fall. See [method atan2] if you always want an exact angle. + [codeblock] + a = atan(0.5) # a is 0.463648 + [/codeblock] </description> </method> <method name="atan2"> @@ -110,10 +123,9 @@ <argument index="1" name="y" type="float"> </argument> <description> - Returns the arc tangent of y/x in radians. Use to get the angle of tangent y/x. To compute the value, the function takes into account the sign of both arguments in order to determine the quadrant. + Returns the arc tangent of y/x in radians. Use to get the angle of tangent y/x. To compute the value, the method takes into account the sign of both arguments in order to determine the quadrant. [codeblock] - # a is 3.141593 - a = atan(0,-1) + a = atan(0,-1) # a is 3.141593 [/codeblock] </description> </method> @@ -134,10 +146,8 @@ <description> Rounds 's' upward, returning the smallest integral value that is not less than 's'. [codeblock] - # i is 2 - i = ceil(1.45) - # i is 2 - i = ceil(1.001) + i = ceil(1.45) # i is 2 + i = ceil(1.001) # i is 2 [/codeblock] </description> </method> @@ -303,7 +313,10 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns [b]e[/b] raised to the power of 's'. [b]e[/b] sometimes called "Euler's number" is a mathematical constant whose value is approximately 2.71828. + Raises the Euler's constant [b]e[/b] to the power of 's' and returns it. [b] has an approximate value of 2.71828. + [codeblock] + a = exp(2) # approximately 7.39 + [/codeblock] </description> </method> <method name="floor"> @@ -312,7 +325,13 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the largest integer value (rounded down) that is less than or equal to 's'. + Rounds 's' to the closest smaller integer and returns it. + [codeblock] + # a is 2 + a = floor(2.99) + # a is -3 + a = floor(-2.99) + [/codeblock] </description> </method> <method name="fmod"> @@ -338,6 +357,26 @@ <argument index="1" name="y" type="float"> </argument> <description> + Returns the floating-point remainder of x/y that wraps equally in positive and negative. + [codeblock] + var i = -10; + while i < 0: + prints(i, fposmod(i, 10)) + i += 1 + [/codeblock] + Produces: + [codeblock] + -10 10 + -9 1 + -8 2 + -7 3 + -6 4 + -5 5 + -4 6 + -3 7 + -2 8 + -1 9 + [/codeblock] </description> </method> <method name="funcref"> @@ -348,6 +387,14 @@ <argument index="1" name="funcname" type="String"> </argument> <description> + Returns a reference to the specified function 'funcname' in the 'instance' node. As functions aren't first-class objects in GDscript, use 'funcref' to store a function in a variable and call it later. + [codeblock] + func foo(): + return("bar") + + a = funcref(self, "foo") + print(a.call_func()) # prints bar + [/codeblock] </description> </method> <method name="hash"> @@ -358,8 +405,7 @@ <description> Returns the integer hash of the variable passed. [codeblock] - # print 177670 - print(hash("a")) + print(hash("a")) # prints 177670 [/codeblock] </description> </method> @@ -396,9 +442,8 @@ func _ready(): var id = get_instance_id() var inst = instance_from_id(id) - print(inst.foo) + print(inst.foo) # prints bar [/codeblock] - Prints "bar" </description> </method> <method name="inverse_lerp"> @@ -413,7 +458,7 @@ <description> Returns a normalized value considering the given range. [codeblock] - inverse_lerp(3, 5, 4) # return 0.5 + inverse_lerp(3, 5, 4) # returns 0.5 [/codeblock] </description> </method> @@ -444,9 +489,8 @@ Returns length of Variant 'var'. Length is the character count of String, element count of Array, size of Dictionary, etc. Note: Generates a fatal error if Variant can not provide a length. [codeblock] a = [1, 2, 3, 4] - print(len(a)) + len(a) # returns 4 [/codeblock] - Prints 4 </description> </method> <method name="lerp"> @@ -460,6 +504,9 @@ </argument> <description> Linear interpolates between two values by a normalized value. + [codeblock] + lerp(1, 3, 0.5) # returns 2 + [/codeblock] </description> </method> <method name="linear2db"> @@ -492,8 +539,7 @@ <description> Natural logarithm. The amount of time needed to reach a certain level of continuous growth. Note: This is not the same as the log funcation on your calculator which is a base 10 logarithm. [codeblock] - # a is 2.302585 - a = log(10) + log(10) # returns 2.302585 [/codeblock] </description> </method> @@ -507,10 +553,8 @@ <description> Returns the maximum of two values. [codeblock] - # a is 2 - a = max(1,2) - # a is -3.99 - a = max(-3.99, -4) + max(1,2) # returns 2 + max(-3.99, -4) # returns -3.99 [/codeblock] </description> </method> @@ -524,10 +568,8 @@ <description> Returns the minimum of two values. [codeblock] - # a is 1 - a = min(1,2) - # a is -4 - a = min(-3.99, -4) + min(1,2) # returns 1 + min(-3.99, -4) # returns -4 [/codeblock] </description> </method> @@ -537,14 +579,11 @@ <argument index="0" name="val" type="int"> </argument> <description> - Returns the nearest larger power of 2 for an integer. + Returns the nearest larger power of 2 for integer 'val'. [codeblock] - # a is 4 - a = nearest_po2(3) - # a is 4 - a = nearest_po2(4) - # a is 8 - a = nearest_po2(5) + nearest_po2(3) # returns 4 + nearest_po2(4) # returns 4 + nearest_po2(5) # returns 8 [/codeblock] </description> </method> @@ -559,7 +598,7 @@ [codeblock] p = parse_json('["a", "b", "c"]') if typeof(p) == TYPE_ARRAY: - print(p[0]) + print(p[0]) # prints a else: print("unexpected results") [/codeblock] @@ -575,8 +614,7 @@ <description> Returns the result of 'x' raised to the power of 'y'. [codeblock] - # a is 32 - a = pow(2,5) + pow(2,5) # returns 32 [/codeblock] </description> </method> @@ -590,6 +628,7 @@ [codeblock] # load a scene called main located in the root of the project directory var main = preload("res://main.tscn") + [/codeblock] </description> </method> <method name="print" qualifiers="vararg"> @@ -599,9 +638,8 @@ Converts one or more arguments to strings in the best way possible and prints them to the console. [codeblock] a = [1,2,3] - print("a","b",a) + print("a","b",a) # prints ab[1, 2, 3] [/codeblock] - Prints ab[1, 2, 3] </description> </method> <method name="print_stack"> @@ -609,6 +647,10 @@ </return> <description> Print a stack track at code location, only works when running with debugger turned on. + Output in the console would look something like this: + [codeblock] + Frame 0 - res://test.gd:16 in function '_process' + [/codeblock] </description> </method> <method name="printerr" qualifiers="vararg"> @@ -616,6 +658,9 @@ </return> <description> Print one or more arguments to strings in the best way possible to standard error line. + [codeblock] + printerr("prints to stderr") + [/codeblock] </description> </method> <method name="printraw" qualifiers="vararg"> @@ -623,6 +668,11 @@ </return> <description> Print one or more arguments to strings in the best way possible to console. No newline is added at the end. + [codeblock] + printraw("A") + printraw("B") + # prints AB + [/codeblock] </description> </method> <method name="prints" qualifiers="vararg"> @@ -630,6 +680,9 @@ </return> <description> Print one or more arguments to the console with a space between each argument. + [codeblock] + prints("A", "B", "C") # prints A B C + [/codeblock] </description> </method> <method name="printt" qualifiers="vararg"> @@ -637,6 +690,9 @@ </return> <description> Print one or more arguments to the console with a tab between each argument. + [codeblock] + printt("A", "B", "C") # prints A B C + [/codeblock] </description> </method> <method name="rad2deg"> @@ -646,6 +702,9 @@ </argument> <description> Convert from radians to degrees. + [codeblock] + rad2deg(0.523599) # returns 30 + [/codeblock] </description> </method> <method name="rand_range"> @@ -657,6 +716,9 @@ </argument> <description> Random range, any floating point value between 'from' and 'to'. + [codeblock] + prints(rand_range(0, 1), rand_range(0, 1)) # prints 0.135591 0.405263 + [/codeblock] </description> </method> <method name="rand_seed"> @@ -673,13 +735,21 @@ </return> <description> Return a random floating point value between 0 and 1. + [codeblock] + randf() # returns 0.375671 + [/codeblock] </description> </method> <method name="randi"> <return type="int"> </return> <description> - Return a random 32 bits integer value. To obtain a random value between 0 to N (where N is smaller than 2^32 - 1), you can use remainder. For example, to get a random integer between 0 and 19 inclusive, you can use randi() % 20. + Return a random 32 bit integer. Use remainder to obtain a random value between 0 and N (where N is smaller than 2^32 -1). + [codeblock] + randi() % 20 # returns random number between 0 and 19 + randi() % 100 # returns random number between 0 and 99 + randi() % 100 + 1 # returns random number between 1 and 100 + [/codeblock] </description> </method> <method name="randomize"> @@ -687,6 +757,10 @@ </return> <description> Randomize the seed (or the internal state) of the random number generator. Current implementation reseeds using a number based on time. + [codeblock] + func _ready(): + randomize() + [/codeblock] </description> </method> <method name="range" qualifiers="vararg"> @@ -694,6 +768,29 @@ </return> <description> Return an array with the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial, final-1, increment). + [codeblock] + for i in range(4): + print(i) + for i in range(2, 5): + print(i) + for i in range(0, 6, 2): + print(i) + [/codeblock] + Output: + [codeblock] + 0 + 1 + 2 + 3 + + 2 + 3 + 4 + + 0 + 2 + 4 + [/codeblock] </description> </method> <method name="range_lerp"> @@ -723,6 +820,9 @@ </argument> <description> Returns the integral value that is nearest to s, with halfway cases rounded away from zero. + [codeblock] + round(2.6) # returns 3 + [/codeblock] </description> </method> <method name="seed"> @@ -732,6 +832,10 @@ </argument> <description> Set seed for the random number generator. + [codeblock] + my_seed = "Godot Rocks" + seed(my_seed.hash()) + [/codeblock] </description> </method> <method name="sign"> @@ -740,7 +844,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Return sign (-1 or +1). + Return sign of 's' -1 or 1. + [codeblock] + sign(-6) # returns -1 + sign(6) # returns 1 + [/codeblock] </description> </method> <method name="sin"> @@ -749,7 +857,10 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the sine of an angle of s radians. + Return the sine of angle 's' in radians. + [codeblock] + sin(0.523599) # returns 0.5 + [/codeblock] </description> </method> <method name="sinh"> @@ -758,7 +869,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the hyperbolic sine of s. + Return the hyperbolic sine of 's'. + [codeblock] + a = log(2.0) # returns 0.693147 + sinh(a) # returns 0.75 + [/codeblock] </description> </method> <method name="sqrt"> @@ -767,7 +882,10 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the square root of s. + Return the square root of 's'. + [codeblock] + sqrt(9) # returns 3 + [/codeblock] </description> </method> <method name="stepify"> @@ -786,6 +904,12 @@ </return> <description> Convert one or more arguments to string in the best way possible. + [codeblock] + var a = [10, 20, 30] + var b = str(a); + len(a) # returns 3 + len(b) # returns 12 + [/codeblock] </description> </method> <method name="str2var"> @@ -795,6 +919,11 @@ </argument> <description> Convert a formatted string that was returned by [method var2str] to the original value. + [codeblock] + a = '{ "a": 1, "b": 2 }' + b = str2var(a) + print(b['a']) # prints 1 + [/codeblock] </description> </method> <method name="tan"> @@ -803,7 +932,10 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the tangent of an angle of s radians. + Return the tangent of angle 's' in radians. + [codeblock] + tan( deg2rad(45) ) # returns 1 + [/codeblock] </description> </method> <method name="tanh"> @@ -812,7 +944,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the hyperbolic tangent of s. + Returns the hyperbolic tangent of 's'. + [codeblock] + a = log(2.0) # returns 0.693147 + tanh(a) # returns 0.6 + [/codeblock] </description> </method> <method name="to_json"> @@ -821,7 +957,12 @@ <argument index="0" name="var" type="Variant"> </argument> <description> - Convert a Variant to json text. + Convert a Variant 'var' to json text and return the result. Useful for serializing data to store or send over the network + [codeblock] + a = { 'a': 1, 'b': 2 } + b = to_json(a) + print(b) # {"a":1, "b":2} + [/codeblock] </description> </method> <method name="type_exists"> @@ -844,6 +985,13 @@ </argument> <description> Return the internal type of the given Variant object, using the TYPE_* enum in [@Global Scope]. + [codeblock] + p = parse_json('["a", "b", "c"]') + if typeof(p) == TYPE_ARRAY: + print(p[0]) # prints a + else: + print("unexpected results") + [/codeblock] </description> </method> <method name="validate_json"> @@ -852,7 +1000,15 @@ <argument index="0" name="json" type="String"> </argument> <description> - This method is used to validate the structure and data types of a piece of JSON, similar to XML Schema for XML. + Check that 'json' is valid json data. Return empty string if valid. Return error message if not valid. + [codeblock] + j = to_json([1, 2, 3]) + v = validate_json(j) + if not v: + print("valid") + else: + prints("invalid", v) + [/codeblock] </description> </method> <method name="var2bytes"> @@ -871,6 +1027,17 @@ </argument> <description> Convert a value to a formatted string that can later be parsed using [method str2var]. + [codeblock] + a = { 'a': 1, 'b': 2 } + print(var2str(a)) + [/codeblock] + prints + [codeblock] + { + "a": 1, + "b": 2 + } + [/codeblock] </description> </method> <method name="weakref"> diff --git a/doc/classes/AudioStreamOGGVorbis.xml b/doc/classes/AudioStreamOGGVorbis.xml index fd9018764d..679438b66b 100644 --- a/doc/classes/AudioStreamOGGVorbis.xml +++ b/doc/classes/AudioStreamOGGVorbis.xml @@ -56,10 +56,13 @@ </methods> <members> <member name="data" type="PoolByteArray" setter="set_data" getter="get_data"> + Raw audio data. </member> <member name="loop" type="bool" setter="set_loop" getter="has_loop"> + If [code]true[/code], audio will loop continuously. Default value: [code]false[/code]. </member> <member name="loop_offset" type="float" setter="set_loop_offset" getter="get_loop_offset"> + If loop is [code]true[/code], loop starts from this position, in seconds. </member> </members> <constants> diff --git a/doc/classes/AudioStreamPlayer.xml b/doc/classes/AudioStreamPlayer.xml index 6ee0ba09a1..edf5dd619b 100644 --- a/doc/classes/AudioStreamPlayer.xml +++ b/doc/classes/AudioStreamPlayer.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AudioStreamPlayer" inherits="Node" category="Core" version="3.0.alpha.custom_build"> <brief_description> + Plays back audio. </brief_description> <description> + Plays background audio. </description> <tutorials> </tutorials> @@ -57,6 +59,7 @@ <argument index="0" name="from_pos" type="float" default="0.0"> </argument> <description> + Plays the audio from the given position 'from_pos', in seconds. </description> </method> <method name="seek"> @@ -65,6 +68,7 @@ <argument index="0" name="to_pos" type="float"> </argument> <description> + Sets the position from which audio will be played, in seconds. </description> </method> <method name="set_autoplay"> @@ -111,26 +115,33 @@ <return type="void"> </return> <description> + Stops the audio. </description> </method> </methods> <members> <member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled"> + If [code]true[/code], audio plays when added to scene tree. Default value: [code]false[/code]. </member> <member name="bus" type="String" setter="set_bus" getter="get_bus"> + Bus on which this audio is playing. </member> <member name="mix_target" type="int" setter="set_mix_target" getter="get_mix_target" enum="AudioStreamPlayer.MixTarget"> </member> <member name="playing" type="bool" setter="_set_playing" getter="is_playing"> + If [code]true[/code], audio is playing. </member> <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream"> + The [AudioStream] object to be played. </member> <member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db"> + Volume of sound, in dB. </member> </members> <signals> <signal name="finished"> <description> + Emitted when the audio stops playing. </description> </signal> </signals> diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml index f2464ddac4..e31f2dd941 100644 --- a/doc/classes/AudioStreamPlayer2D.xml +++ b/doc/classes/AudioStreamPlayer2D.xml @@ -1,10 +1,13 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AudioStreamPlayer2D" inherits="Node2D" category="Core" version="3.0.alpha.custom_build"> <brief_description> + Plays audio in 2D. </brief_description> <description> + Plays audio that dampens with distance from screen center. </description> <tutorials> + http://docs.godotengine.org/en/latest/learning/features/audio/index.html </tutorials> <demos> </demos> @@ -69,6 +72,7 @@ <argument index="0" name="from_pos" type="float" default="0.0"> </argument> <description> + Plays the audio from the given position 'from_pos', in seconds. </description> </method> <method name="seek"> @@ -77,6 +81,7 @@ <argument index="0" name="to_pos" type="float"> </argument> <description> + Sets the position from which audio will be played, in seconds. </description> </method> <method name="set_area_mask"> @@ -139,30 +144,40 @@ <return type="void"> </return> <description> + Stops the audio. </description> </method> </methods> <members> <member name="area_mask" type="int" setter="set_area_mask" getter="get_area_mask"> + Areas in which this sound plays. </member> <member name="attenuation" type="float" setter="set_attenuation" getter="get_attenuation"> + Dampens audio over distance with this as an exponent. </member> <member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled"> + If [code]true[/code], audio plays when added to scene tree. Default value: [code]false[/code]. </member> <member name="bus" type="String" setter="set_bus" getter="get_bus"> + Bus on which this audio is playing. </member> <member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance"> + Maximum distance from which audio is still hearable. </member> <member name="playing" type="bool" setter="_set_playing" getter="is_playing"> + If [code]true[/code], audio is playing. </member> <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream"> + The [AudioStream] object to be played. </member> <member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db"> + Base volume without dampening. </member> </members> <signals> <signal name="finished"> <description> + Emitted when the audio stops playing. </description> </signal> </signals> diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml index 668e0cc0d2..3aad0ea87a 100644 --- a/doc/classes/AudioStreamPlayer3D.xml +++ b/doc/classes/AudioStreamPlayer3D.xml @@ -1,10 +1,13 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AudioStreamPlayer3D" inherits="Spatial" category="Core" version="3.0.alpha.custom_build"> <brief_description> + Plays 3D sound in 3D space </brief_description> <description> + Plays a sound effect with directed sound effects, dampens with distance if needed, generates effect of hearable position in space. </description> <tutorials> + http://docs.godotengine.org/en/latest/learning/features/audio/index.html </tutorials> <demos> </demos> @@ -123,6 +126,7 @@ <argument index="0" name="from_pos" type="float" default="0.0"> </argument> <description> + Plays the audio from the given position 'from_pos', in seconds. </description> </method> <method name="seek"> @@ -131,6 +135,7 @@ <argument index="0" name="to_pos" type="float"> </argument> <description> + Sets the position from which audio will be played, in seconds. </description> </method> <method name="set_area_mask"> @@ -265,67 +270,94 @@ <return type="void"> </return> <description> + Stops the audio. </description> </method> </methods> <members> <member name="area_mask" type="int" setter="set_area_mask" getter="get_area_mask"> + Areas in which this sound plays. </member> <member name="attenuation_filter_cutoff_hz" type="float" setter="set_attenuation_filter_cutoff_hz" getter="get_attenuation_filter_cutoff_hz"> + Dampens audio above this frequency, in Hz. </member> <member name="attenuation_filter_db" type="float" setter="set_attenuation_filter_db" getter="get_attenuation_filter_db"> + Amount how much the filter affects the loudness, in dB. </member> <member name="attenuation_model" type="int" setter="set_attenuation_model" getter="get_attenuation_model" enum="AudioStreamPlayer3D.AttenuationModel"> + Decides if audio should get quieter with distance linearly, quadratically or logarithmically. </member> <member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled"> + If [code]true[/code], audio plays audio plays when added to scene tree. Default value: [code]false[/code]. </member> <member name="bus" type="String" setter="set_bus" getter="get_bus"> + Bus on which this audio is playing. </member> <member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" enum="AudioStreamPlayer3D.DopplerTracking"> + Decides in which step the Doppler effect should be calculated. </member> <member name="emission_angle_degrees" type="float" setter="set_emission_angle" getter="get_emission_angle"> + The angle in which the audio reaches cameras undampened. </member> <member name="emission_angle_enabled" type="bool" setter="set_emission_angle_enabled" getter="is_emission_angle_enabled"> + If [code]true[/code], the audio should be dampened according to the direction of the sound. </member> <member name="emission_angle_filter_attenuation_db" type="float" setter="set_emission_angle_filter_attenuation_db" getter="get_emission_angle_filter_attenuation_db"> + dampens audio if camera is outside of 'emission_angle_degrees' and 'emission_angle_enabled' is set by this factor, in dB. </member> <member name="max_db" type="float" setter="set_max_db" getter="get_max_db"> + Sets the absolute maximum of the soundlevel, in dB. </member> <member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance"> + Sets the distance from wich the 'out_of_range_mode' takes effect. Has no effect if set to 0. </member> <member name="out_of_range_mode" type="int" setter="set_out_of_range_mode" getter="get_out_of_range_mode" enum="AudioStreamPlayer3D.OutOfRangeMode"> + Decides if audio should pause when source is outside of 'max_distance' range. </member> <member name="playing" type="bool" setter="_set_playing" getter="is_playing"> + If [code]true[/code], audio is playing. </member> <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream"> + The [AudioStream] object to be played. </member> <member name="unit_db" type="float" setter="set_unit_db" getter="get_unit_db"> + Base sound level unaffected by dampening, in dB. </member> <member name="unit_size" type="float" setter="set_unit_size" getter="get_unit_size"> + Factor for the attenuation effect. </member> </members> <signals> <signal name="finished"> <description> + Fires when the audio stops playing. </description> </signal> </signals> <constants> <constant name="ATTENUATION_INVERSE_DISTANCE" value="0"> + Linear dampening of loudness according to distance. </constant> <constant name="ATTENUATION_INVERSE_SQUARE_DISTANCE" value="1"> + Squared dampening of loudness according to distance. </constant> <constant name="ATTENUATION_LOGARITHMIC" value="2"> + Logarithmic dampening of loudness according to distance. </constant> <constant name="OUT_OF_RANGE_MIX" value="0"> + Mix this audio in, even when it's out of range. </constant> <constant name="OUT_OF_RANGE_PAUSE" value="1"> + Pause this audio when it gets out of range. </constant> <constant name="DOPPLER_TRACKING_DISABLED" value="0"> + Disables doppler tracking. </constant> <constant name="DOPPLER_TRACKING_IDLE_STEP" value="1"> + Executes doppler trackin in idle step. </constant> <constant name="DOPPLER_TRACKING_FIXED_STEP" value="2"> + Executes doppler tracking in fixed step. </constant> </constants> </class> diff --git a/doc/classes/AudioStreamRandomPitch.xml b/doc/classes/AudioStreamRandomPitch.xml index 91856682e6..1573a78d1f 100644 --- a/doc/classes/AudioStreamRandomPitch.xml +++ b/doc/classes/AudioStreamRandomPitch.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AudioStreamRandomPitch" inherits="AudioStream" category="Core" version="3.0.alpha.custom_build"> <brief_description> + Plays audio with random pitch tweaking. </brief_description> <description> + Randomly varies pitch on each start. </description> <tutorials> </tutorials> @@ -40,8 +42,10 @@ </methods> <members> <member name="audio_stream" type="AudioStream" setter="set_audio_stream" getter="get_audio_stream"> + The current [AudioStream]. </member> <member name="random_pitch" type="float" setter="set_random_pitch" getter="get_random_pitch"> + The intensity of random pitch variation. </member> </members> <constants> diff --git a/doc/classes/AudioStreamSample.xml b/doc/classes/AudioStreamSample.xml index 22b820aa7d..7f7414e4d3 100644 --- a/doc/classes/AudioStreamSample.xml +++ b/doc/classes/AudioStreamSample.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AudioStreamSample" inherits="AudioStream" category="Core" version="3.0.alpha.custom_build"> <brief_description> + Plays audio. </brief_description> <description> + Plays audio, can loop. </description> <tutorials> </tutorials> @@ -110,32 +112,45 @@ </methods> <members> <member name="data" type="PoolByteArray" setter="set_data" getter="get_data"> + Raw audio data. </member> <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamSample.Format"> + Audio format. See FORMAT_* constants for values. </member> <member name="loop_begin" type="int" setter="set_loop_begin" getter="get_loop_begin"> + Loop start in bytes. </member> <member name="loop_end" type="int" setter="set_loop_end" getter="get_loop_end"> + Loop end in bytes. </member> <member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" enum="AudioStreamSample.LoopMode"> + Loop mode. See LOOP_* constants for values. </member> <member name="mix_rate" type="int" setter="set_mix_rate" getter="get_mix_rate"> + The sample rate for mixing this audio. </member> <member name="stereo" type="bool" setter="set_stereo" getter="is_stereo"> + If [code]true[/code], audio is stereo. Default value: [code]false[/code]. </member> </members> <constants> <constant name="FORMAT_8_BITS" value="0"> + Audio codec 8 bit. </constant> <constant name="FORMAT_16_BITS" value="1"> + Audio codec 16 bit. </constant> <constant name="FORMAT_IMA_ADPCM" value="2"> + Audio codec IMA ADPCM. </constant> <constant name="LOOP_DISABLED" value="0"> + Audio does not loop. </constant> <constant name="LOOP_FORWARD" value="1"> + Audio loops the data between loop_begin and loop_end playing forward only. </constant> <constant name="LOOP_PING_PONG" value="2"> + Audio loops the data between loop_begin and loop_end playing back and forth. </constant> </constants> </class> diff --git a/doc/classes/CollisionPolygon.xml b/doc/classes/CollisionPolygon.xml index cf425e3d60..c2496424d6 100644 --- a/doc/classes/CollisionPolygon.xml +++ b/doc/classes/CollisionPolygon.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CollisionPolygon" inherits="Spatial" category="Core" version="3.0.alpha.custom_build"> <brief_description> + Editor-only class for defining a collision polygon in 3D space. </brief_description> <description> + Allows editing a collision polygon's vertices on a selected plane. Can also set a depth perpendicular to that plane. This class is only available in the editor. It will not appear in the scene tree at runtime. Creates a [Shape] for gameplay. Properties modified during gameplay will have no effect. </description> <tutorials> </tutorials> @@ -54,10 +56,13 @@ </methods> <members> <member name="depth" type="float" setter="set_depth" getter="get_depth"> + Length that the resulting collision extends in either direction perpendicular to its polygon. </member> <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled"> + If true, no collision will be produced. </member> <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon"> + Array of vertices which define the polygon. </member> </members> <constants> diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml index b602610167..d3dee1e9bb 100644 --- a/doc/classes/CollisionPolygon2D.xml +++ b/doc/classes/CollisionPolygon2D.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CollisionPolygon2D" inherits="Node2D" category="Core" version="3.0.alpha.custom_build"> <brief_description> - Editor-only class for easy editing of collision polygons. + Editor-only class for defining a collision polygon in 2D space. </brief_description> <description> - Editor-only class. This is not present when running the game. It's used in the editor to properly edit and position collision shapes in [CollisionObject2D]. This is not accessible from regular code. This class is for editing custom shape polygons. + Allows editing a collision polygon's vertices. This class is only available in the editor. It will not appear in the scene tree at runtime. Creates a [Shape2D] for gameplay. Properties modified during gameplay will have no effect. </description> <tutorials> </tutorials> @@ -75,12 +75,16 @@ </methods> <members> <member name="build_mode" type="int" setter="set_build_mode" getter="get_build_mode" enum="CollisionPolygon2D.BuildMode"> + If BUILD_SOLIDS, the polygon and the area within it will have collision. If BUILD_SEGMENTS, only the edges of the polygon will have collision. </member> <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled"> + If true, no collision will be produced. </member> <member name="one_way_collision" type="bool" setter="set_one_way_collision" getter="is_one_way_collision_enabled"> + If true, only edges that face up, relative to CollisionPolygon2D's rotation, will collide with other objects. </member> <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon"> + Array of vertices which define the polygon. </member> </members> <constants> diff --git a/doc/classes/Light2D.xml b/doc/classes/Light2D.xml index 1386fc53d9..cc1882c7a4 100644 --- a/doc/classes/Light2D.xml +++ b/doc/classes/Light2D.xml @@ -340,46 +340,67 @@ </methods> <members> <member name="color" type="Color" setter="set_color" getter="get_color"> + The Light2D's [Color]. </member> <member name="editor_only" type="bool" setter="set_editor_only" getter="is_editor_only"> + If [code]true[/code] Light2D will only appear when editing the scene. Default value: [code]false[/code]. </member> <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled"> + If [code]true[/code] Light2D will emit light. Default value: [code]true[/code]. </member> <member name="energy" type="float" setter="set_energy" getter="get_energy"> + The Light2D's energy value. The larger the value, the stronger the light. </member> <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="Light2D.Mode"> + The Light2D's mode. See MODE_* constants for values. </member> <member name="offset" type="Vector2" setter="set_texture_offset" getter="get_texture_offset"> + The offset of the Light2D's [code]texture[/code]. </member> <member name="range_height" type="float" setter="set_height" getter="get_height"> + The height of the Light2D. Used with 2D normal mapping. </member> <member name="range_item_cull_mask" type="int" setter="set_item_cull_mask" getter="get_item_cull_mask"> + The layer mask. Only objects with a matching mask will be affected by the Light2D. </member> <member name="range_layer_max" type="int" setter="set_layer_range_max" getter="get_layer_range_max"> + Maximum layer value of objects that are affected by the Light2D. Default value: [code]0[/code]. </member> <member name="range_layer_min" type="int" setter="set_layer_range_min" getter="get_layer_range_min"> + Minimum layer value of objects that are affected by the Light2D. Default value: [code]0[/code]. </member> <member name="range_z_max" type="int" setter="set_z_range_max" getter="get_z_range_max"> + Maximum [code]Z[/code] value of objects that are affected by the Light2D. Default value: [code]1024[/code]. </member> <member name="range_z_min" type="int" setter="set_z_range_min" getter="get_z_range_min"> + Minimum [code]z[/code] value of objects that are affected by the Light2D. Default value: [code]-1024[/code]. </member> <member name="shadow_buffer_size" type="int" setter="set_shadow_buffer_size" getter="get_shadow_buffer_size"> + Shadow buffer size. Default value: [code]2048[/code]. </member> <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color"> + [Color] of shadows cast by the Light2D. </member> <member name="shadow_enabled" type="bool" setter="set_shadow_enabled" getter="is_shadow_enabled"> + If [code]true[/code] the Light2D will cast shadows. Default value: [code]false[/code]. </member> <member name="shadow_filter" type="int" setter="set_shadow_filter" getter="get_shadow_filter" enum="Light2D.ShadowFilter"> + Shadow filter type. May be one of [code][None, PCF5, PCF9, PCF13][/code]. Default value: [code]None[/code]. </member> <member name="shadow_filter_smooth" type="float" setter="set_shadow_smooth" getter="get_shadow_smooth"> + Smoothing value for shadows. </member> <member name="shadow_gradient_length" type="float" setter="set_shadow_gradient_length" getter="get_shadow_gradient_length"> + Smooth shadow gradient length. </member> <member name="shadow_item_cull_mask" type="int" setter="set_item_shadow_cull_mask" getter="get_item_shadow_cull_mask"> + The shadow mask. Used with [LightOccluder2D] to cast shadows. Only occluders with a matching shadow mask will cast shadows. </member> <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> + [Texture] used for the Light2D's appearance. </member> <member name="texture_scale" type="float" setter="set_texture_scale" getter="get_texture_scale"> + The [code]texture[/code]'s scale factor. </member> </members> <constants> diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index b3fd6fa2a0..8669c42a7a 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -806,7 +806,7 @@ public: void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows); - _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_passs); + _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass); _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass); diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 344cb87aa6..9797a2e9f5 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -54,12 +54,7 @@ void CreateDialog::popup_create(bool p_dontclear) { TreeItem *ti = recent->create_item(root); ti->set_text(0, l); - if (has_icon(l, "EditorIcons")) { - - ti->set_icon(0, get_icon(l, "EditorIcons")); - } else { - ti->set_icon(0, get_icon("Object", "EditorIcons")); - } + ti->set_icon(0, _get_editor_icon(l)); } } @@ -122,6 +117,29 @@ void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) { } } +Ref<Texture> CreateDialog::_get_editor_icon(const String &p_type) const { + + if (has_icon(p_type, "EditorIcons")) { + return get_icon(p_type, "EditorIcons"); + } + + const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types(); + for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) { + const Vector<EditorData::CustomType> &ct = E->value(); + for (int i = 0; i < ct.size(); ++i) { + if (ct[i].name == p_type) { + if (ct[i].icon.is_valid()) { + return ct[i].icon; + } else { + return get_icon("Object", "EditorIcons"); + } + } + } + } + + return get_icon("Object", "EditorIcons"); +} + void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select) { if (p_types.has(p_type)) @@ -457,13 +475,7 @@ void CreateDialog::_update_favorite_list() { TreeItem *ti = favorites->create_item(root); String l = favorite_list[i]; ti->set_text(0, l); - - if (has_icon(l, "EditorIcons")) { - - ti->set_icon(0, get_icon(l, "EditorIcons")); - } else { - ti->set_icon(0, get_icon("Object", "EditorIcons")); - } + ti->set_icon(0, _get_editor_icon(l)); } } diff --git a/editor/create_dialog.h b/editor/create_dialog.h index 31f106ea22..a523539ba0 100644 --- a/editor/create_dialog.h +++ b/editor/create_dialog.h @@ -74,6 +74,8 @@ class CreateDialog : public ConfirmationDialog { void _confirmed(); void _text_changed(const String &p_newtext); + Ref<Texture> _get_editor_icon(const String &p_type) const; + void add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select); Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp index cfb3abfd1d..658c12d4d0 100644 --- a/editor/editor_dir_dialog.cpp +++ b/editor/editor_dir_dialog.cpp @@ -64,7 +64,7 @@ void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p } } -void EditorDirDialog::reload(const String &p_with_path) { +void EditorDirDialog::reload(const String &p_path) { if (!is_visible_in_tree()) { must_reload = true; @@ -73,7 +73,7 @@ void EditorDirDialog::reload(const String &p_with_path) { tree->clear(); TreeItem *root = tree->create_item(); - _update_dir(root, EditorFileSystem::get_singleton()->get_filesystem(), p_with_path); + _update_dir(root, EditorFileSystem::get_singleton()->get_filesystem(), p_path); _item_collapsed(root); must_reload = false; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 3f0520379a..d7cce71b90 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2780,14 +2780,6 @@ Dictionary EditorNode::_get_main_scene_state() { state["property_edit_offset"] = get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_value(); state["saved_version"] = saved_version; state["node_filter"] = scene_tree_dock->get_filter(); - int current = -1; - for (int i = 0; i < editor_table.size(); i++) { - if (editor_plugin_screen == editor_table[i]) { - current = i; - break; - } - } - state["editor_index"] = current; return state; } @@ -2798,29 +2790,32 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { changing_scene = false; - if (p_state.has("editor_index")) { - - int index = p_state["editor_index"]; - int current = -1; - for (int i = 0; i < editor_table.size(); i++) { - if (editor_plugin_screen == editor_table[i]) { - current = i; - break; - } + int current = -1; + for (int i = 0; i < editor_table.size(); i++) { + if (editor_plugin_screen == editor_table[i]) { + current = i; + break; } + } + if (p_state.has("editor_index")) { + int index = p_state["editor_index"]; if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if curently in script, stay there if (index < 2 || !get_edited_scene()) { _editor_select(index); - } else { - //use heuristic instead - int n2d = 0, n3d = 0; - _find_node_types(get_edited_scene(), n2d, n3d); - if (n2d > n3d) { - _editor_select(EDITOR_2D); - } else if (n3d > n2d) { - _editor_select(EDITOR_3D); - } + } + } + } + + if (get_edited_scene()) { + if (current < 2) { + //use heuristic instead + int n2d = 0, n3d = 0; + _find_node_types(get_edited_scene(), n2d, n3d); + if (n2d > n3d) { + _editor_select(EDITOR_2D); + } else if (n3d > n2d) { + _editor_select(EDITOR_3D); } } } @@ -3343,9 +3338,9 @@ void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog) { Vector<EditorNodeInitCallback> EditorNode::_init_callbacks; -Error EditorNode::export_preset(const String &preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after) { +Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after) { - export_defer.preset = preset; + export_defer.preset = p_preset; export_defer.path = p_path; export_defer.debug = p_debug; export_defer.password = p_password; @@ -4854,7 +4849,7 @@ EditorNode::EditorNode() { scene_root_parent = memnew(PanelContainer); scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE); scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles")); - + scene_root_parent->set_draw_behind_parent(true); srt->add_child(scene_root_parent); scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL); diff --git a/editor/editor_node.h b/editor/editor_node.h index f1cdb7b892..33031e5634 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -715,7 +715,7 @@ public: void show_warning(const String &p_text, const String &p_title = "Warning!"); - Error export_preset(const String &p_platform, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after = false); + Error export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after = false); static void register_editor_types(); static void unregister_editor_types(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index a03eee4687..0cba024595 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -369,6 +369,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Tabs Ref<StyleBoxFlat> style_tab_selected = style_default->duplicate(); + style_tab_selected->set_border_width_all(border_width); + style_tab_selected->set_border_width(MARGIN_BOTTOM, 0); + style_tab_selected->set_border_color_all(dark_color_3); + style_tab_selected->set_expand_margin_size(MARGIN_BOTTOM, border_width); style_tab_selected->set_default_margin(MARGIN_LEFT, 10 * EDSCALE); style_tab_selected->set_default_margin(MARGIN_RIGHT, 10 * EDSCALE); style_tab_selected->set_bg_color(tab_color); @@ -435,19 +439,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border); - // Content of each tab - Ref<StyleBoxFlat> style_content_panel = style_default->duplicate(); - style_content_panel->set_border_color_all(base_color); - - // this is the stylebox used in 3d and 2d viewports (no borders) - Ref<StyleBoxFlat> style_content_panel_vp = style_content_panel->duplicate(); - style_content_panel_vp->set_default_margin(MARGIN_LEFT, border_width); - style_content_panel_vp->set_default_margin(MARGIN_TOP, default_margin_size); - style_content_panel_vp->set_default_margin(MARGIN_RIGHT, border_width); - style_content_panel_vp->set_default_margin(MARGIN_BOTTOM, border_width); - theme->set_stylebox("panel", "TabContainer", style_content_panel); - theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp); - // Buttons theme->set_stylebox("normal", "Button", style_widget); theme->set_stylebox("hover", "Button", style_widget_hover); @@ -608,6 +599,20 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("button_pressed", "Tabs", style_menu); theme->set_stylebox("button", "Tabs", style_menu); + // Content of each tab + Ref<StyleBoxFlat> style_content_panel = style_default->duplicate(); + style_content_panel->set_border_color_all(dark_color_3); + style_content_panel->set_border_width_all(border_width); + + // this is the stylebox used in 3d and 2d viewports (no borders) + Ref<StyleBoxFlat> style_content_panel_vp = style_content_panel->duplicate(); + style_content_panel_vp->set_default_margin(MARGIN_LEFT, border_width); + style_content_panel_vp->set_default_margin(MARGIN_TOP, default_margin_size); + style_content_panel_vp->set_default_margin(MARGIN_LEFT, border_width); + style_content_panel_vp->set_default_margin(MARGIN_BOTTOM, border_width); + theme->set_stylebox("panel", "TabContainer", style_content_panel); + theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp); + // Separators (no separators) theme->set_stylebox("separator", "HSeparator", make_line_stylebox(separator_color, border_width)); theme->set_stylebox("separator", "VSeparator", make_line_stylebox(separator_color, border_width, 0, true)); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index a483c3776f..652977b98a 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -119,7 +119,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animation, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); + void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index ad01d0a31e..b28da54c6d 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -845,6 +845,8 @@ void CanvasItemEditor::_prepare_drag(const Point2 &p_click_pos) { se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot(); if (Object::cast_to<Control>(canvas_item)) se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset(); + + se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); } if (selection.size() == 1 && Object::cast_to<Node2D>(selection[0])) { @@ -1411,6 +1413,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot(); if (Object::cast_to<Control>(canvas_item)) se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset(); + se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); return; } @@ -1432,6 +1435,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot(); if (Object::cast_to<Control>(canvas_item)) se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset(); + se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); return; } @@ -1441,6 +1445,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { if (drag != DRAG_NONE) { drag_from = transform.affine_inverse().xform(click); se->undo_state = canvas_item->edit_get_state(); + se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); return; } } @@ -1993,6 +1998,23 @@ void CanvasItemEditor::_viewport_draw() { Rect2 rect = canvas_item->get_item_rect(); + if (drag != DRAG_NONE && drag != DRAG_PIVOT) { + const Transform2D pre_drag_xform = transform * se->pre_drag_xform; + const Color pre_drag_color = Color(0.4, 0.6, 1, 0.7); + + Vector2 pre_drag_endpoints[4] = { + + pre_drag_xform.xform(rect.position), + pre_drag_xform.xform(rect.position + Vector2(rect.size.x, 0)), + pre_drag_xform.xform(rect.position + rect.size), + pre_drag_xform.xform(rect.position + Vector2(0, rect.size.y)) + }; + + for (int i = 0; i < 4; i++) { + viewport->draw_line(pre_drag_endpoints[i], pre_drag_endpoints[(i + 1) % 4], pre_drag_color, 2); + } + } + Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); VisualServer::get_singleton()->canvas_item_add_set_transform(ci, xform); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 2e1a2eac5f..f61bfc9ebb 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -58,6 +58,8 @@ public: Vector2 prev_pivot; float prev_anchors[4]; + Transform2D pre_drag_xform; + CanvasItemEditorSelectedItem() { prev_rot = 0; } }; @@ -315,7 +317,7 @@ class CanvasItemEditor : public VBoxContainer { void _prepare_drag(const Point2 &p_click_pos); DragType _get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point); - float _anchor_snap(float anchor, bool *snapped = NULL, float p_opposite_anchor = -1); + float _anchor_snap(float p_anchor, bool *p_snapped = NULL, float p_opposite_anchor = -1); Vector2 _anchor_to_position(Control *p_control, Vector2 anchor); Vector2 _position_to_anchor(Control *p_control, Vector2 position); diff --git a/editor/plugins/navigation_mesh_editor_plugin.h b/editor/plugins/navigation_mesh_editor_plugin.h index 3009e2addc..bac7f608ab 100644 --- a/editor/plugins/navigation_mesh_editor_plugin.h +++ b/editor/plugins/navigation_mesh_editor_plugin.h @@ -56,7 +56,7 @@ class NavigationMeshEditor : public Control { protected: void _node_removed(Node *p_node); static void _bind_methods(); - void _notification(int p_what); + void _notification(int p_option); public: void edit(NavigationMeshInstance *p_nav_mesh_instance); @@ -74,8 +74,8 @@ class NavigationMeshEditorPlugin : public EditorPlugin { public: virtual String get_name() const { return "NavigationMesh"; } bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; + virtual void edit(Object *p_object); + virtual bool handles(Object *p_object) const; virtual void make_visible(bool p_visible); NavigationMeshEditorPlugin(EditorNode *p_node); diff --git a/editor/plugins/navigation_mesh_generator.h b/editor/plugins/navigation_mesh_generator.h index 48e7dfe53f..0a1c497f8f 100644 --- a/editor/plugins/navigation_mesh_generator.h +++ b/editor/plugins/navigation_mesh_generator.h @@ -56,7 +56,7 @@ protected: rcPolyMeshDetail *detail_mesh, Vector<float> &verticies, Vector<int> &indices); public: - static void bake(Ref<NavigationMesh> p_nav_mesh, Node *p_base); + static void bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node); static void clear(Ref<NavigationMesh> p_nav_mesh); }; diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 43856116a6..b85ffd6c67 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -72,6 +72,14 @@ void TileMapEditor::_menu_option(int p_option) { switch (p_option) { + case OPTION_PAINTING: { + // NOTE: We do not set tool = TOOL_PAINTING as this begins painting + // immediately without pressing the left mouse button first + tool = TOOL_NONE; + + canvas_item_editor->update(); + + } break; case OPTION_BUCKET: { tool = TOOL_BUCKET; @@ -703,7 +711,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return true; } else { - + // Mousebutton was released if (tool != TOOL_NONE) { if (tool == TOOL_PAINTING) { @@ -801,6 +809,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { undo_redo->add_undo_method(this, "_fill_points", points, pop); undo_redo->commit_action(); + + // We want to keep the bucket-tool active + return true; } tool = TOOL_NONE; @@ -1046,9 +1057,25 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return true; } - if (tool != TOOL_NONE || !mouse_over) + if (!mouse_over) { + // Editor shortcuts should not fire if mouse not in viewport return false; + } + if (ED_IS_SHORTCUT("tile_map_editor/paint_tile", p_event)) { + // NOTE: We do not set tool = TOOL_PAINTING as this begins painting + // immediately without pressing the left mouse button first + tool = TOOL_NONE; + canvas_item_editor->update(); + + return true; + } + if (ED_IS_SHORTCUT("tile_map_editor/bucket_fill", p_event)) { + tool = TOOL_BUCKET; + canvas_item_editor->update(); + + return true; + } if (ED_IS_SHORTCUT("tile_map_editor/erase_selection", p_event)) { _menu_option(OPTION_ERASE_SELECTION); @@ -1458,7 +1485,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase selection"), KEY_DELETE); ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find tile"), KEY_MASK_CMD + KEY_F); - ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose")); + ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose"), KEY_T); ED_SHORTCUT("tile_map_editor/mirror_x", TTR("Mirror X"), KEY_A); ED_SHORTCUT("tile_map_editor/mirror_y", TTR("Mirror Y"), KEY_S); @@ -1512,7 +1539,8 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { PopupMenu *p = options->get_popup(); - p->add_item(TTR("Bucket"), OPTION_BUCKET); + p->add_shortcut(ED_SHORTCUT("tile_map_editor/paint_tile", TTR("Paint Tile"), KEY_P), OPTION_PAINTING); + p->add_shortcut(ED_SHORTCUT("tile_map_editor/bucket_fill", TTR("Bucket Fill"), KEY_G), OPTION_BUCKET); p->add_separator(); p->add_item(TTR("Pick Tile"), OPTION_PICK_TILE, KEY_CONTROL); p->add_separator(); diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index e863c4bf3d..de9b9e8e0d 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -68,7 +68,8 @@ class TileMapEditor : public VBoxContainer { OPTION_PICK_TILE, OPTION_SELECT, OPTION_DUPLICATE, - OPTION_ERASE_SELECTION + OPTION_ERASE_SELECTION, + OPTION_PAINTING, }; TileMap *node; diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h index 6cb5f0a70c..64ac2535a9 100644 --- a/editor/script_editor_debugger.h +++ b/editor/script_editor_debugger.h @@ -150,7 +150,7 @@ class ScriptEditorDebugger : public Control { void _scene_tree_selected(); void _scene_tree_request(); void _parse_message(const String &p_msg, const Array &p_data); - void _set_reason_text(const String &p_msg, MessageType p_type); + void _set_reason_text(const String &p_reason, MessageType p_type); void _scene_tree_property_select_object(ObjectID p_object); void _scene_tree_property_value_edited(const String &p_prop, const Variant &p_value); diff --git a/modules/regex/regex.h b/modules/regex/regex.h index 0d97bcce54..bfa9c84042 100644 --- a/modules/regex/regex.h +++ b/modules/regex/regex.h @@ -87,8 +87,8 @@ public: Error compile(const String &p_pattern); void _init(const String &p_pattern = ""); - Ref<RegExMatch> search(const String &p_subject, int offset = 0, int end = -1) const; - String sub(const String &p_subject, const String &p_replacement, bool p_all = false, int p_start = 0, int p_end = -1) const; + Ref<RegExMatch> search(const String &p_subject, int p_offset = 0, int p_end = -1) const; + String sub(const String &p_subject, const String &p_replacement, bool p_all = false, int p_offset = 0, int p_end = -1) const; bool is_valid() const; String get_pattern() const; diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index c575edbba3..e27452354b 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -128,13 +128,13 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t return OK; } -Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *svg_str, float p_scale, bool upsample, bool convert_colors) { +Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, bool convert_colors) { - size_t str_len = strlen(svg_str); + size_t str_len = strlen(p_svg_str); PoolVector<uint8_t> src_data; src_data.resize(str_len + 1); PoolVector<uint8_t>::Write src_w = src_data.write(); - memcpy(src_w.ptr(), svg_str, str_len + 1); + memcpy(src_w.ptr(), p_svg_str, str_len + 1); return _create_image(p_image, &src_data, p_scale, upsample, convert_colors); } @@ -160,4 +160,4 @@ void ImageLoaderSVG::get_recognized_extensions(List<String> *p_extensions) const ImageLoaderSVG::ImageLoaderSVG() { } -ImageLoaderSVG::ReplaceColors ImageLoaderSVG::replace_colors;
\ No newline at end of file +ImageLoaderSVG::ReplaceColors ImageLoaderSVG::replace_colors; diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h index 332ac214a5..cf44cd8c50 100644 --- a/modules/svg/image_loader_svg.h +++ b/modules/svg/image_loader_svg.h @@ -57,7 +57,7 @@ class ImageLoaderSVG : public ImageFormatLoader { List<uint32_t> new_colors; } replace_colors; static SVGRasterizer rasterizer; - static void _convert_colors(NSVGimage *p_svg_imge); + static void _convert_colors(NSVGimage *p_svg_image); static Error _create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors = false); public: diff --git a/scene/3d/light.h b/scene/3d/light.h index 6aa0220265..2f3ac8a5e7 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -150,7 +150,7 @@ public: void set_shadow_mode(ShadowMode p_mode); ShadowMode get_shadow_mode() const; - void set_shadow_depth_range(ShadowDepthRange p_mode); + void set_shadow_depth_range(ShadowDepthRange p_range); ShadowDepthRange get_shadow_depth_range() const; void set_blend_splits(bool p_enable); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index ab2c2f445f..71b9c4ec72 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -540,14 +540,6 @@ void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int it = _get_next_item(it); - if (p_mode == PROCESS_POINTER && r_click_item && itp && !it && p_click_pos.y > p_ofs.y + y + lh) { - //at the end of all, return this - if (r_outside) *r_outside = true; - *r_click_item = itp; - *r_click_char = rchar; - return; - } - if (it && (p_line + 1 < p_frame->lines.size()) && p_frame->lines[p_line + 1].from == it) { if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh) { diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 657e8590d4..98a8db336e 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -208,6 +208,9 @@ void TabContainer::_notification(int p_what) { break; } + // Draw the tab area. + panel->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height)); + // Draw all visible tabs. int x = 0; for (int i = 0; i < tab_widths.size(); i++) { @@ -280,9 +283,6 @@ void TabContainer::_notification(int p_what) { Point2(x, y_center - (decrement->get_height() / 2)), Color(1, 1, 1, first_tab_cache > 0 ? 1.0 : 0.5)); } - - // Draw the tab area. - panel->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height)); } break; case NOTIFICATION_THEME_CHANGED: { if (get_tab_count() > 0) { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index dc5e4d1010..db6d257640 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2800,11 +2800,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { int ini = selection.from_line; int end = selection.to_line; for (int i = ini; i <= end; i++) { - if (text[i][0] == '#') + if (get_line(i).begins_with("#")) _remove_text(i, 0, i, 1); } } else { - if (text[cursor.line][0] == '#') + if (get_line(cursor.line).begins_with("#")) _remove_text(cursor.line, 0, cursor.line, 1); } update(); diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp index 9af8c42110..2ef20f67f5 100644 --- a/scene/resources/sky_box.cpp +++ b/scene/resources/sky_box.cpp @@ -419,10 +419,10 @@ void ProceduralSky::_queue_update() { call_deferred("_update_sky"); } -void ProceduralSky::_thread_done(const Ref<Image> &image) { +void ProceduralSky::_thread_done(const Ref<Image> &p_image) { - VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT); - VS::get_singleton()->texture_set_data(texture, image); + VS::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT); + VS::get_singleton()->texture_set_data(texture, p_image); _radiance_changed(); Thread::wait_to_finish(sky_thread); memdelete(sky_thread); diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 3d085f7166..4627c900ff 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -178,7 +178,7 @@ public: void set_border_width_all(int p_size); int get_border_width_min() const; - void set_border_width(Margin p_margin, int p_size); + void set_border_width(Margin p_margin, int p_width); int get_border_width(Margin p_margin) const; //blend @@ -214,7 +214,7 @@ public: int get_shadow_size() const; //ANTI_ALIASING - void set_anti_aliased(const bool &p_anit_aliasing); + void set_anti_aliased(const bool &p_anti_aliased); bool is_anti_aliased() const; //tempAA void set_aa_size(const int &p_aa_size); diff --git a/servers/physics/broad_phase_basic.h b/servers/physics/broad_phase_basic.h index 51a24f4678..5c124c1792 100644 --- a/servers/physics/broad_phase_basic.h +++ b/servers/physics/broad_phase_basic.h @@ -82,7 +82,7 @@ class BroadPhaseBasic : public BroadPhaseSW { public: // 0 is an invalid ID - virtual ID create(CollisionObjectSW *p_object_, int p_subindex = 0); + virtual ID create(CollisionObjectSW *p_object, int p_subindex = 0); virtual void move(ID p_id, const Rect3 &p_aabb); virtual void set_static(ID p_id, bool p_static); virtual void remove(ID p_id); diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 779f0d54ac..8f22d1cd44 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -518,7 +518,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co body_aabb = body_aabb.grow(p_margin); static const int max_excluded_shape_pairs = 32; - Pair<Shape2DSW *, Shape2DSW *> excluded_shape_pairs[max_excluded_shape_pairs]; + ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs]; int excluded_shape_pair_count = 0; Transform2D body_transform = p_from; @@ -577,7 +577,11 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co if (!collided && cbk.invalid_by_dir > 0) { //this shape must be excluded if (excluded_shape_pair_count < max_excluded_shape_pairs) { - excluded_shape_pairs[excluded_shape_pair_count++] = Pair<Shape2DSW *, Shape2DSW *>(body_shape, against_shape); + ExcludedShapeSW esp; + esp.local_shape = body_shape; + esp.against_object = col_obj; + esp.against_shape_index = shape_idx; + excluded_shape_pairs[excluded_shape_pair_count++] = esp; } } } @@ -645,7 +649,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co for (int k = 0; k < excluded_shape_pair_count; k++) { - if (excluded_shape_pairs[k].first == body_shape && excluded_shape_pairs[k].second == against_shape) { + if (excluded_shape_pairs[k].local_shape == body_shape && excluded_shape_pairs[k].against_object == col_obj && excluded_shape_pairs[k].against_shape_index == shape_idx) { excluded = true; break; } @@ -776,7 +780,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co bool excluded = false; for (int k = 0; k < excluded_shape_pair_count; k++) { - if (excluded_shape_pairs[k].first == body_shape && excluded_shape_pairs[k].second == against_shape) { + if (excluded_shape_pairs[k].local_shape == body_shape && excluded_shape_pairs[k].against_object == col_obj && excluded_shape_pairs[k].against_shape_index == shape_idx) { excluded = true; break; } diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index ed6136e372..c7e7497397 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -71,6 +71,12 @@ public: }; private: + struct ExcludedShapeSW { + Shape2DSW *local_shape; + const CollisionObject2DSW *against_object; + int against_shape_index; + }; + uint64_t elapsed_time[ELAPSED_TIME_MAX]; Physics2DDirectSpaceStateSW *direct_access; |