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