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