]> jfr.im git - irc/gameservirc.git/blob - gameserv/gameserv.cpp
Fixed a bug that would allow a player to run from a player vs player fight, but still...
[irc/gameservirc.git] / gameserv / gameserv.cpp
1 #include "aClient.h"
2 #include "config.h"
3 #include "extern.h"
4 #include "player.h"
5 #include "pouch.h"
6 #include "flags.h"
7 #include "level.h"
8 #include "sockhelp.h"
9 #include "item.h"
10 #include "script.h"
11
12 #include <algorithm>
13 #include <cctype>
14 #include <fstream>
15 #include <stdlib.h>
16 #include <list>
17 #include <iterator>
18
19 using namespace std;
20
21 #if defined(HAVE_CRYPT_H)
22
23 #include <crypt.h>
24
25 #elif defined(HAVE_UNISTD_H)
26
27 #include <unistd.h>
28
29 #endif
30
31 Monster dragon; // The current dragon
32 Level levels[LEVELS]; // The newest way to store monsters
33 list<item*> Items; // The master list of items
34 list<tavernItem> tavern; // The list of items available at the tavern
35 list<item*> store; // The list of items available at the store
36
37 // Database functions
38 int save_gs_dbase();
39 int load_gs_dbase();
40 int load_items();
41 int load_tavern();
42 int load_store();
43 int load_dragon();
44 int save_dragon();
45
46 item *findItemByID(int id);
47 item *findStoreItemByID(int id);
48 tavernItem *findTavernItemByID(int id);
49
50 // String functions
51 #ifndef HAVE_STRTOK
52 char *strtok(char *str, const char *delim);
53 #endif
54
55 int stricmp(const char *s1, const char *s2);
56 int strnicmp(const char *s1, const char *s2, size_t len);
57 // String Functions
58
59 /********** Password functions **********/
60
61 bool passcmp(const char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
62
63 bool check_password(char *name, char *plaintext); // Finds a password for the given name, and checks it with passcmp against the plaintext password given.
64
65 /********** Password functions **********/
66
67
68 /********** GameServ Booleans **********/
69
70 bool shuttingdown;
71 bool timedOut(Player *p);
72 void updateTS(Player *p);
73 void timeOutEvent(Player *p);
74
75 bool is_playing(char *u); // True if the given nickname in the clients list is playing.
76 bool is_playing(aClient *user);
77
78 bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
79 bool is_fighting(aClient *user);
80
81 bool player_fight(char *u); // True if the player is fighting another player.
82 bool player_fight(aClient *user);
83
84 bool master_fight(char *u); // True if the player is fighting their master.
85 bool master_fight(aClient *user);
86
87 bool dragon_fight(char *u); // True if the player is fighting the dragon.
88 bool dragon_fight(aClient *user);
89
90 bool alphaNumeric(const char *str); // Returns true if all of the characters in str are alphanumeric non-special chars
91 /********** GameServ Booleans **********/
92
93 void display_help(char *u, char *file = NULL);
94 void display_monster(char *u);
95 void display_players(char *u);
96 void display_players(aClient *user);
97 long int chartoint(char ch);
98 int isstringnum(char *num);
99 long int pow (int x, int y);
100 long int stringtoint(char *number);
101
102 char *spaces(int len, char *seperator);
103 void refresh(Player *p);
104 void refreshall();
105 void rollover(Player *p);
106 void rolloverall();
107
108 void updateTS(Player *p);
109 void reset(Player *p);
110 bool load_masters();
111 bool load_monsters();
112 bool load_levels();
113 void delete_monsters();
114
115 void do_admin(char *u);
116 void do_attack(char *u);
117 void do_bank(char *u);
118 void do_check(char *u);
119 void do_equip(char *u);
120 void do_fight(char *u);
121 void do_heal(char *u);
122 void do_help(char *u);
123 void do_identify(char *u);
124 void do_inventory(char *u);
125 void do_refresh(char *u);
126 void do_register(char *u);
127 void do_list(char *u);
128 void do_logout(char *u);
129 void do_master(char *u);
130 void do_dragon(char *u);
131 void do_play(char *u);
132 void do_quitg(char *u);
133 void do_reset(char *u);
134 void do_run(char *u);
135 void do_set(char *u);
136 void do_stats(char *u);
137 void do_store(char *u);
138 void do_tavern(char *u);
139 void do_use(char *u);
140 void see_master(char *u);
141
142 void logout(aClient *user);
143 void showstats(const char *u, const char *nick);
144 void showTavern(aClient *user);
145 void showinventory(Player *from, aClient *to);
146 void showBankBalance(const char *u);
147 void end_turn(aClient *user);
148
149 #define WNA 16
150
151 int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550};
152 int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200};
153 int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
154
155 void gameserv(char *source, char *buf)
156 {
157 char *cmd, z;
158 cmd = strtok(buf, " ");
159
160 #ifndef P10
161 source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
162 #endif
163
164 z = cmd[0];
165 if (z == ':')
166 cmd++; // Get rid of that : at the beginning of the :text (command)
167
168 #ifdef DEBUGMODE
169 log("Source: %s Command: %s", source, cmd);
170 #endif
171
172 if (strnicmp(cmd, "\1PING", 6) == 0)
173 {
174 char *ts;
175 ts = strtok(NULL, "\1");
176 notice(s_GameServ, source, "\1PING %s\1", ts);
177 }
178 else if (stricmp(cmd, "\1VERSION\1") == 0)
179 {
180 notice(s_GameServ, source, "\1VERSION %s %s\1", PACKAGE, VERSION);
181 }
182 else if (stricmp(cmd, "SEARCH") == 0)
183 {
184 cmd = strtok(NULL, " ");
185
186 if (!cmd)
187 notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
188 else
189 do_forest(source);
190
191 }
192 else if (stricmp(cmd, "ADMIN") == 0)
193 {
194 do_admin(source);
195 }
196 else if (stricmp(cmd, "ATTACK") == 0)
197 {
198 do_attack(source);
199 }
200 else if (stricmp(cmd, "BANK") == 0)
201 {
202 do_bank(source);
203 }
204 else if (stricmp(cmd, "CHECK") == 0)
205 {
206 do_check(source);
207 }
208 else if (stricmp(cmd, "DRAGON") == 0)
209 {
210 do_dragon(source);
211 }
212 else if (stricmp(cmd, "EQUIP") == 0)
213 {
214 do_equip(source);
215 }
216 else if (stricmp(cmd, "FIGHT") == 0)
217 {
218 do_fight(source);
219 }
220 else if (stricmp(cmd, "HEAL") == 0)
221 {
222 do_heal(source);
223 }
224 else if (stricmp(cmd, "HELP") == 0)
225 {
226 do_help(source);
227 }
228 else if (stricmp(cmd, "IDENTIFY") == 0)
229 {
230 do_identify(source);
231 }
232 else if (stricmp(cmd, "INVENTORY") == 0)
233 {
234 do_inventory(source);
235 }
236 else if (stricmp(cmd, "LIST") == 0)
237 {
238 do_list(source);
239 }
240 else if (stricmp(cmd, "LOGOUT") == 0)
241 {
242 do_logout(source);
243 }
244 else if (stricmp(cmd, "MASTER") == 0)
245 {
246 do_master(source);
247 }
248 else if (stricmp(cmd, "NEWS") == 0)
249 {
250 do_news(source);
251 }
252 else if (stricmp(cmd, "REGISTER") == 0)
253 {
254 do_register(source);
255 }
256 else if (stricmp(cmd, "REFRESH") == 0)
257 {
258 do_refresh(source);
259 }
260 else if (stricmp(cmd, "RESET") == 0)
261 {
262 do_reset(source);
263 }
264 else if (stricmp(cmd, "RUN") == 0)
265 {
266 do_run(source);
267 }
268 else if (stricmp(cmd, "SET") == 0)
269 {
270 do_set(source);
271 }
272 else if (stricmp(cmd, "STATS") == 0)
273 {
274 do_stats(source);
275 }
276 else if (stricmp(cmd, "STORE") == 0)
277 {
278 do_store(source);
279 }
280 else if (stricmp(cmd, "TAVERN") == 0)
281 {
282 do_tavern(source);
283 }
284 else if (stricmp(cmd, "USE") == 0)
285 {
286 do_use(source);
287 }
288 else if (stricmp(cmd, "SHUTDOWN") == 0)
289 {
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 save_gs_dbase();
304 #ifdef P10
305 raw("[] SQ %s 0 :leaving: %s used the Shutdown command.", servername, user->getRealNick());
306 #else
307 raw("SQUIT %s :leaving: %s used the Shutdown command.", servername, source);
308 #endif
309 shuttingdown = true;
310 }
311 }
312 else if (stricmp(cmd, "SAVE") == 0)
313 {
314 aClient *user;
315
316 if (!(user = find(source)))
317 {
318 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
319 log("Error: aClient not found: %s", source);
320 }
321 else if (!isAdmin(user))
322 {
323 notice(s_GameServ, source, "You must be a %S admin to use this command!");
324 }
325 else
326 {
327 save_gs_dbase();
328 }
329 }
330 else if (stricmp(cmd, "LOAD") == 0)
331 {
332 aClient *user;
333
334 if (!(user = find(source)))
335 {
336 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
337 log("Error: aClient not found: %s", source);
338 }
339 else if (!isAdmin(user))
340 {
341 notice(s_GameServ, source, "You must be a %S admin to use this command!");
342 }
343 else
344 {
345 char *cmd2 = strtok(NULL, " ");
346 if (!cmd2)
347 {
348 notice(s_GameServ, source, "Loading player data from %s", playerdata);
349 load_gs_dbase();
350 }
351 else if (stricmp(cmd2, "MONSTERS") == 0)
352 {
353 notice(s_GameServ, source, "Loading monster data");
354 load_monsters();
355 }
356 else if (stricmp(cmd2, "SCRIPTS") == 0)
357 {
358 // Testing scripts for now
359 script scr;
360 notice(s_GameServ, source, "Loading scripts");
361
362 if (scr.loadScript("test.txt"))
363 scr.executeScript(user->stats);
364 }
365 else
366 {
367 display_help(source, cmd);
368 }
369 }
370 }
371 #ifdef DEBUGMODE
372 else if (stricmp(cmd, "RAW") == 0)
373 {
374 aClient *user;
375
376 if (!(user = find(source)))
377 {
378 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
379 log("Error: aClient not found: %s", source);
380 }
381 else if (!isAdmin(user))
382 {
383 notice(s_GameServ, source, "You must be a %S admin to use this command!");
384 }
385 else
386 {
387 char *rest = strtok(NULL, "");
388 raw("%s", rest);
389 }
390 }
391 else if (stricmp(cmd, "RANDOM") == 0)
392 {
393 char *rstr = strtok(NULL, "");
394 range trange;
395 trange.setRange(rstr);
396 notice(s_GameServ, source, "Random number in that range: %d", trange.random());
397 }
398 #endif
399 else
400 {
401 aClient *user;
402 if ((user = find(source)))
403 {
404 if (isIgnore(user))
405 {
406 #ifdef DEBUGMODE
407 log("Ignoring %s.", user->getNick());
408 #endif
409 }
410 else
411 {
412 notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd);
413 }
414 }
415 }
416
417 #ifndef P10
418 source--; // Bring the ':' back so we don't leak memory
419 #endif
420 if (z == ':')
421 cmd--; // Same thing :)
422 }
423
424 int stricmp(const char *s1, const char *s2)
425 {
426 register int c;
427
428 while ((c = tolower(*s1)) == tolower(*s2)) {
429 if (c == 0)
430 return 0;
431 s1++;
432 s2++;
433 }
434 if (c < tolower(*s2))
435 return -1;
436 return 1;
437 }
438
439 void showstats(const char *u, const char *nick)
440 {
441 aClient *sender = find(u);
442 Player *p;
443 char *buf;
444 buf = new char[50];
445 char *space;
446
447
448 if (!(p = findplayer(nick)))
449 {
450 notice(s_GameServ, u, "%s not found", nick);
451 }
452 else
453 {
454 notice(s_GameServ, sender->getNick(), "Stats for %s:", p->getName().c_str());
455
456 sprintf(buf, "Experience: %ld", p->getExp());
457 space = spaces(strlen(buf), " ");
458 notice(s_GameServ, sender->getNick(), "%s%sLevel: %d", buf, space,
459 p->getLevel());
460 delete [] space;
461
462 sprintf(buf, "Gold: %ld", p->getGold());
463 space = spaces(strlen(buf), " ");
464 notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, p->getBank());
465 delete [] space;
466
467 notice(s_GameServ, sender->getNick(), "Hit Points: %d of %d", p->getHP(),
468 p->getMaxHP());
469
470 sprintf(buf, "Strength: %d", p->getStrength());
471 space = spaces(strlen(buf), " ");
472 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
473 buf, space, p->getDefense());
474 delete [] space;
475
476 sprintf(buf, "Armor: %s", (p->getArmor() ? p->getArmor()->getName().c_str() : "Nothing"));
477 space = spaces(strlen(buf), " ");
478
479 notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
480 (p->getWeapon() ? p->getWeapon()->getName().c_str() : "Fists"));
481
482 delete [] space;
483
484 sprintf(buf, "Forest Fights: %d", p->getForestFights());
485 space = spaces(strlen(buf), " ");
486 notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, p->getPlayerFights());
487 delete [] space;
488 if (p->getClient() == sender || isAdmin(sender))
489 {
490 showinventory(p, sender);
491 }
492 }
493
494 delete [] buf;
495 }
496
497 char *spaces(int len, char *seperator)
498 {
499 char *final;
500 final = new char[30];
501 int y;
502 strcpy(final, seperator);
503 for (y = 0; y < 30 - len; y++)
504 strcat(final, seperator);
505 return final;
506 }
507
508 void raw(const char *fmt, ...)
509 {
510 va_list args;
511 char *input;
512 const char *t = fmt;
513 input = new char[1024];
514 va_start(args, fmt);
515 memset(input, 0, sizeof(input)); // Initialize to NULL
516 for (; *t; t++)
517 {
518 if (*t == '%')
519 {
520 switch(*++t) {
521 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
522 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
523 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
524 case 'l':
525 if (*++t == 'd')
526 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
527 }
528 }
529 else
530 {
531 sprintf(input, "%s%c", input, *t);
532 }
533
534 }
535 #ifdef DEBUGMODE
536 log("Input: %s", input);
537 #endif
538
539 sprintf(input, "%s%s", input, "\r\n");
540 sock_puts(sock, input);
541 delete [] input;
542 va_end(args);
543 }
544 /* Send a NOTICE from the given source to the given nick. */
545
546 void notice(const char *source, const char *dest, const char *fmt, ...)
547 {
548 if (fmt[0] == '\0')
549 return;
550
551 char *commanduse;
552 commanduse = new char[16];
553
554 #ifdef P10
555 if (isUsePrivmsg())
556 strcpy(commanduse, "P");
557 else
558 strcpy(commanduse, "O");
559 #else
560
561 if (isUsePrivmsg())
562 strcpy(commanduse, "PRIVMSG");
563 else
564 strcpy(commanduse, "NOTICE");
565 #endif
566
567 va_list args;
568 char *input;
569 const char *t = fmt;
570 input = new char[1024];
571 va_start(args, fmt);
572 if (dest[0] == ':')
573 {
574 dest++;
575
576 #if !defined(P10)
577 sprintf(input, ":%s %s %s :", source, commanduse, dest);
578 #else
579 sprintf(input, "%s %s %s :", gsnum, commanduse, dest);
580 #endif
581
582 dest--;
583 }
584 else
585 {
586 #if !defined(P10)
587 sprintf(input, ":%s %s %s :", source, commanduse, dest);
588 #else
589 sprintf(input, "%s %s %s :", gsnum, commanduse, dest);
590 #endif
591 }
592
593 for (; *t; t++)
594 {
595 if (*t == '%')
596 {
597 switch(*++t) {
598 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
599 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
600 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
601 case 'c': sprintf(input, "%s%c", input, va_arg(args, int)); break;
602 case 'l':
603 if (*++t == 'd')
604 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
605 }
606 }
607 else
608 {
609 sprintf(input, "%s%c", input, *t);
610 }
611
612 }
613 #ifdef DEBUGMODE
614 log("Input: %s", input);
615 #endif
616 sprintf(input, "%s%s", input, "\r\n");
617 sock_puts(sock, input);
618 delete [] commanduse;
619 delete [] input;
620 va_end(args);
621 }
622
623
624 int strnicmp(const char *s1, const char *s2, size_t len)
625 {
626 register int c;
627
628 if (!len)
629 return 0;
630 while ((c = tolower(*s1)) == tolower(*s2) && len > 0) {
631 if (c == 0 || --len == 0)
632 return 0;
633 s1++;
634 s2++;
635 }
636 if (c < tolower(*s2))
637 return -1;
638 return 1;
639 }
640
641 #ifndef HAVE_STRTOK
642 char *strtok(char *str, const char *delim)
643 {
644 static char *current = NULL;
645 char *ret;
646
647 if (str)
648 current = str;
649 if (!current)
650 return NULL;
651 current += strspn(current, delim);
652 ret = *current ? current : NULL;
653 current += strcspn(current, delim);
654 if (!*current)
655 current = NULL;
656 else
657 *current++ = 0;
658 return ret;
659 }
660 #endif
661
662 void do_check(char *u)
663 {
664 int days, hours, minutes, seconds;
665 long complete;
666 complete = (lastrefresh + refreshperiod) - time(NULL);
667 days = complete / 86400;
668 hours = (complete % 86400) / 3600;
669 minutes = (complete % 86400) % 3600 / 60;
670 seconds = (complete % 86400) % 3600 % 60;
671
672 notice(s_GameServ, u, "Time left to next refresh: %dd %dh %dm %ds",
673 days, hours, minutes, seconds);
674
675 if (isRolloverForestFights())
676 {
677 complete = (lastrollover + rolloverperiod) - time(NULL);
678
679 days = complete / 86400;
680 hours = (complete % 86400) / 3600;
681 minutes = (complete % 86400) % 3600 / 60;
682 seconds = (complete % 86400) % 3600 % 60;
683
684 notice(s_GameServ, u, "Time left to next rollover: %dd %dh %dm %ds",
685 days, hours, minutes, seconds);
686 }
687 }
688
689 void do_list(char *u)
690 {
691 aClient *user;
692 Player *p;
693 char *cmd = strtok(NULL, " ");
694
695 if (!(user = find(u)))
696 {
697 log("Fatal Error: Couldn't find %s in the client list", u);
698 return;
699 }
700 else if (isIgnore(user))
701 {
702 #ifdef DEBUGMODE
703 log("Ignoring %s. Command LIST", user->getNick());
704 #endif
705 return;
706 }
707
708 list<Player*>::iterator iter;
709 bool header = false;
710
711 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
712 {
713 iter = players[x].begin();
714 if (!players[x].empty())
715 {
716 while(iter != players[x].end())
717 {
718 p = (*iter);
719 if (cmd || is_playing(p->getClient()))
720 {
721 if (!header)
722 {
723 notice(s_GameServ, u, "Players:");
724 header = true;
725 }
726 #ifdef P10
727 notice(s_GameServ, u, "IRC: %s Game: %s", (p->getClient() ? p->getClient()->getRealNick() : "Not Playing"),
728 p->getName().c_str());
729 #else
730 notice(s_GameServ, u, "IRC: %s Game: %s", (p->getClient() ? p->getClient()->getNick() : "Not Playing"),
731 p->getName().c_str());
732 #endif
733 }
734 iter++;
735 }
736 }
737 }
738 if (!header)
739 notice(s_GameServ, u, "No one is playing");
740 else
741 notice(s_GameServ, u, "End of List");
742 }
743
744 void do_set(char *u)
745 {
746 aClient *user;
747 Player *p;
748 char *name = strtok(NULL, " ");
749 char *cmd = strtok(NULL, " ");
750 char *cmd2;
751
752 if (!(user = find(u)))
753 {
754 notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\
755 "Buf: %s LOGOUT", u);
756 return;
757 }
758 else if (isIgnore(user))
759 {
760 #ifdef DEBUGMODE
761 log("Ignoring %s.", user->getNick());
762 #endif
763 return;
764 }
765 else if (!name || !cmd)
766 {
767 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
768 return;
769 }
770 else if (!(p = findplayer(name)))
771 {
772 // Back the pointers up... they didn't send a name probably
773 cmd2 = cmd;
774 cmd = name;
775 p = user->stats;
776
777 if (!is_playing(user))
778 {
779 notice(s_GameServ, u, "You must be playing to set things for yourself!");
780 return;
781 }
782 }
783 else
784 {
785 cmd2 = strtok(NULL, " ");
786 }
787 if (!cmd2)
788 {
789 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
790 return;
791 }
792
793 // Regardless of the previous if/else, if it got here, we know we have the cmd pointer at the right spot.
794 if (stricmp(cmd, "PASSWORD") == 0)
795 {
796 // Person is looking to change their password
797 // If they're an admin, or it's theirself, allow it
798 // cmd2 is pointing to the password now
799 if (isAdmin(user) || user == p->getClient())
800 {
801 p->setPassword(cmd2);
802 notice(s_GameServ, u, "Password successfully changed");
803 }
804 else if (user != p->getClient() && !isAdmin(user))
805 {
806 notice(s_GameServ, u, "You must be a %S admin to set other peoples' passwords.");
807 return;
808 }
809 }
810 else if (stricmp(cmd, "BANK") == 0 || stricmp(cmd, "BALANCE") == 0)
811 {
812 if (!isAdmin(user))
813 {
814 notice(s_GameServ, u, "Admins Only!");
815 return;
816 }
817 else if (stricmp(cmd, "BANK") == 0)
818 {
819 cmd2 = strtok(NULL, " "); // Need an extra parameter for set bank balance
820 }
821 if (!cmd2)
822 {
823 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] [BANK] BALANCE <NUMBER>");
824 return;
825 }
826
827 p->setBank(stringtoint(cmd2));
828
829 notice(s_GameServ, u, "Bank balance changed to %ld!", p->getBank());
830 }
831 else if (stricmp(cmd, "PLAYER") == 0)
832 {
833 if (!isAdmin(user))
834 {
835 notice(s_GameServ, u, "Admins Only!");
836 return;
837 }
838 else if (stricmp(cmd2, "FIGHTS") != 0)
839 {
840 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS <NUMBER>");
841 return;
842 }
843 else
844 {
845 cmd2 = strtok(NULL, " ");
846 if (!cmd2)
847 {
848 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] PLAYER FIGHTS <NUMBER>");
849 return;
850 }
851 p->setPlayerFights(stringtoint(cmd2));
852
853 notice(s_GameServ, u, "Player fights changed to %d!", p->getPlayerFights());
854 }
855 }
856 else if (stricmp(cmd, "FOREST") == 0)
857 {
858 if (!isAdmin(user))
859 {
860 notice(s_GameServ, u, "Admins Only!");
861 return;
862 }
863 else if (stricmp(cmd2, "FIGHTS") != 0)
864 {
865 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS <number>");
866 return;
867 }
868 else
869 {
870 cmd2 = strtok(NULL, " ");
871 if (!cmd2)
872 {
873 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] FOREST FIGHTS <NUMBER>");
874 return;
875 }
876
877 p->setForestFights(stringtoint(cmd2));
878
879 notice(s_GameServ, u, "Forest fights changed to %d!", p->getForestFights());
880 }
881 }
882 else if (stricmp(cmd, "GOLD") == 0)
883 {
884 if (!isAdmin(user))
885 {
886 notice(s_GameServ, u, "Admins Only!");
887 return;
888 }
889 else
890 {
891 if (!cmd2)
892 {
893 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] GOLD <NUMBER>");
894 return;
895 }
896 p->setGold(stringtoint(cmd2));
897
898 notice(s_GameServ, u, "Gold set to %ld", p->getGold());
899 return;
900 }
901 }
902 else if (stricmp(cmd, "STRENGTH") == 0 && stricmp(cmd2, "POTIONS") != 0)
903 {
904 if (!isAdmin(user))
905 {
906 notice(s_GameServ, u, "Admins Only!");
907 return;
908 }
909 else
910 {
911 if (!cmd2)
912 {
913 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] STRENGTH <NUMBER>");
914 return;
915 }
916
917 p->setStrength(stringtoint(cmd2));
918
919 notice(s_GameServ, u, "Strength set to %d", p->getStrength());
920 return;
921 }
922 }
923 else if (stricmp(cmd, "DEFENSE") == 0 && stricmp(cmd2, "POTIONS") != 0)
924 {
925 if (!isAdmin(user))
926 {
927 notice(s_GameServ, u, "Admins Only!");
928 return;
929 }
930 else
931 {
932 if (!cmd2)
933 {
934 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] DEFENSE <NUMBER>");
935 return;
936 }
937
938 p->setDefense(stringtoint(cmd2));
939
940 notice(s_GameServ, u, "Defense set to %d", p->getDefense());
941 return;
942 }
943 }
944 else if (stricmp(cmd, "HP") == 0 && stricmp(cmd2, "POTIONS") != 0)
945 {
946 if (!isAdmin(user))
947 {
948 notice(s_GameServ, u, "Admins Only!");
949 return;
950 }
951 else
952 {
953 if (!cmd2)
954 {
955 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] HP <NUMBER>");
956 return;
957 }
958
959 // Make sure it's easy for an admin to set the hp
960 if (p->getMaxHP() < stringtoint(cmd2))
961 p->setMaxHP(stringtoint(cmd2));
962
963 p->setHP(stringtoint(cmd2));
964
965 notice(s_GameServ, u, "HP set to %d", p->getHP());
966 return;
967 }
968 }
969 else if (stricmp(cmd, "MAXHP") == 0)
970 {
971 if (!isAdmin(user))
972 {
973 notice(s_GameServ, u, "Admins Only!");
974 return;
975 }
976 else
977 {
978 if (!cmd2)
979 {
980 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] MAXHP <NUMBER>");
981 return;
982 }
983 p->setMaxHP(stringtoint(cmd2));
984
985 notice(s_GameServ, u, "MaxHP set to %d", p->getMaxHP());
986 return;
987 }
988 }
989 else if (stricmp(cmd, "EXPERIENCE") == 0 || stricmp(cmd, "EXP") == 0)
990 {
991 if (!isAdmin(user))
992 {
993 notice(s_GameServ, u, "Admins Only!");
994 return;
995 }
996 else
997 {
998 if (!cmd2)
999 {
1000 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {EXPERIENCE|EXP} <NUMBER>");
1001 return;
1002 }
1003
1004 p->setExp(stringtoint(cmd2));
1005
1006 notice(s_GameServ, u, "Exp set to %ld", p->getExp());
1007 return;
1008 }
1009 }
1010 else if (stricmp(cmd, "LEVEL") == 0)
1011 {
1012 if (!isAdmin(user))
1013 {
1014 notice(s_GameServ, u, "Admins Only!");
1015 return;
1016 }
1017 else
1018 {
1019 if (!cmd2)
1020 {
1021 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] LEVEL <NUMBER>");
1022 return;
1023 }
1024 p->setLevel(stringtoint(cmd2));
1025
1026 notice(s_GameServ, u, "Level set to %d", p->getLevel());
1027 return;
1028 }
1029 }
1030 else if (stricmp(cmd, "ALIVE") == 0)
1031 {
1032 if (!isAdmin(user))
1033 {
1034 notice(s_GameServ, u, "Admins Only!");
1035 return;
1036 }
1037 else
1038 {
1039 if (!cmd2)
1040 {
1041 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] ALIVE TRUE|FALSE");
1042 return;
1043 }
1044 else if (stricmp(cmd2, "TRUE") == 0)
1045 {
1046 notice(s_GameServ, u, "%s has been Resurrected!", p->getName().c_str());
1047 setAlive(p);
1048 }
1049 else
1050 {
1051 notice(s_GameServ, u, "%s is now dead!", p->getName().c_str());
1052 clearAlive(p);
1053 }
1054 }
1055 }
1056 else if (stricmp(cmd, "SEEN") == 0)
1057 {
1058 if (!isAdmin(user))
1059 {
1060 notice(s_GameServ, u, "Admins Only!");
1061 return;
1062 }
1063 else if (stricmp(cmd2, "MASTER") != 0)
1064 {
1065 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] SEEN MASTER {TRUE|FALSE}");
1066 return;
1067 }
1068 else
1069 {
1070 cmd2 = strtok(NULL, " ");
1071 if (!cmd2)
1072 {
1073 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NICK] SEEN MASTER {TRUE|FALSE}");
1074 return;
1075 }
1076 else if (stricmp(cmd2, "TRUE") == 0)
1077 {
1078 notice(s_GameServ, u, "%s has seen their master now.", p->getName().c_str());
1079 p->addFlag(FLAG_MASTER);
1080 }
1081 else
1082 {
1083 notice(s_GameServ, u, "%s has not seen their master now.", p->getName().c_str());
1084 p->remFlag(FLAG_MASTER);
1085 }
1086 }
1087 }
1088 else
1089 {
1090 notice(s_GameServ, u, "Unknown command: SET %s", cmd);
1091 notice(s_GameServ, u, "SYNTAX: /msg %S SET [NAME] {PASSWORD|BANK BALANCE|PLAYER FIGHTS|FOREST FIGHTS|GOLD|STRENGTH|DEFENSE|HP|MAXHP|EXP|LEVEL|ALIVE|SEEN MASTER} {STRING|NUMBER|TRUE|FALSE}");
1092 return;
1093 }
1094 }
1095
1096 void do_logout(char *u)
1097 {
1098 aClient *user;
1099 Player *p;
1100 char *name = strtok(NULL, " ");
1101
1102 if (!(user = find(u)))
1103 {
1104 notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\
1105 "Buf: %s LOGOUT", u);
1106 log("Could not find aClient Buf: %s LOGOUT",
1107 u);
1108 return;
1109 }
1110 else if (isIgnore(user))
1111 {
1112 #ifdef DEBUGMODE
1113 log("Ignoring %s.", user->getNick());
1114 #endif
1115 return;
1116 }
1117
1118 if (name)
1119 {
1120 if (!isAdmin(user))
1121 {
1122 notice(s_GameServ, u, "You must be a %S admin to use this command!");
1123 }
1124 else if (!(p = findplayer(name)))
1125 {
1126 notice(s_GameServ, u, "Couldn't find a player named %s", name);
1127 }
1128 else
1129 {
1130 notice(s_GameServ, u, "Logging out %s", p->getName().c_str());
1131 logout(p->getClient());
1132 }
1133 }
1134 else if (!name)
1135 {
1136 if (!is_playing(user))
1137 {
1138 notice(s_GameServ, u, "You're not logged in!");
1139 }
1140 else if (is_fighting(user))
1141 {
1142 notice(s_GameServ, u, "You can't logout while fighting!");
1143 }
1144 else
1145 {
1146 notice(s_GameServ, u, "You have left the fields. You have lived to kill another day!");
1147 logout(user);
1148 }
1149 }
1150 }
1151
1152 void logout(aClient *user)
1153 {
1154 if (user != NULL)
1155 {
1156 if (user->stats != NULL)
1157 {
1158
1159 list<Player*>::iterator iter;
1160 unsigned long hv = iHASH((unsigned char *) user->stats->getName().c_str());
1161 iter = find(players[hv].begin(), players[hv].end(), user->stats);
1162
1163 if (iter == players[hv].end())
1164 {
1165 notice(s_GameServ, user->getNick(), "Fatal error. Contact "\
1166 "%S Admin. Cannot find you in the players list. This should NEVER happen");
1167 log("Error on logout(). Can't find %s in the players list",
1168 #ifdef P10
1169 user->getRealNick()
1170 #else
1171 user->getNick()
1172 #endif
1173 );
1174 user->stats = NULL;
1175
1176 return;
1177 }
1178 user->stats->delMonster();
1179 user->stats->delMaster();
1180 user->stats->delBattle();
1181 clearDragonFight(user->stats);
1182 clearYourTurn(user->stats);
1183 clearPlaying(user);
1184
1185 user->stats->setClient(NULL);
1186
1187
1188 if (player_fight(user))
1189 {
1190 clearYourTurn(user->stats->getBattle()->stats);
1191 user->stats->getBattle()->stats->delBattle();
1192 }
1193
1194 #ifdef DEBUGMODE
1195 log("Logged out player %s",
1196 #ifdef P10
1197 user->getRealNick()
1198 #else
1199 user->getNick()
1200 #endif
1201 );
1202 #endif
1203 }
1204 }
1205 if (user)
1206 user->stats = NULL;
1207 }
1208
1209 void do_register(char *u)
1210 {
1211 char *password, *name;
1212 aClient *user;
1213 Player *p;
1214 name = strtok(NULL, " ");
1215 password = strtok(NULL, " ");
1216
1217 if (!name)
1218 {
1219 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
1220 }
1221 else if (stricmp(name, s_GameServ) == 0)
1222 {
1223 notice(s_GameServ, u, "You can't use %S as a name!");
1224 }
1225 else if (!password)
1226 {
1227 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
1228 }
1229 else if (strlen(name) > maxnicklen)
1230 {
1231 notice(s_GameServ, u, "Name too long. Maximum length: %d", maxnicklen);
1232 }
1233 else if (!alphaNumeric(name))
1234 {
1235 notice(s_GameServ, u, "That is not a valid name. Please use only AlphaNumeric (A-Z, 0-9) characters!");
1236 }
1237 else if ((p = findplayer(name)))
1238 {
1239 notice(s_GameServ, u, "%s is already registered!", name);
1240 notice(s_GameServ, u, "Choose another name!");
1241 }
1242 else if (!(user = find(u)))
1243 {
1244 log("Fatal Error: Couldn't find %s in the clients list", u);
1245 }
1246 else if (isIgnore(user))
1247 {
1248 #ifdef DEBUGMODE
1249 log("Ignoring %s.", user->getNick());
1250 #endif
1251 }
1252 else
1253 {
1254 if (!is_playing(user))
1255 {
1256 item *tempItem;
1257 unsigned long hv = iHASH((unsigned char *) name);
1258
1259 // First create the Player
1260 user->stats = new Player();
1261
1262 // Set the backwards pointer
1263 user->stats->setClient(user);
1264
1265 // Set the player's password
1266 user->stats->setPassword(password);
1267
1268 // Set the player's name
1269 user->stats->setName(name);
1270
1271 // Make sure they have a proper time stamp
1272 updateTS(user->stats);
1273
1274 // Update the last login time
1275 user->stats->lastlogin = time(NULL);
1276
1277 // Send notification of success
1278 notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->getName().c_str(), password);
1279 notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!");
1280
1281 // Log the new player
1282 log("Nickname %s registered player %s.", u, user->stats->getName().c_str());
1283
1284 // Log the player in
1285 setPlaying(user);
1286
1287 // Start the player at the beginning
1288 reset(user->stats);
1289
1290 // Add the stick and clothes
1291 tempItem = findItemByID(3001);
1292 user->stats->inventory->addItem((*Items.begin()))->use(user->stats); // Add the stick
1293 user->stats->inventory->addItem(tempItem)->use(user->stats); // Add Clothes
1294
1295 // Add the player to the list
1296 players[hv].push_back(user->stats);
1297 }
1298 else
1299 {
1300 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
1301 }
1302 }
1303 }
1304
1305 void do_identify(char *u)
1306 {
1307 char *password, *name;
1308 aClient *user;
1309 Player *p;
1310 name = strtok(NULL, " ");
1311 password = strtok(NULL, " ");
1312 if (!password || !name)
1313 {
1314 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
1315 }
1316 else if (!(user = find(u)))
1317 {
1318 notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, ""));
1319 log("Error: aClient not found: %s", u);
1320 }
1321 else if (isIgnore(user))
1322 {
1323 #ifdef DEBUGMODE
1324 log("Ignoring %s.", user->getNick());
1325 #endif
1326 return;
1327 }
1328 else if (!(p = findplayer(name)))
1329 {
1330 notice(s_GameServ, u, "Player %s not found", name);
1331 }
1332 else if (is_playing(user))
1333 {
1334 notice(s_GameServ, u, "You are already playing!");
1335 }
1336 else if (is_playing(p->getClient()) && !isAdmin(user))
1337 {
1338 notice(s_GameServ, u, "That player has already identified.");
1339 }
1340 else if (!check_password(name, password) && !isAdmin(user))
1341 {
1342 notice(s_GameServ, u, "Password incorrect");
1343 }
1344 else
1345 {
1346 list<Player*>::iterator iter;
1347 unsigned long hv = iHASH((unsigned char *) p->getName().c_str());
1348
1349 iter = find(players[hv].begin(), players[hv].end(), p);
1350
1351 if (iter == players[hv].end())
1352 {
1353 notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s",
1354 strtok(NULL, ""));
1355 return;
1356 }
1357 // Make sure the other user is logged out
1358 logout(p->getClient());
1359
1360 user->stats = p;
1361 p->setClient(user);
1362 updateTS(p);
1363
1364
1365 #ifdef DEBUGMODE
1366 log("Player %s IRC: %s Identified", user->stats->getName().c_str(),
1367 user->getNick());
1368 #endif
1369 //Set the playing flag
1370 setPlaying(user);
1371
1372 // Update the last login time
1373 user->stats->lastlogin = time(NULL);
1374
1375 notice(s_GameServ, u, "Password Accepted. Identified.");
1376 showNews(u, todaysnews);
1377 }
1378 }
1379
1380 void do_stats(char *u)
1381 {
1382 char *nick;
1383 aClient *user;
1384
1385 nick = strtok(NULL, " ");
1386
1387 if (!(user = find(u)))
1388 {
1389 log("Fatal Error: %s not found in client list", u);
1390 return;
1391 }
1392 else if (isIgnore(user))
1393 {
1394 #ifdef DEBUGMODE
1395 log("Ignoring %s.", user->getNick());
1396 #endif
1397 return;
1398 }
1399 else if (!nick)
1400 {
1401 if (!is_playing(user))
1402 {
1403 notice(s_GameServ, u, "You're not playing, so you have no stats!");
1404 return;
1405 }
1406 else
1407 {
1408 if (!is_fighting(user))
1409 updateTS(user->stats);
1410 showstats(u, user->stats->getName().c_str());
1411 }
1412 }
1413 else
1414 showstats(u, nick);
1415 }
1416
1417 bool load_masters()
1418 {
1419 ifstream infile(masterdata);
1420 char *buf;
1421 int l = 0;
1422 buf = new char[1024];
1423
1424 if (infile.fail())
1425 {
1426 log("Error opening %s", masterdata);
1427 return false;
1428 }
1429
1430 #ifdef DEBUGMODE
1431 log("Loading masters from %s", masterdata);
1432 #endif
1433
1434 for (l = 0; l < LEVELS - 1; l++)
1435 {
1436 infile.getline(buf, 1024, '\n');
1437
1438 log("%s", buf);
1439 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r')
1440 {
1441 l--;
1442 continue;
1443 }
1444 else if (buf[0] == '^')
1445 break;
1446
1447 Monster *master = &levels[l].master;
1448
1449 char *name, *weapon, *strength, *gold, *exp, *maxhp, *death;
1450
1451
1452 name = strtok(buf, "~");
1453 weapon = strtok(NULL, "~");
1454 strength = strtok(NULL, "~");
1455 gold = strtok(NULL, "~");
1456 exp = strtok(NULL, "~");
1457 maxhp = strtok(NULL, "~");
1458 death = strtok(NULL, "~");
1459
1460 master->name = name;
1461 master->weapon = weapon;
1462 master->strength = stringtoint(strength);
1463 master->gold = stringtoint(gold);
1464 master->exp = stringtoint(exp);
1465 master->maxhp = stringtoint(maxhp);
1466 master->hp = master->maxhp;
1467 master->death = death;
1468 }
1469
1470 delete []buf;
1471
1472 if (l < LEVELS - 1) // We didn't load a master for every level - check data/masters.dat
1473 return false;
1474 else
1475 return true;
1476 }
1477
1478 void delete_monsters()
1479 {
1480 for (int x = 0; x < LEVELS; x++)
1481 levels[x].monsters.clear();
1482 }
1483
1484 void display_monster(char *u)
1485 {
1486 if (is_playing(u))
1487 {
1488 aClient *user = find(u);
1489 Player *ni = user->stats;
1490
1491 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->getHP());
1492 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->getMonster()->name.c_str(), ni->getMonster()->hp);
1493 notice(s_GameServ, u, "Here are your commands:");
1494 notice(s_GameServ, u, "/msg %S attack");
1495 notice(s_GameServ, u, "/msg %S run");
1496 notice(s_GameServ, u, "What will you do?");
1497 }
1498 }
1499
1500 void display_players(char *u)
1501 {
1502 aClient *user;
1503 if (!(user = find(u)))
1504 {
1505 log("Fatal error in display_players(): Couldn't find %s", u);
1506 }
1507 else
1508 display_players(user);
1509 }
1510
1511 void display_players(aClient *user)
1512 {
1513 char *u = user->getNick();
1514 if (is_playing(user) && player_fight(user))
1515 {
1516 aClient *battle = user->stats->getBattle();
1517 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", user->stats->getHP());
1518 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->getName().c_str(), battle->stats->getHP());
1519 notice(s_GameServ, u, "Here are your commands:");
1520 notice(s_GameServ, u, "/msg %S attack");
1521 notice(s_GameServ, u, "/msg %S run");
1522 notice(s_GameServ, u, "What will you do?");
1523 }
1524 }
1525
1526
1527 bool is_playing(char *u)
1528 {
1529 aClient *user;
1530 if (!(user = find(u)))
1531 return false;
1532 else
1533 return is_playing(user);
1534 }
1535
1536 bool is_playing(aClient *user)
1537 {
1538 if (!user)
1539 {
1540 return false;
1541 }
1542 else if (!user->stats)
1543 {
1544 return false;
1545 }
1546 else if (!FL_is_playing(user))
1547 {
1548 return false;
1549 }
1550 else if (user->stats->getClient() != user)
1551 {
1552 return false;
1553 }
1554 else
1555 return true;
1556 }
1557
1558 bool is_fighting(char *u)
1559 {
1560 aClient *user;
1561
1562 if (!(user = find(u)))
1563 return false;
1564 else
1565 return is_fighting(user);
1566 }
1567
1568 bool is_fighting(aClient *user)
1569 {
1570 if (!is_playing(user))
1571 return false;
1572 else
1573 return player_fight(user) || master_fight(user) || user->stats->getMonster() != NULL;
1574 }
1575
1576 bool player_fight(char *u)
1577 {
1578 aClient *user;
1579
1580 if (!(user = find(u)))
1581 return false;
1582 else
1583 return player_fight(user);
1584 }
1585
1586 bool player_fight(aClient *user)
1587 {
1588 if (!is_playing(user))
1589 return false;
1590 else if (is_playing(user->stats->getBattle()))
1591 {
1592 return true;
1593 }
1594 return false;
1595 }
1596
1597 bool master_fight(char *u)
1598 {
1599 aClient *user;
1600
1601 if (!(user = find(u)))
1602 return false;
1603 else
1604 return master_fight(user);
1605 }
1606
1607 bool master_fight(aClient *user)
1608 {
1609 if (!is_playing(user))
1610 return false;
1611 else
1612 return user->stats->getMaster() != NULL;
1613 }
1614
1615 bool dragon_fight(char *u)
1616 {
1617 aClient *user;
1618 if (!(user = find(u)))
1619 return false;
1620 else
1621 return dragon_fight(user);
1622 }
1623
1624 bool dragon_fight(aClient *user)
1625 {
1626 if (!is_playing(user))
1627 return false;
1628 else
1629 return (isDragonFight(user->stats));
1630 }
1631
1632 bool alphaNumeric(const char *str)
1633 {
1634 int len = strlen(str);
1635 for (int x = 0; x < len; x++)
1636 {
1637 if (!((int(str[x]) >= 65 && int(str[x]) <= 90) || (int(str[x]) >= 97 && int(str[x]) <= 122) || (int(str[x]) >= 48 && int(str[x]) <= 57) || int(str[x]) == 95))
1638 return false;
1639 }
1640 return true;
1641 }
1642
1643 void do_fight(char *u)
1644 {
1645 aClient *ni;
1646 Player *battle;
1647
1648 char *nick = strtok(NULL, " ");
1649
1650 if (!nick)
1651 {
1652 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
1653 return;
1654 }
1655 else if (!(ni = find(u)))
1656 {
1657 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1658 return;
1659 }
1660 else if (isIgnore(ni))
1661 {
1662 #ifdef DEBUGMODE
1663 log("Ignoring %s.", ni->getNick());
1664 #endif
1665 return;
1666 }
1667 else if (!is_playing(ni))
1668 {
1669 notice(s_GameServ, u, "You are not playing!");
1670 return;
1671 }
1672
1673 updateTS(ni->stats);
1674
1675 if (ni->stats->getPlayerFights() <= 0)
1676 {
1677 ni->stats->setPlayerFights(0); // just to be safe
1678 notice(s_GameServ, u, "You are out of player fights for the "\
1679 "day. You have to wait until tomorrow!");
1680 }
1681 else if (!(battle = findplayer(nick)))
1682 {
1683 notice(s_GameServ, u, "Player %s not found!", nick);
1684 }
1685 else if (!isAlive(ni->stats))
1686 {
1687 notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!");
1688 }
1689 else if (!is_playing(battle->getClient()))
1690 {
1691 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
1692 }
1693
1694 /* offline fighting not available yet
1695 else if (!(fight = finduser(nick)))
1696 {
1697 ni->stats->battle = battle;
1698 battle->battle = ni;
1699 setYourTurn(ni->stats);
1700 clearYourTurn(battle->stats);
1701
1702 notice(s_GameServ, u, "You decide to fight %s while they're "\
1703 "not in the realm!",
1704 battle->stats->name.c_str());
1705 display_players(u);
1706 }
1707 */
1708 else if (stricmp(ni->stats->getName().c_str(), battle->getName().c_str()) == 0)
1709 {
1710 notice(s_GameServ, u, "Are you trying to commit suicide!?");
1711 }
1712 else if (!isAlive(battle))
1713 {
1714 notice(s_GameServ, u, "They are dead. Cannot fight dead players!");
1715 }
1716 else if (player_fight(battle->getClient()))
1717 {
1718 notice(s_GameServ, u, "%s is fighting %s already!", battle->getName().c_str(), battle->getBattle()->stats->getName().c_str());
1719 }
1720 else if (master_fight(battle->getClient()))
1721 {
1722 notice(s_GameServ, u, "%s is fighting their master!", battle->getName().c_str());
1723 }
1724 else if (is_fighting(battle->getClient()))
1725 {
1726 notice(s_GameServ, u, "%s is fighting %s already!", battle->getName().c_str(), battle->getMonster()->name.c_str());
1727 }
1728 else if (!isAdmin(ni) && isFairFights() && (ni->stats->getStrength()/2 - battle->getDefense()) > battle->getHP())
1729 {
1730 notice(s_GameServ, u, "Fair fighting is enabled, and you're too strong for %s!", battle->getName().c_str());
1731 }
1732 else if (ni->stats->getLevel() - battle->getLevel() > maxbfightdistance)
1733 {
1734 // You can't fight someone below you by more than X level(s)
1735 // level 12 can fight level (12 - X) but not < (12 - X)
1736 notice(s_GameServ, u, "You may not fight %s. You're too strong!",
1737 battle->getName().c_str());
1738 }
1739 else if (battle->getLevel() - ni->stats->getLevel() > maxafightdistance)
1740 {
1741 // You can't fight someone above you by more than X level(S)
1742 // level 1 can fight level (1 + X), but not > (1 + X)
1743 notice(s_GameServ, u, "%s, do you really have a death wish? Try the forest you "\
1744 "weakling!", ni->stats->getName().c_str());
1745 }
1746 else
1747 {
1748 // Set your battle pointer to the other player
1749 ni->stats->setBattle(battle->getClient());
1750
1751 // Set the other player's battle pointer to you
1752 battle->setBattle(ni);
1753
1754 // The initiator gets the first move (perhaps this should be 50/50)
1755 setYourTurn(ni->stats);
1756 clearYourTurn(battle);
1757
1758 // Initiate Battle sequence!
1759 ni->stats->subtractPlayerFights(1);
1760
1761 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->getName().c_str());
1762 notice(s_GameServ, c_Forest, "%s walks up and hits %s in the face! Let's see who will bite the dust.",
1763 ni->stats->getName().c_str(), battle->getName().c_str()); /* DrLnet - Modified by Kain*/
1764
1765 notice(s_GameServ, battle->getClient()->getNick(), "%s has challenged you to an online duel!", ni->stats->getName().c_str());
1766 notice(s_GameServ, battle->getClient()->getNick(), "%s gets to go first "\
1767 "because they initiated!", ni->stats->getName().c_str());
1768 notice(s_GameServ, battle->getClient()->getNick(), "Please wait while %s decides what to do.", ni->stats->getName().c_str());
1769 display_players(ni);
1770 }
1771 }
1772
1773 void do_equip(char *u)
1774 {
1775 aClient *user;
1776 pouch *p;
1777 itemContainer *equip;
1778 int id;
1779
1780 char *item = strtok(NULL, " ");
1781
1782 if (!item || int(item[0]) < 48 || int(item[0] > 57))
1783 {
1784 notice(s_GameServ, u, "SYNTAX: EQUIP ####");
1785 notice(s_GameServ, u, "Type /msg %S HELP EQUIP for more information.");
1786 return;
1787 }
1788 else if (!(user = find(u)))
1789 {
1790 notice(s_GameServ, u, "Fatal error in do_equip. Contact a(n) %S Admin");
1791 return;
1792 }
1793 else if (isIgnore(user))
1794 {
1795 #ifdef DEBUGMODE
1796 log("Ignoring %s.", user->getNick());
1797 #endif
1798 return;
1799 }
1800 else if (!is_playing(user))
1801 {
1802 notice(s_GameServ, u, "You must be playing to equip weapons and armor!");
1803 return;
1804 }
1805 id = stringtoint(item);
1806 if (!is_fighting(user))
1807 updateTS(user->stats);
1808 p = user->stats->inventory;
1809
1810
1811 if (!(equip = p->Find(id)))
1812 {
1813 if (!p->isEmpty())
1814 {
1815 notice(s_GameServ, u, "You aren't carrying that item!");
1816 }
1817 showinventory(user->stats, user);
1818 }
1819 else if (equip->getItem()->getType() != ARMOR && equip->getItem()->getType() != WEAPON)
1820 {
1821 notice(s_GameServ, u, "You can't use %s like that. Try /msg %S use", equip->getItem()->getName().c_str());
1822 }
1823 else
1824 {
1825 // Use the item
1826 notice(s_GameServ, u, "You equip %s.", equip->getItem()->getName().c_str());
1827 equip->use(user->stats);
1828 }
1829 }
1830
1831 void do_use(char *u)
1832 {
1833 aClient *user;
1834 pouch *p;
1835
1836 char *item = strtok(NULL, " ");
1837 char *numuse = strtok(NULL, " ");
1838 int id, num;
1839 itemContainer *used;
1840
1841 if (!item || int(item[0]) < 48 || int(item[0]) > 57 || (numuse && (int(numuse[0]) < 48 || int(numuse[0]) > 57)))
1842 {
1843 notice(s_GameServ, u, "SYNTAX: USE ####");
1844 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1845 return;
1846 }
1847 else if (!(user = find(u)))
1848 {
1849 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1850 return;
1851 }
1852 else if (isIgnore(user))
1853 {
1854 #ifdef DEBUGMODE
1855 log("Ignoring %s.", user->getNick());
1856 #endif
1857 return;
1858 }
1859 else if (!is_playing(user))
1860 {
1861 notice(s_GameServ, u, "You must be playing to use items!");
1862 return;
1863 }
1864 id = stringtoint(item);
1865
1866 if (!numuse)
1867 {
1868 num = 1;
1869 }
1870 else
1871 {
1872 num = stringtoint(numuse);
1873 }
1874
1875 updateTS(user->stats);
1876 p = user->stats->inventory;
1877
1878
1879 if (!(used = p->Find(id)))
1880 {
1881 if (!p->isEmpty())
1882 {
1883 notice(s_GameServ, u, "You aren't carrying that item!");
1884 }
1885 showinventory(user->stats, user);
1886 }
1887 else if (used->getItem()->getType() != POTION)
1888 {
1889 notice(s_GameServ, u, "You can't use %s like that. Try /msg %S equip", used->getItem()->getName().c_str());
1890 }
1891 else
1892 {
1893 // Use the item(s)
1894 if (num <= 1 || is_fighting(user))
1895 {
1896 notice(s_GameServ, u, "You used %s.", used->getItem()->getName().c_str());
1897 used->use(user->stats);
1898 if (used->getUses() <= 0)
1899 {
1900 p->deleteItem(used->getItem());
1901 }
1902 end_turn(user);
1903 }
1904 else if (num > 1)
1905 {
1906 int count;
1907 const char *name = used->getItem()->getName().c_str();
1908 for (count = 0; count < num; count++)
1909 {
1910 if (!(used = p->Find(id)))
1911 {
1912 break;
1913 }
1914 else
1915 {
1916 used->use(user->stats);
1917 if (used->getUses() == 0)
1918 {
1919 p->deleteItem(used->getItem());
1920 }
1921 }
1922 }
1923 notice(s_GameServ, u, "You used %d %s's", count, name);
1924 }
1925 }
1926 }
1927 void do_run(char *u)
1928 {
1929 aClient *user;
1930 Player *p, *p2 = NULL;
1931
1932 if (!(user = find(u)))
1933 {
1934 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1935 return;
1936 }
1937 else if (isIgnore(user))
1938 {
1939 #ifdef DEBUGMODE
1940 log("Ignoring %s.", user->getNick());
1941 #endif
1942 return;
1943 }
1944 else if (!is_playing(user))
1945 {
1946 notice(s_GameServ, u, "You must be playing to run!");
1947 return;
1948 }
1949
1950 updateTS(user->stats);
1951 p = user->stats;
1952
1953 if (p->getBattle())
1954 p2 = p->getBattle()->stats;
1955
1956 if (!is_fighting(user))
1957 notice(s_GameServ, u, "You run in place... try fighting next time.");
1958 else if (!player_fight(user) && !master_fight(user) && !dragon_fight(user))
1959 {
1960 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->getMonster()->name.c_str());
1961 p->delMonster();
1962 }
1963 else if (player_fight(user) && isYourTurn(p))
1964 {
1965 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->getName().c_str());
1966 notice(s_GameServ, p->getBattle()->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->getName().c_str());
1967 addNews(todaysnews, "%s ran away from %s like a little baby!!", p->getName().c_str(), p2->getName().c_str()); /* DrLnet - edited by Kain */
1968 p2->delBattle();
1969 p->delBattle();
1970 }
1971 else if (player_fight(user) && !isYourTurn(p))
1972 {
1973 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->getName().c_str());
1974 }
1975 else if (master_fight(user))
1976 {
1977 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->getMaster()->name.c_str());
1978 }
1979 else if (dragon_fight(user))
1980 {
1981 notice(s_GameServ, u, "You cannot run from %s! FIGHT!", dragon.name.c_str());
1982 }
1983 }
1984
1985 void end_turn(aClient *user)
1986 {
1987 char *nick, *u = user->getNick();
1988 Monster *fight;
1989 aClient *battle;
1990 int mhit;
1991
1992 nick = new char[strlen(user->getNick()) + 1];
1993
1994 if (!user || !is_playing(user) || !is_fighting(user))
1995 goto endturn;
1996
1997 if (!player_fight(user) && !master_fight(user))
1998 fight = user->stats->getMonster();
1999 else
2000 fight = user->stats->getMaster();
2001 battle = user->stats->getBattle();
2002
2003 if (!player_fight(user))
2004 {
2005 // Opponent's Hit
2006 mhit = (fight->strength / 2) + (rand() % (fight->strength / 2)) - (user->stats->getDefense());
2007 }
2008 else
2009 {
2010 // Opponent's Hit
2011 mhit = (battle->stats->getStrength() / 2) + (rand() % (battle->stats->getStrength() / 2)) - user->stats->getDefense();
2012 }
2013 if (!player_fight(user))
2014 {
2015
2016 if (mhit > 0)
2017 {
2018 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
2019 fight->name.c_str(), fight->weapon.c_str(), mhit);
2020 }
2021 else if (mhit <= 0)
2022 notice(s_GameServ, u, "%s completely misses you!", fight->name.c_str());
2023
2024 if (mhit >= user->stats->getHP())
2025 {
2026 if (!master_fight(user))
2027 {
2028 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name.c_str());
2029 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
2030 "of your experience!");
2031 user->stats->setGold(0);
2032 user->stats->subtractExp((long int)(user->stats->getExp() * .10));
2033 user->stats->setHP(0);
2034 user->stats->delMonster();
2035 clearAlive(user->stats);
2036 goto endturn;
2037 }
2038 else
2039 {
2040 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
2041 "until tomorrow to try again", user->stats->getMaster()->name.c_str());
2042 user->stats->delMonster();
2043 user->stats->delMaster();
2044 goto endturn;
2045 }
2046 }
2047 else
2048 {
2049 if (mhit > 0)
2050 user->stats->subtractHP(mhit);
2051 display_monster(u);
2052 goto endturn;
2053 }
2054 }
2055 else
2056 {
2057 clearYourTurn(user->stats);
2058 setYourTurn(battle->stats);
2059 display_players(battle);
2060 }
2061 endturn:
2062 delete []nick;
2063 }
2064
2065 void do_heal(char *u)
2066 {
2067 aClient *ni;
2068 char *amount = strtok(NULL, " ");
2069 int price, num;
2070
2071 if (!amount)
2072 {
2073 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
2074 return;
2075 }
2076 else if (!(ni = find(u)))
2077 {
2078 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2079 return;
2080 }
2081 else if (isIgnore(ni))
2082 {
2083 #ifdef DEBUGMODE
2084 log("Ignoring %s.", ni->getNick());
2085 #endif
2086 return;
2087 }
2088 else if (!is_playing(ni))
2089 {
2090 notice(s_GameServ, u, "You aren't playing!");
2091 return;
2092 }
2093 else if (!isAlive(ni->stats))
2094 {
2095 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
2096 return;
2097 }
2098 else if (is_fighting(ni))
2099 {
2100 notice(s_GameServ, u, "You can't heal in battle!");
2101 return;
2102 }
2103 else if (ni->stats->getHP() >= ni->stats->getMaxHP())
2104 {
2105 notice(s_GameServ, u, "You don't need healing!");
2106 return;
2107 }
2108
2109 updateTS(ni->stats);
2110 if (stricmp(amount, "ALL") == 0)
2111 {
2112 price = ni->stats->getLevel() * 3;
2113 if (ni->stats->getGold() < (ni->stats->getMaxHP() - ni->stats->getHP()) * price)
2114 {
2115 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
2116 (long int)ni->stats->getGold()/price, price);
2117 ni->stats->addHP(ni->stats->getGold() / price);
2118 ni->stats->setGold(ni->stats->getGold() % price);
2119 }
2120 else
2121 {
2122 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
2123 "per point.", price);
2124 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
2125 (ni->stats->getMaxHP() - ni->stats->getHP()),
2126 (price * (ni->stats->getMaxHP() - ni->stats->getHP())) );
2127 ni->stats->subtractGold(price * (ni->stats->getMaxHP() - ni->stats->getHP()));
2128 ni->stats->healall();
2129 }
2130 }
2131 else if (isstringnum(amount))
2132 {
2133 num = stringtoint(amount);
2134 price = ni->stats->getLevel() * 3;
2135 if (ni->stats->getGold() < price * num)
2136 {
2137 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
2138 (long int)ni->stats->getGold()/price);
2139 }
2140 else if (num <= ni->stats->getMaxHP() - ni->stats->getHP())
2141 {
2142 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
2143 num, price);
2144 ni->stats->addHP(num);
2145 ni->stats->subtractGold(num * price);
2146 }
2147 else if (num > ni->stats->getMaxHP() - ni->stats->getHP())
2148 {
2149 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
2150 "per point.", price);
2151 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
2152 (ni->stats->getMaxHP() - ni->stats->getHP()));
2153 ni->stats->subtractGold(price * (ni->stats->getMaxHP() - ni->stats->getHP()));
2154 ni->stats->healall();
2155 }
2156 }
2157 else if (amount[0] == '-')
2158 notice(s_GameServ, u, "You trying to cheat?");
2159 else
2160 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
2161 }
2162
2163 int isstringnum(char *num)
2164 {
2165 unsigned int x;
2166 for (x = 0; x < strlen(num); x++)
2167 {
2168 if ((int)num[x] < 48 || (int)num[x] > 57)
2169 return 0;
2170 }
2171 return 1;
2172 }
2173
2174 long int stringtoint(char *number)
2175 {
2176 return atol(number);
2177 }
2178
2179 long int pow(int x, int y)
2180 {
2181 long int value = 0;
2182 int count = 0;
2183 value += x;
2184
2185 if (x != 0 && y != 0)
2186 {
2187 for (count = 1; count <= y - 1; count++)
2188 value *= x;
2189 }
2190 else
2191 {
2192 return 1;
2193 }
2194 return value;
2195 }
2196
2197 long int chartoint(char ch)
2198 {
2199 if (int(ch) >= 48 && int(ch) <= 57)
2200 return int(ch) - 48;
2201 else
2202 return 0;
2203 }
2204
2205 int save_gs_dbase()
2206 {
2207 list<Player*>::iterator iter;
2208 Player *it;
2209 ofstream outfile;
2210
2211 outfile.open(playerdata);
2212
2213 if (!outfile)
2214 {
2215 log("Error opening %s", playerdata);
2216 return 0;
2217 }
2218
2219 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
2220 {
2221 for(iter = players[x].begin(); iter != players[x].end(); iter++)
2222 {
2223 it = (*iter);
2224 clearYourTurn(it);
2225 item *w, *a;
2226 w = it->getWeapon();
2227 a = it->getArmor();
2228
2229 outfile << it->getName().c_str() << ' ' << it->getLevel() << ' ' << it->getExp() << ' ' << it->getGold() << ' ' << it->getBank() << ' '<< it->getHP() << ' ' << it->getMaxHP() << ' ' << it->getStrength() << ' ' << it->getDefense() << ' ' << it->getForestFights() << ' ' << it->getPlayerFights() << ' ' << it->getFlags() << ' ' << it->getPassword().c_str() << ' ' << it->lastlogin << ' ' << (w ? w->getID() : 0) << ' ' << (a ? a->getID() : 0);
2230
2231 // Traverse the list and write out each item ID and how many uses are left
2232 if (!it->inventory->isEmpty())
2233 {
2234 list<itemContainer> *myitems;
2235 list<itemContainer>::iterator item_iter;
2236 myitems = it->inventory->getItems();
2237
2238 for(item_iter = myitems->begin();item_iter != myitems->end();item_iter++)
2239 {
2240 outfile << ' ' << (*item_iter).getItem()->getID() << ' ' << (*item_iter).getUses();
2241 }
2242 }
2243 outfile << endl;
2244 }
2245 }
2246 outfile.close();
2247 return 1;
2248 }
2249
2250 int load_dragon()
2251 {
2252 ifstream infile;
2253 char *buf;
2254
2255 infile.open(dragondata);
2256
2257 if (infile.fail())
2258 {
2259 infile.clear();
2260 log ("Error opening %s. Trying initialdragon.dat", dragondata);
2261 infile.open("data/initialdragon.dat");
2262 if (infile.fail())
2263 {
2264 log ("Error opening data/initialdragon.dat");
2265 return 0;
2266 }
2267 }
2268
2269 buf = new char[1024];
2270
2271 infile.getline(buf, 1024, '\n');
2272 infile.close(); // Done with the file... we have what we want
2273
2274 dragon.name = strtok(buf, "~");
2275 dragon.weapon = strtok(NULL, "~");
2276 dragon.gold = 0;
2277 dragon.exp = 0;
2278 dragon.strength = stringtoint(strtok(NULL, "~"));
2279 dragon.hp = stringtoint(strtok(NULL, "~"));
2280 dragon.defense = stringtoint(strtok(NULL, "~"));
2281 dragon.death = strtok(NULL, "");
2282
2283 log ("loaded dragon: %s", dragon.name.c_str());
2284
2285 delete []buf;
2286
2287 return save_dragon(); // Save the dragon file and return the status code :)
2288 }
2289
2290 int save_dragon()
2291 {
2292 ofstream outfile;
2293
2294 outfile.open(dragondata);
2295
2296 if (outfile.fail())
2297 {
2298 log ("Error opening %s. Exiting.", dragondata);
2299 return 0;
2300 }
2301
2302 outfile << dragon.name.c_str() << '~' << dragon.weapon.c_str() << '~'
2303 << dragon.strength << '~' << dragon.hp << '~'
2304 << dragon.defense << '~' << dragon.death.c_str() << "\n^"
2305 << endl;
2306
2307 outfile.close();
2308
2309 return 1;
2310 }
2311
2312 int load_store()
2313 {
2314 ifstream infile;
2315 char *buf;
2316 item *tempItem;
2317 buf = new char[1024];
2318 long id;
2319
2320 infile.open(storeitemdata);
2321
2322 if (infile.fail())
2323 {
2324 log("Error opening %s", storeitemdata);
2325 return 0;
2326 }
2327
2328 while (infile.getline(buf, 1024, '\n'))
2329 {
2330 try
2331 {
2332 if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '\0')
2333 {
2334 item *tempItem2;
2335 id = stringtoint(strtok(buf, ""));
2336 tempItem2 = findItemByID(id);
2337 if (tempItem2 == NULL)
2338 {
2339 log("Invalid ID in %s", storeitemdata);
2340 return 0;
2341 }
2342
2343 tempItem = tempItem2;
2344 store.push_back(tempItem);
2345 }
2346 }
2347 catch (char *str)
2348 {
2349 log("Exception loading store: %s", str);
2350 delete []buf;
2351 return 0;
2352 }
2353 }
2354 delete []buf;
2355 return 1;
2356 }
2357 int load_tavern()
2358 {
2359 ifstream infile;
2360 char *buf;
2361 tavernItem tempItem;
2362 buf = new char[1024];
2363 long id, level;
2364
2365 infile.open(tavernitemdata);
2366 if (infile.fail())
2367 {
2368 log("Error opening %s", tavernitemdata);
2369 return 0;
2370 }
2371
2372 while (infile.getline(buf, 1024, '\n'))
2373 {
2374 try
2375 {
2376 if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '\0')
2377 {
2378 item *tempItem2;
2379 id = stringtoint(strtok(buf, "~"));
2380 level = stringtoint(strtok(NULL, ""));
2381 tempItem2 = findItemByID(id);
2382 if (tempItem2 == NULL)
2383 {
2384 log("Invalid ID in %s", tavernitemdata);
2385 return 0;
2386 }
2387 tempItem.setItem(tempItem2);
2388 tempItem.setLevel(level);
2389 tavern.push_back(tempItem);
2390 }
2391 }
2392 catch (char *str)
2393 {
2394 log("Exception loading tavern: %s", str);
2395 delete []buf;
2396 return 0;
2397 }
2398 }
2399 delete []buf;
2400 return 1;
2401 }
2402 int load_items()
2403 {
2404 ifstream infile;
2405 char *buf;
2406 item *tempItem;
2407
2408 buf = new char[1024];
2409
2410 infile.open(itemdata);
2411
2412 if (infile.fail())
2413 {
2414 log("Error opening %s", itemdata);
2415 return 0;
2416 }
2417
2418 while (infile.getline(buf, 1024, '\n'))
2419 {
2420 if (buf[0] == '^')
2421 break;
2422 try
2423 {
2424 if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '\0')
2425 {
2426 switch(buf[0])
2427 {
2428 case '1':
2429 tempItem = new weapon();
2430 break;
2431 case '2':
2432 tempItem = new armor();
2433 break;
2434 case '3':
2435 tempItem = new potion();
2436 break;
2437 default:
2438 log("Invalid Item Type %c in %s", buf[0], itemdata);
2439 delete []buf;
2440 return 0;
2441 break;
2442 }
2443 if(tempItem->setData(buf))
2444 {
2445 Items.push_back(tempItem);
2446 }
2447 }
2448 }
2449 catch (char *str)
2450 {
2451 log("Exception loading items: %s", str);
2452 delete []buf;
2453 return 0;
2454 }
2455 }
2456 delete []buf;
2457 return 1;
2458 }
2459
2460 int load_gs_dbase()
2461 {
2462 ifstream infile;
2463 Player *p;
2464 char *tempname, *buf, *password;
2465 int tempnum;
2466 buf = new char[100000];
2467
2468 infile.open(playerdata);
2469
2470 if (infile.fail())
2471 {
2472 log("Error opening %s", playerdata);
2473 return 0;
2474 }
2475
2476
2477 for (int x = 0; x < U_TABLE_SIZE; x++)
2478 {
2479 list<Player*>::iterator iter;
2480
2481 for (iter = players[x].begin(); iter != players[x].end(); iter++)
2482 {
2483 logout((*iter)->getClient());
2484 delete (*iter);
2485 }
2486 players[x].clear();
2487 }
2488
2489 while (infile.getline(buf, 100000, '\n'))
2490 {
2491 tempname = strtok(buf, " ");
2492 p = new Player(tempname);
2493
2494 p->setLevel(stringtoint(strtok(NULL, " ")));
2495 p->setExp(stringtoint(strtok(NULL, " ")));
2496 p->setGold(stringtoint(strtok(NULL, " ")));
2497 p->setBank(stringtoint(strtok(NULL, " ")));
2498 tempnum = stringtoint(strtok(NULL, " "));
2499 p->setMaxHP(stringtoint(strtok(NULL, " ")));
2500 p->setHP(tempnum);
2501 p->setStrength(stringtoint(strtok(NULL, " ")));
2502 p->setDefense(stringtoint(strtok(NULL, " ")));
2503 p->setForestFights(stringtoint(strtok(NULL, " ")));
2504 p->setPlayerFights(stringtoint(strtok(NULL, " ")));
2505 p->setFlags(stringtoint(strtok(NULL, " ")));
2506
2507
2508
2509 password = strtok(NULL, " ");
2510 p->setRawPassword(password);
2511 tempname = strtok(NULL, " ");
2512
2513 if (tempname)
2514 p->lastlogin = stringtoint(tempname);
2515 else
2516 p->lastlogin = time(NULL);
2517
2518 tempname = strtok(NULL, " ");
2519 tempnum = stringtoint(tempname);
2520 item *tempitem;
2521 if (tempnum != 0)
2522 {
2523 tempitem = findItemByID(tempnum);
2524 p->setWeapon(*tempitem);
2525 }
2526
2527 tempname = strtok(NULL, " ");
2528 tempnum = stringtoint(tempname);
2529
2530 if (tempnum != 0)
2531 {
2532 tempitem = findItemByID(tempnum);
2533 p->setArmor(*tempitem);
2534 }
2535
2536
2537 unsigned long hv = iHASH((unsigned char *) p->getName().c_str());
2538
2539 p->setClient(NULL);
2540
2541 for (tempname = strtok(NULL, " "); tempname != NULL; tempname = strtok(NULL, " "))
2542 {
2543 long int id, uses;
2544 list<item*>::iterator item_iter;
2545 id = stringtoint(tempname);
2546 tempname = strtok(NULL, " ");
2547 uses = stringtoint(tempname);
2548
2549 item_iter = Items.begin();
2550 while (item_iter != Items.end())
2551 {
2552 if ((*item_iter)->getID() == id)
2553 {
2554 // Don't sort every time you add an item or it eats CPU
2555 p->inventory->addItemNoChecks((*item_iter))->setUses(uses);
2556 }
2557 item_iter++;
2558 }
2559 }
2560 p->inventory->sort();
2561 players[hv].push_back(p);
2562 }
2563
2564 delete [] buf;
2565 infile.close();
2566 return 1;
2567 }
2568
2569 bool passcmp(const char *encrypted, char *plaintext)
2570 {
2571 char salt[3];
2572 char *plaintext2, *plainToencrypt;
2573 bool same = false;
2574
2575 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
2576 strcpy(plaintext2, plaintext);
2577
2578 salt[0] = encrypted[0];
2579 salt[1] = encrypted[1];
2580 salt[3] = '\0';
2581
2582 plainToencrypt = crypt(plaintext2, salt);
2583
2584 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
2585
2586 delete []plaintext2;
2587
2588 return same;
2589 }
2590
2591 bool check_password(char *name, char *plaintext)
2592 {
2593 Player *p;
2594
2595 if (!(p = findplayer(name)))
2596 return false;
2597 else
2598 {
2599 return passcmp(p->getPassword().c_str(), plaintext);
2600 }
2601 }
2602
2603 void do_store(char *u)
2604 {
2605 list<item*>::iterator item_iterator;
2606 item *tempItem;
2607 char *cmd = strtok(NULL, " ");
2608 char *num = strtok(NULL, " ");
2609 char *space;
2610 int id;
2611 aClient *user;
2612 Player *p;
2613
2614
2615 if (!cmd || !num)
2616 {
2617 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2618 notice(s_GameServ, u, " \ 2STORE SELL NUMBER\ 2");
2619 notice(s_GameServ, u, " \ 2STORE BUY \1fNUMBER\1f\ 2");
2620 return;
2621 }
2622 else if (!(user = find(u)))
2623 {
2624 log("Fatal Error: could not find %s in client list", u);
2625 return;
2626 }
2627 else if (isIgnore(user))
2628 {
2629 #ifdef DEBUGMODE
2630 log("Ignoring %s.", user->getNick());
2631 #endif
2632 return;
2633 }
2634 else if (!is_playing(user))
2635 {
2636 notice(s_GameServ, u, "You must be playing to use the store!");
2637 return;
2638 }
2639 else if (is_fighting(user))
2640 {
2641 notice(s_GameServ, u, "You can't go to the store while fighting!");
2642 return;
2643 }
2644 else if (!isAlive(user->stats))
2645 {
2646 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
2647 return;
2648 }
2649 updateTS(user->stats);
2650
2651 if (stricmp(cmd, "LIST") == 0)
2652 {
2653 if (stricmp(num, "WEAPONS") == 0)
2654 {
2655 notice(s_GameServ, u, "Welcome to Kain's Armory");
2656 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
2657 for (item_iterator = store.begin(); item_iterator != store.end(); ++item_iterator)
2658 {
2659 if ((*item_iterator)->getType() == WEAPON)
2660 {
2661 space = spaces(strlen((*item_iterator)->getName().c_str()), ".");
2662 notice(s_GameServ, u, "%s%ld. %s%s%ld", ((*item_iterator)->getID() < 10 ? " " : ""), (*item_iterator)->getID(), (*item_iterator)->getName().c_str(), space, (*item_iterator)->price());
2663 free(space);
2664 }
2665 }
2666 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2#\ 2.");
2667 notice(s_GameServ, u, "Where # is the weapon number from the menu above.");
2668
2669 }
2670 else if (stricmp(num, "ARMOR") == 0)
2671 {
2672 notice(s_GameServ, u, "Welcome to Kain's Armory");
2673 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
2674 for (item_iterator = store.begin(); item_iterator != store.end(); ++item_iterator)
2675 {
2676 if ((*item_iterator)->getType() == ARMOR)
2677 {
2678 space = spaces(strlen((*item_iterator)->getName().c_str()), ".");
2679 notice(s_GameServ, u, "%s%ld. %s%s%d",((*item_iterator)->getID() < 10 ? " " : ""), (*item_iterator)->getID(), (*item_iterator)->getName().c_str(), space, (*item_iterator)->price());
2680 free(space);
2681 }
2682 }
2683
2684 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy #");
2685 notice(s_GameServ, u, "Where # is the armor number from the menu above.");
2686 }
2687
2688 }
2689 else if (stricmp(cmd, "BUY") == 0)
2690 {
2691 p = user->stats;
2692 if (!num)
2693 {
2694 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY \1f#\1f\ 2");
2695 return;
2696 }
2697 else
2698 {
2699 id = stringtoint(num);
2700 }
2701
2702 if (!isstringnum(num))
2703 {
2704 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY \1f#\1f\ 2");
2705 return;
2706 }
2707 else if (!(tempItem = findStoreItemByID(id)))
2708 {
2709 notice(s_GameServ, u, "Sorry, we don't carry that item!");
2710 return;
2711 }
2712 else if (p->getGold() < tempItem->price())
2713 {
2714 notice(s_GameServ, u, "You can't afford to buy %s", tempItem->getName().c_str());
2715 return;
2716 }
2717 else if (p->inventory->addItem(tempItem))
2718 {
2719 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", tempItem->getName().c_str());
2720 p->subtractGold(tempItem->price());
2721 notice(s_GameServ, u, "Don't forget to type /msg %S equip %ld", tempItem->getID());
2722 }
2723 else
2724 {
2725 notice(s_GameServ, u, "You can't carry any more!");
2726 }
2727 }
2728 else if (stricmp(cmd, "SELL" ) == 0)
2729 {
2730 itemContainer *tempContainer;
2731 p = user->stats;
2732 id = stringtoint(num);
2733 if (!isstringnum(num))
2734 {
2735 notice(s_GameServ, u, "SYNTAX: /msg %S store sell #");
2736 return;
2737 }
2738 else if (!(tempContainer = p->inventory->Find(id)))
2739 {
2740 notice(s_GameServ, u, "You're not carrying that!");
2741 return;
2742 }
2743 else if (p->getGold() >= 2000000000)
2744 {
2745 notice(s_GameServ, u, "You have enough gold. Just hang on to it for now.");
2746 }
2747 else
2748 {
2749 tempItem = tempContainer->getItem();
2750
2751 notice(s_GameServ, u, "Thank you for your business! We gave you %ld gold for %s!", (tempItem->price() / 2), tempItem->getName().c_str());
2752 p->addGold((tempItem->price() / 2));
2753 p->inventory->deleteItem(tempItem);
2754 if (tempItem == p->getWeapon())
2755 {
2756 notice(s_GameServ, u, "Since you equipped %s, you're going to have to reequip something", tempItem->getName().c_str());
2757 tempItem->undo(p);
2758 p->clearWeapon();
2759 }
2760 else if (tempItem == p->getArmor())
2761 {
2762 tempItem->undo(p);
2763 notice(s_GameServ, u, "Since you equipped %s, you're going to have to reequip something", tempItem->getName().c_str());
2764 p->clearArmor();
2765 }
2766 }
2767 }
2768 else
2769 {
2770 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2771 notice(s_GameServ, u, " \ 2STORE SELL #\ 2");
2772 notice(s_GameServ, u, " \ 2STORE BUY \1f#\1f\ 2");
2773 return;
2774 }
2775 }
2776 void do_inventory(char *u)
2777 {
2778 aClient *user;
2779
2780 if (!(user = find(u)))
2781 {
2782 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2783 return;
2784 }
2785 else if (isIgnore(user))
2786 {
2787 #ifdef DEBUGMODE
2788 log("Ignoring %s.", user->getNick());
2789 #endif
2790 return;
2791 }
2792 else if (!is_playing(user))
2793 {
2794 notice(s_GameServ, u, "You must be playing to check your inventory!");
2795 return;
2796 }
2797 if (!is_fighting(user))
2798 updateTS(user->stats);
2799 showinventory(user->stats, user);
2800 }
2801
2802 void showinventory(Player *from, aClient *to)
2803 {
2804 char *nick;
2805 if (!to || !from)
2806 {
2807 return;
2808 }
2809
2810 nick = to->getNick();
2811
2812 if (from->inventory->isEmpty())
2813 {
2814 notice(s_GameServ, nick, "You aren't carrying anything");
2815 return;
2816 }
2817
2818 list <itemContainer> *items;
2819 items = from->inventory->getItems();
2820
2821 list <itemContainer>::iterator item_iter, item_iter2;
2822 item_iter = items->begin();
2823
2824 notice(s_GameServ, nick, "Inventory for %s:", from->getName().c_str());
2825 long count;
2826 while (item_iter != items->end())
2827 {
2828 // Display a list of counted items so as not to show an extra line for duplicate items
2829 count = 0;
2830 item_iter2 = item_iter;
2831 while (item_iter != items->end() && (*item_iter) == (*item_iter2))
2832 {
2833 if ((*item_iter) == (*item_iter2))
2834 {
2835 ++count;
2836 }
2837 else
2838 {
2839 break;
2840 }
2841 ++item_iter;
2842 }
2843 notice(s_GameServ, nick, "%ld.) %s (%ld)", (*item_iter2).getItem()->getID(), (*item_iter2).getItem()->getName().c_str(), count);
2844 }
2845 }
2846
2847 void do_tavern(char *u)
2848 {
2849 char *cmd = strtok(NULL, " ");
2850
2851 aClient *user;
2852 Player *p;
2853
2854 if (!(user = find(u)))
2855 {
2856 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2857 return;
2858 }
2859 else if (isIgnore(user))
2860 {
2861 #ifdef DEBUGMODE
2862 log("Ignoring %s.", user->getNick());
2863 #endif
2864 return;
2865 }
2866 else if (!is_playing(user))
2867 {
2868 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2869 return;
2870 }
2871 else if (is_fighting(user))
2872 {
2873 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2874 return;
2875 }
2876
2877 updateTS(user->stats);
2878 p = user->stats;
2879
2880 if (!cmd)
2881 {
2882 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary and General Store");
2883 notice(s_GameServ, u, "Your commands:");
2884 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2885 notice(s_GameServ, u, "What'll it be?");
2886 }
2887 else if (stricmp(cmd, "LIST") == 0)
2888 {
2889 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2890 showTavern(user);
2891 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
2892 }
2893 else if (stricmp(cmd, "BUY") == 0)
2894 {
2895 int amt = 1;
2896 char *chid = strtok(NULL, " ");
2897 char *amount = strtok(NULL, " ");
2898
2899 if (amount)
2900 amt = stringtoint(amount);
2901
2902 if (!chid)
2903 {
2904 notice(s_GameServ, u, "SYNTAX: TAVERN BUY # [#]");
2905 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 6001");
2906 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 6001 10");
2907 return;
2908 }
2909 long id = stringtoint(chid);
2910 tavernItem *tempItem;
2911
2912 if (!(tempItem = findTavernItemByID(id)) || user->stats->getLevel() < tempItem->getLevel())
2913 {
2914 notice(s_GameServ, u, "Invalid Choice!");
2915 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2916 showTavern(user);
2917 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
2918 return;
2919 }
2920 else if (!amount && user->stats->getGold() < tempItem->getItem()->price())
2921 {
2922 notice(s_GameServ, u, "You don't have enough gold!");
2923 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2924 showTavern(user);
2925 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY #");
2926 }
2927 else if (user->stats->getGold() < amt * tempItem->getItem()->price())
2928 {
2929 notice(s_GameServ, u, "You don't have enough gold!");
2930 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2931 showTavern(user);
2932 notice(s_GameServ, u, "To buy an item, type /msg %S TAVERN BUY # [#]");
2933 }
2934 else
2935 {
2936 if (amount)
2937 {
2938 int amt = stringtoint(amount);
2939 if (amt < 0 || amount[0] == '-')
2940 {
2941 notice(s_GameServ, u, "You trying to steal from me?");
2942 }
2943 else if (user->stats->inventory->addItem(tempItem->getItem(), amt) == NULL)
2944 {
2945 notice(s_GameServ, u, "You can't carry that many!");
2946 }
2947 else
2948 {
2949 notice(s_GameServ, u, "%d %s's coming right up!", amt, tempItem->getItem()->getName().c_str());
2950 user->stats->subtractGold(tempItem->getItem()->price() * amt);
2951 }
2952 }
2953 else
2954 {
2955 if (user->stats->inventory->addItem(tempItem->getItem()) == NULL)
2956 {
2957 notice(s_GameServ, u, "You can't carry any more!");
2958 }
2959 else
2960 {
2961 notice(s_GameServ, u, "One %s coming right up!", tempItem->getItem()->getName().c_str());
2962 user->stats->subtractGold(tempItem->getItem()->price());
2963 }
2964 }
2965 }
2966 }
2967 else
2968 {
2969 notice(s_GameServ, u, "Improper Syntax.");
2970 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2971 }
2972 return;
2973 }
2974
2975 void do_bank(char *u)
2976 {
2977 char *cmd = strtok(NULL, " ");
2978 char *amount = strtok(NULL, " ");
2979 char *nick = strtok(NULL, " ");
2980
2981 aClient *user;
2982 Player *p;
2983
2984 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
2985 {
2986 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
2987 notice (s_GameServ, u, "BANK BALANCE");
2988 return;
2989 }
2990 else if (!(user = find(u)))
2991 {
2992 notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\
2993 " admin for help");
2994 log("Fatal Error. Couldn't find %s while executing do_bank()", u);
2995 return;
2996 }
2997 else if (isIgnore(user))
2998 {
2999 #ifdef DEBUGMODE
3000 log("Ignoring %s.", user->getNick());
3001 #endif
3002 return;
3003 }
3004 else if (!is_playing(user))
3005 {
3006 notice(s_GameServ, u, "You must be playing to use the bank!");
3007 return;
3008 }
3009 else if (is_fighting(user))
3010 {
3011 notice(s_GameServ, u, "You can't go to the bank during a fight!");
3012 return;
3013 }
3014 updateTS(user->stats);
3015 if (stricmp(cmd, "BALANCE") == 0)
3016 {
3017 showBankBalance(u);
3018 return;
3019 }
3020 else if (!isAlive(user->stats))
3021 {
3022 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
3023 return;
3024 }
3025 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
3026 {
3027 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
3028 return;
3029 }
3030 if (stringtoint(amount) < 0)
3031 {
3032 notice(s_GameServ, u, "Sorry. This bank is not licensed "\
3033 "to handle such sums of cash, noble Lord.");
3034 return;
3035 }
3036 p = user->stats;
3037
3038 if (stricmp(cmd, "DEPOSIT") == 0)
3039 {
3040 if (p->getBank() == 2000000000)
3041 {
3042 notice(s_GameServ, u, "Your bank account is full, sire!");
3043 return;
3044 }
3045 else if (stricmp(amount, "ALL") == 0)
3046 {
3047 if (2000000000 - p->getBank() < p->getGold())
3048 {
3049 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
3050 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->getBank()));
3051 p->subtractGold((2000000000 - p->getBank()));
3052 p->setBank(2000000000);
3053 showBankBalance(u);
3054 }
3055 else
3056 {
3057 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->getGold());
3058 p->addBank(p->getGold());
3059 p->setGold(0);
3060 showBankBalance(u);
3061 }
3062 }
3063 else if (stringtoint(amount) > p->getGold())
3064 {
3065 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->getGold());
3066 showBankBalance(u);
3067 return;
3068 }
3069 else
3070 {
3071 if (2000000000 - p->getBank() < stringtoint(amount))
3072 {
3073 notice(s_GameServ, u, "You don't have room in your account for that much.");
3074 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->getBank()));
3075 p->subtractGold((2000000000 - p->getBank()));
3076 p->setBank(2000000000);
3077 showBankBalance(u);
3078 }
3079 else
3080 {
3081 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
3082 p->addBank(stringtoint(amount));
3083 p->subtractGold(stringtoint(amount));
3084 showBankBalance(u);
3085 }
3086 }
3087 }
3088 else if (stricmp(cmd, "WITHDRAW") == 0)
3089 {
3090 if (p->getGold() == 2000000000)
3091 {
3092 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
3093 showBankBalance(u);
3094 return;
3095 }
3096 else if (stricmp(amount, "ALL") == 0)
3097 {
3098 if (2000000000 - p->getGold() < p->getBank())
3099 {
3100 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
3101 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->getGold()));
3102 p->subtractBank((2000000000 - p->getGold()));
3103 p->setGold(2000000000);
3104 showBankBalance(u);
3105 }
3106 else
3107 {
3108 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->getBank());
3109 p->addGold(p->getBank());
3110 p->setBank(0);
3111 showBankBalance(u);
3112 }
3113 }
3114 else if (stringtoint(amount) > p->getBank())
3115 {
3116 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->getBank());
3117 showBankBalance(u);
3118 return;
3119 }
3120 else
3121 {
3122 if (2000000000 - p->getGold() < stringtoint(amount))
3123 {
3124 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
3125 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
3126 (2000000000 - p->getGold()));
3127 p->subtractBank((2000000000 - p->getGold()));
3128 p->setGold(2000000000);
3129 showBankBalance(u);
3130 }
3131 else
3132 {
3133 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
3134 p->addGold(stringtoint(amount));
3135 p->subtractBank(stringtoint(amount));
3136 showBankBalance(u);
3137 }
3138 }
3139 }
3140 }
3141
3142 void do_dragon(char *u)
3143 {
3144 aClient *user;
3145
3146 if (!(user = find(u)))
3147 {
3148 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3149 return;
3150 }
3151 else if (isIgnore(user))
3152 {
3153 #ifdef DEBUGMODE
3154 log("Ignoring %s.", user->getNick());
3155 #endif
3156 return;
3157 }
3158 else if (!is_playing(user))
3159 {
3160 notice(s_GameServ, u, "You must be playing to fight the dragon!");
3161 return;
3162 }
3163 else if (is_fighting(user))
3164 {
3165 notice(s_GameServ, u, "You are already in a fight. How will you fight the almighty dragon!?");
3166 return;
3167 }
3168 else if (!isAlive(user->stats))
3169 {
3170 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
3171 return;
3172 }
3173 else if (user->stats->getLevel() < LEVELS)
3174 {
3175 notice(s_GameServ, u, "You fool! Only those strong enough "\
3176 "to vanquish any foe should DARE fight the dragon!");
3177 notice(s_GameServ, u, "To put it in terms you can understand: "\
3178 "You are too weak. You must be Level %d!", REALLEVELS);
3179 return;
3180 }
3181
3182 updateTS(user->stats);
3183
3184 Player *p = user->stats;
3185 setMaster(p);
3186 notice(s_GameServ, u, "You approach the dragon's lair cautiously.");
3187 notice(s_GameServ, u, "The stench of sulfer fills the air as a "\
3188 "deep, red fog rolls in. The air is filled with the "\
3189 "heated mist of deadly fire from beyond the cave "\
3190 "entrance.");
3191 notice(s_GameServ, u, "You adjust your %s, tighten your grip on "\
3192 "your %s, and venture into the hot, dark cave. "\
3193 "You are surprised at the angle of descent as you climb "\
3194 "lower and lower, deeper into the dragon's den.",
3195 (p->getArmor() ? p->getArmor()->getName().c_str() : "Fists"), (p->getWeapon() ? p->getWeapon()->getName().c_str() : "Birthday Suit"));
3196 notice(s_GameServ, u, "You come to the end of the cave to find "\
3197 "a tooth. It is a large tooth... bigger than your torso."\
3198 " Suddenly the darkness lifts from the gleam of an eye "\
3199 " staring into your soul! The eye is large... HUGE!");
3200 notice(s_GameServ, u, "Just then you notice the eye begin to "\
3201 "glare orange! The tooth is moving... but it is still too "\
3202 "dark for you to make out.... THE DRAGON! You see it!");
3203 p->setMonster(&dragon);
3204 setDragonFight(p);
3205 display_monster(u);
3206 }
3207
3208 void do_master(char *u)
3209 {
3210 aClient *user;
3211
3212
3213 if (!(user = find(u)))
3214 {
3215 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3216 return;
3217 }
3218 else if (isIgnore(user))
3219 {
3220 #ifdef DEBUGMODE
3221 log("Ignoring %s.", user->getNick());
3222 #endif
3223 return;
3224 }
3225 else if (!is_playing(user))
3226 {
3227 notice(s_GameServ, u, "You must be playing to see your master!");
3228 return;
3229 }
3230 else if (is_fighting(user))
3231 {
3232 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
3233 return;
3234 }
3235 else if (!isAlive(user->stats))
3236 {
3237 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
3238 return;
3239 }
3240
3241 updateTS(user->stats);
3242
3243 char *cmd = strtok(NULL, " ");
3244 Player *p = user->stats;
3245 long int need = 0;
3246
3247 if (seenMaster(p))
3248 {
3249 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
3250 return;
3251 }
3252
3253 if (cmd != NULL)
3254 {
3255 switch(p->getLevel())
3256 {
3257 case 1:
3258 need = 200;
3259 break;
3260 case 2:
3261 need = 800;
3262 break;
3263 case 3:
3264 need = 2000;
3265 break;
3266 case 4:
3267 need = 8000;
3268 break;
3269 case 5:
3270 need = 20000;
3271 break;
3272 case 6:
3273 need = 80000;
3274 break;
3275 case 7:
3276 need = 200000;
3277 break;
3278 case 8:
3279 need = 800000;
3280 break;
3281 case 9:
3282 need = 2000000;
3283 break;
3284 case 10:
3285 need = 8000000;
3286 break;
3287 case 11:
3288 need = 20000000;
3289 break;
3290
3291 case REALLEVELS:
3292 need = p->getExp() + 1;
3293 notice(s_GameServ, u, "You are at level %d. You are the master. What's left? The DRAGON!", REALLEVELS);
3294 return;
3295 break;
3296 default:
3297 need = p->getExp() + 1; // Unknown level... don't let them fight a fake master!
3298 break;
3299 }
3300 }
3301 else
3302 {
3303 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
3304 return;
3305 }
3306
3307 if (stricmp(cmd, "FIGHT") == 0)
3308 {
3309 if (p->getExp() >= need)
3310 {
3311 setMaster(p);
3312 see_master(u);
3313 }
3314 else
3315 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.",
3316 levels[p->getLevel() - 1].master.name.c_str(), (need - p->getExp()));
3317 return;
3318 }
3319 else if (stricmp(cmd, "QUESTION") == 0)
3320 {
3321 if (p->getExp() >= need)
3322 notice(s_GameServ, u, "%s looks you up and down and decides you are more ready than you will ever be.",
3323 levels[p->getLevel() - 1].master.name.c_str());
3324 else
3325 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!",
3326 levels[p->getLevel() - 1].master.name.c_str(), p->getName().c_str());
3327
3328 return;
3329 }
3330 else
3331 {
3332 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
3333 }
3334 }
3335
3336 void see_master(char *u)
3337 {
3338 aClient *user;
3339
3340 if (!(user = find(u)))
3341 {
3342 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3343 return;
3344 }
3345
3346 if (!is_fighting(user) && is_playing(user))
3347 {
3348 Player *p = user->stats;
3349 p->setMyMaster(&levels[p->getLevel() - 1].master);
3350 p->setMonster(&levels[p->getLevel() - 1].master);
3351 display_monster(u); // Since master is the same structure, use this function
3352 }
3353 }
3354
3355 void showTavern(aClient *user)
3356 {
3357 Player *p;
3358 list<tavernItem>::iterator item_iterator;
3359 item *tempItem;
3360
3361 p = user->stats;
3362
3363 if (!p)
3364 return;
3365
3366 item_iterator = tavern.begin();
3367 if (tavern.empty())
3368 {
3369 notice(s_GameServ, user->getNick(), "Tavern is empty");
3370 return;
3371 }
3372
3373 while (item_iterator != tavern.end())
3374 {
3375 if (p->getLevel() < (*item_iterator).getLevel())
3376 {
3377 item_iterator++;
3378 continue;
3379 }
3380 tempItem = (*item_iterator).getItem();
3381 notice(s_GameServ, user->getNick(), "%d. %s for %ld gold", tempItem->getID(), tempItem->getName().c_str(), tempItem->price());
3382 item_iterator++;
3383 }
3384 }
3385
3386 void showBankBalance(const char *u)
3387 {
3388 aClient *user;
3389 Player *p;
3390
3391 if (!(user = find(u)))
3392 return;
3393
3394 p = user->stats;
3395
3396 if (!p)
3397 return;
3398
3399 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->getBank(), p->getGold());
3400 }
3401
3402 void rolloverall()
3403 {
3404 list<Player*>::iterator iter;
3405 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3406 {
3407 for (iter = players[x].begin(); iter != players[x].end(); iter++)
3408 {
3409 rollover((*iter));
3410 }
3411 }
3412 }
3413 void refreshall()
3414 {
3415 list<Player*>::iterator iter;
3416 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3417 {
3418 for (iter = players[x].begin(); iter != players[x].end(); iter++)
3419 {
3420 refresh((*iter));
3421 }
3422 }
3423 }
3424
3425 void rollover(Player *p)
3426 {
3427 if (!p)
3428 return;
3429
3430 p->addForestFights(numrolloverfights);
3431
3432 if (p->getForestFights() > maxforestfights)
3433 p->setForestFights(maxforestfights);
3434 }
3435
3436 void refresh(Player *p)
3437 {
3438 if (!p)
3439 return;
3440
3441 if (p->getHP() < p->getMaxHP())
3442 p->healall();
3443 if (p->getForestFights() < forestfights)
3444 {
3445 p->setForestFights(forestfights);
3446 }
3447
3448 p->setPlayerFights(3);
3449 setAlive(p);
3450 clearMaster(p);
3451 }
3452
3453 void do_refresh(char *u)
3454 {
3455 char *name = strtok(NULL, " ");
3456 aClient *user;
3457 Player *p;
3458
3459 if (!(user = find(u)))
3460 {
3461 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3462 log("Error: aClient not found: %s", u);
3463 return;
3464 }
3465 else if (isIgnore(user))
3466 {
3467 #ifdef DEBUGMODE
3468 log("Ignoring %s.", user->getNick());
3469 #endif
3470 return;
3471 }
3472 else if (!isAdmin(user))
3473 {
3474 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3475 return;
3476 }
3477 if (!name)
3478 {
3479 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
3480 return;
3481 }
3482 else if (stricmp(name, "ALL") == 0)
3483 {
3484 notice(s_GameServ, u, "Refreshing everyone's stats!");
3485 refreshall();
3486 }
3487 else if ((p = findplayer(name)))
3488 {
3489 notice(s_GameServ, u, "Refreshing %s.", p->getName().c_str());
3490 refresh(p);
3491 }
3492 else
3493 {
3494 notice(s_GameServ, u, "Player %s not found.", name);
3495 return;
3496 }
3497 }
3498
3499
3500 void resetall()
3501 {
3502 list<Player*>::iterator iter;
3503 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3504 {
3505 for (iter = players[x].begin(); iter != players[x].end(); iter++)
3506 {
3507 reset((*iter));
3508 }
3509 }
3510 }
3511
3512 void reset(Player *p)
3513 {
3514 item *tempItem;
3515
3516 if (!p)
3517 return;
3518
3519 p->reset();
3520 // Add the stick and clothes
3521 tempItem = findItemByID(3001);
3522 p->inventory->addItem((*Items.begin()))->use(p); // Add the stick
3523 p->inventory->addItem(tempItem)->use(p); // Add Clothes
3524 }
3525
3526 void updateTS(Player *p)
3527 {
3528 if (!p)
3529 return;
3530
3531 #ifdef DEBUGMODE
3532 log("Old timestamp for %s: %ld", p->getName().c_str(), p->lastcommand);
3533 #endif
3534 p->lastcommand = time(NULL);
3535 #ifdef DEBUGMODE
3536 log("New timestamp for %s: %ld", p->getName().c_str(), p->lastcommand);
3537 #endif
3538 PF_cleartimedout(p);
3539
3540 }
3541
3542 bool timedOut(Player *p)
3543 {
3544 if (!p)
3545 return false;
3546 else if (p->lastcommand == 0)
3547 return false;
3548 else
3549 {
3550 if ((time(NULL) - p->lastcommand) >= maxidletime)
3551 return true;
3552
3553 return false;
3554 }
3555 }
3556
3557 void timeOutEvent(Player *p)
3558 {
3559 if (!p || !is_playing(p->getClient())) // then they're not playing
3560 return;
3561
3562 char *nick = p->getClient()->getNick();
3563
3564 if (player_fight(p->getClient()) && isYourTurn(p))
3565 {
3566 // Check to see if they were the idler or if it was the other
3567 // person
3568 if (!PF_timedout(p->getBattle()->stats))
3569 {
3570 // This person's last command was given earlier,
3571 // so this person is the idler
3572 notice(s_GameServ, nick, "You timed out "\
3573 "during a fight. You lose your turn!");
3574 notice(s_GameServ, p->getBattle()->getNick(),
3575 "%s hesitated for too long. Your move.", p->getName().c_str());
3576 clearYourTurn(p);
3577 setYourTurn(p->getBattle()->stats);
3578
3579 // Update the TS for both players to give them another
3580 // Chance to wake up, but if the other player doesn't
3581 // Attack now, they both get logged out.
3582 updateTS(p);
3583 PF_settimedout(p);
3584 display_players(p->getBattle());
3585 return;
3586 }
3587 else
3588 {
3589 notice(s_GameServ, p->getBattle()->getNick(),
3590 "You and %s timed out at the same time."\
3591 " Don't fight if you're just going to "\
3592 "sit there!", p->getName().c_str());
3593 notice(s_GameServ, p->getClient()->getNick(),
3594 "You and %s timed out at the same time."\
3595 " Don't fight if you're just going to "\
3596 "sit there!", p->getBattle()->stats->getName().c_str());
3597 logout(p->getBattle());
3598 logout(p->getClient());
3599 return;
3600 }
3601 }
3602 else if (!player_fight(p->getClient()))
3603 {
3604 if (isAlive(p) && p->getGold() > 0)
3605 {
3606 // Place fun stuff here :)
3607 int randnum = 1 + rand() % 100; // 1-100
3608 #define GSN(s) notice(s_GameServ, nick, s)
3609 #define GSN2(s, f) notice(s_GameServ, nick, s, f)
3610
3611 if (randnum < 50)
3612 {
3613 // 35-100% of your gold goes pffft - kain
3614 int stolen = (35 + (rand() % 66)) * (p->getGold() / 100);
3615
3616 GSN("You stop for a moment to rest on the "\
3617 "street corner. All of a sudden, you "\
3618 "are ambushed from all sides by a hoarde "\
3619 "of knife wielding thugs.");
3620 GSN2("The thugs beat you into utter submission "\
3621 "and steal %ld gold from you!", stolen);
3622 p->subtractGold(stolen);
3623 }
3624 else if (randnum >= 50 && randnum < 75)
3625 {
3626 // 25-65% of your gold goes pffft - kain
3627 int stolen = (25 + (rand() % 41)) * (p->getGold() / 100);
3628 GSN("While dilly dallying around, you lose "\
3629 "your sense of time. Little did you know, "\
3630 "but thieves lifted your gold while you "\
3631 "weren't watching.");
3632 GSN2("Better luck next time... you lose %d gold", stolen);
3633 p->subtractGold(stolen);
3634 }
3635 else if (randnum >= 75)
3636 {
3637 // 25-75% of your gold goes pffft - kain
3638 int stolen = (25 + (rand() % 51)) * (p->getGold() / 100);
3639 GSN("Good grief! A gaggle of gooey green ghostlike "\
3640 "goblins grabbed your gold!");
3641 GSN2("They stole %d gold from you!", stolen);
3642 p->subtractGold(stolen);
3643 }
3644 }
3645
3646 // Always log out the user
3647 logout(p->getClient());
3648 }
3649 }
3650
3651 void do_reset(char *u)
3652 {
3653 char *nick = strtok(NULL, " ");
3654 aClient *user;
3655 Player *p;
3656
3657 if (!(user = find(u)))
3658 {
3659 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3660 log("Error: aClient not found: %s", u);
3661 return;
3662 }
3663 else if (!isAdmin(user))
3664 {
3665 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3666 return;
3667 }
3668
3669 if (!nick)
3670 {
3671 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
3672 }
3673 else if (stricmp(nick, "ALL") == 0)
3674 {
3675 notice(s_GameServ, u, "Resetting everyone's stats!");
3676 resetall();
3677 }
3678 else if (!(p = findplayer(nick)))
3679 {
3680 notice(s_GameServ, u, "Nick %s not found.", nick);
3681 }
3682 else
3683 {
3684 notice(s_GameServ, u, "Resetting %s.", p->getName().c_str());
3685 reset(p);
3686 }
3687 }
3688
3689 void do_help(char *u)
3690 {
3691 char *cmd = strtok(NULL, " ");
3692
3693 display_help(u, cmd);
3694 }
3695
3696 void display_help(char *u, char *file)
3697 {
3698 ifstream infile;
3699 char *buf;
3700
3701 if (!file)
3702 {
3703 infile.open("helpfiles/help");
3704 if (infile.fail())
3705 {
3706 log("Error opening helpfiles/help");
3707 notice(s_GameServ, u, "Error opening helpfiles/help");
3708 return;
3709 }
3710 buf = new char[1024];
3711 while(infile.getline(buf, 1024))
3712 {
3713 // Written this way, it will process %S in the helpfiles
3714 // Instead of notice(s_GameServ, u, "%s", buf);
3715 notice(s_GameServ, u, buf);
3716 }
3717
3718 // Minor recursion
3719 aClient *user = find(u);
3720 if (user && isAdmin(user))
3721 display_help(u, "admin_commands");
3722 }
3723 else
3724 {
3725 char *filename;
3726 filename = new char[strlen(file) + 11];
3727 strcpy(filename, "helpfiles/");
3728 strcat(filename, file);
3729
3730 for (unsigned int x = 10; x < strlen(filename); x++)
3731 filename[x] = tolower(filename[x]);
3732
3733 infile.open(filename);
3734 delete [] filename;
3735 if (infile.fail())
3736 {
3737 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
3738 return;
3739 }
3740 buf = new char[1024];
3741 while(infile.getline(buf, 1024))
3742 {
3743 // Written this way, it will process %S in the helpfiles
3744 // Instead of notice(s_GameServ, u, "%s", buf);
3745 notice(s_GameServ, u, buf);
3746 }
3747 }
3748 infile.close();
3749 delete [] buf;
3750 }
3751
3752 void do_admin(char *u)
3753 {
3754 aClient *user;
3755 char *pass = strtok(NULL, " ");
3756
3757 if (!(user = find(u)))
3758 {
3759 log("Error: aClient not found: %s", u);
3760 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
3761 return;
3762 }
3763
3764 if (!pass)
3765 {
3766 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
3767 return;
3768 }
3769
3770 if (isAdmin(user))
3771 {
3772 notice(s_GameServ, u, "You already have administrator privledges.");
3773 return;
3774 }
3775 else if (strcmp(pass, adminpass) == 0)
3776 {
3777 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
3778 setAdmin(user);
3779 #ifdef P10
3780 log("%s became an administrator.", user->getRealNick());
3781 #else
3782 log("%s became an administrator.", user->getNick());
3783 #endif
3784 }
3785 else
3786 {
3787 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
3788 return;
3789 }
3790 }
3791
3792 bool load_levels()
3793 {
3794 char *filename;
3795 filename = new char[256];
3796
3797 for (int x = 1; x <= LEVELS; x++)
3798 {
3799 sprintf(filename, "data/levels/level%d.dat", x);
3800 if (levels[x - 1].loadLevel(filename) == false)
3801 {
3802 delete []filename;
3803 return false;
3804 }
3805 }
3806
3807 delete []filename;
3808 return true;
3809 }
3810
3811 bool load_monsters()
3812 {
3813 char *filename;
3814 ifstream infile;
3815 char *buf;
3816 buf = new char[2048];
3817
3818 for (int level = 1; level <= LEVELS; level++)
3819 {
3820 filename = new char[256];
3821 sprintf(filename, "data/monsters/level%d.dat", level);
3822 infile.open(filename);
3823
3824 if (!infile)
3825 {
3826 log("Error opening %s", filename);
3827 delete []filename;
3828 delete []buf;
3829 return false;
3830 }
3831
3832 #ifdef DEBUGMODE
3833 log("Loading monsters from %s", filename);
3834 #endif
3835
3836 while (infile.getline(buf, 2048))
3837 {
3838 if (buf[0] == '^')
3839 break;
3840 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
3841 continue;
3842 Monster *temp;
3843 temp = new Monster;
3844
3845 temp->name = strtok(buf, "~");
3846 temp->weapon = strtok(NULL, "~");
3847 temp->death = strtok(NULL, "~");
3848
3849 levels[level - 1].monsters.push_back(temp);
3850
3851 }
3852 delete [] filename;
3853 infile.close();
3854 }
3855 delete [] buf;
3856 return true;
3857 }
3858
3859 item *findItemByID(int id)
3860 {
3861 list<item*>::iterator item_iterator;
3862
3863 item_iterator = Items.begin();
3864
3865 while (item_iterator != Items.end())
3866 {
3867 if ((*item_iterator)->getID() == id)
3868 {
3869 return (*item_iterator);
3870 }
3871 item_iterator++;
3872 }
3873 return NULL;
3874 }
3875
3876 item *findStoreItemByID(int id)
3877 {
3878 list<item*>::iterator item_iterator;
3879
3880 item_iterator = store.begin();
3881
3882 while (item_iterator != store.end())
3883 {
3884 if ((*item_iterator)->getID() == id)
3885 {
3886 return (*item_iterator);
3887 }
3888 item_iterator++;
3889 }
3890 return NULL;
3891 }
3892
3893 tavernItem *findTavernItemByID(int id)
3894 {
3895 list<tavernItem>::iterator item_iterator;
3896
3897 item_iterator = tavern.begin();
3898
3899 while (item_iterator != tavern.end())
3900 {
3901 if ((*item_iterator).getItem()->getID() == id)
3902 {
3903 return &(*item_iterator);
3904 }
3905 item_iterator++;
3906 }
3907 return NULL;
3908 }