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