1 /*************************************************************************/
2 /*  area_2d.cpp                                                          */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 #include "area_2d.h"
31 #include "scene/scene_string_names.h"
32 #include "servers/physics_2d_server.h"
set_space_override_mode(SpaceOverride p_mode)33 void Area2D::set_space_override_mode(SpaceOverride p_mode) {
34 
35 	space_override = p_mode;
36 	Physics2DServer::get_singleton()->area_set_space_override_mode(get_rid(), Physics2DServer::AreaSpaceOverrideMode(p_mode));
37 }
get_space_override_mode() const38 Area2D::SpaceOverride Area2D::get_space_override_mode() const {
39 
40 	return space_override;
41 }
42 
set_gravity_is_point(bool p_enabled)43 void Area2D::set_gravity_is_point(bool p_enabled) {
44 
45 	gravity_is_point = p_enabled;
46 	Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_GRAVITY_IS_POINT, p_enabled);
47 }
is_gravity_a_point() const48 bool Area2D::is_gravity_a_point() const {
49 
50 	return gravity_is_point;
51 }
52 
set_gravity_distance_scale(real_t p_scale)53 void Area2D::set_gravity_distance_scale(real_t p_scale) {
54 
55 	gravity_distance_scale = p_scale;
56 	Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale);
57 }
58 
get_gravity_distance_scale() const59 real_t Area2D::get_gravity_distance_scale() const {
60 	return gravity_distance_scale;
61 }
62 
set_gravity_vector(const Vector2 & p_vec)63 void Area2D::set_gravity_vector(const Vector2 &p_vec) {
64 
65 	gravity_vec = p_vec;
66 	Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_GRAVITY_VECTOR, p_vec);
67 }
get_gravity_vector() const68 Vector2 Area2D::get_gravity_vector() const {
69 
70 	return gravity_vec;
71 }
72 
set_gravity(real_t p_gravity)73 void Area2D::set_gravity(real_t p_gravity) {
74 
75 	gravity = p_gravity;
76 	Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_GRAVITY, p_gravity);
77 }
get_gravity() const78 real_t Area2D::get_gravity() const {
79 
80 	return gravity;
81 }
82 
set_linear_damp(real_t p_linear_damp)83 void Area2D::set_linear_damp(real_t p_linear_damp) {
84 
85 	linear_damp = p_linear_damp;
86 	Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_LINEAR_DAMP, p_linear_damp);
87 }
get_linear_damp() const88 real_t Area2D::get_linear_damp() const {
89 
90 	return linear_damp;
91 }
92 
set_angular_damp(real_t p_angular_damp)93 void Area2D::set_angular_damp(real_t p_angular_damp) {
94 
95 	angular_damp = p_angular_damp;
96 	Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_ANGULAR_DAMP, p_angular_damp);
97 }
98 
get_angular_damp() const99 real_t Area2D::get_angular_damp() const {
100 
101 	return angular_damp;
102 }
103 
set_priority(real_t p_priority)104 void Area2D::set_priority(real_t p_priority) {
105 
106 	priority = p_priority;
107 	Physics2DServer::get_singleton()->area_set_param(get_rid(), Physics2DServer::AREA_PARAM_PRIORITY, p_priority);
108 }
get_priority() const109 real_t Area2D::get_priority() const {
110 
111 	return priority;
112 }
113 
_body_enter_tree(ObjectID p_id)114 void Area2D::_body_enter_tree(ObjectID p_id) {
115 
116 	Object *obj = ObjectDB::get_instance(p_id);
117 	Node *node = obj ? obj->cast_to<Node>() : NULL;
118 	ERR_FAIL_COND(!node);
119 
120 	Map<ObjectID, BodyState>::Element *E = body_map.find(p_id);
121 	ERR_FAIL_COND(!E);
122 	ERR_FAIL_COND(E->get().in_tree);
123 
124 	E->get().in_tree = true;
125 	emit_signal(SceneStringNames::get_singleton()->body_enter, node);
126 	for (int i = 0; i < E->get().shapes.size(); i++) {
127 
128 		emit_signal(SceneStringNames::get_singleton()->body_enter_shape, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
129 	}
130 }
131 
_body_exit_tree(ObjectID p_id)132 void Area2D::_body_exit_tree(ObjectID p_id) {
133 
134 	Object *obj = ObjectDB::get_instance(p_id);
135 	Node *node = obj ? obj->cast_to<Node>() : NULL;
136 	ERR_FAIL_COND(!node);
137 	Map<ObjectID, BodyState>::Element *E = body_map.find(p_id);
138 	ERR_FAIL_COND(!E);
139 	ERR_FAIL_COND(!E->get().in_tree);
140 	E->get().in_tree = false;
141 	emit_signal(SceneStringNames::get_singleton()->body_exit, node);
142 	for (int i = 0; i < E->get().shapes.size(); i++) {
143 
144 		emit_signal(SceneStringNames::get_singleton()->body_exit_shape, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
145 	}
146 }
147 
_body_inout(int p_status,const RID & p_body,int p_instance,int p_body_shape,int p_area_shape)148 void Area2D::_body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape) {
149 
150 	bool body_in = p_status == Physics2DServer::AREA_BODY_ADDED;
151 	ObjectID objid = p_instance;
152 
153 	Object *obj = ObjectDB::get_instance(objid);
154 	Node *node = obj ? obj->cast_to<Node>() : NULL;
155 
156 	Map<ObjectID, BodyState>::Element *E = body_map.find(objid);
157 
158 	ERR_FAIL_COND(!body_in && !E);
159 
160 	locked = true;
161 
162 	if (body_in) {
163 		if (!E) {
164 
165 			E = body_map.insert(objid, BodyState());
166 			E->get().rc = 0;
167 			E->get().in_tree = node && node->is_inside_tree();
168 			if (node) {
169 				node->connect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_body_enter_tree, make_binds(objid));
170 				node->connect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_body_exit_tree, make_binds(objid));
171 				if (E->get().in_tree) {
172 					emit_signal(SceneStringNames::get_singleton()->body_enter, node);
173 				}
174 			}
175 		}
176 		E->get().rc++;
177 		if (node)
178 			E->get().shapes.insert(ShapePair(p_body_shape, p_area_shape));
179 
180 		if (!node || E->get().in_tree) {
181 			emit_signal(SceneStringNames::get_singleton()->body_enter_shape, objid, node, p_body_shape, p_area_shape);
182 		}
183 
184 	} else {
185 
186 		E->get().rc--;
187 
188 		if (node)
189 			E->get().shapes.erase(ShapePair(p_body_shape, p_area_shape));
190 
191 		bool eraseit = false;
192 
193 		if (E->get().rc == 0) {
194 
195 			if (node) {
196 				node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_body_enter_tree);
197 				node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_body_exit_tree);
198 				if (E->get().in_tree)
199 					emit_signal(SceneStringNames::get_singleton()->body_exit, obj);
200 			}
201 
202 			eraseit = true;
203 		}
204 		if (!node || E->get().in_tree) {
205 			emit_signal(SceneStringNames::get_singleton()->body_exit_shape, objid, obj, p_body_shape, p_area_shape);
206 		}
207 
208 		if (eraseit)
209 			body_map.erase(E);
210 	}
211 
212 	locked = false;
213 }
214 
_area_enter_tree(ObjectID p_id)215 void Area2D::_area_enter_tree(ObjectID p_id) {
216 
217 	Object *obj = ObjectDB::get_instance(p_id);
218 	Node *node = obj ? obj->cast_to<Node>() : NULL;
219 	ERR_FAIL_COND(!node);
220 
221 	Map<ObjectID, AreaState>::Element *E = area_map.find(p_id);
222 	ERR_FAIL_COND(!E);
223 	ERR_FAIL_COND(E->get().in_tree);
224 
225 	E->get().in_tree = true;
226 	emit_signal(SceneStringNames::get_singleton()->area_enter, node);
227 	for (int i = 0; i < E->get().shapes.size(); i++) {
228 
229 		emit_signal(SceneStringNames::get_singleton()->area_enter_shape, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
230 	}
231 }
232 
_area_exit_tree(ObjectID p_id)233 void Area2D::_area_exit_tree(ObjectID p_id) {
234 
235 	Object *obj = ObjectDB::get_instance(p_id);
236 	Node *node = obj ? obj->cast_to<Node>() : NULL;
237 	ERR_FAIL_COND(!node);
238 	Map<ObjectID, AreaState>::Element *E = area_map.find(p_id);
239 	ERR_FAIL_COND(!E);
240 	ERR_FAIL_COND(!E->get().in_tree);
241 	E->get().in_tree = false;
242 	emit_signal(SceneStringNames::get_singleton()->area_exit, node);
243 	for (int i = 0; i < E->get().shapes.size(); i++) {
244 
245 		emit_signal(SceneStringNames::get_singleton()->area_exit_shape, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
246 	}
247 }
248 
_area_inout(int p_status,const RID & p_area,int p_instance,int p_area_shape,int p_self_shape)249 void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape) {
250 
251 	bool area_in = p_status == Physics2DServer::AREA_BODY_ADDED;
252 	ObjectID objid = p_instance;
253 
254 	Object *obj = ObjectDB::get_instance(objid);
255 	Node *node = obj ? obj->cast_to<Node>() : NULL;
256 
257 	Map<ObjectID, AreaState>::Element *E = area_map.find(objid);
258 
259 	ERR_FAIL_COND(!area_in && !E);
260 
261 	locked = true;
262 
263 	if (area_in) {
264 		if (!E) {
265 
266 			E = area_map.insert(objid, AreaState());
267 			E->get().rc = 0;
268 			E->get().in_tree = node && node->is_inside_tree();
269 			if (node) {
270 				node->connect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_area_enter_tree, make_binds(objid));
271 				node->connect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_area_exit_tree, make_binds(objid));
272 				if (E->get().in_tree) {
273 					emit_signal(SceneStringNames::get_singleton()->area_enter, node);
274 				}
275 			}
276 		}
277 		E->get().rc++;
278 		if (node)
279 			E->get().shapes.insert(AreaShapePair(p_area_shape, p_self_shape));
280 
281 		if (!node || E->get().in_tree) {
282 			emit_signal(SceneStringNames::get_singleton()->area_enter_shape, objid, node, p_area_shape, p_self_shape);
283 		}
284 
285 	} else {
286 
287 		E->get().rc--;
288 
289 		if (node)
290 			E->get().shapes.erase(AreaShapePair(p_area_shape, p_self_shape));
291 
292 		bool eraseit = false;
293 
294 		if (E->get().rc == 0) {
295 
296 			if (node) {
297 				node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_area_enter_tree);
298 				node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_area_exit_tree);
299 				if (E->get().in_tree)
300 					emit_signal(SceneStringNames::get_singleton()->area_exit, obj);
301 			}
302 
303 			eraseit = true;
304 		}
305 		if (!node || E->get().in_tree) {
306 			emit_signal(SceneStringNames::get_singleton()->area_exit_shape, objid, obj, p_area_shape, p_self_shape);
307 		}
308 
309 		if (eraseit)
310 			area_map.erase(E);
311 	}
312 
313 	locked = false;
314 }
315 
_clear_monitoring()316 void Area2D::_clear_monitoring() {
317 
318 	if (locked) {
319 		ERR_EXPLAIN("This function can't be used during the in/out signal.");
320 	}
321 	ERR_FAIL_COND(locked);
322 
323 	{
324 		Map<ObjectID, BodyState> bmcopy = body_map;
325 		body_map.clear();
326 		//disconnect all monitored stuff
327 
328 		for (Map<ObjectID, BodyState>::Element *E = bmcopy.front(); E; E = E->next()) {
329 
330 			Object *obj = ObjectDB::get_instance(E->key());
331 			Node *node = obj ? obj->cast_to<Node>() : NULL;
332 
333 			if (!node) //node may have been deleted in previous frame or at other legiminate point
334 				continue;
335 			//ERR_CONTINUE(!node);
336 
337 			node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_body_enter_tree);
338 			node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_body_exit_tree);
339 
340 			if (!E->get().in_tree)
341 				continue;
342 
343 			for (int i = 0; i < E->get().shapes.size(); i++) {
344 
345 				emit_signal(SceneStringNames::get_singleton()->body_exit_shape, E->key(), node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
346 			}
347 
348 			emit_signal(SceneStringNames::get_singleton()->body_exit, obj);
349 		}
350 	}
351 
352 	{
353 
354 		Map<ObjectID, AreaState> bmcopy = area_map;
355 		area_map.clear();
356 		//disconnect all monitored stuff
357 
358 		for (Map<ObjectID, AreaState>::Element *E = bmcopy.front(); E; E = E->next()) {
359 
360 			Object *obj = ObjectDB::get_instance(E->key());
361 			Node *node = obj ? obj->cast_to<Node>() : NULL;
362 
363 			if (!node) //node may have been deleted in previous frame or at other legiminate point
364 				continue;
365 			//ERR_CONTINUE(!node);
366 
367 			node->disconnect(SceneStringNames::get_singleton()->enter_tree, this, SceneStringNames::get_singleton()->_area_enter_tree);
368 			node->disconnect(SceneStringNames::get_singleton()->exit_tree, this, SceneStringNames::get_singleton()->_area_exit_tree);
369 
370 			if (!E->get().in_tree)
371 				continue;
372 
373 			for (int i = 0; i < E->get().shapes.size(); i++) {
374 
375 				emit_signal(SceneStringNames::get_singleton()->area_exit_shape, E->key(), node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
376 			}
377 
378 			emit_signal(SceneStringNames::get_singleton()->area_exit, obj);
379 		}
380 	}
381 }
382 
_notification(int p_what)383 void Area2D::_notification(int p_what) {
384 
385 	switch (p_what) {
386 
387 		case NOTIFICATION_EXIT_TREE: {
388 
389 			monitoring_stored = monitoring;
390 			set_enable_monitoring(false);
391 			_clear_monitoring();
392 		} break;
393 		case NOTIFICATION_ENTER_TREE: {
394 
395 			if (monitoring_stored) {
396 				set_enable_monitoring(true);
397 				monitoring_stored = false;
398 			}
399 		} break;
400 	}
401 }
402 
set_enable_monitoring(bool p_enable)403 void Area2D::set_enable_monitoring(bool p_enable) {
404 
405 	if (!is_inside_tree()) {
406 		monitoring_stored = p_enable;
407 		return;
408 	}
409 
410 	if (p_enable == monitoring)
411 		return;
412 
413 	if (locked) {
414 		ERR_EXPLAIN("Function blocked during in/out signal. Use call_deferred(\"set_enable_monitoring\",true/false)");
415 	}
416 	ERR_FAIL_COND(locked);
417 
418 	monitoring = p_enable;
419 
420 	if (monitoring) {
421 
422 		Physics2DServer::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout);
423 		Physics2DServer::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout);
424 
425 	} else {
426 		Physics2DServer::get_singleton()->area_set_monitor_callback(get_rid(), NULL, StringName());
427 		Physics2DServer::get_singleton()->area_set_area_monitor_callback(get_rid(), NULL, StringName());
428 		_clear_monitoring();
429 	}
430 }
431 
is_monitoring_enabled() const432 bool Area2D::is_monitoring_enabled() const {
433 
434 	return monitoring || monitoring_stored;
435 }
436 
set_monitorable(bool p_enable)437 void Area2D::set_monitorable(bool p_enable) {
438 
439 	if (locked) {
440 		ERR_EXPLAIN("This function can't be used during the in/out signal.");
441 	}
442 	ERR_FAIL_COND(locked);
443 
444 	if (p_enable == monitorable)
445 		return;
446 
447 	monitorable = p_enable;
448 
449 	Physics2DServer::get_singleton()->area_set_monitorable(get_rid(), monitorable);
450 }
451 
is_monitorable() const452 bool Area2D::is_monitorable() const {
453 
454 	return monitorable;
455 }
456 
get_overlapping_bodies() const457 Array Area2D::get_overlapping_bodies() const {
458 
459 	ERR_FAIL_COND_V(!monitoring, Array());
460 	Array ret;
461 	ret.resize(body_map.size());
462 	int idx = 0;
463 	for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) {
464 		Object *obj = ObjectDB::get_instance(E->key());
465 		if (!obj) {
466 			ret.resize(ret.size() - 1); //ops
467 		} else {
468 			ret[idx++] = obj;
469 		}
470 	}
471 
472 	return ret;
473 }
474 
get_overlapping_areas() const475 Array Area2D::get_overlapping_areas() const {
476 
477 	ERR_FAIL_COND_V(!monitoring, Array());
478 	Array ret;
479 	ret.resize(area_map.size());
480 	int idx = 0;
481 	for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) {
482 		Object *obj = ObjectDB::get_instance(E->key());
483 		if (!obj) {
484 			ret.resize(ret.size() - 1); //ops
485 		} else {
486 			ret[idx++] = obj;
487 		}
488 	}
489 
490 	return ret;
491 }
492 
overlaps_area(Node * p_area) const493 bool Area2D::overlaps_area(Node *p_area) const {
494 
495 	ERR_FAIL_NULL_V(p_area, false);
496 	const Map<ObjectID, AreaState>::Element *E = area_map.find(p_area->get_instance_ID());
497 	if (!E)
498 		return false;
499 	return E->get().in_tree;
500 }
501 
overlaps_body(Node * p_body) const502 bool Area2D::overlaps_body(Node *p_body) const {
503 
504 	ERR_FAIL_NULL_V(p_body, false);
505 	const Map<ObjectID, BodyState>::Element *E = body_map.find(p_body->get_instance_ID());
506 	if (!E)
507 		return false;
508 	return E->get().in_tree;
509 }
510 
set_collision_mask(uint32_t p_mask)511 void Area2D::set_collision_mask(uint32_t p_mask) {
512 
513 	collision_mask = p_mask;
514 	Physics2DServer::get_singleton()->area_set_collision_mask(get_rid(), p_mask);
515 }
516 
get_collision_mask() const517 uint32_t Area2D::get_collision_mask() const {
518 
519 	return collision_mask;
520 }
521 
set_layer_mask(uint32_t p_mask)522 void Area2D::set_layer_mask(uint32_t p_mask) {
523 
524 	layer_mask = p_mask;
525 	Physics2DServer::get_singleton()->area_set_layer_mask(get_rid(), p_mask);
526 }
527 
get_layer_mask() const528 uint32_t Area2D::get_layer_mask() const {
529 
530 	return layer_mask;
531 }
532 
set_collision_mask_bit(int p_bit,bool p_value)533 void Area2D::set_collision_mask_bit(int p_bit, bool p_value) {
534 
535 	uint32_t mask = get_collision_mask();
536 	if (p_value)
537 		mask |= 1 << p_bit;
538 	else
539 		mask &= ~(1 << p_bit);
540 	set_collision_mask(mask);
541 }
542 
get_collision_mask_bit(int p_bit) const543 bool Area2D::get_collision_mask_bit(int p_bit) const {
544 
545 	return get_collision_mask() & (1 << p_bit);
546 }
547 
set_layer_mask_bit(int p_bit,bool p_value)548 void Area2D::set_layer_mask_bit(int p_bit, bool p_value) {
549 
550 	uint32_t mask = get_layer_mask();
551 	if (p_value)
552 		mask |= 1 << p_bit;
553 	else
554 		mask &= ~(1 << p_bit);
555 	set_layer_mask(mask);
556 }
557 
get_layer_mask_bit(int p_bit) const558 bool Area2D::get_layer_mask_bit(int p_bit) const {
559 
560 	return get_layer_mask() & (1 << p_bit);
561 }
562 
_bind_methods()563 void Area2D::_bind_methods() {
564 
565 	ObjectTypeDB::bind_method(_MD("_body_enter_tree", "id"), &Area2D::_body_enter_tree);
566 	ObjectTypeDB::bind_method(_MD("_body_exit_tree", "id"), &Area2D::_body_exit_tree);
567 
568 	ObjectTypeDB::bind_method(_MD("_area_enter_tree", "id"), &Area2D::_area_enter_tree);
569 	ObjectTypeDB::bind_method(_MD("_area_exit_tree", "id"), &Area2D::_area_exit_tree);
570 
571 	ObjectTypeDB::bind_method(_MD("set_space_override_mode", "enable"), &Area2D::set_space_override_mode);
572 	ObjectTypeDB::bind_method(_MD("get_space_override_mode"), &Area2D::get_space_override_mode);
573 
574 	ObjectTypeDB::bind_method(_MD("set_gravity_is_point", "enable"), &Area2D::set_gravity_is_point);
575 	ObjectTypeDB::bind_method(_MD("is_gravity_a_point"), &Area2D::is_gravity_a_point);
576 
577 	ObjectTypeDB::bind_method(_MD("set_gravity_distance_scale", "distance_scale"), &Area2D::set_gravity_distance_scale);
578 	ObjectTypeDB::bind_method(_MD("get_gravity_distance_scale"), &Area2D::get_gravity_distance_scale);
579 
580 	ObjectTypeDB::bind_method(_MD("set_gravity_vector", "vector"), &Area2D::set_gravity_vector);
581 	ObjectTypeDB::bind_method(_MD("get_gravity_vector"), &Area2D::get_gravity_vector);
582 
583 	ObjectTypeDB::bind_method(_MD("set_gravity", "gravity"), &Area2D::set_gravity);
584 	ObjectTypeDB::bind_method(_MD("get_gravity"), &Area2D::get_gravity);
585 
586 	ObjectTypeDB::bind_method(_MD("set_linear_damp", "linear_damp"), &Area2D::set_linear_damp);
587 	ObjectTypeDB::bind_method(_MD("get_linear_damp"), &Area2D::get_linear_damp);
588 
589 	ObjectTypeDB::bind_method(_MD("set_angular_damp", "angular_damp"), &Area2D::set_angular_damp);
590 	ObjectTypeDB::bind_method(_MD("get_angular_damp"), &Area2D::get_angular_damp);
591 
592 	ObjectTypeDB::bind_method(_MD("set_priority", "priority"), &Area2D::set_priority);
593 	ObjectTypeDB::bind_method(_MD("get_priority"), &Area2D::get_priority);
594 
595 	ObjectTypeDB::bind_method(_MD("set_collision_mask", "collision_mask"), &Area2D::set_collision_mask);
596 	ObjectTypeDB::bind_method(_MD("get_collision_mask"), &Area2D::get_collision_mask);
597 
598 	ObjectTypeDB::bind_method(_MD("set_layer_mask", "layer_mask"), &Area2D::set_layer_mask);
599 	ObjectTypeDB::bind_method(_MD("get_layer_mask"), &Area2D::get_layer_mask);
600 
601 	ObjectTypeDB::bind_method(_MD("set_collision_mask_bit", "bit", "value"), &Area2D::set_collision_mask_bit);
602 	ObjectTypeDB::bind_method(_MD("get_collision_mask_bit", "bit"), &Area2D::get_collision_mask_bit);
603 
604 	ObjectTypeDB::bind_method(_MD("set_layer_mask_bit", "bit", "value"), &Area2D::set_layer_mask_bit);
605 	ObjectTypeDB::bind_method(_MD("get_layer_mask_bit", "bit"), &Area2D::get_layer_mask_bit);
606 
607 	ObjectTypeDB::bind_method(_MD("set_enable_monitoring", "enable"), &Area2D::set_enable_monitoring);
608 	ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"), &Area2D::is_monitoring_enabled);
609 
610 	ObjectTypeDB::bind_method(_MD("set_monitorable", "enable"), &Area2D::set_monitorable);
611 	ObjectTypeDB::bind_method(_MD("is_monitorable"), &Area2D::is_monitorable);
612 
613 	ObjectTypeDB::bind_method(_MD("get_overlapping_bodies"), &Area2D::get_overlapping_bodies);
614 	ObjectTypeDB::bind_method(_MD("get_overlapping_areas"), &Area2D::get_overlapping_areas);
615 
616 	ObjectTypeDB::bind_method(_MD("overlaps_body", "body"), &Area2D::overlaps_body);
617 	ObjectTypeDB::bind_method(_MD("overlaps_area", "area"), &Area2D::overlaps_area);
618 
619 	ObjectTypeDB::bind_method(_MD("_body_inout"), &Area2D::_body_inout);
620 	ObjectTypeDB::bind_method(_MD("_area_inout"), &Area2D::_area_inout);
621 
622 	ADD_SIGNAL(MethodInfo("body_enter_shape", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsBody2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
623 	ADD_SIGNAL(MethodInfo("body_exit_shape", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsBody2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
624 	ADD_SIGNAL(MethodInfo("body_enter", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsBody2D")));
625 	ADD_SIGNAL(MethodInfo("body_exit", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsBody2D")));
626 
627 	ADD_SIGNAL(MethodInfo("area_enter_shape", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
628 	ADD_SIGNAL(MethodInfo("area_exit_shape", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "self_shape")));
629 	ADD_SIGNAL(MethodInfo("area_enter", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D")));
630 	ADD_SIGNAL(MethodInfo("area_exit", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D")));
631 
632 	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine"), _SCS("set_space_override_mode"), _SCS("get_space_override_mode"));
633 	ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "gravity_point"), _SCS("set_gravity_is_point"), _SCS("is_gravity_a_point"));
634 	ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001"), _SCS("set_gravity_distance_scale"), _SCS("get_gravity_distance_scale"));
635 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_vec"), _SCS("set_gravity_vector"), _SCS("get_gravity_vector"));
636 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), _SCS("set_gravity"), _SCS("get_gravity"));
637 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.01"), _SCS("set_linear_damp"), _SCS("get_linear_damp"));
638 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.01"), _SCS("set_angular_damp"), _SCS("get_angular_damp"));
639 	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), _SCS("set_priority"), _SCS("get_priority"));
640 	ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "monitoring"), _SCS("set_enable_monitoring"), _SCS("is_monitoring_enabled"));
641 	ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "monitorable"), _SCS("set_monitorable"), _SCS("is_monitorable"));
642 	ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision/layers", PROPERTY_HINT_ALL_FLAGS), _SCS("set_layer_mask"), _SCS("get_layer_mask"));
643 	ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision/mask", PROPERTY_HINT_ALL_FLAGS), _SCS("set_collision_mask"), _SCS("get_collision_mask"));
644 }
645 
Area2D()646 Area2D::Area2D() :
647 		CollisionObject2D(Physics2DServer::get_singleton()->area_create(), true) {
648 
649 	space_override = SPACE_OVERRIDE_DISABLED;
650 	set_gravity(98);
651 	set_gravity_vector(Vector2(0, 1));
652 	gravity_is_point = false;
653 	gravity_distance_scale = 0;
654 	linear_damp = 0.1;
655 	angular_damp = 1;
656 	locked = false;
657 	priority = 0;
658 	monitoring = false;
659 	monitorable = false;
660 	collision_mask = 1;
661 	layer_mask = 1;
662 	monitoring_stored = false;
663 	set_enable_monitoring(true);
664 	set_monitorable(true);
665 }
666 
~Area2D()667 Area2D::~Area2D() {
668 }
669