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