979979ff23e46bb328a83816efea4d17d3b822d7
[blender.git] / source / blender / editors / space_logic / logic_ops.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28 #include <stddef.h>
29
30 #include "DNA_object_types.h"
31 #include "DNA_sensor_types.h"
32 #include "DNA_controller_types.h"
33 #include "DNA_actuator_types.h"
34
35 #include "BLI_blenlib.h"
36 #include "BLI_utildefines.h"
37
38 #include "BKE_context.h"
39 #include "BKE_main.h"
40 #include "BKE_sca.h"
41
42 #include "ED_logic.h"
43 #include "ED_object.h"
44 #include "ED_screen.h"
45
46 #include "RNA_access.h"
47 #include "RNA_define.h"
48 #include "RNA_enum_types.h"
49
50 #include "WM_api.h"
51 #include "WM_types.h"
52
53 #include "logic_intern.h"
54
55 /* ************* Generic Operator Helpers ************* */
56 static int edit_sensor_poll(bContext *C)
57 {
58         PointerRNA ptr= CTX_data_pointer_get_type(C, "sensor", &RNA_Sensor);
59
60         if (ptr.data && ((ID*)ptr.id.data)->lib) return 0;
61         return 1;
62 }
63
64 static int edit_controller_poll(bContext *C)
65 {
66         PointerRNA ptr= CTX_data_pointer_get_type(C, "controller", &RNA_Controller);
67
68         if (ptr.data && ((ID*)ptr.id.data)->lib) return 0;
69         return 1;
70 }
71
72 static int edit_actuator_poll(bContext *C)
73 {
74         PointerRNA ptr= CTX_data_pointer_get_type(C, "actuator", &RNA_Actuator);
75
76         if (ptr.data && ((ID*)ptr.id.data)->lib) return 0;
77         return 1;
78 }
79
80 static void edit_sensor_properties(wmOperatorType *ot)
81 {
82         RNA_def_string(ot->srna, "sensor", "", 32, "Sensor", "Name of the sensor to edit");
83         RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the object the sensor belongs to");
84 }
85
86 static int edit_sensor_invoke_properties(bContext *C, wmOperator *op)
87 {
88         PointerRNA ptr= CTX_data_pointer_get_type(C, "sensor", &RNA_Sensor);
89         
90         if (RNA_property_is_set(op->ptr, "sensor") && RNA_property_is_set(op->ptr, "object") )
91                 return 1;
92         
93         if (ptr.data) {
94                 bSensor *sens = ptr.data;
95                 Object *ob = ptr.id.data;
96                 
97                 RNA_string_set(op->ptr, "sensor", sens->name);
98                 RNA_string_set(op->ptr, "object", ob->id.name+2);
99                 return 1;
100         }
101         
102         return 0;
103 }
104
105 static Object *edit_object_property_get(bContext *C, wmOperator *op)
106 {
107         char ob_name[32];
108         Object *ob;
109
110         RNA_string_get(op->ptr, "object", ob_name);
111
112         /* if ob_name is valid try to find the object with this name
113         otherwise gets the active object */
114         if (BLI_strnlen(ob_name, 32) > 0)
115                 ob = BLI_findstring(&(CTX_data_main(C)->object), ob_name, offsetof(ID, name) + 2);
116         else
117                 ob= ED_object_active_context(C);
118
119         return ob;
120 }
121
122 static bSensor *edit_sensor_property_get(bContext *C, wmOperator *op, Object **ob)
123 {
124         char sensor_name[32];
125         bSensor *sens;
126         
127         RNA_string_get(op->ptr, "sensor", sensor_name);
128
129         *ob= edit_object_property_get(C, op);
130         if (!*ob) return NULL;
131         
132         sens = BLI_findstring(&((*ob)->sensors), sensor_name, offsetof(bSensor, name)); 
133         return sens;
134 }
135
136 static void edit_controller_properties(wmOperatorType *ot)
137 {
138         RNA_def_string(ot->srna, "controller", "", 32, "Controller", "Name of the controller to edit");
139         RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the object the controller belongs to");
140 }
141
142 static int edit_controller_invoke_properties(bContext *C, wmOperator *op)
143 {
144         PointerRNA ptr= CTX_data_pointer_get_type(C, "controller", &RNA_Controller);
145         
146         if (RNA_property_is_set(op->ptr, "controller") && RNA_property_is_set(op->ptr, "object") )
147                 return 1;
148         
149         if (ptr.data) {
150                 bController *cont = ptr.data;
151                 Object *ob = ptr.id.data;
152                 
153                 RNA_string_set(op->ptr, "controller", cont->name);
154                 RNA_string_set(op->ptr, "object", ob->id.name+2);
155                 return 1;
156         }
157         
158         return 0;
159 }
160
161 static bController *edit_controller_property_get(bContext *C, wmOperator *op, Object **ob)
162 {
163         char controller_name[32];
164         bController *cont;
165         
166         RNA_string_get(op->ptr, "controller", controller_name);
167
168         *ob= edit_object_property_get(C, op);
169         if (!*ob) return NULL;
170         
171         cont = BLI_findstring(&((*ob)->controllers), controller_name, offsetof(bController, name));     
172         return cont;
173 }
174
175 static void edit_actuator_properties(wmOperatorType *ot)
176 {
177         RNA_def_string(ot->srna, "actuator", "", 32, "Actuator", "Name of the actuator to edit");
178         RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the object the actuator belongs to");
179 }
180
181 static int edit_actuator_invoke_properties(bContext *C, wmOperator *op)
182 {
183         PointerRNA ptr= CTX_data_pointer_get_type(C, "actuator", &RNA_Actuator);
184         
185         if (RNA_property_is_set(op->ptr, "actuator") && RNA_property_is_set(op->ptr, "object") )
186                 return 1;
187         
188         if (ptr.data) {
189                 bActuator *act = ptr.data;
190                 Object *ob = ptr.id.data;
191                 
192                 RNA_string_set(op->ptr, "actuator",act->name);
193                 RNA_string_set(op->ptr, "object", ob->id.name+2);
194                 return 1;
195         }
196         
197         return 0;
198 }
199
200 static bActuator *edit_actuator_property_get(bContext *C, wmOperator *op, Object **ob)
201 {
202         char actuator_name[32];
203         bActuator *act;
204         
205         RNA_string_get(op->ptr, "actuator", actuator_name);
206
207         *ob= edit_object_property_get(C, op);
208         if (!*ob) return NULL;
209         
210         act = BLI_findstring(&((*ob)->actuators), actuator_name, offsetof(bActuator, name));    
211         return act;
212 }
213
214 static int logicbricks_move_property_get(wmOperator *op)
215 {
216         int type = RNA_enum_get(op->ptr, "direction");
217
218         if (type == 1)
219                 return TRUE;
220         else
221                 return FALSE;
222 }
223
224 /* ************* Add/Remove Sensor Operator ************* */
225
226 static int sensor_remove_exec(bContext *C, wmOperator *op)
227 {
228         Object *ob=NULL;
229         bSensor *sens = edit_sensor_property_get(C, op, &ob);
230         
231         if (!sens)
232                 return OPERATOR_CANCELLED;
233         
234         BLI_remlink(&(ob->sensors), sens);
235         free_sensor(sens);
236         
237         WM_event_add_notifier(C, NC_LOGIC, NULL);
238         
239         return OPERATOR_FINISHED;
240 }
241
242  static int sensor_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
243 {
244         if (edit_sensor_invoke_properties(C, op))
245                 return sensor_remove_exec(C, op);
246         else
247                 return OPERATOR_CANCELLED;
248 }
249
250 static void LOGIC_OT_sensor_remove(wmOperatorType *ot)
251 {
252         ot->name= "Remove Sensor";
253         ot->description= "Remove a sensor from the active object";
254         ot->idname= "LOGIC_OT_sensor_remove";
255         
256         ot->invoke= sensor_remove_invoke;
257         ot->exec= sensor_remove_exec;
258         ot->poll= edit_sensor_poll;
259         
260         /* flags */
261         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
262         edit_sensor_properties(ot);
263 }
264
265 static int sensor_add_exec(bContext *C, wmOperator *op)
266 {
267         Object *ob;
268         bSensor *sens;
269         PointerRNA sens_ptr;
270         PropertyRNA *prop;
271         const char *sens_name;
272         char name[32];
273         int type= RNA_enum_get(op->ptr, "type");
274
275         ob= edit_object_property_get(C, op);
276         if (!ob)
277                 return OPERATOR_CANCELLED;
278
279         sens= new_sensor(type);
280         BLI_addtail(&(ob->sensors), sens);
281         
282         /* set the sensor name based on rna type enum */
283         RNA_pointer_create((ID *)ob, &RNA_Sensor, sens, &sens_ptr);
284         prop = RNA_struct_find_property(&sens_ptr, "type");
285
286         RNA_string_get(op->ptr, "name", name);
287         if(BLI_strnlen(name, 32) < 1){
288                 RNA_property_enum_name(C, &sens_ptr, prop, RNA_property_enum_get(&sens_ptr, prop), &sens_name);
289                 BLI_strncpy(sens->name, sens_name, sizeof(sens->name));
290         }
291         else
292                 BLI_strncpy(sens->name, name, sizeof(sens->name));
293
294         make_unique_prop_names(C, sens->name);
295         ob->scaflag |= OB_SHOWSENS;
296
297         WM_event_add_notifier(C, NC_LOGIC, NULL);
298         
299         return OPERATOR_FINISHED;
300 }
301
302 static void LOGIC_OT_sensor_add(wmOperatorType *ot)
303 {
304         PropertyRNA *prop;
305         
306         /* identifiers */
307         ot->name= "Add Sensor";
308         ot->description = "Add a sensor to the active object";
309         ot->idname= "LOGIC_OT_sensor_add";
310         
311         /* api callbacks */
312         ot->invoke= WM_menu_invoke;
313         ot->exec= sensor_add_exec;
314         ot->poll= ED_operator_object_active_editable;
315         
316         /* flags */
317         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
318         
319         /* properties */
320         prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, SENS_ALWAYS, "Type", "Type of sensor to add");
321         RNA_def_enum_funcs(prop, rna_Sensor_type_itemf);
322         RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the Sensor to add");
323         RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the Object to add the Sensor to");
324 }
325
326 /* ************* Add/Remove Controller Operator ************* */
327
328 static int controller_remove_exec(bContext *C, wmOperator *op)
329 {
330         Object *ob = NULL;
331         bController *cont = edit_controller_property_get(C, op, &ob);
332         
333         if (!cont)
334                 return OPERATOR_CANCELLED;
335         
336         BLI_remlink(&(ob->controllers), cont);
337         unlink_controller(cont);
338         free_controller(cont);
339         
340         WM_event_add_notifier(C, NC_LOGIC, NULL);
341         
342         return OPERATOR_FINISHED;
343 }
344
345  static int controller_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
346 {
347         if (edit_controller_invoke_properties(C, op))
348                 return controller_remove_exec(C, op);
349         else
350                 return OPERATOR_CANCELLED;
351 }
352
353 static void LOGIC_OT_controller_remove(wmOperatorType *ot)
354 {
355         ot->name= "Remove Controller";
356         ot->description= "Remove a controller from the active object";
357         ot->idname= "LOGIC_OT_controller_remove";
358         
359         ot->invoke= controller_remove_invoke;
360         ot->exec= controller_remove_exec;
361         ot->poll= edit_controller_poll;
362         
363         /* flags */
364         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
365         edit_controller_properties(ot);
366 }
367
368 static int controller_add_exec(bContext *C, wmOperator *op)
369 {
370         Object *ob;
371         bController *cont;
372         PointerRNA cont_ptr;
373         PropertyRNA *prop;
374         const char *cont_name;
375         int bit;
376         char name[32];
377         int type= RNA_enum_get(op->ptr, "type");
378
379         ob= edit_object_property_get(C, op);
380         if(!ob)
381                 return OPERATOR_CANCELLED;
382         
383         cont= new_controller(type);
384         BLI_addtail(&(ob->controllers), cont);
385         
386         /* set the controller name based on rna type enum */
387         RNA_pointer_create((ID *)ob, &RNA_Controller, cont, &cont_ptr);
388         prop = RNA_struct_find_property(&cont_ptr, "type");
389
390         RNA_string_get(op->ptr, "name", name);
391         if(BLI_strnlen(name, 32) < 1){
392                 RNA_property_enum_name(C, &cont_ptr, prop, RNA_property_enum_get(&cont_ptr, prop), &cont_name);
393                 BLI_strncpy(cont->name, cont_name, sizeof(cont->name));
394         }
395         else
396                 BLI_strncpy(cont->name, name, sizeof(cont->name));
397
398         make_unique_prop_names(C, cont->name);
399         /* set the controller state mask from the current object state.
400          A controller is always in a single state, so select the lowest bit set
401          from the object state */
402         for (bit=0; bit<OB_MAX_STATES; bit++) {
403                 if (ob->state & (1<<bit))
404                         break;
405         }
406         cont->state_mask = (1<<bit);
407         if (cont->state_mask == 0) {
408                 /* shouldn't happen, object state is never 0 */
409                 cont->state_mask = 1;
410         }
411         
412         ob->scaflag |= OB_SHOWCONT;
413         
414         WM_event_add_notifier(C, NC_LOGIC, NULL);
415         
416         return OPERATOR_FINISHED;
417 }
418
419 static void LOGIC_OT_controller_add(wmOperatorType *ot)
420 {
421         /* identifiers */
422         ot->name= "Add Controller";
423         ot->description = "Add a controller to the active object";
424         ot->idname= "LOGIC_OT_controller_add";
425         
426         /* api callbacks */
427         ot->invoke= WM_menu_invoke;
428         ot->exec= controller_add_exec;
429         ot->poll= ED_operator_object_active_editable;
430         
431         /* flags */
432         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
433         
434         /* properties */
435         RNA_def_enum(ot->srna, "type", controller_type_items, CONT_LOGIC_AND, "Type", "Type of controller to add");
436         RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the Controller to add");
437         RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the Object to add the Controller to");
438 }
439
440 /* ************* Add/Remove Actuator Operator ************* */
441
442 static int actuator_remove_exec(bContext *C, wmOperator *op)
443 {
444         Object *ob=NULL;
445         bActuator *act = edit_actuator_property_get(C, op, &ob);
446         
447         if (!act)
448                 return OPERATOR_CANCELLED;
449         
450         BLI_remlink(&(ob->actuators), act);
451         unlink_actuator(act);
452         free_actuator(act);
453         
454         WM_event_add_notifier(C, NC_LOGIC, NULL);
455         
456         return OPERATOR_FINISHED;
457 }
458
459 static int actuator_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
460 {
461         if (edit_actuator_invoke_properties(C, op))
462                 return actuator_remove_exec(C, op);
463         else
464                 return OPERATOR_CANCELLED;
465 }
466
467 static void LOGIC_OT_actuator_remove(wmOperatorType *ot)
468 {
469         ot->name= "Remove Actuator";
470         ot->description= "Remove a actuator from the active object";
471         ot->idname= "LOGIC_OT_actuator_remove";
472         
473         ot->invoke= actuator_remove_invoke;
474         ot->exec= actuator_remove_exec;
475         ot->poll= edit_actuator_poll;
476         
477         /* flags */
478         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
479         edit_actuator_properties(ot);
480 }
481
482 static int actuator_add_exec(bContext *C, wmOperator *op)
483 {
484         Object *ob;
485         bActuator *act;
486         PointerRNA act_ptr;
487         PropertyRNA *prop;
488         const char *act_name;
489         char  name[32];
490         int type= RNA_enum_get(op->ptr, "type");
491                 
492         ob= edit_object_property_get(C, op);
493         if(!ob)
494                 return OPERATOR_CANCELLED;
495
496         act= new_actuator(type);
497         BLI_addtail(&(ob->actuators), act);
498         
499         /* set the actuator name based on rna type enum */
500         RNA_pointer_create((ID *)ob, &RNA_Actuator, act, &act_ptr);
501         prop = RNA_struct_find_property(&act_ptr, "type");
502
503         RNA_string_get(op->ptr, "name", name);
504         if (BLI_strnlen(name, 32) < 1){
505                 RNA_property_enum_name(C, &act_ptr, prop, RNA_property_enum_get(&act_ptr, prop), &act_name);
506                 BLI_strncpy(act->name, act_name, sizeof(act->name));
507         }
508         else
509                 BLI_strncpy(act->name, name, sizeof(act->name));
510
511         make_unique_prop_names(C, act->name);
512         ob->scaflag |= OB_SHOWACT;
513         
514         WM_event_add_notifier(C, NC_LOGIC, NULL);
515         
516         return OPERATOR_FINISHED;
517 }
518
519 static void LOGIC_OT_actuator_add(wmOperatorType *ot)
520 {
521         PropertyRNA *prop;
522         
523         /* identifiers */
524         ot->name= "Add Actuator";
525         ot->description = "Add a actuator to the active object";
526         ot->idname= "LOGIC_OT_actuator_add";
527         
528         /* api callbacks */
529         ot->invoke= WM_menu_invoke;
530         ot->exec= actuator_add_exec;
531         ot->poll= ED_operator_object_active_editable;
532         
533         /* flags */
534         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
535         
536         /* properties */
537         prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, CONT_LOGIC_AND, "Type", "Type of actuator to add");
538         RNA_def_enum_funcs(prop, rna_Actuator_type_itemf);
539         RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the Actuator to add");
540         RNA_def_string(ot->srna, "object", "", 32, "Object", "Name of the Object to add the Actuator to");
541 }
542
543 /* ************* Move Logic Bricks Operator ************* */
544 static EnumPropertyItem logicbricks_move_direction[] ={
545                 {1, "UP", 0, "Move Up", ""},
546                 {2, "DOWN", 0, "Move Down", ""},
547                 {0, NULL, 0, NULL, NULL}};
548
549
550 static int sensor_move_exec(bContext *C, wmOperator *op)
551 {
552         Object *ob=NULL;
553         bSensor *sens= edit_sensor_property_get(C, op, &ob);
554         int move_up= logicbricks_move_property_get(op);
555         
556         if (!sens)
557                 return OPERATOR_CANCELLED;
558
559         sca_move_sensor(sens, ob, move_up);
560
561         WM_event_add_notifier(C, NC_LOGIC, NULL);
562         
563         return OPERATOR_FINISHED;
564 }
565
566 static int sensor_move_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
567 {
568         if (edit_sensor_invoke_properties(C, op)) {
569                 return sensor_move_exec(C, op);
570         }
571         else
572                 return OPERATOR_CANCELLED;
573 }
574
575 static void LOGIC_OT_sensor_move(wmOperatorType *ot)
576 {
577         /* identifiers */
578         ot->name= "Move Sensor";
579         ot->description = "Move Densor";
580         ot->idname= "LOGIC_OT_sensor_move";
581         
582         /* api callbacks */
583         ot->invoke= sensor_move_invoke;
584         ot->exec= sensor_move_exec;
585         ot->poll= edit_sensor_poll;
586         
587         /* flags */
588         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
589         
590         /* properties */
591         edit_sensor_properties(ot);
592         RNA_def_enum(ot->srna, "direction", logicbricks_move_direction, 1, "Direction", "Move Up or Down");
593 }
594
595 static int controller_move_exec(bContext *C, wmOperator *op)
596 {
597         Object *ob=NULL;
598         bController *cont= edit_controller_property_get(C, op, &ob);
599         int move_up= logicbricks_move_property_get(op);
600         
601         if (!cont)
602                 return OPERATOR_CANCELLED;
603
604         sca_move_controller(cont, ob, move_up);
605
606         WM_event_add_notifier(C, NC_LOGIC, NULL);
607         
608         return OPERATOR_FINISHED;
609 }
610
611 static int controller_move_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
612 {
613         if (edit_controller_invoke_properties(C, op)) {
614                 return controller_move_exec(C, op);
615         }
616         else
617                 return OPERATOR_CANCELLED;
618 }
619
620 static void LOGIC_OT_controller_move(wmOperatorType *ot)
621 {
622         /* identifiers */
623         ot->name= "Move Controller";
624         ot->description = "Move Controller";
625         ot->idname= "LOGIC_OT_controller_move";
626         
627         /* api callbacks */
628         ot->invoke= controller_move_invoke;
629         ot->exec= controller_move_exec;
630         ot->poll= edit_controller_poll;
631         
632         /* flags */
633         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
634         
635         /* properties */
636         edit_controller_properties(ot);
637         RNA_def_enum(ot->srna, "direction", logicbricks_move_direction, 1, "Direction", "Move Up or Down");
638 }
639
640 static int actuator_move_exec(bContext *C, wmOperator *op)
641 {
642         Object *ob=NULL;
643         bActuator *act = edit_actuator_property_get(C, op, &ob);
644         int move_up= logicbricks_move_property_get(op);
645
646         if (!act)
647                 return OPERATOR_CANCELLED;
648
649         sca_move_actuator(act, ob, move_up);
650
651         WM_event_add_notifier(C, NC_LOGIC, NULL);
652         
653         return OPERATOR_FINISHED;
654 }
655
656 static int actuator_move_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
657 {
658         if (edit_actuator_invoke_properties(C, op)) {
659                 return actuator_move_exec(C, op);
660         }
661         else
662                 return OPERATOR_CANCELLED;
663 }
664
665 static void LOGIC_OT_actuator_move(wmOperatorType *ot)
666 {
667         /* identifiers */
668         ot->name= "Move Actuator";
669         ot->description = "Move Actuator";
670         ot->idname= "LOGIC_OT_actuator_move";
671         
672         /* api callbacks */
673         ot->invoke= actuator_move_invoke;
674         ot->exec= actuator_move_exec;
675         ot->poll= edit_actuator_poll;
676         
677         /* flags */
678         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
679         
680         /* properties */
681         edit_actuator_properties(ot);
682         RNA_def_enum(ot->srna, "direction", logicbricks_move_direction, 1, "Direction", "Move Up or Down");
683 }
684
685
686 void ED_operatortypes_logic(void)
687 {
688         WM_operatortype_append(LOGIC_OT_sensor_remove);
689         WM_operatortype_append(LOGIC_OT_sensor_add);
690         WM_operatortype_append(LOGIC_OT_sensor_move);
691         WM_operatortype_append(LOGIC_OT_controller_remove);
692         WM_operatortype_append(LOGIC_OT_controller_add);
693         WM_operatortype_append(LOGIC_OT_controller_move);
694         WM_operatortype_append(LOGIC_OT_actuator_remove);
695         WM_operatortype_append(LOGIC_OT_actuator_add);
696         WM_operatortype_append(LOGIC_OT_actuator_move);
697 }