source: network-game/client/Client/main.cpp@ 8795a38

Last change on this file since 8795a38 was fbcfc35, checked in by dportnoy <dmp1488@…>, 11 years ago

Add the Projectile class to the client project and add a list of projectiles to the client

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