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