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