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