]> jfr.im git - irc/gameservirc.git/blob - gameserv/gameserv.cpp
TODO update, we've already got cheaters
[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] = {1, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
130 int arbonus[WNA] = {1, 2, 4, 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 (!isAlive(battle->stats))
1005 {
1006 notice(s_GameServ, u, "They are dead. Cannot fight dead players!");
1007 return;
1008 }
1009 else if (player_fight(battle))
1010 {
1011 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name);
1012 return;
1013 }
1014 else if (is_fighting(battle))
1015 {
1016 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name);
1017 return;
1018 }
1019 else if (is_playing(ni) && is_playing(battle) && stricmp(ni->stats->name, battle->stats->name) != 0)
1020 {
1021 // Set your battle pointer to the other player
1022 ni->stats->battle = battle;
1023
1024 // Set the other player's battle pointer to you
1025 battle->stats->battle = ni;
1026
1027 // The initiator gets the first move (perhaps this should be 50/50)
1028 setYourTurn(ni->stats);
1029 clearYourTurn(battle->stats);
1030
1031 // Initiate Battle sequence!
1032 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name);
1033 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name);
1034 notice(s_GameServ, battle->getNick(), "%s gets to go first because he initiated!", ni->stats->name);
1035 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name);
1036 display_players(u);
1037 }
1038 }
1039 void do_use(char *u)
1040 {
1041 aClient *user;
1042 Pouch *p;
1043
1044 char *item = strtok(NULL, " ");
1045
1046 if (!item)
1047 {
1048 notice(s_GameServ, u, "SYNTAX: USE ITEM");
1049 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1050 return;
1051 }
1052 else if (!(user = find(u)))
1053 {
1054 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1055 return;
1056 }
1057 else if (!is_playing(user))
1058 {
1059 notice(s_GameServ, u, "You must be playing to use items!");
1060 return;
1061 }
1062
1063 p = &user->stats->inventory;
1064
1065 if (stricmp(item, "HEALTH") == 0)
1066 {
1067 if (p->Healing() <= 0)
1068 {
1069 notice(s_GameServ, u, "You are out of Health Potions!");
1070 return;
1071 }
1072 int oldhealth = user->stats->hp;
1073 notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
1074 notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
1075 user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
1076 notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealth);
1077 p->decHealing();
1078 }
1079 else if (stricmp(item, "STRENGTH") == 0)
1080 {
1081 if (p->Strength() <= 0)
1082 {
1083 notice(s_GameServ, u, "You are out of Strength Potions!");
1084 return;
1085 }
1086 int oldstrength = user->stats->strength;
1087 notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!");
1088 notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!");
1089 user->stats->strength += 1 + rand() % 2; // 1 - 2 Strength Added
1090 notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength);
1091 p->decStrength();
1092 }
1093 else if (stricmp(item, "DEFENSE") == 0)
1094 {
1095 if (p->Defense() <= 0)
1096 {
1097 notice(s_GameServ, u, "You are out of Defense Potions!");
1098 return;
1099 }
1100 int olddefense = user->stats->defense;
1101 notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust.");
1102 notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!");
1103 user->stats->defense += 1 + rand() % 2; // 1 - 2 Defense Added
1104 notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense);
1105 p->decDefense();
1106 }
1107 else if (stricmp(item, "HP") == 0)
1108 {
1109 if (p->HP() <= 0)
1110 {
1111 notice(s_GameServ, u, "You are out of HP Potions!");
1112 return;
1113 }
1114 int oldHP = user->stats->maxhp;
1115 notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid.");
1116 user->stats->maxhp += 1 + rand() % 5; // 1 - 5 Maxhp
1117 notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP);
1118 p->decHP();
1119 }
1120 else
1121 {
1122 notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALTH | STRENGTH | DEFENSE}");
1123 return;
1124 }
1125
1126 end_turn(user); // If they're fighting, end their turn
1127 }
1128 void do_run(char *u)
1129 {
1130 aClient *user;
1131 Player *p, *p2 = NULL;
1132
1133 if (!(user = find(u)))
1134 {
1135 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1136 return;
1137 }
1138
1139 else if (!is_playing(user))
1140 {
1141 notice(s_GameServ, u, "You must be playing to run!");
1142 return;
1143 }
1144
1145 p = user->stats;
1146
1147 if (p->battle)
1148 p2 = p->battle->stats;
1149
1150 if (!is_fighting(user))
1151 notice(s_GameServ, u, "You run in place... try fighting next time.");
1152 else if (!player_fight(user) && !master_fight(user))
1153 {
1154 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name);
1155 delete p->fight;
1156 p->fight = NULL;
1157 }
1158 else if (player_fight(user) && isYourTurn(p))
1159 {
1160 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name);
1161 notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->name);
1162 p2->battle = NULL;
1163 }
1164 else if (player_fight(user) && !isYourTurn(p))
1165 {
1166 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->name);
1167 }
1168 else if (master_fight(user))
1169 {
1170 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name);
1171 }
1172 p->battle = NULL;
1173 }
1174
1175 void end_turn(aClient *user)
1176 {
1177 char *nick, *u = user->getNick();
1178 Monster *fight;
1179 aClient *battle;
1180 int mhit;
1181
1182 nick = new char[strlen(user->getNick()) + 1];
1183
1184 if (!user || !is_playing(user) || !is_fighting(user))
1185 goto endturn;
1186
1187 if (!player_fight(user) && !master_fight(user))
1188 fight = user->stats->fight;
1189 else
1190 fight = user->stats->master;
1191 battle = user->stats->battle;
1192
1193 if (!player_fight(user))
1194 {
1195 // Opponent's Hit
1196 mhit = (fight->strength / 2) +
1197 (rand() % (fight->strength / 2) - (user->stats->defense +
1198 arbonus[user->stats->armor]));
1199 }
1200 else
1201 {
1202 // Opponent's Hit
1203 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1204 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1205 (user->stats->defense + arbonus[user->stats->armor]));
1206 }
1207 if (!player_fight(user))
1208 {
1209
1210 if (mhit > 0)
1211 {
1212 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1213 fight->name, fight->weapon, mhit);
1214 }
1215 else if (mhit <= 0)
1216 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1217
1218 if (mhit >= user->stats->hp)
1219 {
1220 if (!master_fight(user))
1221 {
1222 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1223 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1224 "of your experience!");
1225 user->stats->gold = 0;
1226 user->stats->exp -= (long int)(user->stats->exp * .10);
1227 user->stats->fight = NULL;
1228 clearAlive(user->stats);
1229 goto endturn;
1230 }
1231 else
1232 {
1233 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1234 "until tomorrow to try again", user->stats->master->name);
1235 user->stats->fight = NULL;
1236 user->stats->master = NULL;
1237 goto endturn;
1238 }
1239 }
1240 else
1241 {
1242 if (mhit > 0)
1243 user->stats->hp -= mhit;
1244 display_monster(u);
1245 goto endturn;
1246 }
1247 }
1248 else
1249 {
1250 clearYourTurn(user->stats);
1251 setYourTurn(battle->stats);
1252 display_players(battle);
1253 }
1254 endturn:
1255 delete nick;
1256 }
1257
1258 void do_attack(char *u)
1259 {
1260 int hit, mhit;
1261 aClient *ni, *battle; // The player and perhaps the player they're fighting
1262 Monster *fight; // The monster they may be fighting
1263
1264 if (!(ni = find(u)))
1265 {
1266 notice(s_GameServ, u, "Fatal error in do_attack. Contact a(n) %S admin for help.");
1267 return;
1268 }
1269 else if (!is_playing(ni))
1270 {
1271 notice(s_GameServ, u, "You're not playing!");
1272 return;
1273 }
1274 else if (!is_fighting(ni))
1275 {
1276 notice(s_GameServ, u, "You're not in battle!");
1277 return;
1278 }
1279 else
1280 {
1281 if (!ni->stats->master) // This is not a master fight
1282 fight = ni->stats->fight; // Monster Could be NULL
1283 else // This IS a master fight
1284 fight = ni->stats->master; // Master Could be NULL
1285
1286 battle = ni->stats->battle; // Player Could be NULL
1287
1288 // One has to be !NULL based on the previous else if
1289 // We wouldn't be here if they were all NULL
1290 }
1291
1292 if (!player_fight(ni))
1293 {
1294 // Player's Hit
1295 hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1296 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
1297
1298 // Opponent's Hit
1299 mhit = (fight->strength / 2) +
1300 (rand() % (fight->strength / 2) - (ni->stats->defense +
1301 arbonus[ni->stats->armor]));
1302 }
1303 else
1304 {
1305 // Opponent's Hit
1306 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1307 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1308 (ni->stats->defense + arbonus[ni->stats->armor]));
1309
1310 // Player's Hit
1311 hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1312 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
1313 (battle->stats->defense + arbonus[battle->stats->armor]));
1314 }
1315
1316 if (!player_fight(ni))
1317 {
1318 if (hit > 0)
1319 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
1320 else
1321 notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
1322
1323 if (hit >= fight->hp)
1324 {
1325 if (master_fight(ni))
1326 notice(s_GameServ, u, "You have bested %s!", fight->name);
1327 else
1328 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
1329
1330 notice(s_GameServ, u, "%s", fight->death);
1331 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
1332 fight->exp, fight->gold);
1333
1334 // If your new experience (or gold) will be greater than 2 billion,
1335 // then set your exp to 2bil. (2 billion max)... otherwise add them.
1336 // This could be a problem with overflowing out of the sign bit.
1337 // Unsigned long int maybe? Leave it for now.
1338 ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 :
1339 ni->stats->exp + fight->exp);
1340
1341 ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 :
1342 ni->stats->gold + fight->gold);
1343
1344
1345 if (master_fight(ni))
1346 {
1347 notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
1348 notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
1349 strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
1350
1351 // Increase your level
1352 ni->stats->level++;
1353
1354 // Increase your maximum hit points
1355 ni->stats->maxhp += hpbonus[ni->stats->level - 1];
1356
1357 // Heal the player by setting hp to their max
1358 ni->stats->hp = ni->stats->maxhp;
1359
1360 // Add to your strength
1361 ni->stats->strength += strbonus[ni->stats->level - 1];
1362
1363 // Add to your defensive power
1364 ni->stats->defense += defbonus[ni->stats->level - 1];
1365
1366 // Clear the pointer for your master
1367 ni->stats->master = NULL;
1368 }
1369
1370 // They're dead so remove the pointer
1371 delete ni->stats->fight;
1372 ni->stats->fight = NULL;
1373 ni->stats->master = NULL;
1374
1375 return;
1376 }
1377 else
1378 {
1379 if (hit > 0)
1380 fight->hp -= hit;
1381 if (mhit > 0)
1382 {
1383 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1384 fight->name, fight->weapon, mhit);
1385 }
1386 else if (mhit <= 0)
1387 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1388
1389 if (mhit >= ni->stats->hp)
1390 {
1391 if (!master_fight(ni))
1392 {
1393 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1394 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1395 "of your experience!");
1396 ni->stats->gold = 0;
1397 ni->stats->exp -= (long int)(ni->stats->exp * .10);
1398 ni->stats->fight = NULL;
1399 clearAlive(ni->stats);
1400 return;
1401 }
1402 else
1403 {
1404 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1405 "until tomorrow to try again", ni->stats->master->name);
1406 ni->stats->fight = NULL;
1407 ni->stats->master = NULL;
1408 return;
1409 }
1410 }
1411 else
1412 {
1413 if (mhit > 0)
1414 ni->stats->hp -= mhit;
1415 display_monster(u);
1416 return;
1417 }
1418 }
1419 }
1420 else if (player_fight(ni))
1421 {
1422 /* Offline fighting not available yet
1423 if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
1424 {
1425 if (hit > 0)
1426 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
1427 else
1428 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
1429 if (hit >= battle->stats->hp)
1430 {
1431 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
1432 * notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1433 (long int)(battle->stats->exp * .10), battle->stats->gold);
1434 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1435 {
1436 ni->stats->exp += (long int)(battle->stats->exp * .10);
1437 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1438 }
1439 * else
1440 {
1441 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1442 ni->stats->exp = 2000000000;
1443 }
1444
1445 if (2000000000 - ni->stats->gold > battle->stats->gold)
1446 {
1447 * ni->stats->gold += battle->stats->gold;
1448 battle->stats->gold = 0;
1449 }
1450 else
1451 {
1452 battle->stats->gold = 2000000000 - ni->stats->gold;
1453 ni->stats->gold = 2000000000;
1454 }
1455 * ni->stats->battle->stats->alive = 0;
1456 ni->stats->battle->battle = NULL;
1457 ni->stats->battle = NULL;
1458 return;
1459 }
1460 else
1461 {
1462 if (hit > 0)
1463 * battle->stats->hp -= hit;
1464 if (mhit > 0)
1465 {
1466 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1467 battle->nick, weapons[battle->stats->weapon], mhit);
1468 }
1469 else if (mhit <= 0)
1470 notice(s_GameServ, u, "%s completely misses you!", battle->nick);
1471 *
1472 if (mhit >= ni->stats->hp)
1473 {
1474 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
1475 if (2000000000 - battle->stats->gold > ni->stats->gold)
1476 {
1477 notice(s_GameServ, u, "%s took all your gold!", battle->nick);
1478 battle->stats->gold += ni->stats->gold;
1479 * ni->stats->gold = 0;
1480 }
1481 else
1482 {
1483 notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
1484 battle->nick);
1485 ni->stats->gold -= (2000000000 - battle->stats->gold);
1486 notice(s_GameServ, u, "You were left dead with %d gold.",
1487 * (long int)ni->stats->gold);
1488 battle->stats->gold = 2000000000;
1489 }
1490 ni->stats->battle->battle = NULL;
1491 ni->stats->battle = NULL;
1492 ni->stats->alive = 0;
1493 return;
1494 }
1495 * else
1496 {
1497 if (mhit > 0)
1498 ni->stats->hp -= mhit;
1499 display_players(u);
1500 return;
1501 }
1502 }
1503 }
1504 * end offline fighting */
1505
1506 if (is_playing(battle))
1507 {
1508 if (!isYourTurn(ni->stats))
1509 {
1510 notice(s_GameServ, u, "Please wait until %s decides what to do!",
1511 battle->stats->name);
1512 return;
1513 }
1514 if (hit > 0)
1515 {
1516 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->stats->name, hit);
1517
1518 notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
1519 "\ 2%d\ 2 damage!", ni->stats->name,
1520 weapons[ni->stats->weapon], hit);
1521 clearYourTurn(ni->stats);
1522 setYourTurn(battle->stats);
1523 display_players(battle->getNick());
1524 }
1525 else
1526 {
1527 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->stats->name);
1528 notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name);
1529 clearYourTurn(ni->stats);
1530 setYourTurn(battle->stats);
1531 display_players(battle->getNick());
1532 }
1533 if (hit >= battle->stats->hp)
1534 {
1535 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name);
1536 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1537 (long int)(battle->stats->exp * .10), battle->stats->gold);
1538 notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!",
1539 ni->stats->name);
1540 battle->stats->hp = 0;
1541 clearAlive(battle->stats);
1542
1543 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1544 {
1545 ni->stats->exp += (long int)(battle->stats->exp * .10);
1546 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1547 }
1548 else
1549 {
1550 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1551 ni->stats->exp = 2000000000;
1552 }
1553
1554 if (2000000000 - ni->stats->gold > battle->stats->gold)
1555 {
1556 notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
1557 "all gold on hand!");
1558 ni->stats->gold += battle->stats->gold;
1559 battle->stats->gold = 0;
1560 }
1561 else
1562 {
1563 battle->stats->gold = 2000000000 - ni->stats->gold;
1564 notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
1565
1566 notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
1567 "gold.", ni->stats->name);
1568
1569 notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
1570 "left. All is not lost!", battle->stats->gold);
1571
1572 ni->stats->gold = 2000000000;
1573 }
1574 battle->stats->battle = NULL;
1575 ni->stats->battle = NULL;
1576 return;
1577 }
1578 else
1579 {
1580 if (hit > 0)
1581 battle->stats->hp -= hit;
1582 clearYourTurn(ni->stats);
1583 setYourTurn(battle->stats);
1584 notice(s_GameServ, u, "Please wait while %s decides what to do!",
1585 battle->stats->name);
1586
1587 return;
1588 }
1589 }
1590 }
1591 }
1592
1593 void do_heal(char *u)
1594 {
1595 aClient *ni;
1596 char *amount = strtok(NULL, " ");
1597 int price, num;
1598
1599 if (!amount)
1600 {
1601 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1602 }
1603 else if (!(ni = find(u)))
1604 {
1605 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1606 return;
1607 }
1608 else if (!is_playing(ni))
1609 {
1610 notice(s_GameServ, u, "You aren't playing!");
1611 return;
1612 }
1613 else if (!isAlive(ni->stats))
1614 {
1615 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
1616 return;
1617 }
1618 else if (is_fighting(ni))
1619 {
1620 notice(s_GameServ, u, "You can't heal in battle!");
1621 }
1622 else if (ni->stats->hp >= ni->stats->maxhp)
1623 {
1624 notice(s_GameServ, u, "You don't need healing!");
1625 }
1626 else if (stricmp(amount, "ALL") == 0)
1627 {
1628 price = ni->stats->level * 3;
1629 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
1630 {
1631 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1632 (long int)ni->stats->gold/price, price);
1633 ni->stats->hp += ni->stats->gold / price;
1634 ni->stats->gold %= price;
1635 }
1636 else
1637 {
1638 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1639 "per point.", price);
1640 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
1641 (ni->stats->maxhp - ni->stats->hp),
1642 (price * (ni->stats->maxhp - ni->stats->hp)) );
1643 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1644 ni->stats->hp = ni->stats->maxhp;
1645 }
1646 }
1647 else if (isstringnum(amount))
1648 {
1649 num = stringtoint(amount);
1650 price = ni->stats->level * 3;
1651 if (ni->stats->gold < price * num)
1652 {
1653 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
1654 (long int)ni->stats->gold/price);
1655 }
1656 else if (num <= ni->stats->maxhp - ni->stats->hp)
1657 {
1658 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
1659 num, price);
1660 ni->stats->hp += num;
1661 ni->stats->gold -= num * price;
1662 }
1663 else if (num > ni->stats->maxhp - ni->stats->hp)
1664 {
1665 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1666 "per point.", price);
1667 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
1668 (ni->stats->maxhp - ni->stats->hp));
1669 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1670 ni->stats->hp = ni->stats->maxhp;
1671 }
1672 }
1673 else if (amount[0] == '-')
1674 notice(s_GameServ, u, "You trying to cheat?");
1675 else
1676 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1677 }
1678
1679 int isstringnum(char *num)
1680 {
1681 unsigned int x;
1682 for (x = 0; x < strlen(num); x++)
1683 {
1684 if ((int)num[x] < 48 || (int)num[x] > 57)
1685 return 0;
1686 }
1687 return 1;
1688 }
1689
1690 long int stringtoint(char *number)
1691 {
1692 long int x, len = strlen(number), sum = 0;
1693 if (len == 1)
1694 return chartoint(number[0]);
1695 sum += chartoint(number[len - 1]);
1696 for (x = len - 2; x >= 0; x--)
1697 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
1698 return sum;
1699 }
1700
1701 long int pow(int x, int y)
1702 {
1703 long int value = 0;
1704 int count = 0;
1705 value += x;
1706
1707 if (x != 0 && y != 0)
1708 {
1709 for (count = 1; count <= y - 1; count++)
1710 value *= x;
1711 }
1712 else
1713 return 1;
1714 return value;
1715 }
1716
1717 long int chartoint(char ch)
1718 {
1719 if (int(ch) >= 48 && int(ch) <= 57)
1720 return int(ch) - 48;
1721 else
1722 return 0;
1723 }
1724
1725 int save_gs_dbase()
1726 {
1727 ListNode<aClient> *ptr = players.First();
1728 Player *it;
1729 ofstream outfile;
1730
1731 outfile.open(playerdata);
1732
1733 if (!outfile)
1734 {
1735 log("Error opening %s", playerdata);
1736 return 0;
1737 }
1738
1739 while(ptr)
1740 {
1741 it = ptr->getData()->stats;
1742 outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
1743 << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
1744 << it->armor << ' ' << it->weapon << ' '
1745 << it->forest_fights << ' ' << it->player_fights << ' '
1746 << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
1747 << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl;
1748 ptr = ptr->Next();
1749 }
1750 outfile.close();
1751 return 1;
1752 }
1753
1754 int load_gs_dbase()
1755 {
1756 ifstream infile;
1757 aClient *temp;
1758 Player *p;
1759 char *tempname, *buf, *password;
1760 buf = new char[1023];
1761
1762 infile.open(playerdata);
1763
1764 if (infile.fail())
1765 {
1766 log("Error opening %s", playerdata);
1767 return 0;
1768 }
1769
1770 while (infile.getline(buf, 1024, '\n'))
1771 {
1772 temp = new aClient;
1773 tempname = strtok(buf, " ");
1774 temp->stats = new Player(tempname);
1775 p = temp->stats;
1776
1777 p->level = stringtoint(strtok(NULL, " "));
1778 p->exp = stringtoint(strtok(NULL, " "));
1779 p->gold = stringtoint(strtok(NULL, " "));
1780 p->bank = stringtoint(strtok(NULL, " "));
1781 p->hp = stringtoint(strtok(NULL, " "));
1782 p->maxhp = stringtoint(strtok(NULL, " "));
1783 p->strength = stringtoint(strtok(NULL, " "));
1784 p->defense = stringtoint(strtok(NULL, " "));
1785 p->armor = stringtoint(strtok(NULL, " "));
1786 p->weapon = stringtoint(strtok(NULL, " "));
1787 p->forest_fights = stringtoint(strtok(NULL, " "));
1788 p->player_fights = stringtoint(strtok(NULL, " "));
1789 p->setFlags(stringtoint(strtok(NULL, " ")));
1790
1791 password = strtok(NULL, " ");
1792 strcpy(p->password, password);
1793 temp->setNick("!NULL!");
1794 #ifdef P10
1795 temp->setRealNick("!NULL!");
1796 #endif
1797
1798 p->inventory.reset(); // Set inventory to all 0s
1799 // Old player databases didn't have these three extra values
1800 // If they come up null, leave them to 0 as the default.
1801 // On the next gameserv database save, it will save the values.
1802 tempname = strtok(NULL, " ");
1803 if (tempname)
1804 p->inventory.setHealing(stringtoint(tempname));
1805
1806 tempname = strtok(NULL, " ");
1807 if (tempname)
1808 p->inventory.setStrength(stringtoint(tempname));
1809
1810 tempname = strtok(NULL, " ");
1811 if (tempname)
1812 p->inventory.setDefense(stringtoint(tempname));
1813
1814 tempname = strtok(NULL, " ");
1815 if (tempname)
1816 p->inventory.setHP(stringtoint(tempname));
1817
1818 players.insertAtBack(temp);
1819 delete temp;
1820 }
1821 delete [] buf;
1822 infile.close();
1823 return 1;
1824 }
1825
1826 bool passcmp(char *encrypted, char *plaintext)
1827 {
1828 char salt[3];
1829 char *plaintext2, *plainToencrypt;
1830 bool same = false;
1831
1832 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
1833 strcpy(plaintext2, plaintext);
1834
1835 salt[0] = encrypted[0];
1836 salt[1] = encrypted[1];
1837 salt[3] = '\0';
1838
1839 plainToencrypt = crypt(plaintext2, salt);
1840
1841 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
1842
1843 delete []plaintext2;
1844
1845 return same;
1846 }
1847
1848 bool check_password(char *name, char *plaintext)
1849 {
1850 aClient *client;
1851
1852 if (!(client = findplayer(name)))
1853 return false;
1854 else
1855 {
1856 return passcmp(client->stats->password, plaintext);
1857 }
1858 }
1859
1860 void do_store(char *u)
1861 {
1862 char *cmd = strtok(NULL, " ");
1863 char *item = strtok(NULL, " ");
1864 char *num = strtok(NULL, " ");
1865 char *space;
1866 int wep;
1867 aClient *user;
1868 Player *p;
1869
1870 if (!cmd || !item)
1871 {
1872 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
1873 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
1874 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
1875 }
1876 else if (!(user = find(u)) || !is_playing(user))
1877 notice(s_GameServ, u, "You must be playing to use the store!");
1878 else if (!isAlive(user->stats))
1879 {
1880 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
1881 return;
1882 }
1883 else if (stricmp(cmd, "LIST") == 0)
1884 {
1885 if (stricmp(item, "WEAPONS") == 0)
1886 {
1887 notice(s_GameServ, u, "Welcome to Kain's Armory");
1888 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
1889 for (int x = 1; x < WNA; x++)
1890 {
1891 space = spaces(strlen(weapons[x]), ".");
1892 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
1893 free(space);
1894 }
1895 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
1896 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
1897
1898 }
1899 else if (stricmp(item, "ARMOR") == 0)
1900 {
1901 notice(s_GameServ, u, "Welcome to Kain's Armory");
1902 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
1903 for (int x = 1; x < WNA; x++)
1904 {
1905 space = spaces(strlen(armors[x]), ".");
1906 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
1907 free(space);
1908 }
1909 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
1910 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
1911
1912
1913 }
1914 } else if (stricmp(cmd, "BUY") == 0) {
1915 if (!num)
1916 {
1917 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
1918 return;
1919 }
1920 else if (!isstringnum(num))
1921 {
1922 notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
1923 return;
1924 }
1925 if (stricmp(item, "WEAPON") == 0)
1926 {
1927 wep = stringtoint(num);
1928 if (wep >= WNA || wep < 1)
1929 {
1930 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
1931 return;
1932 }
1933
1934 p = user->stats;
1935
1936 if (p->weapon != 0)
1937 notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
1938 else if (p->gold < prices[wep - 1])
1939 notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
1940 else
1941 {
1942 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
1943 p->weapon = wep;
1944 p->gold -= prices[wep - 1];
1945 }
1946 }
1947 else if (stricmp(item, "ARMOR") == 0)
1948 {
1949 wep = stringtoint(num);
1950 if (wep >= WNA || wep < 1)
1951 {
1952 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
1953 return;
1954 }
1955
1956 p = user->stats;
1957
1958 if (p->armor != 0)
1959 notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
1960 else if (p->gold < prices[wep - 1])
1961 notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
1962 else
1963 {
1964 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
1965 p->armor = wep;
1966 p->gold -= prices[wep - 1];
1967 }
1968 }
1969 }
1970 else if (stricmp(cmd, "SELL" ) == 0)
1971 {
1972 p = user->stats;
1973
1974 if (stricmp(item, "WEAPON") == 0)
1975 {
1976 if (p->weapon == 0)
1977 {
1978 notice(s_GameServ, u, "You want me to chop off your hands?");
1979 return;
1980 }
1981 else if (p->gold == 2000000000)
1982 {
1983 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
1984 p->weapon = 0;
1985 }
1986 else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
1987 {
1988 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
1989 notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
1990 p->gold = 2000000000;
1991 p->weapon = 0;
1992 }
1993 else
1994 {
1995 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
1996 p->gold += (prices[p->weapon - 1] / 2);
1997 p->weapon = 0;
1998 }
1999 }
2000 else if (stricmp(item, "ARMOR") == 0)
2001 {
2002 p = user->stats;
2003
2004 if (p->armor == 0)
2005 {
2006 notice(s_GameServ, u, "I don't think you can be any more naked...");
2007 return;
2008 }
2009 if (p->gold == 2000000000)
2010 {
2011 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2012 p->armor = 0;
2013 }
2014 else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
2015 {
2016 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2017 notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
2018 p->gold = 2000000000;
2019 p->armor = 0;
2020 }
2021 else
2022 {
2023 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
2024 (prices[p->armor - 1] / 2));
2025
2026 p->gold += (prices[p->armor - 1] / 2);
2027 p->armor = 0;
2028 }
2029 }
2030 else
2031 {
2032 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2033 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2034 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2035 }
2036 }
2037 }
2038 void do_inventory(char *u)
2039 {
2040 aClient *user;
2041
2042 if (!(user = find(u)))
2043 {
2044 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2045 return;
2046 }
2047 else if (!is_playing(user))
2048 {
2049 notice(s_GameServ, u, "You must be playing to check your inventory!");
2050 return;
2051 }
2052 showinventory(user, user);
2053 }
2054 void showinventory(aClient *from, aClient *to)
2055 {
2056 char *nick = to->getNick();
2057
2058 if (!to)
2059 to = from;
2060 if (is_playing(from))
2061 {
2062 Pouch *p = &from->stats->inventory;
2063 notice(s_GameServ, nick, "Inventory for %s:", from->stats->name);
2064 notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
2065 notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
2066 notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
2067 notice(s_GameServ, nick, " HP Potions: %d", p->HP());
2068 }
2069 }
2070 void do_tavern(char *u)
2071 {
2072 char *cmd = strtok(NULL, " ");
2073 long int price;
2074
2075 aClient *user;
2076 Player *p;
2077 if (!(user = find(u)))
2078 {
2079 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2080 return;
2081 }
2082 else if (!is_playing(user))
2083 {
2084 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2085 return;
2086 }
2087 else if (is_fighting(user))
2088 {
2089 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2090 return;
2091 }
2092 p = user->stats;
2093 if (!cmd)
2094 {
2095 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
2096 notice(s_GameServ, u, "Your commands:");
2097 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2098 notice(s_GameServ, u, "What'll it be?");
2099 }
2100 else if (stricmp(cmd, "LIST") == 0)
2101 {
2102 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2103 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10));
2104 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10));
2105 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10));
2106 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10));
2107 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2108 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2109 notice(s_GameServ, u, "By something will ya!");
2110 }
2111 else if (stricmp(cmd, "BUY") == 0)
2112 {
2113 char *chnum = strtok(NULL, " ");
2114 int num = stringtoint(chnum);
2115
2116 if (!chnum)
2117 {
2118 notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
2119 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
2120 return;
2121 }
2122 if (num < 1 || num > 4)
2123 {
2124 notice(s_GameServ, u, "Invalid Choice!");
2125 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2126 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10));
2127 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10));
2128 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10));
2129 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10));
2130 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2131 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2132 return;
2133 }
2134 switch(num)
2135 {
2136 case 1:
2137 price = (1000 * p->level) + (p->exp / 10);
2138 if (p->gold >= price)
2139 {
2140 notice(s_GameServ, u, "One healing potion coming right up!");
2141 p->inventory.incHealing();
2142 p->gold -= price;
2143 }
2144 else
2145 notice(s_GameServ, u, "You don't have enough gold!");
2146 break;
2147 case 2:
2148 price = (2050 * p->level) + (p->exp / 10);
2149 if (p->gold >= price)
2150 {
2151 notice(s_GameServ, u, "One strength boost coming right up!");
2152 p->inventory.incStrength();
2153 p->gold -= price;
2154 }
2155 else
2156 notice(s_GameServ, u, "You don't have enough gold!");
2157 break;
2158 case 3:
2159 price = (2000 * p->level) + (p->exp / 10);
2160 if (p->gold >= price)
2161 {
2162 notice(s_GameServ, u, "One defense boost coming right up!");
2163 p->inventory.incDefense();
2164 p->gold -= price;
2165 }
2166 else
2167 notice(s_GameServ, u, "You don't have enough gold!");
2168 break;
2169 case 4:
2170 price = (2300 * p->level) + (p->exp / 10);
2171 if (p->gold >= price)
2172 {
2173 notice(s_GameServ, u, "One HP Potion coming right up!");
2174 p->inventory.incHP();
2175 p->gold -= price;
2176 }
2177 else
2178 notice(s_GameServ, u, "You don't have enough gold!");
2179 break;
2180 default:
2181 notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
2182 break;
2183 }
2184 }
2185 else
2186 {
2187 notice(s_GameServ, u, "Improper Syntax.");
2188 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2189 }
2190 }
2191
2192 void do_bank(char *u)
2193 {
2194 char *cmd = strtok(NULL, " ");
2195 char *amount = strtok(NULL, " ");
2196 char *nick = strtok(NULL, " ");
2197
2198 aClient *user;
2199 Player *p;
2200
2201 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
2202 {
2203 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
2204 notice (s_GameServ, u, "BANK BALANCE");
2205 return;
2206 }
2207
2208 user = find(u);
2209 if (!is_playing(user))
2210 {
2211 notice(s_GameServ, u, "You must be playing to use the bank!");
2212 return;
2213 }
2214 else if (stricmp(cmd, "BALANCE") == 0)
2215 {
2216 showBankBalance(u);
2217 return;
2218 }
2219 else if (!isAlive(user->stats))
2220 {
2221 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2222 return;
2223 }
2224 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2225 {
2226 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2227 return;
2228 }
2229
2230 p = user->stats;
2231
2232 if (stricmp(cmd, "DEPOSIT") == 0)
2233 {
2234 if (p->bank == 2000000000)
2235 {
2236 notice(s_GameServ, u, "Your bank account is full, sire!");
2237 return;
2238 }
2239 else if (stricmp(amount, "ALL") == 0)
2240 {
2241 if (2000000000 - p->bank < p->gold)
2242 {
2243 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2244 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
2245 p->gold -= (2000000000 - p->bank);
2246 p->bank = 2000000000;
2247 showBankBalance(u);
2248 }
2249 else
2250 {
2251 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
2252 p->bank += p->gold;
2253 p->gold = 0;
2254 showBankBalance(u);
2255 }
2256 }
2257 else if (stringtoint(amount) > p->gold)
2258 {
2259 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
2260 showBankBalance(u);
2261 return;
2262 }
2263 else
2264 {
2265 if (2000000000 - p->bank < stringtoint(amount))
2266 {
2267 notice(s_GameServ, u, "You don't have room in your account for that much.");
2268 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
2269 p->gold -= (2000000000 - p->bank);
2270 p->bank = 2000000000;
2271 showBankBalance(u);
2272 }
2273 else
2274 {
2275 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2276 p->bank += stringtoint(amount);
2277 p->gold -= stringtoint(amount);
2278 showBankBalance(u);
2279 }
2280 }
2281 }
2282 else if (stricmp(cmd, "WITHDRAW") == 0)
2283 {
2284 if (p->gold == 2000000000)
2285 {
2286 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
2287 showBankBalance(u);
2288 return;
2289 }
2290 else if (stricmp(amount, "ALL") == 0)
2291 {
2292 if (2000000000 - p->gold < p->bank)
2293 {
2294 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2295 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
2296 p->bank -= (2000000000 - p->gold);
2297 p->gold = 2000000000;
2298 showBankBalance(u);
2299 }
2300 else
2301 {
2302 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
2303 p->gold += p->bank;
2304 p->bank = 0;
2305 showBankBalance(u);
2306 }
2307 }
2308 else if (stringtoint(amount) > p->bank)
2309 {
2310 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
2311 showBankBalance(u);
2312 return;
2313 }
2314 else
2315 {
2316 if (2000000000 - p->gold < stringtoint(amount))
2317 {
2318 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2319 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2320 (2000000000 - p->gold));
2321 p->bank -= (2000000000 - p->gold);
2322 p->gold = 2000000000;
2323 showBankBalance(u);
2324 }
2325 else
2326 {
2327 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2328 p->gold += stringtoint(amount);
2329 p->bank -= stringtoint(amount);
2330 showBankBalance(u);
2331 }
2332 }
2333 }
2334
2335 }
2336
2337 void do_master(char *u)
2338 {
2339 aClient *user;
2340 user = find(u);
2341
2342 if (!user)
2343 {
2344 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2345 return;
2346 }
2347 else if (is_fighting(user))
2348 {
2349 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
2350 return;
2351 }
2352 else if (!isAlive(user->stats))
2353 {
2354 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2355 return;
2356 }
2357 else if (!is_playing(user))
2358 {
2359 notice(s_GameServ, u, "You must be playing to see your master!");
2360 return;
2361 }
2362
2363 char *cmd = strtok(NULL, " ");
2364 Player *p = user->stats;
2365 long int need = 0;
2366
2367 if (seenMaster(p))
2368 {
2369 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
2370 return;
2371 }
2372
2373 if (cmd != NULL)
2374 {
2375 switch(p->level)
2376 {
2377 case 1:
2378 need = 100;
2379 break;
2380 case 2:
2381 need = 400;
2382 break;
2383 case 3:
2384 need = 1000;
2385 break;
2386 case 4:
2387 need = 4000;
2388 break;
2389 case 5:
2390 need = 10000;
2391 break;
2392 case 6:
2393 need = 40000;
2394 break;
2395 case 7:
2396 need = 100000;
2397 break;
2398 case 8:
2399 need = 400000;
2400 break;
2401 case 9:
2402 need = 1000000;
2403 break;
2404 case 10:
2405 need = 4000000;
2406 break;
2407 case 11:
2408 need = 10000000;
2409 break;
2410 case 12:
2411 need = p->exp + 1;
2412 notice(s_GameServ, u, "You are at level 12. You are the master. What's left? The DRAGON!");
2413 break;
2414 default:
2415 need = p->exp + 1; // Unknown level... don't let them fight a fake master!
2416 break;
2417 }
2418 }
2419 else
2420 {
2421 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2422 return;
2423 }
2424
2425 if (stricmp(cmd, "FIGHT") == 0)
2426 {
2427 if (p->exp >= need)
2428 {
2429 setMaster(p);
2430 see_master(u);
2431 }
2432 else
2433 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.", masters[p->level - 1]->name, (need - p->exp));
2434 return;
2435 }
2436 else if (stricmp(cmd, "QUESTION") == 0)
2437 {
2438 if (p->exp >= need)
2439 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);
2440 else
2441 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", masters[p->level - 1]->name, p->name);
2442
2443 return;
2444 }
2445 else
2446 {
2447 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2448 }
2449 }
2450
2451 void see_master(char *u)
2452 {
2453 aClient *user;
2454
2455 if (!(user = find(u)))
2456 {
2457 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2458 return;
2459 }
2460
2461 if (!is_fighting(user) && is_playing(user))
2462 {
2463 Player *p = user->stats;
2464 p->master = new Monster(masters[p->level - 1]);
2465 p->fight = p->master;
2466 display_monster(u); // Since master is the same structure, use this function
2467 }
2468 }
2469
2470 void showBankBalance(const char *u)
2471 {
2472 aClient *user;
2473 Player *p;
2474
2475 if (!(user = find(u)))
2476 return;
2477
2478 p = user->stats;
2479
2480 if (!p)
2481 return;
2482
2483 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->bank, p->gold);
2484
2485 }
2486
2487 void refreshall()
2488 {
2489 ListNode <aClient> *it;
2490 Player *p;
2491
2492 it = players.First();
2493
2494 while (it)
2495 {
2496 p = it->getData()->stats;
2497 refresh(p);
2498 it = it->Next();
2499 }
2500 }
2501
2502 void refresh(Player *p)
2503 {
2504 if (!p)
2505 return;
2506
2507 if (p->hp < p->maxhp)
2508 p->hp = p->maxhp;
2509 p->forest_fights = forestfights;
2510 p->player_fights = 3;
2511 setAlive(p);
2512 clearMaster(p);
2513 }
2514
2515 void do_refresh(char *u)
2516 {
2517 char *nick = strtok(NULL, " ");
2518 aClient *user;
2519
2520 if (!(user = find(u)))
2521 {
2522 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
2523 log("Error: aClient not found: %s", u);
2524 return;
2525 }
2526 else if (!isAdmin(user))
2527 {
2528 notice(s_GameServ, u, "You must be a %S admin to use this command!");
2529 return;
2530 }
2531 if (!nick)
2532 {
2533 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
2534 return;
2535 }
2536 else if (stricmp(nick, "ALL") == 0)
2537 {
2538 notice(s_GameServ, u, "Refreshing everyone's stats!");
2539 refreshall();
2540 }
2541 else if ((user = findbyrealnick(nick)))
2542 {
2543 if (is_playing(user))
2544 {
2545 #ifdef P10
2546 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
2547 #else
2548 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
2549 #endif
2550 refresh(user->stats);
2551 }
2552 else
2553 {
2554 #ifdef P10
2555 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
2556 #else
2557 notice(s_GameServ, u, "%s is not playing.", user->getNick());
2558 #endif
2559 }
2560 }
2561 else
2562 {
2563 notice(s_GameServ, u, "Nick %s not found.", nick);
2564 return;
2565 }
2566 }
2567
2568
2569 void resetall()
2570 {
2571 ListNode <aClient> *it;
2572 Player *p;
2573
2574 it = players.First();
2575
2576 while (it)
2577 {
2578 p = it->getData()->stats;
2579 reset(p);
2580 it = it->Next();
2581 }
2582 }
2583
2584 void reset(Player *p)
2585 {
2586 if (!p)
2587 return;
2588
2589 p->reset();
2590 }
2591
2592 void do_reset(char *u)
2593 {
2594 char *nick = strtok(NULL, " ");
2595 aClient *user;
2596
2597 if (!(user = find(u)))
2598 {
2599 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
2600 log("Error: aClient not found: %s", u);
2601 return;
2602 }
2603 else if (!isAdmin(user))
2604 {
2605 notice(s_GameServ, u, "You must be a %S admin to use this command!");
2606 return;
2607 }
2608 if (!nick)
2609 {
2610 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
2611 return;
2612 }
2613 else if (stricmp(nick, "ALL") == 0)
2614 {
2615 notice(s_GameServ, u, "Resetting everyone's stats!");
2616 resetall();
2617 }
2618 else if ((user = findbyrealnick(nick)))
2619 {
2620 if (is_playing(user))
2621 {
2622 #ifdef P10
2623 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
2624 #else
2625 notice(s_GameServ, u, "Resetting %s.", user->getNick());
2626 #endif
2627 reset(user->stats);
2628 }
2629 else
2630 {
2631 #ifdef P10
2632 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
2633 #else
2634 notice(s_GameServ, u, "%s is not playing.", user->getNick());
2635 #endif
2636 }
2637 }
2638 else
2639 {
2640 notice(s_GameServ, u, "Nick %s not found.", nick);
2641 return;
2642 }
2643 }
2644
2645 void do_help(char *u)
2646 {
2647 char *cmd = strtok(NULL, " ");
2648
2649 display_help(u, cmd);
2650 }
2651
2652 void display_help(char *u, char *file)
2653 {
2654 ifstream infile;
2655 char *buf;
2656
2657 if (!file)
2658 {
2659 infile.open("helpfiles/help");
2660 if (infile.fail())
2661 {
2662 log("Error opening helpfiles/help");
2663 notice(s_GameServ, u, "Error opening helpfiles/help");
2664 return;
2665 }
2666 buf = new char[1024];
2667 while(infile.getline(buf, 1024))
2668 {
2669 // Written this way, it will process %S in the helpfiles
2670 // Instead of notice(s_GameServ, u, "%s", buf);
2671 notice(s_GameServ, u, buf);
2672 }
2673
2674 // Minor recursion
2675 aClient *user = find(u);
2676 if (user && isAdmin(user))
2677 display_help(u, "admin_commands");
2678 }
2679 else
2680 {
2681 char *filename;
2682 filename = new char[strlen(file) + 11];
2683 strcpy(filename, "helpfiles/");
2684 strcat(filename, file);
2685
2686 for (unsigned int x = 10; x < strlen(filename); x++)
2687 filename[x] = tolower(filename[x]);
2688
2689 infile.open(filename);
2690 delete [] filename;
2691 if (infile.fail())
2692 {
2693 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
2694 return;
2695 }
2696 buf = new char[1024];
2697 while(infile.getline(buf, 1024))
2698 {
2699 // Written this way, it will process %S in the helpfiles
2700 // Instead of notice(s_GameServ, u, "%s", buf);
2701 notice(s_GameServ, u, buf);
2702 }
2703 }
2704 infile.close();
2705 delete [] buf;
2706 }
2707
2708 void do_admin(char *u)
2709 {
2710 aClient *user;
2711 char *pass = strtok(NULL, " ");
2712
2713 if (!(user = find(u)))
2714 {
2715 log("Error: aClient not found: %s", u);
2716 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
2717 return;
2718 }
2719 if (!pass)
2720 {
2721 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
2722 return;
2723 }
2724
2725 if (isAdmin(user))
2726 {
2727 notice(s_GameServ, u, "You already have administrator privledges.");
2728 return;
2729 }
2730 else if (strcmp(pass, adminpass) == 0)
2731 {
2732 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
2733 setAdmin(user);
2734 #ifdef P10
2735 log("%s became an administrator.", user->getRealNick());
2736 #else
2737 log("%s became an administrator.", user->getNick());
2738 #endif
2739 }
2740 else
2741 {
2742 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
2743 return;
2744 }
2745 }
2746
2747 bool load_monsters()
2748 {
2749 ifstream infile;
2750 infile.open("monsters.dat");
2751
2752 char *buf;
2753
2754 if (infile.fail())
2755 {
2756 log("Error opening monsters.dat");
2757 return false;
2758 }
2759 init_monsters();
2760 buf = new char[2048];
2761
2762 #ifdef DEBUGMODE
2763 log("Loading monsters from monsters.dat");
2764 #endif
2765
2766 for (int l = 0; l < REALLEVELS; l++)
2767 {
2768 for (int m = 0; m < MONSTERS;)
2769 {
2770 infile.getline(buf, 2048);
2771 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
2772 continue;
2773 else
2774 {
2775 strcpy(monsters[l][m]->name, strtok(buf, "~"));
2776 strcpy(monsters[l][m]->weapon, strtok(NULL, "~"));
2777 monsters[l][m]->strength = stringtoint(strtok(NULL, "~"));
2778 monsters[l][m]->gold = stringtoint(strtok(NULL, "~"));
2779 monsters[l][m]->exp = stringtoint(strtok(NULL, "~"));
2780 monsters[l][m]->maxhp = stringtoint(strtok(NULL, "~"));
2781 monsters[l][m]->hp = monsters[l][m]->maxhp;
2782 strcpy(monsters[l][m]->death, strtok(NULL, ""));
2783 m++;
2784 }
2785 }
2786 }
2787 delete [] buf;
2788 return true;
2789 }