SHARE
TWEET

update.cpp

Archon Dec 7th, 2010 119 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // (C) 2010 Tim Gurto
  2.  
  3. #include <cassert>
  4. #include <sstream>
  5. #include <ctime>
  6. #include "update.h"
  7. #include "game.h"
  8. #include "util.h"
  9. #include "misc.h"
  10. #include "UIBar.h"
  11. #include "Building.h"
  12. #include "Unit.h"
  13. #include "Debug.h"
  14. #include "MessageBox.h"
  15. #include "Entity.h"
  16. #include "Screen.h"
  17.  
  18. extern Debug debug;
  19.  
  20. void updateState(double delta, const CoreData &core, GameData &game,
  21.                  UIBars_t &bars, MessageBox &contextHelp,
  22.                  MessageBox &resourcesBox, MessageBox &fpsDisplay){
  23.  
  24.    //Interface stuff
  25.    handleEvents(core, game, bars, contextHelp, fpsDisplay);
  26.    scrollMap(game, delta);
  27.  
  28.    if (game.selectionChanged)
  29.       setModeFromSelection(game, bars);
  30.  
  31.    //Actual updates
  32.    if (!game.paused && delta > 0){
  33.  
  34.       //Entities
  35.       ITERATE(entities_t::iterator, game.entities, it){
  36.          (*it)->tick(delta);
  37.  
  38.          //re-sort entity if it has moved vertically
  39.          VerticalMovement v = (*it)->getVerticalMovement();
  40.          if (v != VM_NONE)
  41.             reSort(game.entities, it, v);
  42.       }
  43.       Entity::emptyTrash();
  44.  
  45.       //tick non-human, non-nature Players
  46.       for (typeNum_t i = 0; i != game.players.size(); ++i)
  47.          if (i != HUMAN_PLAYER &&
  48.              i != NATURE_PLAYER)
  49.             game.players[i].tick();
  50.  
  51.       //UI bars, if necessary
  52.       if (game.recalcBars){
  53.          game.recalcBars = false;
  54.          ITERATE(UIBars_t::iterator, bars, it)
  55.             if ((*it)->isActive())
  56.                (*it)->calculateRect();
  57.       }
  58.  
  59.       //Particles
  60.       ITERATE(particles_t::iterator, game.particles, it){
  61.          it->tick(delta);
  62.          if (it->expired()){
  63.             //debug("particle expired");
  64.             it = game.particles.erase(it);
  65.             if (it == game.particles.end())
  66.                break;
  67.          }
  68.       }
  69.      
  70.       //Misc.
  71.       resourcesBox(game.players[HUMAN_PLAYER].getResources());
  72.  
  73.    }
  74.  
  75. }
  76.  
  77. void handleEvents(const CoreData &core, GameData &game,
  78.                   UIBars_t &bars,
  79.                   MessageBox &contextHelp, MessageBox &fpsDisplay){
  80.    SDL_Event event;
  81.    while (SDL_PollEvent(&event))
  82.       switch (event.type){
  83.  
  84.  
  85.  
  86.       //Window is exited
  87.       case SDL_QUIT:
  88.          game.loop = false;
  89.          game.outcome = QUIT;
  90.          break;
  91.  
  92.  
  93.  
  94.       //Mouse is moved
  95.       case SDL_MOUSEMOTION:
  96.          { //new scope for overBar, index
  97.             game.cursorColor = CLR_MAX;
  98.             contextHelp("");
  99.             Screen::mousePos.x = event.motion.x;
  100.             Screen::mousePos.y = event.motion.y;
  101.             //check right mouse movement
  102.             if (!game.rightMouse.dragging)
  103.                game.rightMouse.checkDrag(Screen::mousePos);
  104.             if (!game.leftMouse.dragging)
  105.                game.leftMouse.checkDrag(Screen::mousePos - game.map);
  106.  
  107.             //if over a UI bar
  108.             bool overBar = false;
  109.             typeNum_t index;
  110.             ITERATE(UIBars_t::iterator, bars, it)
  111.                if ((*it)->isActive()){
  112.                   index = (*it)->mouseIndex();
  113.                   if (index != NO_TYPE){
  114.                      //mousing over this bar
  115.                      contextHelp((*it)->helpText(index));
  116.                      overBar = true;
  117.                      break;
  118.                   }
  119.                }
  120.  
  121.             if (!overBar){
  122.                Entity *entityP = findEntity(game, false);
  123.                if (entityP){
  124.                   contextHelp(entityP->getHelp());
  125.                   game.cursorColor = entityP->getColor();
  126.                }else
  127.                   game.cursorColor = CLR_MAX; //no color
  128.             }
  129.  
  130.             switch(game.mode){
  131.             case MODE_CONSTRUCTION:
  132.                game.buildLocationOK =
  133.                   noCollision(game, core.buildingTypes[game.toBuild],
  134.                               Screen::mousePos - locRect(game.map));
  135.                break;
  136.             }
  137.          }
  138.          break;
  139.  
  140.  
  141.  
  142.          //A key is pressed
  143.          case SDL_KEYDOWN:
  144.             {//new scope for key
  145.                SDLKey key = event.key.keysym.sym;
  146.                switch (key){
  147.                case SDLK_PRINT:
  148.                   { //new scope for os
  149.                      std::ostringstream os;
  150.                      os << SCREENSHOTS_PATH << "shot" << time(0) << ".bmp";
  151.                      screenBuf.saveToBitmap(os.str());
  152.                   }
  153.                   break;
  154.  
  155.                case SDLK_KP_PLUS:
  156.                   if (DEBUG)
  157.                      game.players[HUMAN_PLAYER]
  158.                         .addResources(resources_t(Resources::getResourceCount(), 1337));
  159.                   break;
  160.  
  161.                case SDLK_KP_MINUS:
  162.                   //HACK remove this cheat
  163.                   if (DEBUG)
  164.                      game.players[HUMAN_PLAYER].godMode();
  165.                   break;
  166.  
  167.                case SDLK_ESCAPE:
  168.                   if (DEBUG){
  169.                      game.loop = false;
  170.                      game.outcome = ALT_F4;
  171.                      return;
  172.                   }
  173.                   switch(game.mode){
  174.                   //unselect all
  175.                   case MODE_BUILDING:
  176.                      game.buildingSelected->selected = false;
  177.                      game.buildingSelected = 0;
  178.                      //fall-through
  179.                   case MODE_BUILDER:
  180.                   case MODE_NORMAL:
  181.                      ITERATE(entities_t::iterator, game.entities, it)
  182.                         (*it)->selected = false;
  183.                      game.mode = MODE_NORMAL;
  184.                      break;
  185.                   case MODE_CONSTRUCTION:
  186.                      game.toBuild = NO_TYPE;
  187.                      game.mode = MODE_NORMAL;
  188.                      ITERATE(UIBars_t::iterator, bars, it)
  189.                         if ((*it)->isActive())
  190.                            (*it)->calculateRect();
  191.                      break;
  192.                   }
  193.                   break;
  194.  
  195.                case SDLK_DELETE:
  196.                   { //new scope for selected
  197.                      //find selected entities
  198.                      ITERATE(entities_t::iterator, game.entities, it)
  199.                         if ((*it)->selected){
  200.                            (*it)->kill();
  201.                            break;
  202.                         }
  203.                   }
  204.                   break;
  205.  
  206.                case SDLK_F4:
  207.                   //Alt+F4: Exit program immediately
  208.                   if (isKeyPressed(SDLK_LALT) || isKeyPressed(SDLK_RALT)){
  209.                      game.loop = false;
  210.                      game.outcome = ALT_F4;
  211.                      return;
  212.                   }
  213.                   break;
  214.  
  215.                case SDLK_F11:
  216.                   //F11: toggle FPS display
  217.                   fpsDisplay.toggleVisibility();
  218.                   break;
  219.  
  220.                case SDLK_F9:
  221.                   //F9: restart
  222.                   game.loop = false;
  223.                   game.outcome = LOSS;
  224.                   return;
  225.  
  226.                case SDLK_F10:
  227.                   //F10: quit
  228.                   game.loop = false;
  229.                   game.outcome = QUIT;
  230.                   return;
  231.                
  232.                case SDLK_F3:
  233.                case SDLK_PAUSE:
  234.                   //toggle pause
  235.                   game.paused = !game.paused;
  236.                   if (game.paused)
  237.                      Mix_PauseMusic();
  238.                   else
  239.                      Mix_ResumeMusic();
  240.                   break;
  241.  
  242.                //another key
  243.                default:
  244.                  
  245.                   //control groups
  246.                   if (key >= CONTROL_MIN &&
  247.                       key <= CONTROL_MAX ||
  248.                       key == CONTROL_NONE)
  249.  
  250.                      //Ctrl: Set control group
  251.                      if (isKeyPressed(SDLK_LCTRL) ||
  252.                          isKeyPressed(SDLK_RCTRL)){
  253.                         ITERATE(entities_t::iterator, game.entities, it)
  254.                            if ((*it)->classID() == ENT_UNIT){
  255.                               Unit &unit = (Unit &)(**it);
  256.                               if (unit.controlGroup == key)
  257.                                  unit.controlGroup = CONTROL_NONE;
  258.                               if ((*it)->selected)
  259.                                  unit.controlGroup = ControlGroup(key);
  260.                            }
  261.                      
  262.                      //No Ctrl: select control group
  263.                      }else{
  264.                         if (key != CONTROL_NONE){ //0 nothing to select
  265.                            const Sound *sound = 0; //selection sound to play
  266.                            ITERATE(entities_t::iterator, game.entities, it){
  267.  
  268.                               //no Shift: unselect all
  269.                               if (!(isKeyPressed(SDLK_LSHIFT) ||
  270.                                     isKeyPressed(SDLK_RSHIFT)))
  271.                                  (*it)->selected = false;
  272.  
  273.                               //select if right control group
  274.                               if ((*it)->classID() == ENT_UNIT){
  275.                                  Unit &unit = (Unit &)(**it);
  276.                                  if (unit.controlGroup == key){
  277.                                     unit.selected = true;
  278.                                     if (!sound)
  279.                                        sound = &unit.type().getSound();
  280.                                  }
  281.                               }
  282.                            }
  283.                            game.selectionChanged = true;
  284.                            assert(sound);
  285.                            sound->play();
  286.                         }
  287.                      }
  288.  
  289.                   //home row keys - click equivalent UI bar button
  290.                   else if (key == SDLK_a ||
  291.                            key == SDLK_s ||
  292.                            key == SDLK_d ||
  293.                            key == SDLK_f ||
  294.                            key == SDLK_g ||
  295.                            key == SDLK_h ||
  296.                            key == SDLK_j ||
  297.                            key == SDLK_k ||
  298.                            key == SDLK_l){
  299.                      typeNum_t index = NO_TYPE;
  300.                      switch (key){
  301.                      case SDLK_a:
  302.                         index = 0; break;
  303.                      case SDLK_s:
  304.                         index = 1; break;
  305.                      case SDLK_d:
  306.                         index = 2; break;
  307.                      case SDLK_f:
  308.                         index = 3; break;
  309.                      case SDLK_g:
  310.                         index = 4; break;
  311.                      case SDLK_h:
  312.                         index = 5; break;
  313.                      case SDLK_j:
  314.                         index = 6; break;
  315.                      case SDLK_k:
  316.                         index = 7; break;
  317.                      case SDLK_l:
  318.                         index = 8; break;
  319.                      }
  320.                      ITERATE(UIBars_t::iterator, bars, it)
  321.                         if ((*it)->isActive() &&
  322.                             (*it)->size() > index)
  323.                            (*it)->click(index);
  324.                   }
  325.                   else
  326.                      debug("unhandled keypress: ", key);
  327.                }
  328.             }
  329.          break;
  330.  
  331.  
  332.  
  333.       //TODO * clicking on a useless entity (eg. tree) = try next one
  334.       //A mouse button is pressed
  335.       case SDL_MOUSEBUTTONDOWN:
  336.          debug("Mouse down: ", int(event.button.button));
  337.          switch (event.button.button){
  338.          case MOUSE_BUTTON_LEFT:
  339.             game.leftMouse.mouseDown(Screen::mousePos - game.map);
  340.             { //new scope for barClicked
  341.                //if not clicking a button
  342.                bool barClicked = false;
  343.                for (UIBars_t::iterator it = bars.begin();
  344.                     !barClicked && it != bars.end(); ++it)
  345.                   if ((*it)->isActive())
  346.                      if ((*it)->mouseIndex() != NO_TYPE)
  347.                         barClicked = true;
  348.                if (!barClicked){
  349.                   //initialize selection box stuff
  350.                   game.leftMouse.mouseDown(Screen::mousePos - game.map);
  351.                }
  352.                break;
  353.             }
  354.          case MOUSE_BUTTON_RIGHT:
  355.             //initialize right-drag scroll stuff
  356.             game.rightMouse.mouseDown(Screen::mousePos);
  357.             break;
  358.          }// switch mouse button
  359.          pushMouseMove();
  360.          break;
  361.  
  362.  
  363.  
  364.       //A mouse button is released
  365.       case SDL_MOUSEBUTTONUP:
  366.          switch (event.button.button){
  367.  
  368.          case MOUSE_BUTTON_RIGHT:
  369.             if (!game.rightMouse.dragging)
  370.                if (!game.leftMouse.dragging)
  371.                   switch(game.mode){
  372.                   case MODE_CONSTRUCTION:
  373.                      //cancel build mode
  374.                      game.toBuild = NO_TYPE;
  375.                      game.mode = MODE_BUILDER;
  376.                      ITERATE(UIBars_t::iterator, bars, it)
  377.                         if ((*it)->isActive())
  378.                            (*it)->calculateRect();
  379.                      break;
  380.                   default:
  381.                      setSelectedTargets(game);
  382.                   }
  383.             game.rightMouse.mouseUp();
  384.             break;
  385.  
  386.          case MOUSE_BUTTON_LEFT:
  387.             //check UI bars
  388.             if (!game.leftMouse.dragging){
  389.                bool barClicked = false; //whether a UIBar was clicked
  390.                for (UIBars_t::iterator it = bars.begin();
  391.                     !barClicked && it != bars.end(); ++it)
  392.                   if ((*it)->isActive()){
  393.                      typeNum_t index = (*it)->mouseIndex();
  394.                      if (index != NO_TYPE){
  395.                         (*it)->click();
  396.                         barClicked = true;
  397.                      }
  398.                   }
  399.                if (!barClicked){
  400.                   //place new building
  401.                   if (game.mode == MODE_CONSTRUCTION){
  402.                      assert (game.toBuild != NO_TYPE);
  403.                      if (game.buildLocationOK){
  404.                         game.constructBuilding(game.toBuild,
  405.                                                Screen::mousePos - game.map,
  406.                                                HUMAN_PLAYER);
  407.                         //Shift key: multiple constructions
  408.                         if(!isKeyPressed(SDLK_LSHIFT)){
  409.                            game.mode = MODE_BUILDER;
  410.                            ITERATE(UIBars_t::iterator, bars, it)
  411.                               if ((*it)->isActive())
  412.                                  (*it)->calculateRect();
  413.                         }
  414.                      }else
  415.                         debug ("Bad location for building");
  416.  
  417.                   }else{ //not construction mode
  418.                      select(game);
  419.                      setModeFromSelection(game, bars);
  420.                   }
  421.                }// if !barClicked
  422.             }else{ //if dragging
  423.                select(game);
  424.                setModeFromSelection(game, bars);
  425.             }
  426.             game.leftMouse.mouseUp();
  427.             break;
  428.          }
  429.          pushMouseMove();
  430.          break;
  431.       } //switch event
  432. }
  433.  
  434. void scrollMap(GameData &game, double delta){
  435.  
  436.    bool scrolling = false;
  437.  
  438.    //right-dragging
  439.    if (game.rightMouse.dragging){
  440.       scrolling = true;
  441.       Point rmbDisplacement = Screen::mousePos - game.rightMouse.dragBegin;
  442.       Point scroll = rmbDisplacement * (delta * RMB_SCROLL_MULTIPLIER);
  443.       if (game.scrollLockX)
  444.          scroll.x = 0;
  445.       if (game.scrollLockY)
  446.          scroll.y = 0;
  447.       game.map = game.map - scroll;
  448.    }
  449.  
  450.    pixels_t scroll = pixels_t(delta * SCROLL_AMOUNT);
  451.  
  452.    //edge of screen
  453.    if (!game.scrollLockX){
  454.       if (Screen::mousePos.x < EDGE_SCROLL_MARGIN){
  455.          scrolling = true;
  456.          game.map.x += scroll;
  457.       }else if (Screen::mousePos.x > Screen::getScreenRes().x - EDGE_SCROLL_MARGIN){
  458.          scrolling = true;
  459.          game.map.x -= scroll;
  460.       }
  461.    }
  462.    if (!game.scrollLockY){
  463.       if (Screen::mousePos.y < EDGE_SCROLL_MARGIN){
  464.          scrolling = true;
  465.          game.map.y += scroll;
  466.       }else if (Screen::mousePos.y > Screen::getScreenRes().y - EDGE_SCROLL_MARGIN){
  467.          scrolling = true;
  468.          game.map.y -= scroll;
  469.       }
  470.    }
  471.  
  472.    //arrow keys
  473.    if (!game.scrollLockX){
  474.       if (isKeyPressed(SDLK_LEFT)){
  475.          scrolling = true;
  476.          game.map.x += scroll;
  477.       }
  478.       if (isKeyPressed(SDLK_RIGHT)){
  479.          scrolling = true;
  480.          game.map.x -= scroll;
  481.       }
  482.    }
  483.    if (!game.scrollLockY){
  484.       if (isKeyPressed(SDLK_UP)){
  485.          scrolling = true;
  486.          game.map.y += scroll;
  487.       }
  488.       if (isKeyPressed(SDLK_DOWN)){
  489.          scrolling = true;
  490.          game.map.y -= scroll;
  491.       }
  492.    }
  493.  
  494.    //Enforce scroll boundaries
  495.    if (!game.scrollLockX){
  496.       if (game.map.x > SCROLL_MARGIN){
  497.          scrolling = true;
  498.          game.map.x = SCROLL_MARGIN;
  499.       }
  500.       if (game.map.x + game.map.w < Screen::getScreenRes().x - SCROLL_MARGIN){
  501.          scrolling = true;
  502.          game.map.x = Screen::getScreenRes().x - SCROLL_MARGIN - game.map.w;
  503.       }
  504.    }
  505.    if (!game.scrollLockY){
  506.       if (game.map.y > SCROLL_MARGIN){
  507.          scrolling = true;
  508.          game.map.y = SCROLL_MARGIN;
  509.       }
  510.       if (game.map.y + game.map.h < Screen::getScreenRes().y - SCROLL_MARGIN){
  511.          scrolling = true;
  512.          game.map.y = Screen::getScreenRes().y - SCROLL_MARGIN - game.map.h;
  513.       }
  514.    }
  515.  
  516.    if (scrolling)
  517.       pushMouseMove();
  518. }
  519.  
  520. SDL_Rect getSelectionRect(const GameData &game){
  521.    const SDL_Rect &map = game.map;
  522.    const MouseButton &leftMouse = game.leftMouse;
  523.    Point modMouse = Screen::mousePos - map;
  524.    SDL_Rect selRect;
  525.  
  526.    if (leftMouse.dragBegin.x < modMouse.x){
  527.       selRect.x = leftMouse.dragBegin.x;
  528.       selRect.w = modMouse.x - leftMouse.dragBegin.x;
  529.    }else{
  530.       selRect.x = modMouse.x;
  531.       selRect.w = leftMouse.dragBegin.x - modMouse.x;
  532.    }
  533.    if (leftMouse.dragBegin.y < modMouse.y){
  534.       selRect.y = leftMouse.dragBegin.y;
  535.       selRect.h = modMouse.y - leftMouse.dragBegin.y;
  536.    }else{
  537.       selRect.y = modMouse.y;
  538.       selRect.h = leftMouse.dragBegin.y - modMouse.y;
  539.    }
  540.    return selRect + map;
  541. }
  542.  
  543. void select(GameData &game){
  544.    bool entitySelected = false;
  545.    bool soundPlayed = false;
  546.    game.selectionChanged = true;
  547.  
  548.    //loop backwards, so objects in front have priority to be
  549.    //selected
  550.    for (entities_t::reverse_iterator it = game.entities.rbegin();
  551.         it != game.entities.rend(); ++it){
  552.       if ((*it)->selectable()){
  553.          //unselect everything
  554.          if (!(isKeyPressed(SDLK_LCTRL) || isKeyPressed(SDLK_LSHIFT))){
  555.             (*it)->selected = false;
  556.          }
  557.          
  558.          //if single point click, don't waste time looking for
  559.          //multiple selections
  560.          if (!entitySelected || game.leftMouse.dragging){
  561.  
  562.             //determine collision
  563.             bool collides;
  564.             if (game.leftMouse.dragging)
  565.                //selection box: collision(SDL_Rect, SDL_Rect)
  566.                collides = collision((*it)->getDrawRect(),
  567.                                     getSelectionRect(game) -
  568.                                     locRect(game.map));
  569.             else
  570.                //single point: collision(SDL_Rect, Point)
  571.                collides = collision((*it)->getDrawRect(),
  572.                                     Screen::mousePos -
  573.                                     Point(game.map));
  574.  
  575.             if (collides){
  576.                if (isKeyPressed(SDLK_LCTRL))
  577.                   (*it)->toggleSelect(); //Ctrl: toggle
  578.                else
  579.                   (*it)->selected = true; //No ctrl: select
  580.                entitySelected = true;
  581.                if ((*it)->selected)
  582.                   if (!soundPlayed){
  583.                      (*it)->type().getSound().play();
  584.                      soundPlayed = true;
  585.                   }
  586.             }// if collides
  587.  
  588.          }// if single point etc.
  589.  
  590.       }// if selectable
  591.  
  592.       //exit loop if possible
  593.       if (entitySelected &&
  594.           !game.leftMouse.dragging &&
  595.           (isKeyPressed(SDLK_LCTRL) || isKeyPressed(SDLK_LSHIFT)))
  596.          break;
  597.  
  598.    }// for entities
  599. }
  600.  
  601. void setSelectedTargets(GameData &game){
  602.    ITERATE(entities_t::iterator, game.entities, it){
  603.  
  604.       //only selected units have their targets set
  605.       if ((*it)->classID() != ENT_UNIT ||
  606.           !(*it)->selected)
  607.           continue;
  608.  
  609.       Unit *unitP = (Unit *)(*it);
  610.       Entity *targetEntity = findEntity(game, unitP);
  611.  
  612.       //no entity
  613.       if (!targetEntity){
  614.          unitP->setTarget();
  615.          continue;
  616.       }
  617.  
  618.       EntityTypeID targetClass = targetEntity->classID();
  619.  
  620.       //enemy unit or building
  621.       if ((targetClass == ENT_UNIT || targetClass == ENT_BUILDING) &&
  622.           targetEntity->getPlayer() != unitP->getPlayer()){
  623.          unitP->setTarget(targetEntity);
  624.          continue;
  625.       }
  626.  
  627.       //friendly, unfinished building
  628.       if (targetClass == ENT_BUILDING &&
  629.           targetEntity->getPlayer() == unitP->getPlayer() &&
  630.           unitP->isBuilder() &&
  631.           !((Building *)(targetEntity))->isFinished()){
  632.          unitP->setTarget(targetEntity);
  633.          continue;
  634.       }
  635.  
  636.       //resource node
  637.       if (targetClass == ENT_RESOURCE_NODE &&
  638.           unitP->isGatherer())
  639.          unitP->setTarget(targetEntity);
  640.    }
  641. }
  642.  
  643. void reSort(entities_t &entities, entities_t::iterator it,
  644.             VerticalMovement verticalMovement){
  645.    entities_t::iterator old = it;
  646.    switch(verticalMovement){
  647.    case DIR_UP:
  648.       if (it != entities.begin()){
  649.          entities_t::iterator next = it;
  650.          --next;
  651.          while (next != entities.begin() && **it < **next){
  652.             std::iter_swap(it, next);
  653.             it = next;
  654.             --next;
  655.          }
  656.       }
  657.       break;
  658.  
  659.    case DIR_DOWN:
  660.       entities_t::iterator next = it;
  661.       ++next;
  662.       while (next != entities.end() && **next < **it){
  663.          std::iter_swap(it, next);
  664.          it = next;
  665.          ++next;
  666.       }
  667.  
  668.    }
  669. }
  670.  
  671. Entity *findEntity(GameData &game, const Unit *targetingUnit){
  672.    //loop backwards, so objects in front have priority
  673.    for (entities_t::reverse_iterator it = game.entities.rbegin();
  674.         it != game.entities.rend(); ++it){
  675.  
  676.       //skip decorations
  677.       if ((*it)->classID() == ENT_DECORATION)
  678.          continue;
  679.  
  680.       //filtering
  681.       //only targetable entities
  682.       if (targetingUnit && !(*it)->targetable())
  683.          continue;
  684.  
  685.       if (collision((*it)->getDrawRect(),
  686.                     Screen::mousePos - Point(game.map)))
  687.          return *it;
  688.    }
  689.    return 0;
  690. }
  691.  
  692. void setModeFromSelection(GameData &game, UIBars_t &bars){
  693.    game.selectionChanged = false;
  694.    game.buildingSelected = 0;
  695.    ControlMode oldMode = game.mode;
  696.    game.mode = MODE_NONE;
  697.  
  698.    //loop backwards, so objects in front have priority to be
  699.    //selected
  700.    ITERATE(entities_t::const_iterator, game.entities, it){
  701.       if ((*it)->selected){
  702.          EntityTypeID classType = (*it)->classID();
  703.  
  704.          //builder
  705.          if (classType == ENT_UNIT &&
  706.              ((const Unit &)(**it)).isBuilder()){
  707.             game.mode = MODE_BUILDER;
  708.             break;
  709.          }
  710.  
  711.          //building
  712.          else if (classType == ENT_BUILDING){
  713.             game.mode = MODE_BUILDING;
  714.             game.buildingSelected = (Building *)(*it);
  715.          }
  716.       }
  717.    }
  718.  
  719.    if (oldMode == MODE_CONSTRUCTION &&
  720.        game.mode == MODE_BUILDER)
  721.          game.mode = MODE_CONSTRUCTION;
  722.  
  723.    ITERATE(UIBars_t::iterator, bars, it)
  724.       (*it)->calculateRect();
  725. }
  726.  
  727. void checkVictory(GameData &game){
  728.    //set each player initially to dead
  729.    ITERATE(players_t::iterator, game.players, it)
  730.       it->alive = false;
  731.    
  732.    //change players based on which entities exist
  733.    ITERATE(entities_t::const_iterator, game.entities, it){
  734.       typeNum_t player = (*it)->getPlayer();
  735.       if (player != NO_TYPE)
  736.          game.players[player].alive = true;
  737.    }
  738.  
  739.    //determine victory/loss
  740.    bool enemiesAlive = false;
  741.    for (typeNum_t i = 0; i != game.players.size(); ++i)
  742.       if (i != HUMAN_PLAYER &&
  743.           i != NATURE_PLAYER &&
  744.           game.players[i].alive)
  745.          enemiesAlive = true; //not a victory
  746.    if (!enemiesAlive){
  747.       game.outcome = VICTORY;
  748.       game.loop = false;
  749.    }else if (!game.players[HUMAN_PLAYER].alive){
  750.       game.outcome = LOSS;
  751.       game.loop = false;
  752.    }
  753. }
RAW Paste Data
Top