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