Logo Search packages:      
Sourcecode: qonk version File versions  Download package

game.cpp

#include "game.h"
#include "gameoptions.h"

#include "timer.h"
#include "planets.h"
#include "players.h"
#include "universe.h"
#include "messages.h"
#include "timer.h"
#include "settings.h"
#include "canvas.h"
#include "selection.h"

#include "extensions.h"

using namespace std;

Game::Game(GameOptions &go)
  : gameOptions(go), nextNumberOfPlanets(0), nextNumberOfComputerPlayers(0), timer(new Timer()),
    players(0), universe(0), messages(0), selection(0)
{
  int numberOfPlanets = gameOptions.getPlanets();
  int numberOfComputerPlayers = gameOptions.getPlayers();

  state = PLAYING;
  quit = false;
  timer->start();

  // Initialize selection
  x = Settings::getScreenWidth()/2;
  y = Settings::getScreenHeight()/2;
  xp = xn = yp = yn = 0;

  universe = new Universe( numberOfPlanets );

  players = new Players( universe );
  universe->actionQueue->scheduleAction( 1000, new UpdatePlayersStatsAction( players) );

  humanPlayer = new HumanPlayer( universe, 0xffffff, 1);
  humanPlayer->setVisible(true);
  universe->claim(0, humanPlayer, 1, 3);
  players->push_back(humanPlayer);
  
  bool vis = gameOptions.getEnemyVisibility();
     
  int hueCounter = rand() % 360;
  for (int i=0;i<numberOfComputerPlayers;i++)
  {
    Player *newPlayer = new ComputerPlayer( universe, HSVtoRGB( hueCounter, 0.9, 0.9 ), 2);
    newPlayer->setVisible(vis);
    universe->claim(0, newPlayer, 1, 3);
    hueCounter = ( hueCounter + 360 / numberOfComputerPlayers ) % 360;
    players->push_back(newPlayer);
  }

  NeutralPlayer *neutral = new NeutralPlayer(universe, 0x808080);
  neutral->setVisible(vis);
  universe->claimRemaining(0, neutral, 3, 2);
  players->push_back(neutral);

  messages = new Messages();
  selection = new Selection();
}

Game::~Game()
{
  delete players;
  delete universe;
  delete messages;
  delete selection;
  delete timer;
}

bool
Game::run(bool menuVisible)
{
  if (quit)
    return false;

  // TODO: Find a way to live without the next line.
  setPaused(menuVisible);

      if (timer->isPaused())
    return true;

  moveCursor(xp - xn, yp - yn);

  Uint32 time = getTime();
  // update the universe
  universe->update(time);

  // let players update their states
  players->update(this);
            
      if( state == PLAYING )
  {
    if(checkLost()) {
      setEnemyVisibility(true);
      state = LOST;
      MSGlost(this);
    }

            if( checkWin()) {
      nextNumberOfPlanets = gameOptions.getPlanets() + 1;
      nextNumberOfComputerPlayers = gameOptions.getPlayers() + 1;
        
      if( nextNumberOfPlanets == 11 )
      {
        int d = nextNumberOfPlanets - nextNumberOfComputerPlayers;
        if( d != 1 )
          nextNumberOfPlanets = 10;
      }

                  MSGwon(this, nextNumberOfPlanets, nextNumberOfComputerPlayers);
                  state = WON;
            }
      }

  return true;
}

void
Game::handle(GameAction gameAction, int value)
{
  if (timer->isPaused())
    return;

  switch (gameAction)
  {
    case GA_NEXT_ROUND:
      if (!value) return;
      if(state==WON)
      {
        quit = true;
      }
      gameOptions.setPlanets(nextNumberOfPlanets);
      gameOptions.setPlayers(nextNumberOfComputerPlayers);

      break;
    case GA_RESTART_ROUND:
      if (!value) return;
      quit = true;
      break;
    case GA_SELECT_ALL:
      if (value)
        selectAllPlanets();
      break;
    case GA_TOGGLE_ENEMY_VISIBILITY:
      if (value)
      {
        gameOptions.setEnemyVisibility(!gameOptions.getEnemyVisibility());
        setEnemyVisibility(gameOptions.getEnemyVisibility());
      }
      break;
    case GA_SELECTION:
      if (value)
        startSelection(x, y);
      else
        endSelection(x, y);
      break;
    case GA_SELECT_NEAREST_PLANET:
      if (value)
        selectNearestPlanet(x, y);
      break;
    case GA_MOVE_TO_NEAREST_PLANET:
      if (value)
        moveToNearestPlanet(x, y);
      break;
    case GA_FLEET_STRENGTH_UP:
      if (value)
        fleetStrengthUp();
      break;
    case GA_FLEET_STRENGTH_DOWN:
      if (value)
        fleetStrengthDown();
      break;
    case GA_SET_FLEET_STRENGTH_SINGLE:
      if (value)
        setFleetStrength(1);
      break;
    case GA_CURSOR_UP:
        yn = value;
        break;
    case GA_CURSOR_DOWN:
        yp = value;
        break;
    case GA_CURSOR_LEFT:
        xn = value;
        break;
    case GA_CURSOR_RIGHT:
        xp = value;
        break;
    default:
      if (value 
          && gameAction >= GA_SET_FLEET_STRENGTH_10
          && gameAction <= GA_SET_FLEET_STRENGTH_100)
      {
        setFleetStrength(10 * (1 + gameAction - GA_SET_FLEET_STRENGTH_10));
      }
  }
}

void
Game::moveCursor(int xrel, int yrel)
{
  x += xrel;
  y += yrel;

  x = max(0, min(x, Settings::getScreenWidth()));
  y = max(0, min(y, Settings::getScreenHeight()));
  
  if (selection->isSelecting())
    selection->update(x, y);
  else
    universe->highlightNearestPlanet(x, y);
}

bool
Game::checkWin()
{
        bool allPlayersDead = true;
        for( Players::iterator i = players->begin(); i != players->end(); i++ ) {
                if( (*i)->getTeam() == 2 )
                
                if( ((ComputerPlayer*)(*i))->getPoints() > 0 )
                        allPlayersDead = false;
        }

        return allPlayersDead;
}

bool
Game::checkLost()
{
  return humanPlayer->getPoints() == 0;
}

void
Game::fleetStrengthUp()
{
  int str = humanPlayer->getFleetStrength();
  if (str == 1)
    str = 10;
  else if (str == 100)
    str = 1;
  else
    str += 10;

  setFleetStrength(str);
}

void
Game::fleetStrengthDown()
{
  int str = humanPlayer->getFleetStrength();
  if (str == 1)
    str = 100;
  else if (str == 10)
    str = 1;
  else
    str -= 10;

  setFleetStrength(str);
}

void
Game::setFleetStrength(int str)
{
  humanPlayer->setFleetStrength(str);
  
  stringstream s;
  if (str == 1)
        s << "Single ship mode";
  else
  {
        s << "Fleet strength " << str << "%";
  }

  messages->setFleetStrengthMessage( Message(getTime(), s.str(), 0x808080) );
}

void
Game::setPaused(bool p)
{
  if (p ^ timer->isPaused())
    timer->pause();

}

void
Game::setEnemyVisibility(bool visible)
{
  int humanTeam = humanPlayer->getTeam();

  for( Players::iterator i = players->begin(); i != players->end(); i++ )
  {
    Player *p = *i;
    if (p->getTeam() != humanTeam)
      p->setVisible(visible);
  }

  stringstream s;
  s << "Made enemies " << (visible ? "visible" : "invisible");

  messages->addMessage(timer->getTime(), Message(getTime(), s.str(), 20000, 0x808080));
}

void
Game::selectAllPlanets()
{
  humanPlayer->selectAllPlanets();
}

void
Game::selectNearestPlanet(int x, int y)
{
  humanPlayer->selectNearestPlanet(x, y);
}

void
Game::moveToNearestPlanet(int x, int y)
{
  humanPlayer->moveToNearestPlanet(getTime(), x, y);
}

void
Game::startSelection(int x, int y)
{
  selection->start(x, y);
}

void
Game::updateSelection(int x, int y)
{
  selection->update(x, y);
}

void
Game::endSelection(int x, int y)
{
  selection->end();

  if (selection->isEmpty())
    humanPlayer->selectPlanetAt(x, y);
  else
    universe->planets->sourceSelect(selection, humanPlayer);
}

void
Game::addMessage(int offset, Message msg)
{
  messages->addMessage( timer->getTime() + offset, msg);
}

Uint32
Game::getTime() const
{
  return timer->getTime();
}

void
Game::render()
{
  Uint32 time = getTime();
  
  universe->renderBackground(time);
  players->render();

  humanPlayer->render();
  selection->render();

  universe->renderForeground(time);

  messages->render(time);

  Canvas::drawCursor(x, y);
}

Generated by  Doxygen 1.6.0   Back to index