Line data Source code
1 : #include <cstdlib>
2 : #include <cstring>
3 :
4 : #include "GameLevel.h"
5 : #include "api.h"
6 : #include "SpriteGameObject.h"
7 :
8 : #include "LuaGL.h"
9 :
10 : //------------------------------------------------------------------------------
11 58 : GameLevel::GameLevel(const unsigned int &lists) {
12 29 : lists_ = lists;
13 29 : isComplete_ = false;
14 :
15 29 : terrain_ = NULL;
16 :
17 29 : player_ = NULL;
18 29 : camera_ = NULL;
19 :
20 29 : musicPath_ = "";
21 :
22 29 : id_ = 0;
23 :
24 29 : numObjects_ = 0;
25 29725 : for (int i = 0; i < MAX_LEVEL_OBJECTS; ++i)
26 29696 : idToObjectMap_[i] = NULL;
27 :
28 : #if EDIT
29 : grid_ = true;
30 : #else
31 29 : grid_ = false;
32 : #endif
33 29 : bboxes_ = false;
34 29 : controlTriangles_ = false;
35 :
36 29 : luaState_ = NULL;
37 :
38 29 : elapsedTime_ = 0.0f;
39 58 : }
40 :
41 : //------------------------------------------------------------------------------
42 58 : GameLevel::~GameLevel() { unloadLevel(); }
43 :
44 : //------------------------------------------------------------------------------
45 0 : void GameLevel::drawLevel() {
46 : // setup cel shading ///////////////////////
47 0 : glCallList(lists_);
48 :
49 : // draw scene and shade /////////////////////
50 0 : drawObjects();
51 :
52 : // setup to draw outline ////////////////////
53 0 : glCallList(lists_ + 1);
54 0 : drawObjectOutlines();
55 :
56 : // reset draw mode to "normal"
57 0 : glCallList(lists_ + 2);
58 :
59 0 : dynamic_cast<Camera*>(camera_)->draw(camera_);
60 :
61 0 : if (grid_) {
62 0 : terrain_->drawGrid();
63 0 : }
64 :
65 0 : if (bboxes_)
66 0 : ((Object*)objects_.head)->showCollisionBox();
67 :
68 0 : if (controlTriangles_)
69 0 : ((Object*)objects_.head)->showControlTriangle();
70 :
71 : //terrain->drawShadows(light);
72 :
73 : // Attempt to execute the script only if the lua state has already been
74 : // initialized with a script
75 0 : if (luaState_ == NULL)
76 0 : return;
77 :
78 : // Find the update function and call it
79 0 : lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_DRAW);
80 :
81 0 : if (lua_isfunction(luaState_, -1)) {
82 : // Push a pointer to the current object for use within the lua function
83 0 : returnObject(luaState_, terrain_);
84 :
85 : // Push the time passed since the last iteration of the game loop
86 0 : lua_pushnumber(luaState_, elapsedTime_);
87 :
88 0 : lua_call(luaState_, 2, 0);
89 0 : }
90 : else {
91 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_DRAW);
92 0 : lua_pop(luaState_, 1);
93 : }
94 0 : }
95 :
96 : //------------------------------------------------------------------------------
97 0 : void GameLevel::postDraw() {
98 : // Attempt to execute the script only if the lua state has already been
99 : // initialized with a script
100 0 : if (luaState_ == NULL)
101 0 : return;
102 :
103 : // Find the update function and call it
104 0 : lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_DRAW_SCREEN);
105 :
106 0 : if (lua_isfunction(luaState_, -1)) {
107 : // Push a pointer to the current object for use within the lua function
108 0 : returnObject(luaState_, terrain_);
109 :
110 : // Push the time passed since the last iteration of the game loop
111 0 : lua_pushnumber(luaState_, elapsedTime_);
112 :
113 0 : lua_call(luaState_, 2, 0);
114 0 : }
115 : else {
116 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_DRAW_SCREEN);
117 0 : lua_pop(luaState_, 1);
118 : }
119 0 : }
120 :
121 : //------------------------------------------------------------------------------
122 0 : void GameLevel::updateLevel() {
123 : // Attempt to execute the script only if the lua state has already been
124 : // initialized with a script
125 0 : if (luaState_ == NULL)
126 0 : return;
127 :
128 : // Find the update function and call it
129 0 : lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_UPDATE);
130 :
131 0 : if (lua_isfunction(luaState_, -1)) {
132 : // Push a pointer to the current object for use within the lua function
133 0 : returnObject(luaState_, terrain_);
134 :
135 : // Push the time passed since the last iteration of the game loop
136 0 : lua_pushnumber(luaState_, elapsedTime_);
137 :
138 0 : lua_call(luaState_, 2, 0);
139 0 : }
140 : else {
141 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_UPDATE);
142 0 : lua_pop(luaState_, 1);
143 : }
144 :
145 0 : updateObjects(&lightDirection_);
146 :
147 0 : displayList_.clearList();
148 0 : dynamic_cast<Camera*>(camera_)->frustum.extractFromProjectionMatrix(dynamic_cast<Camera*>(camera_)->final);
149 0 : quadTree_.buildDisplayList(&displayList_, dynamic_cast<Camera*>(camera_));
150 0 : terrain_->setDisplayList(&displayList_);
151 :
152 0 : dynamic_cast<Camera*>(camera_)->draw(camera_);
153 0 : }
154 :
155 : //------------------------------------------------------------------------------
156 0 : void GameLevel::prepareLevel() { prepareObjects(); }
157 :
158 : //------------------------------------------------------------------------------
159 0 : void GameLevel::animateLevel() { animateObjects(elapsedTime_); }
160 :
161 : //------------------------------------------------------------------------------
162 13 : bool GameLevel::prepLevelLoad(const char* luaCode) {
163 13 : isComplete_ = false;
164 13 : id_ = 0;
165 13 : numObjects_ = 0;
166 :
167 : // If the lua state has not been initialized for the level, attempt to
168 : // initialize it.
169 13 : if (strcmp(luaCode, "") == 0 || luaState_ != NULL)
170 4 : return false;
171 :
172 9 : luaState_ = lua_open();
173 :
174 : // If the lua state still could not be initialized, then exit the game.
175 : // TODO: do something smarter with this for the finished product.
176 9 : if (luaState_ == NULL) {
177 0 : PRINT_ERROR("Could not create Lua state.\n");
178 0 : exit(-1);
179 : }
180 :
181 : // load Lua base libraries
182 9 : luaL_openlibs(luaState_);
183 9 : luaopen_opengl(luaState_);
184 :
185 : // Load our library
186 9 : luaopen_krigApi(luaState_);
187 :
188 9 : return true;
189 13 : }
190 :
191 9 : bool GameLevel::finishLevelLoad() {
192 9 : player_ = new ModelGameObject();
193 9 : terrain_ = new Terrain();
194 :
195 9 : music_.load();
196 :
197 9 : idToObjectMap_[1] = (Object*)player_;
198 9 : idToObjectMap_[2] = (Object*)terrain_;
199 :
200 9 : player_->setGameLevelId(1);
201 9 : terrain_->setGameLevelId(2);
202 :
203 9 : numObjects_ = 3;
204 :
205 : PRINT_DEBUG("Terrain and Player allocated.\n");
206 :
207 9 : objects_.insertFront(terrain_);
208 :
209 : PRINT_DEBUG("Terrain stored in objects list.\n");
210 :
211 9 : if (camera_ == NULL) {
212 0 : PRINT_ERROR("Camera was not allocated in GameLevel class.\n");
213 0 : exit (1);
214 : }
215 :
216 : // Find the update function and call it
217 : PRINT_DEBUG("Calling Lua level script 'on_load' function...\n");
218 :
219 9 : lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_LOAD);
220 :
221 9 : if (lua_isfunction(luaState_, -1)) {
222 : // Push a pointer to the current object for use within the lua function
223 0 : returnObject(luaState_, terrain_);
224 0 : lua_call(luaState_, 1, 0);
225 0 : }
226 : else {
227 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_LOAD);
228 9 : lua_pop(luaState_, 1);
229 : }
230 :
231 : PRINT_DEBUG("Lua level script 'on_load' function complete.\n");
232 :
233 9 : objects_.insertFront(player_);
234 : ////////////////////////////////////////////
235 :
236 : PRINT_DEBUG("Building quad tree...\n");
237 9 : quadTree_.buildTree(terrain_);
238 : //q->traverseTree();
239 :
240 : PRINT_DEBUG("Building display list...\n");
241 :
242 9 : quadTree_.buildDisplayList(&displayList_, dynamic_cast<Camera*>(camera_));
243 : //q->buildLeafList(luaState_);
244 :
245 : PRINT_DEBUG("Traversing list...\n");
246 9 : displayList_.traverseList();
247 :
248 : PRINT_DEBUG("Finished building quad tree.\n");
249 9 : terrain_->setDisplayList(&displayList_);
250 : PRINT_DEBUG("Finished loading level.\n\n");
251 :
252 9 : return (true);
253 0 : }
254 : //------------------------------------------------------------------------------
255 1 : bool GameLevel::loadLevel(const char* file) {
256 1 : if (!prepLevelLoad(file)) {
257 1 : return false;
258 : }
259 :
260 : // load and run the specified lua script
261 : PRINT_DEBUG("Loading Lua level script '%s'...\n", file);
262 0 : luaL_dofile(luaState_, file);
263 : ////////////////////////////////////////////////////////
264 :
265 0 : return finishLevelLoad();
266 1 : }
267 :
268 : //------------------------------------------------------------------------------
269 12 : bool GameLevel::loadLevelFromBuffer(const char* buffer) {
270 12 : if (!prepLevelLoad(buffer)) {
271 3 : return false;
272 : }
273 :
274 : // load the lua script from the specified buffer and run it
275 : PRINT_DEBUG("Loading Lua level script from buffer...\n");
276 9 : luaL_loadbuffer(luaState_, buffer, strlen(buffer), "line") ||
277 9 : lua_pcall(luaState_, 0, 0, 0);
278 : ////////////////////////////////////////////////////////
279 :
280 9 : return finishLevelLoad();
281 12 : }
282 :
283 : //------------------------------------------------------------------------------
284 0 : void GameLevel::drawSky() {
285 : // front sky
286 0 : glBegin(GL_TRIANGLE_STRIP);
287 0 : glColor3fv (bgcolor_[0]);
288 0 : glVertex3f (-1.0f, 1.0f, -1.0f);
289 0 : glColor3fv (bgcolor_[1]);
290 0 : glVertex3f (-1.0f, 0.0f, -1.0f);
291 0 : glColor3fv (bgcolor_[0]);
292 0 : glVertex3f (1.0f, 1.0f, -1.0f);
293 0 : glColor3fv (bgcolor_[1]);
294 0 : glVertex3f (1.0f, 0.0f, -1.0f);
295 0 : glEnd();
296 :
297 0 : glBegin(GL_TRIANGLE_STRIP);
298 0 : glVertex3f (-1.0f, 0.0f, -1.0f);
299 0 : glColor3fv (bgcolor_[2]);
300 0 : glVertex3f (-1.0f, -1.0f, -1.0f);
301 0 : glColor3fv (bgcolor_[1]);
302 0 : glVertex3f (1.0f, 0.0f, -1.0f);
303 0 : glColor3fv (bgcolor_[2]);
304 0 : glVertex3f (1.0f, -1.0f, -1.0f);
305 0 : glEnd();
306 :
307 : // left sky
308 0 : glBegin(GL_TRIANGLE_STRIP);
309 0 : glColor3fv (bgcolor_[0]);
310 0 : glVertex3f (-1.0f, 1.0f, 1.0f);
311 0 : glColor3fv (bgcolor_[1]);
312 0 : glVertex3f (-1.0f, 0.0f, 1.0f);
313 0 : glColor3fv (bgcolor_[0]);
314 0 : glVertex3f (-1.0f, 1.0f, -1.0f);
315 0 : glColor3fv (bgcolor_[1]);
316 0 : glVertex3f (-1.0f, 0.0f, -1.0f);
317 0 : glEnd();
318 :
319 0 : glBegin(GL_TRIANGLE_STRIP);
320 0 : glVertex3f (-1.0f, 0.0f, 1.0f);
321 0 : glColor3fv (bgcolor_[2]);
322 0 : glVertex3f (-1.0f, -1.0f, 1.0f);
323 0 : glColor3fv (bgcolor_[1]);
324 0 : glVertex3f (-1.0f, 0.0f, -1.0f);
325 0 : glColor3fv (bgcolor_[2]);
326 0 : glVertex3f (-1.0f, -1.0f, -1.0f);
327 0 : glEnd();
328 :
329 : // right sky
330 0 : glBegin(GL_TRIANGLE_STRIP);
331 0 : glColor3fv (bgcolor_[0]);
332 0 : glVertex3f (1.0f, 1.0f, -1.0f);
333 0 : glColor3fv (bgcolor_[1]);
334 0 : glVertex3f (1.0f, 0.0f, -1.0f);
335 0 : glColor3fv (bgcolor_[0]);
336 0 : glVertex3f (1.0f, 1.0f, 1.0f);
337 0 : glColor3fv (bgcolor_[1]);
338 0 : glVertex3f (1.0f, 0.0f, 1.0f);
339 0 : glEnd();
340 :
341 0 : glBegin(GL_TRIANGLE_STRIP);
342 0 : glVertex3f (1.0f, 0.0f, -1.0f);
343 0 : glColor3fv (bgcolor_[2]);
344 0 : glVertex3f (1.0f, -1.0f, -1.0f);
345 0 : glColor3fv (bgcolor_[1]);
346 0 : glVertex3f (1.0f, 0.0f, 1.0f);
347 0 : glColor3fv (bgcolor_[2]);
348 0 : glVertex3f (1.0f, -1.0f, 1.0f);
349 0 : glEnd();
350 :
351 : // back sky
352 0 : glBegin(GL_TRIANGLE_STRIP);
353 0 : glColor3fv (bgcolor_[0]);
354 0 : glVertex3f (1.0f, 1.0f, 1.0f);
355 0 : glColor3fv (bgcolor_[1]);
356 0 : glVertex3f (1.0f, 0.0f, 1.0f);
357 0 : glColor3fv (bgcolor_[0]);
358 0 : glVertex3f (-1.0f, 1.0f, 1.0f);
359 0 : glColor3fv (bgcolor_[1]);
360 0 : glVertex3f (-1.0f, 0.0f, 1.0f);
361 0 : glEnd();
362 :
363 0 : glBegin(GL_TRIANGLE_STRIP);
364 0 : glVertex3f (1.0f, 0.0f, 1.0f);
365 0 : glColor3fv (bgcolor_[2]);
366 0 : glVertex3f (1.0f, -1.0f, 1.0f);
367 0 : glColor3fv (bgcolor_[1]);
368 0 : glVertex3f (-1.0f, 0.0f, 1.0f);
369 0 : glColor3fv (bgcolor_[2]);
370 0 : glVertex3f (-1.0f, -1.0f, 1.0f);
371 0 : glEnd();
372 :
373 : // top sky
374 0 : glBegin(GL_TRIANGLE_STRIP);
375 0 : glColor3fv (bgcolor_[0]);
376 0 : glVertex3f (-1.0f, 1.0f, -1.0f);
377 0 : glVertex3f (1.0f, 1.0f, -1.0f);
378 0 : glVertex3f (-1.0f, 1.0f, 1.0f);
379 0 : glVertex3f (1.0f, 1.0f, 1.0f);
380 0 : glEnd();
381 :
382 : // bottom sky
383 0 : glBegin(GL_TRIANGLE_STRIP);
384 0 : glColor3fv (bgcolor_[2]);
385 0 : glVertex3f (1.0f, -1.0f, -1.0f);
386 0 : glVertex3f (-1.0f, -1.0f, -1.0f);
387 0 : glVertex3f (1.0f, -1.0f, 1.0f);
388 0 : glVertex3f (-1.0f, -1.0f, 1.0f);
389 0 : glEnd();
390 0 : }
391 :
392 : //------------------------------------------------------------------------------
393 0 : Object* GameLevel::findEnemyOfType(const int &type) {
394 0 : float closest = 1000, temp;
395 0 : Object* obj = static_cast <Object*>(objects_.head);
396 0 : Object* ret = NULL;
397 :
398 0 : while (obj->next != 0) {
399 0 : obj = (Object*)obj->next;
400 0 : if (obj->getTypeId() == type && obj->getInView()) {
401 0 : temp = findDistance((Object*)player_, obj);
402 0 : if (temp < closest) {
403 0 : ret = obj;
404 0 : closest = temp;
405 0 : }
406 0 : }
407 : }
408 :
409 0 : return ret;
410 : }
411 :
412 : //------------------------------------------------------------------------------
413 0 : float GameLevel::findDistance (Object* obj1, Object* obj2) {
414 0 : Vector position1 = obj1->getPosition();
415 0 : Vector position2 = obj2->getPosition();
416 :
417 0 : return sqrtf(
418 0 : (position1.x - position2.x) * (position1.x - position2.x) +
419 0 : (position1.y - position2.y) * (position1.y - position2.y) +
420 0 : (position1.z - position2.z) * (position1.z - position2.z)
421 : );
422 : }
423 :
424 : //------------------------------------------------------------------------------
425 2 : bool GameLevel::checkComplete()
426 2 : { return isComplete_; }
427 :
428 : //------------------------------------------------------------------------------
429 29 : void GameLevel::unloadLevel() {
430 : // Attempt to execute the on_unload function only if the lua state has
431 : // already been initialized with a script
432 29 : if (luaState_ != NULL) {
433 : // Find the update function and call it
434 9 : lua_getglobal(luaState_, SCRIPT_CALLBACK_ON_UNLOAD);
435 :
436 9 : if (lua_isfunction(luaState_, -1)) {
437 : // Push a pointer to the current object for use within the lua function
438 0 : returnObject(luaState_, terrain_);
439 :
440 0 : lua_call(luaState_, 1, 0);
441 0 : }
442 : else {
443 : PRINT_DEBUG_LVL(4, "'%s' function not defined.\n", SCRIPT_CALLBACK_ON_UNLOAD);
444 9 : lua_pop(luaState_, 1);
445 : }
446 9 : }
447 :
448 : PRINT_DEBUG("Removing objects...\n");
449 29 : removeObjects();
450 : PRINT_DEBUG("done.\n");
451 :
452 29 : if (luaState_ != NULL)
453 9 : lua_close(luaState_);
454 :
455 29 : terrain_ = NULL;
456 29 : player_ = NULL;
457 29 : camera_ = NULL;
458 29 : luaState_ = NULL;
459 :
460 29 : music_.unload();
461 29 : }
462 :
463 : //------------------------------------------------------------------------------
464 29 : void GameLevel::removeObjects() {
465 29 : ObjectNode *objectNode = objects_.head;
466 47 : while (objectNode != NULL) {
467 18 : objects_.remove(objectNode);
468 18 : delete objectNode;
469 18 : objectNode = objects_.head;
470 : }
471 29 : }
472 :
473 : //------------------------------------------------------------------------------
474 0 : void GameLevel::updateTerrain(int &x, int &z, float &height, int &type, float &red, float &green, float &blue) {
475 0 : terrain_->setVertexHeight(x, z,height);
476 0 : terrain_->setVertexColor(x, z, Vector(red, green, blue));
477 0 : terrain_->setVertexType(x, z, type);
478 :
479 : // TODO: Because calculating normals is an expensive operation, this call
480 : // should be optimized to only calculate the normal for the specified vertex
481 : // when its height has changed.
482 0 : terrain_->calcViewableTerrainNorm();
483 0 : }
484 :
485 : //------------------------------------------------------------------------------
486 0 : void GameLevel::updateColor(int &x, int &z, float &red, float &green, float &blue) {
487 0 : terrain_->setVertexColor(x, z, Vector(red, green, blue));
488 :
489 : // TODO: Because calculating normals is an expensive operation, this call
490 : // should be optimized to only calculate the normal for the specified vertex
491 : // when its height has changed.
492 : // TODO: This command has been commented out. Since we're only changing color
493 : // here, investigate if this call is even necessary.
494 : //terrain_->calcTerrainNorm(&lightDirection_);
495 0 : }
496 :
497 : //------------------------------------------------------------------------------
498 0 : void GameLevel::getTerrainInfo(int &x, int &z, float &height, int &type, float &red, float &green, float &blue) {
499 0 : height = terrain_->getVertexHeight(x, z);
500 0 : type = terrain_->getVertexType(x, z);
501 :
502 0 : Vector color = terrain_->getVertexColor(x, z);
503 :
504 0 : red = color.x;
505 0 : green = color.y;
506 0 : blue = color.z;
507 0 : }
508 :
509 : //------------------------------------------------------------------------------
510 0 : void GameLevel::saveTerrain(const char* filePath) {
511 0 : terrain_->save(filePath, &lightDirection_);
512 0 : }
513 :
514 : //------------------------------------------------------------------------------
515 0 : void GameLevel::toggleGrid() { grid_ = !grid_; }
516 :
517 : //------------------------------------------------------------------------------
518 0 : void GameLevel::toggleBoundingBoxes() { bboxes_ = !bboxes_; }
519 :
520 : //------------------------------------------------------------------------------
521 0 : void GameLevel::toggleControlTriangles() { controlTriangles_ = !controlTriangles_; }
522 :
523 : //------------------------------------------------------------------------------
524 0 : void GameLevel::setSkyBox(float bgcolor[][3], const int &x, const int &y) {
525 0 : for (int i = 0; i < y; ++i) {
526 0 : for (int j = 0; j < x; ++j) {
527 0 : bgcolor_[i][j] = bgcolor[i][j];
528 0 : }
529 0 : }
530 0 : }
531 :
532 : //------------------------------------------------------------------------------
533 0 : void GameLevel::drawObjects() {
534 0 : for (Object *object = static_cast<Object*>(objects_.head);
535 0 : object != NULL;
536 0 : object = static_cast<Object*>(object->next)) {
537 0 : if (object->isDrawable()) {
538 0 : object->draw(dynamic_cast<Camera*>(camera_));
539 0 : }
540 0 : }
541 0 : }
542 :
543 : //------------------------------------------------------------------------------
544 0 : void GameLevel::drawObjectOutlines() {
545 0 : for (Object *object = static_cast<Object*>(objects_.head);
546 0 : object != NULL;
547 0 : object = static_cast<Object*>(object->next)) {
548 0 : if (object->isDrawable()) {
549 0 : object->drawOutline(dynamic_cast<Camera*>(camera_));
550 0 : }
551 0 : }
552 0 : }
553 :
554 : //------------------------------------------------------------------------------
555 0 : void GameLevel::drawShadows(Vector* l) {
556 0 : for (Object *object = static_cast<Object*>(objects_.head);
557 0 : object != NULL;
558 0 : object = static_cast<Object*>(object->next)) {
559 0 : if (object->isDrawable()) {
560 0 : object->drawShadow(l);
561 0 : }
562 0 : }
563 0 : }
564 :
565 : //------------------------------------------------------------------------------
566 0 : void GameLevel::updateObjects(Vector* light) {
567 0 : for (Object *object = static_cast<Object*>(objects_.head); object != NULL;) {
568 0 : if (object->getActive() && object->getState() != DEAD)
569 0 : object->update(light);
570 :
571 0 : Object* tempObject = NULL;
572 :
573 0 : if (object->next != NULL)
574 0 : tempObject = static_cast<Object*>(object->next);
575 :
576 0 : if (object->getState() == DEAD) {
577 0 : objects_.remove(object);
578 0 : freeObjects_[object->getScriptName()].insertFront(object);
579 :
580 : PRINT_DEBUG_LVL(
581 : 3,
582 : "Object removed: script='%s'. Added to free objects map (size=%d).\n",
583 : object->getScriptName().c_str(),
584 : freeObjects_[object->getScriptName()].size
585 : );
586 : //delete object;
587 0 : }
588 :
589 0 : object = tempObject;
590 : }
591 0 : }
592 :
593 : //------------------------------------------------------------------------------
594 0 : void GameLevel::prepareObjects() {
595 0 : for (Object *object = static_cast<Object*>(objects_.head);
596 0 : object != NULL;
597 0 : object = static_cast<Object*>(object->next)) {
598 :
599 0 : object->processCollisions(static_cast<Object*>(objects_.head));
600 0 : }
601 0 : }
602 :
603 : //------------------------------------------------------------------------------
604 0 : void GameLevel::animateObjects(const float &timeElapsed) {
605 0 : for (Object *object = static_cast<Object*>(objects_.head);
606 0 : object != NULL;
607 0 : object = static_cast<Object*>(object->next)) {
608 :
609 0 : if (object->getActive())
610 0 : object->animate(timeElapsed, dynamic_cast<Camera*>(camera_));
611 0 : }
612 0 : }
613 :
614 : //------------------------------------------------------------------------------
615 0 : Object* GameLevel::addObject(const std::string &script, lua_State* luaState, const unsigned int &type) {
616 0 : Object *temp = (Object*)freeObjects_[script].head;
617 :
618 0 : if (temp != NULL) {
619 0 : switch (type) {
620 : case TYPE_GAME_OBJECT:
621 0 : temp = static_cast<ModelGameObject*>(temp);
622 0 : break;
623 : case TYPE_GAME_TEXT:
624 0 : temp = static_cast<TextGameObject*>(temp);
625 0 : break;
626 : case TYPE_GAME_SPRITE:
627 0 : temp = static_cast<SpriteGameObject*>(temp);
628 0 : break;
629 : default:
630 0 : PRINT_ERROR("Could not add new object of type '%u'.\n", type);
631 0 : return NULL;
632 : }
633 :
634 0 : temp->initSettings();
635 0 : freeObjects_[script].remove(temp);
636 : PRINT_DEBUG_LVL(
637 : 3,
638 : "Object removed: script='%s'. Added to free objects map (size=%d).\n",
639 : script.c_str(),
640 : freeObjects_[script].size
641 : );
642 0 : }
643 : else {
644 0 : if (numObjects_ < MAX_LEVEL_OBJECTS) {
645 0 : switch (type) {
646 : case TYPE_GAME_OBJECT:
647 0 : temp = new ModelGameObject();
648 0 : break;
649 : case TYPE_GAME_TEXT:
650 0 : temp = new TextGameObject();
651 0 : break;
652 : case TYPE_GAME_SPRITE:
653 0 : temp = new SpriteGameObject();
654 0 : break;
655 : default:
656 0 : PRINT_ERROR("Could not add new object of type '%u'.\n", type);
657 0 : return NULL;
658 : }
659 0 : temp->setScript(script);
660 0 : temp->setGameLevelId(numObjects_);
661 0 : idToObjectMap_[numObjects_] = temp;
662 0 : numObjects_++;
663 :
664 : PRINT_DEBUG_LVL(3, "Allocated a new object of type '%s' (num objects = %u).\n", script.c_str(), numObjects_);
665 0 : }
666 : else {
667 0 : PRINT_ERROR("Could not allocate a new object of type '%s'.\n", script.c_str());
668 0 : return NULL;
669 : }
670 : }
671 :
672 0 : objects_.insertFront(temp);
673 :
674 0 : temp->loadScript(script, luaState);
675 :
676 0 : return temp;
677 0 : }
|