BGE patch: Add PyDoc for new logic bricks, set exception message on Py error, remove...
[blender.git] / source / gameengine / Ketsji / KX_IpoActuator.cpp
1 /**
2  * Do Ipo stuff
3  *
4  * $Id$
5  *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  */
31
32 #if defined (__sgi)
33 #include <math.h>
34 #else
35 #include <cmath>
36 #endif
37  
38 #include "KX_IpoActuator.h"
39 #include "KX_GameObject.h"
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 #include "KX_KetsjiEngine.h"
46
47 /* ------------------------------------------------------------------------- */
48 /* Type strings                                                              */
49 /* ------------------------------------------------------------------------- */
50
51 STR_String KX_IpoActuator::S_KX_ACT_IPO_PLAY_STRING      = "Play";
52 STR_String KX_IpoActuator::S_KX_ACT_IPO_PINGPONG_STRING  = "PingPong";
53 STR_String KX_IpoActuator::S_KX_ACT_IPO_FLIPPER_STRING   = "Flipper";
54 STR_String KX_IpoActuator::S_KX_ACT_IPO_LOOPSTOP_STRING  = "LoopStop";
55 STR_String KX_IpoActuator::S_KX_ACT_IPO_LOOPEND_STRING   = "LoopEnd";
56 STR_String KX_IpoActuator::S_KX_ACT_IPO_KEY2KEY_STRING   = "Key2key";
57 STR_String KX_IpoActuator::S_KX_ACT_IPO_FROM_PROP_STRING = "FromProp";
58
59 /* ------------------------------------------------------------------------- */
60 /* Native functions                                                          */
61 /* ------------------------------------------------------------------------- */
62
63 KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
64                                                            const STR_String& propname,
65                                                            float starttime,
66                                                            float endtime,
67                                                            bool recurse,
68                                                            int acttype,
69                                                            bool ipo_as_force,
70                                                            bool ipo_add,
71                                                            bool ipo_local,
72                                                            PyTypeObject* T) 
73         : SCA_IActuator(gameobj,T),
74         m_bNegativeEvent(false),
75         m_startframe (starttime),
76         m_endframe(endtime),
77         m_recurse(recurse),
78         m_localtime(starttime),
79         m_direction(1),
80         m_propname(propname),
81         m_ipo_as_force(ipo_as_force),
82         m_ipo_add(ipo_add),
83         m_ipo_local(ipo_local),
84         m_type((IpoActType)acttype)
85 {
86         m_starttime = -2.0*fabs(m_endframe - m_startframe) - 1.0;
87         m_bIpoPlaying = false;
88 }
89
90 void KX_IpoActuator::SetStart(float starttime) 
91
92         m_startframe=starttime;
93 }
94
95 void KX_IpoActuator::SetEnd(float endtime) 
96
97         m_endframe=endtime;
98 }
99
100 bool KX_IpoActuator::ClampLocalTime()
101 {
102         if (m_startframe < m_endframe)
103         {
104                 if (m_localtime < m_startframe)
105                 {
106                         m_localtime = m_startframe;
107                         return true;
108                 } 
109                 else if (m_localtime > m_endframe)
110                 {
111                         m_localtime = m_endframe;
112                         return true;
113                 }
114         } else {
115                 if (m_localtime > m_startframe)
116                 {
117                         m_localtime = m_startframe;
118                         return true;
119                 }
120                 else if (m_localtime < m_endframe)
121                 {
122                         m_localtime = m_endframe;
123                         return true;
124                 }
125         }
126         return false;
127 }
128
129 void KX_IpoActuator::SetStartTime(float curtime)
130 {
131         float direction = m_startframe < m_endframe ? 1.0f : -1.0f;
132
133         curtime = curtime - KX_KetsjiEngine::GetSuspendedDelta();       
134         if (m_direction > 0)
135                 m_starttime = curtime - direction*(m_localtime - m_startframe)/KX_KetsjiEngine::GetAnimFrameRate();
136         else
137                 m_starttime = curtime - direction*(m_endframe - m_localtime)/KX_KetsjiEngine::GetAnimFrameRate();
138 }
139
140 void KX_IpoActuator::SetLocalTime(float curtime)
141 {
142         float delta_time = ((curtime - m_starttime) - KX_KetsjiEngine::GetSuspendedDelta())*KX_KetsjiEngine::GetAnimFrameRate();
143         
144         // negative delta_time is caused by floating point inaccuracy
145         // perhaps the inaccuracy could be reduced a bit
146         if ((m_localtime==m_startframe || m_localtime==m_endframe) && delta_time<0.0)
147         {
148                 delta_time = 0.0;
149         }
150         
151         if (m_endframe < m_startframe)
152                 delta_time = -delta_time;
153
154         if (m_direction > 0)
155                 m_localtime = m_startframe + delta_time;
156         else
157                 m_localtime = m_endframe - delta_time;
158 }
159
160 bool KX_IpoActuator::Update(double curtime, bool frame)
161 {
162         // result = true if animation has to be continued, false if animation stops
163         // maybe there are events for us in the queue !
164         bool bNegativeEvent = false;
165         int numevents = 0;
166         bool bIpoStart = false;
167
168         if (frame)
169         {
170                 numevents = m_events.size();
171                 bNegativeEvent = IsNegativeEvent();
172                 RemoveAllEvents();
173         }
174         
175         float  start_smaller_then_end = ( m_startframe < m_endframe ? 1.0f : -1.0f);
176
177         bool result=true;
178         if (!bNegativeEvent)
179         {
180                 if (m_starttime < -2.0f*start_smaller_then_end*(m_endframe - m_startframe))
181                 {
182                         // start for all Ipo, initial start for LOOP_STOP
183                         m_starttime = curtime - KX_KetsjiEngine::GetSuspendedDelta();
184                         m_bIpoPlaying = true;
185                         bIpoStart = true;
186                 }
187         }       
188
189         switch (m_type)
190         {
191                 
192         case KX_ACT_IPO_PLAY:
193         {
194                 // Check if playing forwards.  result = ! finished
195                 
196                 if (start_smaller_then_end > 0.f)
197                         result = (m_localtime < m_endframe && m_bIpoPlaying);
198                 else
199                         result = (m_localtime > m_endframe && m_bIpoPlaying);
200                 
201                 if (result)
202                 {
203                         SetLocalTime(curtime);
204                 
205                         /* Perform clamping */
206                         ClampLocalTime();
207         
208                         if (bIpoStart)
209                                 ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);
210                         ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
211                 } else
212                 {
213                         m_localtime=m_startframe;
214                         m_direction=1;
215                 }
216                 break;
217         }
218         case KX_ACT_IPO_PINGPONG:
219         {
220                 result = true;
221                 if (bNegativeEvent && !m_bIpoPlaying)
222                         result = false;
223                 else
224                         SetLocalTime(curtime);
225                         
226                 if (ClampLocalTime())
227                 {
228                         result = false;
229                         m_direction = -m_direction;
230                 }
231                 
232                 if (bIpoStart && m_direction > 0)
233                         ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);
234                 ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
235                 break;
236         }
237         case KX_ACT_IPO_FLIPPER:
238         {
239                 if (bNegativeEvent && !m_bIpoPlaying)
240                         result = false;
241                 if (numevents)
242                 {
243                         float oldDirection = m_direction;
244                         if (bNegativeEvent)
245                                 m_direction = -1;
246                         else
247                                 m_direction = 1;
248                         if (m_direction != oldDirection)
249                                 // changing direction, reset start time
250                                 SetStartTime(curtime);
251                 }
252                 
253                 SetLocalTime(curtime);
254                 
255                 if (ClampLocalTime() && m_localtime == m_startframe)
256                         result = false;
257
258                 if (bIpoStart)
259                         ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);                 
260                 ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
261                 break;
262         }
263
264         case KX_ACT_IPO_LOOPSTOP:
265         {
266                 if (numevents)
267                 {
268                         if (bNegativeEvent)
269                         {
270                                 result = false;
271                                 m_bNegativeEvent = false;
272                                 numevents = 0;
273                         }
274                         if (!m_bIpoPlaying)
275                         {
276                                 // Ipo was stopped, make sure we will restart from where it stopped
277                                 SetStartTime(curtime);
278                                 if (!bNegativeEvent)
279                                         // positive signal will restart the Ipo
280                                         m_bIpoPlaying = true;
281                         }
282
283                 } // fall through to loopend, and quit the ipo animation immediatly 
284         }
285         case KX_ACT_IPO_LOOPEND:
286         {
287                 if (numevents){
288                         if (bNegativeEvent && m_bIpoPlaying){
289                                 m_bNegativeEvent = true;
290                         }
291                 }
292                 
293                 if (bNegativeEvent && !m_bIpoPlaying){
294                         result = false;
295                 } 
296                 else
297                 {
298                         if (m_localtime*start_smaller_then_end < m_endframe*start_smaller_then_end)
299                         {
300                                 SetLocalTime(curtime);
301                         }
302                         else{
303                                 if (!m_bNegativeEvent){
304                                         /* Perform wraparound */
305                                         SetLocalTime(curtime);
306                                         if (start_smaller_then_end > 0.f)
307                                                 m_localtime = m_startframe + fmod(m_localtime - m_startframe, m_endframe - m_startframe);
308                                         else
309                                                 m_localtime = m_startframe - fmod(m_startframe - m_localtime, m_startframe - m_endframe);
310                                         SetStartTime(curtime);
311                                         bIpoStart = true;
312                                 }
313                                 else
314                                 {       
315                                         /* Perform clamping */
316                                         m_localtime=m_endframe;
317                                         result = false;
318                                         m_bNegativeEvent = false;
319                                 }
320                         }
321                 }
322                 
323                 if (m_bIpoPlaying && bIpoStart)
324                         ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);
325                 ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
326                 break;
327         }
328         
329         case KX_ACT_IPO_KEY2KEY:
330         {
331                 // not implemented yet
332                 result = false;
333                 break;
334         }
335         
336         case KX_ACT_IPO_FROM_PROP:
337         {
338                 result = !bNegativeEvent;
339
340                 CValue* propval = GetParent()->GetProperty(m_propname);
341                 if (propval)
342                 {
343                         m_localtime = propval->GetNumber(); 
344         
345                         if (bIpoStart)
346                                 ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);
347                         ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
348                 } else
349                 {
350                         result = false;
351                 }
352                 break;
353         }
354                 
355         default:
356                 result = false;
357         }
358         
359         if (!result)
360         {
361                 if (m_type != KX_ACT_IPO_LOOPSTOP)
362                         m_starttime = -2.0*start_smaller_then_end*(m_endframe - m_startframe) - 1.0;
363                 m_bIpoPlaying = false;
364         }
365
366         return result;
367 }
368
369 KX_IpoActuator::IpoActType KX_IpoActuator::string2mode(char* modename) {
370         IpoActType res = KX_ACT_IPO_NODEF;
371
372         if (modename == S_KX_ACT_IPO_PLAY_STRING) { 
373                 res = KX_ACT_IPO_PLAY;
374         } else if (modename == S_KX_ACT_IPO_PINGPONG_STRING) {
375                 res = KX_ACT_IPO_PINGPONG;
376         } else if (modename == S_KX_ACT_IPO_FLIPPER_STRING) {
377                 res = KX_ACT_IPO_FLIPPER;
378         } else if (modename == S_KX_ACT_IPO_LOOPSTOP_STRING) {
379                 res = KX_ACT_IPO_LOOPSTOP;
380         } else if (modename == S_KX_ACT_IPO_LOOPEND_STRING) {
381                 res = KX_ACT_IPO_LOOPEND;
382         } else if (modename == S_KX_ACT_IPO_KEY2KEY_STRING) {
383                 res = KX_ACT_IPO_KEY2KEY;
384         } else if (modename == S_KX_ACT_IPO_FROM_PROP_STRING) {
385                 res = KX_ACT_IPO_FROM_PROP;
386         }
387
388         return res;
389 }
390
391 /* ------------------------------------------------------------------------- */
392 /* Python functions                                                          */
393 /* ------------------------------------------------------------------------- */
394
395
396
397 /* Integration hooks ------------------------------------------------------- */
398 PyTypeObject KX_IpoActuator::Type = {
399         PyObject_HEAD_INIT(&PyType_Type)
400         0,
401         "KX_IpoActuator",
402         sizeof(KX_IpoActuator),
403         0,
404         PyDestructor,
405         0,
406         __getattr,
407         __setattr,
408         0, //&MyPyCompare,
409         __repr,
410         0, //&cvalue_as_number,
411         0,
412         0,
413         0,
414         0
415 };
416
417 PyParentObject KX_IpoActuator::Parents[] = {
418         &KX_IpoActuator::Type,
419         &SCA_IActuator::Type,
420         &SCA_ILogicBrick::Type,
421         &CValue::Type,
422         NULL
423 };
424
425 PyMethodDef KX_IpoActuator::Methods[] = {
426         {"set", (PyCFunction) KX_IpoActuator::sPySet, 
427                 METH_VARARGS, Set_doc},
428         {"setProperty", (PyCFunction) KX_IpoActuator::sPySetProperty, 
429                 METH_VARARGS, SetProperty_doc},
430         {"setStart", (PyCFunction) KX_IpoActuator::sPySetStart, 
431                 METH_VARARGS, SetStart_doc},
432         {"getStart", (PyCFunction) KX_IpoActuator::sPyGetStart, 
433                 METH_NOARGS, GetStart_doc},
434         {"setEnd", (PyCFunction) KX_IpoActuator::sPySetEnd, 
435                 METH_VARARGS, SetEnd_doc},
436         {"getEnd", (PyCFunction) KX_IpoActuator::sPyGetEnd, 
437                 METH_NOARGS, GetEnd_doc},
438         {"setIpoAsForce", (PyCFunction) KX_IpoActuator::sPySetIpoAsForce, 
439                 METH_VARARGS, SetIpoAsForce_doc},
440         {"getIpoAsForce", (PyCFunction) KX_IpoActuator::sPyGetIpoAsForce, 
441                 METH_NOARGS, GetIpoAsForce_doc},
442         {"setIpoAdd", (PyCFunction) KX_IpoActuator::sPySetIpoAdd, 
443                 METH_VARARGS, SetIpoAdd_doc},
444         {"getIpoAdd", (PyCFunction) KX_IpoActuator::sPyGetIpoAdd, 
445                 METH_NOARGS, GetIpoAdd_doc},
446         {"setType", (PyCFunction) KX_IpoActuator::sPySetType, 
447                 METH_VARARGS, SetType_doc},
448         {"getType", (PyCFunction) KX_IpoActuator::sPyGetType, 
449                 METH_NOARGS, GetType_doc},      
450         {"setForceIpoActsLocal", (PyCFunction) KX_IpoActuator::sPySetForceIpoActsLocal,
451                 METH_VARARGS, SetForceIpoActsLocal_doc},
452         {"getForceIpoActsLocal", (PyCFunction) KX_IpoActuator::sPyGetForceIpoActsLocal,
453                 METH_NOARGS, GetForceIpoActsLocal_doc},
454         {NULL,NULL} //Sentinel
455 };
456
457 PyObject* KX_IpoActuator::_getattr(const STR_String& attr) {
458         _getattr_up(SCA_IActuator);
459 }
460
461
462
463 /* set --------------------------------------------------------------------- */
464 char KX_IpoActuator::Set_doc[] = 
465 "set(type, startframe, endframe, mode?)\n"
466 "\t - type:       Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
467 "\t - startframe: first frame to use (int)\n"
468 "\t - endframe  : last frame to use (int)\n"
469 "\t - mode?     : special mode (0=normal, 1=interpret location as force, 2=additive)"
470 "\tSet the properties of the actuator.\n";
471 PyObject* KX_IpoActuator::PySet(PyObject* self, 
472                                                                 PyObject* args, 
473                                                                 PyObject* kwds) {
474         /* sets modes PLAY, PINGPONG, FLIPPER, LOOPSTOP, LOOPEND                 */
475         /* arg 1 = mode string, arg 2 = startframe, arg3 = stopframe,            */
476         /* arg4 = force toggle                                                   */
477         char* mode;
478         int forceToggle;
479         IpoActType modenum;
480         int startFrame, stopFrame;
481         if(!PyArg_ParseTuple(args, "siii", &mode, &startFrame, 
482                                                  &stopFrame, &forceToggle)) {
483                 PyErr_SetString(PyExc_TypeError, "Invalid arguments");
484                 return NULL;
485         }
486         modenum = string2mode(mode);
487         
488         switch (modenum) {
489         case KX_ACT_IPO_PLAY:
490         case KX_ACT_IPO_PINGPONG:
491         case KX_ACT_IPO_FLIPPER:
492         case KX_ACT_IPO_LOOPSTOP:
493         case KX_ACT_IPO_LOOPEND:
494                 m_type         = modenum;
495                 m_startframe    = startFrame;
496                 m_endframe      = stopFrame;
497                 m_ipo_as_force = forceToggle == 1;
498                 m_ipo_add = forceToggle == 2;
499                 break;
500         default:
501                 ; /* error */
502         }
503
504         Py_Return;
505 }
506
507 /* set property  ----------------------------------------------------------- */
508 char KX_IpoActuator::SetProperty_doc[] = 
509 "setProperty(propname)\n"
510 "\t - propname: name of the property (string)\n"
511 "\tSet the property to be used in FromProp mode.\n";
512 PyObject* KX_IpoActuator::PySetProperty(PyObject* self, 
513                                                                                 PyObject* args, 
514                                                                                 PyObject* kwds) {
515         /* mode is implicit here, but not supported yet... */
516         /* args: property */
517         char *propertyName;
518         if(!PyArg_ParseTuple(args, "s", &propertyName)) {
519                 PyErr_SetString(PyExc_TypeError, "Invalid arguments");
520                 return NULL;
521         }
522
523         m_propname = propertyName;
524         
525         Py_Return;
526 }
527
528 /* 4. setStart:                                                              */
529 char KX_IpoActuator::SetStart_doc[] = 
530 "setStart(frame)\n"
531 "\t - frame: first frame to use (int)\n"
532 "\tSet the frame from which the ipo starts playing.\n";
533 PyObject* KX_IpoActuator::PySetStart(PyObject* self, 
534                                                                          PyObject* args, 
535                                                                          PyObject* kwds) {
536         float startArg;
537         if(!PyArg_ParseTuple(args, "f", &startArg)) {
538                 PyErr_SetString(PyExc_TypeError, "Invalid arguments");
539                 return NULL;            
540         }
541         
542         m_startframe = startArg;
543
544         Py_Return;
545 }
546 /* 5. getStart:                                                              */
547 char KX_IpoActuator::GetStart_doc[] = 
548 "getStart()\n"
549 "\tReturns the frame from which the ipo starts playing.\n";
550 PyObject* KX_IpoActuator::PyGetStart(PyObject* self) {
551         return PyFloat_FromDouble(m_startframe);
552 }
553
554 /* 6. setEnd:                                                                */
555 char KX_IpoActuator::SetEnd_doc[] = 
556 "setEnd(frame)\n"
557 "\t - frame: last frame to use (int)\n"
558 "\tSet the frame at which the ipo stops playing.\n";
559 PyObject* KX_IpoActuator::PySetEnd(PyObject* self, 
560                                                                    PyObject* args, 
561                                                                    PyObject* kwds) {
562         float endArg;
563         if(!PyArg_ParseTuple(args, "f", &endArg)) {
564                 PyErr_SetString(PyExc_TypeError, "Invalid arguments");
565                 return NULL;            
566         }
567         
568         m_endframe = endArg;
569
570         Py_Return;
571 }
572 /* 7. getEnd:                                                                */
573 char KX_IpoActuator::GetEnd_doc[] = 
574 "getEnd()\n"
575 "\tReturns the frame at which the ipo stops playing.\n";
576 PyObject* KX_IpoActuator::PyGetEnd(PyObject* self) {
577         return PyFloat_FromDouble(m_endframe);
578 }
579
580 /* 6. setIpoAsForce:                                                           */
581 char KX_IpoActuator::SetIpoAsForce_doc[] = 
582 "setIpoAsForce(force?)\n"
583 "\t - force?    : interpret this ipo as a force? (KX_TRUE, KX_FALSE)\n"
584 "\tSet whether to interpret the ipo as a force rather than a displacement.\n";
585 PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self, 
586                                                                                   PyObject* args, 
587                                                                                   PyObject* kwds) { 
588         int boolArg;
589         
590         if (!PyArg_ParseTuple(args, "i", &boolArg)) {
591                 PyErr_SetString(PyExc_TypeError, "Invalid arguments");
592                 return NULL;
593         }
594
595         m_ipo_as_force = PyArgToBool(boolArg);
596         if (m_ipo_as_force)
597                 m_ipo_add = false;
598         
599         Py_Return;      
600 }
601 /* 7. getIpoAsForce:                                                         */
602 char KX_IpoActuator::GetIpoAsForce_doc[] = 
603 "getIpoAsForce()\n"
604 "\tReturns whether to interpret the ipo as a force rather than a displacement.\n";
605 PyObject* KX_IpoActuator::PyGetIpoAsForce(PyObject* self) {
606         return BoolToPyArg(m_ipo_as_force);
607 }
608
609 /* 6. setIpoAsForce:                                                           */
610 char KX_IpoActuator::SetIpoAdd_doc[] = 
611 "setIpoAdd(add?)\n"
612 "\t - add?    : add flag (KX_TRUE, KX_FALSE)\n"
613 "\tSet whether to interpret the ipo as additive rather than absolute.\n";
614 PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* self, 
615                                                                           PyObject* args, 
616                                                                           PyObject* kwds) { 
617         int boolArg;
618         
619         if (!PyArg_ParseTuple(args, "i", &boolArg)) {
620                 PyErr_SetString(PyExc_TypeError, "Invalid arguments");
621                 return NULL;
622         }
623
624         m_ipo_add = PyArgToBool(boolArg);
625         if (m_ipo_add)
626                 m_ipo_as_force = false;
627         
628         Py_Return;      
629 }
630 /* 7. getIpoAsForce:                                                         */
631 char KX_IpoActuator::GetIpoAdd_doc[] = 
632 "getIpoAsAdd()\n"
633 "\tReturns whether to interpret the ipo as additive rather than absolute.\n";
634 PyObject* KX_IpoActuator::PyGetIpoAdd(PyObject* self) {
635         return BoolToPyArg(m_ipo_add);
636 }
637
638 /* 8. setType:                                                               */
639 char KX_IpoActuator::SetType_doc[] = 
640 "setType(mode)\n"
641 "\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
642 "\tSet the operation mode of the actuator.\n";
643 PyObject* KX_IpoActuator::PySetType(PyObject* self, 
644                                                                         PyObject* args, 
645                                                                         PyObject* kwds) {
646         int typeArg;
647         
648         if (!PyArg_ParseTuple(args, "i", &typeArg)) {
649                 PyErr_SetString(PyExc_TypeError, "Invalid arguments");
650                 return NULL;
651         }
652         
653         if ( (typeArg > KX_ACT_IPO_NODEF) 
654                  && (typeArg < KX_ACT_IPO_KEY2KEY) ) {
655                 m_type = (IpoActType) typeArg;
656         }
657         
658         Py_Return;
659 }
660 /* 9. getType:                                                               */
661 char KX_IpoActuator::GetType_doc[] = 
662 "getType()\n"
663 "\tReturns the operation mode of the actuator.\n";
664 PyObject* KX_IpoActuator::PyGetType(PyObject* self) {
665         return PyInt_FromLong(m_type);
666 }
667
668 /* 10. setForceIpoActsLocal:                                                 */
669 char KX_IpoActuator::SetForceIpoActsLocal_doc[] = 
670 "setForceIpoActsLocal(local?)\n"
671 "\t - local?    : Apply the ipo-as-force in the object's local\n"
672 "\t               coordinates? (KX_TRUE, KX_FALSE)\n"
673 "\tSet whether to apply the force in the object's local\n"
674 "\tcoordinates rather than the world global coordinates.\n";
675 PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self, 
676                                                                                          PyObject* args, 
677                                                                                      PyObject* kwds) { 
678         int boolArg;
679         
680         if (!PyArg_ParseTuple(args, "i", &boolArg)) {
681                 PyErr_SetString(PyExc_TypeError, "Invalid arguments");
682                 return NULL;
683         }
684
685         m_ipo_local = PyArgToBool(boolArg);
686         
687         Py_Return;      
688 }
689 /* 11. getForceIpoActsLocal:                                                */
690 char KX_IpoActuator::GetForceIpoActsLocal_doc[] = 
691 "getForceIpoActsLocal()\n"
692 "\tReturn whether to apply the force in the object's local\n"
693 "\tcoordinates rather than the world global coordinates.\n";
694 PyObject* KX_IpoActuator::PyGetForceIpoActsLocal(PyObject* self) {
695         return BoolToPyArg(m_ipo_local);
696 }
697
698
699 /* eof */