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