Undo revision 23130 which was a merge with 2.5, a messy one because I did something...
[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         PyVarObject_HEAD_INIT(NULL, 0)
226         "KX_SceneActuator",
227         sizeof(PyObjectPlus_Proxy),
228         0,
229         py_base_dealloc,
230         0,
231         0,
232         0,
233         0,
234         py_base_repr,
235         0,0,0,0,0,0,0,0,0,
236         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
237         0,0,0,0,0,0,0,
238         Methods,
239         0,
240         0,
241         &SCA_IActuator::Type,
242         0,0,0,0,0,0,
243         py_base_new
244 };
245
246 PyMethodDef KX_SceneActuator::Methods[] =
247 {
248         //Deprecated functions ------>
249         {"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, (const char *)SetUseRestart_doc},
250         {"setScene",      (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, (const char *)SetScene_doc},
251         {"setCamera",     (PyCFunction) KX_SceneActuator::sPySetCamera, METH_O, (const char *)SetCamera_doc},
252         {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_NOARGS, (const char *)GetUseRestart_doc},
253         {"getScene",      (PyCFunction) KX_SceneActuator::sPyGetScene, METH_NOARGS, (const char *)GetScene_doc},
254         {"getCamera",     (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_NOARGS, (const char *)GetCamera_doc},
255         //<----- Deprecated
256         {NULL,NULL} //Sentinel
257 };
258
259 PyAttributeDef KX_SceneActuator::Attributes[] = {
260         KX_PYATTRIBUTE_STRING_RW("scene",0,32,true,KX_SceneActuator,m_nextSceneName),
261         KX_PYATTRIBUTE_RW_FUNCTION("camera",KX_SceneActuator,pyattr_get_camera,pyattr_set_camera),
262         KX_PYATTRIBUTE_BOOL_RW("useRestart", KX_SceneActuator, m_restart),
263         KX_PYATTRIBUTE_INT_RW("mode", KX_SCENE_NODEF+1, KX_SCENE_MAX-1, true, KX_SceneActuator, m_mode),
264         { NULL }        //Sentinel
265 };
266
267 PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
268 {
269         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
270         if (!actuator->m_camera)
271                 Py_RETURN_NONE;
272         
273         return actuator->m_camera->GetProxy();
274 }
275
276 int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
277 {
278         KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self);
279         KX_Camera *camOb;
280         
281         if (!ConvertPythonToCamera(value, &camOb, true, "actu.camera = value: KX_SceneActuator"))
282                 return PY_SET_ATTR_FAIL;
283         
284         if (actuator->m_camera)
285                 actuator->m_camera->UnregisterActuator(actuator);
286         
287         if(camOb==NULL) {
288                 actuator->m_camera= NULL;
289         }
290         else {  
291                 actuator->m_camera = camOb;
292                 actuator->m_camera->RegisterActuator(actuator);
293         }
294         
295         return PY_SET_ATTR_SUCCESS;
296 }
297
298
299 /* 2. setUseRestart--------------------------------------------------------- */
300 const char KX_SceneActuator::SetUseRestart_doc[] = 
301 "setUseRestart(flag)\n"
302 "\t- flag: 0 or 1.\n"
303 "\tSet flag to 1 to restart the scene.\n" ;
304 PyObject* KX_SceneActuator::PySetUseRestart(PyObject* args)
305 {
306         ShowDeprecationWarning("setUseRestart()", "the useRestart property");
307         int boolArg;
308         
309         if (!PyArg_ParseTuple(args, "i:setUseRestart", &boolArg))
310         {
311                 return NULL;
312         }
313         
314         m_restart = boolArg != 0;
315         
316         Py_RETURN_NONE;
317 }
318
319
320
321 /* 3. getUseRestart:                                                         */
322 const char KX_SceneActuator::GetUseRestart_doc[] = 
323 "getUseRestart()\n"
324 "\tReturn whether the scene will be restarted.\n" ;
325 PyObject* KX_SceneActuator::PyGetUseRestart()
326 {
327         ShowDeprecationWarning("getUseRestart()", "the useRestart property");
328         return PyLong_FromSsize_t(!(m_restart == 0));
329 }
330
331
332
333 /* 4. set scene------------------------------------------------------------- */
334 const char KX_SceneActuator::SetScene_doc[] = 
335 "setScene(scene)\n"
336 "\t- scene: string\n"
337 "\tSet the name of scene the actuator will switch to.\n" ;
338 PyObject* KX_SceneActuator::PySetScene(PyObject* args)
339 {
340         ShowDeprecationWarning("setScene()", "the scene property");
341         /* one argument: a scene, ignore the rest */
342         char *scene_name;
343
344         if(!PyArg_ParseTuple(args, "s:setScene", &scene_name))
345         {
346                 return NULL;
347         }
348
349         /* Scene switch is done by name. */
350         m_nextSceneName = scene_name;
351
352         Py_RETURN_NONE;
353 }
354
355
356
357 /* 5. getScene:                                                              */
358 const char KX_SceneActuator::GetScene_doc[] = 
359 "getScene()\n"
360 "\tReturn the name of the scene the actuator wants to switch to.\n" ;
361 PyObject* KX_SceneActuator::PyGetScene()
362 {
363         ShowDeprecationWarning("getScene()", "the scene property");
364         return PyUnicode_FromString(m_nextSceneName);
365 }
366
367
368
369 /* 6. set camera------------------------------------------------------------ */
370 const char KX_SceneActuator::SetCamera_doc[] = 
371 "setCamera(camera)\n"
372 "\t- camera: string\n"
373 "\tSet the camera to switch to.\n" ;
374 PyObject* KX_SceneActuator::PySetCamera(PyObject* value)
375 {
376         ShowDeprecationWarning("setCamera()", "the camera property");
377         KX_Camera *camOb;
378         
379         if (!ConvertPythonToCamera(value, &camOb, true, "actu.setCamera(value): KX_SceneActuator"))
380                 return NULL;
381         
382         if (m_camera)
383                 m_camera->UnregisterActuator(this);
384         
385         if(camOb==NULL) {
386                 m_camera= NULL;
387         }
388         else {  
389                 m_camera = camOb;
390                 m_camera->RegisterActuator(this);
391         }
392         Py_RETURN_NONE;
393 }
394
395
396
397 /* 7. getCamera:                                                             */
398 const char KX_SceneActuator::GetCamera_doc[] = 
399 "getCamera()\n"
400 "\tReturn the name of the camera to switch to.\n" ;
401 PyObject* KX_SceneActuator::PyGetCamera()
402 {
403         ShowDeprecationWarning("getCamera()", "the camera property");
404         if (m_camera) {
405                 return PyUnicode_FromString(m_camera->GetName());
406         }
407         else {
408                 Py_RETURN_NONE;
409         }
410 }
411 /* eof */