Changeset d05c484 in network-game


Ignore:
Timestamp:
Jan 19, 2014, 7:40:55 PM (11 years ago)
Author:
dportnoy <dmp1488@…>
Branches:
master
Children:
e5697b1
Parents:
6054f1e
Message:

Some game-specific functions moved from server.cpp to the Game class and a function moved to the MessageProcessor class

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • common/Game.cpp

    r6054f1e rd05c484  
    11#include "Game.h"
     2
     3#include <iostream>
     4#include <cstring>
    25
    36#include "Common.h"
     
    1114   this->redScore = 0;
    1215   this->worldMap = NULL;
    13 }
    14 
    15 Game::Game(string name, string filepath) {
     16   this->msgProcessor = NULL;
     17}
     18
     19Game::Game(string name, string filepath, MessageProcessor* msgProcessor) {
    1620   this->id = 0;
    1721   this->name = name;
     
    1923   this->redScore = 0;
    2024   this->worldMap = WorldMap::loadMapFromFile(filepath);
     25   this->msgProcessor = msgProcessor;
    2126}
    2227
     
    95100void Game::setBlueScore(unsigned int score) {
    96101   this->blueScore = score;
     102}
     103
     104void Game::addObjectToMap(WorldMap::ObjectType objectType, int x, int y) {
     105   NETWORK_MSG serverMsg;
     106
     107   this->getMap()->addObject(objectType, x, y);
     108
     109   serverMsg.type = MSG_TYPE_OBJECT;
     110   this->worldMap->getObjects()->back().serialize(serverMsg.buffer);
     111
     112   this->msgProcessor->broadcastMessage(serverMsg, this->players);
    97113}
    98114
     
    175191}
    176192
     193void Game::dealDamageToPlayer(Player* p, int damage) {
     194   p->takeDamage(damage);
     195
     196   if (p->isDead)
     197   {
     198      WorldMap::ObjectType flagType = WorldMap::OBJECT_NONE;
     199      if (p->hasBlueFlag)
     200         flagType = WorldMap::OBJECT_BLUE_FLAG;
     201      else if (p->hasRedFlag)
     202         flagType = WorldMap::OBJECT_RED_FLAG;
     203
     204      if (flagType != WorldMap::OBJECT_NONE)
     205         this->addObjectToMap(flagType, p->pos.x, p->pos.y);
     206   }
     207
     208   // send a PLAYER message after dealing damage
     209   NETWORK_MSG serverMsg;
     210   serverMsg.type = MSG_TYPE_PLAYER;
     211   p->serialize(serverMsg.buffer);
     212   msgProcessor->broadcastMessage(serverMsg, this->players);
     213}
     214
     215bool Game::handleGameEvents() {
     216   NETWORK_MSG serverMsg;
     217   map<unsigned int, Player*>::iterator it;
     218   bool gameFinished = false;
     219
     220   for (it = this->getPlayers().begin(); it != this->getPlayers().end(); it++)
     221   {
     222      gameFinished = gameFinished ||
     223         this->handlePlayerEvents(it->second);
     224   }
     225
     226   if (gameFinished) {
     227      for (it = this->players.begin(); it != this->players.end(); it++)
     228      {
     229         it->second->currentGame = NULL;
     230      }
     231   }
     232
     233   return gameFinished;
     234}
     235
     236bool Game::handlePlayerEvents(Player* p) {
     237   NETWORK_MSG serverMsg;
     238   FLOAT_POSITION oldPos;
     239   bool gameFinished = false;
     240   bool broadcastMove = false;
     241
     242   cout << "moving player" << endl;
     243
     244   // move player and perform associated tasks
     245   oldPos = p->pos;
     246   if (p->move(this->worldMap)) {
     247
     248      cout << "player moved" << endl;
     249      if (this->processPlayerMovement(p, oldPos))
     250         broadcastMove = true;
     251      cout << "player move processed" << endl;
     252
     253      WorldMap::ObjectType flagType;
     254      POSITION pos;
     255      bool flagTurnedIn = false;
     256      bool flagReturned = false;
     257      bool ownFlagAtBase = false;
     258
     259      switch(this->worldMap->getStructure(p->pos.x/25, p->pos.y/25))
     260      {
     261         case WorldMap::STRUCTURE_BLUE_FLAG:
     262         {
     263            if (p->team == 0 && p->hasRedFlag)
     264            {
     265               // check that your flag is at your base
     266               pos = this->worldMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
     267                           
     268               vector<WorldMap::Object>* vctObjects = this->worldMap->getObjects();
     269               vector<WorldMap::Object>::iterator itObjects;
     270
     271               for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
     272               {
     273                  if (itObjects->type == WorldMap::OBJECT_BLUE_FLAG)
     274                  {
     275                     if (itObjects->pos.x == pos.x*25+12 && itObjects->pos.y == pos.y*25+12)
     276                     {
     277                        ownFlagAtBase = true;
     278                        break;
     279                     }
     280                  }
     281               }
     282
     283               if (ownFlagAtBase)
     284               {
     285                  p->hasRedFlag = false;
     286                  flagType = WorldMap::OBJECT_RED_FLAG;
     287                  pos = this->worldMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
     288                  flagTurnedIn = true;
     289                  this->blueScore++;
     290               }
     291            }
     292
     293            break;
     294         }
     295         case WorldMap::STRUCTURE_RED_FLAG:
     296         {
     297            if (p->team == 1 && p->hasBlueFlag)
     298            {
     299               // check that your flag is at your base
     300               pos = this->worldMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
     301                       
     302               vector<WorldMap::Object>* vctObjects = this->worldMap->getObjects();
     303               vector<WorldMap::Object>::iterator itObjects;
     304
     305               for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
     306               {
     307                  if (itObjects->type == WorldMap::OBJECT_RED_FLAG)
     308                  {
     309                     if (itObjects->pos.x == pos.x*25+12 && itObjects->pos.y == pos.y*25+12)
     310                     {
     311                        ownFlagAtBase = true;
     312                        break;
     313                     }
     314                  }
     315               }
     316
     317               if (ownFlagAtBase)
     318               {
     319                  p->hasBlueFlag = false;
     320                  flagType = WorldMap::OBJECT_BLUE_FLAG;
     321                  pos = this->worldMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
     322                  flagTurnedIn = true;
     323                  this->redScore++;
     324               }
     325            }
     326
     327            break;
     328         }
     329      }
     330
     331      if (flagTurnedIn)
     332      {
     333         unsigned int blueScore = this->blueScore;
     334         unsigned int redScore = this->redScore;
     335
     336         pos.x = pos.x*25+12;
     337         pos.y = pos.y*25+12;
     338         this->addObjectToMap(flagType, pos.x, pos.y);
     339
     340         serverMsg.type = MSG_TYPE_SCORE;
     341         memcpy(serverMsg.buffer, &blueScore, 4);
     342         memcpy(serverMsg.buffer+4, &redScore, 4);
     343         msgProcessor->broadcastMessage(serverMsg, this->players);
     344
     345         // check to see if the game should end
     346         // move to its own method
     347         if (this->blueScore == 3 || this->redScore == 3) {
     348            gameFinished = true;
     349
     350            unsigned int winningTeam;
     351            if (this->blueScore == 3)
     352               winningTeam = 0;
     353            else if (this->redScore == 3)
     354               winningTeam = 1;
     355
     356            serverMsg.type = MSG_TYPE_FINISH_GAME;
     357
     358            // I should create an instance of the GameSummary object here and just serialize it into this message
     359            memcpy(serverMsg.buffer, &winningTeam, 4);
     360            memcpy(serverMsg.buffer+4, &blueScore, 4);
     361            memcpy(serverMsg.buffer+8, &redScore, 4);
     362            strcpy(serverMsg.buffer+12, this->getName().c_str());
     363            msgProcessor->broadcastMessage(serverMsg, this->players);
     364         }
     365
     366         // this means a PLAYER message will be sent
     367         broadcastMove = true;
     368      }
     369
     370      // go through all objects and check if the player is close to one and if its their flag
     371      vector<WorldMap::Object>* vctObjects = this->worldMap->getObjects();
     372      vector<WorldMap::Object>::iterator itObjects;
     373      POSITION structPos;
     374
     375      for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
     376      {
     377         POSITION pos = itObjects->pos;
     378
     379         if (posDistance(p->pos, pos.toFloat()) < 10)
     380         {
     381            if (p->team == 0 &&
     382                itObjects->type == WorldMap::OBJECT_BLUE_FLAG)
     383            {
     384               structPos = this->worldMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
     385               flagReturned = true;
     386               break;
     387            }
     388            else if (p->team == 1 &&
     389                     itObjects->type == WorldMap::OBJECT_RED_FLAG)
     390            {
     391               structPos = this->worldMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
     392               flagReturned = true;
     393               break;
     394            }
     395         }
     396      }
     397
     398      if (flagReturned)
     399      {
     400         itObjects->pos.x = structPos.x*25+12;
     401         itObjects->pos.y = structPos.y*25+12;
     402
     403         serverMsg.type = MSG_TYPE_OBJECT;
     404         itObjects->serialize(serverMsg.buffer);
     405         msgProcessor->broadcastMessage(serverMsg, this->players);
     406      }
     407
     408      if (broadcastMove)
     409      {
     410         serverMsg.type = MSG_TYPE_PLAYER;
     411         p->serialize(serverMsg.buffer);
     412         msgProcessor->broadcastMessage(serverMsg, this->players);
     413      }
     414   }
     415
     416   cout << "processing player attack" << endl;
     417
     418   // check if the player's attack animation is complete
     419   if (p->isAttacking && p->timeAttackStarted+p->attackCooldown <= getCurrentMillis())
     420   {
     421      p->isAttacking = false;
     422      cout << "Attack animation is complete" << endl;
     423
     424      //send everyone an ATTACK message
     425      cout << "about to broadcast attack" << endl;
     426
     427      if (p->attackType == Player::ATTACK_MELEE)
     428      {
     429         cout << "Melee attack" << endl;
     430
     431         Player* target = players[p->targetPlayer];
     432         this->dealDamageToPlayer(target, p->damage);
     433      }
     434      else if (p->attackType == Player::ATTACK_RANGED)
     435      {
     436         cout << "Ranged attack" << endl;
     437
     438         Projectile proj(p->pos.x, p->pos.y, p->targetPlayer, p->damage);
     439         this->assignProjectileId(&proj);
     440         this->addProjectile(proj);
     441
     442         int x = p->pos.x;
     443         int y = p->pos.y;
     444
     445         serverMsg.type = MSG_TYPE_PROJECTILE;
     446         memcpy(serverMsg.buffer, &proj.id, 4);
     447         memcpy(serverMsg.buffer+4, &x, 4);
     448         memcpy(serverMsg.buffer+8, &y, 4);
     449         memcpy(serverMsg.buffer+12, &p->targetPlayer, 4);
     450         msgProcessor->broadcastMessage(serverMsg, players);
     451      }
     452      else
     453         cout << "Invalid attack type: " << p->attackType << endl;
     454   }
     455
     456   return gameFinished;
     457}
     458
    177459void Game::assignProjectileId(Projectile* p) {
    178460   p->id = unusedProjectileId;
  • common/Game.h

    r6054f1e rd05c484  
    1414#include "WorldMap.h"
    1515#include "Projectile.h"
     16#include "MessageProcessor.h"
    1617
    1718using namespace std;
     
    2728   unsigned int redScore;
    2829   unsigned int unusedProjectileId;
     30   MessageProcessor* msgProcessor;
    2931
    3032public:
    3133   Game();
    32    Game(string name, string filepath);
     34   Game(string name, string filepath, MessageProcessor* msgProcessor);
    3335
    3436   ~Game();
     
    4446   void setRedScore(unsigned int score);
    4547
     48   void addObjectToMap(WorldMap::ObjectType objectType, int x, int y);
     49
    4650   map<unsigned int, Player*>& getPlayers();
    4751   bool addPlayer(Player* p);
     
    5559   bool processPlayerMovement(Player* p, FLOAT_POSITION oldPos);
    5660   int processFlagPickupRequest(Player* p);
     61   void dealDamageToPlayer(Player* p, int damage);
     62
     63   bool handleGameEvents();
     64   bool handlePlayerEvents(Player* p);
    5765
    5866   void assignProjectileId(Projectile* p);
  • common/MessageProcessor.cpp

    r6054f1e rd05c484  
    9595}
    9696
     97void MessageProcessor::broadcastMessage(NETWORK_MSG &msg, map<unsigned int, Player*>& players) {
     98   map<unsigned int, Player*>::iterator it;
     99   for (it = players.begin(); it != players.end(); it++) {
     100      this->sendMessage(&msg, &(it->second->addr));
     101   }
     102}
     103
    97104void MessageProcessor::resendUnackedMessages() {
    98105   map<unsigned int, map<unsigned long, MessageContainer> >::iterator it;
  • common/MessageProcessor.h

    r6054f1e rd05c484  
    55
    66#include "MessageContainer.h"
     7#include "Player.h"
    78
    89using namespace std;
     
    2930   int sendMessage(NETWORK_MSG *msg, struct sockaddr_in *dest);
    3031   int receiveMessage(NETWORK_MSG *msg, struct sockaddr_in *source);
     32   void broadcastMessage(NETWORK_MSG &msg, map<unsigned int, Player*>& players);
    3133   void resendUnackedMessages();
    3234   void cleanAckedMessages();
  • server/makefile

    r6054f1e rd05c484  
    22#LIB_FLAGS = -lssl -lmysqlclient -lcrypt -lrt
    33LIB_FLAGS = -lmysqlclient -lcrypt -lrt
    4 FLAGS = $(LIB_FLAGS)
     4FLAGS = -Wall $(LIB_FLAGS)
    55COMMON_PATH = ../common
    66DEPENDENCIES = Common.o MessageContainer.o MessageProcessor.o Player.o WorldMap.o DataAccess.o Projectile.o Game.o GameSummary.o
  • server/server.cpp

    r6054f1e rd05c484  
    4646void processMessage(const NETWORK_MSG& clientMsg, struct sockaddr_in& from, MessageProcessor& msgProcessor, map<unsigned int, Player*>& mapPlayers, map<string, Game*>& mapGames, unsigned int& unusedPlayerId);
    4747
    48 bool handleGameEvents(Game* game, map<unsigned int, Player*>& mapPlayers, MessageProcessor& msgPocessor);
    49 bool handlePlayerEvents(Player* p, Game* game, MessageProcessor& msgProcessor);
    50 
    51 void broadcastMessage(MessageProcessor &msgProcessor, NETWORK_MSG &serverMsg, map<unsigned int, Player*>& players);
    5248void updateUnusedPlayerId(unsigned int& id, map<unsigned int, Player*>& mapPlayers);
    5349Player *findPlayerByName(map<unsigned int, Player*> &m, string name);
    5450Player *findPlayerByAddr(map<unsigned int, Player*> &m, const sockaddr_in &addr);
    55 
    56 void addObjectToMap(WorldMap::ObjectType objectType, int x, int y, WorldMap* gameMap, map<unsigned int, Player*>& mapPlayers, MessageProcessor &msgProcessor);
    5751
    5852void quit(int sig);
     
    7064   map<unsigned int, Projectile> mapProjectiles;
    7165   map<string, Game*> mapGames;
    72    unsigned int unusedPlayerId = 1, unusedProjectileId = 1;
     66   unsigned int unusedPlayerId = 1;
    7367   ofstream outputLog;
    7468
     
    106100
    107101   timespec ts;
    108    int timeLastUpdated = 0, curTime = 0, timeLastBroadcast = 0;
     102   int timeLastUpdated = 0, curTime = 0;
    109103   while (!done)
    110104   {
     
    169163                  p->serialize(serverMsg.buffer);
    170164
    171                   broadcastMessage(msgProcessor, serverMsg, p->currentGame->getPlayers());
     165                  msgProcessor.broadcastMessage(serverMsg, p->currentGame->getPlayers());
    172166               }
    173167
     
    181175                  serverMsg.type = MSG_TYPE_PLAYER;
    182176                  p->serialize(serverMsg.buffer);
    183                   broadcastMessage(msgProcessor, serverMsg, playersInGame);
     177                  msgProcessor.broadcastMessage(serverMsg, playersInGame);
    184178               }
    185179            }
     
    193187
    194188         for (itGames = mapGames.begin(); itGames != mapGames.end();) {
    195             if (handleGameEvents(itGames->second, mapPlayers, msgProcessor)) {
     189            game = itGames->second;
     190            if (game->handleGameEvents()) {
     191               // send a GAME_INFO message with 0 players to force clients to delete the game
     192               int numPlayers = 0;
     193               serverMsg.type = MSG_TYPE_GAME_INFO;
     194               memcpy(serverMsg.buffer, &numPlayers, 4);
     195               strcpy(serverMsg.buffer+4, game->getName().c_str());
     196               msgProcessor.broadcastMessage(serverMsg, mapPlayers);
     197
    196198               delete itGames->second;
    197199               mapGames.erase(itGames++);
     
    218220                  memcpy(serverMsg.buffer, &itProj->second.id, 4);
    219221                  game->removeProjectile(itProj->second.id);
    220                   broadcastMessage(msgProcessor, serverMsg, game->getPlayers());
     222                  msgProcessor.broadcastMessage(serverMsg, game->getPlayers());
    221223
    222224                  Player* target = game->getPlayers()[itProj->second.target];
    223                   target->takeDamage(itProj->second.damage);
    224 
    225                   if (target->isDead)
    226                   {
    227                      WorldMap::ObjectType flagType = WorldMap::OBJECT_NONE;
    228                      if (target->hasBlueFlag)
    229                         flagType = WorldMap::OBJECT_BLUE_FLAG;
    230                      else if (target->hasRedFlag)
    231                         flagType = WorldMap::OBJECT_RED_FLAG;
    232 
    233                      if (flagType != WorldMap::OBJECT_NONE)
    234                         addObjectToMap(flagType, target->pos.x, target->pos.y, game->getMap(), game->getPlayers(), msgProcessor);
    235                   }
    236 
    237                   // send a PLAYER message after dealing damage
    238                   serverMsg.type = MSG_TYPE_PLAYER;
    239                   target->serialize(serverMsg.buffer);
    240                   broadcastMessage(msgProcessor, serverMsg, game->getPlayers());
     225                  game->dealDamageToPlayer(target, itProj->second.damage);
    241226               }
    242227            }
     
    387372            serverMsg.type = MSG_TYPE_PLAYER;
    388373            p->serialize(serverMsg.buffer);
    389             broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     374            msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    390375
    391376            mapPlayers[unusedPlayerId] = p;
     
    421406            memcpy(serverMsg.buffer, &p->id, 4);
    422407
    423             broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     408            msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    424409
    425410            if (p->id < unusedPlayerId)
     
    456441
    457442            strcpy(serverMsg.buffer, oss.str().c_str());
    458             broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     443            msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    459444         }     
    460445
     
    488473               memcpy(serverMsg.buffer+8, &p->target.y, 4);
    489474
    490                broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     475               msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    491476
    492477               validMessage = true;
     
    521506            serverMsg.type = MSG_TYPE_REMOVE_OBJECT;
    522507            memcpy(serverMsg.buffer, &objectId, 4);
    523             broadcastMessage(msgProcessor, serverMsg, players);
     508            msgProcessor.broadcastMessage(serverMsg, players);
    524509
    525510            serverMsg.type = MSG_TYPE_PLAYER;
    526511            p->serialize(serverMsg.buffer);
    527             broadcastMessage(msgProcessor, serverMsg, players);
     512            msgProcessor.broadcastMessage(serverMsg, players);
    528513         }
    529514
     
    550535         map<unsigned int, Player*> players = p->currentGame->getPlayers();
    551536
    552          addObjectToMap(flagType, p->pos.x, p->pos.y, p->currentGame->getMap(), players, msgProcessor);
     537         p->currentGame->addObjectToMap(flagType, p->pos.x, p->pos.y);
    553538
    554539         p->hasBlueFlag = false;
     
    557542         serverMsg.type = MSG_TYPE_PLAYER;
    558543         p->serialize(serverMsg.buffer);
    559          broadcastMessage(msgProcessor, serverMsg, players);
     544         msgProcessor.broadcastMessage(serverMsg, players);
    560545
    561546         break;
     
    581566         memcpy(serverMsg.buffer, &id, 4);
    582567         memcpy(serverMsg.buffer+4, &targetId, 4);
    583          broadcastMessage(msgProcessor, serverMsg, players);
     568         msgProcessor.broadcastMessage(serverMsg, players);
    584569
    585570         break;
     
    597582            serverMsg.type = MSG_TYPE_JOIN_GAME_FAILURE;
    598583         }else {
    599             Game* g = new Game(gameName, "../data/map.txt");
     584            Game* g = new Game(gameName, "../data/map.txt", &msgProcessor);
    600585            mapGames[gameName] = g;
    601586
     
    611596                        m->addObject(WorldMap::OBJECT_RED_FLAG, x*25+12, y*25+12);
    612597                        break;
     598                     case WorldMap::STRUCTURE_NONE:
     599                        break;
    613600                  }
    614601               }
     
    674661                  flagType = WorldMap::OBJECT_RED_FLAG;
    675662
    676                if (flagType != WorldMap::OBJECT_NONE) {
    677                   addObjectToMap(flagType, p->pos.x, p->pos.y, g->getMap(), g->getPlayers(), msgProcessor);
    678                }
     663               if (flagType != WorldMap::OBJECT_NONE)
     664                  g->addObjectToMap(flagType, p->pos.x, p->pos.y);
    679665            }
    680666
     
    685671            memcpy(serverMsg.buffer, &p->id, 4);
    686672            strcpy(serverMsg.buffer+4, g->getName().c_str());
    687             broadcastMessage(msgProcessor, serverMsg, g->getPlayers());
     673            msgProcessor.broadcastMessage(serverMsg, g->getPlayers());
    688674
    689675            int numPlayers = g->getNumPlayers();
     
    692678            memcpy(serverMsg.buffer, &numPlayers, 4);
    693679            strcpy(serverMsg.buffer+4, g->getName().c_str());
    694             broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     680            msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    695681
    696682            // if there are no more players in the game, remove it
     
    751737         p->serialize(serverMsg.buffer);
    752738         cout << "Should be broadcasting the message" << endl;
    753          broadcastMessage(msgProcessor, serverMsg, g->getPlayers());
     739         msgProcessor.broadcastMessage(serverMsg, g->getPlayers());
    754740
    755741         g->addPlayer(p);
     
    777763         memcpy(serverMsg.buffer, &numPlayers, 4);
    778764         strcpy(serverMsg.buffer+4, gameName.c_str());
    779          broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     765         msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    780766
    781767         break;
     
    791777         break;
    792778      }
    793    }
    794 }
    795 
    796 bool handleGameEvents(Game* game, map<unsigned int, Player*>& mapPlayers, MessageProcessor& msgProcessor) {
    797    NETWORK_MSG serverMsg;
    798    map<unsigned int, Player*>::iterator it;
    799    bool gameFinished = false;
    800 
    801    for (it = game->getPlayers().begin(); it != game->getPlayers().end(); it++)
    802    {
    803       gameFinished = gameFinished ||
    804          handlePlayerEvents(it->second, game, msgProcessor);
    805    }
    806 
    807    // set each player's current game to null
    808    if (gameFinished) {
    809       // send a GAME_INFO message with 0 players to force clients to delete the game
    810       int numPlayers = 0;
    811       serverMsg.type = MSG_TYPE_GAME_INFO;
    812       memcpy(serverMsg.buffer, &numPlayers, 4);
    813       strcpy(serverMsg.buffer+4, game->getName().c_str());
    814       broadcastMessage(msgProcessor, serverMsg, mapPlayers);
    815 
    816       for (it = game->getPlayers().begin(); it != game->getPlayers().end(); it++)
    817       {
    818          it->second->currentGame = NULL;
    819       }
    820    }
    821 
    822    return gameFinished;
    823 }
    824 
    825 bool handlePlayerEvents(Player* p, Game* game, MessageProcessor& msgProcessor) {
    826    NETWORK_MSG serverMsg;
    827    WorldMap* gameMap = game->getMap();
    828    map<unsigned int, Player*>& playersInGame = game->getPlayers();
    829    bool gameFinished = false;
    830    FLOAT_POSITION oldPos;
    831 
    832    cout << "moving player" << endl;
    833    bool broadcastMove = false;
    834 
    835    // move player and perform associated tasks
    836    oldPos = p->pos;
    837    if (p->move(gameMap)) {
    838 
    839       cout << "player moved" << endl;
    840       if (game->processPlayerMovement(p, oldPos))
    841          broadcastMove = true;
    842       cout << "player move processed" << endl;
    843 
    844       WorldMap::ObjectType flagType;
    845       POSITION pos;
    846       bool flagTurnedIn = false;
    847       bool flagReturned = false;
    848       bool ownFlagAtBase = false;
    849 
    850       // need to figure out how to move this to a different file
    851       // while still sending back flag type and position
    852       switch(gameMap->getStructure(p->pos.x/25, p->pos.y/25))
    853       {
    854          case WorldMap::STRUCTURE_BLUE_FLAG:
    855          {
    856             if (p->team == 0 && p->hasRedFlag)
    857             {
    858                // check that your flag is at your base
    859                pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
    860                            
    861                vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
    862                vector<WorldMap::Object>::iterator itObjects;
    863 
    864                for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
    865                {
    866                   if (itObjects->type == WorldMap::OBJECT_BLUE_FLAG)
    867                   {
    868                      if (itObjects->pos.x == pos.x*25+12 && itObjects->pos.y == pos.y*25+12)
    869                      {
    870                         ownFlagAtBase = true;
    871                         break;
    872                      }
    873                   }
    874                }
    875 
    876                if (ownFlagAtBase)
    877                {
    878                   p->hasRedFlag = false;
    879                   flagType = WorldMap::OBJECT_RED_FLAG;
    880                   pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
    881                   flagTurnedIn = true;
    882                   game->setBlueScore(game->getBlueScore()+1);
    883                }
    884             }
    885 
    886             break;
    887          }
    888          case WorldMap::STRUCTURE_RED_FLAG:
    889          {
    890             if (p->team == 1 && p->hasBlueFlag)
    891             {
    892                // check that your flag is at your base
    893                pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
    894                        
    895                vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
    896                vector<WorldMap::Object>::iterator itObjects;
    897 
    898                for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
    899                {
    900                   if (itObjects->type == WorldMap::OBJECT_RED_FLAG)
    901                   {
    902                      if (itObjects->pos.x == pos.x*25+12 && itObjects->pos.y == pos.y*25+12)
    903                      {
    904                         ownFlagAtBase = true;
    905                         break;
    906                      }
    907                   }
    908                }
    909 
    910                if (ownFlagAtBase)
    911                {
    912                   p->hasBlueFlag = false;
    913                   flagType = WorldMap::OBJECT_BLUE_FLAG;
    914                   pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
    915                   flagTurnedIn = true;
    916                   game->setRedScore(game->getRedScore()+1);
    917                }
    918             }
    919 
    920             break;
    921          }
    922       }
    923 
    924       if (flagTurnedIn)
    925       {
    926          unsigned int blueScore = game->getBlueScore();
    927          unsigned int redScore = game->getRedScore();
    928 
    929          // send an OBJECT message to add the flag back to its spawn point
    930          pos.x = pos.x*25+12;
    931          pos.y = pos.y*25+12;
    932          gameMap->addObject(flagType, pos.x, pos.y);
    933 
    934          serverMsg.type = MSG_TYPE_OBJECT;
    935          gameMap->getObjects()->back().serialize(serverMsg.buffer);
    936          broadcastMessage(msgProcessor, serverMsg, playersInGame);
    937 
    938          serverMsg.type = MSG_TYPE_SCORE;
    939          memcpy(serverMsg.buffer, &blueScore, 4);
    940          memcpy(serverMsg.buffer+4, &redScore, 4);
    941          broadcastMessage(msgProcessor, serverMsg, playersInGame);
    942 
    943          // check to see if the game should end
    944          // move to its own method
    945          if (game->getBlueScore() == 3 || game->getRedScore() == 3) {
    946             gameFinished = true;
    947 
    948             unsigned int winningTeam;
    949             if (game->getBlueScore() == 3)
    950                winningTeam = 0;
    951             else if (game->getRedScore() == 3)
    952                winningTeam = 1;
    953 
    954             serverMsg.type = MSG_TYPE_FINISH_GAME;
    955 
    956             // I should create an instance of the GameSummary object here and just serialize it into this message
    957             memcpy(serverMsg.buffer, &winningTeam, 4);
    958             memcpy(serverMsg.buffer+4, &blueScore, 4);
    959             memcpy(serverMsg.buffer+8, &redScore, 4);
    960             strcpy(serverMsg.buffer+12, game->getName().c_str());
    961             broadcastMessage(msgProcessor, serverMsg, playersInGame);
    962          }
    963 
    964          // this means a PLAYER message will be sent
    965          broadcastMove = true;
    966       }
    967 
    968       // go through all objects and check if the player is close to one and if its their flag
    969       vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
    970       vector<WorldMap::Object>::iterator itObjects;
    971       POSITION structPos;
    972 
    973       for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
    974       {
    975          POSITION pos = itObjects->pos;
    976 
    977          if (posDistance(p->pos, pos.toFloat()) < 10)
    978          {
    979             if (p->team == 0 &&
    980                 itObjects->type == WorldMap::OBJECT_BLUE_FLAG)
    981             {
    982                structPos = gameMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
    983                flagReturned = true;
    984                break;
    985             }
    986             else if (p->team == 1 &&
    987                      itObjects->type == WorldMap::OBJECT_RED_FLAG)
    988             {
    989                structPos = gameMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
    990                flagReturned = true;
    991                break;
    992             }
    993          }
    994       }
    995 
    996       if (flagReturned)
    997       {
    998          itObjects->pos.x = structPos.x*25+12;
    999          itObjects->pos.y = structPos.y*25+12;
    1000 
    1001          serverMsg.type = MSG_TYPE_OBJECT;
    1002          itObjects->serialize(serverMsg.buffer);
    1003          broadcastMessage(msgProcessor, serverMsg, playersInGame);
    1004       }
    1005 
    1006       if (broadcastMove)
    1007       {
    1008          serverMsg.type = MSG_TYPE_PLAYER;
    1009          p->serialize(serverMsg.buffer);
    1010          broadcastMessage(msgProcessor, serverMsg, playersInGame);
    1011       }
    1012    }
    1013 
    1014    cout << "processing player attack" << endl;
    1015 
    1016    // check if the player's attack animation is complete
    1017    if (p->isAttacking && p->timeAttackStarted+p->attackCooldown <= getCurrentMillis())
    1018    {
    1019       p->isAttacking = false;
    1020       cout << "Attack animation is complete" << endl;
    1021 
    1022       //send everyone an ATTACK message
    1023       cout << "about to broadcast attack" << endl;
    1024 
    1025       if (p->attackType == Player::ATTACK_MELEE)
    1026       {
    1027          cout << "Melee attack" << endl;
    1028 
    1029          Player* target = playersInGame[p->targetPlayer];
    1030          target->takeDamage(p->damage);
    1031 
    1032          if (target->isDead)
    1033          {
    1034             WorldMap::ObjectType flagType = WorldMap::OBJECT_NONE;
    1035             if (target->hasBlueFlag)
    1036                flagType = WorldMap::OBJECT_BLUE_FLAG;
    1037             else if (target->hasRedFlag)
    1038                flagType = WorldMap::OBJECT_RED_FLAG;
    1039 
    1040             if (flagType != WorldMap::OBJECT_NONE) {
    1041                addObjectToMap(flagType, target->pos.x, target->pos.y, gameMap, playersInGame, msgProcessor);
    1042             }
    1043          }
    1044 
    1045          serverMsg.type = MSG_TYPE_PLAYER;
    1046          target->serialize(serverMsg.buffer);
    1047       }
    1048       else if (p->attackType == Player::ATTACK_RANGED)
    1049       {
    1050          cout << "Ranged attack" << endl;
    1051 
    1052          Projectile proj(p->pos.x, p->pos.y, p->targetPlayer, p->damage);
    1053          game->assignProjectileId(&proj);
    1054          game->addProjectile(proj);
    1055 
    1056          int x = p->pos.x;
    1057          int y = p->pos.y;
    1058 
    1059          serverMsg.type = MSG_TYPE_PROJECTILE;
    1060          memcpy(serverMsg.buffer, &proj.id, 4);
    1061          memcpy(serverMsg.buffer+4, &x, 4);
    1062          memcpy(serverMsg.buffer+8, &y, 4);
    1063          memcpy(serverMsg.buffer+12, &p->targetPlayer, 4);
    1064       }
    1065       else
    1066          cout << "Invalid attack type: " << p->attackType << endl;
    1067 
    1068       broadcastMessage(msgProcessor, serverMsg, playersInGame);
    1069    }
    1070 
    1071    return gameFinished;
    1072 }
    1073 
    1074 void broadcastMessage(MessageProcessor &msgProcessor, NETWORK_MSG &serverMsg, map<unsigned int, Player*>& players) {
    1075    map<unsigned int, Player*>::iterator it;
    1076    for (it = players.begin(); it != players.end(); it++) {
    1077       msgProcessor.sendMessage(&serverMsg, &(it->second->addr));
    1078779   }
    1079780}
     
    1112813}
    1113814
    1114 void addObjectToMap(WorldMap::ObjectType objectType, int x, int y, WorldMap* gameMap, map<unsigned int, Player*>& mapPlayers, MessageProcessor &msgProcessor) {
    1115    NETWORK_MSG serverMsg;
    1116 
    1117    gameMap->addObject(objectType, x, y);
    1118 
    1119    serverMsg.type = MSG_TYPE_OBJECT;
    1120    gameMap->getObjects()->back().serialize(serverMsg.buffer);
    1121 
    1122    broadcastMessage(msgProcessor, serverMsg, mapPlayers);
    1123 }
    1124 
    1125815void quit(int sig) {
    1126816   done = true;
Note: See TracChangeset for help on using the changeset viewer.