2.50:
[blender.git] / source / gameengine / Ketsji / KX_SceneActuator.cpp
1 /**
2 * Set scene/camera 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 #include "SCA_IActuator.h"
33 #include "KX_SceneActuator.h"
34 #include <iostream>
35 #include "KX_Scene.h"
36 #include "KX_Camera.h"
37 #include "KX_KetsjiEngine.h"
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 /* ------------------------------------------------------------------------- */
44 /* Native functions                                                          */
45 /* ------------------------------------------------------------------------- */
46
47 KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj, 
48                                                                    int mode,
49                                                                    KX_Scene *scene,
50                                                                    KX_KetsjiEngine* ketsjiEngine,
51                                                                    const STR_String& nextSceneName,
52                                                                    KX_Camera* camera,
53                                                                    PyTypeObject* T)
54                                                                    : SCA_IActuator(gameobj, T)
55 {
56         m_mode = mode;
57         m_scene  = scene;
58         m_KetsjiEngine=ketsjiEngine;
59         m_camera = camera;
60         m_nextSceneName = nextSceneName;
61         if (m_camera)
62                 m_camera->RegisterActuator(this);
63 } /* End of constructor */
64
65
66
67 KX_SceneActuator::~KX_SceneActuator()
68
69         if (m_camera)
70                 m_camera->UnregisterActuator(this);
71 } /* end of destructor */
72
73
74
75 CValue* KX_SceneActuator::GetReplica()
76 {
77         KX_SceneActuator* replica = new KX_SceneActuator(*this);
78         replica->ProcessReplica();
79         return replica;
80 }
81
82 void KX_SceneActuator::ProcessReplica()
83 {
84         if (m_camera)
85                 m_camera->RegisterActuator(this);
86         SCA_IActuator::ProcessReplica();
87 }
88
89 bool KX_SceneActuator::UnlinkObject(SCA_IObject* clientobj)
90 {
91         if (clientobj == (SCA_IObject*)m_camera)
92         {
93                 // this object is being deleted, we cannot continue to track it.
94                 m_camera = NULL;
95                 return true;
96         }
97         return false;
98 }
99
100 void KX_SceneActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
101 {
102         void **h_obj = (*obj_map)[m_camera];
103         if (h_obj) {
104                 if (m_camera)
105                         m_camera->UnregisterActuator(this);
106                 m_camera = (KX_Camera*)(*h_obj);
107                 m_camera->RegisterActuator(this);
108         }
109 }
110
111
112 bool KX_SceneActuator::Update()
113 {
114         // bool result = false; /*unused*/
115         bool bNegativeEvent = IsNegativeEvent();
116         RemoveAllEvents();
117
118         if (bNegativeEvent)
119                 return false; // do nothing on negative events
120
121         switch (m_mode)
122         {
123         case KX_SCENE_RESTART:
124                 {
125                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_scene->GetName());
126                         break;
127                 }
128         case KX_SCENE_SET_CAMERA:
129                 if (m_camera)
130                 {
131                         m_scene->SetActiveCamera(m_camera);
132                 }
133                 else
134                 {
135                         // if no camera is set and the parent object is a camera, use it as the camera
136                         SCA_IObject* parent = GetParent();
137                         if (parent->isA(&KX_Camera::Type))
138                         {
139                                 m_scene->SetActiveCamera((KX_Camera*)parent);
140                         }
141                 }
142                 break;
143         default:
144                 break;
145         }
146         
147         if (!m_nextSceneName.Length())
148                 return false;
149         
150         switch (m_mode)
151         {
152         case KX_SCENE_SET_SCENE:
153                 {
154                         m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_nextSceneName);
155                         break;
156                 }
157         case KX_SCENE_ADD_FRONT_SCENE:
158                 {
159                         bool overlay=true;
160                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
161                         break;
162                 }
163         case KX_SCENE_ADD_BACK_SCENE:
164                 {
165                         bool overlay=false;
166                         m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay);
167                         break;
168                 }
169         case KX_SCENE_REMOVE_SCENE:
170                 {
171                         m_KetsjiEngine->RemoveScene(m_nextSceneName);
172                         break;
173                 }
174         case KX_SCENE_SUSPEND:
175                 {
176                         m_KetsjiEngine->SuspendScene(m_nextSceneName);
177                         break;
178                 }
179         case KX_SCENE_RESUME:
180                 {
181                         m_KetsjiEngine->ResumeScene(m_nextSceneName);
182                         break;
183                 }
184         default:
185                 ; /* do nothing? this is an internal error !!! */
186         }
187         
188         return false;
189 }
190
191
192
193 /*  returns a camera if the name is valid */
194 KX_Camera* KX_SceneActuator::FindCamera(char *camName)
195 {
196         KX_SceneList* sl = m_KetsjiEngine->CurrentScenes();
197         STR_String name = STR_String(camName);
198         KX_SceneList::iterator it = sl->begin();
199         KX_Camera* cam = NULL;
200
201         while ((it != sl->end()) && (!cam))
202         {
203                 cam = (*it)->FindCamera(name);
204                 it++;
205         }
206
207         return cam;
208 }
209
210
211
212 KX_Scene* KX_SceneActuator::FindScene(char * sceneName)
213 {
214         return m_KetsjiEngine->FindScene(sceneName);
215 }
216
217
218
219
220 /* ------------------------------------------------------------------------- */
221 /* Python functions                                                          */
222 /* ------------------------------------------------------------------------- */
223
224 /* Integration hooks ------------------------------------------------------- */
225 PyTypeObject KX_SceneActuator::Type = {
226 #if (PY_VERSION_HEX >= 0x02060000)
227         PyVarObject_HEAD_INIT(NULL, 0)
228 #else
229         /* python 2.5 and below */
230         PyObject_HEAD_INIT( NULL )  /* required py macro */
231         0,                          /* ob_size */
232 #endif
233                 "KX_SceneActuator",
234                 sizeof(PyObjectPlus_Proxy),
235                 0,
236                 py_base_dealloc,
237                 0,
238                 0,
239                 0,
240                 0,
241                 py_base_repr,
242                 0,0,0,0,0,0,
243                 py_base_getattro,
244                 py_base_setattro,
245                 0,0,0,0,0,0,0,0,0,
246                 Methods
247 };
248
249
250
251 PyParentObject KX_SceneActuator::Parents[] =
252 {
253         &KX_SceneActuator::Type,
254                 &SCA_IActuator::Type,
255                 &SCA_ILogicBrick::Type,
256                 &CValue::Type,
257                 NULL
258 };
259
260
261
262 PyMethodDef KX_SceneActuator::Methods[] =
263 {
264         //Deprecated functions ------>
265         {"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, (PY_METHODCHAR)SetUseRestart_doc},
266         {"setScene",      (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, (PY_METHODCHAR)SetScene_doc},
267         {"setCamera",     (PyCFunction) KX_SceneActuator::sPySetCamera, METH_O, (PY_METHODCHAR)SetCamera_doc},
268         {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_NOARGS, (PY_METHODCHAR)GetUseRestart_doc},
269         {"getScene",      (PyCFunction) KX_SceneActuator::sPyGetScene, METH_NOARGS, (PY_METHODCHAR)GetScene_doc},
270         {"getCamera",     (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_NOARGS, (PY_METHODCHAR)GetCamera_doc},
271         //<----- Deprecated
272         {NULL,NULL} //Sentinel
273 };
274
275 PyAttributeDef KX_SceneActuator::Attributes[] = {
276         KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName),
277         KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera),
278         KX_PYATTRIBUTE_BOOL_RW("useRestart", KX_SceneActuator, m_restart),
279         KX_PYATTRIBUTE_INT_RW("mode", KX_SCENE_NODEF+1, KX_SCENE_MAX-1, true, KX_SceneActuator, m_mode),
280         { NULL }        //Sentinel
281 };
282
283 PyObject* KX_SceneActuator::py_getattro(PyObject *attr)
284 {
285         py_getattro_up(SCA_IActuator);
286 }
287
288 PyObject* KX_SceneActuator::py_getattro_dict() {
289         py_getattro_dict_up(SCA_IActuator);
290 }
291
292 int KX_SceneActuator::py_setattro(PyObject *attr, PyObject *value)
293 {
294         py_setattro_up(SCA_IActuator);
295 }
296
297 PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
298 {
299         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
300         if (!actuator->m_camera)
301                 Py_RETURN_NONE;
302         
303         return actuator->m_camera->GetProxy();
304 }
305
306 int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
307 {
308         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
309         KX_Camera *camOb;
310         
311         if (!ConvertPythonToCamera(value, &camOb, true, "actu.camera = value: KX_SceneActuator"))
312                 return PY_SET_ATTR_FAIL;
313         
314         if (actuator->m_camera)
315                 actuator->m_camera->UnregisterActuator(actuator);
316         
317         if(camOb==NULL) {
318                 actuator->m_camera= NULL;
319         }
320         else {  
321                 actuator->m_camera = camOb;
322                 actuator->m_camera->RegisterActuator(actuator);
323         }
324         
325         return PY_SET_ATTR_SUCCESS;
326 }
327
328
329 /* 2. setUseRestart--------------------------------------------------------- */
330 const char KX_SceneActuator::SetUseRestart_doc[] = 
331 "setUseRestart(flag)\n"
332 "\t- flag: 0 or 1.\n"
333 "\tSet flag to 1 to restart the scene.\n" ;
334 PyObject* KX_SceneActuator::PySetUseRestart(PyObject* args)
335 {
336         ShowDeprecationWarning("setUseRestart()", "the useRestart property");
337         int boolArg;
338         
339         if (!PyArg_ParseTuple(args, "i:setUseRestart", &boolArg))
340         {
341                 return NULL;
342         }
343         
344         m_restart = boolArg != 0;
345         
346         Py_RETURN_NONE;
347 }
348
349
350
351 /* 3. getUseRestart:                                                         */
352 const char KX_SceneActuator::GetUseRestart_doc[] = 
353 "getUseRestart()\n"
354 "\tReturn whether the scene will be restarted.\n" ;
355 PyObject* KX_SceneActuator::PyGetUseRestart()
356 {
357         ShowDeprecationWarning("getUseRestart()", "the useRestart property");
358         return PyInt_FromLong(!(m_restart == 0));
359 }
360
361
362
363 /* 4. set scene------------------------------------------------------------- */
364 const char KX_SceneActuator::SetScene_doc[] = 
365 "setScene(scene)\n"
366 "\t- scene: string\n"
367 "\tSet the name of scene the actuator will switch to.\n" ;
368 PyObject* KX_SceneActuator::PySetScene(PyObject* args)
369 {
370         ShowDeprecationWarning("setScene()", "the scene property");
371         /* one argument: a scene, ignore the rest */
372         char *scene_name;
373
374         if(!PyArg_ParseTuple(args, "s:setScene", &scene_name))
375         {
376                 return NULL;
377         }
378
379         /* Scene switch is done by name. */
380         m_nextSceneName = scene_name;
381
382         Py_RETURN_NONE;
383 }
384
385
386
387 /* 5. getScene:                                                              */
388 const char KX_SceneActuator::GetScene_doc[] = 
389 "getScene()\n"
390 "\tReturn the name of the scene the actuator wants to switch to.\n" ;
391 PyObject* KX_SceneActuator::PyGetScene()
392 {
393         ShowDeprecationWarning("getScene()", "the scene property");
394         return PyString_FromString(m_nextSceneName);
395 }
396
397
398
399 /* 6. set camera------------------------------------------------------------ */
400 const char KX_SceneActuator::SetCamera_doc[] = 
401 "setCamera(camera)\n"
402 "\t- camera: string\n"
403 "\tSet the camera to switch to.\n" ;
404 PyObject* KX_SceneActuator::PySetCamera(PyObject* value)
405 {
406         ShowDeprecationWarning("setCamera()", "the camera property");
407         KX_Camera *camOb;
408         
409         if (!ConvertPythonToCamera(value, &camOb, true, "actu.setCamera(value): KX_SceneActuator"))
410                 return NULL;
411         
412         if (m_camera)
413                 m_camera->UnregisterActuator(this);
414         
415         if(camOb==NULL) {
416                 m_camera= NULL;
417         }
418         else {  
419                 m_camera = camOb;
420                 m_camera->RegisterActuator(this);
421         }
422         Py_RETURN_NONE;
423 }
424
425
426
427 /* 7. getCamera:                                                             */
428 const char KX_SceneActuator::GetCamera_doc[] = 
429 "getCamera()\n"
430 "\tReturn the name of the camera to switch to.\n" ;
431 PyObject* KX_SceneActuator::PyGetCamera()
432 {
433         ShowDeprecationWarning("getCamera()", "the camera property");
434         if (m_camera) {
435                 return PyString_FromString(m_camera->GetName());
436         }
437         else {
438                 Py_RETURN_NONE;
439         }
440 }
441 /* eof */