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