diff options
Diffstat (limited to 'core')
37 files changed, 1690 insertions, 314 deletions
diff --git a/core/array.cpp b/core/array.cpp index 23792f90fc..683a43e3d0 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -276,16 +276,26 @@ void Array::push_front(const Variant& p_value) { _p->array.insert(0,p_value); } -void Array::pop_back(){ +Variant Array::pop_back(){ - if (!_p->array.empty()) - _p->array.resize( _p->array.size() -1 ); + if (!_p->array.empty()) { + int n = _p->array.size() - 1; + Variant ret = _p->array.get(n); + _p->array.resize(n); + return ret; + } + return Variant(); } -void Array::pop_front(){ - if (!_p->array.empty()) +Variant Array::pop_front(){ + + if (!_p->array.empty()) { + Variant ret = _p->array.get(0); _p->array.remove(0); + return ret; + } + return Variant(); } diff --git a/core/array.h b/core/array.h index dfc902525c..eb79b0cf33 100644 --- a/core/array.h +++ b/core/array.h @@ -80,8 +80,8 @@ public: void erase(const Variant& p_value); void push_front(const Variant& p_value); - void pop_back(); - void pop_front(); + Variant pop_back(); + Variant pop_front(); Array(const Array& p_from); Array(bool p_shared=false); diff --git a/core/dvector.h b/core/dvector.h index a5519ed604..9a54641617 100644 --- a/core/dvector.h +++ b/core/dvector.h @@ -262,6 +262,34 @@ public: w[bs+i]=r[i]; } + DVector<T> subarray(int p_from, int p_to) { + + if (p_from<0) { + p_from=size()+p_from; + } + if (p_to<0) { + p_to=size()+p_to; + } + if (p_from<0 || p_from>=size()) { + DVector<T>& aux=*((DVector<T>*)0); // nullreturn + ERR_FAIL_COND_V(p_from<0 || p_from>=size(),aux) + } + if (p_to<0 || p_to>=size()) { + DVector<T>& aux=*((DVector<T>*)0); // nullreturn + ERR_FAIL_COND_V(p_to<0 || p_to>=size(),aux) + } + + DVector<T> slice; + int span=1 + p_to - p_from; + slice.resize(span); + Read r = read(); + Write w = slice.write(); + for (int i=0; i<span; ++i) { + w[i] = r[p_from+i]; + } + + return slice; + } Error insert(int p_pos,const T& p_val) { diff --git a/core/func_ref.cpp b/core/func_ref.cpp index 644d8b5b63..ca890111be 100644 --- a/core/func_ref.cpp +++ b/core/func_ref.cpp @@ -61,11 +61,7 @@ void FuncRef::_bind_methods() { MethodInfo mi; mi.name="call_func"; Vector<Variant> defargs; - for(int i=0;i<10;i++) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_func:Variant",&FuncRef::call_func,mi,defargs); + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call_func:Variant",&FuncRef::call_func,mi,defargs); } diff --git a/core/image.cpp b/core/image.cpp index d6ac3f28ea..90051d7d0d 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -2052,6 +2052,7 @@ Error Image::_decompress_bc() { ht/=2; } break; + default: {} } } diff --git a/core/input_map.cpp b/core/input_map.cpp index 08ee8138a3..09cb7ce426 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -232,62 +232,8 @@ bool InputMap::event_is_action(const InputEvent& p_event, const StringName& p_ac return _find_event(E->get().inputs,p_event)!=NULL; } -bool InputMap::event_is_joy_motion_action_pressed(const InputEvent& p_event) const { - - ERR_FAIL_COND_V(p_event.type!=InputEvent::JOYSTICK_MOTION,false); - bool pressed=false; - - //this could be optimized by having a separate list of joymotions? - - for (Map<StringName, Action>::Element *A=input_map.front();A;A=A->next()) { - - for (List<InputEvent>::Element *E=A->get().inputs.front();E;E=E->next()) { - - const InputEvent& e=E->get(); - if(e.type!=p_event.type) - continue; - if (e.type!=InputEvent::KEY && e.device!=p_event.device) - continue; - - switch(p_event.type) { - - case InputEvent::KEY: { - - if (e.key.scancode==p_event.key.scancode && e.key.mod == p_event.key.mod) - return e.key.pressed; - - } break; - case InputEvent::JOYSTICK_BUTTON: { - - if (e.joy_button.button_index==p_event.joy_button.button_index) { - return e.joy_button.pressed; - } - - } break; - case InputEvent::MOUSE_BUTTON: { - - if (e.mouse_button.button_index==p_event.mouse_button.button_index) { - return e.mouse_button.pressed; - } - - } break; - case InputEvent::JOYSTICK_MOTION: { - - if (e.joy_motion.axis==p_event.joy_motion.axis) { - if ( - (e.joy_motion.axis_value * p_event.joy_motion.axis_value >0) && //same axis - ABS(e.joy_motion.axis_value)>0.5 && ABS(p_event.joy_motion.axis_value)>0.5 ) - pressed=true; - } - - } break; - } - - } - } - - return pressed; - +const Map<StringName, InputMap::Action>& InputMap::get_action_map() const { + return input_map; } void InputMap::load_from_globals() { diff --git a/core/input_map.h b/core/input_map.h index dc5a911963..21c479588d 100644 --- a/core/input_map.h +++ b/core/input_map.h @@ -35,12 +35,14 @@ class InputMap : public Object { OBJ_TYPE( InputMap, Object ); - static InputMap *singleton; - +public: struct Action { int id; List<InputEvent> inputs; }; +private: + static InputMap *singleton; + mutable Map<StringName, Action> input_map; mutable Map<int,StringName> input_id_map; @@ -70,9 +72,8 @@ public: const List<InputEvent> *get_action_list(const StringName& p_action); bool event_is_action(const InputEvent& p_event, const StringName& p_action) const; - bool event_is_joy_motion_action_pressed(const InputEvent& p_event) const; - + const Map<StringName, Action>& get_action_map() const; void load_from_globals(); void load_default(); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 5c8c741f28..1632b841c6 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -409,6 +409,8 @@ Error DirAccessPack::change_dir(String p_dir) { nd=nd.simplify_path(); + if (nd == "") nd = "."; + if (nd.begins_with("/")) { nd=nd.replace_first("/","") ; absolute=true; diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp new file mode 100644 index 0000000000..04b88ea028 --- /dev/null +++ b/core/io/pck_packer.cpp @@ -0,0 +1,191 @@ +/*************************************************************************/ +/* pkc_packer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "pck_packer.h" + +#include "core/os/file_access.h" + +static uint64_t _align(uint64_t p_n, int p_alignment) { + + if (p_alignment == 0) + return p_n; + + uint64_t rest = p_n % p_alignment; + if (rest == 0) + return p_n; + else + return p_n + (p_alignment - rest); +}; + +static void _pad(FileAccess* p_file, int p_bytes) { + + for (int i=0; i<p_bytes; i++) { + + p_file->store_8(0); + }; +}; + +void PCKPacker::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("pck_start","pck_name","alignment"),&PCKPacker::pck_start); + ObjectTypeDB::bind_method(_MD("add_file","pck_path","source_path"),&PCKPacker::add_file); + ObjectTypeDB::bind_method(_MD("flush","verbose"),&PCKPacker::flush); +}; + + +Error PCKPacker::pck_start(const String& p_file, int p_alignment) { + + file = FileAccess::open(p_file, FileAccess::WRITE); + if (file == NULL) { + + return ERR_CANT_CREATE; + }; + + alignment = p_alignment; + + file->store_32(0x43504447); // MAGIC + file->store_32(0); // # version + file->store_32(0); // # major + file->store_32(0); // # minor + file->store_32(0); // # revision + + for (int i=0; i<16; i++) { + + file->store_32(0); // reserved + }; + + files.clear(); + + return OK; +}; + +Error PCKPacker::add_file(const String& p_file, const String& p_src) { + + FileAccess* f = FileAccess::open(p_src, FileAccess::READ); + if (!f) { + return ERR_FILE_CANT_OPEN; + }; + + File pf; + pf.path = p_file; + pf.src_path = p_src; + pf.size = f->get_len(); + pf.offset_offset = 0; + + files.push_back(pf); + + f->close(); + memdelete(f); + + return OK; +}; + +Error PCKPacker::flush(bool p_verbose) { + + if (!file) { + ERR_FAIL_COND_V(!file, ERR_INVALID_PARAMETER); + return ERR_INVALID_PARAMETER; + }; + + // write the index + + file->store_32(files.size()); + + for (int i=0; i<files.size(); i++) { + + file->store_pascal_string(files[i].path); + files[i].offset_offset = file->get_pos(); + file->store_64(0); // offset + file->store_64(files[i].size); // size + + // # empty md5 + file->store_32(0); + file->store_32(0); + file->store_32(0); + file->store_32(0); + }; + + + uint64_t ofs = file->get_pos(); + ofs = _align(ofs, alignment); + + _pad(file, ofs - file->get_pos()); + + const uint32_t buf_max = 65536; + uint8_t *buf = memnew_arr(uint8_t, buf_max); + + int count = 0; + for (int i=0; i<files.size(); i++) { + + FileAccess* src = FileAccess::open(files[i].src_path, FileAccess::READ); + uint64_t to_write = files[i].size; + while (to_write > 0) { + + int read = src->get_buffer(buf, MIN(to_write, buf_max)); + file->store_buffer(buf, read); + to_write -= read; + }; + + uint64_t pos = file->get_pos(); + file->seek(files[i].offset_offset); // go back to store the file's offset + file->store_64(ofs); + file->seek(pos); + + ofs = _align(ofs + files[i].size, alignment); + _pad(file, ofs - pos); + + src->close(); + memdelete(src); + count += 1; + if (p_verbose) { + if (count % 100 == 0) { + printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100); + fflush(stdout); + }; + }; + }; + + if (p_verbose) + printf("\n"); + + file->close(); + + return OK; +}; + +PCKPacker::PCKPacker() { + + file = NULL; +}; + +PCKPacker::~PCKPacker() { + if (file != NULL) { + memdelete(file); + }; + file = NULL; +}; diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h new file mode 100644 index 0000000000..b1182335e2 --- /dev/null +++ b/core/io/pck_packer.h @@ -0,0 +1,59 @@ +/*************************************************************************/ +/* pck_packer.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "core/reference.h" + +class FileAccess; + +class PCKPacker : public Reference { + + OBJ_TYPE(PCKPacker, Reference); + + FileAccess* file; + int alignment; + + static void _bind_methods(); + + struct File { + + String path; + String src_path; + int size; + uint64_t offset_offset; + }; + Vector<File> files; + +public: + Error pck_start(const String& p_file, int p_alignment); + Error add_file(const String& p_file, const String& p_src); + Error flush(bool p_verbose = false); + + + PCKPacker(); + ~PCKPacker(); +}; diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp new file mode 100644 index 0000000000..5bbbbdaa5a --- /dev/null +++ b/core/math/a_star.cpp @@ -0,0 +1,412 @@ +#include "a_star.h" +#include "geometry.h" + + +int AStar::get_available_point_id() const { + + if (points.empty()) { + return 1; + } + + return points.back()->key()+1; +} + +void AStar::add_point(int p_id, const Vector3 &p_pos, float p_weight_scale) { + ERR_FAIL_COND(p_id<0); + if (!points.has(p_id)) { + Point *pt = memnew( Point ); + pt->id=p_id; + pt->pos=p_pos; + pt->weight_scale=p_weight_scale; + pt->prev_point=NULL; + pt->last_pass=0; + points[p_id]=pt; + } else { + points[p_id]->pos=p_pos; + points[p_id]->weight_scale=p_weight_scale; + } +} + +Vector3 AStar::get_point_pos(int p_id) const{ + + ERR_FAIL_COND_V(!points.has(p_id),Vector3()); + + return points[p_id]->pos; + +} +float AStar::get_point_weight_scale(int p_id) const{ + + ERR_FAIL_COND_V(!points.has(p_id),0); + + return points[p_id]->weight_scale; + +} +void AStar::remove_point(int p_id){ + + ERR_FAIL_COND(!points.has(p_id)); + + Point* p = points[p_id]; + + for(int i=0;i<p->neighbours.size();i++) { + + Segment s(p_id,p->neighbours[i]->id); + segments.erase(s); + p->neighbours[i]->neighbours.erase(p); + } + + memdelete(p); + points.erase(p_id); +} + +void AStar::connect_points(int p_id,int p_with_id){ + + ERR_FAIL_COND(!points.has(p_id)); + ERR_FAIL_COND(!points.has(p_with_id)); + ERR_FAIL_COND(p_id==p_with_id); + + + Point* a = points[p_id]; + Point* b = points[p_with_id]; + a->neighbours.push_back(b); + b->neighbours.push_back(a); + + Segment s(p_id,p_with_id); + if (s.from==p_id) { + s.from_point=a; + s.to_point=b; + } else { + s.from_point=b; + s.to_point=a; + } + + segments.insert(s); + + +} +void AStar::disconnect_points(int p_id,int p_with_id){ + + Segment s(p_id,p_with_id); + ERR_FAIL_COND(!segments.has(s)); + + + segments.erase(s); + + Point *a = points[p_id]; + Point *b = points[p_with_id]; + a->neighbours.erase(b); + b->neighbours.erase(a); + +} +bool AStar::are_points_connected(int p_id,int p_with_id) const{ + + Segment s(p_id,p_with_id); + return segments.has(s); +} + +void AStar::clear(){ + + for (const Map<int,Point*>::Element *E=points.front();E;E=E->next()) { + + memdelete(E->get()); + } + segments.clear(); + points.clear(); +} + + +int AStar::get_closest_point(const Vector3& p_point) const{ + + int closest_id=-1; + float closest_dist=1e20; + + for (const Map<int,Point*>::Element *E=points.front();E;E=E->next()) { + + float d = p_point.distance_squared_to(E->get()->pos); + if (closest_id<0 || d<closest_dist) { + closest_dist=d; + closest_id=E->key(); + } + } + + return closest_id; + + +} +Vector3 AStar::get_closest_pos_in_segment(const Vector3& p_point) const { + + float closest_dist = 1e20; + bool found=false; + Vector3 closest_point; + + + for (const Set<Segment>::Element *E=segments.front();E;E=E->next()) { + + Vector3 segment[2]={ + E->get().from_point->pos, + E->get().to_point->pos, + }; + + Vector3 p = Geometry::get_closest_point_to_segment(p_point,segment); + float d = p_point.distance_squared_to(p); + if (!found || d<closest_dist) { + + closest_point=p; + closest_dist=d; + found=true; + } + } + + return closest_point; +} + +bool AStar::_solve(Point* begin_point, Point* end_point) { + + pass++; + + SelfList<Point>::List open_list; + + bool found_route=false; + + + for(int i=0;i<begin_point->neighbours.size();i++) { + + Point *n = begin_point->neighbours[i]; + n->prev_point=begin_point; + n->distance=n->pos.distance_to(begin_point->pos); + n->distance*=n->weight_scale; + n->last_pass=pass; + open_list.add(&n->list); + + if (end_point==n) { + found_route=true; + break; + } + } + + while(!found_route) { + + if (open_list.first()==NULL) { + //could not find path sadly + break; + } + //check open list + + SelfList<Point> *least_cost_point=NULL; + float least_cost=1e30; + + //this could be faster (cache previous results) + for (SelfList<Point> *E=open_list.first();E;E=E->next()) { + + Point *p=E->self(); + + float cost=p->distance; + cost+=p->pos.distance_to(end_point->pos); + cost*=p->weight_scale; + + if (cost<least_cost) { + + least_cost_point=E; + least_cost=cost; + } + } + + + Point *p=least_cost_point->self(); + //open the neighbours for search + int es = p->neighbours.size(); + + for(int i=0;i<es;i++) { + + + Point* e=p->neighbours[i]; + + + float distance = p->pos.distance_to(e->pos) + p->distance; + distance*=e->weight_scale; + + + + if (e->last_pass==pass) { + //oh this was visited already, can we win the cost? + + if (e->distance>distance) { + + e->prev_point=p; + e->distance=distance; + } + } else { + //add to open neighbours + + e->prev_point=p; + e->distance=distance; + e->last_pass=pass; //mark as used + open_list.add(&e->list); + + if (e==end_point) { + //oh my reached end! stop algorithm + found_route=true; + break; + + } + + } + } + + if (found_route) + break; + + open_list.remove(least_cost_point); + } + + //clear the openf list + while(open_list.first()) { + open_list.remove( open_list.first() ); + } + + return found_route; + +} + +DVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) { + + ERR_FAIL_COND_V(!points.has(p_from_id),DVector<Vector3>()); + ERR_FAIL_COND_V(!points.has(p_to_id),DVector<Vector3>()); + + + pass++; + + Point* a = points[p_from_id]; + Point* b = points[p_to_id]; + + if (a==b) { + DVector<Vector3> ret; + ret.push_back(a->pos); + return ret; + } + + + Point *begin_point=a; + Point *end_point=b; + + bool found_route=_solve(begin_point,end_point); + + if (!found_route) + return DVector<Vector3>(); + + //midpoints + Point *p=end_point; + int pc=1; //begin point + while(p!=begin_point) { + pc++; + p=p->prev_point; + } + + DVector<Vector3> path; + path.resize(pc); + + { + DVector<Vector3>::Write w = path.write(); + + Point *p=end_point; + int idx=pc-1; + while(p!=begin_point) { + w[idx--]=p->pos; + p=p->prev_point; + } + + w[0]=p->pos; //assign first + + } + + return path; + +} + + +DVector<int> AStar::get_id_path(int p_from_id, int p_to_id) { + + ERR_FAIL_COND_V(!points.has(p_from_id),DVector<int>()); + ERR_FAIL_COND_V(!points.has(p_to_id),DVector<int>()); + + + pass++; + + Point* a = points[p_from_id]; + Point* b = points[p_to_id]; + + if (a==b) { + DVector<int> ret; + ret.push_back(a->id); + return ret; + } + + + Point *begin_point=a; + Point *end_point=b; + + bool found_route=_solve(begin_point,end_point); + + if (!found_route) + return DVector<int>(); + + //midpoints + Point *p=end_point; + int pc=1; //begin point + while(p!=begin_point) { + pc++; + p=p->prev_point; + } + + DVector<int> path; + path.resize(pc); + + { + DVector<int>::Write w = path.write(); + + p=end_point; + int idx=pc-1; + while(p!=begin_point) { + w[idx--]=p->id; + p=p->prev_point; + } + + w[0]=p->id; //assign first + + } + + return path; +} + +void AStar::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("get_available_point_id"),&AStar::get_available_point_id); + ObjectTypeDB::bind_method(_MD("add_point","id","pos","weight_scale"),&AStar::add_point,DEFVAL(1.0)); + ObjectTypeDB::bind_method(_MD("get_point_pos","id"),&AStar::get_point_pos); + ObjectTypeDB::bind_method(_MD("get_point_weight_scale","id"),&AStar::get_point_weight_scale); + ObjectTypeDB::bind_method(_MD("remove_point","id"),&AStar::remove_point); + + ObjectTypeDB::bind_method(_MD("connect_points","id","to_id"),&AStar::connect_points); + ObjectTypeDB::bind_method(_MD("disconnect_points","id","to_id"),&AStar::disconnect_points); + ObjectTypeDB::bind_method(_MD("are_points_connected","id","to_id"),&AStar::are_points_connected); + + ObjectTypeDB::bind_method(_MD("clear"),&AStar::clear); + + ObjectTypeDB::bind_method(_MD("get_closest_point","to_pos"),&AStar::get_closest_point); + ObjectTypeDB::bind_method(_MD("get_closest_pos_in_segment","to_pos"),&AStar::get_closest_pos_in_segment); + + ObjectTypeDB::bind_method(_MD("get_point_path","from_id","to_id"),&AStar::get_point_path); + ObjectTypeDB::bind_method(_MD("get_id_path","from_id","to_id"),&AStar::get_id_path); + +} + + +AStar::AStar() { + + pass=1; +} + + +AStar::~AStar() { + + pass=1; +} diff --git a/core/math/a_star.h b/core/math/a_star.h new file mode 100644 index 0000000000..a0517b5941 --- /dev/null +++ b/core/math/a_star.h @@ -0,0 +1,92 @@ +#ifndef ASTAR_H +#define ASTAR_H + +#include "reference.h" +#include "self_list.h" + +class AStar: public Reference { + + OBJ_TYPE(AStar,Reference) + + + uint64_t pass; + + struct Point { + + SelfList<Point> list; + + int id; + Vector3 pos; + float weight_scale; + uint64_t last_pass; + + Vector<Point*> neighbours; + + //used for pathfinding + Point *prev_point; + float distance; + + Point() : list(this) {} + }; + + Map<int,Point*> points; + + struct Segment { + union { + struct { + int32_t from; + int32_t to; + }; + uint64_t key; + }; + + Point *from_point; + Point *to_point; + + bool operator<(const Segment& p_s) const { return key<p_s.key; } + Segment() { key=0; } + Segment(int p_from,int p_to) { + if (p_from > p_to) { + SWAP(p_from,p_to); + } + + from=p_from; + to=p_to; + } + }; + + + Set<Segment> segments; + + bool _solve(Point *begin_point, Point *end_point); + +protected: + + static void _bind_methods(); +public: + + int get_available_point_id() const; + + void add_point(int p_id,const Vector3& p_pos,float p_weight_scale=1); + Vector3 get_point_pos(int p_id) const; + float get_point_weight_scale(int p_id) const; + void remove_point(int p_id); + + void connect_points(int p_id,int p_with_id); + void disconnect_points(int p_id,int p_with_id); + bool are_points_connected(int p_id,int p_with_id) const; + + void clear(); + + + int get_closest_point(const Vector3& p_point) const; + Vector3 get_closest_pos_in_segment(const Vector3& p_point) const; + + DVector<Vector3> get_point_path(int p_from_id, int p_to_id); + DVector<int> get_id_path(int p_from_id, int p_to_id); + + AStar(); + ~AStar(); +}; + +#endif // ASTAR_H diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index 0e2060008c..e616f05914 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -424,7 +424,7 @@ Matrix32 Matrix32::inverse() const { void Matrix32::affine_invert() { - float det = elements[0][0]*elements[1][1] - elements[1][0]*elements[0][1]; + float det = basis_determinant(); ERR_FAIL_COND(det==0); float idet = 1.0 / det; @@ -475,18 +475,18 @@ Matrix32::Matrix32(real_t p_rot, const Vector2& p_pos) { elements[2]=p_pos; } -Vector2 Matrix32::get_scale() const { +Size2 Matrix32::get_scale() const { - return Vector2( elements[0].length(), elements[1].length() ); + return Size2( elements[0].length(), elements[1].length() ); } -void Matrix32::scale(const Vector2& p_scale) { +void Matrix32::scale(const Size2& p_scale) { elements[0]*=p_scale; elements[1]*=p_scale; elements[2]*=p_scale; } -void Matrix32::scale_basis(const Vector2& p_scale) { +void Matrix32::scale_basis(const Size2& p_scale) { elements[0]*=p_scale; elements[1]*=p_scale; @@ -501,7 +501,6 @@ void Matrix32::translate( const Vector2& p_translation ) { elements[2]+=basis_xform(p_translation); } - void Matrix32::orthonormalize() { // Gram-Schmidt Process @@ -550,11 +549,6 @@ void Matrix32::operator*=(const Matrix32& p_transform) { elements[2] = xform(p_transform.elements[2]); float x0,x1,y0,y1; -/* - x0 = p_transform.tdotx(elements[0]); - x1 = p_transform.tdoty(elements[0]); - y0 = p_transform.tdotx(elements[1]); - y1 = p_transform.tdoty(elements[1]);*/ x0 = tdotx(p_transform.elements[0]); x1 = tdoty(p_transform.elements[0]); @@ -576,7 +570,7 @@ Matrix32 Matrix32::operator*(const Matrix32& p_transform) const { } -Matrix32 Matrix32::scaled(const Vector2& p_scale) const { +Matrix32 Matrix32::scaled(const Size2& p_scale) const { Matrix32 copy=*this; copy.scale(p_scale); @@ -584,7 +578,7 @@ Matrix32 Matrix32::scaled(const Vector2& p_scale) const { } -Matrix32 Matrix32::basis_scaled(const Vector2& p_scale) const { +Matrix32 Matrix32::basis_scaled(const Size2& p_scale) const { Matrix32 copy=*this; copy.scale_basis(p_scale); @@ -629,8 +623,8 @@ Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) cons real_t r1 = get_rotation(); real_t r2 = p_transform.get_rotation(); - Vector2 s1 = get_scale(); - Vector2 s2 = p_transform.get_scale(); + Size2 s1 = get_scale(); + Size2 s2 = p_transform.get_scale(); //slerp rotation Vector2 v1(Math::cos(r1), Math::sin(r1)); diff --git a/core/math/math_2d.h b/core/math/math_2d.h index 90aae9fe50..38c1ac9656 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -553,10 +553,8 @@ struct Rect2i { struct Matrix32 { - Vector2 elements[3]; - _FORCE_INLINE_ float tdotx(const Vector2& v) const { return elements[0][0] * v.x + elements[1][0] * v.y; } _FORCE_INLINE_ float tdoty(const Vector2& v) const { return elements[0][1] * v.x + elements[1][1] * v.y; } @@ -577,26 +575,25 @@ struct Matrix32 { _FORCE_INLINE_ void set_rotation_and_scale(real_t p_phi,const Size2& p_scale); void rotate(real_t p_phi); - void scale(const Vector2& p_scale); - void scale_basis(const Vector2& p_scale); + void scale(const Size2& p_scale); + void scale_basis(const Size2& p_scale); void translate( real_t p_tx, real_t p_ty); void translate( const Vector2& p_translation ); float basis_determinant() const; - Vector2 get_scale() const; + Size2 get_scale() const; _FORCE_INLINE_ const Vector2& get_origin() const { return elements[2]; } _FORCE_INLINE_ void set_origin(const Vector2& p_origin) { elements[2]=p_origin; } - Matrix32 scaled(const Vector2& p_scale) const; - Matrix32 basis_scaled(const Vector2& p_scale) const; + Matrix32 scaled(const Size2& p_scale) const; + Matrix32 basis_scaled(const Size2& p_scale) const; Matrix32 translated(const Vector2& p_offset) const; Matrix32 rotated(float p_phi) const; Matrix32 untranslated() const; - void orthonormalize(); Matrix32 orthonormalized() const; @@ -615,7 +612,6 @@ struct Matrix32 { _FORCE_INLINE_ Rect2 xform(const Rect2& p_vec) const; _FORCE_INLINE_ Rect2 xform_inv(const Rect2& p_vec) const; - operator String() const; Matrix32(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) { @@ -630,7 +626,6 @@ struct Matrix32 { Matrix32(real_t p_rot, const Vector2& p_pos); Matrix32() { elements[0][0]=1.0; elements[1][1]=1.0; } - }; bool Rect2::intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const { diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp index 27b7c86675..1f5d5ed6b3 100644 --- a/core/math/triangulate.cpp +++ b/core/math/triangulate.cpp @@ -157,7 +157,10 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour,Vector<int> &result m++; /* remove v from remaining polygon */ - for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; nv--; + for(s=v,t=v+1;t<nv;s++,t++) + V[s] = V[t]; + + nv--; /* resest error detection counter */ count = 2*nv; diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 8afd73f482..fae3831dd6 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -49,13 +49,13 @@ void Vector3::set_axis(int p_axis,real_t p_value) { } real_t Vector3::get_axis(int p_axis) const { - ERR_FAIL_INDEX_V(p_axis,3,0); - return operator[](p_axis); + ERR_FAIL_INDEX_V(p_axis,3,0); + return operator[](p_axis); } int Vector3::min_axis() const { - return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2); + return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2); } int Vector3::max_axis() const { @@ -65,19 +65,15 @@ int Vector3::max_axis() const { void Vector3::snap(float p_val) { - x+=p_val/2.0; - x-=Math::fmod(x,p_val); - y+=p_val/2.0; - y-=Math::fmod(y,p_val); - z+=p_val/2.0; - z-=Math::fmod(z,p_val); - + x=Math::stepify(x,p_val); + y=Math::stepify(y,p_val); + z=Math::stepify(z,p_val); } Vector3 Vector3::snapped(float p_val) const { - Vector3 v=*this; - v.snap(p_val); - return v; + Vector3 v=*this; + v.snap(p_val); + return v; } diff --git a/core/math/vector3.h b/core/math/vector3.h index 910446023a..06840be5e7 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -63,77 +63,78 @@ struct Vector3 { return coord[p_axis]; } - void set_axis(int p_axis,real_t p_value); - real_t get_axis(int p_axis) const; + void set_axis(int p_axis,real_t p_value); + real_t get_axis(int p_axis) const; - int min_axis() const; - int max_axis() const; + int min_axis() const; + int max_axis() const; - _FORCE_INLINE_ real_t length() const; - _FORCE_INLINE_ real_t length_squared() const; + _FORCE_INLINE_ real_t length() const; + _FORCE_INLINE_ real_t length_squared() const; - _FORCE_INLINE_ void normalize(); - _FORCE_INLINE_ Vector3 normalized() const; - _FORCE_INLINE_ Vector3 inverse() const; + _FORCE_INLINE_ void normalize(); + _FORCE_INLINE_ Vector3 normalized() const; + _FORCE_INLINE_ Vector3 inverse() const; _FORCE_INLINE_ void zero(); - void snap(float p_val); - Vector3 snapped(float p_val) const; + void snap(float p_val); + Vector3 snapped(float p_val) const; void rotate(const Vector3& p_axis,float p_phi); Vector3 rotated(const Vector3& p_axis,float p_phi) const; - /* Static Methods between 2 vector3s */ + /* Static Methods between 2 vector3s */ - _FORCE_INLINE_ Vector3 linear_interpolate(const Vector3& p_b,float p_t) const; + _FORCE_INLINE_ Vector3 linear_interpolate(const Vector3& p_b,float p_t) const; Vector3 cubic_interpolate(const Vector3& p_b,const Vector3& p_pre_a, const Vector3& p_post_b,float p_t) const; Vector3 cubic_interpolaten(const Vector3& p_b,const Vector3& p_pre_a, const Vector3& p_post_b,float p_t) const; - _FORCE_INLINE_ Vector3 cross(const Vector3& p_b) const; - _FORCE_INLINE_ real_t dot(const Vector3& p_b) const; + _FORCE_INLINE_ Vector3 cross(const Vector3& p_b) const; + _FORCE_INLINE_ real_t dot(const Vector3& p_b) const; - _FORCE_INLINE_ Vector3 abs() const; - _FORCE_INLINE_ Vector3 floor() const; - _FORCE_INLINE_ Vector3 ceil() const; + _FORCE_INLINE_ Vector3 abs() const; + _FORCE_INLINE_ Vector3 floor() const; + _FORCE_INLINE_ Vector3 ceil() const; - _FORCE_INLINE_ real_t distance_to(const Vector3& p_b) const; - _FORCE_INLINE_ real_t distance_squared_to(const Vector3& p_b) const; + _FORCE_INLINE_ real_t distance_to(const Vector3& p_b) const; + _FORCE_INLINE_ real_t distance_squared_to(const Vector3& p_b) const; + _FORCE_INLINE_ real_t angle_to(const Vector3& p_b) const; _FORCE_INLINE_ Vector3 slide(const Vector3& p_vec) const; _FORCE_INLINE_ Vector3 reflect(const Vector3& p_vec) const; - /* Operators */ + /* Operators */ - _FORCE_INLINE_ Vector3& operator+=(const Vector3& p_v); - _FORCE_INLINE_ Vector3 operator+(const Vector3& p_v) const; - _FORCE_INLINE_ Vector3& operator-=(const Vector3& p_v); - _FORCE_INLINE_ Vector3 operator-(const Vector3& p_v) const; - _FORCE_INLINE_ Vector3& operator*=(const Vector3& p_v); - _FORCE_INLINE_ Vector3 operator*(const Vector3& p_v) const; - _FORCE_INLINE_ Vector3& operator/=(const Vector3& p_v); - _FORCE_INLINE_ Vector3 operator/(const Vector3& p_v) const; + _FORCE_INLINE_ Vector3& operator+=(const Vector3& p_v); + _FORCE_INLINE_ Vector3 operator+(const Vector3& p_v) const; + _FORCE_INLINE_ Vector3& operator-=(const Vector3& p_v); + _FORCE_INLINE_ Vector3 operator-(const Vector3& p_v) const; + _FORCE_INLINE_ Vector3& operator*=(const Vector3& p_v); + _FORCE_INLINE_ Vector3 operator*(const Vector3& p_v) const; + _FORCE_INLINE_ Vector3& operator/=(const Vector3& p_v); + _FORCE_INLINE_ Vector3 operator/(const Vector3& p_v) const; - _FORCE_INLINE_ Vector3& operator*=(real_t p_scalar); - _FORCE_INLINE_ Vector3 operator*(real_t p_scalar) const; - _FORCE_INLINE_ Vector3& operator/=(real_t p_scalar); - _FORCE_INLINE_ Vector3 operator/(real_t p_scalar) const; + _FORCE_INLINE_ Vector3& operator*=(real_t p_scalar); + _FORCE_INLINE_ Vector3 operator*(real_t p_scalar) const; + _FORCE_INLINE_ Vector3& operator/=(real_t p_scalar); + _FORCE_INLINE_ Vector3 operator/(real_t p_scalar) const; - _FORCE_INLINE_ Vector3 operator-() const; + _FORCE_INLINE_ Vector3 operator-() const; - _FORCE_INLINE_ bool operator==(const Vector3& p_v) const; - _FORCE_INLINE_ bool operator!=(const Vector3& p_v) const; - _FORCE_INLINE_ bool operator<(const Vector3& p_v) const; + _FORCE_INLINE_ bool operator==(const Vector3& p_v) const; + _FORCE_INLINE_ bool operator!=(const Vector3& p_v) const; + _FORCE_INLINE_ bool operator<(const Vector3& p_v) const; _FORCE_INLINE_ bool operator<=(const Vector3& p_v) const; operator String() const; - _FORCE_INLINE_ Vector3() { x=y=z=0; } - _FORCE_INLINE_ Vector3(real_t p_x,real_t p_y,real_t p_z) { x=p_x; y=p_y; z=p_z; } + _FORCE_INLINE_ Vector3() { x=y=z=0; } + _FORCE_INLINE_ Vector3(real_t p_x,real_t p_y,real_t p_z) { x=p_x; y=p_y; z=p_z; } }; @@ -151,11 +152,12 @@ Vector3 Vector3::cross(const Vector3& p_b) const { (x * p_b.y) - (y * p_b.x) ); - return ret; + return ret; } + real_t Vector3::dot(const Vector3& p_b) const { - return x*p_b.x + y*p_b.y + z*p_b.z; + return x*p_b.x + y*p_b.y + z*p_b.z; } Vector3 Vector3::abs() const { @@ -180,115 +182,119 @@ Vector3 Vector3::linear_interpolate(const Vector3& p_b,float p_t) const { y+(p_t * (p_b.y-y)), z+(p_t * (p_b.z-z)) ); - } - - real_t Vector3::distance_to(const Vector3& p_b) const { + return (p_b-*this).length(); } + real_t Vector3::distance_squared_to(const Vector3& p_b) const { - return (p_b-*this).length_squared(); + return (p_b-*this).length_squared(); +} + +real_t Vector3::angle_to(const Vector3& p_b) const { + + return Math::acos(this->dot(p_b) / Math::sqrt(this->length_squared() * p_b.length_squared())); } /* Operators */ Vector3& Vector3::operator+=(const Vector3& p_v) { - x+=p_v.x; - y+=p_v.y; - z+=p_v.z; - return *this; + x+=p_v.x; + y+=p_v.y; + z+=p_v.z; + return *this; } + Vector3 Vector3::operator+(const Vector3& p_v) const { - return Vector3(x+p_v.x, y+p_v.y, z+ p_v.z); + return Vector3(x+p_v.x, y+p_v.y, z+ p_v.z); } Vector3& Vector3::operator-=(const Vector3& p_v) { - x-=p_v.x; - y-=p_v.y; - z-=p_v.z; - return *this; + x-=p_v.x; + y-=p_v.y; + z-=p_v.z; + return *this; } Vector3 Vector3::operator-(const Vector3& p_v) const { - return Vector3(x-p_v.x, y-p_v.y, z- p_v.z); + return Vector3(x-p_v.x, y-p_v.y, z- p_v.z); } - - Vector3& Vector3::operator*=(const Vector3& p_v) { - x*=p_v.x; - y*=p_v.y; - z*=p_v.z; - return *this; + x*=p_v.x; + y*=p_v.y; + z*=p_v.z; + return *this; } Vector3 Vector3::operator*(const Vector3& p_v) const { - return Vector3(x*p_v.x, y*p_v.y, z* p_v.z); + return Vector3(x*p_v.x, y*p_v.y, z* p_v.z); } Vector3& Vector3::operator/=(const Vector3& p_v) { - x/=p_v.x; - y/=p_v.y; - z/=p_v.z; - return *this; + x/=p_v.x; + y/=p_v.y; + z/=p_v.z; + return *this; } + Vector3 Vector3::operator/(const Vector3& p_v) const { - return Vector3(x/p_v.x, y/p_v.y, z/ p_v.z); + return Vector3(x/p_v.x, y/p_v.y, z/ p_v.z); } Vector3& Vector3::operator*=(real_t p_scalar) { - x*=p_scalar; - y*=p_scalar; - z*=p_scalar; - return *this; + x*=p_scalar; + y*=p_scalar; + z*=p_scalar; + return *this; } _FORCE_INLINE_ Vector3 operator*(real_t p_scalar, const Vector3& p_vec) { + return p_vec * p_scalar; } Vector3 Vector3::operator*(real_t p_scalar) const { - return Vector3( x*p_scalar, y*p_scalar, z*p_scalar); + return Vector3( x*p_scalar, y*p_scalar, z*p_scalar); } Vector3& Vector3::operator/=(real_t p_scalar) { - x/=p_scalar; - y/=p_scalar; - z/=p_scalar; - return *this; + x/=p_scalar; + y/=p_scalar; + z/=p_scalar; + return *this; } Vector3 Vector3::operator/(real_t p_scalar) const { - return Vector3( x/p_scalar, y/p_scalar, z/p_scalar); + return Vector3( x/p_scalar, y/p_scalar, z/p_scalar); } Vector3 Vector3::operator-() const { - return Vector3( -x, -y, -z ); + return Vector3( -x, -y, -z ); } - bool Vector3::operator==(const Vector3& p_v) const { - return (x==p_v.x && y==p_v.y && z==p_v.z); + return (x==p_v.x && y==p_v.y && z==p_v.z); } bool Vector3::operator!=(const Vector3& p_v) const { - return (x!=p_v.x || y!=p_v.y || z!=p_v.z); + return (x!=p_v.x || y!=p_v.y || z!=p_v.z); } bool Vector3::operator<(const Vector3& p_v) const { @@ -298,9 +304,9 @@ bool Vector3::operator<(const Vector3& p_v) const { return z<p_v.z; else return y<p_v.y; - } else + } else { return x<p_v.x; - + } } bool Vector3::operator<=(const Vector3& p_v) const { @@ -310,9 +316,9 @@ bool Vector3::operator<=(const Vector3& p_v) const { return z<=p_v.z; else return y<p_v.y; - } else + } else { return x<p_v.x; - + } } _FORCE_INLINE_ Vector3 vec3_cross(const Vector3& p_a, const Vector3& p_b) { @@ -333,6 +339,7 @@ real_t Vector3::length() const { return Math::sqrt(x2+y2+z2); } + real_t Vector3::length_squared() const { real_t x2=x*x; @@ -340,27 +347,25 @@ real_t Vector3::length_squared() const { real_t z2=z*z; return x2+y2+z2; - } void Vector3::normalize() { - real_t l=length(); - if (l==0) { - + real_t l=length(); + if (l==0) { x=y=z=0; - } else { - + } else { x/=l; y/=l; z/=l; - } + } } + Vector3 Vector3::normalized() const { - Vector3 v=*this; - v.normalize(); - return v; + Vector3 v=*this; + v.normalize(); + return v; } Vector3 Vector3::inverse() const { @@ -377,10 +382,10 @@ Vector3 Vector3::slide(const Vector3& p_vec) const { return p_vec - *this * this->dot(p_vec); } + Vector3 Vector3::reflect(const Vector3& p_vec) const { return p_vec - *this * this->dot(p_vec) * 2.0; - } #endif diff --git a/core/method_bind.h b/core/method_bind.h index 072953743c..04ff5c22c6 100644 --- a/core/method_bind.h +++ b/core/method_bind.h @@ -52,6 +52,7 @@ enum MethodFlags { METHOD_FLAG_REVERSE=16, // used for events METHOD_FLAG_VIRTUAL=32, METHOD_FLAG_FROM_SCRIPT=64, + METHOD_FLAG_VARARG=128, METHOD_FLAGS_DEFAULT=METHOD_FLAG_NORMAL, }; @@ -229,7 +230,7 @@ public: Vector<StringName> get_argument_names() const; #endif void set_hint_flags(uint32_t p_hint) { hint_flags=p_hint; } - uint32_t get_hint_flags() const { return hint_flags|(is_const()?METHOD_FLAG_CONST:0); } + uint32_t get_hint_flags() const { return hint_flags|(is_const()?METHOD_FLAG_CONST:0)|(is_vararg()?METHOD_FLAG_VARARG:0); } virtual String get_instance_type() const=0; _FORCE_INLINE_ int get_argument_count() const { return argument_count; }; @@ -267,7 +268,7 @@ public: _FORCE_INLINE_ int get_method_id() const { return method_id; } _FORCE_INLINE_ bool is_const() const { return _const; } _FORCE_INLINE_ bool has_return() const { return _returns; } - + virtual bool is_vararg() const { return false; } void set_default_arguments(const Vector<Variant>& p_defargs); @@ -277,7 +278,7 @@ public: template<class T> -class MethodBindNative : public MethodBind { +class MethodBindVarArg : public MethodBind { public: typedef Variant (T::*NativeCall)(const Variant**,int ,Variant::CallError &); protected: @@ -319,7 +320,9 @@ public: } #ifdef PTRCALL_ENABLED - virtual void ptrcall(Object* p_object,const void** p_args,void* r_ret) {} //todo + virtual void ptrcall(Object* p_object,const void** p_args,void* r_ret) { + ERR_FAIL(); //can't call + } //todo #endif @@ -327,14 +330,16 @@ public: virtual bool is_const() const { return false; } virtual String get_instance_type() const { return T::get_type_static(); } - MethodBindNative() { call_method=NULL; _set_returns(true);} + virtual bool is_vararg() const { return true; } + + MethodBindVarArg() { call_method=NULL; _set_returns(true);} }; template<class T > -MethodBind* create_native_method_bind( Variant (T::*p_method)(const Variant**,int ,Variant::CallError &), const MethodInfo& p_info ) { +MethodBind* create_vararg_method_bind( Variant (T::*p_method)(const Variant**,int ,Variant::CallError &), const MethodInfo& p_info ) { - MethodBindNative<T > * a = memnew( (MethodBindNative<T >) ); + MethodBindVarArg<T > * a = memnew( (MethodBindVarArg<T >) ); a->set_method(p_method); a->set_method_info(p_info); return a; diff --git a/core/object.cpp b/core/object.cpp index b036efa501..9a1e9be8d5 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1215,6 +1215,15 @@ void Object::emit_signal(const StringName& p_name,const Variant** p_args,int p_a Signal *s = signal_map.getptr(p_name); if (!s) { +#ifdef DEBUG_ENABLED + bool signal_is_valid = ObjectTypeDB::has_signal(get_type_name(),p_name); + //check in script + if (!signal_is_valid && !script.is_null() && !Ref<Script>(script)->has_script_signal(p_name)) { + ERR_EXPLAIN("Can't emit non-existing signal " + String("\"")+p_name+"\"."); + ERR_FAIL(); + } +#endif + //not connected? just return return; } @@ -1644,6 +1653,7 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { _clear_internal_resource_paths(d[E->get()]); } } break; + default: {} } } @@ -1693,42 +1703,26 @@ void Object::_bind_methods() { MethodInfo mi; mi.name="emit_signal"; mi.arguments.push_back( PropertyInfo( Variant::STRING, "signal")); - Vector<Variant> defargs; - for(int i=0;i<VARIANT_ARG_MAX;i++) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"emit_signal",&Object::_emit_signal,mi,defargs); + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"emit_signal",&Object::_emit_signal,mi); } { MethodInfo mi; mi.name="call"; mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); - Vector<Variant> defargs; - for(int i=0;i<10;i++) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call:Variant",&Object::_call_bind,mi,defargs); + + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call:Variant",&Object::_call_bind,mi); } { MethodInfo mi; mi.name="call_deferred"; mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); - Vector<Variant> defargs; - for(int i=0;i<VARIANT_ARG_MAX;i++) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_deferred",&Object::_call_deferred_bind,mi,defargs); + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call_deferred",&Object::_call_deferred_bind,mi); } ObjectTypeDB::bind_method(_MD("callv:Variant","method","arg_array"),&Object::callv); diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp index b6a69e3bd4..e121dc9e98 100644 --- a/core/object_type_db.cpp +++ b/core/object_type_db.cpp @@ -189,6 +189,14 @@ MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,co #endif + +ObjectTypeDB::APIType ObjectTypeDB::current_api=API_CORE; + +void ObjectTypeDB::set_current_api(APIType p_api) { + + current_api=p_api; +} + HashMap<StringName,ObjectTypeDB::TypeInfo,StringNameHasher> ObjectTypeDB::types; HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::resource_base_extensions; HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::compat_types; @@ -258,6 +266,171 @@ StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) { return ti->inherits; } +ObjectTypeDB::APIType ObjectTypeDB::get_api_type(const StringName &p_type) { + + OBJTYPE_LOCK; + + TypeInfo *ti = types.getptr(p_type); + ERR_FAIL_COND_V(!ti,API_NONE); + return ti->api; +} + +uint64_t ObjectTypeDB::get_api_hash(APIType p_api) { + +#ifdef DEBUG_METHODS_ENABLED + + uint64_t hash = hash_djb2_one_64(HashMapHahserDefault::hash(VERSION_FULL_NAME)); + + List<StringName> names; + + const StringName *k=NULL; + + while((k=types.next(k))) { + + names.push_back(*k); + } + //must be alphabetically sorted for hash to compute + names.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *E=names.front();E;E=E->next()) { + + TypeInfo *t = types.getptr(E->get()); + ERR_FAIL_COND_V(!t,0); + if (t->api!=p_api) + continue; + hash = hash_djb2_one_64(t->name.hash(),hash); + hash = hash_djb2_one_64(t->inherits.hash(),hash); + + { //methods + + List<StringName> snames; + + k=NULL; + + while((k=t->method_map.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *F=snames.front();F;F=F->next()) { + + MethodBind *mb = t->method_map[F->get()]; + hash = hash_djb2_one_64( mb->get_name().hash(), hash); + hash = hash_djb2_one_64( mb->get_argument_count(), hash); + hash = hash_djb2_one_64( mb->get_argument_type(-1), hash); //return + + for(int i=0;i<mb->get_argument_count();i++) { + hash = hash_djb2_one_64( mb->get_argument_info(i).type, hash ); + hash = hash_djb2_one_64( mb->get_argument_info(i).name.hash(), hash ); + hash = hash_djb2_one_64( mb->get_argument_info(i).hint, hash ); + hash = hash_djb2_one_64( mb->get_argument_info(i).hint_string.hash(), hash ); + } + + hash = hash_djb2_one_64( mb->get_default_argument_count(), hash); + + for(int i=0;i<mb->get_default_argument_count();i++) { + //hash should not change, i hope for tis + Variant da = mb->get_default_argument(i); + hash = hash_djb2_one_64( da.hash(), hash ); + } + + hash = hash_djb2_one_64( mb->get_hint_flags(), hash); + + } + } + + + { //constants + + List<StringName> snames; + + k=NULL; + + while((k=t->constant_map.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *F=snames.front();F;F=F->next()) { + + hash = hash_djb2_one_64(F->get().hash(), hash); + hash = hash_djb2_one_64( t->constant_map[F->get()], hash); + } + } + + + { //signals + + List<StringName> snames; + + k=NULL; + + while((k=t->signal_map.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *F=snames.front();F;F=F->next()) { + + MethodInfo &mi = t->signal_map[F->get()]; + hash = hash_djb2_one_64( F->get().hash(), hash); + for(int i=0;i<mi.arguments.size();i++) { + hash = hash_djb2_one_64( mi.arguments[i].type, hash); + } + } + } + + { //properties + + List<StringName> snames; + + k=NULL; + + while((k=t->property_setget.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *F=snames.front();F;F=F->next()) { + + PropertySetGet *psg=t->property_setget.getptr(F->get()); + + hash = hash_djb2_one_64( F->get().hash(), hash); + hash = hash_djb2_one_64( psg->setter.hash(), hash); + hash = hash_djb2_one_64( psg->getter.hash(), hash); + + } + } + + //property list + for (List<PropertyInfo>::Element *F=t->property_list.front();F;F=F->next()) { + + hash = hash_djb2_one_64( F->get().name.hash(), hash); + hash = hash_djb2_one_64( F->get().type, hash); + hash = hash_djb2_one_64( F->get().hint, hash); + hash = hash_djb2_one_64( F->get().hint_string.hash(), hash); + hash = hash_djb2_one_64( F->get().usage, hash); + } + + + } + + + return hash; +#else + return 0; +#endif + +} + bool ObjectTypeDB::type_exists(const StringName &p_type) { OBJTYPE_LOCK; @@ -309,6 +482,7 @@ void ObjectTypeDB::_add_type2(const StringName& p_type, const StringName& p_inhe TypeInfo &ti=types[name]; ti.name=name; ti.inherits=p_inherits; + ti.api=current_api; if (ti.inherits) { @@ -866,21 +1040,14 @@ MethodBind* ObjectTypeDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , c Vector<Variant> defvals; -#define PARSE_DEFVAL(m_defval)\ -if (d##m_defval.used) defvals.insert(0,d##m_defval.val);\ -else goto set_defvals; - defvals.resize(p_defcount); for(int i=0;i<p_defcount;i++) { defvals[i]=*p_defs[p_defcount-i-1]; } - set_defvals: - p_bind->set_default_arguments(defvals); p_bind->set_hint_flags(p_flags); -#undef PARSE_DEFVAL return p_bind; } diff --git a/core/object_type_db.h b/core/object_type_db.h index 3fcd38aa31..9e9029ff2f 100644 --- a/core/object_type_db.h +++ b/core/object_type_db.h @@ -109,7 +109,13 @@ static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name; #endif class ObjectTypeDB { - +public: + enum APIType { + API_CORE, + API_EDITOR, + API_NONE + }; +public: struct PropertySetGet { int index; @@ -122,6 +128,7 @@ class ObjectTypeDB { struct TypeInfo { + APIType api; TypeInfo *inherits_ptr; HashMap<StringName,MethodBind*,StringNameHasher> method_map; HashMap<StringName,int,StringNameHasher> constant_map; @@ -161,6 +168,7 @@ class ObjectTypeDB { #endif + static APIType current_api; static void _add_type2(const StringName& p_type, const StringName& p_inherits); public: @@ -236,6 +244,9 @@ public: static bool is_type(const StringName &p_type,const StringName& p_inherits); static bool can_instance(const StringName &p_type); static Object *instance(const StringName &p_type); + static APIType get_api_type(const StringName &p_type); + + static uint64_t get_api_hash(APIType p_api); #if 0 template<class N, class M> @@ -415,13 +426,13 @@ public: #endif template<class M> - static MethodBind* bind_native_method(uint32_t p_flags, StringName p_name, M p_method,const MethodInfo& p_info=MethodInfo(),const Vector<Variant>& p_default_args=Vector<Variant>()) { + static MethodBind* bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method,const MethodInfo& p_info=MethodInfo(),const Vector<Variant>& p_default_args=Vector<Variant>()) { GLOBAL_LOCK_FUNCTION; - MethodBind *bind = create_native_method_bind(p_method,p_info); + MethodBind *bind = create_vararg_method_bind(p_method,p_info); ERR_FAIL_COND_V(!bind,NULL); String rettype; @@ -499,6 +510,8 @@ public: static void add_compatibility_type(const StringName& p_type,const StringName& p_fallback); static void init(); + + static void set_current_api(APIType p_api); static void cleanup(); }; diff --git a/core/os/input.cpp b/core/os/input.cpp index 531db73838..4ab57a84ea 100644 --- a/core/os/input.cpp +++ b/core/os/input.cpp @@ -53,6 +53,8 @@ void Input::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_mouse_button_pressed","button"),&Input::is_mouse_button_pressed); ObjectTypeDB::bind_method(_MD("is_joy_button_pressed","device","button"),&Input::is_joy_button_pressed); ObjectTypeDB::bind_method(_MD("is_action_pressed","action"),&Input::is_action_pressed); + ObjectTypeDB::bind_method(_MD("is_action_just_pressed","action"),&Input::is_action_just_pressed); + ObjectTypeDB::bind_method(_MD("is_action_just_released","action"),&Input::is_action_just_released); ObjectTypeDB::bind_method(_MD("add_joy_mapping","mapping", "update_existing"),&Input::add_joy_mapping, DEFVAL(false)); ObjectTypeDB::bind_method(_MD("remove_joy_mapping","guid"),&Input::remove_joy_mapping); ObjectTypeDB::bind_method(_MD("is_joy_known","device"),&Input::is_joy_known); @@ -62,6 +64,10 @@ void Input::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_connected_joysticks"),&Input::get_connected_joysticks); ObjectTypeDB::bind_method(_MD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength); ObjectTypeDB::bind_method(_MD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration); + ObjectTypeDB::bind_method(_MD("get_joy_button_string", "button_index"), &Input::get_joy_button_string); + ObjectTypeDB::bind_method(_MD("get_joy_button_index_from_string", "button"), &Input::get_joy_button_index_from_string); + ObjectTypeDB::bind_method(_MD("get_joy_axis_string", "axis_index"), &Input::get_joy_axis_string); + ObjectTypeDB::bind_method(_MD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string); ObjectTypeDB::bind_method(_MD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0)); ObjectTypeDB::bind_method(_MD("stop_joy_vibration", "device"), &Input::stop_joy_vibration); ObjectTypeDB::bind_method(_MD("get_accelerometer"),&Input::get_accelerometer); @@ -88,7 +94,7 @@ void Input::get_argument_options(const StringName& p_function,int p_idx,List<Str #ifdef TOOLS_ENABLED String pf=p_function; - if (p_idx==0 && (pf=="is_action_pressed" || pf=="action_press" || pf=="action_release")) { + if (p_idx==0 && (pf=="is_action_pressed" || pf=="action_press" || pf=="action_release" || pf=="is_action_just_pressed" || pf=="is_action_just_released")) { List<PropertyInfo> pinfo; Globals::get_singleton()->get_property_list(&pinfo); diff --git a/core/os/input.h b/core/os/input.h index 16bcc0ff9a..d8f3be09df 100644 --- a/core/os/input.h +++ b/core/os/input.h @@ -55,12 +55,14 @@ public: static Input *get_singleton(); - virtual bool is_key_pressed(int p_scancode)=0; - virtual bool is_mouse_button_pressed(int p_button)=0; - virtual bool is_joy_button_pressed(int p_device, int p_button)=0; - virtual bool is_action_pressed(const StringName& p_action)=0; - - virtual float get_joy_axis(int p_device,int p_axis)=0; + virtual bool is_key_pressed(int p_scancode) const=0; + virtual bool is_mouse_button_pressed(int p_button) const=0; + virtual bool is_joy_button_pressed(int p_device, int p_button) const=0; + virtual bool is_action_pressed(const StringName& p_action) const=0; + virtual bool is_action_just_pressed(const StringName& p_action) const=0; + virtual bool is_action_just_released(const StringName& p_action) const=0; + + virtual float get_joy_axis(int p_device,int p_axis) const=0; virtual String get_joy_name(int p_idx)=0; virtual Array get_connected_joysticks()=0; virtual void joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid)=0; @@ -80,9 +82,9 @@ public: virtual void warp_mouse_pos(const Vector2& p_to)=0; - virtual Vector3 get_accelerometer()=0; - virtual Vector3 get_magnetometer()=0; - virtual Vector3 get_gyroscope()=0; + virtual Vector3 get_accelerometer() const=0; + virtual Vector3 get_magnetometer() const=0; + virtual Vector3 get_gyroscope() const=0; virtual void action_press(const StringName& p_action)=0; virtual void action_release(const StringName& p_action)=0; @@ -94,6 +96,11 @@ public: virtual void set_custom_mouse_cursor(const RES& p_cursor,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; + virtual int get_joy_button_index_from_string(String p_button)=0; + virtual int get_joy_axis_index_from_string(String p_axis)=0; + Input(); }; diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index f4a6de0e96..9982767be1 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -39,6 +39,8 @@ bool InputEvent::operator==(const InputEvent &p_event) const { } switch(type) { + case NONE: + return true; case KEY: return key.unicode == p_event.key.unicode && key.scancode == p_event.key.scancode @@ -77,6 +79,8 @@ bool InputEvent::operator==(const InputEvent &p_event) const { case ACTION: return action.action == p_event.action.action && action.pressed == p_event.action.pressed; + default: + ERR_PRINT("No logic to compare InputEvents of this type, this shouldn't happen."); } return false; @@ -200,7 +204,7 @@ bool InputEvent::is_pressed() const { case MOUSE_BUTTON: return mouse_button.pressed; case JOYSTICK_BUTTON: return joy_button.pressed; case SCREEN_TOUCH: return screen_touch.pressed; - case JOYSTICK_MOTION: return InputMap::get_singleton()->event_is_joy_motion_action_pressed(*this); + case JOYSTICK_MOTION: return ABS(joy_motion.axis_value) > 0.5; case ACTION: return action.pressed; default: {} } diff --git a/core/os/os.cpp b/core/os/os.cpp index 5f86962048..ee32476234 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -587,6 +587,9 @@ OS::OS() { _time_scale=1.0; _pixel_snap=false; _allow_hidpi=true; + _fixed_frames=0; + _idle_frames=0; + _in_fixed=false; Math::seed(1234567); } diff --git a/core/os/os.h b/core/os/os.h index 2521d67e29..c2b46a5420 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -62,6 +62,10 @@ class OS { bool _pixel_snap; bool _allow_hidpi; + uint64_t _fixed_frames; + uint64_t _idle_frames; + bool _in_fixed; + char *last_error; public: @@ -282,6 +286,10 @@ public: uint64_t get_frames_drawn(); + uint64_t get_fixed_frames() const { return _fixed_frames; } + uint64_t get_idle_frames() const { return _idle_frames; } + bool is_in_fixed_frame() const { return _in_fixed; } + bool is_stdout_verbose() const; enum CursorShape { @@ -364,6 +372,7 @@ public: virtual void set_screen_orientation(ScreenOrientation p_orientation); ScreenOrientation get_screen_orientation() const; + virtual void enable_for_stealing_focus(ProcessID pid) {} virtual void move_window_to_foreground() {} virtual void debug_break(); diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 3de26573f4..c3a127afb9 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -33,6 +33,7 @@ #include "io/config_file.h" #include "os/main_loop.h" #include "io/packet_peer.h" +#include "math/a_star.h" #include "globals.h" #include "object_type_db.h" #include "geometry.h" @@ -48,6 +49,7 @@ #include "os/input.h" #include "core/io/xml_parser.h" #include "io/http_client.h" +#include "io/pck_packer.h" #include "packed_data_container.h" #include "func_ref.h" #include "input_map.h" @@ -145,8 +147,11 @@ void register_core_types() { ObjectTypeDB::register_type<ConfigFile>(); + ObjectTypeDB::register_type<PCKPacker>(); + ObjectTypeDB::register_type<PackedDataContainer>(); ObjectTypeDB::register_virtual_type<PackedDataContainerRef>(); + ObjectTypeDB::register_type<AStar>(); ip = IP::create(); diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 99d1e22c07..6d685d3c43 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -134,6 +134,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) { ERR_FAIL(); } + OS::get_singleton()->enable_for_stealing_focus(Globals::get_singleton()->get("editor_pid")); + packet_peer_stream->put_var("debug_enter"); packet_peer_stream->put_var(2); packet_peer_stream->put_var(p_can_continue); @@ -219,7 +221,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) { if (F->get().get_type()==Variant::OBJECT) { packet_peer_stream->put_var("*"+E->get()); - packet_peer_stream->put_var(safe_get_instance_id(F->get())); + String pretty_print = F->get().operator String(); + packet_peer_stream->put_var(pretty_print.ascii().get_data()); } else { packet_peer_stream->put_var(E->get()); packet_peer_stream->put_var(F->get()); @@ -242,7 +245,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) { if (F->get().get_type()==Variant::OBJECT) { packet_peer_stream->put_var("*"+E->get()); - packet_peer_stream->put_var(safe_get_instance_id(F->get())); + String pretty_print = F->get().operator String(); + packet_peer_stream->put_var(pretty_print.ascii().get_data()); } else { packet_peer_stream->put_var(E->get()); packet_peer_stream->put_var(F->get()); @@ -271,6 +275,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) { set_depth(-1); set_lines_left(-1); + OS::get_singleton()->move_window_to_foreground(); break; } else if (command=="break") { ERR_PRINT("Got break when already broke!"); diff --git a/core/script_language.h b/core/script_language.h index 1b037e908c..53af4c74d1 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -122,6 +122,7 @@ public: virtual void get_script_method_list(List<MethodInfo> *p_list) const=0; virtual void get_script_property_list(List<PropertyInfo> *p_list) const=0; + virtual int get_member_line(const StringName& p_member) const { return 0; } Script() {} }; @@ -207,7 +208,26 @@ public: virtual bool has_named_classes() const=0; virtual int find_function(const String& p_function,const String& p_code) const=0; virtual String make_function(const String& p_class,const String& p_name,const StringArray& p_args) const=0; + virtual Error complete_code(const String& p_code, const String& p_base_path, Object*p_owner,List<String>* r_options,String& r_call_hint) { return ERR_UNAVAILABLE; } + + struct LookupResult { + enum Type { + RESULT_SCRIPT_LOCATION, + RESULT_CLASS, + RESULT_CLASS_CONSTANT, + RESULT_CLASS_PROPERTY, + RESULT_CLASS_METHOD + }; + Type type; + Ref<Script> script; + String class_name; + String class_member; + int location; + }; + + virtual Error lookup_code(const String& p_code, const String& p_symbol,const String& p_base_path, Object*p_owner,LookupResult& r_result) { return ERR_UNAVAILABLE; } + virtual void auto_indent_code(String& p_code,int p_from_line,int p_to_line) const=0; virtual void add_global_constant(const StringName& p_variable,const Variant& p_value)=0; diff --git a/core/translation.cpp b/core/translation.cpp index 01789747ea..4592d00598 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -32,11 +32,23 @@ #include "os/os.h" static const char* locale_list[]={ +"aa", // Afar +"aa_DJ", // Afar (Djibouti) +"aa_ER", // Afar (Eritrea) +"aa_ET", // Afar (Ethiopia) +"af", // Afrikaans +"af_ZA", // Afrikaans (South Africa) +"agr_PE", // Aguaruna (Peru) +"ak_GH", // Akan (Ghana) +"am_ET", // Amharic (Ethiopia) +"an_ES", // Aragonese (Spain) +"anp_IN", // Angika (India) "ar", // Arabic "ar_AE", // Arabic (United Arab Emirates) "ar_BH", // Arabic (Bahrain) "ar_DZ", // Arabic (Algeria) "ar_EG", // Arabic (Egypt) +"ar_IN", // Arabic (India) "ar_IQ", // Arabic (Iraq) "ar_JO", // Arabic (Jordan) "ar_KW", // Arabic (Kuwait) @@ -47,48 +59,91 @@ static const char* locale_list[]={ "ar_QA", // Arabic (Qatar) "ar_SA", // Arabic (Saudi Arabia) "ar_SD", // Arabic (Sudan) +"ar_SS", // Arabic (South Soudan) "ar_SY", // Arabic (Syria) "ar_TN", // Arabic (Tunisia) "ar_YE", // Arabic (Yemen) +"as_IN", // Assamese (India) +"ast_ES", // Asturian (Spain) +"ayc_PE", // Southern Aymara (Peru) +"ay_PE", // Aymara (Peru) +"az_AZ", // Azerbaijani (Azerbaijan) "be", // Belarusian "be_BY", // Belarusian (Belarus) +"bem_ZM", // Bemba (Zambia) +"ber_DZ", // Berber languages (Algeria) +"ber_MA", // Berber languages (Morocco) "bg", // Bulgarian "bg_BG", // Bulgarian (Bulgaria) +"bhb_IN", // Bhili (India) +"bho_IN", // Bhojpuri (India) +"bi_TV", // Bislama (Tuvalu) "bn", // Bengali "bn_BD", // Bengali (Bangladesh) "bn_IN", // Bengali (India) +"bo", // Tibetan +"bo_CN", // Tibetan (China) +"bo_IN", // Tibetan (India) +"br_FR", // Breton (France) +"brx_IN", // Bodo (India) +"bs_BA", // Bosnian (Bosnia and Herzegovina) +"byn_ER", // Bilin (Eritrea) "ca", // Catalan +"ca_AD", // Catalan (Andorra) "ca_ES", // Catalan (Spain) +"ca_FR", // Catalan (France) +"ca_IT", // Catalan (Italy) +"ce_RU", // Chechen (Russia) +"chr_US", // Cherokee (United States) +"cmn_TW", // Mandarin Chinese (Taiwan) +"crh_UA", // Crimean Tatar (Ukraine) +"csb_PL", // Kashubian (Poland) "cs", // Czech "cs_CZ", // Czech (Czech Republic) +"cv_RU", // Chuvash (Russia) +"cy_GB", // Welsh (United Kingdom) "da", // Danish "da_DK", // Danish (Denmark) "de", // German "de_AT", // German (Austria) +"de_BE", // German (Belgium) "de_CH", // German (Switzerland) "de_DE", // German (Germany) +"de_IT", // German (Italy) "de_LU", // German (Luxembourg) +"doi_IN", // Dogri (India) +"dv_MV", // Dhivehi (Maldives) +"dz_BT", // Dzongkha (Bhutan) "el", // Greek "el_CY", // Greek (Cyprus) "el_GR", // Greek (Greece) "en", // English +"en_AG", // English (Antigua and Barbuda) "en_AU", // English (Australia) +"en_BW", // English (Botswana) "en_CA", // English (Canada) +"en_DK", // English (Denmark) "en_GB", // English (United Kingdom) +"en_HK", // English (Hong Kong) "en_IE", // English (Ireland) +"en_IL", // English (Israel) "en_IN", // English (India) -"en_MT", // English (Malta) +"en_NG", // English (Nigeria) "en_NZ", // English (New Zealand) "en_PH", // English (Philippines) "en_SG", // English (Singapore) "en_US", // English (United States) "en_ZA", // English (South Africa) +"en_ZM", // English (Zambia) +"en_ZW", // English (Zimbabwe) +"eo", // Esperanto "es", // Spanish "es_AR", // Spanish (Argentina) "es_BO", // Spanish (Bolivia) "es_CL", // Spanish (Chile) "es_CO", // Spanish (Colombia) "es_CR", // Spanish (Costa Rica) +"es_CU", // Spanish (Cuba) "es_DO", // Spanish (Dominican Republic) "es_EC", // Spanish (Ecuador) "es_ES", // Spanish (Spain) @@ -106,100 +161,252 @@ static const char* locale_list[]={ "es_VE", // Spanish (Venezuela) "et", // Estonian "et_EE", // Estonian (Estonia) +"eu", // Basque +"eu_ES", // Basque (Spain) +"fa", // Persian +"fa_IR", // Persian (Iran) +"ff_SN", // Fulah (Senegal) "fi", // Finnish "fi_FI", // Finnish (Finland) +"fil_PH", // Filipino (Philippines) +"fo_FO", // Faroese (Faroe Islands) "fr", // French "fr_BE", // French (Belgium) "fr_CA", // French (Canada) "fr_CH", // French (Switzerland) "fr_FR", // French (France) "fr_LU", // French (Luxembourg) +"fur_IT", // Friulian (Italy) +"fy_DE", // Western Frisian (Germany) +"fy_NL", // Western Frisian (Netherlands) "ga", // Irish "ga_IE", // Irish (Ireland) -"hi", // Hindi (India) +"gd_GB", // Scottish Gaelic (United Kingdom) +"gez_ER", // Geez (Eritrea) +"gez_ET", // Geez (Ethiopia) +"gl_ES", // Galician (Spain) +"gu_IN", // Gujarati (India) +"gv_GB", // Manx (United Kingdom) +"hak_TW", // Hakka Chinese (Taiwan) +"ha_NG", // Hausa (Nigeria) +"he", // Hebrew +"he_IL", // Hebrew (Israel) +"hi", // Hindi "hi_IN", // Hindi (India) +"hne_IN", // Chhattisgarhi (India) "hr", // Croatian "hr_HR", // Croatian (Croatia) +"hsb_DE", // Upper Sorbian (Germany) +"ht_HT", // Haitian (Haiti) "hu", // Hungarian "hu_HU", // Hungarian (Hungary) -"in", // Indonesian -"in_ID", // Indonesian (Indonesia) +"hus_MX", // Huastec (Mexico) +"hy_AM", // Armenian (Armenia) +"ia_FR", // Interlingua (France) +"id", // Indonesian +"id_ID", // Indonesian (Indonesia) +"ig_NG", // Igbo (Nigeria) +"ik_CA", // Inupiaq (Canada) "is", // Icelandic "is_IS", // Icelandic (Iceland) "it", // Italian "it_CH", // Italian (Switzerland) "it_IT", // Italian (Italy) -"iw", // Hebrew -"iw_IL", // Hebrew (Israel) +"iu_CA", // Inuktitut (Canada) "ja", // Japanese "ja_JP", // Japanese (Japan) -"ja_JP_JP", // Japanese (Japan,JP) +"kab_DZ", // Kabyle (Algeria) +"ka_GE", // Georgian (Georgia) +"kk_KZ", // Kazakh (Kazakhstan) +"kl_GL", // Kalaallisut (Greenland) +"km_KH", // Central Khmer (Cambodia) +"kn_IN", // Kannada (India) +"kok_IN", // Konkani (India) "ko", // Korean "ko_KR", // Korean (South Korea) +"ks_IN", // Kashmiri (India) +"ku", // Kurdish +"ku_TR", // Kurdish (Turkey) +"kw_GB", // Cornish (United Kingdom) +"ky_KG", // Kirghiz (Kyrgyzstan) +"lb_LU", // Luxembourgish (Luxembourg) +"lg_UG", // Ganda (Uganda) +"li_BE", // Limburgan (Belgium) +"li_NL", // Limburgan (Netherlands) +"lij_IT", // Ligurian (Italy) +"ln_CD", // Lingala (Congo) +"lo_LA", // Lao (Laos) "lt", // Lithuanian "lt_LT", // Lithuanian (Lithuania) "lv", // Latvian "lv_LV", // Latvian (Latvia) +"lzh_TW", // Literary Chinese (Taiwan) +"mag_IN", // Magahi (India) +"mai_IN", // Maithili (India) +"mg_MG", // Malagasy (Madagascar) +"mh_MH", // Marshallese (Marshall Islands) +"mhr_RU", // Eastern Mari (Russia) +"mi_NZ", // Maori (New Zealand) +"miq_NI", // Mískito (Nicaragua) "mk", // Macedonian "mk_MK", // Macedonian (Macedonia) +"ml_IN", // Malayalam (India) +"mni_IN", // Manipuri (India) +"mn_MN", // Mongolian (Mongolia) +"mr_IN", // Marathi (India) "ms", // Malay "ms_MY", // Malay (Malaysia) "mt", // Maltese "mt_MT", // Maltese (Malta) +"my_MM", // Burmese (Myanmar) +"myv_RU", // Erzya (Russia) +"nah_MX", // Nahuatl languages (Mexico) +"nan_TW", // Min Nan Chinese (Taiwan) +"nb", // Norwegian Bokmål +"nb_NO", // Norwegian Bokmål (Norway) +"nds_DE", // Low German (Germany) +"nds_NL", // Low German (Netherlands) +"ne_NP", // Nepali (Nepal) +"nhn_MX", // Central Nahuatl (Mexico) +"niu_NU", // Niuean (Niue) +"niu_NZ", // Niuean (New Zealand) "nl", // Dutch +"nl_AW", // Dutch (Aruba) "nl_BE", // Dutch (Belgium) "nl_NL", // Dutch (Netherlands) -"no", // Norwegian -"no_NO", // Norwegian (Norway) -"no_NO_NY", // Norwegian (Norway,Nynorsk) +"nn", // Norwegian Nynorsk +"nn_NO", // Norwegian Nynorsk (Norway) +"nr_ZA", // South Ndebele (South Africa) +"nso_ZA", // Pedi (South Africa) +"oc_FR", // Occitan (France) +"om", // Oromo +"om_ET", // Oromo (Ethiopia) +"om_KE", // Oromo (Kenya) +"or_IN", // Oriya (India) +"os_RU", // Ossetian (Russia) +"pa_IN", // Panjabi (India) +"pap", // Papiamento +"pap_AN", // Papiamento (Netherlands Antilles) +"pap_AW", // Papiamento (Aruba) +"pap_CW", // Papiamento (Curaçao) +"pa_PK", // Panjabi (Pakistan) "pl", // Polish "pl_PL", // Polish (Poland) +"ps_AF", // Pushto (Afghanistan) "pt", // Portuguese "pt_BR", // Portuguese (Brazil) "pt_PT", // Portuguese (Portugal) +"quy_PE", // Ayacucho Quechua (Peru) +"quz_PE", // Cusco Quechua (Peru) +"raj_IN", // Rajasthani (India) "ro", // Romanian "ro_RO", // Romanian (Romania) "ru", // Russian "ru_RU", // Russian (Russia) +"ru_UA", // Russian (Ukraine) +"rw_RW", // Kinyarwanda (Rwanda) +"sa_IN", // Sanskrit (India) +"sat_IN", // Santali (India) +"sc_IT", // Sardinian (Italy) +"sd_IN", // Sindhi (India) +"se_NO", // Northern Sami (Norway) +"sgs_LT", // Samogitian (Lithuania) +"shs_CA", // Shuswap (Canada) +"sid_ET", // Sidamo (Ethiopia) +"si_LK", // Sinhala (Sri Lanka) "sk", // Slovak "sk_SK", // Slovak (Slovakia) "sl", // Slovenian "sl_SI", // Slovenian (Slovenia) +"so", // Somali +"so_DJ", // Somali (Djibouti) +"so_ET", // Somali (Ethiopia) +"so_KE", // Somali (Kenya) +"so_SO", // Somali (Somalia) +"son_ML", // Songhai languages (Mali) "sq", // Albanian "sq_AL", // Albanian (Albania) +"sq_KV", // Albanian (Kosovo) +"sq_MK", // Albanian (Macedonia) "sr", // Serbian -"sr_BA", // Serbian (Bosnia and Herzegovina) -"sr_CS", // Serbian (Serbia and Montenegro) "sr_ME", // Serbian (Montenegro) "sr_RS", // Serbian (Serbia) +"ss_ZA", // Swati (South Africa) +"st_ZA", // Southern Sotho (South Africa) "sv", // Swedish +"sv_FI", // Swedish (Finland) "sv_SE", // Swedish (Sweden) +"sw_KE", // Swahili (Kenya) +"sw_TZ", // Swahili (Tanzania) +"szl_PL", // Silesian (Poland) +"ta", // Tamil +"ta_IN", // Tamil (India) +"ta_LK", // Tamil (Sri Lanka) +"tcy_IN", // Tulu (India) +"te_IN", // Telugu (India) +"tg_TJ", // Tajik (Tajikistan) +"the_NP", // Chitwania Tharu (Nepal) "th", // Thai "th_TH", // Thai (Thailand) -"th_TH_TH", // Thai (Thailand,TH) +"ti", // Tigrinya +"ti_ER", // Tigrinya (Eritrea) +"ti_ET", // Tigrinya (Ethiopia) +"tig_ER", // Tigre (Eritrea) +"tk_TM", // Turkmen (Turkmenistan) +"tl_PH", // Tagalog (Philippines) +"tn_ZA", // Tswana (South Africa) "tr", // Turkish +"tr_CY", // Turkish (Cyprus) "tr_TR", // Turkish (Turkey) +"ts_ZA", // Tsonga (South Africa) +"tt_RU", // Tatar (Russia) +"ug_CN", // Uighur (China) "uk", // Ukrainian "uk_UA", // Ukrainian (Ukraine) +"unm_US", // Unami (United States) "ur", // Urdu "ur_IN", // Urdu (India) "ur_PK", // Urdu (Pakistan) +"uz", // Uzbek +"uz_UZ", // Uzbek (Uzbekistan) +"ve_ZA", // Venda (South Africa) "vi", // Vietnamese "vi_VN", // Vietnamese (Vietnam) +"wa_BE", // Walloon (Belgium) +"wae_CH", // Walser (Switzerland) +"wal_ET", // Wolaytta (Ethiopia) +"wo_SN", // Wolof (Senegal) +"xh_ZA", // Xhosa (South Africa) +"yi_US", // Yiddish (United States) +"yo_NG", // Yoruba (Nigeria) +"yue_HK", // Yue Chinese (Hong Kong) "zh", // Chinese "zh_CN", // Chinese (China) "zh_HK", // Chinese (Hong Kong) "zh_SG", // Chinese (Singapore) "zh_TW", // Chinese (Taiwan) +"zu_ZA", // Zulu (South Africa) 0 }; static const char* locale_names[]={ +"Afar", +"Afar (Djibouti)", +"Afar (Eritrea)", +"Afar (Ethiopia)", +"Afrikaans", +"Afrikaans (South Africa)", +"Aguaruna (Peru)", +"Akan (Ghana)", +"Amharic (Ethiopia)", +"Aragonese (Spain)", +"Angika (India)", "Arabic", "Arabic (United Arab Emirates)", "Arabic (Bahrain)", "Arabic (Algeria)", "Arabic (Egypt)", +"Arabic (India)", "Arabic (Iraq)", "Arabic (Jordan)", "Arabic (Kuwait)", @@ -210,48 +417,91 @@ static const char* locale_names[]={ "Arabic (Qatar)", "Arabic (Saudi Arabia)", "Arabic (Sudan)", +"Arabic (South Soudan)", "Arabic (Syria)", "Arabic (Tunisia)", "Arabic (Yemen)", +"Assamese (India)", +"Asturian (Spain)", +"Southern Aymara (Peru)", +"Aymara (Peru)", +"Azerbaijani (Azerbaijan)", "Belarusian", "Belarusian (Belarus)", +"Bemba (Zambia)", +"Berber languages (Algeria)", +"Berber languages (Morocco)", "Bulgarian", "Bulgarian (Bulgaria)", +"Bhili (India)", +"Bhojpuri (India)", +"Bislama (Tuvalu)", "Bengali", "Bengali (Bangladesh)", "Bengali (India)", +"Tibetan", +"Tibetan (China)", +"Tibetan (India)", +"Breton (France)", +"Bodo (India)", +"Bosnian (Bosnia and Herzegovina)", +"Bilin (Eritrea)", "Catalan", +"Catalan (Andorra)", "Catalan (Spain)", +"Catalan (France)", +"Catalan (Italy)", +"Chechen (Russia)", +"Cherokee (United States)", +"Mandarin Chinese (Taiwan)", +"Crimean Tatar (Ukraine)", +"Kashubian (Poland)", "Czech", "Czech (Czech Republic)", +"Chuvash (Russia)", +"Welsh (United Kingdom)", "Danish", "Danish (Denmark)", "German", "German (Austria)", +"German (Belgium)", "German (Switzerland)", "German (Germany)", +"German (Italy)", "German (Luxembourg)", +"Dogri (India)", +"Dhivehi (Maldives)", +"Dzongkha (Bhutan)", "Greek", "Greek (Cyprus)", "Greek (Greece)", "English", +"English (Antigua and Barbuda)", "English (Australia)", +"English (Botswana)", "English (Canada)", +"English (Denmark)", "English (United Kingdom)", +"English (Hong Kong)", "English (Ireland)", +"English (Israel)", "English (India)", -"English (Malta)", +"English (Nigeria)", "English (New Zealand)", "English (Philippines)", "English (Singapore)", "English (United States)", "English (South Africa)", +"English (Zambia)", +"English (Zimbabwe)", +"Esperanto", "Spanish", "Spanish (Argentina)", "Spanish (Bolivia)", "Spanish (Chile)", "Spanish (Colombia)", "Spanish (Costa Rica)", +"Spanish (Cuba)", "Spanish (Dominican Republic)", "Spanish (Ecuador)", "Spanish (Spain)", @@ -269,91 +519,231 @@ static const char* locale_names[]={ "Spanish (Venezuela)", "Estonian", "Estonian (Estonia)", +"Basque", +"Basque (Spain)", +"Persian", +"Persian (Iran)", +"Fulah (Senegal)", "Finnish", "Finnish (Finland)", +"Filipino (Philippines)", +"Faroese (Faroe Islands)", "French", "French (Belgium)", "French (Canada)", "French (Switzerland)", "French (France)", "French (Luxembourg)", +"Friulian (Italy)", +"Western Frisian (Germany)", +"Western Frisian (Netherlands)", "Irish", "Irish (Ireland)", +"Scottish Gaelic (United Kingdom)", +"Geez (Eritrea)", +"Geez (Ethiopia)", +"Galician (Spain)", +"Gujarati (India)", +"Manx (United Kingdom)", +"Hakka Chinese (Taiwan)", +"Hausa (Nigeria)", +"Hebrew", +"Hebrew (Israel)", +"Hindi", "Hindi (India)", -"Hindi (India)", +"Chhattisgarhi (India)", "Croatian", "Croatian (Croatia)", +"Upper Sorbian (Germany)", +"Haitian (Haiti)", "Hungarian", "Hungarian (Hungary)", +"Huastec (Mexico)", +"Armenian (Armenia)", +"Interlingua (France)", "Indonesian", "Indonesian (Indonesia)", +"Igbo (Nigeria)", +"Inupiaq (Canada)", "Icelandic", "Icelandic (Iceland)", "Italian", "Italian (Switzerland)", "Italian (Italy)", -"Hebrew", -"Hebrew (Israel)", +"Inuktitut (Canada)", "Japanese", "Japanese (Japan)", -"Japanese (Japan JP)", +"Kabyle (Algeria)", +"Georgian (Georgia)", +"Kazakh (Kazakhstan)", +"Kalaallisut (Greenland)", +"Central Khmer (Cambodia)", +"Kannada (India)", +"Konkani (India)", "Korean", "Korean (South Korea)", +"Kashmiri (India)", +"Kurdish", +"Kurdish (Turkey)", +"Cornish (United Kingdom)", +"Kirghiz (Kyrgyzstan)", +"Luxembourgish (Luxembourg)", +"Ganda (Uganda)", +"Limburgan (Belgium)", +"Limburgan (Netherlands)", +"Ligurian (Italy)", +"Lingala (Congo)", +"Lao (Laos)", "Lithuanian", "Lithuanian (Lithuania)", "Latvian", "Latvian (Latvia)", +"Literary Chinese (Taiwan)", +"Magahi (India)", +"Maithili (India)", +"Malagasy (Madagascar)", +"Marshallese (Marshall Islands)", +"Eastern Mari (Russia)", +"Maori (New Zealand)", +"Mískito (Nicaragua)", "Macedonian", "Macedonian (Macedonia)", +"Malayalam (India)", +"Manipuri (India)", +"Mongolian (Mongolia)", +"Marathi (India)", "Malay", "Malay (Malaysia)", "Maltese", "Maltese (Malta)", +"Burmese (Myanmar)", +"Erzya (Russia)", +"Nahuatl languages (Mexico)", +"Min Nan Chinese (Taiwan)", +"Norwegian Bokmål", +"Norwegian Bokmål (Norway)", +"Low German (Germany)", +"Low German (Netherlands)", +"Nepali (Nepal)", +"Central Nahuatl (Mexico)", +"Niuean (Niue)", +"Niuean (New Zealand)", "Dutch", +"Dutch (Aruba)", "Dutch (Belgium)", "Dutch (Netherlands)", -"Norwegian", -"Norwegian (Norway)", -"Norwegian (Norway Nynorsk)", +"Norwegian Nynorsk", +"Norwegian Nynorsk (Norway)", +"South Ndebele (South Africa)", +"Pedi (South Africa)", +"Occitan (France)", +"Oromo", +"Oromo (Ethiopia)", +"Oromo (Kenya)", +"Oriya (India)", +"Ossetian (Russia)", +"Panjabi (India)", +"Papiamento", +"Papiamento (Netherlands Antilles)", +"Papiamento (Aruba)", +"Papiamento (Curaçao)", +"Panjabi (Pakistan)", "Polish", "Polish (Poland)", +"Pushto (Afghanistan)", "Portuguese", "Portuguese (Brazil)", "Portuguese (Portugal)", +"Ayacucho Quechua (Peru)", +"Cusco Quechua (Peru)", +"Rajasthani (India)", "Romanian", "Romanian (Romania)", "Russian", "Russian (Russia)", +"Russian (Ukraine)", +"Kinyarwanda (Rwanda)", +"Sanskrit (India)", +"Santali (India)", +"Sardinian (Italy)", +"Sindhi (India)", +"Northern Sami (Norway)", +"Samogitian (Lithuania)", +"Shuswap (Canada)", +"Sidamo (Ethiopia)", +"Sinhala (Sri Lanka)", "Slovak", "Slovak (Slovakia)", "Slovenian", "Slovenian (Slovenia)", +"Somali", +"Somali (Djibouti)", +"Somali (Ethiopia)", +"Somali (Kenya)", +"Somali (Somalia)", +"Songhai languages (Mali)", "Albanian", "Albanian (Albania)", +"Albanian (Kosovo)", +"Albanian (Macedonia)", "Serbian", -"Serbian (Bosnia and Herzegovina)", -"Serbian (Serbia and Montenegro)", "Serbian (Montenegro)", "Serbian (Serbia)", +"Swati (South Africa)", +"Southern Sotho (South Africa)", "Swedish", +"Swedish (Finland)", "Swedish (Sweden)", +"Swahili (Kenya)", +"Swahili (Tanzania)", +"Silesian (Poland)", +"Tamil", +"Tamil (India)", +"Tamil (Sri Lanka)", +"Tulu (India)", +"Telugu (India)", +"Tajik (Tajikistan)", +"Chitwania Tharu (Nepal)", "Thai", "Thai (Thailand)", -"Thai (Thailand TH)", +"Tigrinya", +"Tigrinya (Eritrea)", +"Tigrinya (Ethiopia)", +"Tigre (Eritrea)", +"Turkmen (Turkmenistan)", +"Tagalog (Philippines)", +"Tswana (South Africa)", "Turkish", +"Turkish (Cyprus)", "Turkish (Turkey)", +"Tsonga (South Africa)", +"Tatar (Russia)", +"Uighur (China)", "Ukrainian", "Ukrainian (Ukraine)", +"Unami (United States)", "Urdu", "Urdu (India)", "Urdu (Pakistan)", +"Uzbek", +"Uzbek (Uzbekistan)", +"Venda (South Africa)", "Vietnamese", "Vietnamese (Vietnam)", +"Walloon (Belgium)", +"Walser (Switzerland)", +"Wolaytta (Ethiopia)", +"Wolof (Senegal)", +"Xhosa (South Africa)", +"Yiddish (United States)", +"Yoruba (Nigeria)", +"Yue Chinese (Hong Kong)", "Chinese", "Chinese (China)", "Chinese (Hong Kong)", "Chinese (Singapore)", "Chinese (Taiwan)", +"Zulu (South Africa)", 0 }; diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp index 99740b365c..e8a71d4991 100644 --- a/core/undo_redo.cpp +++ b/core/undo_redo.cpp @@ -490,13 +490,9 @@ void UndoRedo::_bind_methods() { mi.name="add_do_method"; mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object")); mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); - Vector<Variant> defargs; - for(int i=0;i<VARIANT_ARG_MAX;++i) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_do_method",&UndoRedo::_add_do_method,mi,defargs); + + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"add_do_method",&UndoRedo::_add_do_method,mi); } { @@ -504,13 +500,9 @@ void UndoRedo::_bind_methods() { mi.name="add_undo_method"; mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object")); mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); - Vector<Variant> defargs; - for(int i=0;i<VARIANT_ARG_MAX;++i) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_undo_method",&UndoRedo::_add_undo_method,mi,defargs); + + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"add_undo_method",&UndoRedo::_add_undo_method,mi); } ObjectTypeDB::bind_method(_MD("add_do_property","object", "property", "value:Variant"),&UndoRedo::add_do_property); diff --git a/core/ustring.cpp b/core/ustring.cpp index 0d887210c3..2e907381f7 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3073,6 +3073,11 @@ String String::simplify_path() const { } s =s.replace("\\","/"); + while(true){ // in case of using 2 or more slash + String compare = s.replace("//","/"); + if (s==compare) break; + else s=compare; + } Vector<String> dirs = s.split("/",false); for(int i=0;i<dirs.size();i++) { @@ -3173,7 +3178,7 @@ bool String::is_valid_identifier() const { //kind of poor should be rewritten properly -String String::world_wrap(int p_chars_per_line) const { +String String::word_wrap(int p_chars_per_line) const { int from=0; int last_space=0; diff --git a/core/ustring.h b/core/ustring.h index bb57b11d88..09d13a9e64 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -218,7 +218,7 @@ public: String c_escape() const; String c_unescape() const; String json_escape() const; - String world_wrap(int p_chars_per_line) const; + String word_wrap(int p_chars_per_line) const; String percent_encode() const; String percent_decode() const; diff --git a/core/variant.cpp b/core/variant.cpp index a78c07d819..b2afc9d080 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -429,6 +429,7 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) { return true; i++; } + } else if (invalid_types) { @@ -439,6 +440,8 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) { return false; i++; } + + return true; } return false; @@ -457,7 +460,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from,Variant::Type p_type_ }; const Type *valid_types=NULL; - const Type *invalid_types=NULL; switch(p_type_to) { case BOOL: { @@ -679,16 +681,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from,Variant::Type p_type_ return true; i++; } - } else if (invalid_types) { - - - int i=0; - while(invalid_types[i]!=NIL) { - - if (p_type_from==invalid_types[i]) - return false; - i++; - } } return false; diff --git a/core/variant.h b/core/variant.h index b8b028a760..90be593bd9 100644 --- a/core/variant.h +++ b/core/variant.h @@ -426,7 +426,7 @@ public: static void get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list); static void get_numeric_constants_for_type(Variant::Type p_type, List<StringName> *p_constants); static bool has_numeric_constant(Variant::Type p_type, const StringName& p_value); - static int get_numeric_constant_value(Variant::Type p_type, const StringName& p_value); + static int get_numeric_constant_value(Variant::Type p_type, const StringName& p_value,bool *r_valid=NULL); typedef String (*ObjectDeConstruct)(const Variant& p_object,void *ud); typedef void (*ObjectConstruct)(const String& p_text,void *ud,Variant& r_value); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 069c20bc6e..51cd4c2399 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -54,10 +54,10 @@ struct _VariantCall { int arg_count; Vector<Variant> default_args; Vector<Variant::Type> arg_types; - -#ifdef DEBUG_ENABLED Vector<StringName> arg_names; Variant::Type return_type; + +#ifdef DEBUG_ENABLED bool returns; #endif VariantFunc func; @@ -346,6 +346,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM0R(Vector2,angle); // VCALL_LOCALMEM1R(Vector2,cross); VCALL_LOCALMEM0R(Vector2,abs); + VCALL_LOCALMEM1R(Vector2,clamped); VCALL_LOCALMEM0R(Rect2,get_area); VCALL_LOCALMEM1R(Rect2,intersects); @@ -374,6 +375,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM0R(Vector3, ceil); VCALL_LOCALMEM1R(Vector3, distance_to); VCALL_LOCALMEM1R(Vector3, distance_squared_to); + VCALL_LOCALMEM1R(Vector3, angle_to); VCALL_LOCALMEM1R(Vector3, slide); VCALL_LOCALMEM1R(Vector3, reflect); @@ -464,8 +466,8 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM0R(Array,hash); VCALL_LOCALMEM1(Array,push_back); VCALL_LOCALMEM1(Array,push_front); - VCALL_LOCALMEM0(Array,pop_back); - VCALL_LOCALMEM0(Array,pop_front); + VCALL_LOCALMEM0R(Array,pop_back); + VCALL_LOCALMEM0R(Array,pop_front); VCALL_LOCALMEM1(Array,append); VCALL_LOCALMEM1(Array,resize); VCALL_LOCALMEM2(Array,insert); @@ -518,6 +520,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM1(ByteArray,append); VCALL_LOCALMEM1(ByteArray,append_array); VCALL_LOCALMEM0(ByteArray,invert); + VCALL_LOCALMEM2R(ByteArray,subarray); VCALL_LOCALMEM0R(IntArray,size); VCALL_LOCALMEM2(IntArray,set); @@ -1324,14 +1327,22 @@ bool Variant::has_numeric_constant(Variant::Type p_type, const StringName& p_val return cd.value.has(p_value); } -int Variant::get_numeric_constant_value(Variant::Type p_type, const StringName& p_value) { +int Variant::get_numeric_constant_value(Variant::Type p_type, const StringName& p_value, bool *r_valid) { + + if (r_valid) + *r_valid=false; ERR_FAIL_INDEX_V(p_type,Variant::VARIANT_MAX,0); _VariantCall::ConstantData& cd = _VariantCall::constant_data[p_type]; Map<StringName,int>::Element *E = cd.value.find(p_value); - ERR_FAIL_COND_V(!E,0); + if (!E) { + return -1; + } + if (r_valid) + *r_valid=true; + return E->get(); } @@ -1448,6 +1459,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(VECTOR2,VECTOR2,Vector2,reflect,VECTOR2,"vec",varray()); //ADDFUNC1(VECTOR2,REAL,Vector2,cross,VECTOR2,"with",varray()); ADDFUNC0(VECTOR2,VECTOR2,Vector2,abs,varray()); + ADDFUNC1(VECTOR2,VECTOR2,Vector2,clamped,REAL,"length",varray()); ADDFUNC0(RECT2,REAL,Rect2,get_area,varray()); ADDFUNC1(RECT2,BOOL,Rect2,intersects,RECT2,"b",varray()); @@ -1476,6 +1488,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC0(VECTOR3,VECTOR3,Vector3,ceil,varray()); ADDFUNC1(VECTOR3,REAL,Vector3,distance_to,VECTOR3,"b",varray()); ADDFUNC1(VECTOR3,REAL,Vector3,distance_squared_to,VECTOR3,"b",varray()); + ADDFUNC1(VECTOR3,REAL,Vector3,angle_to,VECTOR3,"to",varray()); ADDFUNC1(VECTOR3,VECTOR3,Vector3,slide,VECTOR3,"by",varray()); ADDFUNC1(VECTOR3,VECTOR3,Vector3,reflect,VECTOR3,"by",varray()); @@ -1584,6 +1597,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC2(RAW_ARRAY,INT,ByteArray,insert,INT,"idx",INT,"byte",varray()); ADDFUNC1(RAW_ARRAY,NIL,ByteArray,resize,INT,"idx",varray()); ADDFUNC0(RAW_ARRAY,NIL,ByteArray,invert,varray()); + ADDFUNC2(RAW_ARRAY,RAW_ARRAY,ByteArray,subarray,INT,"from",INT,"to",varray()); ADDFUNC0(RAW_ARRAY,STRING,ByteArray,get_string_from_ascii,varray()); ADDFUNC0(RAW_ARRAY,STRING,ByteArray,get_string_from_utf8,varray()); diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 023605a952..6b3828a572 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -986,7 +986,18 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in InputEvent ie; - if (id=="KEY") { + if (id=="NONE") { + + ie.type=InputEvent::NONE; + + get_token(p_stream,token,line,r_err_str); + + if (token.type!=TK_PARENTHESIS_CLOSE) { + r_err_str="Expected ')'"; + return ERR_PARSE_ERROR; + } + + } else if (id=="KEY") { get_token(p_stream,token,line,r_err_str); if (token.type!=TK_COMMA) { @@ -2093,6 +2104,9 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str case InputEvent::JOYSTICK_MOTION: { str+="JAXIS,"+itos(ev.joy_motion.axis)+","+itos(ev.joy_motion.axis_value); } break; + case InputEvent::NONE: { + str+="NONE"; + } break; default: {} } |