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