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