]> jfr.im git - irc/gameservirc.git/blob - gameserv/gameserv.cpp
adding updateperiod to config file
[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 for (int x = 0; x < U_TABLE_SIZE; x++)
2132 {
2133 ListNode<aClient> *tempNode;
2134 tempNode = players[x].First();
2135 while (tempNode)
2136 {
2137 if (tempNode->getData()->stats->client)
2138 logout(tempNode->getData()->stats->client);
2139 tempNode = tempNode->Next();
2140 }
2141 players[x].deleteNodes();
2142 }
2143
2144 while (infile.getline(buf, 1024, '\n'))
2145 {
2146 temp = new aClient;
2147 tempname = strtok(buf, " ");
2148 temp->stats = new Player(tempname);
2149 p = temp->stats;
2150
2151 p->level = stringtoint(strtok(NULL, " "));
2152 p->exp = stringtoint(strtok(NULL, " "));
2153 p->gold = stringtoint(strtok(NULL, " "));
2154 p->bank = stringtoint(strtok(NULL, " "));
2155 p->hp = stringtoint(strtok(NULL, " "));
2156 p->maxhp = stringtoint(strtok(NULL, " "));
2157 p->strength = stringtoint(strtok(NULL, " "));
2158 p->defense = stringtoint(strtok(NULL, " "));
2159 p->armor = stringtoint(strtok(NULL, " "));
2160 p->weapon = stringtoint(strtok(NULL, " "));
2161 p->forest_fights = stringtoint(strtok(NULL, " "));
2162 p->player_fights = stringtoint(strtok(NULL, " "));
2163 p->setFlags(stringtoint(strtok(NULL, " ")));
2164
2165 password = strtok(NULL, " ");
2166 strcpy(p->password, password);
2167 temp->setNick("Not Playing");
2168 #ifdef P10
2169 temp->setRealNick("Not Playing");
2170 #endif
2171
2172 p->inventory.reset(); // Set inventory to all 0s
2173 // Old player databases didn't have these three extra values
2174 // If they come up null, leave them to 0 as the default.
2175 // On the next gameserv database save, it will save the values.
2176 tempname = strtok(NULL, " ");
2177 if (tempname)
2178 p->inventory.setHealing(stringtoint(tempname));
2179
2180 tempname = strtok(NULL, " ");
2181 if (tempname)
2182 p->inventory.setStrength(stringtoint(tempname));
2183
2184 tempname = strtok(NULL, " ");
2185 if (tempname)
2186 p->inventory.setDefense(stringtoint(tempname));
2187
2188 tempname = strtok(NULL, " ");
2189 if (tempname)
2190 p->inventory.setHP(stringtoint(tempname));
2191 unsigned long hv = iHASH((unsigned char *) temp->stats->name);
2192
2193 temp->stats->client = NULL;
2194 players[hv].insertAtBack(temp);
2195 delete temp;
2196 }
2197 delete [] buf;
2198 infile.close();
2199 return 1;
2200 }
2201
2202 bool passcmp(char *encrypted, char *plaintext)
2203 {
2204 char salt[3];
2205 char *plaintext2, *plainToencrypt;
2206 bool same = false;
2207
2208 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
2209 strcpy(plaintext2, plaintext);
2210
2211 salt[0] = encrypted[0];
2212 salt[1] = encrypted[1];
2213 salt[3] = '\0';
2214
2215 plainToencrypt = crypt(plaintext2, salt);
2216
2217 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
2218
2219 delete []plaintext2;
2220
2221 return same;
2222 }
2223
2224 bool check_password(char *name, char *plaintext)
2225 {
2226 aClient *client;
2227
2228 if (!(client = findplayer(name)))
2229 return false;
2230 else
2231 {
2232 return passcmp(client->stats->password, plaintext);
2233 }
2234 }
2235
2236 void do_store(char *u)
2237 {
2238 char *cmd = strtok(NULL, " ");
2239 char *item = strtok(NULL, " ");
2240 char *num = strtok(NULL, " ");
2241 char *space;
2242 int wep;
2243 aClient *user;
2244 Player *p;
2245
2246 if (!cmd || !item)
2247 {
2248 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2249 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2250 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2251 return;
2252 }
2253 else if (!(user = find(u)))
2254 {
2255 log("Fatal Error: could not find %s in client list", u);
2256 return;
2257 }
2258 else if (isIgnore(user))
2259 {
2260 #ifdef DEBUGMODE
2261 log("Ignoring %s.", user->getNick());
2262 #endif
2263 return;
2264 }
2265 else if (!is_playing(user))
2266 {
2267 notice(s_GameServ, u, "You must be playing to use the store!");
2268 return;
2269 }
2270 else if (!isAlive(user->stats))
2271 {
2272 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
2273 return;
2274 }
2275 updateTS(user->stats);
2276
2277 if (stricmp(cmd, "LIST") == 0)
2278 {
2279 if (stricmp(item, "WEAPONS") == 0)
2280 {
2281 notice(s_GameServ, u, "Welcome to Kain's Armory");
2282 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
2283 for (int x = 1; x < WNA; x++)
2284 {
2285 space = spaces(strlen(weapons[x]), ".");
2286 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
2287 free(space);
2288 }
2289 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
2290 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
2291
2292 }
2293 else if (stricmp(item, "ARMOR") == 0)
2294 {
2295 notice(s_GameServ, u, "Welcome to Kain's Armory");
2296 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
2297 for (int x = 1; x < WNA; x++)
2298 {
2299 space = spaces(strlen(armors[x]), ".");
2300 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
2301 free(space);
2302 }
2303 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
2304 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
2305
2306
2307 }
2308 } else if (stricmp(cmd, "BUY") == 0) {
2309 if (!num)
2310 {
2311 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2312 return;
2313 }
2314 else if (!isstringnum(num))
2315 {
2316 notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
2317 return;
2318 }
2319 if (stricmp(item, "WEAPON") == 0)
2320 {
2321 wep = stringtoint(num);
2322 if (wep >= WNA || wep < 1)
2323 {
2324 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2325 return;
2326 }
2327
2328 p = user->stats;
2329
2330 if (p->weapon != 0)
2331 notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
2332 else if (p->gold < prices[wep - 1])
2333 notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
2334 else
2335 {
2336 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
2337 p->weapon = wep;
2338 p->gold -= prices[wep - 1];
2339 }
2340 }
2341 else if (stricmp(item, "ARMOR") == 0)
2342 {
2343 wep = stringtoint(num);
2344 if (wep >= WNA || wep < 1)
2345 {
2346 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2347 return;
2348 }
2349
2350 p = user->stats;
2351
2352 if (p->armor != 0)
2353 notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
2354 else if (p->gold < prices[wep - 1])
2355 notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
2356 else
2357 {
2358 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
2359 p->armor = wep;
2360 p->gold -= prices[wep - 1];
2361 }
2362 }
2363 }
2364 else if (stricmp(cmd, "SELL" ) == 0)
2365 {
2366 p = user->stats;
2367
2368 if (stricmp(item, "WEAPON") == 0)
2369 {
2370 if (p->weapon == 0)
2371 {
2372 notice(s_GameServ, u, "You want me to chop off your hands?");
2373 return;
2374 }
2375 else if (p->gold == 2000000000)
2376 {
2377 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2378 p->weapon = 0;
2379 }
2380 else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
2381 {
2382 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2383 notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
2384 p->gold = 2000000000;
2385 p->weapon = 0;
2386 }
2387 else
2388 {
2389 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
2390 p->gold += (prices[p->weapon - 1] / 2);
2391 p->weapon = 0;
2392 }
2393 }
2394 else if (stricmp(item, "ARMOR") == 0)
2395 {
2396 p = user->stats;
2397
2398 if (p->armor == 0)
2399 {
2400 notice(s_GameServ, u, "I don't think you can be any more naked...");
2401 return;
2402 }
2403 if (p->gold == 2000000000)
2404 {
2405 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2406 p->armor = 0;
2407 }
2408 else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
2409 {
2410 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2411 notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
2412 p->gold = 2000000000;
2413 p->armor = 0;
2414 }
2415 else
2416 {
2417 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
2418 (prices[p->armor - 1] / 2));
2419
2420 p->gold += (prices[p->armor - 1] / 2);
2421 p->armor = 0;
2422 }
2423 }
2424 else
2425 {
2426 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2427 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2428 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2429 }
2430 }
2431 else
2432 {
2433 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2434 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2435 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2436 return;
2437 }
2438 }
2439 void do_inventory(char *u)
2440 {
2441 aClient *user;
2442
2443 if (!(user = find(u)))
2444 {
2445 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2446 return;
2447 }
2448 else if (isIgnore(user))
2449 {
2450 #ifdef DEBUGMODE
2451 log("Ignoring %s.", user->getNick());
2452 #endif
2453 return;
2454 }
2455 else if (!is_playing(user))
2456 {
2457 notice(s_GameServ, u, "You must be playing to check your inventory!");
2458 return;
2459 }
2460 updateTS(user->stats);
2461 showinventory(user, user);
2462 }
2463 void showinventory(aClient *from, aClient *to)
2464 {
2465 char *nick = to->getNick();
2466
2467 if (!to)
2468 to = from;
2469 if (is_playing(from))
2470 {
2471 Pouch *p = &from->stats->inventory;
2472 notice(s_GameServ, nick, "Inventory for %s:", from->stats->name);
2473 notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
2474 notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
2475 notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
2476 notice(s_GameServ, nick, " HP Potions: %d", p->HP());
2477 }
2478 }
2479 void do_tavern(char *u)
2480 {
2481 char *cmd = strtok(NULL, " ");
2482 long int price;
2483
2484 aClient *user;
2485 Player *p;
2486
2487 if (!(user = find(u)))
2488 {
2489 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2490 return;
2491 }
2492 else if (isIgnore(user))
2493 {
2494 #ifdef DEBUGMODE
2495 log("Ignoring %s.", user->getNick());
2496 #endif
2497 return;
2498 }
2499 else if (!is_playing(user))
2500 {
2501 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2502 return;
2503 }
2504 else if (is_fighting(user))
2505 {
2506 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2507 return;
2508 }
2509
2510 updateTS(user->stats);
2511 p = user->stats;
2512
2513 if (!cmd)
2514 {
2515 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
2516 notice(s_GameServ, u, "Your commands:");
2517 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2518 notice(s_GameServ, u, "What'll it be?");
2519 }
2520 else if (stricmp(cmd, "LIST") == 0)
2521 {
2522 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2523 notice(s_GameServ, u, "1. Healing Potions for %ld Gold",
2524 1000 * p->level * 4);
2525 notice(s_GameServ, u, "2. Strength Potions for %ld Gold",
2526 2500 * p->level * 4);
2527 notice(s_GameServ, u, "3. Defense Potions for %ld Gold",
2528 3000 * p->level * 4);
2529 notice(s_GameServ, u, "4. HP Potions for %ld Gold",
2530 2000 * p->level * 4);
2531 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2532 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2533 }
2534 else if (stricmp(cmd, "BUY") == 0)
2535 {
2536 char *chnum = strtok(NULL, " ");
2537
2538 if (!chnum)
2539 {
2540 notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
2541 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
2542 return;
2543 }
2544 int num = stringtoint(chnum);
2545
2546 if (num < 1 || num > 4)
2547 {
2548 notice(s_GameServ, u, "Invalid Choice!");
2549 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2550 notice(s_GameServ, u, "1. Healing Potions for %ld Gold",
2551 1000 * p->level * 4);
2552 notice(s_GameServ, u, "2. Strength Potions for %ld Gold",
2553 2500 * p->level * 4);
2554 notice(s_GameServ, u, "3. Defense Potions for %ld Gold",
2555 3000 * p->level * 4);
2556 notice(s_GameServ, u, "4. HP Potions for %ld Gold",
2557 2000 * p->level * 4);
2558 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2559 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2560 return;
2561 }
2562 switch(num)
2563 {
2564 case 1:
2565 price = (1000 * p->level * 4);
2566 if (p->gold >= price)
2567 {
2568 notice(s_GameServ, u, "One healing potion coming right up!");
2569 p->inventory.incHealing();
2570 p->gold -= price;
2571 }
2572 else
2573 notice(s_GameServ, u, "You don't have enough gold!");
2574 break;
2575 case 2:
2576 price = 2500 * p->level * 4;
2577 if (p->gold >= price)
2578 {
2579 notice(s_GameServ, u, "One strength boost coming right up!");
2580 p->inventory.incStrength();
2581 p->gold -= price;
2582 }
2583 else
2584 notice(s_GameServ, u, "You don't have enough gold!");
2585 break;
2586 case 3:
2587 price = 3000 * p->level * 4;
2588 if (p->gold >= price)
2589 {
2590 notice(s_GameServ, u, "One defense boost coming right up!");
2591 p->inventory.incDefense();
2592 p->gold -= price;
2593 }
2594 else
2595 notice(s_GameServ, u, "You don't have enough gold!");
2596 break;
2597 case 4:
2598 price = 3000 * p->level * 4;
2599 if (p->gold >= price)
2600 {
2601 notice(s_GameServ, u, "One HP Potion coming right up!");
2602 p->inventory.incHP();
2603 p->gold -= price;
2604 }
2605 else
2606 notice(s_GameServ, u, "You don't have enough gold!");
2607 break;
2608 default:
2609 notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
2610 break;
2611 }
2612 }
2613 else
2614 {
2615 notice(s_GameServ, u, "Improper Syntax.");
2616 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2617 }
2618 }
2619
2620 void do_bank(char *u)
2621 {
2622 char *cmd = strtok(NULL, " ");
2623 char *amount = strtok(NULL, " ");
2624 char *nick = strtok(NULL, " ");
2625
2626 aClient *user;
2627 Player *p;
2628
2629 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
2630 {
2631 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
2632 notice (s_GameServ, u, "BANK BALANCE");
2633 return;
2634 }
2635 else if (!(user = find(u)))
2636 {
2637 notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\
2638 " admin for help");
2639 log("Fatal Error. Couldn't find %s while executing do_bank()", u);
2640 return;
2641 }
2642 else if (isIgnore(user))
2643 {
2644 #ifdef DEBUGMODE
2645 log("Ignoring %s.", user->getNick());
2646 #endif
2647 return;
2648 }
2649 else if (!is_playing(user))
2650 {
2651 notice(s_GameServ, u, "You must be playing to use the bank!");
2652 return;
2653 }
2654 else if (is_fighting(user))
2655 {
2656 notice(s_GameServ, u, "You can't go to the bank during a fight!");
2657 return;
2658 }
2659 updateTS(user->stats);
2660 if (stricmp(cmd, "BALANCE") == 0)
2661 {
2662 showBankBalance(u);
2663 return;
2664 }
2665 else if (!isAlive(user->stats))
2666 {
2667 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2668 return;
2669 }
2670 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2671 {
2672 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2673 return;
2674 }
2675 if (stringtoint(amount) < 0)
2676 {
2677 notice(s_GameServ, u, "Sorry. This bank is not licensed "\
2678 "to handle such sums of cash, noble Lord.");
2679 return;
2680 }
2681 p = user->stats;
2682
2683 if (stricmp(cmd, "DEPOSIT") == 0)
2684 {
2685 if (p->bank == 2000000000)
2686 {
2687 notice(s_GameServ, u, "Your bank account is full, sire!");
2688 return;
2689 }
2690 else if (stricmp(amount, "ALL") == 0)
2691 {
2692 if (2000000000 - p->bank < p->gold)
2693 {
2694 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2695 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
2696 p->gold -= (2000000000 - p->bank);
2697 p->bank = 2000000000;
2698 showBankBalance(u);
2699 }
2700 else
2701 {
2702 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
2703 p->bank += p->gold;
2704 p->gold = 0;
2705 showBankBalance(u);
2706 }
2707 }
2708 else if (stringtoint(amount) > p->gold)
2709 {
2710 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
2711 showBankBalance(u);
2712 return;
2713 }
2714 else
2715 {
2716 if (2000000000 - p->bank < stringtoint(amount))
2717 {
2718 notice(s_GameServ, u, "You don't have room in your account for that much.");
2719 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
2720 p->gold -= (2000000000 - p->bank);
2721 p->bank = 2000000000;
2722 showBankBalance(u);
2723 }
2724 else
2725 {
2726 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2727 p->bank += stringtoint(amount);
2728 p->gold -= stringtoint(amount);
2729 showBankBalance(u);
2730 }
2731 }
2732 }
2733 else if (stricmp(cmd, "WITHDRAW") == 0)
2734 {
2735 if (p->gold == 2000000000)
2736 {
2737 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
2738 showBankBalance(u);
2739 return;
2740 }
2741 else if (stricmp(amount, "ALL") == 0)
2742 {
2743 if (2000000000 - p->gold < p->bank)
2744 {
2745 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2746 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
2747 p->bank -= (2000000000 - p->gold);
2748 p->gold = 2000000000;
2749 showBankBalance(u);
2750 }
2751 else
2752 {
2753 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
2754 p->gold += p->bank;
2755 p->bank = 0;
2756 showBankBalance(u);
2757 }
2758 }
2759 else if (stringtoint(amount) > p->bank)
2760 {
2761 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
2762 showBankBalance(u);
2763 return;
2764 }
2765 else
2766 {
2767 if (2000000000 - p->gold < stringtoint(amount))
2768 {
2769 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2770 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2771 (2000000000 - p->gold));
2772 p->bank -= (2000000000 - p->gold);
2773 p->gold = 2000000000;
2774 showBankBalance(u);
2775 }
2776 else
2777 {
2778 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2779 p->gold += stringtoint(amount);
2780 p->bank -= stringtoint(amount);
2781 showBankBalance(u);
2782 }
2783 }
2784 }
2785
2786 }
2787
2788 void do_dragon(char *u)
2789 {
2790 aClient *user;
2791
2792 if (!(user = find(u)))
2793 {
2794 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2795 return;
2796 }
2797 else if (isIgnore(user))
2798 {
2799 #ifdef DEBUGMODE
2800 log("Ignoring %s.", user->getNick());
2801 #endif
2802 return;
2803 }
2804 else if (!is_playing(user))
2805 {
2806 notice(s_GameServ, u, "You must be playing to fight the dragon!");
2807 return;
2808 }
2809 else if (is_fighting(user))
2810 {
2811 notice(s_GameServ, u, "You are already in a fight. How will you fight the almighty dragon!?");
2812 return;
2813 }
2814 else if (!isAlive(user->stats))
2815 {
2816 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2817 return;
2818 }
2819 else if (user->stats->level < REALLEVELS)
2820 {
2821 notice(s_GameServ, u, "You fool! Only those strong enough "\
2822 "to vanquish any foe should DARE fight the dragon!");
2823 notice(s_GameServ, u, "To put it in terms you can understand: "\
2824 "You are too weak. You must be Level %d!", REALLEVELS);
2825 return;
2826 }
2827
2828 updateTS(user->stats);
2829
2830 Player *p = user->stats;
2831 p->fight = new Monster(boss);
2832 notice(s_GameServ, u, "You approach the dragon's lair cautiously.");
2833 notice(s_GameServ, u, "The stench of sulfer fills the air as a "\
2834 "deep, red fog rolls in. The air is filled with the "\
2835 "heated mist of deadly fire from beyond the cave "\
2836 "entrance.");
2837 notice(s_GameServ, u, "You adjust your %s, tighten your grip on "\
2838 "your %s, and venture into the hot, dark cave. "\
2839 "You are surprised at the angle of descent as you climb "\
2840 "lower and lower, deeper into the dragon's den.");
2841 notice(s_GameServ, u, "You come to the end of the cave to find "\
2842 "a tooth. It is a large tooth... bigger than your torso."\
2843 " Suddenly the darkness lifts from the gleam of an eye "\
2844 " staring into your soul! The eye is large... HUGE!");
2845 notice(s_GameServ, u, "Just then you notice the eye begin to "\
2846 "glare orange! The tooth is moving... but it is still too "\
2847 "dark for you to make out.... THE DRAGON! You see it!");
2848 display_monster(u);
2849 }
2850
2851 void do_master(char *u)
2852 {
2853 aClient *user;
2854
2855
2856 if (!(user = find(u)))
2857 {
2858 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2859 return;
2860 }
2861 else if (isIgnore(user))
2862 {
2863 #ifdef DEBUGMODE
2864 log("Ignoring %s.", user->getNick());
2865 #endif
2866 return;
2867 }
2868 else if (!is_playing(user))
2869 {
2870 notice(s_GameServ, u, "You must be playing to see your master!");
2871 return;
2872 }
2873 else if (is_fighting(user))
2874 {
2875 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
2876 return;
2877 }
2878 else if (!isAlive(user->stats))
2879 {
2880 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2881 return;
2882 }
2883
2884 updateTS(user->stats);
2885
2886 char *cmd = strtok(NULL, " ");
2887 Player *p = user->stats;
2888 long int need = 0;
2889
2890 if (seenMaster(p))
2891 {
2892 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
2893 return;
2894 }
2895
2896 if (cmd != NULL)
2897 {
2898 switch(p->level)
2899 {
2900 case 1:
2901 need = 200;
2902 break;
2903 case 2:
2904 need = 800;
2905 break;
2906 case 3:
2907 need = 2000;
2908 break;
2909 case 4:
2910 need = 8000;
2911 break;
2912 case 5:
2913 need = 20000;
2914 break;
2915 case 6:
2916 need = 80000;
2917 break;
2918 case 7:
2919 need = 200000;
2920 break;
2921 case 8:
2922 need = 800000;
2923 break;
2924 case 9:
2925 need = 2000000;
2926 break;
2927 case 10:
2928 need = 8000000;
2929 break;
2930 case 11:
2931 need = 20000000;
2932 break;
2933
2934 case REALLEVELS:
2935 need = p->exp + 1;
2936 notice(s_GameServ, u, "You are at level %d. You are the master. What's left? The DRAGON!", REALLEVELS);
2937 return;
2938 break;
2939 default:
2940 need = p->exp + 1; // Unknown level... don't let them fight a fake master!
2941 break;
2942 }
2943 }
2944 else
2945 {
2946 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2947 return;
2948 }
2949
2950 if (stricmp(cmd, "FIGHT") == 0)
2951 {
2952 if (p->exp >= need)
2953 {
2954 setMaster(p);
2955 see_master(u);
2956 }
2957 else
2958 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.", masters[p->level - 1]->name, (need - p->exp));
2959 return;
2960 }
2961 else if (stricmp(cmd, "QUESTION") == 0)
2962 {
2963 if (p->exp >= need)
2964 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);
2965 else
2966 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", masters[p->level - 1]->name, p->name);
2967
2968 return;
2969 }
2970 else
2971 {
2972 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2973 }
2974 }
2975
2976 void see_master(char *u)
2977 {
2978 aClient *user;
2979
2980 if (!(user = find(u)))
2981 {
2982 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2983 return;
2984 }
2985
2986 if (!is_fighting(user) && is_playing(user))
2987 {
2988 Player *p = user->stats;
2989 p->master = new Monster(masters[p->level - 1]);
2990 p->fight = p->master;
2991 display_monster(u); // Since master is the same structure, use this function
2992 }
2993 }
2994
2995 void showBankBalance(const char *u)
2996 {
2997 aClient *user;
2998 Player *p;
2999
3000 if (!(user = find(u)))
3001 return;
3002
3003 p = user->stats;
3004
3005 if (!p)
3006 return;
3007
3008 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->bank, p->gold);
3009
3010 }
3011
3012 void refreshall()
3013 {
3014 ListNode <aClient> *it;
3015 Player *p;
3016 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3017 {
3018 it = players[x].First();
3019
3020 while (it)
3021 {
3022 p = it->getData()->stats;
3023 refresh(p);
3024 it = it->Next();
3025 }
3026 }
3027 }
3028
3029 void refresh(Player *p)
3030 {
3031 if (!p)
3032 return;
3033
3034 if (p->hp < p->maxhp)
3035 p->hp = p->maxhp;
3036 p->forest_fights = forestfights;
3037 p->player_fights = 3;
3038 setAlive(p);
3039 clearMaster(p);
3040 }
3041
3042 void do_refresh(char *u)
3043 {
3044 char *nick = strtok(NULL, " ");
3045 aClient *user;
3046
3047 if (!(user = find(u)))
3048 {
3049 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3050 log("Error: aClient not found: %s", u);
3051 return;
3052 }
3053 else if (isIgnore(user))
3054 {
3055 #ifdef DEBUGMODE
3056 log("Ignoring %s.", user->getNick());
3057 #endif
3058 return;
3059 }
3060 else if (!isAdmin(user))
3061 {
3062 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3063 return;
3064 }
3065 if (!nick)
3066 {
3067 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
3068 return;
3069 }
3070 else if (stricmp(nick, "ALL") == 0)
3071 {
3072 notice(s_GameServ, u, "Refreshing everyone's stats!");
3073 refreshall();
3074 }
3075 else if ((user = findplayer(nick)))
3076 {
3077 if (is_playing(user))
3078 {
3079 #ifdef P10
3080 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
3081 #else
3082 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
3083 #endif
3084 refresh(user->stats);
3085 }
3086 else
3087 {
3088 #ifdef P10
3089 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
3090 #else
3091 notice(s_GameServ, u, "%s is not playing.", user->getNick());
3092 #endif
3093 }
3094 }
3095 else
3096 {
3097 notice(s_GameServ, u, "Nick %s not found.", nick);
3098 return;
3099 }
3100 }
3101
3102
3103 void resetall()
3104 {
3105 ListNode <aClient> *it;
3106 Player *p;
3107
3108 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3109 {
3110 it = players[x].First();
3111
3112 while (it)
3113 {
3114 p = it->getData()->stats;
3115 reset(p);
3116 it = it->Next();
3117 }
3118 }
3119 }
3120
3121 void reset(Player *p)
3122 {
3123 if (!p)
3124 return;
3125
3126 p->reset();
3127 }
3128
3129 void updateTS(Player *p)
3130 {
3131 if (!p)
3132 return;
3133
3134 #ifdef DEBUGMODE
3135 log("Old timestamp for %s: %ld", p->name, p->lastcommand);
3136 #endif
3137 p->lastcommand = time(NULL);
3138 #ifdef DEBUGMODE
3139 log("New timestamp for %s: %ld", p->name, p->lastcommand);
3140 #endif
3141
3142 }
3143
3144 bool timedOut(Player *p)
3145 {
3146 if (!p)
3147 return false;
3148 else if (p->lastcommand == 0)
3149 return false;
3150 else
3151 {
3152 if ((time(NULL) - p->lastcommand) >= maxidletime)
3153 return true;
3154
3155 return false;
3156 }
3157 }
3158
3159 void timeOutEvent(Player *p)
3160 {
3161 aClient *user = findplayer(p->name);
3162
3163 if (!user || !p->client) // then they're not playing
3164 return;
3165
3166 char *nick = user->getNick();
3167
3168 if (player_fight(user) && isYourTurn(p))
3169 {
3170 // Check to see if they were the idler or if it was the other
3171 // person
3172 if (p->lastcommand != p->battle->stats->lastcommand)
3173 {
3174 // This person's last command was given earlier,
3175 // so this person is the idler
3176 notice(s_GameServ, nick, "You timed out "\
3177 "during a fight. You lose your turn!");
3178 notice(s_GameServ, p->battle->getNick(),
3179 "%s hesitated for too long. Your move.", p->name);
3180 clearYourTurn(p);
3181 setYourTurn(p->battle->stats);
3182
3183 // Update the TS for both players to give them another
3184 // Chance to wake up, but if the other player doesn't
3185 // Attack now, they both get logged out.
3186 updateTS(p);
3187 p->battle->stats->lastcommand = p->lastcommand;
3188 display_players(p->battle);
3189 return;
3190 }
3191 else
3192 {
3193 notice(s_GameServ, p->battle->getNick(),
3194 "You and %s timed out at the same time."\
3195 " Don't fight if you're just going to "\
3196 "sit there!", p->name);
3197 notice(s_GameServ, user->getNick(),
3198 "You and %s timed out at the same time."\
3199 " Don't fight if you're just going to "\
3200 "sit there!", p->battle->stats->name);
3201 logout(p->battle);
3202 logout(user);
3203 return;
3204 }
3205 }
3206 else if (!player_fight(user))
3207 {
3208 if (isAlive(user->stats) && user->stats->gold > 0)
3209 {
3210 // Place fun stuff here :)
3211 int randnum = 1 + rand() % 100; // 1-100
3212 #define GSN(s) notice(s_GameServ, nick, s)
3213 #define GSN2(s, f) notice(s_GameServ, nick, s, f)
3214
3215 if (randnum < 50)
3216 {
3217 // 35-100% of your gold goes pffft - kain
3218 int stolen = (35 + (rand() % 66)) * user->stats->gold / 100;
3219
3220 GSN("You stop for a moment to rest on the "\
3221 "street corner. All of a sudden, you "\
3222 "are ambushed from all sides by a hoarde "\
3223 "of knife wielding thugs.");
3224 GSN2("The thugs beat you into utter submission "\
3225 "and steal %d gold from you!", stolen);
3226 user->stats->gold -= stolen;
3227 }
3228 else if (randnum >= 50 && randnum < 75)
3229 {
3230 // 25-65% of your gold goes pffft - kain
3231 int stolen = (25 + (rand() % 41)) * user->stats->gold / 100;
3232 GSN("While dilly dallying around, you lose "\
3233 "your sense of time. Little did you know, "\
3234 "but thieves lifted your gold while you "\
3235 "weren't watching.");
3236 GSN2("Better luck next time... you lose %d gold", stolen);
3237 user->stats->gold -= stolen;
3238 }
3239 else if (randnum >= 75)
3240 {
3241 // 25-75% of your gold goes pffft - kain
3242 int stolen = (25 + (rand() % 51)) * user->stats->gold / 100;
3243 GSN("Good grief! A gaggle of gooey green ghostlike "\
3244 "goblins grabbed your gold!");
3245 GSN2("They stole %d gold from you!", stolen);
3246 user->stats->gold -= stolen;
3247 }
3248 }
3249
3250 // Always log out the user
3251 logout(user);
3252 }
3253 }
3254
3255 void do_reset(char *u)
3256 {
3257 char *nick = strtok(NULL, " ");
3258 aClient *user;
3259
3260 if (!(user = find(u)))
3261 {
3262 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3263 log("Error: aClient not found: %s", u);
3264 return;
3265 }
3266 else if (!isAdmin(user))
3267 {
3268 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3269 return;
3270 }
3271
3272 if (!nick)
3273 {
3274 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
3275 return;
3276 }
3277 else if (stricmp(nick, "ALL") == 0)
3278 {
3279 notice(s_GameServ, u, "Resetting everyone's stats!");
3280 resetall();
3281 }
3282 else if ((user = findbyrealnick(nick)))
3283 {
3284 if (is_playing(user))
3285 {
3286 #ifdef P10
3287 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
3288 #else
3289 notice(s_GameServ, u, "Resetting %s.", user->getNick());
3290 #endif
3291 reset(user->stats);
3292 }
3293 else
3294 {
3295 #ifdef P10
3296 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
3297 #else
3298 notice(s_GameServ, u, "%s is not playing.", user->getNick());
3299 #endif
3300 }
3301 }
3302 else
3303 {
3304 notice(s_GameServ, u, "Nick %s not found.", nick);
3305 return;
3306 }
3307 }
3308
3309 void do_help(char *u)
3310 {
3311 char *cmd = strtok(NULL, " ");
3312
3313 display_help(u, cmd);
3314 }
3315
3316 void display_help(char *u, char *file)
3317 {
3318 ifstream infile;
3319 char *buf;
3320
3321 if (!file)
3322 {
3323 infile.open("helpfiles/help");
3324 if (infile.fail())
3325 {
3326 log("Error opening helpfiles/help");
3327 notice(s_GameServ, u, "Error opening helpfiles/help");
3328 return;
3329 }
3330 buf = new char[1024];
3331 while(infile.getline(buf, 1024))
3332 {
3333 // Written this way, it will process %S in the helpfiles
3334 // Instead of notice(s_GameServ, u, "%s", buf);
3335 notice(s_GameServ, u, buf);
3336 }
3337
3338 // Minor recursion
3339 aClient *user = find(u);
3340 if (user && isAdmin(user))
3341 display_help(u, "admin_commands");
3342 }
3343 else
3344 {
3345 char *filename;
3346 filename = new char[strlen(file) + 11];
3347 strcpy(filename, "helpfiles/");
3348 strcat(filename, file);
3349
3350 for (unsigned int x = 10; x < strlen(filename); x++)
3351 filename[x] = tolower(filename[x]);
3352
3353 infile.open(filename);
3354 delete [] filename;
3355 if (infile.fail())
3356 {
3357 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
3358 return;
3359 }
3360 buf = new char[1024];
3361 while(infile.getline(buf, 1024))
3362 {
3363 // Written this way, it will process %S in the helpfiles
3364 // Instead of notice(s_GameServ, u, "%s", buf);
3365 notice(s_GameServ, u, buf);
3366 }
3367 }
3368 infile.close();
3369 delete [] buf;
3370 }
3371
3372 void do_admin(char *u)
3373 {
3374 aClient *user;
3375 char *pass = strtok(NULL, " ");
3376
3377 if (!(user = find(u)))
3378 {
3379 log("Error: aClient not found: %s", u);
3380 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
3381 return;
3382 }
3383
3384 if (!pass)
3385 {
3386 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
3387 return;
3388 }
3389
3390 if (isAdmin(user))
3391 {
3392 notice(s_GameServ, u, "You already have administrator privledges.");
3393 return;
3394 }
3395 else if (strcmp(pass, adminpass) == 0)
3396 {
3397 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
3398 setAdmin(user);
3399 #ifdef P10
3400 log("%s became an administrator.", user->getRealNick());
3401 #else
3402 log("%s became an administrator.", user->getNick());
3403 #endif
3404 }
3405 else
3406 {
3407 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
3408 return;
3409 }
3410 }
3411
3412 bool load_monsters()
3413 {
3414 ifstream infile;
3415 infile.open("monsters.dat");
3416
3417 char *buf;
3418
3419 if (infile.fail())
3420 {
3421 log("Error opening monsters.dat");
3422 return false;
3423 }
3424 init_monsters();
3425 buf = new char[2048];
3426
3427 #ifdef DEBUGMODE
3428 log("Loading monsters from monsters.dat");
3429 #endif
3430
3431 for (int l = 0; l < REALLEVELS; l++)
3432 {
3433 for (int m = 0; m < MONSTERS;)
3434 {
3435 infile.getline(buf, 2048);
3436 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
3437 continue;
3438 else
3439 {
3440 strcpy(monsters[l][m]->name, strtok(buf, "~"));
3441 strcpy(monsters[l][m]->weapon, strtok(NULL, "~"));
3442 monsters[l][m]->strength = stringtoint(strtok(NULL, "~"));
3443 monsters[l][m]->gold = stringtoint(strtok(NULL, "~"));
3444 monsters[l][m]->exp = stringtoint(strtok(NULL, "~"));
3445 monsters[l][m]->maxhp = stringtoint(strtok(NULL, "~"));
3446 monsters[l][m]->hp = monsters[l][m]->maxhp;
3447 strcpy(monsters[l][m]->death, strtok(NULL, ""));
3448 m++;
3449 }
3450 }
3451 }
3452 delete [] buf;
3453 return true;
3454 }