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