source: network-game/common/Game.cpp@ ea3a3a9

Last change on this file since ea3a3a9 was 85da778, checked in by dportnoy <dmp1488@…>, 10 years ago

Convert the client to use the PlayerTeam enum

  • Property mode set to 100644
File size: 5.4 KB
Line 
1#include "Game.h"
2
3#include <iostream>
4#include <cstring>
5#include <cstdlib>
6
7#include "Common.h"
8
9using namespace std;
10
11Game::Game() {
12 this->id = 0;
13 this->name = "";
14 this->blueScore = 0;
15 this->redScore = 0;
16 this->worldMap = NULL;
17 this->msgProcessor = NULL;
18}
19
20Game::Game(string name, string filepath, MessageProcessor* msgProcessor) {
21 this->id = 0;
22 this->name = name;
23 this->blueScore = 0;
24 this->redScore = 0;
25 this->worldMap = WorldMap::loadMapFromFile(filepath);
26 this->msgProcessor = msgProcessor;
27}
28
29Game::~Game() {
30 delete this->worldMap;
31}
32
33string Game::getName() {
34 return this->name;
35}
36
37int Game::getNumPlayers() {
38 return this->players.size();
39}
40
41map<unsigned int, Player*>& Game::getPlayers() {
42 return this->players;
43}
44
45bool Game::addPlayer(Player* p) {
46 if (players.find(p->getId()) == players.end()) {
47 players[p->getId()] = p;
48
49 // reset player stats, location, etc.
50 p->pos.x = p->target.x = 200;
51 p->pos.y = p->target.y = 200;
52 p->setTargetPlayer(0);
53 p->isChasing = false;
54 p->isAttacking = false;
55 p->isDead = false;
56 p->health = p->maxHealth;
57 p->hasBlueFlag = false;
58 p->hasRedFlag = false;
59
60 p->currentGame = this;
61
62 return true;
63 }
64 else
65 return false;
66}
67
68bool Game::removePlayer(unsigned int id) {
69 if (players.erase(id) == 1)
70 return true;
71 else
72 return false;
73}
74
75map<unsigned int, Projectile>& Game::getProjectiles() {
76 return this->projectiles;
77}
78
79bool Game::addProjectile(Projectile p) {
80 if (projectiles.find(p.id) == projectiles.end()) {
81 projectiles[p.id] = p;
82 return true;
83 }
84 else
85 return false;
86}
87
88bool Game::removeProjectile(unsigned int id) {
89 if (projectiles.erase(id) == 1)
90 return true;
91 else
92 return false;
93}
94
95unsigned int Game::getRedScore() {
96 return this->redScore;
97}
98
99unsigned int Game::getBlueScore() {
100 return this->blueScore;
101}
102
103WorldMap* Game::getMap() {
104 return this->worldMap;
105}
106
107void Game::setId(unsigned int id) {
108 this->id = id;
109}
110
111void Game::setRedScore(unsigned int score) {
112 this->redScore = score;
113}
114
115void Game::setBlueScore(unsigned int score) {
116 this->blueScore = score;
117}
118
119void Game::addObjectToMap(ObjectType objectType, int x, int y) {
120 NETWORK_MSG serverMsg;
121
122 this->getMap()->addObject(objectType, x, y);
123
124 serverMsg.type = MSG_TYPE_OBJECT;
125 this->worldMap->getObjects()->back().serialize(serverMsg.buffer);
126
127 this->msgProcessor->broadcastMessage(serverMsg, this->players);
128}
129
130bool Game::startPlayerMovement(unsigned int id, int x, int y) {
131 // need to check if players actually contains the id
132 Player* p = players[id];
133
134 // we need to make sure the player can move here
135 if (0 <= x && x < this->worldMap->width*25 &&
136 0 <= y && y < this->worldMap->height*25 &&
137 this->worldMap->getElement(x/25, y/25) == TERRAIN_GRASS)
138 {
139 p->target.x = x;
140 p->target.y = y;
141
142 p->isChasing = false;
143 p->isAttacking = false;
144 p->setTargetPlayer(0);
145
146 return true;
147 }
148 else
149 return false;
150}
151
152// returns true if the movement should be canceled
153bool Game::processPlayerMovement(Player* p, FLOAT_POSITION oldPos) {
154
155 // check if the move needs to be canceled
156 switch(this->worldMap->getElement(p->pos.x/25, p->pos.y/25))
157 {
158 case TERRAIN_NONE:
159 case TERRAIN_OCEAN:
160 case TERRAIN_ROCK:
161 {
162 p->pos = oldPos;
163 p->target.x = p->pos.x;
164 p->target.y = p->pos.y;
165 p->isChasing = false;
166 return true;
167 break;
168 }
169 default:
170 // if there are no obstacles, don't cancel movement
171 return false;
172 break;
173 }
174}
175
176// returns the id of the picked-up flag or -1 if none was picked up
177int Game::processFlagPickupRequest(Player* p) {
178 vector<WorldMap::Object>* vctObjects = this->worldMap->getObjects();
179 vector<WorldMap::Object>::iterator it;
180 int itemId = -1;
181
182 for (it = vctObjects->begin(); it != vctObjects->end(); it++) {
183 if (posDistance(p->pos, it->pos.toFloat()) < 10) {
184 switch (it->type) {
185 case OBJECT_BLUE_FLAG:
186 if (p->team == Player::TEAM_RED) {
187 p->hasBlueFlag = true;
188 itemId = it->id;
189 }
190 break;
191 case OBJECT_RED_FLAG:
192 if (p->team == Player::TEAM_BLUE) {
193 p->hasRedFlag = true;
194 itemId = it->id;
195 }
196 break;
197 case OBJECT_NONE:
198 break;
199 }
200
201 if (itemId > -1) {
202 vctObjects->erase(it);
203 return itemId;
204 }
205 }
206 }
207
208 return itemId;
209}
210
211void Game::dealDamageToPlayer(Player* p, int damage) {
212 p->takeDamage(damage);
213
214 if (p->isDead) {
215 ObjectType flagType = OBJECT_NONE;
216 if (p->hasBlueFlag)
217 flagType = OBJECT_BLUE_FLAG;
218 else if (p->hasRedFlag)
219 flagType = OBJECT_RED_FLAG;
220
221 if (flagType != OBJECT_NONE)
222 this->addObjectToMap(flagType, p->pos.x, p->pos.y);
223 }
224
225 // send a PLAYER message after dealing damage
226 NETWORK_MSG serverMsg;
227 serverMsg.type = MSG_TYPE_PLAYER;
228 p->serialize(serverMsg.buffer);
229 msgProcessor->broadcastMessage(serverMsg, this->players);
230}
231
232void Game::assignProjectileId(Projectile* p) {
233 p->id = unusedProjectileId;
234 updateUnusedProjectileId();
235}
236
237void Game::updateUnusedProjectileId() {
238 while (projectiles.find(unusedProjectileId) != projectiles.end())
239 unusedProjectileId++;
240}
Note: See TracBrowser for help on using the repository browser.