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