source: network-game/client/Client/main.cpp@ 7c52498

Last change on this file since 7c52498 was 032e550, checked in by dportnoy <dmp1488@…>, 11 years ago

Add some more debug info

  • Property mode set to 100644
File size: 25.1 KB
Line 
1#include "../../common/Compiler.h"
2
3#if defined WINDOWS
4 #include <winsock2.h>
5 #include <WS2tcpip.h>
6#elif defined LINUX
7 #include <sys/types.h>
8 #include <unistd.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <netdb.h>
12 #include <cstring>
13#endif
14
15#include <cstdio>
16#include <cstdlib>
17#include <cmath>
18#include <sys/types.h>
19#include <string>
20#include <iostream>
21#include <sstream>
22#include <map>
23
24#include <allegro5/allegro.h>
25#include <allegro5/allegro_font.h>
26#include <allegro5/allegro_ttf.h>
27#include <allegro5/allegro_primitives.h>
28
29#include "../../common/Message.h"
30#include "../../common/Common.h"
31#include "../../common/WorldMap.h"
32#include "../../common/Player.h"
33#include "../../common/Projectile.h"
34
35#include "Window.h"
36#include "Textbox.h"
37#include "Button.h"
38#include "chat.h"
39
40#ifdef WINDOWS
41 #pragma comment(lib, "ws2_32.lib")
42#endif
43
44using namespace std;
45
46void initWinSock();
47void shutdownWinSock();
48void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole, WorldMap *gameMap, map<unsigned int, Player>& mapPlayers, map<unsigned int, Projectile>& mapProjectiles, unsigned int& curPlayerId, int &scoreBlue, int &scoreRed);
49void drawMap(WorldMap* gameMap);
50void drawPlayers(map<unsigned int, Player>& mapPlayers, ALLEGRO_FONT* font, unsigned int curPlayerId);
51POSITION screenToMap(POSITION pos);
52POSITION mapToScreen(POSITION pos);
53
54// callbacks
55void registerAccount();
56void login();
57void logout();
58void quit();
59void sendChatMessage();
60
61void error(const char *);
62
63const float FPS = 60;
64const int SCREEN_W = 640;
65const int SCREEN_H = 480;
66
67enum STATE {
68 STATE_START,
69 STATE_LOGIN // this means you're already logged in
70};
71
72int state;
73
74bool doexit;
75
76Window* wndLogin;
77Window* wndMain;
78Window* wndCurrent;
79
80Textbox* txtUsername;
81Textbox* txtPassword;
82Textbox* txtChat;
83
84int sock;
85struct sockaddr_in server, from;
86struct hostent *hp;
87NETWORK_MSG msgTo, msgFrom;
88string username;
89chat chatConsole;
90
91int main(int argc, char **argv)
92{
93 ALLEGRO_DISPLAY *display = NULL;
94 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
95 ALLEGRO_TIMER *timer = NULL;
96 bool key[4] = { false, false, false, false };
97 bool redraw = true;
98 doexit = false;
99 map<unsigned int, Player> mapPlayers;
100 map<unsigned int, Projectile> mapProjectiles;
101 unsigned int curPlayerId = -1;
102 int scoreBlue, scoreRed;
103
104 scoreBlue = 0;
105 scoreRed = 0;
106
107 state = STATE_START;
108
109 if(!al_init()) {
110 fprintf(stderr, "failed to initialize allegro!\n");
111 return -1;
112 }
113
114 if (al_init_primitives_addon())
115 cout << "Primitives initialized" << endl;
116 else
117 cout << "Primitives not initialized" << endl;
118
119 al_init_font_addon();
120 al_init_ttf_addon();
121
122 #if defined WINDOWS
123 ALLEGRO_FONT *font = al_load_ttf_font("../pirulen.ttf", 12, 0);
124 #elif defined LINUX
125 ALLEGRO_FONT *font = al_load_ttf_font("pirulen.ttf", 12, 0);
126 #endif
127
128 if (!font) {
129 fprintf(stderr, "Could not load 'pirulen.ttf'.\n");
130 getchar();
131 return -1;
132 }
133
134 if(!al_install_keyboard()) {
135 fprintf(stderr, "failed to initialize the keyboard!\n");
136 return -1;
137 }
138
139 if(!al_install_mouse()) {
140 fprintf(stderr, "failed to initialize the mouse!\n");
141 return -1;
142 }
143
144 timer = al_create_timer(1.0 / FPS);
145 if(!timer) {
146 fprintf(stderr, "failed to create timer!\n");
147 return -1;
148 }
149
150 display = al_create_display(SCREEN_W, SCREEN_H);
151 if(!display) {
152 fprintf(stderr, "failed to create display!\n");
153 al_destroy_timer(timer);
154 return -1;
155 }
156
157 WorldMap* gameMap = WorldMap::loadMapFromFile("../../data/map.txt");
158
159 wndLogin = new Window(0, 0, SCREEN_W, SCREEN_H);
160 wndLogin->addComponent(new Textbox(104, 40, 100, 20, font));
161 wndLogin->addComponent(new Textbox(104, 70, 100, 20, font));
162 wndLogin->addComponent(new Button(22, 100, 90, 20, font, "Register", registerAccount));
163 wndLogin->addComponent(new Button(122, 100, 60, 20, font, "Login", login));
164 wndLogin->addComponent(new Button(540, 10, 80, 20, font, "Quit", quit));
165
166 txtUsername = (Textbox*)wndLogin->getComponent(0);
167 txtPassword = (Textbox*)wndLogin->getComponent(1);
168
169 wndMain = new Window(0, 0, SCREEN_W, SCREEN_H);
170 wndMain->addComponent(new Textbox(95, 40, 525, 20, font));
171 wndMain->addComponent(new Button(95, 70, 160, 20, font, "Send Message", sendChatMessage));
172 wndMain->addComponent(new Button(540, 10, 80, 20, font, "Logout", logout));
173
174 txtChat = (Textbox*)wndMain->getComponent(0);
175
176 wndCurrent = wndLogin;
177
178 event_queue = al_create_event_queue();
179 if(!event_queue) {
180 fprintf(stderr, "failed to create event_queue!\n");
181 al_destroy_display(display);
182 al_destroy_timer(timer);
183 return -1;
184 }
185
186 al_set_target_bitmap(al_get_backbuffer(display));
187
188 al_register_event_source(event_queue, al_get_display_event_source(display));
189 al_register_event_source(event_queue, al_get_timer_event_source(timer));
190 al_register_event_source(event_queue, al_get_keyboard_event_source());
191 al_register_event_source(event_queue, al_get_mouse_event_source());
192
193 al_clear_to_color(al_map_rgb(0,0,0));
194
195 al_flip_display();
196
197 if (argc != 3) {
198 cout << "Usage: server port" << endl;
199 exit(1);
200 }
201
202 initWinSock();
203
204 sock = socket(AF_INET, SOCK_DGRAM, 0);
205 if (sock < 0)
206 error("socket");
207
208 set_nonblock(sock);
209
210 server.sin_family = AF_INET;
211 hp = gethostbyname(argv[1]);
212 if (hp==0)
213 error("Unknown host");
214
215 memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
216 server.sin_port = htons(atoi(argv[2]));
217
218 al_start_timer(timer);
219
220 while(!doexit)
221 {
222 ALLEGRO_EVENT ev;
223
224 al_wait_for_event(event_queue, &ev);
225
226 if(wndCurrent->handleEvent(ev)) {
227 // do nothing
228 }
229 else if(ev.type == ALLEGRO_EVENT_TIMER) {
230 redraw = true; // seems like we should just call a draw function here instead
231 }
232 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
233 doexit = true;
234 }
235 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
236 }
237 else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
238 switch(ev.keyboard.keycode) {
239 case ALLEGRO_KEY_ESCAPE:
240 doexit = true;
241 break;
242 case ALLEGRO_KEY_S: // pickup an item next to you
243 if (state == STATE_LOGIN) {
244 msgTo.type = MSG_TYPE_PICKUP_FLAG;
245 memcpy(msgTo.buffer, &curPlayerId, 4);
246 sendMessage(&msgTo, sock, &server);
247 }
248 break;
249 case ALLEGRO_KEY_D: // drop the current item
250 if (state == STATE_LOGIN) {
251 // find the current player in the player list
252 map<unsigned int, Player>::iterator it;
253 Player* p = NULL;
254 for(it = mapPlayers.begin(); it != mapPlayers.end(); it++)
255 {
256 if (it->second.id == curPlayerId)
257 p = &it->second;
258 }
259
260 if (p != NULL) {
261 int flagType = WorldMap::OBJECT_NONE;
262
263 if (p->hasBlueFlag)
264 flagType = WorldMap::OBJECT_BLUE_FLAG;
265 else if (p->hasRedFlag)
266 flagType = WorldMap::OBJECT_RED_FLAG;
267
268 if (flagType != WorldMap::OBJECT_NONE) {
269 msgTo.type = MSG_TYPE_DROP_FLAG;
270 memcpy(msgTo.buffer, &curPlayerId, 4);
271 sendMessage(&msgTo, sock, &server);
272 }
273 }
274 }
275 break;
276 }
277 }
278 else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
279 if(wndCurrent == wndMain) {
280 if (ev.mouse.button == 1) { // left click
281 msgTo.type = MSG_TYPE_PLAYER_MOVE;
282
283 POSITION pos;
284 pos.x = ev.mouse.x;
285 pos.y = ev.mouse.y;
286 pos = screenToMap(pos);
287
288 if (pos.x != -1)
289 {
290 memcpy(msgTo.buffer, &curPlayerId, 4);
291 memcpy(msgTo.buffer+4, &pos.x, 4);
292 memcpy(msgTo.buffer+8, &pos.y, 4);
293
294 sendMessage(&msgTo, sock, &server);
295 }
296 else
297 cout << "Invalid point: User did not click on the map" << endl;
298 }else if (ev.mouse.button == 2) { // right click
299 map<unsigned int, Player>::iterator it;
300
301 cout << "Detected a right-click" << endl;
302
303 Player* curPlayer;
304 for(it = mapPlayers.begin(); it != mapPlayers.end(); it++)
305 {
306 if (it->second.id == curPlayerId)
307 curPlayer = &it->second;
308 }
309
310 Player* target;
311 for(it = mapPlayers.begin(); it != mapPlayers.end(); it++)
312 {
313 // need to check if the right-click was actually on this player
314 target = &it->second;
315 if (target->id != curPlayerId && target->team != curPlayer->team) {
316 msgTo.type = MSG_TYPE_START_ATTACK;
317 memcpy(msgTo.buffer, &curPlayerId, 4);
318 memcpy(msgTo.buffer+4, &target->id, 4);
319
320 sendMessage(&msgTo, sock, &server);
321 }
322 }
323 }
324 }
325 }
326
327 if (receiveMessage(&msgFrom, sock, &from) >= 0)
328 processMessage(msgFrom, state, chatConsole, gameMap, mapPlayers, mapProjectiles, curPlayerId, scoreBlue, scoreRed);
329
330 if (redraw)
331 {
332 redraw = false;
333
334 wndCurrent->draw(display);
335
336 chatConsole.draw(font, al_map_rgb(255,255,255));
337
338 if(wndCurrent == wndLogin) {
339 al_draw_text(font, al_map_rgb(0, 255, 0), 4, 43, ALLEGRO_ALIGN_LEFT, "Username:");
340 al_draw_text(font, al_map_rgb(0, 255, 0), 1, 73, ALLEGRO_ALIGN_LEFT, "Password:");
341 }
342 else if(wndCurrent == wndMain) {
343 al_draw_text(font, al_map_rgb(0, 255, 0), 4, 43, ALLEGRO_ALIGN_LEFT, "Message:");
344
345 ostringstream ossScoreBlue, ossScoreRed;
346
347 ossScoreBlue << "Blue: " << scoreBlue << endl;
348 ossScoreRed << "Red: " << scoreRed << endl;
349
350 al_draw_text(font, al_map_rgb(0, 255, 0), 330, 80, ALLEGRO_ALIGN_LEFT, ossScoreBlue.str().c_str());
351 al_draw_text(font, al_map_rgb(0, 255, 0), 515, 80, ALLEGRO_ALIGN_LEFT, ossScoreRed.str().c_str());
352
353 // update players
354 map<unsigned int, Player>::iterator it;
355 for (it = mapPlayers.begin(); it != mapPlayers.end(); it++)
356 {
357 it->second.updateTarget(mapPlayers);
358 }
359
360 for (it = mapPlayers.begin(); it != mapPlayers.end(); it++)
361 {
362 it->second.move(gameMap); // ignore return value
363 }
364
365 // update projectile positions
366 map<unsigned int, Projectile>::iterator it2;
367 for (it2 = mapProjectiles.begin(); it2 != mapProjectiles.end(); it2++)
368 {
369 cout << "Update projectile position" << endl;
370 it2->second.move(mapPlayers);
371 }
372
373 drawMap(gameMap);
374 drawPlayers(mapPlayers, font, curPlayerId);
375
376 // draw projectiles
377 for (it2 = mapProjectiles.begin(); it2 != mapProjectiles.end(); it2++)
378 {
379 cout << "Draw projectile" << endl;
380
381 Projectile proj = it2->second;
382
383 FLOAT_POSITION target = mapPlayers[proj.target].pos;
384 float angle = atan2(target.y-proj.pos.toFloat().y, target.x-proj.pos.toFloat().x);
385
386 POSITION start, end;
387 start.x = cos(angle)*15+proj.pos.x;
388 start.y = sin(angle)*15+proj.pos.y;
389 end.x = proj.pos.x;
390 end.y = proj.pos.y;
391
392 start = mapToScreen(start);
393 end = mapToScreen(end);
394
395 al_draw_line(start.x, start.y, end.x, end.y, al_map_rgb(0, 0, 0), 4);
396 }
397 }
398
399 al_flip_display();
400 }
401 }
402
403 #if defined WINDOWS
404 closesocket(sock);
405 #elif defined LINUX
406 close(sock);
407 #endif
408
409 shutdownWinSock();
410
411 delete wndLogin;
412 delete wndMain;
413
414 delete gameMap;
415
416 al_destroy_event_queue(event_queue);
417 al_destroy_display(display);
418 al_destroy_timer(timer);
419
420 return 0;
421}
422
423// need to make a function like this that works on windows
424void error(const char *msg)
425{
426 perror(msg);
427 shutdownWinSock();
428 exit(1);
429}
430
431void initWinSock()
432{
433#if defined WINDOWS
434 WORD wVersionRequested;
435 WSADATA wsaData;
436 int wsaerr;
437
438 wVersionRequested = MAKEWORD(2, 2);
439 wsaerr = WSAStartup(wVersionRequested, &wsaData);
440
441 if (wsaerr != 0) {
442 cout << "The Winsock dll not found." << endl;
443 exit(1);
444 }else
445 cout << "The Winsock dll was found." << endl;
446#endif
447}
448
449void shutdownWinSock()
450{
451#if defined WINDOWS
452 WSACleanup();
453#endif
454}
455
456POSITION screenToMap(POSITION pos)
457{
458 pos.x = pos.x-300;
459 pos.y = pos.y-100;
460
461 if (pos.x < 0 || pos.y < 0)
462 {
463 pos.x = -1;
464 pos.y = -1;
465 }
466
467 return pos;
468}
469
470POSITION mapToScreen(POSITION pos)
471{
472 pos.x = pos.x+300;
473 pos.y = pos.y+100;
474
475 return pos;
476}
477
478POSITION mapToScreen(FLOAT_POSITION pos)
479{
480 POSITION p;
481 p.x = pos.x+300;
482 p.y = pos.y+100;
483
484 return p;
485}
486
487void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole, WorldMap *gameMap, map<unsigned int, Player>& mapPlayers, map<unsigned int, Projectile>& mapProjectiles, unsigned int& curPlayerId, int &scoreBlue, int &scoreRed)
488{
489 string response = string(msg.buffer);
490
491 switch(state)
492 {
493 case STATE_START:
494 {
495 cout << "In STATE_START" << endl;
496
497 switch(msg.type)
498 {
499 case MSG_TYPE_REGISTER:
500 {
501 break;
502 }
503 case MSG_TYPE_LOGIN:
504 {
505 if (response.compare("Player has already logged in.") == 0)
506 {
507 username.clear();
508 cout << "User login failed" << endl;
509 }
510 else if (response.compare("Incorrect username or password") == 0)
511 {
512 username.clear();
513 cout << "User login failed" << endl;
514 }
515 else
516 {
517 state = STATE_LOGIN;
518 wndCurrent = wndMain;
519
520 Player p("", "");
521 p.deserialize(msg.buffer);
522 mapPlayers[p.id] = p;
523 curPlayerId = p.id;
524
525 cout << "Got a valid login response with the player" << endl;
526 cout << "Player id: " << curPlayerId << endl;
527 cout << "map size: " << mapPlayers.size() << endl;
528 }
529
530 break;
531 }
532 case MSG_TYPE_PLAYER: // kind of hacky to put this here
533 {
534 cout << "Got MSG_TYPE_PLAYER message in STATE_START" << endl;
535
536 Player p("", "");
537 p.deserialize(msg.buffer);
538 p.timeLastUpdated = getCurrentMillis();
539 mapPlayers[p.id] = p;
540
541 cout << "new player id: " << p.id << endl;
542 cout << "map size: " << mapPlayers.size() << endl;
543
544 break;
545 }
546 case MSG_TYPE_OBJECT:
547 {
548 cout << "Received OBJECT message in STATE_START." << endl;
549
550 WorldMap::Object o(0, WorldMap::OBJECT_NONE, 0, 0);
551 o.deserialize(msg.buffer);
552 cout << "object id: " << o.id << endl;
553 gameMap->updateObject(o.id, o.type, o.pos.x, o.pos.y);
554
555 break;
556 }
557 }
558
559 break;
560 }
561 case STATE_LOGIN:
562 {
563 switch(msg.type)
564 {
565 case MSG_TYPE_REGISTER:
566 {
567 break;
568 }
569 case MSG_TYPE_LOGIN:
570 {
571 cout << "Got a login message" << endl;
572
573 chatConsole.addLine(response);
574 cout << "Added new line" << endl;
575
576 break;
577 }
578 case MSG_TYPE_LOGOUT:
579 {
580 cout << "Got a logout message" << endl;
581
582 if (response.compare("You have successfully logged out.") == 0)
583 {
584 cout << "Logged out" << endl;
585 state = STATE_START;
586 wndCurrent = wndLogin;
587 }
588
589 break;
590 }
591 case MSG_TYPE_PLAYER:
592 {
593 //cout << "Got MSG_TYPE_PLAYER message in STATE_LOGIN" << endl;
594
595 Player p("", "");
596 p.deserialize(msg.buffer);
597 p.timeLastUpdated = getCurrentMillis();
598 p.isChasing = false;
599 mapPlayers[p.id] = p;
600
601 break;
602 }
603 case MSG_TYPE_PLAYER_MOVE:
604 {
605 cout << "Got a player move message" << endl;
606
607 unsigned int id;
608 int x, y;
609
610 memcpy(&id, msg.buffer, 4);
611 memcpy(&x, msg.buffer+4, 4);
612 memcpy(&y, msg.buffer+8, 4);
613
614 mapPlayers[id].target.x = x;
615 mapPlayers[id].target.y = y;
616
617 break;
618 }
619 case MSG_TYPE_CHAT:
620 {
621 chatConsole.addLine(response);
622
623 break;
624 }
625 case MSG_TYPE_OBJECT:
626 {
627 cout << "Received object message in STATE_LOGIN." << endl;
628
629 WorldMap::Object o(0, WorldMap::OBJECT_NONE, 0, 0);
630 o.deserialize(msg.buffer);
631 gameMap->updateObject(o.id, o.type, o.pos.x, o.pos.y);
632
633 break;
634 }
635 case MSG_TYPE_REMOVE_OBJECT:
636 {
637 cout << "Received REMOVE_OBJECT message!" << endl;
638
639 int id;
640 memcpy(&id, msg.buffer, 4);
641
642 cout << "Removing object with id " << id << endl;
643
644 if (!gameMap->removeObject(id))
645 cout << "Did not remove the object" << endl;
646
647 break;
648 }
649 case MSG_TYPE_SCORE:
650 {
651 memcpy(&scoreBlue, msg.buffer, 4);
652 memcpy(&scoreRed, msg.buffer+4, 4);
653
654 break;
655 }
656 case MSG_TYPE_ATTACK:
657 {
658 cout << "Received ATTACK message" << endl;
659
660 break;
661 }
662 case MSG_TYPE_START_ATTACK:
663 {
664 cout << "Received START_ATTACK message" << endl;
665
666 unsigned int id, targetID;
667 memcpy(&id, msg.buffer, 4);
668 memcpy(&targetID, msg.buffer+4, 4);
669
670 cout << "source id: " << id << endl;
671 cout << "target id: " << targetID << endl;
672
673 Player* source = &mapPlayers[id];
674 source->targetPlayer = targetID;
675 source->isChasing = true;
676
677 break;
678 }
679 case MSG_TYPE_PROJECTILE:
680 {
681 cout << "Received a PROJECTILE message" << endl;
682
683 int id, x, y, targetId;
684
685 memcpy(&id, msg.buffer, 4);
686 memcpy(&x, msg.buffer+4, 4);
687 memcpy(&y, msg.buffer+8, 4);
688 memcpy(&targetId, msg.buffer+12, 4);
689
690 cout << "id: " << id << endl;
691 cout << "x: " << x << endl;
692 cout << "y: " << y << endl;
693 cout << "Target: " << targetId << endl;
694
695 Projectile proj(x, y, targetId, 0);
696 proj.setId(id);
697
698 mapProjectiles[id] = proj;
699
700 break;
701 }
702 case MSG_TYPE_REMOVE_PROJECTILE:
703 {
704 cout << "Received a REMOVE_PROJECTILE message" << endl;
705
706 int id;
707
708 memcpy(&id, msg.buffer, 4);
709
710 mapProjectiles.erase(id);
711
712 break;
713 }
714 default:
715 {
716 cout << "Received an unexpected message type: " << msg.type << endl;
717 }
718 }
719
720 break;
721 }
722 default:
723 {
724 cout << "The state has an invalid value: " << state << endl;
725
726 break;
727 }
728 }
729}
730
731// this should probably be in the WorldMap class
732void drawMap(WorldMap* gameMap)
733{
734 POSITION mapPos;
735 mapPos.x = 0;
736 mapPos.y = 0;
737 mapPos = mapToScreen(mapPos);
738
739 for (int x=0; x<12; x++)
740 {
741 for (int y=0; y<12; y++)
742 {
743 WorldMap::TerrainType el = gameMap->getElement(x, y);
744 WorldMap::StructureType structure = gameMap->getStructure(x, y);
745
746 if (el == WorldMap::TERRAIN_GRASS)
747 al_draw_filled_rectangle(x*25+mapPos.x, y*25+mapPos.y, x*25+25+mapPos.x, y*25+25+mapPos.y, al_map_rgb(0, 255, 0));
748 else if (el == WorldMap::TERRAIN_OCEAN)
749 al_draw_filled_rectangle(x*25+mapPos.x, y*25+mapPos.y, x*25+25+mapPos.x, y*25+25+mapPos.y, al_map_rgb(0, 0, 255));
750 else if (el == WorldMap::TERRAIN_ROCK)
751 al_draw_filled_rectangle(x*25+mapPos.x, y*25+mapPos.y, x*25+25+mapPos.x, y*25+25+mapPos.y, al_map_rgb(100, 100, 0));
752
753 if (structure == WorldMap::STRUCTURE_BLUE_FLAG) {
754 al_draw_circle(x*25+12+mapPos.x, y*25+12+mapPos.y, 12, al_map_rgb(0, 0, 0), 3);
755 //al_draw_filled_rectangle(x*25+5+mapPos.x, y*25+5+mapPos.y, x*25+20+mapPos.x, y*25+20+mapPos.y, al_map_rgb(0, 0, 255));
756 }else if (structure == WorldMap::STRUCTURE_RED_FLAG) {
757 al_draw_circle(x*25+12+mapPos.x, y*25+12+mapPos.y, 12, al_map_rgb(0, 0, 0), 3);
758 //al_draw_filled_rectangle(x*25+5+mapPos.x, y*25+5+mapPos.y, x*25+20+mapPos.x, y*25+20+mapPos.y, al_map_rgb(255, 0, 0));
759 }
760 }
761 }
762
763 for (int x=0; x<12; x++)
764 {
765 for (int y=0; y<12; y++)
766 {
767 vector<WorldMap::Object> vctObjects = gameMap->getObjects(x, y);
768
769 vector<WorldMap::Object>::iterator it;
770 for(it = vctObjects.begin(); it != vctObjects.end(); it++) {
771 switch(it->type) {
772 case WorldMap::OBJECT_BLUE_FLAG:
773 al_draw_filled_rectangle(it->pos.x-8+mapPos.x, it->pos.y-8+mapPos.y, it->pos.x+8+mapPos.x, it->pos.y+8+mapPos.y, al_map_rgb(0, 0, 255));
774 break;
775 case WorldMap::OBJECT_RED_FLAG:
776 al_draw_filled_rectangle(it->pos.x-8+mapPos.x, it->pos.y-8+mapPos.y, it->pos.x+8+mapPos.x, it->pos.y+8+mapPos.y, al_map_rgb(255, 0, 0));
777 break;
778 }
779 }
780 }
781 }
782}
783
784void drawPlayers(map<unsigned int, Player>& mapPlayers, ALLEGRO_FONT* font, unsigned int curPlayerId)
785{
786 map<unsigned int, Player>::iterator it;
787
788 Player* p;
789 POSITION pos;
790 ALLEGRO_COLOR color;
791
792 for(it = mapPlayers.begin(); it != mapPlayers.end(); it++)
793 {
794 p = &it->second;
795 pos = mapToScreen(p->pos);
796
797 if (p->id == curPlayerId)
798 al_draw_filled_circle(pos.x, pos.y, 14, al_map_rgb(0, 0, 0));
799
800 if (p->team == 0)
801 color = al_map_rgb(0, 0, 255);
802 else if (p->team == 1)
803 color = al_map_rgb(255, 0, 0);
804
805 al_draw_filled_circle(pos.x, pos.y, 12, color);
806
807 // draw player class
808 int fontHeight = al_get_font_line_height(font);
809
810 string strClass;
811 switch (p->playerClass) {
812 case Player::CLASS_WARRIOR:
813 strClass = "W";
814 break;
815 case Player::CLASS_RANGER:
816 strClass = "R";
817 break;
818 case Player::CLASS_NONE:
819 strClass = "";
820 break;
821 default:
822 strClass = "";
823 break;
824 }
825 al_draw_text(font, al_map_rgb(0, 0, 0), pos.x, pos.y-fontHeight/2, ALLEGRO_ALIGN_CENTRE, strClass.c_str());
826
827 // draw player health
828 al_draw_filled_rectangle(pos.x-12, pos.y-24, pos.x+12, pos.y-16, al_map_rgb(0, 0, 0));
829 if (it->second.maxHealth != 0)
830 al_draw_filled_rectangle(pos.x-11, pos.y-23, pos.x-11+(22*it->second.health)/it->second.maxHealth, pos.y-17, al_map_rgb(255, 0, 0));
831
832 if (p->hasBlueFlag)
833 al_draw_filled_rectangle(pos.x+4, pos.y-18, pos.x+18, pos.y-4, al_map_rgb(0, 0, 255));
834 else if (p->hasRedFlag)
835 al_draw_filled_rectangle(pos.x+4, pos.y-18, pos.x+18, pos.y-4, al_map_rgb(255, 0, 0));
836 }
837}
838
839void registerAccount()
840{
841 string username = txtUsername->getStr();
842 string password = txtPassword->getStr();
843
844 txtUsername->clear();
845 txtPassword->clear();
846
847 msgTo.type = MSG_TYPE_REGISTER;
848
849 strcpy(msgTo.buffer, username.c_str());
850 strcpy(msgTo.buffer+username.size()+1, password.c_str());
851
852 sendMessage(&msgTo, sock, &server);
853}
854
855void login()
856{
857 string strUsername = txtUsername->getStr();
858 string strPassword = txtPassword->getStr();
859 username = strUsername;
860
861 txtUsername->clear();
862 txtPassword->clear();
863
864 msgTo.type = MSG_TYPE_LOGIN;
865
866 strcpy(msgTo.buffer, strUsername.c_str());
867 strcpy(msgTo.buffer+username.size()+1, strPassword.c_str());
868
869 sendMessage(&msgTo, sock, &server);
870}
871
872void logout()
873{
874 txtChat->clear();
875
876 msgTo.type = MSG_TYPE_LOGOUT;
877
878 strcpy(msgTo.buffer, username.c_str());
879
880 sendMessage(&msgTo, sock, &server);
881}
882
883void quit()
884{
885 doexit = true;
886}
887
888void sendChatMessage()
889{
890 string msg = txtChat->getStr();
891
892 txtChat->clear();
893
894 msgTo.type = MSG_TYPE_CHAT;
895
896 strcpy(msgTo.buffer, msg.c_str());
897
898 sendMessage(&msgTo, sock, &server);
899}
Note: See TracBrowser for help on using the repository browser.