BGE - button for deactivate sensors, controllers and actuators
[blender.git] / source / gameengine / Converter / KX_ConvertActuators.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * Convert Blender actuators for use in the GameEngine
27  */
28
29 /** \file gameengine/Converter/KX_ConvertActuators.cpp
30  *  \ingroup bgeconv
31  */
32
33 #ifdef _MSC_VER
34 #  pragma warning (disable:4786)
35 #endif
36
37 #include <math.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "KX_BlenderSceneConverter.h"
42 #include "KX_ConvertActuators.h"
43
44 #ifdef WITH_AUDASPACE
45 #  include "AUD_C-API.h"
46 #  include "AUD_ChannelMapperFactory.h"
47 #endif
48
49 // Actuators
50 //SCA logiclibrary native logicbricks
51 #include "SCA_PropertyActuator.h"
52 #include "SCA_LogicManager.h"
53 #include "SCA_RandomActuator.h"
54 #include "SCA_2DFilterActuator.h"
55
56 // Ketsji specific logicbricks
57 #include "KX_SceneActuator.h"
58 #include "KX_IpoActuator.h"
59 #include "KX_SoundActuator.h"
60 #include "KX_ObjectActuator.h"
61 #include "KX_TrackToActuator.h"
62 #include "KX_ConstraintActuator.h"
63 #include "KX_CameraActuator.h"
64 #include "KX_GameActuator.h"
65 #include "KX_StateActuator.h"
66 #include "KX_VisibilityActuator.h"
67 #include "KX_SCA_AddObjectActuator.h"
68 #include "KX_SCA_EndObjectActuator.h"
69 #include "KX_SCA_ReplaceMeshActuator.h"
70 #include "KX_ParentActuator.h"
71 #include "KX_SCA_DynamicActuator.h"
72 #include "KX_SteeringActuator.h"
73
74 #include "KX_Scene.h"
75 #include "KX_KetsjiEngine.h"
76
77 #include "IntValue.h"
78 #include "KX_GameObject.h"
79
80 /* This little block needed for linking to Blender... */
81 #include "BKE_text.h"
82 #include "BLI_blenlib.h"
83 #include "BLI_math.h"
84 #include "BLI_path_util.h"
85
86 #include "KX_NetworkMessageActuator.h"
87
88 #ifdef WIN32
89 #include "BLI_winstuff.h"
90 #endif
91
92 #include "DNA_object_types.h"
93 #include "DNA_sound_types.h"
94 #include "DNA_scene_types.h"
95 #include "DNA_actuator_types.h"
96 #include "DNA_packedFile_types.h"
97 #include "BL_ActionActuator.h"
98 #include "BL_ShapeActionActuator.h"
99 #include "BL_ArmatureActuator.h"
100 #include "RNA_access.h"
101 #include "BL_Action.h"
102 /* end of blender include block */
103
104 #include "BL_BlenderDataConversion.h"
105
106 /** 
107  * KX_flt_trunc needed to round 'almost' zero values to zero, else velocities etc. are incorrectly set
108  */
109
110 BLI_INLINE float KX_flt_trunc(const float x)
111 {
112         return ( x < 0.0001f && x > -0.0001f ) ? 0.0f : x;
113 }
114
115 void BL_ConvertActuators(const char* maggiename,
116                          struct Object* blenderobject,
117                          KX_GameObject* gameobj,
118                          SCA_LogicManager* logicmgr,
119                          KX_Scene* scene,
120                          KX_KetsjiEngine* ketsjiEngine,
121                          int activeLayerBitInfo,
122                          bool isInActiveLayer,
123                          KX_BlenderSceneConverter* converter
124                          )
125 {
126         
127         int uniqueint = 0;
128         int actcount = 0;
129         int executePriority = 0;
130         bActuator* bact = (bActuator*) blenderobject->actuators.first;
131         while (bact)
132         {
133                 actcount++;
134                 bact = bact->next;
135         }
136         gameobj->ReserveActuator(actcount);
137         bact = (bActuator*) blenderobject->actuators.first;
138         while (bact)
139         {
140                 STR_String uniquename = bact->name;
141                 STR_String& objectname = gameobj->GetName();
142                 
143                 SCA_IActuator* baseact = NULL;
144                 switch (bact->type)
145                 {
146                 case ACT_OBJECT:
147                         {
148                                 bObjectActuator* obact = (bObjectActuator*) bact->data;
149                                 KX_GameObject* obref = NULL;
150                                 MT_Vector3 forcevec(KX_flt_trunc(obact->forceloc[0]),
151                                                     KX_flt_trunc(obact->forceloc[1]),
152                                                     KX_flt_trunc(obact->forceloc[2]));
153                                 MT_Vector3 torquevec(obact->forcerot[0],
154                                                      obact->forcerot[1],
155                                                      obact->forcerot[2]);
156                                 MT_Vector3 dlocvec(KX_flt_trunc(obact->dloc[0]),
157                                                    KX_flt_trunc(obact->dloc[1]),
158                                                    KX_flt_trunc(obact->dloc[2]));
159                                 MT_Vector3 drotvec(KX_flt_trunc(obact->drot[0]),
160                                                    obact->drot[1],obact->drot[2]);
161                                 MT_Vector3 linvelvec(KX_flt_trunc(obact->linearvelocity[0]),
162                                                      KX_flt_trunc(obact->linearvelocity[1]),
163                                                      KX_flt_trunc(obact->linearvelocity[2]));
164                                 MT_Vector3 angvelvec(KX_flt_trunc(obact->angularvelocity[0]),
165                                                      KX_flt_trunc(obact->angularvelocity[1]),
166                                                      KX_flt_trunc(obact->angularvelocity[2]));
167                                 short damping = obact->damping;
168
169                                 /* Blender uses a bit vector internally for the local-flags. In */
170                                 /* KX, we have four bools. The compiler should be smart enough  */
171                                 /* to do the right thing. We need to explicitly convert here!   */
172                                 
173                                 KX_LocalFlags bitLocalFlag;
174                                 
175                                 bitLocalFlag.Force = bool((obact->flag & ACT_FORCE_LOCAL)!=0);
176                                 bitLocalFlag.Torque = bool((obact->flag & ACT_TORQUE_LOCAL) !=0);//rlocal;
177                                 bitLocalFlag.DLoc = bool((obact->flag & ACT_DLOC_LOCAL)!=0);
178                                 bitLocalFlag.DRot = bool((obact->flag & ACT_DROT_LOCAL)!=0);
179                                 bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0);
180                                 bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0);
181                                 bitLocalFlag.ServoControl = bool(obact->type == ACT_OBJECT_SERVO);
182                                 bitLocalFlag.CharacterMotion = bool(obact->type == ACT_OBJECT_CHARACTER);
183                                 bitLocalFlag.CharacterJump = bool((obact->flag & ACT_CHAR_JUMP)!=0);
184                                 bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0);
185                                 bitLocalFlag.AddOrSetCharLoc = bool((obact->flag & ACT_ADD_CHAR_LOC)!=0);
186                                 if (obact->reference && bitLocalFlag.ServoControl)
187                                 {
188                                         obref = converter->FindGameObject(obact->reference);
189                                 }
190                                 
191                                 KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator(
192                                             gameobj,
193                                             obref,
194                                             forcevec.getValue(),
195                                             torquevec.getValue(),
196                                             dlocvec.getValue(),
197                                             drotvec.getValue(),
198                                             linvelvec.getValue(),
199                                             angvelvec.getValue(),
200                                             damping,
201                                             bitLocalFlag);
202                                 baseact = tmpbaseact;
203                                 break;
204                         }
205                 case ACT_ACTION:
206                         {
207                                 bActionActuator* actact = (bActionActuator*) bact->data;
208                                 STR_String propname = actact->name;
209                                 STR_String propframe = actact->frameProp;
210
211                                 short ipo_flags = 0;
212
213                                 // Convert flags
214                                 if (actact->flag & ACT_IPOFORCE) ipo_flags |= BL_Action::ACT_IPOFLAG_FORCE;
215                                 if (actact->flag & ACT_IPOLOCAL) ipo_flags |= BL_Action::ACT_IPOFLAG_LOCAL;
216                                 if (actact->flag & ACT_IPOADD) ipo_flags |= BL_Action::ACT_IPOFLAG_ADD;
217                                 if (actact->flag & ACT_IPOCHILD) ipo_flags |= BL_Action::ACT_IPOFLAG_CHILD;
218                                         
219                                 BL_ActionActuator* tmpbaseact = new BL_ActionActuator(
220                                             gameobj,
221                                             propname,
222                                             propframe,
223                                             actact->sta,
224                                             actact->end,
225                                             actact->act,
226                                             actact->type, // + 1, because Blender starts to count at zero,
227                                             actact->blend_mode,
228                                             actact->blendin,
229                                             actact->priority,
230                                             actact->layer,
231                                             actact->layer_weight,
232                                             ipo_flags,
233                                             actact->end_reset,
234                                             actact->stridelength
235                                             // Ketsji at 1, because zero is reserved for "NoDef"
236                                             );
237                                 baseact= tmpbaseact;
238                                 break;
239                         }
240                 case ACT_SHAPEACTION:
241                         {
242                                 if (blenderobject->type==OB_MESH) {
243                                         bActionActuator* actact = (bActionActuator*) bact->data;
244                                         STR_String propname = actact->name;
245                                         STR_String propframe = actact->frameProp;
246                                         
247                                         BL_ShapeActionActuator* tmpbaseact = new BL_ShapeActionActuator(
248                                                     gameobj,
249                                                     propname,
250                                                     propframe,
251                                                     actact->sta,
252                                                     actact->end,
253                                                     actact->act,
254                                                     actact->type, // + 1, because Blender starts to count at zero,
255                                                     actact->blendin,
256                                                     actact->priority,
257                                                     actact->stridelength);
258                                         // Ketsji at 1, because zero is reserved for "NoDef"
259                                         baseact= tmpbaseact;
260                                         break;
261                                 }
262                                 else
263                                         printf ("Discarded shape action actuator from non-mesh object [%s]\n", blenderobject->id.name+2);
264                         }
265                 case ACT_IPO:
266                         {
267                                 bIpoActuator* ipoact = (bIpoActuator*) bact->data;
268                                 bool ipochild = (ipoact->flag & ACT_IPOCHILD) !=0;
269                                 STR_String propname = ipoact->name;
270                                 STR_String frameProp = ipoact->frameProp;
271                                 // first bit?
272                                 bool ipo_as_force = (ipoact->flag & ACT_IPOFORCE);
273                                 bool local = (ipoact->flag & ACT_IPOLOCAL);
274                                 bool ipo_add = (ipoact->flag & ACT_IPOADD);
275                                 
276                                 KX_IpoActuator* tmpbaseact = new KX_IpoActuator(
277                                             gameobj,
278                                             propname ,
279                                             frameProp,
280                                             ipoact->sta,
281                                             ipoact->end,
282                                             ipochild,
283                                             ipoact->type + 1, // + 1, because Blender starts to count at zero,
284                                             // Ketsji at 1, because zero is reserved for "NoDef"
285                                             ipo_as_force,
286                                             ipo_add,
287                                             local);
288                                 baseact = tmpbaseact;
289                                 break;
290                         }
291                 case ACT_LAMP:
292                         {
293                                 break;
294                         }
295                 case ACT_CAMERA:
296                         {
297                                 bCameraActuator *camact = (bCameraActuator *) bact->data;
298                                 if (camact->ob) {
299                                         KX_GameObject *tmpgob = converter->FindGameObject(camact->ob);
300                                         
301                                         /* visifac, fac and axis are not copied from the struct...   */ 
302                                         /* that's some internal state...                             */
303                                         KX_CameraActuator *tmpcamact = new KX_CameraActuator(
304                                                     gameobj,
305                                                     tmpgob,
306                                                     camact->height,
307                                                     camact->min,
308                                                     camact->max,
309                                                     camact->axis,
310                                                     camact->damping);
311                                         baseact = tmpcamact;
312                                 }
313                                 break;
314                         }
315                 case ACT_MESSAGE:
316                         {
317                                 bMessageActuator *msgAct = (bMessageActuator *) bact->data;
318                                 
319                                 /* Get the name of the properties that objects must own that
320                                  * we're sending to, if present
321                                  */
322                                 STR_String toPropName = msgAct->toPropName;
323                                 
324                                 /* Get the Message Subject to send.
325                                  */
326                                 STR_String subject = msgAct->subject;
327                                 
328                                 /* Get the bodyType
329                                  */
330                                 int bodyType = msgAct->bodyType;
331
332                                 /* Get the body (text message or property name whose value
333                                  * we'll be sending, might be empty
334                                  */
335                                 const STR_String body = msgAct->body;
336                                 
337                                 KX_NetworkMessageActuator *tmpmsgact = new KX_NetworkMessageActuator(
338                                             gameobj,                                    // actuator controlling object
339                                             scene->GetNetworkScene(),   // needed for replication
340                                             toPropName,
341                                             subject,
342                                             bodyType,
343                                             body);
344                                 baseact = tmpmsgact;
345                                 break;
346                         }
347                 case ACT_MATERIAL:
348                         {
349                                 break;
350                         }
351                 case ACT_SOUND:
352                         {
353                                 bSoundActuator* soundact = (bSoundActuator*) bact->data;
354                                 /* get type, and possibly a start and end frame */
355                                 KX_SoundActuator::KX_SOUNDACT_TYPE
356                                         soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
357                                 
358                                 switch (soundact->type) {
359                                 case ACT_SND_PLAY_STOP_SOUND:
360                                         soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYSTOP;
361                                         break;
362                                 case ACT_SND_PLAY_END_SOUND:
363                                         soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYEND;
364                                         break;
365                                 case ACT_SND_LOOP_STOP_SOUND:
366                                         soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPSTOP;
367                                         break;
368                                 case ACT_SND_LOOP_END_SOUND:
369                                         soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPEND;
370                                         break;
371                                 case ACT_SND_LOOP_BIDIRECTIONAL_SOUND:
372                                         soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL;
373                                         break;
374                                 case ACT_SND_LOOP_BIDIRECTIONAL_STOP_SOUND:
375                                         soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP;
376                                         break;
377                                         
378                                 default:
379                                         /* This is an error!!! */
380                                         soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
381                                 }
382                                 
383                                 if (soundActuatorType != KX_SoundActuator::KX_SOUNDACT_NODEF) 
384                                 {
385                                         bSound* sound = soundact->sound;
386                                         bool is3d = soundact->flag & ACT_SND_3D_SOUND ? true : false;
387                                         boost::shared_ptr<AUD_IFactory> snd_sound;
388                                         KX_3DSoundSettings settings;
389                                         settings.cone_inner_angle = RAD2DEGF(soundact->sound3D.cone_inner_angle);
390                                         settings.cone_outer_angle = RAD2DEGF(soundact->sound3D.cone_outer_angle);
391                                         settings.cone_outer_gain = soundact->sound3D.cone_outer_gain;
392                                         settings.max_distance = soundact->sound3D.max_distance;
393                                         settings.max_gain = soundact->sound3D.max_gain;
394                                         settings.min_gain = soundact->sound3D.min_gain;
395                                         settings.reference_distance = soundact->sound3D.reference_distance;
396                                         settings.rolloff_factor = soundact->sound3D.rolloff_factor;
397
398                                         if (!sound)
399                                         {
400                                                 std::cout <<    "WARNING: Sound actuator \"" << bact->name <<
401                                                                                 "\" from object \"" <<  blenderobject->id.name+2 <<
402                                                                                 "\" has no sound datablock." << std::endl;
403                                         }
404                                         else
405                                         {
406                                                 snd_sound = *reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(sound->playback_handle);
407
408                                                 // if sound shall be 3D but isn't mono, we have to make it mono!
409                                                 if (is3d)
410                                                 {
411                                                         try
412                                                         {
413                                                                 boost::shared_ptr<AUD_IReader> reader = snd_sound->createReader();
414                                                                 if (reader->getSpecs().channels != AUD_CHANNELS_MONO)
415                                                                 {
416                                                                         AUD_DeviceSpecs specs;
417                                                                         specs.channels = AUD_CHANNELS_MONO;
418                                                                         specs.rate = AUD_RATE_INVALID;
419                                                                         specs.format = AUD_FORMAT_INVALID;
420                                                                         snd_sound = boost::shared_ptr<AUD_IFactory>(new AUD_ChannelMapperFactory(snd_sound, specs));
421                                                                 }
422                                                         }
423                                                         catch(AUD_Exception&)
424                                                         {
425                                                                 // sound cannot be played... ignore
426                                                         }
427                                                 }
428                                         }
429                                         KX_SoundActuator* tmpsoundact =
430                                                 new KX_SoundActuator(gameobj,
431                                                 snd_sound,
432                                                 soundact->volume,
433                                                 (float)(expf((soundact->pitch / 12.0f) * (float)M_LN2)),
434                                                 is3d,
435                                                 settings,
436                                                 soundActuatorType);
437
438                                         tmpsoundact->SetName(bact->name);
439                                         baseact = tmpsoundact;
440                                 }
441                                 break;
442                         }
443                 case ACT_PROPERTY:
444                         {
445                                 bPropertyActuator* propact = (bPropertyActuator*) bact->data;
446                                 SCA_IObject* destinationObj = NULL;
447                                 
448                                 /*
449                                  * here the destinationobject is searched. problem with multiple scenes: other scenes
450                                  * have not been converted yet, so the destobj will not be found, so the prop will
451                                  * not be copied.
452                                  * possible solutions:
453                                  * - convert everything when possible and not realtime only when needed.
454                                  * - let the object-with-property report itself to the act when converted
455                                  */
456                                 if (propact->ob)
457                                         destinationObj = converter->FindGameObject(propact->ob);
458                                 
459                                 SCA_PropertyActuator* tmppropact = new SCA_PropertyActuator(
460                                             gameobj,
461                                             destinationObj,
462                                             propact->name,
463                                             propact->value,
464                                             propact->type + 1); // + 1 because Ketsji Logic starts
465                                 // with 0 for KX_ACT_PROP_NODEF
466                                 baseact = tmppropact;
467                                 break;
468                         }
469                 case ACT_EDIT_OBJECT:
470                         {
471                                 bEditObjectActuator *editobact 
472                                         = (bEditObjectActuator *) bact->data;
473                                 /* There are four different kinds of 'edit object' thingies  */
474                                 /* The alternative to this lengthy conversion is packing     */
475                                 /* several actuators in one, which is not very nice design.. */
476                                 switch (editobact->type) {
477                                 case ACT_EDOB_ADD_OBJECT: 
478                                         {
479                                                 
480                                                 // does the 'original' for replication exists, and 
481                                                 // is it in a non-active layer ?
482                                                 SCA_IObject* originalval = NULL;
483                                                 if (editobact->ob)
484                                                 {
485                                                         if (editobact->ob->lay & activeLayerBitInfo)
486                                                         {
487                                                                 fprintf(stderr, "Warning, object \"%s\" from AddObject actuator \"%s\" is not in a hidden layer.\n", objectname.Ptr(), uniquename.Ptr());
488                                                         }
489                                                         else {
490                                                                 originalval = converter->FindGameObject(editobact->ob);
491                                                         }
492                                                 }
493                                                 
494                                                 KX_SCA_AddObjectActuator* tmpaddact = new KX_SCA_AddObjectActuator(
495                                                             gameobj,
496                                                             originalval,
497                                                             editobact->time,
498                                                             scene,
499                                                             editobact->linVelocity,
500                                                             (editobact->localflag & ACT_EDOB_LOCAL_LINV) != 0,
501                                                             editobact->angVelocity,
502                                                             (editobact->localflag & ACT_EDOB_LOCAL_ANGV) != 0);
503
504                                                                 //editobact->ob to gameobj
505                                                                 baseact = tmpaddact;
506                                         }
507                                         break;
508                                 case ACT_EDOB_END_OBJECT:
509                                         {
510                                                 KX_SCA_EndObjectActuator* tmpendact 
511                                                         = new KX_SCA_EndObjectActuator(gameobj,scene);
512                                                 baseact = tmpendact;
513                                         }
514                                         break;
515                                 case ACT_EDOB_REPLACE_MESH:
516                                         {
517                                                 RAS_MeshObject *tmpmesh = NULL;
518                                                 if (editobact->me)
519                                                         tmpmesh = BL_ConvertMesh(
520                                                                     editobact->me,
521                                                                     blenderobject,
522                                                                     scene,
523                                                                     converter,
524                                                                     false
525                                                                     );
526
527                                                 KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator(
528                                                             gameobj,
529                                                             tmpmesh,
530                                                             scene,
531                                                             (editobact->flag & ACT_EDOB_REPLACE_MESH_NOGFX) == 0,
532                                                             (editobact->flag & ACT_EDOB_REPLACE_MESH_PHYS) != 0);
533
534                                                 baseact = tmpreplaceact;
535                                         }
536                                         break;
537                                 case ACT_EDOB_TRACK_TO:
538                                         {
539                                                 SCA_IObject* originalval = NULL;
540                                                 if (editobact->ob)
541                                                         originalval = converter->FindGameObject(editobact->ob);
542                                                         
543                                                 KX_TrackToActuator* tmptrackact = new KX_TrackToActuator(
544                                                             gameobj,
545                                                             originalval,
546                                                             editobact->time,
547                                                             editobact->flag,
548                                                             blenderobject->trackflag,
549                                                             blenderobject->upflag);
550                                                 baseact = tmptrackact;
551                                                 break;
552                                         }
553                                 case ACT_EDOB_DYNAMICS:
554                                         {
555                                                 KX_SCA_DynamicActuator* tmpdynact = new KX_SCA_DynamicActuator(
556                                                             gameobj,
557                                                             editobact->dyn_operation,
558                                                             editobact->mass);
559                                                 baseact = tmpdynact;
560                                         }
561                                 }
562                                 break;
563                         }
564                 case ACT_CONSTRAINT:
565                         {
566                                 float min = 0.0, max = 0.0;
567                                 char *prop = NULL;
568                                 KX_ConstraintActuator::KX_CONSTRAINTTYPE locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_NODEF;
569                                 bConstraintActuator *conact 
570                                         = (bConstraintActuator*) bact->data;
571                                 /* convert settings... degrees in the ui become radians  */ 
572                                 /* internally                                            */ 
573                                 if (conact->type == ACT_CONST_TYPE_ORI) {
574                                         min = conact->minloc[0];
575                                         max = conact->maxloc[0];
576                                         switch (conact->mode) {
577                                         case ACT_CONST_DIRPX:
578                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX;
579                                                 break;
580                                         case ACT_CONST_DIRPY:
581                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIY;
582                                                 break;
583                                         case ACT_CONST_DIRPZ:
584                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIZ;
585                                                 break;
586                                         }
587                                 } else if (conact->type == ACT_CONST_TYPE_DIST) {
588                                         switch (conact->mode) {
589                                         case ACT_CONST_DIRPX:
590                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPX;
591                                                 min = conact->minloc[0];
592                                                 max = conact->maxloc[0];
593                                                 break;
594                                         case ACT_CONST_DIRPY:
595                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPY;
596                                                 min = conact->minloc[1];
597                                                 max = conact->maxloc[1];
598                                                 break;
599                                         case ACT_CONST_DIRPZ:
600                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPZ;
601                                                 min = conact->minloc[2];
602                                                 max = conact->maxloc[2];
603                                                 break;
604                                         case ACT_CONST_DIRNX:
605                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNX;
606                                                 min = conact->minloc[0];
607                                                 max = conact->maxloc[0];
608                                                 break;
609                                         case ACT_CONST_DIRNY:
610                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNY;
611                                                 min = conact->minloc[1];
612                                                 max = conact->maxloc[1];
613                                                 break;
614                                         case ACT_CONST_DIRNZ:
615                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNZ;
616                                                 min = conact->minloc[2];
617                                                 max = conact->maxloc[2];
618                                                 break;
619                                         }
620                                         prop = conact->matprop;
621                                 } else if (conact->type == ACT_CONST_TYPE_FH) {
622                                         switch (conact->mode) {
623                                         case ACT_CONST_DIRPX:
624                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPX;
625                                                 min = conact->minloc[0];
626                                                 max = conact->maxloc[0];
627                                                 break;
628                                         case ACT_CONST_DIRPY:
629                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPY;
630                                                 min = conact->minloc[1];
631                                                 max = conact->maxloc[1];
632                                                 break;
633                                         case ACT_CONST_DIRPZ:
634                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPZ;
635                                                 min = conact->minloc[2];
636                                                 max = conact->maxloc[2];
637                                                 break;
638                                         case ACT_CONST_DIRNX:
639                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNX;
640                                                 min = conact->minloc[0];
641                                                 max = conact->maxloc[0];
642                                                 break;
643                                         case ACT_CONST_DIRNY:
644                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNY;
645                                                 min = conact->minloc[1];
646                                                 max = conact->maxloc[1];
647                                                 break;
648                                         case ACT_CONST_DIRNZ:
649                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNZ;
650                                                 min = conact->minloc[2];
651                                                 max = conact->maxloc[2];
652                                                 break;
653                                         }
654                                         prop = conact->matprop;
655                                 } else {
656                                         switch (conact->flag) {
657                                         case ACT_CONST_LOCX:
658                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX; 
659                                                 min = conact->minloc[0];
660                                                 max = conact->maxloc[0];
661                                                 break;
662                                         case ACT_CONST_LOCY:
663                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY; 
664                                                 min = conact->minloc[1];
665                                                 max = conact->maxloc[1];
666                                                 break;
667                                         case ACT_CONST_LOCZ:
668                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ;
669                                                 min = conact->minloc[2];
670                                                 max = conact->maxloc[2];
671                                                 break;
672                                         case ACT_CONST_ROTX:
673                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX;
674                                                 min = conact->minrot[0] * (float)MT_RADS_PER_DEG;
675                                                 max = conact->maxrot[0] * (float)MT_RADS_PER_DEG;
676                                                 break;
677                                         case ACT_CONST_ROTY:
678                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY;
679                                                 min = conact->minrot[1] * (float)MT_RADS_PER_DEG;
680                                                 max = conact->maxrot[1] * (float)MT_RADS_PER_DEG;
681                                                 break;
682                                         case ACT_CONST_ROTZ:
683                                                 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ;
684                                                 min = conact->minrot[2] * (float)MT_RADS_PER_DEG;
685                                                 max = conact->maxrot[2] * (float)MT_RADS_PER_DEG;
686                                                 break;
687                                         default:
688                                                 ; /* error */ 
689                                         }
690                                 }
691                                 KX_ConstraintActuator *tmpconact = new KX_ConstraintActuator(
692                                             gameobj,
693                                             conact->damp,
694                                             conact->rotdamp,
695                                             min,
696                                             max,
697                                             conact->maxrot,
698                                             locrot,
699                                             conact->time,
700                                             conact->flag,
701                                             prop);
702                                 baseact = tmpconact;
703                                 break;
704                         }
705                 case ACT_GROUP:
706                         {
707                                 // deprecated
708                         }
709                         break;
710                 case ACT_SCENE:
711                         {
712                                 bSceneActuator *sceneact = (bSceneActuator *) bact->data;
713                                 STR_String nextSceneName("");
714                                 
715                                 KX_SceneActuator* tmpsceneact;
716                                 int mode = KX_SceneActuator::KX_SCENE_NODEF;
717                                 KX_Camera *cam = NULL;
718                                 //KX_Scene* scene = NULL;
719                                 switch (sceneact->type)
720                                 {
721                                 case ACT_SCENE_RESUME:
722                                 case ACT_SCENE_SUSPEND:
723                                 case ACT_SCENE_ADD_FRONT:
724                                 case ACT_SCENE_ADD_BACK:
725                                 case ACT_SCENE_REMOVE:
726                                 case ACT_SCENE_SET:
727                                         {
728                                                 switch (sceneact->type)
729                                                 {
730                                                 case ACT_SCENE_RESUME:
731                                                         mode = KX_SceneActuator::KX_SCENE_RESUME;
732                                                         break;
733                                                 case ACT_SCENE_SUSPEND:
734                                                         mode = KX_SceneActuator::KX_SCENE_SUSPEND;
735                                                         break;
736                                                 case ACT_SCENE_ADD_FRONT:
737                                                         mode = KX_SceneActuator::KX_SCENE_ADD_FRONT_SCENE;
738                                                         break;
739                                                 case ACT_SCENE_ADD_BACK:
740                                                         mode = KX_SceneActuator::KX_SCENE_ADD_BACK_SCENE;
741                                                         break;
742                                                 case ACT_SCENE_REMOVE:
743                                                         mode = KX_SceneActuator::KX_SCENE_REMOVE_SCENE;
744                                                         break;
745                                                 case ACT_SCENE_SET:
746                                                 default:
747                                                         mode = KX_SceneActuator::KX_SCENE_SET_SCENE;
748                                                         break;
749                                                 };
750                                                 
751                                                 if (sceneact->scene) {
752                                                         nextSceneName = sceneact->scene->id.name + 2;
753                                                 }
754                                                 
755                                                 break;
756                                         }
757                                 case ACT_SCENE_CAMERA:
758                                         mode = KX_SceneActuator::KX_SCENE_SET_CAMERA;
759                                         if (sceneact->camera)
760                                         {
761                                                 KX_GameObject *tmp = converter->FindGameObject(sceneact->camera);
762                                                 if (tmp && tmp->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
763                                                         cam = (KX_Camera*)tmp;
764                                         }
765                                         break;
766                                 case ACT_SCENE_RESTART:
767                                         {
768                                                 
769                                                 mode =  KX_SceneActuator::KX_SCENE_RESTART;
770                                                 break;
771                                         }
772                                 default:
773                                         ; /* flag error */
774                                 }
775                                 tmpsceneact = new KX_SceneActuator(
776                                             gameobj,
777                                             mode,
778                                             scene,
779                                             ketsjiEngine,
780                                             nextSceneName,
781                                             cam);
782                                 baseact = tmpsceneact;
783                                 break;
784                         }
785                 case ACT_GAME:
786                         {
787                                 bGameActuator *gameact = (bGameActuator *) bact->data;
788                                 KX_GameActuator* tmpgameact;
789                                 STR_String filename = maggiename;
790                                 STR_String loadinganimationname = "";
791                                 int mode = KX_GameActuator::KX_GAME_NODEF;
792                                 switch (gameact->type)
793                                 {
794                                 case ACT_GAME_LOAD:
795                                         {
796                                                 mode = KX_GameActuator::KX_GAME_LOAD;
797                                                 filename = gameact->filename;
798                                                 loadinganimationname = gameact->loadaniname;
799                                                 break;
800                                         }
801                                 case ACT_GAME_START:
802                                         {
803                                                 mode = KX_GameActuator::KX_GAME_START;
804                                                 filename = gameact->filename;
805                                                 loadinganimationname = gameact->loadaniname;
806                                                 break;
807                                         }
808                                 case ACT_GAME_RESTART:
809                                         {
810                                                 mode = KX_GameActuator::KX_GAME_RESTART;
811                                                 break;
812                                         }
813                                 case ACT_GAME_QUIT:
814                                         {
815                                                 mode = KX_GameActuator::KX_GAME_QUIT;
816                                                 break;
817                                         }
818                                 case ACT_GAME_SAVECFG:
819                                         {
820                                                 mode = KX_GameActuator::KX_GAME_SAVECFG;
821                                                 break;
822                                         }
823                                 case ACT_GAME_LOADCFG:
824                                         {
825                                                 mode = KX_GameActuator::KX_GAME_LOADCFG;
826                                                 break;
827                                         }
828                                 default:
829                                         ; /* flag error */
830                                 }
831                                 tmpgameact = new KX_GameActuator(
832                                             gameobj,
833                                             mode,
834                                             filename,
835                                             loadinganimationname,
836                                             scene,
837                                             ketsjiEngine);
838                                 baseact = tmpgameact;
839
840                                 break;
841                         }
842                 case ACT_RANDOM:
843                         {
844                                 bRandomActuator *randAct 
845                                         = (bRandomActuator *) bact->data;
846                                 
847                                 unsigned long seedArg = randAct->seed;
848                                 if (seedArg == 0)
849                                 {
850                                         seedArg = (int)(ketsjiEngine->GetRealTime()*100000.0);
851                                         seedArg ^= (intptr_t)randAct;
852                                 }
853                                 SCA_RandomActuator::KX_RANDOMACT_MODE modeArg 
854                                         = SCA_RandomActuator::KX_RANDOMACT_NODEF;
855                                 SCA_RandomActuator *tmprandomact;
856                                 float paraArg1 = 0.0;
857                                 float paraArg2 = 0.0;
858                                 
859                                 switch (randAct->distribution) {
860                                 case ACT_RANDOM_BOOL_CONST:
861                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST;
862                                         paraArg1 = (float) randAct->int_arg_1;
863                                         break;
864                                 case ACT_RANDOM_BOOL_UNIFORM:
865                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM;
866                                         break;
867                                 case ACT_RANDOM_BOOL_BERNOUILLI:
868                                         paraArg1 = randAct->float_arg_1;
869                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI;
870                                         break;
871                                 case ACT_RANDOM_INT_CONST:
872                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_CONST;
873                                         paraArg1 = (float) randAct->int_arg_1;
874                                         break;
875                                 case ACT_RANDOM_INT_UNIFORM:
876                                         paraArg1 = (float) randAct->int_arg_1;
877                                         paraArg2 = (float) randAct->int_arg_2;
878                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_UNIFORM;
879                                         break;
880                                 case ACT_RANDOM_INT_POISSON:
881                                         paraArg1 = randAct->float_arg_1;
882                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_POISSON;
883                                         break;
884                                 case ACT_RANDOM_FLOAT_CONST:
885                                         paraArg1 = randAct->float_arg_1;
886                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_CONST;
887                                         break;
888                                 case ACT_RANDOM_FLOAT_UNIFORM:
889                                         paraArg1 = randAct->float_arg_1;
890                                         paraArg2 = randAct->float_arg_2;
891                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_UNIFORM;
892                                         break;
893                                 case ACT_RANDOM_FLOAT_NORMAL:
894                                         paraArg1 = randAct->float_arg_1;
895                                         paraArg2 = randAct->float_arg_2;
896                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL;
897                                         break;
898                                 case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
899                                         paraArg1 = randAct->float_arg_1;
900                                         modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
901                                         break;
902                                 default:
903                                         ; /* error */
904                                 }
905                                 tmprandomact = new SCA_RandomActuator(
906                                             gameobj,
907                                             seedArg,
908                                             modeArg,
909                                             paraArg1,
910                                             paraArg2,
911                                             randAct->propname);
912                                 baseact = tmprandomact;
913                         }
914                         break;
915
916                 case ACT_VISIBILITY:
917                 {
918                         bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data;
919                         KX_VisibilityActuator * tmp_vis_act = NULL;
920                         bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0);
921                         bool o = ((vis_act->flag & ACT_VISIBILITY_OCCLUSION) != 0);
922                         bool recursive = ((vis_act->flag & ACT_VISIBILITY_RECURSIVE) != 0);
923
924                         tmp_vis_act = new KX_VisibilityActuator(gameobj, !v, o, recursive);
925                         
926                         baseact = tmp_vis_act;
927                 }
928                 break;
929
930                 case ACT_STATE:
931                 {
932                         bStateActuator *sta_act = (bStateActuator *) bact->data;
933                         KX_StateActuator * tmp_sta_act = NULL;
934
935                         tmp_sta_act = 
936                                 new KX_StateActuator(gameobj, sta_act->type, sta_act->mask);
937                         
938                         baseact = tmp_sta_act;
939                 }
940                 break;
941
942                 case ACT_2DFILTER:
943                 {
944                         bTwoDFilterActuator *_2dfilter = (bTwoDFilterActuator*) bact->data;
945                         SCA_2DFilterActuator *tmp = NULL;
946
947                         RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode;
948                         switch (_2dfilter->type) {
949                                 case ACT_2DFILTER_MOTIONBLUR:
950                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_MOTIONBLUR;
951                                         break;
952                                 case ACT_2DFILTER_BLUR:
953                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_BLUR;
954                                         break;
955                                 case ACT_2DFILTER_SHARPEN:
956                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_SHARPEN;
957                                         break;
958                                 case ACT_2DFILTER_DILATION:
959                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_DILATION;
960                                         break;
961                                 case ACT_2DFILTER_EROSION:
962                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_EROSION;
963                                         break;
964                                 case ACT_2DFILTER_LAPLACIAN:
965                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_LAPLACIAN;
966                                         break;
967                                 case ACT_2DFILTER_SOBEL:
968                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_SOBEL;
969                                         break;
970                                 case ACT_2DFILTER_PREWITT:
971                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_PREWITT;
972                                         break;
973                                 case ACT_2DFILTER_GRAYSCALE:
974                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_GRAYSCALE;
975                                         break;
976                                 case ACT_2DFILTER_SEPIA:
977                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_SEPIA;
978                                         break;
979                                 case ACT_2DFILTER_INVERT:
980                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_INVERT;
981                                         break;
982                                 case ACT_2DFILTER_CUSTOMFILTER:
983                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_CUSTOMFILTER;
984                                         break;
985                                 case ACT_2DFILTER_NOFILTER:
986                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
987                                         break;
988                                 case ACT_2DFILTER_DISABLED:
989                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_DISABLED;
990                                         break;
991                                 case ACT_2DFILTER_ENABLED:
992                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_ENABLED;
993                                         break;
994                                 default:
995                                         filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
996                                         break;
997                         }
998
999                         tmp = new SCA_2DFilterActuator(gameobj, filtermode,  _2dfilter->flag,
1000                                                        _2dfilter->float_arg, _2dfilter->int_arg,
1001                                                        ketsjiEngine->GetRasterizer(), scene);
1002
1003                         if (_2dfilter->text)
1004                         {
1005                                 char *buf;
1006                                 // this is some blender specific code
1007                                 buf = txt_to_buf(_2dfilter->text);
1008                                 if (buf)
1009                                 {
1010                                         tmp->SetShaderText(buf);
1011                                         MEM_freeN(buf);
1012                                 }
1013                         }
1014
1015                         baseact = tmp;
1016
1017                 }
1018                 break;
1019                 case ACT_PARENT:
1020                         {
1021                                 bParentActuator *parAct = (bParentActuator *) bact->data;
1022                                 int mode = KX_ParentActuator::KX_PARENT_NODEF;
1023                                 bool addToCompound = true;
1024                                 bool ghost = true;
1025                                 KX_GameObject *tmpgob = NULL;
1026
1027                                 switch (parAct->type) {
1028                                         case ACT_PARENT_SET:
1029                                                 mode = KX_ParentActuator::KX_PARENT_SET;
1030                                                 tmpgob = converter->FindGameObject(parAct->ob);
1031                                                 addToCompound = !(parAct->flag & ACT_PARENT_COMPOUND);
1032                                                 ghost = !(parAct->flag & ACT_PARENT_GHOST);
1033                                                 break;
1034                                         case ACT_PARENT_REMOVE:
1035                                                 mode = KX_ParentActuator::KX_PARENT_REMOVE;
1036                                                 tmpgob = NULL;
1037                                                 break;
1038                                 }
1039         
1040                                 KX_ParentActuator *tmpparact
1041                                         = new KX_ParentActuator(gameobj,
1042                                         mode,
1043                                         addToCompound,
1044                                         ghost,
1045                                         tmpgob);
1046                                 baseact = tmpparact;
1047                                 break;
1048                         }
1049                 
1050                 case ACT_ARMATURE:
1051                         {
1052                                 bArmatureActuator* armAct = (bArmatureActuator*) bact->data;
1053                                 KX_GameObject *tmpgob = converter->FindGameObject(armAct->target);
1054                                 KX_GameObject *subgob = converter->FindGameObject(armAct->subtarget);
1055                                 BL_ArmatureActuator* tmparmact = new BL_ArmatureActuator(
1056                                             gameobj,
1057                                             armAct->type,
1058                                             armAct->posechannel,
1059                                             armAct->constraint,
1060                                             tmpgob,
1061                                             subgob,
1062                                             armAct->weight,
1063                                             armAct->influence);
1064                                 baseact = tmparmact;
1065                                 break;
1066                         }
1067                 case ACT_STEERING:
1068                         {
1069                                 bSteeringActuator *stAct = (bSteeringActuator *) bact->data;
1070                                 KX_GameObject *navmeshob = NULL;
1071                                 if (stAct->navmesh)
1072                                 {
1073                                         PointerRNA settings_ptr;
1074                                         RNA_pointer_create((ID *)stAct->navmesh, &RNA_GameObjectSettings, stAct->navmesh, &settings_ptr);
1075                                         if (RNA_enum_get(&settings_ptr, "physics_type") == OB_BODY_TYPE_NAVMESH)
1076                                                 navmeshob = converter->FindGameObject(stAct->navmesh);
1077                                 }
1078                                 KX_GameObject *targetob = converter->FindGameObject(stAct->target);
1079
1080                                 int mode = KX_SteeringActuator::KX_STEERING_NODEF;
1081                                 switch (stAct->type) {
1082                                 case ACT_STEERING_SEEK:
1083                                         mode = KX_SteeringActuator::KX_STEERING_SEEK;
1084                                         break;
1085                                 case ACT_STEERING_FLEE:
1086                                         mode = KX_SteeringActuator::KX_STEERING_FLEE;
1087                                         break;
1088                                 case ACT_STEERING_PATHFOLLOWING:
1089                                         mode = KX_SteeringActuator::KX_STEERING_PATHFOLLOWING;
1090                                         break;
1091                                 }
1092
1093                                 bool selfTerminated = (stAct->flag & ACT_STEERING_SELFTERMINATED) !=0;
1094                                 bool enableVisualization = (stAct->flag & ACT_STEERING_ENABLEVISUALIZATION) !=0;
1095                                 short facingMode = (stAct->flag & ACT_STEERING_AUTOMATICFACING) ? stAct->facingaxis : 0;
1096                                 bool normalup = (stAct->flag & ACT_STEERING_NORMALUP) !=0;
1097                                 KX_SteeringActuator *tmpstact
1098                                         = new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,stAct->dist, 
1099                                         stAct->velocity, stAct->acceleration, stAct->turnspeed, 
1100                                         selfTerminated, stAct->updateTime,
1101                                         scene->GetObstacleSimulation(), facingMode, normalup, enableVisualization);
1102                                 baseact = tmpstact;
1103                                 break;
1104                         }
1105                 default:
1106                         ; /* generate some error */
1107                 }
1108                 
1109                 if (baseact && !(bact->flag & ACT_DEACTIVATE))
1110                 {
1111                         baseact->SetExecutePriority(executePriority++);
1112                         uniquename += "#ACT#";
1113                         uniqueint++;
1114                         CIntValue* uniqueval = new CIntValue(uniqueint);
1115                         uniquename += uniqueval->GetText();
1116                         uniqueval->Release();
1117                         baseact->SetName(bact->name);
1118                         //gameobj->SetProperty(uniquename,baseact);
1119                         gameobj->AddActuator(baseact);
1120                         
1121                         converter->RegisterGameActuator(baseact, bact);
1122                         // done with baseact, release it
1123                         baseact->Release();
1124                 }
1125                 
1126                 bact = bact->next;
1127         }
1128 }
1129
1130