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