home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / XenonSource.exe / xenon / source / scene.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-13  |  11.1 KB  |  456 lines

  1. //-------------------------------------------------------------
  2. //
  3. // Class:    CScene
  4. //
  5. // Author:    John M Phillips
  6. //
  7. // Started:    06/05/00
  8. //
  9. // Base:    None
  10. //
  11. // Derived:    None
  12. //
  13. //-------------------------------------------------------------
  14.  
  15. #include "game.h"
  16.  
  17. //-------------------------------------------------------------
  18.  
  19. CScene::CScene()
  20. {
  21.     m_frame_count = 0;
  22.     m_map = 0;
  23.     m_checkpoint_active = false;
  24.     m_is_warping = false;
  25. }
  26.  
  27. //-------------------------------------------------------------
  28.  
  29. CScene::~CScene()
  30. {
  31. }
  32.  
  33. //-------------------------------------------------------------
  34.  
  35. gsCTiledImage *CScene::getImage(const char *filename)
  36. {
  37.     if (filename == 0)
  38.         return 0;
  39.  
  40.     for (int i = 0; i < m_image_list.getSize(); i++) {
  41.         if (strcmp(m_image_list[i]->m_filename,filename) == 0)
  42.             return &m_image_list[i]->m_image;
  43.         }
  44.  
  45.     ImageEntry *image_entry = new ImageEntry;
  46.  
  47.     strcpy(image_entry->m_filename,filename);
  48.  
  49. //    gsCFile::setDirectory(DIRECTORY_GRAPHICS24);
  50.  
  51.     if (image_entry->m_image.load(filename)) {
  52.         m_image_list.addItem(image_entry);
  53.         return &image_entry->m_image;
  54.         }
  55.     else {
  56.         delete image_entry;
  57.         return 0;
  58.         }
  59. }
  60.  
  61. //-------------------------------------------------------------
  62.  
  63. bool CScene::loadImages()
  64. {
  65.     for (int i = 0; i < INFO_TOTAL; i++) {
  66.         gsCTiledImage *image = getImage(ActorInfoList[i].m_filename);
  67.  
  68.         if (image) {
  69.             image->setTileSize(gsCPoint(ActorInfoList[i].m_tile_width,
  70.                                         ActorInfoList[i].m_tile_height));
  71.  
  72.             image->enableColourKey(gsCColour(gsMAGENTA));
  73.             }
  74.         }
  75.  
  76.     return true;
  77. }
  78.  
  79. //-------------------------------------------------------------
  80.  
  81. void CScene::addToCollisionList(CActor *actor,const gsCRect& rect)
  82. {
  83.     switch (actor->getActorInfo().m_type) {
  84.         case ACTOR_TYPE_SHIP:
  85.             if (m_ship_is_cloaked)
  86.                 break;
  87.             m_collision_list.addObject((void *) actor,
  88.                                       rect,
  89.                                       (1 << ACTOR_TYPE_SHIP),
  90.                                       (1 << ACTOR_TYPE_PICKUP) | (1 << ACTOR_TYPE_ALIEN));
  91.             break;
  92.         case ACTOR_TYPE_UPGRADE:
  93.             if (m_ship_is_cloaked)
  94.                 break;
  95.             m_collision_list.addObject((void *) actor,
  96.                                       rect,
  97.                                       (1 << ACTOR_TYPE_UPGRADE),
  98.                                       (1 << ACTOR_TYPE_PICKUP) | (1 << ACTOR_TYPE_ALIEN));
  99.             break;
  100.         case ACTOR_TYPE_BULLET:
  101.             m_collision_list.addObject((void *) actor,
  102.                                       rect,
  103.                                       (1 << ACTOR_TYPE_BULLET),
  104.                                       (1 << ACTOR_TYPE_ALIEN) | (1 << ACTOR_TYPE_ALIENBULLET));
  105.             break;
  106.         case ACTOR_TYPE_ALIENBULLET:
  107.             m_collision_list.addObject((void *) actor,
  108.                                       rect,
  109.                                       (1 << ACTOR_TYPE_ALIENBULLET),
  110.                                       (1 << ACTOR_TYPE_SHIP));
  111.             break;
  112.         case ACTOR_TYPE_ALIEN:
  113.             m_collision_list.addObject((void *) actor,
  114.                                       rect,
  115.                                       (1 << ACTOR_TYPE_ALIEN),
  116.                                       0);
  117.             break;
  118.         case ACTOR_TYPE_PICKUP:
  119.             m_collision_list.addObject((void *) actor,
  120.                                       rect,
  121.                                       (1 << ACTOR_TYPE_PICKUP),
  122.                                       0);
  123.             break;
  124.         case ACTOR_TYPE_WEAPON:
  125.         case ACTOR_TYPE_ENGINE:
  126.         case ACTOR_TYPE_LABEL:
  127.         case ACTOR_TYPE_EFFECT:
  128.             // no collision detection
  129.             break;
  130.         }
  131. }
  132.  
  133. //-------------------------------------------------------------
  134.  
  135. void CScene::updateActorsOfType(ActorType type,Controls *controls)
  136. {
  137.     for (int j = 0; j < m_actor_list.getSize(); j++) {
  138.         CActor *obj = m_actor_list[j];
  139.         if (obj->isActive() &&
  140.             obj->getActorInfo().m_type == type)
  141.             obj->update(controls);
  142.         }
  143. }
  144.  
  145. //-------------------------------------------------------------
  146.  
  147. void CScene::updateAllActors(Controls *controls)
  148. {
  149.     updateActorsOfType(ACTOR_TYPE_SHIP,controls);
  150.     updateActorsOfType(ACTOR_TYPE_UPGRADE,controls);
  151.     updateActorsOfType(ACTOR_TYPE_ALIEN,controls);
  152.     updateActorsOfType(ACTOR_TYPE_WEAPON,controls);
  153.     updateActorsOfType(ACTOR_TYPE_ENGINE,controls);
  154.     updateActorsOfType(ACTOR_TYPE_ALIENBULLET,controls);
  155.     updateActorsOfType(ACTOR_TYPE_BULLET,controls);
  156.     updateActorsOfType(ACTOR_TYPE_PICKUP,controls);
  157.     updateActorsOfType(ACTOR_TYPE_LABEL,controls);
  158.     updateActorsOfType(ACTOR_TYPE_EFFECT,controls);
  159. }
  160.  
  161. //-------------------------------------------------------------
  162.  
  163. void CScene::drawActorsOfType(ActorType type,int total)
  164. {
  165.     for (int j = 0; j < total; j++) {
  166.         CActor *actor = m_actor_list[j];
  167.         if (actor->isActive() &&
  168.             actor->getActorInfo().m_type == type)
  169.             actor->draw();
  170.         }
  171. }
  172.  
  173. //-------------------------------------------------------------
  174.  
  175. void CScene::actorCollisionCallback(void *object1,void *object2)
  176. {
  177.     gsASSERT(object1);
  178.     gsASSERT(object2);
  179.     
  180.     CActor *actor1 = (CActor *) object1;
  181.     CActor *actor2 = (CActor *) object2;
  182.  
  183.     if (!actor1->isActive() ||
  184.         !actor2->isActive())
  185.         return;
  186.  
  187.     actor1->onCollisionWithActor(actor2);
  188. }
  189.  
  190. //-------------------------------------------------------------
  191. // Draw all active game actors - prioritized
  192.  
  193. void CScene::drawAllActors(gsCMap *map)
  194. {
  195.     m_frame_count++;
  196.     
  197.     m_collision_list.clear();
  198.  
  199.     int total = m_actor_list.getSize();
  200.  
  201.     CShip *ship = findShip();
  202.  
  203.     m_ship_is_cloaked = ship && ship->isCloaked();
  204.  
  205.     if (ship && ship->getDiveLevel() != 0) {
  206.         drawActorsOfType(ACTOR_TYPE_ENGINE,total);
  207.         drawActorsOfType(ACTOR_TYPE_SHIP,total);
  208.         drawActorsOfType(ACTOR_TYPE_UPGRADE,total);
  209.  
  210.         map->draw();
  211.  
  212.         drawActorsOfType(ACTOR_TYPE_EFFECT,total);
  213.         drawActorsOfType(ACTOR_TYPE_PICKUP,total);
  214.         drawActorsOfType(ACTOR_TYPE_ALIEN,total);
  215.         drawActorsOfType(ACTOR_TYPE_ALIENBULLET,total);
  216.         drawActorsOfType(ACTOR_TYPE_BULLET,total);
  217.         drawActorsOfType(ACTOR_TYPE_WEAPON,total);
  218.         drawActorsOfType(ACTOR_TYPE_LABEL,total);
  219.         }
  220.     else {
  221.  
  222.         map->draw();
  223.  
  224.         drawActorsOfType(ACTOR_TYPE_EFFECT,total);
  225.         drawActorsOfType(ACTOR_TYPE_PICKUP,total);
  226.         drawActorsOfType(ACTOR_TYPE_ALIEN,total);
  227.         drawActorsOfType(ACTOR_TYPE_ALIENBULLET,total);
  228.         drawActorsOfType(ACTOR_TYPE_BULLET,total);
  229.         drawActorsOfType(ACTOR_TYPE_ENGINE,total);
  230.         drawActorsOfType(ACTOR_TYPE_SHIP,total);
  231.         drawActorsOfType(ACTOR_TYPE_UPGRADE,total);
  232.         drawActorsOfType(ACTOR_TYPE_WEAPON,total);
  233.         drawActorsOfType(ACTOR_TYPE_LABEL,total);
  234.         }
  235. }
  236.  
  237. //-------------------------------------------------------------
  238.  
  239. void CScene::checkActorCollisions()
  240. {
  241.     m_collision_list.scan(actorCollisionCallback);
  242.  
  243.     for (int i = 0; i < m_actor_list.getSize(); i++) {
  244.         if (m_actor_list[i]->isActive())
  245.             m_actor_list[i]->postProcessCollision();
  246.         }
  247. }
  248.  
  249. //-------------------------------------------------------------
  250.  
  251. void CScene::checkMapCollisions(gsCMap *map)
  252. {
  253.     // check for collisions between actors and map
  254.  
  255.     for (int i = 0; i < m_actor_list.getSize(); i++) {
  256.         CActor *actor = m_actor_list[i];
  257.         if (actor->isActive()) {
  258.             switch (actor->getActorInfo().m_type) {
  259.                 case ACTOR_TYPE_SHIP:
  260.                 case ACTOR_TYPE_UPGRADE:
  261.                     if (m_ship_is_cloaked)
  262.                         break;
  263.                     {
  264.                         gsCRect rect = actor->getCollisionRect();
  265.                         rect.move(-map->getPosition());
  266.                         int hits = map->hitBy(rect,COLLIDE_WITH_SHIP);
  267.                         if (hits)
  268.                             actor->onCollisionWithMap(map,hits);
  269.                     }
  270.                     break;
  271.  
  272.                 case ACTOR_TYPE_BULLET:
  273.                 case ACTOR_TYPE_ALIENBULLET:
  274.                     {
  275.                         gsCRect rect = actor->getCollisionRect();
  276.                         rect.move(-map->getPosition());
  277.                         int hits = map->hitBy(rect,COLLIDE_WITH_BULLETS);
  278.                         if (hits)
  279.                             actor->onCollisionWithMap(map,hits);
  280.                     }
  281.                     break;
  282.                 }
  283.             }
  284.         }
  285. }
  286.  
  287. //-------------------------------------------------------------
  288.  
  289. void CScene::removeDeadActors()
  290. {
  291.     for (int i = m_actor_list.getSize() - 1; i >= 0; i--) {
  292.         if (!m_actor_list[i]->isActive()) {
  293.             delete m_actor_list[i];
  294.             m_actor_list.removeIndex(i);
  295.             }
  296.         }
  297. }
  298.  
  299. //-------------------------------------------------------------
  300.  
  301. void CScene::killAllActors()
  302. {
  303.     int i;
  304.     
  305.     for (i = 0; i < m_actor_list.getSize(); i++)
  306.         m_actor_list[i]->kill();
  307.  
  308.     for (i = 0; i < m_actor_list.getSize(); i++)
  309.         delete m_actor_list[i];
  310.  
  311.     m_actor_list.clear();
  312. }
  313.  
  314. //-------------------------------------------------------------
  315.  
  316. void CScene::destroyAll()
  317. {
  318.     int i;
  319.  
  320.     for (i = 0; i < m_actor_list.getSize(); i++)
  321.         delete m_actor_list[i];
  322.  
  323.     m_actor_list.clear();
  324.  
  325.     for (i = 0; i < m_image_list.getSize(); i++) {
  326.         m_image_list[i]->m_image.destroy();
  327.         delete m_image_list[i];
  328.         }
  329.     
  330.     m_image_list.clear();
  331. }
  332.  
  333. //-------------------------------------------------------------
  334.  
  335. CShip *CScene::findShip()
  336. {
  337.     for (int i = 0; i < m_actor_list.getSize(); i++) {
  338.         if (m_actor_list[i]->getActorInfo().m_type == ACTOR_TYPE_SHIP)
  339.             return (CShip *) m_actor_list[i];
  340.         }
  341.  
  342.     return 0;
  343. }
  344.  
  345. //-------------------------------------------------------------
  346.  
  347. void CScene::createLabel(const gsCVector& position,const char *text)
  348. {
  349.     CLabel *label = new CLabel;
  350.     addActor(label);
  351.  
  352.     label->activate();
  353.     label->setText(text);
  354.     label->setPosition(position);
  355.     label->setVelocity(gsCVector(0.f,-1.25f));
  356.     label->setTime(0.5);
  357. }
  358.  
  359. //-------------------------------------------------------------
  360.  
  361. void CScene::createLabel(const gsCVector& position,int number)
  362. {
  363.     CLabel *label = new CLabel;
  364.     addActor(label);
  365.  
  366.     label->activate();
  367.     label->setText("%i",number);
  368.     label->setPosition(position);
  369.     label->setVelocity(gsCVector(0.f,-1.25f));
  370.     label->setTime(0.5);
  371. }
  372.  
  373. //-------------------------------------------------------------
  374.  
  375. void CScene::createMapExplosion(gsCMap *map,const gsCPoint& position)
  376. {
  377.     CSmallExplosion *exp = new CSmallExplosion();
  378.     addActor(exp);
  379.  
  380.     gsCPoint tile_size = map->getImage()->getTileSize();
  381.     gsCPoint tile_centre = tile_size / gsCPoint(2,2);
  382.  
  383.     gsCPoint pos = position * tile_size + tile_centre;
  384.     exp->setPosition(gsCVector((float) pos.getX(),(float) pos.getY()));
  385.     exp->activate();
  386. }
  387.  
  388. //-------------------------------------------------------------
  389.  
  390. CActor *CScene::getActor(int index)
  391. {
  392.     return m_actor_list[index];
  393. }
  394.  
  395. //-------------------------------------------------------------
  396.  
  397. CActor *CScene::findNearestActor(ActorType type,const gsCVector& position,int dir)
  398. {
  399.     CActor *nearest_actor = 0;
  400.     float nearest_distance = 99999.f;
  401.  
  402.     for (int i = 0; i < m_actor_list.getSize(); i++) {
  403.         CActor *actor = m_actor_list[i];
  404.         if (actor->isActive() &&
  405.             actor->getActorInfo().m_type == type) {
  406.             if (dir != 0) {
  407.                 float sy = position.getY();
  408.                 float ay = actor->getPosition().getY();
  409.                 if (dir < 0 && sy < ay)
  410.                     continue;
  411.                 if (dir > 0 && sy > ay)
  412.                     continue;
  413.                 }
  414.             float d = (actor->getPosition() - position).length();
  415.             if (nearest_actor == 0 ||
  416.                 d < nearest_distance) {
  417.                 nearest_actor = actor;
  418.                 nearest_distance = d;
  419.                 }
  420.             }
  421.         }
  422.  
  423.     return nearest_actor;
  424. }
  425.  
  426. //-------------------------------------------------------------
  427.  
  428. void CScene::clearCheckpoint()
  429. {
  430.     m_checkpoint_active = false;
  431. }
  432.  
  433. //-------------------------------------------------------------
  434.  
  435. void CScene::setNextCheckpoint(const gsCVector& position)
  436. {
  437.     m_checkpoint = position;
  438.     m_checkpoint_active = true;
  439. }
  440.  
  441. //-------------------------------------------------------------
  442.  
  443. bool CScene::hasCheckpoint()
  444. {
  445.     return m_checkpoint_active;
  446. }
  447.  
  448. //-------------------------------------------------------------
  449.  
  450. gsCVector CScene::getCheckpoint()
  451. {
  452.     return m_checkpoint;
  453. }
  454.  
  455. //-------------------------------------------------------------
  456.