]> jfr.im git - irc/gameservirc.git/blob - gameserv/gameserv.cpp
Added ONE monster lol
[irc/gameservirc.git] / gameserv / gameserv.cpp
1 #include "aClient.h"
2 #include "config.h"
3 #include "extern.h"
4 #include "flags.h"
5 #include "list.h"
6 #include "sockhelp.h"
7
8 #include <cctype>
9 #include <fstream>
10
11 using std::ifstream;
12 using std::ofstream;
13
14 #if defined(HAVE_CRYPT_H)
15
16 #include <crypt.h>
17
18 #elif defined(HAVE_UNISTD_H)
19
20 #include <unistd.h>
21
22 #endif
23
24 List<aClient> players;
25
26 Monster *monsters[LEVELS][MONSTERS]; // Monsters per level. Total = MONSTERS * LEVELS
27 Monster boss; // The boss monster
28
29 Monster *masters[LEVELS]; // A master for each level
30
31 // Database functions
32 int save_gs_dbase();
33 int load_gs_dbase();
34
35 // String functions
36 #ifndef HAVE_STRTOK
37 char *strtok(char *str, const char *delim);
38 #endif
39
40 int stricmp(const char *s1, const char *s2);
41 int strnicmp(const char *s1, const char *s2, size_t len);
42 // String Functions
43
44
45 /********** Password functions **********/
46
47 bool passcmp(char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
48
49 bool check_password(char *name, char *plaintext); // Finds a password for the given name, and checks it with passcmp against the plaintext password given.
50
51 /********** Password functions **********/
52
53
54 /********** GameServ Booleans **********/
55
56 bool is_playing(char *u); // True if the given nickname in the clients list is playing.
57 bool is_playing(aClient *user);
58
59 bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
60 bool is_fighting(aClient *user);
61
62 bool player_fight(char *u); // True if the player is fighting another player.
63 bool player_fight(aClient *user);
64
65 bool master_fight(char *u); // True if the player is fighting their master.
66 bool master_fight(aClient *user);
67
68 /********** GameServ Booleans **********/
69
70 void display_help(char *u, char *file = NULL);
71 void display_monster(char *u);
72 void display_players(char *u);
73 void display_players(aClient *user);
74 long int chartoint(char ch);
75 int isstringnum(char *num);
76 long int pow (int x, int y);
77 long int stringtoint(char *number);
78
79 char *spaces(int len, char *seperator);
80 void refresh(Player *p);
81 void refreshall();
82 void reset(Player *p);
83 void init_masters();
84 void init_monsters();
85 bool load_monsters();
86 void delete_monsters();
87 void delete_masters();
88
89 void do_admin(char *u);
90 void do_attack(char *u);
91 void do_bank(char *u);
92 void do_fight(char *u);
93 void do_heal(char *u);
94 void do_help(char *u);
95 void do_identify(char *u);
96 void do_inventory(char *u);
97 void do_refresh(char *u);
98 void do_register(char *u);
99 void do_list(char *u);
100 void do_master(char *u);
101 void do_play(char *u);
102 void do_quitg(char *u);
103 void do_reset(char *u);
104 void do_run(char *u);
105 void do_stats(char *u);
106 void do_store(char *u);
107 void do_tavern(char *u);
108 void do_use(char *u);
109 void see_master(char *u);
110
111 void showstats(const char *u, const char *nick);
112 void showinventory(aClient *from, aClient *to);
113 void showBankBalance(const char *u);
114 void end_turn(aClient *user);
115
116 #define WNA 16
117 char *weapons[WNA] = { "Fists", "Stick", "Dagger", "Quarterstaff", "Short Sword",
118 "Long Sword", "Silver Spear", "Battle Axe", "The Ragnarok",
119 "Chain Saw", "Poison Sword", "Flame Sword", "Earth Hammer",
120 "Light Saber", "Masamune", "Mystical Sword"};
121
122 char *armors[WNA] = { "Nothing", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor",
123 "Full Body Armor", "Magic Mail", "Graphite Suit", "Steel Suit",
124 "Force Field", "Armor of Light", "Mythril Vest", "DemiGod Armor",
125 "Hades' Cloak", "Dragon Scales", "Adamantium"};
126
127 int prices[WNA - 1] = {200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000,
128 1000000, 4000000, 10000000, 40000000, 100000000, 400000000};
129 int webonus[WNA] = {0, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
130 int arbonus[WNA] = {0, 1, 3, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000};
131
132 int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550};
133 int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200};
134 int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
135
136 void gameserv(char *source, char *buf)
137 {
138 char *cmd;
139 cmd = strtok(buf, " ");
140
141 #ifndef P10
142 source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
143 #endif
144
145 if (cmd[0] == ':')
146 cmd++; // Get rid of that : at the beginning of the :text (command)
147
148 #ifdef DEBUGMODE
149 log("Source: %s Command: %s", source, cmd);
150 #endif
151
152 struct tm *tm;
153 time_t ti;
154 time(&ti);
155 tm = localtime(&ti);
156
157 int curday = tm->tm_mday;
158
159 if (curday != day)
160 {
161 refreshall();
162 day = curday;
163 save_day();
164 }
165
166 if (strnicmp(cmd, "\1PING", 6) == 0)
167 {
168 char *ts;
169 ts = strtok(NULL, "\1");
170 notice(s_GameServ, source, "\1PING %s\1", ts);
171 } else if (stricmp(cmd, "\1VERSION\1") == 0) {
172 notice(s_GameServ, source, "\1VERSION %s %s +devel\1", PACKAGE, VERSION);
173 } else if (stricmp(cmd, "SEARCH") == 0) {
174 cmd = strtok(NULL, " ");
175
176 if (!cmd)
177 notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
178 else
179 do_forest(source);
180
181 } else if (stricmp(cmd, "FIGHT") == 0) {
182 do_fight(source);
183 } else if (stricmp(cmd, "ATTACK") == 0) {
184 do_attack(source);
185 } else if (stricmp(cmd, "RUN") == 0) {
186 do_run(source);
187 } else if (stricmp(cmd, "USE") == 0) {
188 do_use(source);
189 } else if (stricmp(cmd, "HEAL") == 0) {
190 do_heal(source);
191 } else if (stricmp(cmd, "INVENTORY") == 0) {
192 do_inventory(source);
193 } else if (stricmp(cmd, "MASTER") == 0) {
194 do_master(source);
195 } else if (stricmp(cmd, "STORE") == 0) {
196 do_store(source);
197 } else if (stricmp(cmd, "BANK") == 0) {
198 do_bank(source);
199 } else if (stricmp(cmd, "ADMIN") == 0) {
200 do_admin(source);
201 } else if (stricmp(cmd, "REFRESH") == 0) {
202 do_refresh(source);
203 } else if (stricmp(cmd, "RESET") == 0) {
204 do_reset(source);
205 } else if (stricmp(cmd, "TAVERN") == 0) {
206 do_tavern(source);
207 } else if (stricmp(cmd, "LIST") == 0) {
208 do_list(source);
209 #ifdef DEBUGMODE
210 } else if (stricmp(cmd, "PRINT") == 0) {
211 cout << "Printing the clients list:" << endl;
212 clients.print();
213 cout << "\nPrinting the players list:" << endl;
214 players.print();
215 #endif
216 } else if (stricmp(cmd, "REGISTER") == 0) {
217 do_register(source);
218 } else if (stricmp(cmd, "IDENTIFY") == 0) {
219 do_identify(source);
220 } else if (stricmp(cmd, "HELP") == 0) {
221 do_help(source);
222 } else if (stricmp(cmd, "STATS") == 0) {
223 do_stats(source);
224 } else if (stricmp(cmd, "SHUTDOWN") == 0) {
225 aClient *user;
226
227 if (!(user = find(source)))
228 {
229 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
230 log("Error: aClient not found: %s", source);
231 }
232 else if (!isAdmin(user))
233 {
234 notice(s_GameServ, source, "You must be a %S admin to use this command!");
235 }
236 else
237 {
238 save_gs_dbase();
239 #ifdef P10
240 raw("[] SQ %s 0 :leaving: %s used the Shutdown command.", servername, user->getRealNick());
241 #else
242 raw("SQUIT %s :leaving: %s used the Shutdown command.", servername, source);
243 #endif
244 }
245 } else if (stricmp(cmd, "SAVE") == 0) {
246 aClient *user;
247
248 if (!(user = find(source)))
249 {
250 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
251 log("Error: aClient not found: %s", source);
252 }
253 else if (!isAdmin(user))
254 {
255 notice(s_GameServ, source, "You must be a %S admin to use this command!");
256 }
257 else
258 {
259 save_gs_dbase();
260 }
261 } else if (stricmp(cmd, "LOAD") == 0) {
262 aClient *user;
263
264 if (!(user = find(source)))
265 {
266 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
267 log("Error: aClient not found: %s", source);
268 }
269 else if (!isAdmin(user))
270 {
271 notice(s_GameServ, source, "You must be a %S admin to use this command!");
272 }
273 else
274 {
275 char *cmd2 = strtok(NULL, " ");
276 if (!cmd2)
277 {
278 notice(s_GameServ, source, "Loading player data from %s", playerdata);
279 load_gs_dbase();
280 }
281 else if (stricmp(cmd2, "MONSTERS") == 0)
282 {
283 notice(s_GameServ, source, "Loading monster data from %s", monsterdata);
284 load_monsters();
285 }
286 else
287 display_help(source, cmd);
288 }
289 } else if (stricmp(cmd, "RAW") == 0) {
290 aClient *user;
291
292 if (!(user = find(source)))
293 {
294 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
295 log("Error: aClient not found: %s", source);
296 }
297 else if (!isAdmin(user))
298 {
299 notice(s_GameServ, source, "You must be a %S admin to use this command!");
300 }
301 else
302 {
303 char *rest = strtok(NULL, "");
304 raw("%s", rest);
305 }
306 } else {
307 notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd);
308 }
309
310 source--; // Bring the ':' back so we don't leak memory
311 cmd--; // Same thing :)
312 }
313
314 int stricmp(const char *s1, const char *s2)
315 {
316 register int c;
317
318 while ((c = tolower(*s1)) == tolower(*s2)) {
319 if (c == 0)
320 return 0;
321 s1++;
322 s2++;
323 }
324 if (c < tolower(*s2))
325 return -1;
326 return 1;
327 }
328
329 void showstats(const char *u, const char *nick)
330 {
331 aClient *ni, *sender = find(u);
332 char *buf;
333 buf = new char[50];
334 char *space;
335
336
337 if (!(ni = findplayer(nick)))
338 {
339 notice(s_GameServ, u, "%s not found", nick);
340 }
341 else if (ni->stats)
342 {
343 notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name);
344
345 sprintf(buf, "Experience: %ld", ni->stats->exp);
346 space = spaces(strlen(buf), " ");
347 notice(s_GameServ, sender->getNick(), "%s%sLevel: %d", buf, space,
348 ni->stats->level);
349 delete [] space;
350
351 sprintf(buf, "Gold: %ld", ni->stats->gold);
352 space = spaces(strlen(buf), " ");
353 notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, ni->stats->bank);
354 delete [] space;
355
356 notice(s_GameServ, sender->getNick(), "Hit Points: %d of %d", ni->stats->hp,
357 ni->stats->maxhp);
358
359 sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->weapon]);
360 space = spaces(strlen(buf), " ");
361 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
362 buf, space, ni->stats->defense + arbonus[ni->stats->armor]);
363 delete [] space;
364
365 sprintf(buf, "Armor: %s", armors[ni->stats->armor]);
366 space = spaces(strlen(buf), " ");
367 notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
368 weapons[ni->stats->weapon]);
369 delete [] space;
370
371 sprintf(buf, "Forest Fights: %d", ni->stats->forest_fights);
372 space = spaces(strlen(buf), " ");
373 notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->player_fights);
374 delete [] space;
375 }
376 else
377 {
378 notice(s_GameServ, u, "%s is not playing!", ni->stats->name);
379 }
380 delete [] buf;
381 }
382
383 char *spaces(int len, char *seperator)
384 {
385 char *final;
386 final = new char[30];
387 int y;
388 strcpy(final, seperator);
389 for (y = 0; y < 30 - len; y++)
390 strcat(final, seperator);
391 return final;
392 }
393
394 void raw(const char *fmt, ...)
395 {
396 va_list args;
397 char *input;
398 const char *t = fmt;
399 input = new char[1024];
400 va_start(args, fmt);
401 memset(input, 0, sizeof(input)); // Initialize to NULL
402 for (; *t; t++)
403 {
404 if (*t == '%')
405 {
406 switch(*++t) {
407 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
408 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
409 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
410 case 'l':
411 if (*++t == 'd')
412 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
413 }
414 }
415 else
416 {
417 sprintf(input, "%s%c", input, *t);
418 }
419
420 }
421 #ifdef DEBUGMODE
422 log("Input: %s", input);
423 #endif
424
425 sprintf(input, "%s%s", input, "\r\n");
426 sock_puts(sock, input);
427 delete [] input;
428 va_end(args);
429 }
430 /* Send a NOTICE from the given source to the given nick. */
431
432 void notice(const char *source, const char *dest, const char *fmt, ...)
433 {
434 if (fmt[0] == '\0')
435 return;
436
437 va_list args;
438 char *input;
439 const char *t = fmt;
440 input = new char[1024];
441 va_start(args, fmt);
442 if (dest[0] == ':')
443 {
444 dest++;
445
446 #if !defined(P10)
447 sprintf(input, ":%s NOTICE %s :", source, dest);
448 #else
449 sprintf(input, "%s O %s :", gsnum, dest);
450 #endif
451
452 dest--;
453 }
454 else
455 {
456 #if !defined(P10)
457 sprintf(input, ":%s NOTICE %s :", source, dest);
458 #else
459 sprintf(input, "%s O %s :", gsnum, dest);
460 #endif
461 }
462
463 for (; *t; t++)
464 {
465 if (*t == '%')
466 {
467 switch(*++t) {
468 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
469 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
470 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
471 case 'l':
472 if (*++t == 'd')
473 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
474 }
475 }
476 else
477 {
478 sprintf(input, "%s%c", input, *t);
479 }
480
481 }
482 #ifdef DEBUGMODE
483 log("Input: %s", input);
484 #endif
485 sprintf(input, "%s%s", input, "\r\n");
486 sock_puts(sock, input);
487 delete [] input;
488 va_end(args);
489 }
490
491
492 int strnicmp(const char *s1, const char *s2, size_t len)
493 {
494 register int c;
495
496 if (!len)
497 return 0;
498 while ((c = tolower(*s1)) == tolower(*s2) && len > 0) {
499 if (c == 0 || --len == 0)
500 return 0;
501 s1++;
502 s2++;
503 }
504 if (c < tolower(*s2))
505 return -1;
506 return 1;
507 }
508
509 #ifndef HAVE_STRTOK
510 char *strtok(char *str, const char *delim)
511 {
512 static char *current = NULL;
513 char *ret;
514
515 if (str)
516 current = str;
517 if (!current)
518 return NULL;
519 current += strspn(current, delim);
520 ret = *current ? current : NULL;
521 current += strcspn(current, delim);
522 if (!*current)
523 current = NULL;
524 else
525 *current++ = 0;
526 return ret;
527 }
528 #endif
529
530 void do_list(char *u)
531 {
532 ListNode<aClient> *temp;
533 temp = players.First();
534 if (!players.isEmpty())
535 {
536 notice(s_GameServ, u, "People Playing:");
537 while(temp)
538 {
539
540 #ifdef P10
541 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getRealNick(),
542 temp->getData()->stats->name);
543 #else
544 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(),
545 temp->getData()->stats->name);
546 #endif
547
548 temp = temp->Next();
549 }
550 notice(s_GameServ, u, "End of List");
551 }
552 else
553 notice(s_GameServ, u, "No one is playing");
554 }
555
556 void do_register(char *u)
557 {
558 char *password, *name;
559 aClient *user, *p;
560 name = strtok(NULL, " ");
561 password = strtok(NULL, " ");
562
563 static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
564 static char salt[3];
565
566 salt[0] = saltChars[rand() % strlen(saltChars)];
567 salt[1] = saltChars[rand() % strlen(saltChars)];
568 salt[2] = '\0';
569
570 if (!name)
571 {
572 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
573 }
574 else if (!password)
575 {
576 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
577 }
578 else if ((user = find(u)))
579 {
580 p = findplayer(u);
581 if (!user->stats && !p)
582 {
583 user->stats = new Player(user);
584 user->stats->user = user; // Set the backwards pointer
585 strcpy(user->stats->password, crypt(password, salt));
586 strcpy(user->stats->name, name);
587 players.insertAtBack(user);
588 notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name, password);
589 notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!");
590 log("Nickname %s registered player %s.", u, user->stats->name);
591 }
592 else
593 {
594 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
595 }
596 }
597 }
598
599 void do_identify(char *u)
600 {
601 char *password, *name;
602 aClient *user, *p;
603 name = strtok(NULL, " ");
604 password = strtok(NULL, " ");
605 user = find(u);
606 if (!password || !name)
607 {
608 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
609 }
610 else if (!user)
611 {
612 notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, ""));
613 log("Error: aClient not found: %s", u);
614 }
615 else if (!(p = findplayer(name)) || !p->stats)
616 notice(s_GameServ, u, "Player %s not found", name);
617 else if (!check_password(name, password) && !isAdmin(user))
618 {
619 notice(s_GameServ, u, "Password incorrect");
620 }
621 else
622 {
623 if (p->stats->user && !isAdmin(user))
624 {
625 notice(s_GameServ, u, "That player has already identified.");
626 return;
627 }
628 if (!user->stats)
629 {
630 ListNode<aClient> *temp;
631 temp = players.Find(p);
632 if (!temp)
633 {
634 notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s",
635 strtok(NULL, ""));
636 return;
637 }
638 user->stats = new Player(p->stats->name);
639 #ifdef DEBUGMODE
640 log("Setting data for identified");
641 #endif
642 user->stats->setData(p->stats);
643
644 #ifdef DEBUGMODE
645 log("Player Identified");
646 #endif
647
648 temp->setPtr(user);
649
650 notice(s_GameServ, u, "Password Accepted. Identified.");
651
652 }
653 else
654 {
655 notice(s_GameServ, u, "Already identified. Contact a %S admin for help.");
656 }
657 }
658 }
659
660 void do_stats(char *u)
661 {
662 char *nick;
663 aClient *user;
664
665 nick = strtok(NULL, " ");
666
667 if (!nick)
668 {
669 if (!(user = find(u)))
670 {
671 notice(s_GameServ, u, "Fatal Error in do_stats(). Contact a %S admin for help!");
672 log("Error: aClient not found: %s", u);
673 return;
674 }
675 else if (!is_playing(user))
676 {
677 notice(s_GameServ, u, "You're not playing, so you have no stats!");
678 return;
679 }
680 else
681 showstats(u, user->stats->name);
682 }
683 else
684 showstats(u, nick);
685 }
686 void init_masters()
687 {
688 #ifdef DEBUGMODE
689 log("Calling delete_masters()");
690 #endif
691
692 delete_masters();
693
694 #ifdef DEBUGMODE
695 log("Initializing masters");
696 #endif
697
698 for (int x = 0; x < LEVELS; x++)
699 masters[x] = new Monster;
700
701 strcpy(masters[0]->name, "Old Bones");
702 strcpy(masters[0]->weapon, "Dull Sword Cane");
703 masters[0]->strength = 15;
704 masters[0]->gold = 0;
705 masters[0]->exp = 0;
706 masters[0]->maxhp = 30;
707 masters[0]->hp = 30;
708 strcpy(masters[0]->death, "You have done well my student, but the road is long. Use your new strength with humility and honor as you progress in levels!");
709
710 strcpy(masters[1]->name, "Master Chang");
711 strcpy(masters[1]->weapon, "Nanchaku");
712 masters[1]->strength = 30;
713 masters[1]->gold = 0;
714 masters[1]->exp = 0;
715 masters[1]->maxhp = 40;
716 masters[1]->hp = 40;
717 strcpy(masters[1]->death, "You try to make out what Master Chang is saying, but the only thing you catch is something about a grasshopper.");
718
719 strcpy(masters[2]->name, "Chuck Norris");
720 strcpy(masters[2]->weapon, "Ranger Kick");
721 masters[2]->strength = 85;
722 masters[2]->gold = 0;
723 masters[2]->exp = 0;
724 masters[2]->maxhp = 70;
725 masters[2]->hp = 70;
726 strcpy(masters[2]->death, "Be strong, and keep your goals in site. Drink milk, and don't do drugs. One day you may be fighting next to me as a Texas Ranger YEEHAW!");
727
728
729 strcpy(masters[3]->name, "Mr. Miagi");
730 strcpy(masters[3]->weapon, "Petrified Bonsai");
731 masters[3]->strength = 120;
732 masters[3]->gold = 0;
733 masters[3]->exp = 0;
734 masters[3]->maxhp = 120;
735 masters[3]->hp = 120;
736 strcpy(masters[3]->death, "Skill comes from repeating the correct but seemingly mundane actions. Wax ON, wax OFF!");
737
738 strcpy(masters[4]->name, "Jackie Chan");
739 strcpy(masters[4]->weapon, "Kung Fu Kick");
740 masters[4]->strength = 135;
741 masters[4]->gold = 0;
742 masters[4]->exp = 0;
743 masters[4]->maxhp = 200;
744 masters[4]->hp = 200;
745 strcpy(masters[4]->death, "I like to let people talk who like to talk... it's easier to find out how full of it they really are!");
746
747 strcpy(masters[5]->name, "Jet Li");
748 strcpy(masters[5]->weapon, "Motorcycle");
749 masters[5]->strength = 160;
750 masters[5]->gold = 0;
751 masters[5]->exp = 0;
752 masters[5]->maxhp = 400;
753 masters[5]->hp = 400;
754 strcpy(masters[5]->death, "Failure is a fuel for excuses. It's the doing the do, that makes the making.");
755
756
757 strcpy(masters[6]->name, "Muhammad Ali");
758 strcpy(masters[6]->weapon, "Quick Jab");
759 masters[6]->strength = 185;
760 masters[6]->gold = 0;
761 masters[6]->exp = 0;
762 masters[6]->maxhp = 600;
763 masters[6]->hp = 600;
764 strcpy(masters[6]->death, "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up.");
765
766 strcpy(masters[7]->name, "Li Mu Bai");
767 strcpy(masters[7]->weapon, "Green Destiny");
768 masters[7]->strength = 210;
769 masters[7]->gold = 0;
770 masters[7]->exp = 0;
771 masters[7]->maxhp = 800;
772 masters[7]->hp = 800;
773 strcpy(masters[7]->death, "No growth without resistance. No action without reaction. No desire without restraint.");
774
775
776 strcpy(masters[8]->name, "Jimmy Wang Yu");
777 strcpy(masters[8]->weapon, "Flying Guillotine");
778 masters[8]->strength = 275;
779 masters[8]->gold = 0;
780 masters[8]->exp = 0;
781 masters[8]->maxhp = 1200;
782 masters[8]->hp = 1200;
783 strcpy(masters[8]->death, "You have beaten the one armed boxer. Proceed with caution!");
784
785 strcpy(masters[9]->name, "Wong Fei Hung");
786 strcpy(masters[9]->weapon, "Drunken Boxing");
787 masters[9]->strength = 360;
788 masters[9]->gold = 0;
789 masters[9]->exp = 0;
790 masters[9]->maxhp = 1800;
791 masters[9]->hp = 1800;
792 strcpy(masters[9]->death, "Hiccup! Monkey drinks master's wine!");
793
794 strcpy(masters[10]->name, "Bruce Lee");
795 strcpy(masters[10]->weapon, "Fists of fury");
796 masters[10]->strength = 575;
797 masters[10]->gold = 0;
798 masters[10]->exp = 0;
799 masters[10]->maxhp = 2500;
800 masters[10]->hp = 2500;
801 strcpy(masters[10]->death, "You must learn to concentrate. It is like a finger pointing away to the moon... DONT concentrate on the finger, or you will miss all the heavenly glory.");
802 }
803
804 void init_monsters()
805 {
806 #ifdef DEBUGMODE
807 log("Calling delete_monsters");
808 #endif
809
810 delete_monsters();
811
812 for (int x = 0; x < LEVELS; x++)
813 for (int y = 0; y < MONSTERS; y++)
814 monsters[x][y] = new Monster();
815 }
816
817 void delete_monsters()
818 {
819 for (int x = 0; x < LEVELS; x++)
820 for (int y = 0; y < MONSTERS; y++)
821 if (monsters[x][y])
822 delete monsters[x][y];
823 }
824
825 void delete_masters()
826 {
827 for (int x = 0; x < LEVELS; x++)
828 if (masters[x])
829 delete masters[x];
830 }
831
832 void display_monster(char *u)
833 {
834 if (is_playing(u))
835 {
836 aClient *user = find(u);
837 Player *ni = user->stats;
838
839 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->hp);
840 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name, ni->fight->hp);
841 notice(s_GameServ, u, "Here are your commands:");
842 notice(s_GameServ, u, "/msg %S attack");
843 notice(s_GameServ, u, "/msg %S run");
844 notice(s_GameServ, u, "What will you do?");
845 }
846 }
847
848 void display_players(char *u)
849 {
850 if (is_playing(u))
851 {
852 aClient *ni = find(u);
853
854 aClient *battle = ni->stats->battle;
855
856 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->stats->hp);
857 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name,
858 battle->stats->hp);
859 notice(s_GameServ, u, "Here are your commands:");
860 notice(s_GameServ, u, "/msg %S attack");
861 notice(s_GameServ, u, "/msg %S run");
862 notice(s_GameServ, u, "What will you do?");
863 }
864 }
865 void display_players(aClient *user)
866 {
867 char *u = user->getNick();
868 if (is_playing(user) && player_fight(user))
869 {
870 aClient *battle = user->stats->battle;
871 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", user->stats->hp);
872 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name, battle->stats->hp);
873 notice(s_GameServ, u, "Here are your commands:");
874 notice(s_GameServ, u, "/msg %S attack");
875 notice(s_GameServ, u, "/msg %S run");
876 notice(s_GameServ, u, "What will you do?");
877 }
878 }
879
880
881 bool is_playing(char *u)
882 {
883 aClient *user;
884 if (!(user = find(u)))
885 {
886 return false;
887 }
888 else
889 {
890 return user->stats != NULL;
891 }
892 }
893
894 bool is_playing(aClient *user)
895 {
896 return user->stats != NULL && (stricmp(user->getNick(), "!NULL!") != 0);
897 }
898
899 bool is_fighting(char *u)
900 {
901 aClient *user;
902
903 if (!(user = find(u)))
904 {
905 return false;
906 }
907 else if (user->stats)
908 {
909 return user->stats->fight != NULL || user->stats->battle != NULL
910 || user->stats->master != NULL;
911 }
912 else
913 return false;
914 }
915 bool is_fighting(aClient *user)
916 {
917 if (!is_playing(user))
918 return false;
919 else
920 return (user->stats->fight != NULL || user->stats->battle != NULL || user->stats->master != NULL);
921 }
922
923 bool player_fight(char *u)
924 {
925 aClient *user;
926
927 if (!(user = find(u)))
928 return false;
929 else if (user->stats)
930 return user->stats->battle != NULL;
931 else
932 return false;
933 }
934 bool player_fight(aClient *user)
935 {
936 if (!is_fighting(user))
937 return false;
938 else
939 return user->stats->battle != NULL;
940 }
941
942 bool master_fight(char *u)
943 {
944 aClient *user;
945
946 if (!(user = find(u)))
947 return false;
948 else if (user->stats)
949 return user->stats->master != NULL;
950 else
951 return false;
952 }
953 bool master_fight(aClient *user)
954 {
955 if (!is_playing(user))
956 return false;
957 else
958 return user->stats->master != NULL;
959 }
960
961 void do_fight(char *u)
962 {
963 aClient *ni, *battle;
964
965 char *nick = strtok(NULL, " ");
966
967 if (!nick)
968 {
969 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
970 }
971 else if (!(ni = find(u)))
972 {
973 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
974 return;
975 }
976 else if (!(battle = findbyrealnick(nick)))
977 {
978 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
979 return;
980 }
981 else if (!is_playing(ni))
982 {
983 notice(s_GameServ, u, "You are not playing!");
984 return;
985 }
986 /*
987 * Offline fighting not implemented yet.
988 * else if (!(fight = finduser(nick)))
989 * {
990 * ni->stats->battle = battle;
991 * battle->battle = ni;
992 * ni->yourturn = 1;
993 * battle->yourturn = 0;
994 * notice(s_GameServ, u, "You decide to fight %s while they're not online!",
995 * battle->stats->name);
996 * display_players(u);
997 * }
998 */
999 else if (!isAlive(ni->stats))
1000 {
1001 notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!");
1002 return;
1003 }
1004 else if (player_fight(battle))
1005 {
1006 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name);
1007 return;
1008 }
1009 else if (is_fighting(battle))
1010 {
1011 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name);
1012 return;
1013 }
1014 else if (is_playing(ni) && is_playing(battle) && stricmp(ni->stats->name, battle->stats->name) != 0)
1015 {
1016 // Set your battle pointer to the other player
1017 ni->stats->battle = battle;
1018
1019 // Set the other player's battle pointer to you
1020 battle->stats->battle = ni;
1021
1022 // The initiator gets the first move (perhaps this should be 50/50)
1023 setYourTurn(ni->stats);
1024 clearYourTurn(battle->stats);
1025
1026 // Initiate Battle sequence!
1027 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name);
1028 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name);
1029 notice(s_GameServ, battle->getNick(), "%s gets to go first because he initiated!", ni->stats->name);
1030 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name);
1031 display_players(u);
1032 }
1033 }
1034 void do_use(char *u)
1035 {
1036 aClient *user;
1037 Pouch *p;
1038
1039 char *item = strtok(NULL, " ");
1040
1041 if (!item)
1042 {
1043 notice(s_GameServ, u, "SYNTAX: USE ITEM");
1044 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1045 return;
1046 }
1047 else if (!(user = find(u)))
1048 {
1049 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1050 return;
1051 }
1052 else if (!is_playing(user))
1053 {
1054 notice(s_GameServ, u, "You must be playing to use items!");
1055 return;
1056 }
1057
1058 p = &user->stats->inventory;
1059
1060 if (stricmp(item, "HEALTH") == 0)
1061 {
1062 if (p->Healing() <= 0)
1063 {
1064 notice(s_GameServ, u, "You are out of Health Potions!");
1065 return;
1066 }
1067 int oldhealth = user->stats->hp;
1068 notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
1069 notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
1070 user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
1071 notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealth);
1072 p->decHealing();
1073 }
1074 else if (stricmp(item, "STRENGTH") == 0)
1075 {
1076 if (p->Strength() <= 0)
1077 {
1078 notice(s_GameServ, u, "You are out of Strength Potions!");
1079 return;
1080 }
1081 int oldstrength = user->stats->strength;
1082 notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!");
1083 notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!");
1084 user->stats->strength += 1 + rand() % 2; // 1 - 2 Strength Added
1085 notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength);
1086 p->decStrength();
1087 }
1088 else if (stricmp(item, "DEFENSE") == 0)
1089 {
1090 if (p->Defense() <= 0)
1091 {
1092 notice(s_GameServ, u, "You are out of Defense Potions!");
1093 return;
1094 }
1095 int olddefense = user->stats->defense;
1096 notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust.");
1097 notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!");
1098 user->stats->defense += 1 + rand() % 2; // 1 - 2 Defense Added
1099 notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense);
1100 p->decDefense();
1101 }
1102 else if (stricmp(item, "HP") == 0)
1103 {
1104 if (p->HP() <= 0)
1105 {
1106 notice(s_GameServ, u, "You are out of HP Potions!");
1107 return;
1108 }
1109 int oldHP = user->stats->maxhp;
1110 notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid.");
1111 user->stats->maxhp += 1 + rand() % 5; // 1 - 5 Maxhp
1112 notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP);
1113 p->decHP();
1114 }
1115 else
1116 {
1117 notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALTH | STRENGTH | DEFENSE}");
1118 return;
1119 }
1120
1121 end_turn(user); // If they're fighting, end their turn
1122 }
1123 void do_run(char *u)
1124 {
1125 aClient *user;
1126 Player *p, *p2 = NULL;
1127
1128 if (!(user = find(u)))
1129 {
1130 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1131 return;
1132 }
1133
1134 p = user->stats;
1135
1136 if (p->battle)
1137 p2 = p->battle->stats;
1138
1139 if (!is_fighting(user))
1140 notice(s_GameServ, u, "You run in place... try fighting next time.");
1141 else if (!player_fight(user) && !master_fight(user))
1142 {
1143 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name);
1144 delete p->fight;
1145 p->fight = NULL;
1146 }
1147 else if (player_fight(user) && isYourTurn(p))
1148 {
1149 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name);
1150 notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->name);
1151 p2->battle = NULL;
1152 }
1153 else if (player_fight(user) && !isYourTurn(p))
1154 {
1155 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->name);
1156 }
1157 else if (master_fight(user))
1158 {
1159 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name);
1160 }
1161 p->battle = NULL;
1162 }
1163
1164 void end_turn(aClient *user)
1165 {
1166 char *nick, *u = user->getNick();
1167 Monster *fight;
1168 aClient *battle;
1169 int mhit;
1170
1171 nick = new char[strlen(user->getNick()) + 1];
1172
1173 if (!user || !is_playing(user) || !is_fighting(user))
1174 goto endturn;
1175
1176 if (!player_fight(user) && !master_fight(user))
1177 fight = user->stats->fight;
1178 else
1179 fight = user->stats->master;
1180 battle = user->stats->battle;
1181
1182 if (!player_fight(user))
1183 {
1184 // Opponent's Hit
1185 mhit = (fight->strength / 2) +
1186 (rand() % (fight->strength / 2) - (user->stats->defense +
1187 arbonus[user->stats->armor]));
1188 }
1189 else
1190 {
1191 // Opponent's Hit
1192 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1193 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1194 (user->stats->defense + arbonus[user->stats->armor]));
1195 }
1196 if (!player_fight(user))
1197 {
1198
1199 if (mhit > 0)
1200 {
1201 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1202 fight->name, fight->weapon, mhit);
1203 }
1204 else if (mhit <= 0)
1205 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1206
1207 if (mhit >= user->stats->hp)
1208 {
1209 if (!master_fight(user))
1210 {
1211 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1212 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1213 "of your experience!");
1214 user->stats->gold = 0;
1215 user->stats->exp -= (long int)(user->stats->exp * .10);
1216 user->stats->fight = NULL;
1217 clearAlive(user->stats);
1218 goto endturn;
1219 }
1220 else
1221 {
1222 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1223 "until tomorrow to try again", user->stats->master->name);
1224 user->stats->fight = NULL;
1225 user->stats->master = NULL;
1226 goto endturn;
1227 }
1228 }
1229 else
1230 {
1231 if (mhit > 0)
1232 user->stats->hp -= mhit;
1233 display_monster(u);
1234 goto endturn;
1235 }
1236 }
1237 else
1238 {
1239 clearYourTurn(user->stats);
1240 setYourTurn(battle->stats);
1241 display_players(battle);
1242 }
1243 endturn:
1244 delete nick;
1245 }
1246
1247 void do_attack(char *u)
1248 {
1249 int hit, mhit;
1250 aClient *ni, *battle; // The player and perhaps the player they're fighting
1251 Monster *fight; // The monster they may be fighting
1252
1253 if (!(ni = find(u)))
1254 {
1255 notice(s_GameServ, u, "Fatal error in do_attack. Contact a(n) %S admin for help.");
1256 return;
1257 }
1258 else if (!is_playing(ni))
1259 {
1260 notice(s_GameServ, u, "You're not playing!");
1261 return;
1262 }
1263 else if (!is_fighting(ni))
1264 {
1265 notice(s_GameServ, u, "You're not in battle!");
1266 return;
1267 }
1268 else
1269 {
1270 if (!ni->stats->master) // This is not a master fight
1271 fight = ni->stats->fight; // Monster Could be NULL
1272 else // This IS a master fight
1273 fight = ni->stats->master; // Master Could be NULL
1274
1275 battle = ni->stats->battle; // Player Could be NULL
1276
1277 // One has to be !NULL based on the previous else if
1278 // We wouldn't be here if they were all NULL
1279 }
1280
1281 if (!player_fight(ni))
1282 {
1283 // Player's Hit
1284 hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1285 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
1286
1287 // Opponent's Hit
1288 mhit = (fight->strength / 2) +
1289 (rand() % (fight->strength / 2) - (ni->stats->defense +
1290 arbonus[ni->stats->armor]));
1291 }
1292 else
1293 {
1294 // Opponent's Hit
1295 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1296 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1297 (ni->stats->defense + arbonus[ni->stats->armor]));
1298
1299 // Player's Hit
1300 hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1301 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
1302 (battle->stats->defense + arbonus[battle->stats->armor]));
1303 }
1304
1305 if (!player_fight(ni))
1306 {
1307 if (hit > 0)
1308 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
1309 else
1310 notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
1311
1312 if (hit >= fight->hp)
1313 {
1314 if (master_fight(ni))
1315 notice(s_GameServ, u, "You have bested %s!", fight->name);
1316 else
1317 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
1318
1319 notice(s_GameServ, u, "%s", fight->death);
1320 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
1321 fight->exp, fight->gold);
1322
1323 // If your new experience (or gold) will be greater than 2 billion,
1324 // then set your exp to 2bil. (2 billion max)... otherwise add them.
1325 // This could be a problem with overflowing out of the sign bit.
1326 // Unsigned long int maybe? Leave it for now.
1327 ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 :
1328 ni->stats->exp + fight->exp);
1329
1330 ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 :
1331 ni->stats->gold + fight->gold);
1332
1333
1334 if (master_fight(ni))
1335 {
1336 notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
1337 notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
1338 strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
1339
1340 // Increase your level
1341 ni->stats->level++;
1342
1343 // Increase your maximum hit points
1344 ni->stats->maxhp += hpbonus[ni->stats->level - 1];
1345
1346 // Heal the player by setting hp to their max
1347 ni->stats->hp = ni->stats->maxhp;
1348
1349 // Add to your strength
1350 ni->stats->strength += strbonus[ni->stats->level - 1];
1351
1352 // Add to your defensive power
1353 ni->stats->defense += defbonus[ni->stats->level - 1];
1354
1355 // Clear the pointer for your master
1356 ni->stats->master = NULL;
1357 }
1358
1359 // They're dead so remove the pointer
1360 delete ni->stats->fight;
1361 ni->stats->fight = NULL;
1362 ni->stats->master = NULL;
1363
1364 return;
1365 }
1366 else
1367 {
1368 if (hit > 0)
1369 fight->hp -= hit;
1370 if (mhit > 0)
1371 {
1372 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1373 fight->name, fight->weapon, mhit);
1374 }
1375 else if (mhit <= 0)
1376 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1377
1378 if (mhit >= ni->stats->hp)
1379 {
1380 if (!master_fight(ni))
1381 {
1382 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1383 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1384 "of your experience!");
1385 ni->stats->gold = 0;
1386 ni->stats->exp -= (long int)(ni->stats->exp * .10);
1387 ni->stats->fight = NULL;
1388 clearAlive(ni->stats);
1389 return;
1390 }
1391 else
1392 {
1393 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1394 "until tomorrow to try again", ni->stats->master->name);
1395 ni->stats->fight = NULL;
1396 ni->stats->master = NULL;
1397 return;
1398 }
1399 }
1400 else
1401 {
1402 if (mhit > 0)
1403 ni->stats->hp -= mhit;
1404 display_monster(u);
1405 return;
1406 }
1407 }
1408 }
1409 else if (player_fight(ni))
1410 {
1411 /* Offline fighting not available yet
1412 if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
1413 {
1414 if (hit > 0)
1415 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
1416 else
1417 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
1418 if (hit >= battle->stats->hp)
1419 {
1420 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
1421 * notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1422 (long int)(battle->stats->exp * .10), battle->stats->gold);
1423 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1424 {
1425 ni->stats->exp += (long int)(battle->stats->exp * .10);
1426 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1427 }
1428 * else
1429 {
1430 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1431 ni->stats->exp = 2000000000;
1432 }
1433
1434 if (2000000000 - ni->stats->gold > battle->stats->gold)
1435 {
1436 * ni->stats->gold += battle->stats->gold;
1437 battle->stats->gold = 0;
1438 }
1439 else
1440 {
1441 battle->stats->gold = 2000000000 - ni->stats->gold;
1442 ni->stats->gold = 2000000000;
1443 }
1444 * ni->stats->battle->stats->alive = 0;
1445 ni->stats->battle->battle = NULL;
1446 ni->stats->battle = NULL;
1447 return;
1448 }
1449 else
1450 {
1451 if (hit > 0)
1452 * battle->stats->hp -= hit;
1453 if (mhit > 0)
1454 {
1455 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1456 battle->nick, weapons[battle->stats->weapon], mhit);
1457 }
1458 else if (mhit <= 0)
1459 notice(s_GameServ, u, "%s completely misses you!", battle->nick);
1460 *
1461 if (mhit >= ni->stats->hp)
1462 {
1463 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
1464 if (2000000000 - battle->stats->gold > ni->stats->gold)
1465 {
1466 notice(s_GameServ, u, "%s took all your gold!", battle->nick);
1467 battle->stats->gold += ni->stats->gold;
1468 * ni->stats->gold = 0;
1469 }
1470 else
1471 {
1472 notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
1473 battle->nick);
1474 ni->stats->gold -= (2000000000 - battle->stats->gold);
1475 notice(s_GameServ, u, "You were left dead with %d gold.",
1476 * (long int)ni->stats->gold);
1477 battle->stats->gold = 2000000000;
1478 }
1479 ni->stats->battle->battle = NULL;
1480 ni->stats->battle = NULL;
1481 ni->stats->alive = 0;
1482 return;
1483 }
1484 * else
1485 {
1486 if (mhit > 0)
1487 ni->stats->hp -= mhit;
1488 display_players(u);
1489 return;
1490 }
1491 }
1492 }
1493 * end offline fighting */
1494
1495 if (is_playing(battle))
1496 {
1497 if (!isYourTurn(ni->stats))
1498 {
1499 notice(s_GameServ, u, "Please wait until %s decides what to do!",
1500 battle->stats->name);
1501 return;
1502 }
1503 if (hit > 0)
1504 {
1505 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->stats->name, hit);
1506
1507 notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
1508 "\ 2%d\ 2 damage!", ni->stats->name,
1509 weapons[ni->stats->weapon], hit);
1510 clearYourTurn(ni->stats);
1511 setYourTurn(battle->stats);
1512 display_players(battle->getNick());
1513 }
1514 else
1515 {
1516 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->stats->name);
1517 notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name);
1518 clearYourTurn(ni->stats);
1519 setYourTurn(battle->stats);
1520 display_players(battle->getNick());
1521 }
1522 if (hit >= battle->stats->hp)
1523 {
1524 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name);
1525 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1526 (long int)(battle->stats->exp * .10), battle->stats->gold);
1527 notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!",
1528 ni->stats->name);
1529 battle->stats->hp = 0;
1530 clearAlive(battle->stats);
1531
1532 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1533 {
1534 ni->stats->exp += (long int)(battle->stats->exp * .10);
1535 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1536 }
1537 else
1538 {
1539 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1540 ni->stats->exp = 2000000000;
1541 }
1542
1543 if (2000000000 - ni->stats->gold > battle->stats->gold)
1544 {
1545 notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
1546 "all gold on hand!");
1547 ni->stats->gold += battle->stats->gold;
1548 battle->stats->gold = 0;
1549 }
1550 else
1551 {
1552 battle->stats->gold = 2000000000 - ni->stats->gold;
1553 notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
1554
1555 notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
1556 "gold.", ni->stats->name);
1557
1558 notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
1559 "left. All is not lost!", battle->stats->gold);
1560
1561 ni->stats->gold = 2000000000;
1562 }
1563 battle->stats->battle = NULL;
1564 ni->stats->battle = NULL;
1565 return;
1566 }
1567 else
1568 {
1569 if (hit > 0)
1570 battle->stats->hp -= hit;
1571 clearYourTurn(ni->stats);
1572 setYourTurn(battle->stats);
1573 notice(s_GameServ, u, "Please wait while %s decides what to do!",
1574 battle->stats->name);
1575
1576 return;
1577 }
1578 }
1579 }
1580 }
1581
1582 void do_heal(char *u)
1583 {
1584 aClient *ni;
1585 char *amount = strtok(NULL, " ");
1586 int price, num;
1587
1588 if (!amount)
1589 {
1590 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1591 }
1592 else if (!(ni = find(u)))
1593 {
1594 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1595 return;
1596 }
1597 else if (!is_playing(ni))
1598 {
1599 notice(s_GameServ, u, "You aren't playing!");
1600 return;
1601 }
1602 else if (!isAlive(ni->stats))
1603 {
1604 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
1605 return;
1606 }
1607 else if (is_fighting(ni))
1608 {
1609 notice(s_GameServ, u, "You can't heal in battle!");
1610 }
1611 else if (ni->stats->hp >= ni->stats->maxhp)
1612 {
1613 notice(s_GameServ, u, "You don't need healing!");
1614 }
1615 else if (stricmp(amount, "ALL") == 0)
1616 {
1617 price = ni->stats->level * 3;
1618 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
1619 {
1620 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1621 (long int)ni->stats->gold/price, price);
1622 ni->stats->hp += ni->stats->gold / price;
1623 ni->stats->gold %= price;
1624 }
1625 else
1626 {
1627 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1628 "per point.", price);
1629 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
1630 (ni->stats->maxhp - ni->stats->hp),
1631 (price * (ni->stats->maxhp - ni->stats->hp)) );
1632 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1633 ni->stats->hp = ni->stats->maxhp;
1634 }
1635 }
1636 else if (isstringnum(amount))
1637 {
1638 num = stringtoint(amount);
1639 price = ni->stats->level * 3;
1640 if (ni->stats->gold < price * num)
1641 {
1642 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
1643 (long int)ni->stats->gold/price);
1644 }
1645 else if (num <= ni->stats->maxhp - ni->stats->hp)
1646 {
1647 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
1648 num, price);
1649 ni->stats->hp += num;
1650 ni->stats->gold -= num * price;
1651 }
1652 else if (num > ni->stats->maxhp - ni->stats->hp)
1653 {
1654 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1655 "per point.", price);
1656 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
1657 (ni->stats->maxhp - ni->stats->hp));
1658 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1659 ni->stats->hp = ni->stats->maxhp;
1660 }
1661 }
1662 else if (amount[0] == '-')
1663 notice(s_GameServ, u, "You trying to cheat?");
1664 else
1665 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1666 }
1667
1668 int isstringnum(char *num)
1669 {
1670 unsigned int x;
1671 for (x = 0; x < strlen(num); x++)
1672 {
1673 if ((int)num[x] < 48 || (int)num[x] > 57)
1674 return 0;
1675 }
1676 return 1;
1677 }
1678
1679 long int stringtoint(char *number)
1680 {
1681 long int x, len = strlen(number), sum = 0;
1682 if (len == 1)
1683 return chartoint(number[0]);
1684 sum += chartoint(number[len - 1]);
1685 for (x = len - 2; x >= 0; x--)
1686 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
1687 return sum;
1688 }
1689
1690 long int pow(int x, int y)
1691 {
1692 long int value = 0;
1693 int count = 0;
1694 value += x;
1695
1696 if (x != 0 && y != 0)
1697 {
1698 for (count = 1; count <= y - 1; count++)
1699 value *= x;
1700 }
1701 else
1702 return 1;
1703 return value;
1704 }
1705
1706 long int chartoint(char ch)
1707 {
1708 if (int(ch) >= 48 && int(ch) <= 57)
1709 return int(ch) - 48;
1710 else
1711 return 0;
1712 }
1713
1714 int save_gs_dbase()
1715 {
1716 ListNode<aClient> *ptr = players.First();
1717 Player *it;
1718 ofstream outfile;
1719
1720 outfile.open(playerdata);
1721
1722 if (!outfile)
1723 {
1724 log("Error opening %s", playerdata);
1725 return 0;
1726 }
1727
1728 while(ptr)
1729 {
1730 it = ptr->getData()->stats;
1731 outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
1732 << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
1733 << it->armor << ' ' << it->weapon << ' '
1734 << it->forest_fights << ' ' << it->player_fights << ' '
1735 << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
1736 << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl;
1737 ptr = ptr->Next();
1738 }
1739 outfile.close();
1740 return 1;
1741 }
1742
1743 int load_gs_dbase()
1744 {
1745 ifstream infile;
1746 aClient *temp;
1747 Player *p;
1748 char *tempname, *buf, *password;
1749 buf = new char[1023];
1750
1751 infile.open(playerdata);
1752
1753 if (infile.fail())
1754 {
1755 log("Error opening %s", playerdata);
1756 return 0;
1757 }
1758
1759 while (infile.getline(buf, 1024, '\n'))
1760 {
1761 temp = new aClient;
1762 tempname = strtok(buf, " ");
1763 temp->stats = new Player(tempname);
1764 p = temp->stats;
1765
1766 p->level = stringtoint(strtok(NULL, " "));
1767 p->exp = stringtoint(strtok(NULL, " "));
1768 p->gold = stringtoint(strtok(NULL, " "));
1769 p->bank = stringtoint(strtok(NULL, " "));
1770 p->hp = stringtoint(strtok(NULL, " "));
1771 p->maxhp = stringtoint(strtok(NULL, " "));
1772 p->strength = stringtoint(strtok(NULL, " "));
1773 p->defense = stringtoint(strtok(NULL, " "));
1774 p->armor = stringtoint(strtok(NULL, " "));
1775 p->weapon = stringtoint(strtok(NULL, " "));
1776 p->forest_fights = stringtoint(strtok(NULL, " "));
1777 p->player_fights = stringtoint(strtok(NULL, " "));
1778 p->setFlags(stringtoint(strtok(NULL, " ")));
1779
1780 password = strtok(NULL, " ");
1781 strcpy(p->password, password);
1782 temp->setNick("!NULL!");
1783 #ifdef P10
1784 temp->setRealNick("!NULL!");
1785 #endif
1786
1787 p->inventory.reset(); // Set inventory to all 0s
1788 // Old player databases didn't have these three extra values
1789 // If they come up null, leave them to 0 as the default.
1790 // On the next gameserv database save, it will save the values.
1791 tempname = strtok(NULL, " ");
1792 if (tempname)
1793 p->inventory.setHealing(stringtoint(tempname));
1794
1795 tempname = strtok(NULL, " ");
1796 if (tempname)
1797 p->inventory.setStrength(stringtoint(tempname));
1798
1799 tempname = strtok(NULL, " ");
1800 if (tempname)
1801 p->inventory.setDefense(stringtoint(tempname));
1802
1803 tempname = strtok(NULL, " ");
1804 if (tempname)
1805 p->inventory.setHP(stringtoint(tempname));
1806
1807 players.insertAtBack(temp);
1808 delete temp;
1809 }
1810 delete [] buf;
1811 infile.close();
1812 return 1;
1813 }
1814
1815 bool passcmp(char *encrypted, char *plaintext)
1816 {
1817 char salt[3];
1818 char *plaintext2, *plainToencrypt;
1819 bool same = false;
1820
1821 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
1822 strcpy(plaintext2, plaintext);
1823
1824 salt[0] = encrypted[0];
1825 salt[1] = encrypted[1];
1826 salt[3] = '\0';
1827
1828 plainToencrypt = crypt(plaintext2, salt);
1829
1830 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
1831
1832 delete []plaintext2;
1833
1834 return same;
1835 }
1836
1837 bool check_password(char *name, char *plaintext)
1838 {
1839 aClient *client;
1840
1841 if (!(client = findplayer(name)))
1842 return false;
1843 else
1844 {
1845 return passcmp(client->stats->password, plaintext);
1846 }
1847 }
1848
1849 void do_store(char *u)
1850 {
1851 char *cmd = strtok(NULL, " ");
1852 char *item = strtok(NULL, " ");
1853 char *num = strtok(NULL, " ");
1854 char *space;
1855 int wep;
1856 aClient *user;
1857 Player *p;
1858
1859 if (!cmd || !item)
1860 {
1861 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
1862 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
1863 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
1864 }
1865 else if (!(user = find(u)) || !is_playing(user))
1866 notice(s_GameServ, u, "You must be playing to use the store!");
1867 else if (!isAlive(user->stats))
1868 {
1869 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
1870 return;
1871 }
1872 else if (stricmp(cmd, "LIST") == 0)
1873 {
1874 if (stricmp(item, "WEAPONS") == 0)
1875 {
1876 notice(s_GameServ, u, "Welcome to Kain's Armory");
1877 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
1878 for (int x = 1; x < WNA; x++)
1879 {
1880 space = spaces(strlen(weapons[x]), ".");
1881 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
1882 free(space);
1883 }
1884 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
1885 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
1886
1887 }
1888 else if (stricmp(item, "ARMOR") == 0)
1889 {
1890 notice(s_GameServ, u, "Welcome to Kain's Armory");
1891 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
1892 for (int x = 1; x < WNA; x++)
1893 {
1894 space = spaces(strlen(armors[x]), ".");
1895 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
1896 free(space);
1897 }
1898 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
1899 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
1900
1901
1902 }
1903 } else if (stricmp(cmd, "BUY") == 0) {
1904 if (!num)
1905 {
1906 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
1907 return;
1908 }
1909 else if (!isstringnum(num))
1910 {
1911 notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
1912 return;
1913 }
1914 if (stricmp(item, "WEAPON") == 0)
1915 {
1916 wep = stringtoint(num);
1917 if (wep >= WNA || wep < 1)
1918 {
1919 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
1920 return;
1921 }
1922
1923 p = user->stats;
1924
1925 if (p->weapon != 0)
1926 notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
1927 else if (p->gold < prices[wep - 1])
1928 notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
1929 else
1930 {
1931 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
1932 p->weapon = wep;
1933 p->gold -= prices[wep - 1];
1934 }
1935 }
1936 else if (stricmp(item, "ARMOR") == 0)
1937 {
1938 wep = stringtoint(num);
1939 if (wep >= WNA || wep < 1)
1940 {
1941 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
1942 return;
1943 }
1944
1945 p = user->stats;
1946
1947 if (p->armor != 0)
1948 notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
1949 else if (p->gold < prices[wep - 1])
1950 notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
1951 else
1952 {
1953 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
1954 p->armor = wep;
1955 p->gold -= prices[wep - 1];
1956 }
1957 }
1958 }
1959 else if (stricmp(cmd, "SELL" ) == 0)
1960 {
1961 p = user->stats;
1962
1963 if (stricmp(item, "WEAPON") == 0)
1964 {
1965 if (p->weapon == 0)
1966 {
1967 notice(s_GameServ, u, "You want me to chop off your hands?");
1968 return;
1969 }
1970 else if (p->gold == 2000000000)
1971 {
1972 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
1973 p->weapon = 0;
1974 }
1975 else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
1976 {
1977 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
1978 notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
1979 p->gold = 2000000000;
1980 p->weapon = 0;
1981 }
1982 else
1983 {
1984 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
1985 p->gold += (prices[p->weapon - 1] / 2);
1986 p->weapon = 0;
1987 }
1988 }
1989 else if (stricmp(item, "ARMOR") == 0)
1990 {
1991 p = user->stats;
1992
1993 if (p->armor == 0)
1994 {
1995 notice(s_GameServ, u, "I don't think you can be any more naked...");
1996 return;
1997 }
1998 if (p->gold == 2000000000)
1999 {
2000 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2001 p->armor = 0;
2002 }
2003 else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
2004 {
2005 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2006 notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
2007 p->gold = 2000000000;
2008 p->armor = 0;
2009 }
2010 else
2011 {
2012 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
2013 (prices[p->armor - 1] / 2));
2014
2015 p->gold += (prices[p->armor - 1] / 2);
2016 p->armor = 0;
2017 }
2018 }
2019 else
2020 {
2021 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2022 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2023 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2024 }
2025 }
2026 }
2027 void do_inventory(char *u)
2028 {
2029 aClient *user;
2030
2031 if (!(user = find(u)))
2032 {
2033 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2034 return;
2035 }
2036 else if (!is_playing(user))
2037 {
2038 notice(s_GameServ, u, "You must be playing to check your inventory!");
2039 return;
2040 }
2041 showinventory(user, user);
2042 }
2043 void showinventory(aClient *from, aClient *to)
2044 {
2045 char *nick = to->getNick();
2046
2047 if (!to)
2048 to = from;
2049 if (is_playing(from))
2050 {
2051 Pouch *p = &from->stats->inventory;
2052 notice(s_GameServ, nick, "Inventory for %s:", from->stats->name);
2053 notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
2054 notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
2055 notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
2056 notice(s_GameServ, nick, " HP Potions: %d", p->HP());
2057 }
2058 }
2059 void do_tavern(char *u)
2060 {
2061 char *cmd = strtok(NULL, " ");
2062 long int price;
2063
2064 aClient *user;
2065 Player *p;
2066 if (!(user = find(u)))
2067 {
2068 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2069 return;
2070 }
2071 else if (!is_playing(user))
2072 {
2073 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2074 return;
2075 }
2076 else if (is_fighting(user))
2077 {
2078 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2079 return;
2080 }
2081 p = user->stats;
2082 if (!cmd)
2083 {
2084 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
2085 notice(s_GameServ, u, "Your commands:");
2086 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2087 notice(s_GameServ, u, "What'll it be?");
2088 }
2089 else if (stricmp(cmd, "LIST") == 0)
2090 {
2091 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2092 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10));
2093 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10));
2094 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10));
2095 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10));
2096 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2097 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2098 notice(s_GameServ, u, "By something will ya!");
2099 }
2100 else if (stricmp(cmd, "BUY") == 0)
2101 {
2102 char *chnum = strtok(NULL, " ");
2103 int num = stringtoint(chnum);
2104
2105 if (!chnum)
2106 {
2107 notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
2108 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
2109 return;
2110 }
2111 if (num < 1 || num > 4)
2112 {
2113 notice(s_GameServ, u, "Invalid Choice!");
2114 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2115 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10));
2116 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10));
2117 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10));
2118 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10));
2119 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2120 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2121 return;
2122 }
2123 switch(num)
2124 {
2125 case 1:
2126 price = (1000 * p->level) + (p->exp / 10);
2127 if (p->gold >= price)
2128 {
2129 notice(s_GameServ, u, "One healing potion coming right up!");
2130 p->inventory.incHealing();
2131 p->gold -= price;
2132 }
2133 else
2134 notice(s_GameServ, u, "You don't have enough gold!");
2135 break;
2136 case 2:
2137 price = (2050 * p->level) + (p->exp / 10);
2138 if (p->gold >= price)
2139 {
2140 notice(s_GameServ, u, "One strength boost coming right up!");
2141 p->inventory.incStrength();
2142 p->gold -= price;
2143 }
2144 else
2145 notice(s_GameServ, u, "You don't have enough gold!");
2146 break;
2147 case 3:
2148 price = (2000 * p->level) + (p->exp / 10);
2149 if (p->gold >= price)
2150 {
2151 notice(s_GameServ, u, "One defense boost coming right up!");
2152 p->inventory.incDefense();
2153 p->gold -= price;
2154 }
2155 else
2156 notice(s_GameServ, u, "You don't have enough gold!");
2157 break;
2158 case 4:
2159 price = (2300 * p->level) + (p->exp / 10);
2160 if (p->gold >= price)
2161 {
2162 notice(s_GameServ, u, "One HP Potion coming right up!");
2163 p->inventory.incHP();
2164 p->gold -= price;
2165 }
2166 else
2167 notice(s_GameServ, u, "You don't have enough gold!");
2168 break;
2169 default:
2170 notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
2171 break;
2172 }
2173 }
2174 else
2175 {
2176 notice(s_GameServ, u, "Improper Syntax.");
2177 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2178 }
2179 }
2180
2181 void do_bank(char *u)
2182 {
2183 char *cmd = strtok(NULL, " ");
2184 char *amount = strtok(NULL, " ");
2185 char *nick = strtok(NULL, " ");
2186
2187 aClient *user;
2188 Player *p;
2189
2190 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
2191 {
2192 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
2193 notice (s_GameServ, u, "BANK BALANCE");
2194 return;
2195 }
2196
2197 user = find(u);
2198 if (!is_playing(user))
2199 {
2200 notice(s_GameServ, u, "You must be playing to use the bank!");
2201 return;
2202 }
2203 else if (stricmp(cmd, "BALANCE") == 0)
2204 {
2205 showBankBalance(u);
2206 return;
2207 }
2208 else if (!isAlive(user->stats))
2209 {
2210 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2211 return;
2212 }
2213 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2214 {
2215 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2216 return;
2217 }
2218
2219 p = user->stats;
2220
2221 if (stricmp(cmd, "DEPOSIT") == 0)
2222 {
2223 if (p->bank == 2000000000)
2224 {
2225 notice(s_GameServ, u, "Your bank account is full, sire!");
2226 return;
2227 }
2228 else if (stricmp(amount, "ALL") == 0)
2229 {
2230 if (2000000000 - p->bank < p->gold)
2231 {
2232 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2233 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
2234 p->gold -= (2000000000 - p->bank);
2235 p->bank = 2000000000;
2236 showBankBalance(u);
2237 }
2238 else
2239 {
2240 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
2241 p->bank += p->gold;
2242 p->gold = 0;
2243 showBankBalance(u);
2244 }
2245 }
2246 else if (stringtoint(amount) > p->gold)
2247 {
2248 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
2249 showBankBalance(u);
2250 return;
2251 }
2252 else
2253 {
2254 if (2000000000 - p->bank < stringtoint(amount))
2255 {
2256 notice(s_GameServ, u, "You don't have room in your account for that much.");
2257 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
2258 p->gold -= (2000000000 - p->bank);
2259 p->bank = 2000000000;
2260 showBankBalance(u);
2261 }
2262 else
2263 {
2264 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2265 p->bank += stringtoint(amount);
2266 p->gold -= stringtoint(amount);
2267 showBankBalance(u);
2268 }
2269 }
2270 }
2271 else if (stricmp(cmd, "WITHDRAW") == 0)
2272 {
2273 if (p->gold == 2000000000)
2274 {
2275 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
2276 showBankBalance(u);
2277 return;
2278 }
2279 else if (stricmp(amount, "ALL") == 0)
2280 {
2281 if (2000000000 - p->gold < p->bank)
2282 {
2283 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2284 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
2285 p->bank -= (2000000000 - p->gold);
2286 p->gold = 2000000000;
2287 showBankBalance(u);
2288 }
2289 else
2290 {
2291 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
2292 p->gold += p->bank;
2293 p->bank = 0;
2294 showBankBalance(u);
2295 }
2296 }
2297 else if (stringtoint(amount) > p->bank)
2298 {
2299 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
2300 showBankBalance(u);
2301 return;
2302 }
2303 else
2304 {
2305 if (2000000000 - p->gold < stringtoint(amount))
2306 {
2307 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2308 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2309 (2000000000 - p->gold));
2310 p->bank -= (2000000000 - p->gold);
2311 p->gold = 2000000000;
2312 showBankBalance(u);
2313 }
2314 else
2315 {
2316 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2317 p->gold += stringtoint(amount);
2318 p->bank -= stringtoint(amount);
2319 showBankBalance(u);
2320 }
2321 }
2322 }
2323
2324 }
2325
2326 void do_master(char *u)
2327 {
2328 aClient *user;
2329 user = find(u);
2330
2331 if (!user)
2332 {
2333 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2334 return;
2335 }
2336 else if (is_fighting(user))
2337 {
2338 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
2339 return;
2340 }
2341 else if (!isAlive(user->stats))
2342 {
2343 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2344 return;
2345 }
2346 else if (!is_playing(user))
2347 {
2348 notice(s_GameServ, u, "You must be playing to see your master!");
2349 return;
2350 }
2351
2352 char *cmd = strtok(NULL, " ");
2353 Player *p = user->stats;
2354 long int need = 0;
2355
2356 if (seenMaster(p))
2357 {
2358 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
2359 return;
2360 }
2361
2362 if (cmd != NULL)
2363 {
2364 switch(p->level)
2365 {
2366 case 1:
2367 need = 100;
2368 break;
2369 case 2:
2370 need = 400;
2371 break;
2372 case 3:
2373 need = 1000;
2374 break;
2375 case 4:
2376 need = 4000;
2377 break;
2378 case 5:
2379 need = 10000;
2380 break;
2381 case 6:
2382 need = 40000;
2383 break;
2384 case 7:
2385 need = 100000;
2386 break;
2387 case 8:
2388 need = 400000;
2389 break;
2390 case 9:
2391 need = 1000000;
2392 break;
2393 case 10:
2394 need = 4000000;
2395 break;
2396 case 11:
2397 need = 10000000;
2398 break;
2399 case 12:
2400 need = p->exp + 1;
2401 notice(s_GameServ, u, "You are at level 12. You are the master. What's left? The DRAGON!");
2402 break;
2403 default:
2404 need = p->exp + 1; // Unknown level... don't let them fight a fake master!
2405 break;
2406 }
2407 }
2408 else
2409 {
2410 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2411 return;
2412 }
2413
2414 if (stricmp(cmd, "FIGHT") == 0)
2415 {
2416 if (p->exp >= need)
2417 {
2418 setMaster(p);
2419 see_master(u);
2420 }
2421 else
2422 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.", masters[p->level - 1]->name, (need - p->exp));
2423 return;
2424 }
2425 else if (stricmp(cmd, "QUESTION") == 0)
2426 {
2427 if (p->exp >= need)
2428 notice(s_GameServ, u, "%s looks you up and down and decides you are more ready than you will ever be.", masters[p->level - 1]->name);
2429 else
2430 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", masters[p->level - 1]->name, p->name);
2431
2432 return;
2433 }
2434 else
2435 {
2436 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2437 }
2438 }
2439
2440 void see_master(char *u)
2441 {
2442 aClient *user;
2443
2444 if (!(user = find(u)))
2445 {
2446 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2447 return;
2448 }
2449
2450 if (!is_fighting(user) && is_playing(user))
2451 {
2452 Player *p = user->stats;
2453 p->master = new Monster(masters[p->level - 1]);
2454 p->fight = p->master;
2455 display_monster(u); // Since master is the same structure, use this function
2456 }
2457 }
2458
2459 void showBankBalance(const char *u)
2460 {
2461 aClient *user;
2462 Player *p;
2463
2464 if (!(user = find(u)))
2465 return;
2466
2467 p = user->stats;
2468
2469 if (!p)
2470 return;
2471
2472 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->bank, p->gold);
2473
2474 }
2475
2476 void refreshall()
2477 {
2478 ListNode <aClient> *it;
2479 Player *p;
2480
2481 it = players.First();
2482
2483 while (it)
2484 {
2485 p = it->getData()->stats;
2486 refresh(p);
2487 it = it->Next();
2488 }
2489 }
2490
2491 void refresh(Player *p)
2492 {
2493 if (!p)
2494 return;
2495
2496 if (p->hp < p->maxhp)
2497 p->hp = p->maxhp;
2498 p->forest_fights = forestfights;
2499 p->player_fights = 3;
2500 setAlive(p);
2501 clearMaster(p);
2502 }
2503
2504 void do_refresh(char *u)
2505 {
2506 char *nick = strtok(NULL, " ");
2507 aClient *user;
2508
2509 if (!(user = find(u)))
2510 {
2511 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
2512 log("Error: aClient not found: %s", u);
2513 return;
2514 }
2515 else if (!isAdmin(user))
2516 {
2517 notice(s_GameServ, u, "You must be a %S admin to use this command!");
2518 return;
2519 }
2520 if (!nick)
2521 {
2522 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
2523 return;
2524 }
2525 else if (stricmp(nick, "ALL") == 0)
2526 {
2527 notice(s_GameServ, u, "Refreshing everyone's stats!");
2528 refreshall();
2529 }
2530 else if ((user = findbyrealnick(nick)))
2531 {
2532 if (is_playing(user))
2533 {
2534 #ifdef P10
2535 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
2536 #else
2537 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
2538 #endif
2539 refresh(user->stats);
2540 }
2541 else
2542 {
2543 #ifdef P10
2544 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
2545 #else
2546 notice(s_GameServ, u, "%s is not playing.", user->getNick());
2547 #endif
2548 }
2549 }
2550 else
2551 {
2552 notice(s_GameServ, u, "Nick %s not found.", nick);
2553 return;
2554 }
2555 }
2556
2557
2558 void resetall()
2559 {
2560 ListNode <aClient> *it;
2561 Player *p;
2562
2563 it = players.First();
2564
2565 while (it)
2566 {
2567 p = it->getData()->stats;
2568 reset(p);
2569 it = it->Next();
2570 }
2571 }
2572
2573 void reset(Player *p)
2574 {
2575 if (!p)
2576 return;
2577
2578 p->reset();
2579 }
2580
2581 void do_reset(char *u)
2582 {
2583 char *nick = strtok(NULL, " ");
2584 aClient *user;
2585
2586 if (!(user = find(u)))
2587 {
2588 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
2589 log("Error: aClient not found: %s", u);
2590 return;
2591 }
2592 else if (!isAdmin(user))
2593 {
2594 notice(s_GameServ, u, "You must be a %S admin to use this command!");
2595 return;
2596 }
2597 if (!nick)
2598 {
2599 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
2600 return;
2601 }
2602 else if (stricmp(nick, "ALL") == 0)
2603 {
2604 notice(s_GameServ, u, "Resetting everyone's stats!");
2605 resetall();
2606 }
2607 else if ((user = findbyrealnick(nick)))
2608 {
2609 if (is_playing(user))
2610 {
2611 #ifdef P10
2612 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
2613 #else
2614 notice(s_GameServ, u, "Resetting %s.", user->getNick());
2615 #endif
2616 reset(user->stats);
2617 }
2618 else
2619 {
2620 #ifdef P10
2621 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
2622 #else
2623 notice(s_GameServ, u, "%s is not playing.", user->getNick());
2624 #endif
2625 }
2626 }
2627 else
2628 {
2629 notice(s_GameServ, u, "Nick %s not found.", nick);
2630 return;
2631 }
2632 }
2633
2634 void do_help(char *u)
2635 {
2636 char *cmd = strtok(NULL, " ");
2637
2638 display_help(u, cmd);
2639 }
2640
2641 void display_help(char *u, char *file)
2642 {
2643 ifstream infile;
2644 char *buf;
2645
2646 if (!file)
2647 {
2648 infile.open("helpfiles/help");
2649 if (infile.fail())
2650 {
2651 log("Error opening helpfiles/help");
2652 notice(s_GameServ, u, "Error opening helpfiles/help");
2653 return;
2654 }
2655 buf = new char[1024];
2656 while(infile.getline(buf, 1024))
2657 {
2658 // Written this way, it will process %S in the helpfiles
2659 // Instead of notice(s_GameServ, u, "%s", buf);
2660 notice(s_GameServ, u, buf);
2661 }
2662
2663 // Minor recursion
2664 aClient *user = find(u);
2665 if (user && isAdmin(user))
2666 display_help(u, "admin_commands");
2667 }
2668 else
2669 {
2670 char *filename;
2671 filename = new char[strlen(file) + 11];
2672 strcpy(filename, "helpfiles/");
2673 strcat(filename, file);
2674
2675 for (unsigned int x = 10; x < strlen(filename); x++)
2676 filename[x] = tolower(filename[x]);
2677
2678 infile.open(filename);
2679 delete [] filename;
2680 if (infile.fail())
2681 {
2682 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
2683 return;
2684 }
2685 buf = new char[1024];
2686 while(infile.getline(buf, 1024))
2687 {
2688 // Written this way, it will process %S in the helpfiles
2689 // Instead of notice(s_GameServ, u, "%s", buf);
2690 notice(s_GameServ, u, buf);
2691 }
2692 }
2693 infile.close();
2694 delete [] buf;
2695 }
2696
2697 void do_admin(char *u)
2698 {
2699 aClient *user;
2700 char *pass = strtok(NULL, " ");
2701
2702 if (!(user = find(u)))
2703 {
2704 log("Error: aClient not found: %s", u);
2705 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
2706 return;
2707 }
2708 if (!pass)
2709 {
2710 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
2711 return;
2712 }
2713
2714 if (isAdmin(user))
2715 {
2716 notice(s_GameServ, u, "You already have administrator privledges.");
2717 return;
2718 }
2719 else if (strcmp(pass, adminpass) == 0)
2720 {
2721 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
2722 setAdmin(user);
2723 #ifdef P10
2724 log("%s became an administrator.", user->getRealNick());
2725 #else
2726 log("%s became an administrator.", user->getNick());
2727 #endif
2728 }
2729 else
2730 {
2731 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
2732 return;
2733 }
2734 }
2735
2736 bool load_monsters()
2737 {
2738 ifstream infile;
2739 infile.open("monsters.dat");
2740
2741 char *buf;
2742
2743 if (infile.fail())
2744 {
2745 log("Error opening monsters.dat");
2746 return false;
2747 }
2748 init_monsters();
2749 buf = new char[2048];
2750
2751 #ifdef DEBUGMODE
2752 log("Loading monsters from monsters.dat");
2753 #endif
2754
2755 for (int l = 0; l < REALLEVELS; l++)
2756 {
2757 for (int m = 0; m < MONSTERS;)
2758 {
2759 infile.getline(buf, 2048);
2760 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
2761 continue;
2762 else
2763 {
2764 strcpy(monsters[l][m]->name, strtok(buf, "~"));
2765 strcpy(monsters[l][m]->weapon, strtok(NULL, "~"));
2766 monsters[l][m]->strength = stringtoint(strtok(NULL, "~"));
2767 monsters[l][m]->gold = stringtoint(strtok(NULL, "~"));
2768 monsters[l][m]->exp = stringtoint(strtok(NULL, "~"));
2769 monsters[l][m]->maxhp = stringtoint(strtok(NULL, "~"));
2770 monsters[l][m]->hp = monsters[l][m]->maxhp;
2771 strcpy(monsters[l][m]->death, strtok(NULL, ""));
2772 m++;
2773 }
2774 }
2775 }
2776 delete [] buf;
2777 return true;
2778 }