]> jfr.im git - irc/gameservirc.git/blob - gameserv/gameserv.cpp
Added a todo entry about time checks
[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 available yet
1225 else if (!(fight = finduser(nick)))
1226 {
1227 ni->stats->battle = battle;
1228 battle->battle = ni;
1229 setYourTurn(ni->stats);
1230 clearYourTurn(battle->stats);
1231
1232 notice(s_GameServ, u, "You decide to fight %s while they're "\
1233 "not in the realm!",
1234 battle->stats->name);
1235 display_players(u);
1236 }
1237 */
1238 else if (stricmp(ni->stats->name, battle->stats->name) == 0)
1239 {
1240 notice(s_GameServ, u, "Are you trying to commit suicide!?");
1241 }
1242 else if (!isAlive(battle->stats))
1243 {
1244 notice(s_GameServ, u, "They are dead. Cannot fight dead players!");
1245 }
1246 else if (player_fight(battle))
1247 {
1248 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name);
1249 }
1250 else if (master_fight(battle))
1251 {
1252 notice(s_GameServ, u, "%s is fighting their master!", battle->stats->name);
1253 }
1254 else if (is_fighting(battle))
1255 {
1256 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name);
1257 }
1258 else if (ni->stats->level - battle->stats->level > maxbfightdistance)
1259 {
1260 // You can't fight someone below you by more than X level(s)
1261 // level 12 can fight level (12 - X) but not < (12 - X)
1262 notice(s_GameServ, u, "You may not fight %s. You're too strong!",
1263 battle->stats->name);
1264 }
1265 else if (battle->stats->level - ni->stats->level > maxafightdistance)
1266 {
1267 // You can't fight someone above you by more than X level(S)
1268 // level 1 can fight level (1 + X), but not > (1 + X)
1269 notice(s_GameServ, u, "%s, do you really have a death wish? Try the forest you "\
1270 "weakling!", ni->stats->name);
1271 }
1272 else
1273 {
1274 // Set your battle pointer to the other player
1275 ni->stats->battle = battle;
1276
1277 // Set the other player's battle pointer to you
1278 ni->stats->battle->stats->battle = ni;
1279
1280 // The initiator gets the first move (perhaps this should be 50/50)
1281 setYourTurn(ni->stats);
1282 clearYourTurn(battle->stats);
1283
1284 // Initiate Battle sequence!
1285 ni->stats->player_fights -= 1;
1286
1287 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name);
1288 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name);
1289 notice(s_GameServ, battle->getNick(), "%s gets to go first "\
1290 "because they initiated!", ni->stats->name);
1291 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name);
1292 display_players(ni);
1293 }
1294 }
1295
1296 void do_use(char *u)
1297 {
1298 aClient *user;
1299 Pouch *p;
1300
1301 char *item = strtok(NULL, " ");
1302
1303 if (!item)
1304 {
1305 notice(s_GameServ, u, "SYNTAX: USE ITEM");
1306 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1307 return;
1308 }
1309 else if (!(user = find(u)))
1310 {
1311 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1312 return;
1313 }
1314 else if (isIgnore(user))
1315 {
1316 #ifdef DEBUGMODE
1317 log("Ignoring %s.", user->getNick());
1318 #endif
1319 return;
1320 }
1321 else if (!is_playing(user))
1322 {
1323 notice(s_GameServ, u, "You must be playing to use items!");
1324 return;
1325 }
1326
1327 updateTS(user->stats);
1328
1329 p = &user->stats->inventory;
1330
1331 if (stricmp(item, "HEALTH") == 0)
1332 {
1333 if (p->Healing() <= 0)
1334 {
1335 notice(s_GameServ, u, "You are out of Health Potions!");
1336 return;
1337 }
1338 int oldhealth = user->stats->hp;
1339 notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
1340 notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
1341 user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
1342 notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealth);
1343 p->decHealing();
1344 }
1345 else if (stricmp(item, "STRENGTH") == 0)
1346 {
1347 if (p->Strength() <= 0)
1348 {
1349 notice(s_GameServ, u, "You are out of Strength Potions!");
1350 return;
1351 }
1352 int oldstrength = user->stats->strength;
1353 notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!");
1354 notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!");
1355 user->stats->strength += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
1356 notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength);
1357 p->decStrength();
1358 }
1359 else if (stricmp(item, "DEFENSE") == 0)
1360 {
1361 if (p->Defense() <= 0)
1362 {
1363 notice(s_GameServ, u, "You are out of Defense Potions!");
1364 return;
1365 }
1366 int olddefense = user->stats->defense;
1367 notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust.");
1368 notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!");
1369 user->stats->defense += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
1370 notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense);
1371 p->decDefense();
1372 }
1373 else if (stricmp(item, "HP") == 0)
1374 {
1375 if (p->HP() <= 0)
1376 {
1377 notice(s_GameServ, u, "You are out of HP Potions!");
1378 return;
1379 }
1380 int oldHP = user->stats->maxhp;
1381 notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid.");
1382 user->stats->maxhp += 2 +
1383 (rand() % 100 > 70 ? (rand() % 7) : (rand() % 2) );
1384
1385 notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP);
1386 p->decHP();
1387 }
1388 else
1389 {
1390 notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALTH | STRENGTH | DEFENSE}");
1391 return;
1392 }
1393
1394 end_turn(user); // If they're fighting, end their turn
1395 }
1396 void do_run(char *u)
1397 {
1398 aClient *user;
1399 Player *p, *p2 = NULL;
1400
1401 if (!(user = find(u)))
1402 {
1403 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1404 return;
1405 }
1406 else if (isIgnore(user))
1407 {
1408 #ifdef DEBUGMODE
1409 log("Ignoring %s.", user->getNick());
1410 #endif
1411 return;
1412 }
1413 else if (!is_playing(user))
1414 {
1415 notice(s_GameServ, u, "You must be playing to run!");
1416 return;
1417 }
1418
1419 updateTS(user->stats);
1420 p = user->stats;
1421
1422 if (p->battle)
1423 p2 = p->battle->stats;
1424
1425 if (!is_fighting(user))
1426 notice(s_GameServ, u, "You run in place... try fighting next time.");
1427 else if (!player_fight(user) && !master_fight(user))
1428 {
1429 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name);
1430 delete p->fight;
1431 p->fight = NULL;
1432 }
1433 else if (player_fight(user) && isYourTurn(p))
1434 {
1435 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name);
1436 notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->name);
1437 p2->battle = NULL;
1438 }
1439 else if (player_fight(user) && !isYourTurn(p))
1440 {
1441 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->name);
1442 }
1443 else if (master_fight(user))
1444 {
1445 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name);
1446 }
1447 p->battle = NULL;
1448 }
1449
1450 void end_turn(aClient *user)
1451 {
1452 char *nick, *u = user->getNick();
1453 Monster *fight;
1454 aClient *battle;
1455 int mhit;
1456
1457 nick = new char[strlen(user->getNick()) + 1];
1458
1459 if (!user || !is_playing(user) || !is_fighting(user))
1460 goto endturn;
1461
1462 if (!player_fight(user) && !master_fight(user))
1463 fight = user->stats->fight;
1464 else
1465 fight = user->stats->master;
1466 battle = user->stats->battle;
1467
1468 if (!player_fight(user))
1469 {
1470 // Opponent's Hit
1471 mhit = (fight->strength / 2) +
1472 (rand() % (fight->strength / 2) - (user->stats->defense +
1473 arbonus[user->stats->armor]));
1474 }
1475 else
1476 {
1477 // Opponent's Hit
1478 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1479 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1480 (user->stats->defense + arbonus[user->stats->armor]));
1481 }
1482 if (!player_fight(user))
1483 {
1484
1485 if (mhit > 0)
1486 {
1487 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1488 fight->name, fight->weapon, mhit);
1489 }
1490 else if (mhit <= 0)
1491 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1492
1493 if (mhit >= user->stats->hp)
1494 {
1495 if (!master_fight(user))
1496 {
1497 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1498 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1499 "of your experience!");
1500 user->stats->gold = 0;
1501 user->stats->exp -= (long int)(user->stats->exp * .10);
1502 user->stats->hp = 0;
1503 user->stats->fight = NULL;
1504 clearAlive(user->stats);
1505 goto endturn;
1506 }
1507 else
1508 {
1509 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1510 "until tomorrow to try again", user->stats->master->name);
1511 user->stats->fight = NULL;
1512 user->stats->master = NULL;
1513 goto endturn;
1514 }
1515 }
1516 else
1517 {
1518 if (mhit > 0)
1519 user->stats->hp -= mhit;
1520 display_monster(u);
1521 goto endturn;
1522 }
1523 }
1524 else
1525 {
1526 clearYourTurn(user->stats);
1527 setYourTurn(battle->stats);
1528 display_players(battle);
1529 }
1530 endturn:
1531 delete nick;
1532 }
1533
1534 void do_attack(char *u)
1535 {
1536 int hit, mhit;
1537 aClient *ni, *battle; // The player and perhaps the player they're fighting
1538 Monster *fight; // The monster they may be fighting
1539
1540 if (!(ni = find(u)))
1541 {
1542 notice(s_GameServ, u, "Fatal error in do_attack. Contact a(n) %S admin for help.");
1543 return;
1544 }
1545 else if (isIgnore(ni))
1546 {
1547 #ifdef DEBUGMODE
1548 log("Ignoring %s.", ni->getNick());
1549 #endif
1550 return;
1551 }
1552 else if (!is_playing(ni))
1553 {
1554 notice(s_GameServ, u, "You're not playing!");
1555 return;
1556 }
1557 else if (!is_fighting(ni))
1558 {
1559 notice(s_GameServ, u, "You're not in battle!");
1560 return;
1561 }
1562 else
1563 {
1564 if (!ni->stats->master) // This is not a master fight
1565 fight = ni->stats->fight; // Monster Could be NULL
1566 else // This IS a master fight
1567 fight = ni->stats->master; // Master Could be NULL
1568
1569 battle = ni->stats->battle; // Player Could be NULL
1570
1571 // One has to be !NULL based on the previous else if
1572 // We wouldn't be here if they were all NULL
1573 }
1574 updateTS(ni->stats);
1575
1576 if (!player_fight(ni))
1577 {
1578 // Player's Hit
1579 hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1580 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
1581
1582 // Opponent's Hit
1583 mhit = (fight->strength / 2) +
1584 (rand() % (fight->strength / 2) - (ni->stats->defense +
1585 arbonus[ni->stats->armor]));
1586 }
1587 else
1588 {
1589 // Opponent's Hit
1590 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1591 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1592 (ni->stats->defense + arbonus[ni->stats->armor]));
1593
1594 // Player's Hit
1595 hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1596 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
1597 (battle->stats->defense + arbonus[battle->stats->armor]));
1598 }
1599
1600 if (!player_fight(ni))
1601 {
1602 if (hit > 0)
1603 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
1604 else
1605 notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
1606
1607 if (hit >= fight->hp)
1608 {
1609 if (master_fight(ni))
1610 notice(s_GameServ, u, "You have bested %s!", fight->name);
1611 else
1612 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
1613
1614 notice(s_GameServ, u, "%s", fight->death);
1615 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
1616 fight->exp, fight->gold);
1617
1618 // If your new experience (or gold) will be greater than 2 billion,
1619 // then set your exp to 2bil. (2 billion max)... otherwise add them.
1620 // This could be a problem with overflowing out of the sign bit.
1621 // Unsigned long int maybe? Leave it for now.
1622 ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 :
1623 ni->stats->exp + fight->exp);
1624
1625 ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 :
1626 ni->stats->gold + fight->gold);
1627
1628
1629 if (master_fight(ni))
1630 {
1631 notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
1632 notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
1633 strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
1634
1635 // Increase your level
1636 ni->stats->level++;
1637
1638 // Increase your maximum hit points
1639 ni->stats->maxhp += hpbonus[ni->stats->level - 1];
1640
1641 // Heal the player by setting hp to their max
1642 ni->stats->hp = ni->stats->maxhp;
1643
1644 // Add to your strength
1645 ni->stats->strength += strbonus[ni->stats->level - 1];
1646
1647 // Add to your defensive power
1648 ni->stats->defense += defbonus[ni->stats->level - 1];
1649
1650 // Clear the pointer for your master
1651 ni->stats->master = NULL;
1652 }
1653
1654 // They're dead so remove the pointer
1655 delete ni->stats->fight;
1656 ni->stats->fight = NULL;
1657 ni->stats->master = NULL;
1658
1659 return;
1660 }
1661 else
1662 {
1663 if (hit > 0)
1664 fight->hp -= hit;
1665 if (mhit > 0)
1666 {
1667 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1668 fight->name, fight->weapon, mhit);
1669 }
1670 else if (mhit <= 0)
1671 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1672
1673 if (mhit >= ni->stats->hp)
1674 {
1675 if (!master_fight(ni))
1676 {
1677 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1678 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1679 "of your experience!");
1680 ni->stats->gold = 0;
1681 ni->stats->exp -= (long int)(ni->stats->exp * .10);
1682 ni->stats->hp = 0;
1683 ni->stats->fight = NULL;
1684 clearAlive(ni->stats);
1685 return;
1686 }
1687 else
1688 {
1689 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1690 "until tomorrow to try again", ni->stats->master->name);
1691 ni->stats->fight = NULL;
1692 ni->stats->master = NULL;
1693 return;
1694 }
1695 }
1696 else
1697 {
1698 if (mhit > 0)
1699 ni->stats->hp -= mhit;
1700 display_monster(u);
1701 return;
1702 }
1703 }
1704 }
1705 else if (player_fight(ni))
1706 {
1707 /* Offline fighting not available yet
1708 if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
1709 {
1710 if (hit > 0)
1711 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
1712 else
1713 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
1714 if (hit >= battle->stats->hp)
1715 {
1716 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
1717 * notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1718 (long int)(battle->stats->exp * .10), battle->stats->gold);
1719 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1720 {
1721 ni->stats->exp += (long int)(battle->stats->exp * .10);
1722 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1723 }
1724 * else
1725 {
1726 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1727 ni->stats->exp = 2000000000;
1728 }
1729
1730 if (2000000000 - ni->stats->gold > battle->stats->gold)
1731 {
1732 * ni->stats->gold += battle->stats->gold;
1733 battle->stats->gold = 0;
1734 }
1735 else
1736 {
1737 battle->stats->gold = 2000000000 - ni->stats->gold;
1738 ni->stats->gold = 2000000000;
1739 }
1740 * ni->stats->battle->stats->alive = 0;
1741 ni->stats->battle->battle = NULL;
1742 ni->stats->battle = NULL;
1743 return;
1744 }
1745 else
1746 {
1747 if (hit > 0)
1748 * battle->stats->hp -= hit;
1749 if (mhit > 0)
1750 {
1751 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1752 battle->nick, weapons[battle->stats->weapon], mhit);
1753 }
1754 else if (mhit <= 0)
1755 notice(s_GameServ, u, "%s completely misses you!", battle->nick);
1756 *
1757 if (mhit >= ni->stats->hp)
1758 {
1759 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
1760 if (2000000000 - battle->stats->gold > ni->stats->gold)
1761 {
1762 notice(s_GameServ, u, "%s took all your gold!", battle->nick);
1763 battle->stats->gold += ni->stats->gold;
1764 * ni->stats->gold = 0;
1765 }
1766 else
1767 {
1768 notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
1769 battle->nick);
1770 ni->stats->gold -= (2000000000 - battle->stats->gold);
1771 notice(s_GameServ, u, "You were left dead with %d gold.",
1772 * (long int)ni->stats->gold);
1773 battle->stats->gold = 2000000000;
1774 }
1775 ni->stats->battle->battle = NULL;
1776 ni->stats->battle = NULL;
1777 ni->stats->alive = 0;
1778 return;
1779 }
1780 * else
1781 {
1782 if (mhit > 0)
1783 ni->stats->hp -= mhit;
1784 display_players(u);
1785 return;
1786 }
1787 }
1788 }
1789 * end offline fighting */
1790
1791 if (is_playing(battle))
1792 {
1793 if (!isYourTurn(ni->stats))
1794 {
1795 notice(s_GameServ, u, "Please wait until %s decides what to do!",
1796 battle->stats->name);
1797 return;
1798 }
1799 if (hit > 0)
1800 {
1801 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->stats->name, hit);
1802
1803 notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
1804 "\ 2%d\ 2 damage!", ni->stats->name,
1805 weapons[ni->stats->weapon], hit);
1806 clearYourTurn(ni->stats);
1807 setYourTurn(battle->stats);
1808 display_players(battle);
1809 }
1810 else
1811 {
1812 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->stats->name);
1813 notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name);
1814 clearYourTurn(ni->stats);
1815 setYourTurn(battle->stats);
1816 display_players(battle);
1817 }
1818 if (hit >= battle->stats->hp)
1819 {
1820 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name);
1821 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1822 (long int)(battle->stats->exp * .10), battle->stats->gold);
1823 notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!",
1824 ni->stats->name);
1825 battle->stats->hp = 0;
1826 clearAlive(battle->stats);
1827
1828 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1829 {
1830 ni->stats->exp += (long int)(battle->stats->exp * .10);
1831 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1832 }
1833 else
1834 {
1835 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1836 ni->stats->exp = 2000000000;
1837 }
1838
1839 if (2000000000 - ni->stats->gold > battle->stats->gold)
1840 {
1841 notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
1842 "all gold on hand!");
1843 ni->stats->gold += battle->stats->gold;
1844 battle->stats->gold = 0;
1845 }
1846 else
1847 {
1848 battle->stats->gold = 2000000000 - ni->stats->gold;
1849 notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
1850
1851 notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
1852 "gold.", ni->stats->name);
1853
1854 notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
1855 "left. All is not lost!", battle->stats->gold);
1856
1857 ni->stats->gold = 2000000000;
1858 }
1859 battle->stats->battle = NULL;
1860 ni->stats->battle = NULL;
1861 return;
1862 }
1863 else
1864 {
1865 if (hit > 0)
1866 battle->stats->hp -= hit;
1867 clearYourTurn(ni->stats);
1868 setYourTurn(battle->stats);
1869 notice(s_GameServ, u, "Please wait while %s decides what to do!",
1870 battle->stats->name);
1871
1872 return;
1873 }
1874 }
1875 }
1876 }
1877
1878 void do_heal(char *u)
1879 {
1880 aClient *ni;
1881 char *amount = strtok(NULL, " ");
1882 int price, num;
1883
1884 if (!amount)
1885 {
1886 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1887 return;
1888 }
1889 else if (!(ni = find(u)))
1890 {
1891 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1892 return;
1893 }
1894 else if (isIgnore(ni))
1895 {
1896 #ifdef DEBUGMODE
1897 log("Ignoring %s.", ni->getNick());
1898 #endif
1899 return;
1900 }
1901 else if (!is_playing(ni))
1902 {
1903 notice(s_GameServ, u, "You aren't playing!");
1904 return;
1905 }
1906 else if (!isAlive(ni->stats))
1907 {
1908 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
1909 return;
1910 }
1911 else if (is_fighting(ni))
1912 {
1913 notice(s_GameServ, u, "You can't heal in battle!");
1914 return;
1915 }
1916 else if (ni->stats->hp >= ni->stats->maxhp)
1917 {
1918 notice(s_GameServ, u, "You don't need healing!");
1919 return;
1920 }
1921
1922 updateTS(ni->stats);
1923 if (stricmp(amount, "ALL") == 0)
1924 {
1925 price = ni->stats->level * 3;
1926 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
1927 {
1928 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1929 (long int)ni->stats->gold/price, price);
1930 ni->stats->hp += ni->stats->gold / price;
1931 ni->stats->gold %= price;
1932 }
1933 else
1934 {
1935 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1936 "per point.", price);
1937 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
1938 (ni->stats->maxhp - ni->stats->hp),
1939 (price * (ni->stats->maxhp - ni->stats->hp)) );
1940 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1941 ni->stats->hp = ni->stats->maxhp;
1942 }
1943 }
1944 else if (isstringnum(amount))
1945 {
1946 num = stringtoint(amount);
1947 price = ni->stats->level * 3;
1948 if (ni->stats->gold < price * num)
1949 {
1950 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
1951 (long int)ni->stats->gold/price);
1952 }
1953 else if (num <= ni->stats->maxhp - ni->stats->hp)
1954 {
1955 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
1956 num, price);
1957 ni->stats->hp += num;
1958 ni->stats->gold -= num * price;
1959 }
1960 else if (num > ni->stats->maxhp - ni->stats->hp)
1961 {
1962 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1963 "per point.", price);
1964 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
1965 (ni->stats->maxhp - ni->stats->hp));
1966 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1967 ni->stats->hp = ni->stats->maxhp;
1968 }
1969 }
1970 else if (amount[0] == '-')
1971 notice(s_GameServ, u, "You trying to cheat?");
1972 else
1973 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1974 }
1975
1976 int isstringnum(char *num)
1977 {
1978 unsigned int x;
1979 for (x = 0; x < strlen(num); x++)
1980 {
1981 if ((int)num[x] < 48 || (int)num[x] > 57)
1982 return 0;
1983 }
1984 return 1;
1985 }
1986
1987 long int stringtoint(char *number)
1988 {
1989 long int x, len = strlen(number), sum = 0;
1990 if (len == 1)
1991 return chartoint(number[0]);
1992 sum += chartoint(number[len - 1]);
1993 for (x = len - 2; x >= 0; x--)
1994 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
1995 return sum;
1996 }
1997
1998 long int pow(int x, int y)
1999 {
2000 long int value = 0;
2001 int count = 0;
2002 value += x;
2003
2004 if (x != 0 && y != 0)
2005 {
2006 for (count = 1; count <= y - 1; count++)
2007 value *= x;
2008 }
2009 else
2010 return 1;
2011 return value;
2012 }
2013
2014 long int chartoint(char ch)
2015 {
2016 if (int(ch) >= 48 && int(ch) <= 57)
2017 return int(ch) - 48;
2018 else
2019 return 0;
2020 }
2021
2022 int save_gs_dbase()
2023 {
2024 ListNode<aClient> *ptr;
2025 Player *it;
2026 ofstream outfile;
2027
2028 outfile.open(playerdata);
2029
2030 if (!outfile)
2031 {
2032 log("Error opening %s", playerdata);
2033 return 0;
2034 }
2035
2036 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
2037 {
2038 ptr = players[x].First();
2039 while(ptr)
2040 {
2041 it = ptr->getData()->stats;
2042 clearYourTurn(it);
2043 outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
2044 << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
2045 << it->armor << ' ' << it->weapon << ' '
2046 << it->forest_fights << ' ' << it->player_fights << ' '
2047 << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
2048 << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl;
2049 ptr = ptr->Next();
2050 }
2051 }
2052 outfile.close();
2053 return 1;
2054 }
2055
2056 int load_gs_dbase()
2057 {
2058 ifstream infile;
2059 aClient *temp;
2060 Player *p;
2061 char *tempname, *buf, *password;
2062 buf = new char[1023];
2063
2064 infile.open(playerdata);
2065
2066 if (infile.fail())
2067 {
2068 log("Error opening %s", playerdata);
2069 return 0;
2070 }
2071
2072 while (infile.getline(buf, 1024, '\n'))
2073 {
2074 temp = new aClient;
2075 tempname = strtok(buf, " ");
2076 temp->stats = new Player(tempname);
2077 p = temp->stats;
2078
2079 p->level = stringtoint(strtok(NULL, " "));
2080 p->exp = stringtoint(strtok(NULL, " "));
2081 p->gold = stringtoint(strtok(NULL, " "));
2082 p->bank = stringtoint(strtok(NULL, " "));
2083 p->hp = stringtoint(strtok(NULL, " "));
2084 p->maxhp = stringtoint(strtok(NULL, " "));
2085 p->strength = stringtoint(strtok(NULL, " "));
2086 p->defense = stringtoint(strtok(NULL, " "));
2087 p->armor = stringtoint(strtok(NULL, " "));
2088 p->weapon = stringtoint(strtok(NULL, " "));
2089 p->forest_fights = stringtoint(strtok(NULL, " "));
2090 p->player_fights = stringtoint(strtok(NULL, " "));
2091 p->setFlags(stringtoint(strtok(NULL, " ")));
2092
2093 password = strtok(NULL, " ");
2094 strcpy(p->password, password);
2095 temp->setNick("Not Playing");
2096 #ifdef P10
2097 temp->setRealNick("Not Playing");
2098 #endif
2099
2100 p->inventory.reset(); // Set inventory to all 0s
2101 // Old player databases didn't have these three extra values
2102 // If they come up null, leave them to 0 as the default.
2103 // On the next gameserv database save, it will save the values.
2104 tempname = strtok(NULL, " ");
2105 if (tempname)
2106 p->inventory.setHealing(stringtoint(tempname));
2107
2108 tempname = strtok(NULL, " ");
2109 if (tempname)
2110 p->inventory.setStrength(stringtoint(tempname));
2111
2112 tempname = strtok(NULL, " ");
2113 if (tempname)
2114 p->inventory.setDefense(stringtoint(tempname));
2115
2116 tempname = strtok(NULL, " ");
2117 if (tempname)
2118 p->inventory.setHP(stringtoint(tempname));
2119 unsigned long hv = iHASH((unsigned char *) temp->stats->name);
2120
2121 temp->stats->client = NULL;
2122 players[hv].insertAtBack(temp);
2123 delete temp;
2124 }
2125 delete [] buf;
2126 infile.close();
2127 return 1;
2128 }
2129
2130 bool passcmp(char *encrypted, char *plaintext)
2131 {
2132 char salt[3];
2133 char *plaintext2, *plainToencrypt;
2134 bool same = false;
2135
2136 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
2137 strcpy(plaintext2, plaintext);
2138
2139 salt[0] = encrypted[0];
2140 salt[1] = encrypted[1];
2141 salt[3] = '\0';
2142
2143 plainToencrypt = crypt(plaintext2, salt);
2144
2145 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
2146
2147 delete []plaintext2;
2148
2149 return same;
2150 }
2151
2152 bool check_password(char *name, char *plaintext)
2153 {
2154 aClient *client;
2155
2156 if (!(client = findplayer(name)))
2157 return false;
2158 else
2159 {
2160 return passcmp(client->stats->password, plaintext);
2161 }
2162 }
2163
2164 void do_store(char *u)
2165 {
2166 char *cmd = strtok(NULL, " ");
2167 char *item = strtok(NULL, " ");
2168 char *num = strtok(NULL, " ");
2169 char *space;
2170 int wep;
2171 aClient *user;
2172 Player *p;
2173
2174 if (!cmd || !item)
2175 {
2176 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2177 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2178 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2179 return;
2180 }
2181 else if (!(user = find(u)))
2182 {
2183 log("Fatal Error: could not find %s in client list", u);
2184 return;
2185 }
2186 else if (isIgnore(user))
2187 {
2188 #ifdef DEBUGMODE
2189 log("Ignoring %s.", user->getNick());
2190 #endif
2191 return;
2192 }
2193 else if (!is_playing(user))
2194 {
2195 notice(s_GameServ, u, "You must be playing to use the store!");
2196 return;
2197 }
2198 else if (!isAlive(user->stats))
2199 {
2200 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
2201 return;
2202 }
2203 updateTS(user->stats);
2204
2205 if (stricmp(cmd, "LIST") == 0)
2206 {
2207 if (stricmp(item, "WEAPONS") == 0)
2208 {
2209 notice(s_GameServ, u, "Welcome to Kain's Armory");
2210 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
2211 for (int x = 1; x < WNA; x++)
2212 {
2213 space = spaces(strlen(weapons[x]), ".");
2214 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
2215 free(space);
2216 }
2217 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
2218 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
2219
2220 }
2221 else if (stricmp(item, "ARMOR") == 0)
2222 {
2223 notice(s_GameServ, u, "Welcome to Kain's Armory");
2224 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
2225 for (int x = 1; x < WNA; x++)
2226 {
2227 space = spaces(strlen(armors[x]), ".");
2228 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
2229 free(space);
2230 }
2231 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
2232 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
2233
2234
2235 }
2236 } else if (stricmp(cmd, "BUY") == 0) {
2237 if (!num)
2238 {
2239 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2240 return;
2241 }
2242 else if (!isstringnum(num))
2243 {
2244 notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
2245 return;
2246 }
2247 if (stricmp(item, "WEAPON") == 0)
2248 {
2249 wep = stringtoint(num);
2250 if (wep >= WNA || wep < 1)
2251 {
2252 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2253 return;
2254 }
2255
2256 p = user->stats;
2257
2258 if (p->weapon != 0)
2259 notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
2260 else if (p->gold < prices[wep - 1])
2261 notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
2262 else
2263 {
2264 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
2265 p->weapon = wep;
2266 p->gold -= prices[wep - 1];
2267 }
2268 }
2269 else if (stricmp(item, "ARMOR") == 0)
2270 {
2271 wep = stringtoint(num);
2272 if (wep >= WNA || wep < 1)
2273 {
2274 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2275 return;
2276 }
2277
2278 p = user->stats;
2279
2280 if (p->armor != 0)
2281 notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
2282 else if (p->gold < prices[wep - 1])
2283 notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
2284 else
2285 {
2286 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
2287 p->armor = wep;
2288 p->gold -= prices[wep - 1];
2289 }
2290 }
2291 }
2292 else if (stricmp(cmd, "SELL" ) == 0)
2293 {
2294 p = user->stats;
2295
2296 if (stricmp(item, "WEAPON") == 0)
2297 {
2298 if (p->weapon == 0)
2299 {
2300 notice(s_GameServ, u, "You want me to chop off your hands?");
2301 return;
2302 }
2303 else if (p->gold == 2000000000)
2304 {
2305 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2306 p->weapon = 0;
2307 }
2308 else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
2309 {
2310 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2311 notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
2312 p->gold = 2000000000;
2313 p->weapon = 0;
2314 }
2315 else
2316 {
2317 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
2318 p->gold += (prices[p->weapon - 1] / 2);
2319 p->weapon = 0;
2320 }
2321 }
2322 else if (stricmp(item, "ARMOR") == 0)
2323 {
2324 p = user->stats;
2325
2326 if (p->armor == 0)
2327 {
2328 notice(s_GameServ, u, "I don't think you can be any more naked...");
2329 return;
2330 }
2331 if (p->gold == 2000000000)
2332 {
2333 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2334 p->armor = 0;
2335 }
2336 else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
2337 {
2338 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2339 notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
2340 p->gold = 2000000000;
2341 p->armor = 0;
2342 }
2343 else
2344 {
2345 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
2346 (prices[p->armor - 1] / 2));
2347
2348 p->gold += (prices[p->armor - 1] / 2);
2349 p->armor = 0;
2350 }
2351 }
2352 else
2353 {
2354 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2355 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2356 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2357 }
2358 }
2359 else
2360 {
2361 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2362 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2363 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2364 return;
2365 }
2366 }
2367 void do_inventory(char *u)
2368 {
2369 aClient *user;
2370
2371 if (!(user = find(u)))
2372 {
2373 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2374 return;
2375 }
2376 else if (isIgnore(user))
2377 {
2378 #ifdef DEBUGMODE
2379 log("Ignoring %s.", user->getNick());
2380 #endif
2381 return;
2382 }
2383 else if (!is_playing(user))
2384 {
2385 notice(s_GameServ, u, "You must be playing to check your inventory!");
2386 return;
2387 }
2388 updateTS(user->stats);
2389 showinventory(user, user);
2390 }
2391 void showinventory(aClient *from, aClient *to)
2392 {
2393 char *nick = to->getNick();
2394
2395 if (!to)
2396 to = from;
2397 if (is_playing(from))
2398 {
2399 Pouch *p = &from->stats->inventory;
2400 notice(s_GameServ, nick, "Inventory for %s:", from->stats->name);
2401 notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
2402 notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
2403 notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
2404 notice(s_GameServ, nick, " HP Potions: %d", p->HP());
2405 }
2406 }
2407 void do_tavern(char *u)
2408 {
2409 char *cmd = strtok(NULL, " ");
2410 long int price;
2411
2412 aClient *user;
2413 Player *p;
2414 if (!(user = find(u)))
2415 {
2416 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2417 return;
2418 }
2419 else if (isIgnore(user))
2420 {
2421 #ifdef DEBUGMODE
2422 log("Ignoring %s.", user->getNick());
2423 #endif
2424 return;
2425 }
2426 else if (!is_playing(user))
2427 {
2428 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2429 return;
2430 }
2431 else if (is_fighting(user))
2432 {
2433 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2434 return;
2435 }
2436
2437 updateTS(user->stats);
2438 p = user->stats;
2439
2440 if (!cmd)
2441 {
2442 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
2443 notice(s_GameServ, u, "Your commands:");
2444 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2445 notice(s_GameServ, u, "What'll it be?");
2446 }
2447 else if (stricmp(cmd, "LIST") == 0)
2448 {
2449 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2450 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 100 * p->level + (p->exp / 10));
2451 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 205 * p->level + (p->exp / 10));
2452 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 200 * p->level + (p->exp / 10));
2453 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 230 * p->level + (p->exp / 10));
2454 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2455 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2456 notice(s_GameServ, u, "By something will ya!");
2457 }
2458 else if (stricmp(cmd, "BUY") == 0)
2459 {
2460 char *chnum = strtok(NULL, " ");
2461 int num = stringtoint(chnum);
2462
2463 if (!chnum)
2464 {
2465 notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
2466 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
2467 return;
2468 }
2469 if (num < 1 || num > 4)
2470 {
2471 notice(s_GameServ, u, "Invalid Choice!");
2472 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2473 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 100 * p->level + (p->exp / 10));
2474 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 205 * p->level + (p->exp / 10));
2475 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 200 * p->level + (p->exp / 10));
2476 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 230 * p->level + (p->exp / 10));
2477 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2478 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2479 return;
2480 }
2481 switch(num)
2482 {
2483 case 1:
2484 price = (100 * p->level) + (p->exp / 10);
2485 if (p->gold >= price)
2486 {
2487 notice(s_GameServ, u, "One healing potion coming right up!");
2488 p->inventory.incHealing();
2489 p->gold -= price;
2490 }
2491 else
2492 notice(s_GameServ, u, "You don't have enough gold!");
2493 break;
2494 case 2:
2495 price = (205 * p->level) + (p->exp / 10);
2496 if (p->gold >= price)
2497 {
2498 notice(s_GameServ, u, "One strength boost coming right up!");
2499 p->inventory.incStrength();
2500 p->gold -= price;
2501 }
2502 else
2503 notice(s_GameServ, u, "You don't have enough gold!");
2504 break;
2505 case 3:
2506 price = (200 * p->level) + (p->exp / 10);
2507 if (p->gold >= price)
2508 {
2509 notice(s_GameServ, u, "One defense boost coming right up!");
2510 p->inventory.incDefense();
2511 p->gold -= price;
2512 }
2513 else
2514 notice(s_GameServ, u, "You don't have enough gold!");
2515 break;
2516 case 4:
2517 price = (230 * p->level) + (p->exp / 10);
2518 if (p->gold >= price)
2519 {
2520 notice(s_GameServ, u, "One HP Potion coming right up!");
2521 p->inventory.incHP();
2522 p->gold -= price;
2523 }
2524 else
2525 notice(s_GameServ, u, "You don't have enough gold!");
2526 break;
2527 default:
2528 notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
2529 break;
2530 }
2531 }
2532 else
2533 {
2534 notice(s_GameServ, u, "Improper Syntax.");
2535 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2536 }
2537 }
2538
2539 void do_bank(char *u)
2540 {
2541 char *cmd = strtok(NULL, " ");
2542 char *amount = strtok(NULL, " ");
2543 char *nick = strtok(NULL, " ");
2544
2545 aClient *user;
2546 Player *p;
2547
2548 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
2549 {
2550 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
2551 notice (s_GameServ, u, "BANK BALANCE");
2552 return;
2553 }
2554 else if (!(user = find(u)))
2555 {
2556 notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\
2557 " admin for help");
2558 log("Fatal Error. Couldn't find %s while executing do_bank()", u);
2559 return;
2560 }
2561 else if (isIgnore(user))
2562 {
2563 #ifdef DEBUGMODE
2564 log("Ignoring %s.", user->getNick());
2565 #endif
2566 return;
2567 }
2568 else if (!is_playing(user))
2569 {
2570 notice(s_GameServ, u, "You must be playing to use the bank!");
2571 return;
2572 }
2573 else if (is_fighting(user))
2574 {
2575 notice(s_GameServ, u, "You can't go to the bank during a fight!");
2576 return;
2577 }
2578 updateTS(user->stats);
2579 if (stricmp(cmd, "BALANCE") == 0)
2580 {
2581 showBankBalance(u);
2582 return;
2583 }
2584 else if (!isAlive(user->stats))
2585 {
2586 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2587 return;
2588 }
2589 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2590 {
2591 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2592 return;
2593 }
2594
2595 p = user->stats;
2596
2597 if (stricmp(cmd, "DEPOSIT") == 0)
2598 {
2599 if (p->bank == 2000000000)
2600 {
2601 notice(s_GameServ, u, "Your bank account is full, sire!");
2602 return;
2603 }
2604 else if (stricmp(amount, "ALL") == 0)
2605 {
2606 if (2000000000 - p->bank < p->gold)
2607 {
2608 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2609 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
2610 p->gold -= (2000000000 - p->bank);
2611 p->bank = 2000000000;
2612 showBankBalance(u);
2613 }
2614 else
2615 {
2616 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
2617 p->bank += p->gold;
2618 p->gold = 0;
2619 showBankBalance(u);
2620 }
2621 }
2622 else if (stringtoint(amount) > p->gold)
2623 {
2624 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
2625 showBankBalance(u);
2626 return;
2627 }
2628 else
2629 {
2630 if (2000000000 - p->bank < stringtoint(amount))
2631 {
2632 notice(s_GameServ, u, "You don't have room in your account for that much.");
2633 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
2634 p->gold -= (2000000000 - p->bank);
2635 p->bank = 2000000000;
2636 showBankBalance(u);
2637 }
2638 else
2639 {
2640 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2641 p->bank += stringtoint(amount);
2642 p->gold -= stringtoint(amount);
2643 showBankBalance(u);
2644 }
2645 }
2646 }
2647 else if (stricmp(cmd, "WITHDRAW") == 0)
2648 {
2649 if (p->gold == 2000000000)
2650 {
2651 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
2652 showBankBalance(u);
2653 return;
2654 }
2655 else if (stricmp(amount, "ALL") == 0)
2656 {
2657 if (2000000000 - p->gold < p->bank)
2658 {
2659 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2660 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
2661 p->bank -= (2000000000 - p->gold);
2662 p->gold = 2000000000;
2663 showBankBalance(u);
2664 }
2665 else
2666 {
2667 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
2668 p->gold += p->bank;
2669 p->bank = 0;
2670 showBankBalance(u);
2671 }
2672 }
2673 else if (stringtoint(amount) > p->bank)
2674 {
2675 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
2676 showBankBalance(u);
2677 return;
2678 }
2679 else
2680 {
2681 if (2000000000 - p->gold < stringtoint(amount))
2682 {
2683 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2684 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2685 (2000000000 - p->gold));
2686 p->bank -= (2000000000 - p->gold);
2687 p->gold = 2000000000;
2688 showBankBalance(u);
2689 }
2690 else
2691 {
2692 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2693 p->gold += stringtoint(amount);
2694 p->bank -= stringtoint(amount);
2695 showBankBalance(u);
2696 }
2697 }
2698 }
2699
2700 }
2701
2702 void do_master(char *u)
2703 {
2704 aClient *user;
2705
2706
2707 if (!(user = find(u)))
2708 {
2709 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2710 return;
2711 }
2712 else if (isIgnore(user))
2713 {
2714 #ifdef DEBUGMODE
2715 log("Ignoring %s.", user->getNick());
2716 #endif
2717 return;
2718 }
2719 else if (!is_playing(user))
2720 {
2721 notice(s_GameServ, u, "You must be playing to see your master!");
2722 return;
2723 }
2724 else if (is_fighting(user))
2725 {
2726 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
2727 return;
2728 }
2729 else if (!isAlive(user->stats))
2730 {
2731 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2732 return;
2733 }
2734
2735 updateTS(user->stats);
2736
2737 char *cmd = strtok(NULL, " ");
2738 Player *p = user->stats;
2739 long int need = 0;
2740
2741 if (seenMaster(p))
2742 {
2743 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
2744 return;
2745 }
2746
2747 if (cmd != NULL)
2748 {
2749 switch(p->level)
2750 {
2751 case 1:
2752 need = 100;
2753 break;
2754 case 2:
2755 need = 400;
2756 break;
2757 case 3:
2758 need = 1000;
2759 break;
2760 case 4:
2761 need = 4000;
2762 break;
2763 case 5:
2764 need = 10000;
2765 break;
2766 case 6:
2767 need = 40000;
2768 break;
2769 case 7:
2770 need = 100000;
2771 break;
2772 case 8:
2773 need = 400000;
2774 break;
2775 case 9:
2776 need = 1000000;
2777 break;
2778 case 10:
2779 need = 4000000;
2780 break;
2781 case 11:
2782 need = 10000000;
2783 break;
2784 case 12:
2785 need = p->exp + 1;
2786 notice(s_GameServ, u, "You are at level 12. You are the master. What's left? The DRAGON!");
2787 break;
2788 default:
2789 need = p->exp + 1; // Unknown level... don't let them fight a fake master!
2790 break;
2791 }
2792 }
2793 else
2794 {
2795 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2796 return;
2797 }
2798
2799 if (stricmp(cmd, "FIGHT") == 0)
2800 {
2801 if (p->exp >= need)
2802 {
2803 setMaster(p);
2804 see_master(u);
2805 }
2806 else
2807 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.", masters[p->level - 1]->name, (need - p->exp));
2808 return;
2809 }
2810 else if (stricmp(cmd, "QUESTION") == 0)
2811 {
2812 if (p->exp >= need)
2813 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);
2814 else
2815 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", masters[p->level - 1]->name, p->name);
2816
2817 return;
2818 }
2819 else
2820 {
2821 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2822 }
2823 }
2824
2825 void see_master(char *u)
2826 {
2827 aClient *user;
2828
2829 if (!(user = find(u)))
2830 {
2831 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2832 return;
2833 }
2834
2835 if (!is_fighting(user) && is_playing(user))
2836 {
2837 Player *p = user->stats;
2838 p->master = new Monster(masters[p->level - 1]);
2839 p->fight = p->master;
2840 display_monster(u); // Since master is the same structure, use this function
2841 }
2842 }
2843
2844 void showBankBalance(const char *u)
2845 {
2846 aClient *user;
2847 Player *p;
2848
2849 if (!(user = find(u)))
2850 return;
2851
2852 p = user->stats;
2853
2854 if (!p)
2855 return;
2856
2857 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->bank, p->gold);
2858
2859 }
2860
2861 void refreshall()
2862 {
2863 ListNode <aClient> *it;
2864 Player *p;
2865 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
2866 {
2867 it = players[x].First();
2868
2869 while (it)
2870 {
2871 p = it->getData()->stats;
2872 refresh(p);
2873 it = it->Next();
2874 }
2875 }
2876 }
2877
2878 void refresh(Player *p)
2879 {
2880 if (!p)
2881 return;
2882
2883 if (p->hp < p->maxhp)
2884 p->hp = p->maxhp;
2885 p->forest_fights = forestfights;
2886 p->player_fights = 3;
2887 setAlive(p);
2888 clearMaster(p);
2889 }
2890
2891 void do_refresh(char *u)
2892 {
2893 char *nick = strtok(NULL, " ");
2894 aClient *user;
2895
2896 if (!(user = find(u)))
2897 {
2898 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
2899 log("Error: aClient not found: %s", u);
2900 return;
2901 }
2902 else if (isIgnore(user))
2903 {
2904 #ifdef DEBUGMODE
2905 log("Ignoring %s.", user->getNick());
2906 #endif
2907 return;
2908 }
2909 else if (!isAdmin(user))
2910 {
2911 notice(s_GameServ, u, "You must be a %S admin to use this command!");
2912 return;
2913 }
2914 if (!nick)
2915 {
2916 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
2917 return;
2918 }
2919 else if (stricmp(nick, "ALL") == 0)
2920 {
2921 notice(s_GameServ, u, "Refreshing everyone's stats!");
2922 refreshall();
2923 }
2924 else if ((user = findplayer(nick)))
2925 {
2926 if (is_playing(user))
2927 {
2928 #ifdef P10
2929 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
2930 #else
2931 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
2932 #endif
2933 refresh(user->stats);
2934 }
2935 else
2936 {
2937 #ifdef P10
2938 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
2939 #else
2940 notice(s_GameServ, u, "%s is not playing.", user->getNick());
2941 #endif
2942 }
2943 }
2944 else
2945 {
2946 notice(s_GameServ, u, "Nick %s not found.", nick);
2947 return;
2948 }
2949 }
2950
2951
2952 void resetall()
2953 {
2954 ListNode <aClient> *it;
2955 Player *p;
2956
2957 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
2958 {
2959 it = players[x].First();
2960
2961 while (it)
2962 {
2963 p = it->getData()->stats;
2964 reset(p);
2965 it = it->Next();
2966 }
2967 }
2968 }
2969
2970 void reset(Player *p)
2971 {
2972 if (!p)
2973 return;
2974
2975 p->reset();
2976 }
2977
2978 void updateTS(Player *p)
2979 {
2980 if (!p)
2981 return;
2982
2983 #ifdef DEBUGMODE
2984 log("Old timestamp for %s: %ld", p->name, p->lastcommand);
2985 #endif
2986 p->lastcommand = time(NULL);
2987 #ifdef DEBUGMODE
2988 log("New timestamp for %s: %ld", p->name, p->lastcommand);
2989 #endif
2990
2991 }
2992
2993 bool timedOut(Player *p)
2994 {
2995 if (!p)
2996 return false;
2997 else if (p->lastcommand == 0)
2998 return false;
2999 else
3000 {
3001 if ((time(NULL) - p->lastcommand) >= maxidletime)
3002 return true;
3003
3004 return false;
3005 }
3006 }
3007
3008 void timeOutEvent(Player *p)
3009 {
3010 aClient *user = findplayer(p->name);
3011
3012 if (!user || !p->client) // then they're not playing
3013 return;
3014
3015 char *nick = user->getNick();
3016
3017 if (player_fight(user) && isYourTurn(p))
3018 {
3019 // Check to see if they were the idler or if it was the other
3020 // person
3021 if (p->lastcommand != p->battle->stats->lastcommand)
3022 {
3023 // This person's last command was given earlier,
3024 // so this person is the idler
3025 notice(s_GameServ, nick, "You timed out "\
3026 "during a fight. You lose your turn!");
3027 notice(s_GameServ, p->battle->getNick(),
3028 "%s hesitated for too long. Your move.", p->name);
3029 clearYourTurn(p);
3030 setYourTurn(p->battle->stats);
3031
3032 // Update the TS for both players to give them another
3033 // Chance to wake up, but if the other player doesn't
3034 // Attack now, they both get logged out.
3035 updateTS(p);
3036 p->battle->stats->lastcommand = p->lastcommand;
3037 display_players(p->battle);
3038 return;
3039 }
3040 else
3041 {
3042 notice(s_GameServ, p->battle->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->name);
3046 notice(s_GameServ, user->getNick(),
3047 "You and %s timed out at the same time."\
3048 " Don't fight if you're just going to "\
3049 "sit there!", p->battle->stats->name);
3050 logout(p->battle);
3051 logout(user);
3052 return;
3053 }
3054 }
3055 else if (!player_fight(user))
3056 {
3057 if (isAlive(user->stats) && user->stats->gold > 0)
3058 {
3059 // Place fun stuff here :)
3060 int randnum = 1 + rand() % 100; // 1-100
3061 #define GSN(s) notice(s_GameServ, nick, s)
3062 #define GSN2(s, f) notice(s_GameServ, nick, s, f)
3063
3064 if (randnum < 50)
3065 {
3066 // 35-100% of your gold goes pffft - kain
3067 int stolen = (35 + (rand() % 66)) * user->stats->gold / 100;
3068
3069 GSN("You stop for a moment to rest on the "\
3070 "street corner. All of a sudden, you "\
3071 "are ambushed from all sides by a hoarde "\
3072 "of knife wielding thugs.");
3073 GSN2("The thugs beat you into utter submission "\
3074 "and steal %d gold from you!", stolen);
3075 user->stats->gold -= stolen;
3076 }
3077 else if (randnum >= 50 && randnum < 75)
3078 {
3079 // 25-65% of your gold goes pffft - kain
3080 int stolen = (25 + (rand() % 41)) * user->stats->gold / 100;
3081 GSN("While dilly dallying around, you lose "\
3082 "your sense of time. Little did you know, "\
3083 "but thieves lifted your gold while you "\
3084 "weren't watching.");
3085 GSN2("Better luck next time... you lose %d gold", stolen);
3086 user->stats->gold -= stolen;
3087 }
3088 else if (randnum >= 75)
3089 {
3090 // 25-75% of your gold goes pffft - kain
3091 int stolen = (25 + (rand() % 51)) * user->stats->gold / 100;
3092 GSN("Good grief! A gaggle of gooey green ghostlike "\
3093 "goblins grabbed your gold!");
3094 GSN2("They stole %d gold from you!", stolen);
3095 user->stats->gold -= stolen;
3096 }
3097 }
3098
3099 // Always log out the user
3100 logout(user);
3101 }
3102 }
3103
3104 void do_reset(char *u)
3105 {
3106 char *nick = strtok(NULL, " ");
3107 aClient *user;
3108
3109 if (!(user = find(u)))
3110 {
3111 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3112 log("Error: aClient not found: %s", u);
3113 return;
3114 }
3115 else if (!isAdmin(user))
3116 {
3117 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3118 return;
3119 }
3120
3121 if (!nick)
3122 {
3123 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
3124 return;
3125 }
3126 else if (stricmp(nick, "ALL") == 0)
3127 {
3128 notice(s_GameServ, u, "Resetting everyone's stats!");
3129 resetall();
3130 }
3131 else if ((user = findbyrealnick(nick)))
3132 {
3133 if (is_playing(user))
3134 {
3135 #ifdef P10
3136 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
3137 #else
3138 notice(s_GameServ, u, "Resetting %s.", user->getNick());
3139 #endif
3140 reset(user->stats);
3141 }
3142 else
3143 {
3144 #ifdef P10
3145 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
3146 #else
3147 notice(s_GameServ, u, "%s is not playing.", user->getNick());
3148 #endif
3149 }
3150 }
3151 else
3152 {
3153 notice(s_GameServ, u, "Nick %s not found.", nick);
3154 return;
3155 }
3156 }
3157
3158 void do_help(char *u)
3159 {
3160 char *cmd = strtok(NULL, " ");
3161
3162 display_help(u, cmd);
3163 }
3164
3165 void display_help(char *u, char *file)
3166 {
3167 ifstream infile;
3168 char *buf;
3169
3170 if (!file)
3171 {
3172 infile.open("helpfiles/help");
3173 if (infile.fail())
3174 {
3175 log("Error opening helpfiles/help");
3176 notice(s_GameServ, u, "Error opening helpfiles/help");
3177 return;
3178 }
3179 buf = new char[1024];
3180 while(infile.getline(buf, 1024))
3181 {
3182 // Written this way, it will process %S in the helpfiles
3183 // Instead of notice(s_GameServ, u, "%s", buf);
3184 notice(s_GameServ, u, buf);
3185 }
3186
3187 // Minor recursion
3188 aClient *user = find(u);
3189 if (user && isAdmin(user))
3190 display_help(u, "admin_commands");
3191 }
3192 else
3193 {
3194 char *filename;
3195 filename = new char[strlen(file) + 11];
3196 strcpy(filename, "helpfiles/");
3197 strcat(filename, file);
3198
3199 for (unsigned int x = 10; x < strlen(filename); x++)
3200 filename[x] = tolower(filename[x]);
3201
3202 infile.open(filename);
3203 delete [] filename;
3204 if (infile.fail())
3205 {
3206 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
3207 return;
3208 }
3209 buf = new char[1024];
3210 while(infile.getline(buf, 1024))
3211 {
3212 // Written this way, it will process %S in the helpfiles
3213 // Instead of notice(s_GameServ, u, "%s", buf);
3214 notice(s_GameServ, u, buf);
3215 }
3216 }
3217 infile.close();
3218 delete [] buf;
3219 }
3220
3221 void do_admin(char *u)
3222 {
3223 aClient *user;
3224 char *pass = strtok(NULL, " ");
3225
3226 if (!(user = find(u)))
3227 {
3228 log("Error: aClient not found: %s", u);
3229 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
3230 return;
3231 }
3232
3233 if (!pass)
3234 {
3235 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
3236 return;
3237 }
3238
3239 if (isAdmin(user))
3240 {
3241 notice(s_GameServ, u, "You already have administrator privledges.");
3242 return;
3243 }
3244 else if (strcmp(pass, adminpass) == 0)
3245 {
3246 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
3247 setAdmin(user);
3248 #ifdef P10
3249 log("%s became an administrator.", user->getRealNick());
3250 #else
3251 log("%s became an administrator.", user->getNick());
3252 #endif
3253 }
3254 else
3255 {
3256 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
3257 return;
3258 }
3259 }
3260
3261 bool load_monsters()
3262 {
3263 ifstream infile;
3264 infile.open("monsters.dat");
3265
3266 char *buf;
3267
3268 if (infile.fail())
3269 {
3270 log("Error opening monsters.dat");
3271 return false;
3272 }
3273 init_monsters();
3274 buf = new char[2048];
3275
3276 #ifdef DEBUGMODE
3277 log("Loading monsters from monsters.dat");
3278 #endif
3279
3280 for (int l = 0; l < REALLEVELS; l++)
3281 {
3282 for (int m = 0; m < MONSTERS;)
3283 {
3284 infile.getline(buf, 2048);
3285 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
3286 continue;
3287 else
3288 {
3289 strcpy(monsters[l][m]->name, strtok(buf, "~"));
3290 strcpy(monsters[l][m]->weapon, strtok(NULL, "~"));
3291 monsters[l][m]->strength = stringtoint(strtok(NULL, "~"));
3292 monsters[l][m]->gold = stringtoint(strtok(NULL, "~"));
3293 monsters[l][m]->exp = stringtoint(strtok(NULL, "~"));
3294 monsters[l][m]->maxhp = stringtoint(strtok(NULL, "~"));
3295 monsters[l][m]->hp = monsters[l][m]->maxhp;
3296 strcpy(monsters[l][m]->death, strtok(NULL, ""));
3297 m++;
3298 }
3299 }
3300 }
3301 delete [] buf;
3302 return true;
3303 }
3304
3305 // this will be hash.cpp start
3306 // thank you wcampbel
3307 unsigned long sHASH(const unsigned char *name)
3308 {
3309 unsigned long h = 0, g;
3310
3311 while (*name)
3312 {
3313 h = (h << 4) + (*name++); // Case sensitive for numerics
3314 if ((g = (h & 0xF0000000)))
3315 h ^= g >> 24;
3316 h &= ~g;
3317 }
3318 return h % U_TABLE_SIZE;
3319 }
3320
3321 unsigned long iHASH(const unsigned char *name)
3322 {
3323 unsigned long h = 0, g;
3324
3325 while (*name)
3326 {
3327 h = (h << 4) + tolower(*name++);
3328 if ((g = (h & 0xF0000000)))
3329 h ^= g >> 24;
3330 h &= ~g;
3331 }
3332 return h % U_TABLE_SIZE;
3333 }
3334
3335 // this will be hash.cpp end