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