]> jfr.im git - irc/gameservirc.git/blob - gameserv/gameserv.cpp
Fixed BANK BALANCE from coring.
[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
14 #if defined(HAVE_CRYPT_H)
15
16 #include <crypt.h>
17
18 #elif defined(HAVE_UNISTD_H)
19
20 #include <unistd.h>
21
22 #endif
23
24 List<aClient> players;
25
26 Monster *monsters[LEVELS][MONSTERS]; // Monsters per level. Total = MONSTERS * LEVELS
27
28 Monster *masters[LEVELS]; // A master for each level
29
30 // Database functions
31 int save_gs_dbase();
32 int load_gs_dbase();
33
34 // String functions
35 #ifndef HAVE_STRTOK
36 char *strtok(char *str, const char *delim);
37 #endif
38
39 int stricmp(const char *s1, const char *s2);
40 int strnicmp(const char *s1, const char *s2, size_t len);
41 // String Functions
42
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 is_playing(char *u); // True if the given nickname in the clients list is playing.
56 bool is_playing(aClient *user);
57
58 bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
59 bool is_fighting(aClient *user);
60
61 bool player_fight(char *u); // True if the player is fighting another player.
62 bool player_fight(aClient *user);
63
64 bool master_fight(char *u); // True if the player is fighting their master.
65 bool master_fight(aClient *user);
66
67 /********** GameServ Booleans **********/
68
69 void display_help(char *u, char *file = NULL);
70 void display_monster(char *u);
71 void display_players(char *u);
72 void display_players(aClient *user);
73 long int chartoint(char ch);
74 int isstringnum(char *num);
75 long int pow (int x, int y);
76 long int stringtoint(char *number);
77
78 char *spaces(int len, char *seperator);
79 void refresh(Player *p);
80 void refreshall();
81 void reset(Player *p);
82 void init_masters();
83 void init_monsters();
84 bool load_monsters();
85 void delete_monsters();
86 void delete_masters();
87
88 void do_admin(char *u);
89 void do_attack(char *u);
90 void do_bank(char *u);
91 void do_fight(char *u);
92 void do_heal(char *u);
93 void do_help(char *u);
94 void do_identify(char *u);
95 void do_inventory(char *u);
96 void do_refresh(char *u);
97 void do_register(char *u);
98 void do_list(char *u);
99 void do_master(char *u);
100 void do_play(char *u);
101 void do_quitg(char *u);
102 void do_reset(char *u);
103 void do_run(char *u);
104 void do_stats(char *u);
105 void do_store(char *u);
106 void do_tavern(char *u);
107 void do_use(char *u);
108 void see_master(char *u);
109
110 void showstats(const char *u, const char *nick);
111 void showinventory(aClient *from, aClient *to);
112 void showBankBalance(const char *u);
113 void end_turn(aClient *user);
114
115 #define WNA 16
116 char *weapons[WNA] = { "Fists", "Stick", "Dagger", "Quarterstaff", "Short Sword",
117 "Long Sword", "Silver Spear", "Battle Axe", "The Ragnarok",
118 "Chain Saw", "Poison Sword", "Flame Sword", "Earth Hammer",
119 "Light Saber", "Masamune", "Mystical Sword"};
120
121 char *armors[WNA] = { "Nothing", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor",
122 "Full Body Armor", "Magic Mail", "Graphite Suit", "Steel Suit",
123 "Force Field", "Armor of Light", "Mythril Vest", "DemiGod Armor",
124 "Hades' Cloak", "Dragon Scales", "Adamantium"};
125
126 int prices[WNA - 1] = {200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000,
127 1000000, 4000000, 10000000, 40000000, 100000000, 400000000};
128 int webonus[WNA] = {0, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
129 int arbonus[WNA] = {0, 1, 3, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000};
130
131 int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550};
132 int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200};
133 int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
134
135 void gameserv(char *source, char *buf)
136 {
137 char *cmd;
138 cmd = strtok(buf, " ");
139
140 #ifndef P10
141 source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
142 #endif
143
144 if (cmd[0] == ':')
145 cmd++; // Get rid of that : at the beginning of the :text (command)
146
147 #ifdef DEBUGMODE
148 log("Source: %s Command: %s", source, cmd);
149 #endif
150
151 struct tm *tm;
152 time_t ti;
153 time(&ti);
154 tm = localtime(&ti);
155
156 int curday = tm->tm_mday;
157
158 if (curday != day)
159 {
160 refreshall();
161 day = curday;
162 save_day();
163 }
164
165 if (strnicmp(cmd, "\1PING", 6) == 0)
166 {
167 char *ts;
168 ts = strtok(NULL, "\1");
169 notice(s_GameServ, source, "\1PING %s\1", ts);
170 } else if (stricmp(cmd, "\1VERSION\1") == 0) {
171 notice(s_GameServ, source, "\1VERSION %s %s +devel\1", PACKAGE, VERSION);
172 } else if (stricmp(cmd, "SEARCH") == 0) {
173 cmd = strtok(NULL, " ");
174
175 if (!cmd)
176 notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
177 else
178 do_forest(source);
179
180 } else if (stricmp(cmd, "FIGHT") == 0) {
181 do_fight(source);
182 } else if (stricmp(cmd, "ATTACK") == 0) {
183 do_attack(source);
184 } else if (stricmp(cmd, "RUN") == 0) {
185 do_run(source);
186 } else if (stricmp(cmd, "USE") == 0) {
187 do_use(source);
188 } else if (stricmp(cmd, "HEAL") == 0) {
189 do_heal(source);
190 } else if (stricmp(cmd, "INVENTORY") == 0) {
191 do_inventory(source);
192 } else if (stricmp(cmd, "MASTER") == 0) {
193 do_master(source);
194 } else if (stricmp(cmd, "STORE") == 0) {
195 do_store(source);
196 } else if (stricmp(cmd, "BANK") == 0) {
197 do_bank(source);
198 } else if (stricmp(cmd, "ADMIN") == 0) {
199 do_admin(source);
200 } else if (stricmp(cmd, "REFRESH") == 0) {
201 do_refresh(source);
202 } else if (stricmp(cmd, "RESET") == 0) {
203 do_reset(source);
204 } else if (stricmp(cmd, "TAVERN") == 0) {
205 do_tavern(source);
206 } else if (stricmp(cmd, "LIST") == 0) {
207 do_list(source);
208 #ifdef DEBUGMODE
209 } else if (stricmp(cmd, "PRINT") == 0) {
210 cout << "Printing the clients list:" << endl;
211 clients.print();
212 cout << "\nPrinting the players list:" << endl;
213 players.print();
214 #endif
215 } else if (stricmp(cmd, "REGISTER") == 0) {
216 do_register(source);
217 } else if (stricmp(cmd, "IDENTIFY") == 0) {
218 do_identify(source);
219 } else if (stricmp(cmd, "HELP") == 0) {
220 do_help(source);
221 } else if (stricmp(cmd, "STATS") == 0) {
222 do_stats(source);
223 } else if (stricmp(cmd, "SHUTDOWN") == 0) {
224 aClient *user;
225
226 if (!(user = find(source)))
227 {
228 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
229 log("Error: aClient not found: %s", source);
230 }
231 else if (!isAdmin(user))
232 {
233 notice(s_GameServ, source, "You must be a %S admin to use this command!");
234 }
235 else
236 {
237 save_gs_dbase();
238 #ifdef P10
239 raw("[] SQ %s 0 :leaving: %s used the Shutdown command.", servername, user->getRealNick());
240 #else
241 raw("SQUIT %s :leaving: %s used the Shutdown command.", servername, source);
242 #endif
243 }
244 } else if (stricmp(cmd, "SAVE") == 0) {
245 aClient *user;
246
247 if (!(user = find(source)))
248 {
249 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
250 log("Error: aClient not found: %s", source);
251 }
252 else if (!isAdmin(user))
253 {
254 notice(s_GameServ, source, "You must be a %S admin to use this command!");
255 }
256 else
257 {
258 save_gs_dbase();
259 }
260 } else if (stricmp(cmd, "LOAD") == 0) {
261 aClient *user;
262
263 if (!(user = find(source)))
264 {
265 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
266 log("Error: aClient not found: %s", source);
267 }
268 else if (!isAdmin(user))
269 {
270 notice(s_GameServ, source, "You must be a %S admin to use this command!");
271 }
272 else
273 {
274 char *cmd2 = strtok(NULL, " ");
275 if (!cmd2)
276 {
277 notice(s_GameServ, source, "Loading player data from %s", playerdata);
278 load_gs_dbase();
279 }
280 else if (stricmp(cmd2, "MONSTERS") == 0)
281 {
282 notice(s_GameServ, source, "Loading monster data from %s", monsterdata);
283 load_monsters();
284 }
285 else
286 display_help(source, cmd);
287 }
288 } else if (stricmp(cmd, "RAW") == 0) {
289 aClient *user;
290
291 if (!(user = find(source)))
292 {
293 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
294 log("Error: aClient not found: %s", source);
295 }
296 else if (!isAdmin(user))
297 {
298 notice(s_GameServ, source, "You must be a %S admin to use this command!");
299 }
300 else
301 {
302 char *rest = strtok(NULL, "");
303 raw("%s", rest);
304 }
305 } else {
306 notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd);
307 }
308
309 source--; // Bring the ':' back so we don't leak memory
310 cmd--; // Same thing :)
311 }
312
313 int stricmp(const char *s1, const char *s2)
314 {
315 register int c;
316
317 while ((c = tolower(*s1)) == tolower(*s2)) {
318 if (c == 0)
319 return 0;
320 s1++;
321 s2++;
322 }
323 if (c < tolower(*s2))
324 return -1;
325 return 1;
326 }
327
328 void showstats(const char *u, const char *nick)
329 {
330 aClient *ni, *sender = find(u);
331 char *buf;
332 buf = new char[50];
333 char *space;
334
335
336 if (!(ni = findplayer(nick)))
337 {
338 notice(s_GameServ, u, "%s not found", nick);
339 }
340 else if (ni->stats)
341 {
342 notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name);
343
344 sprintf(buf, "Experience: %ld", ni->stats->exp);
345 space = spaces(strlen(buf), " ");
346 notice(s_GameServ, sender->getNick(), "%s%sLevel: %d", buf, space,
347 ni->stats->level);
348 delete [] space;
349
350 sprintf(buf, "Gold: %ld", ni->stats->gold);
351 space = spaces(strlen(buf), " ");
352 notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, ni->stats->bank);
353 delete [] space;
354
355 notice(s_GameServ, sender->getNick(), "Hit Points: %d of %d", ni->stats->hp,
356 ni->stats->maxhp);
357
358 sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->weapon]);
359 space = spaces(strlen(buf), " ");
360 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
361 buf, space, ni->stats->defense + arbonus[ni->stats->armor]);
362 delete [] space;
363
364 sprintf(buf, "Armor: %s", armors[ni->stats->armor]);
365 space = spaces(strlen(buf), " ");
366 notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
367 weapons[ni->stats->weapon]);
368 delete [] space;
369
370 sprintf(buf, "Forest Fights: %d", ni->stats->forest_fights);
371 space = spaces(strlen(buf), " ");
372 notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->player_fights);
373 delete [] space;
374 }
375 else
376 {
377 notice(s_GameServ, u, "%s is not playing!", ni->stats->name);
378 }
379 delete [] buf;
380 }
381
382 char *spaces(int len, char *seperator)
383 {
384 char *final;
385 final = new char[30];
386 int y;
387 strcpy(final, seperator);
388 for (y = 0; y < 30 - len; y++)
389 strcat(final, seperator);
390 return final;
391 }
392
393 void raw(const char *fmt, ...)
394 {
395 va_list args;
396 char *input;
397 const char *t = fmt;
398 input = new char[1024];
399 va_start(args, fmt);
400 memset(input, 0, sizeof(input)); // Initialize to NULL
401 for (; *t; t++)
402 {
403 if (*t == '%')
404 {
405 switch(*++t) {
406 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
407 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
408 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
409 case 'l':
410 if (*++t == 'd')
411 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
412 }
413 }
414 else
415 {
416 sprintf(input, "%s%c", input, *t);
417 }
418
419 }
420 #ifdef DEBUGMODE
421 log("Input: %s", input);
422 #endif
423
424 sprintf(input, "%s%s", input, "\r\n");
425 sock_puts(sock, input);
426 delete [] input;
427 va_end(args);
428 }
429 /* Send a NOTICE from the given source to the given nick. */
430
431 void notice(const char *source, const char *dest, const char *fmt, ...)
432 {
433 if (fmt[0] == '\0')
434 return;
435
436 va_list args;
437 char *input;
438 const char *t = fmt;
439 input = new char[1024];
440 va_start(args, fmt);
441 if (dest[0] == ':')
442 {
443 dest++;
444
445 #if !defined(P10)
446 sprintf(input, ":%s NOTICE %s :", source, dest);
447 #else
448 sprintf(input, "%s O %s :", gsnum, dest);
449 #endif
450
451 dest--;
452 }
453 else
454 {
455 #if !defined(P10)
456 sprintf(input, ":%s NOTICE %s :", source, dest);
457 #else
458 sprintf(input, "%s O %s :", gsnum, dest);
459 #endif
460 }
461
462 for (; *t; t++)
463 {
464 if (*t == '%')
465 {
466 switch(*++t) {
467 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
468 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
469 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
470 case 'l':
471 if (*++t == 'd')
472 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
473 }
474 }
475 else
476 {
477 sprintf(input, "%s%c", input, *t);
478 }
479
480 }
481 #ifdef DEBUGMODE
482 log("Input: %s", input);
483 #endif
484 sprintf(input, "%s%s", input, "\r\n");
485 sock_puts(sock, input);
486 delete [] input;
487 va_end(args);
488 }
489
490
491 int strnicmp(const char *s1, const char *s2, size_t len)
492 {
493 register int c;
494
495 if (!len)
496 return 0;
497 while ((c = tolower(*s1)) == tolower(*s2) && len > 0) {
498 if (c == 0 || --len == 0)
499 return 0;
500 s1++;
501 s2++;
502 }
503 if (c < tolower(*s2))
504 return -1;
505 return 1;
506 }
507
508 #ifndef HAVE_STRTOK
509 char *strtok(char *str, const char *delim)
510 {
511 static char *current = NULL;
512 char *ret;
513
514 if (str)
515 current = str;
516 if (!current)
517 return NULL;
518 current += strspn(current, delim);
519 ret = *current ? current : NULL;
520 current += strcspn(current, delim);
521 if (!*current)
522 current = NULL;
523 else
524 *current++ = 0;
525 return ret;
526 }
527 #endif
528
529 void do_list(char *u)
530 {
531 ListNode<aClient> *temp;
532 temp = players.First();
533 if (!players.isEmpty())
534 {
535 notice(s_GameServ, u, "People Playing:");
536 while(temp)
537 {
538
539 #ifdef P10
540 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getRealNick(),
541 temp->getData()->stats->name);
542 #else
543 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(),
544 temp->getData()->stats->name);
545 #endif
546
547 temp = temp->Next();
548 }
549 notice(s_GameServ, u, "End of List");
550 }
551 else
552 notice(s_GameServ, u, "No one is playing");
553 }
554
555 void do_register(char *u)
556 {
557 char *password, *name;
558 aClient *user, *p;
559 name = strtok(NULL, " ");
560 password = strtok(NULL, " ");
561
562 static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
563 static char salt[3];
564
565 salt[0] = saltChars[rand() % strlen(saltChars)];
566 salt[1] = saltChars[rand() % strlen(saltChars)];
567 salt[2] = '\0';
568
569 if (!name)
570 {
571 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
572 }
573 else if (!password)
574 {
575 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
576 }
577 else if ((user = find(u)))
578 {
579 p = findplayer(u);
580 if (!user->stats && !p)
581 {
582 user->stats = new Player(user);
583 user->stats->user = user; // Set the backwards pointer
584 strcpy(user->stats->password, crypt(password, salt));
585 strcpy(user->stats->name, name);
586 players.insertAtBack(user);
587 notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name, password);
588 notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!");
589 log("Nickname %s registered player %s.", u, user->stats->name);
590 }
591 else
592 {
593 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
594 }
595 }
596 }
597
598 void do_identify(char *u)
599 {
600 char *password, *name;
601 aClient *user, *p;
602 name = strtok(NULL, " ");
603 password = strtok(NULL, " ");
604 user = find(u);
605 if (!password || !name)
606 {
607 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
608 }
609 else if (!user)
610 {
611 notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, ""));
612 log("Error: aClient not found: %s", u);
613 }
614 else if (!(p = findplayer(name)) || !p->stats)
615 notice(s_GameServ, u, "Player %s not found", name);
616 else if (!check_password(name, password) && !isAdmin(user))
617 {
618 notice(s_GameServ, u, "Password incorrect");
619 }
620 else
621 {
622 if (p->stats->user && !isAdmin(user))
623 {
624 notice(s_GameServ, u, "That player has already identified.");
625 return;
626 }
627 if (!user->stats)
628 {
629 ListNode<aClient> *temp;
630 temp = players.Find(p);
631 if (!temp)
632 {
633 notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s",
634 strtok(NULL, ""));
635 return;
636 }
637 user->stats = new Player(p->stats->name);
638 #ifdef DEBUGMODE
639 log("Setting data for identified");
640 #endif
641 user->stats->setData(p->stats);
642
643 #ifdef DEBUGMODE
644 log("Player Identified");
645 #endif
646
647 temp->setPtr(user);
648
649 notice(s_GameServ, u, "Password Accepted. Identified.");
650
651 }
652 else
653 {
654 notice(s_GameServ, u, "Already identified. Contact a %S admin for help.");
655 }
656 }
657 }
658
659 void do_stats(char *u)
660 {
661 char *nick;
662 aClient *user;
663
664 nick = strtok(NULL, " ");
665
666 if (!nick)
667 {
668 if (!(user = find(u)))
669 {
670 notice(s_GameServ, u, "Fatal Error in do_stats(). Contact a %S admin for help!");
671 log("Error: aClient not found: %s", u);
672 return;
673 }
674 else if (!is_playing(user))
675 {
676 notice(s_GameServ, u, "You're not playing, so you have no stats!");
677 return;
678 }
679 else
680 showstats(u, user->stats->name);
681 }
682 else
683 showstats(u, nick);
684 }
685 void init_masters()
686 {
687 #ifdef DEBUGMODE
688 log("Calling delete_masters()");
689 #endif
690
691 delete_masters();
692
693 #ifdef DEBUGMODE
694 log("Initializing masters");
695 #endif
696
697 for (int x = 0; x < LEVELS; x++)
698 masters[x] = new Monster;
699
700 strcpy(masters[0]->name, "Old Bones");
701 strcpy(masters[0]->weapon, "Dull Sword Cane");
702 masters[0]->strength = 15;
703 masters[0]->gold = 0;
704 masters[0]->exp = 0;
705 masters[0]->maxhp = 30;
706 masters[0]->hp = 30;
707 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!");
708
709 strcpy(masters[1]->name, "Master Chang");
710 strcpy(masters[1]->weapon, "Nanchaku");
711 masters[1]->strength = 30;
712 masters[1]->gold = 0;
713 masters[1]->exp = 0;
714 masters[1]->maxhp = 40;
715 masters[1]->hp = 40;
716 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.");
717
718 strcpy(masters[2]->name, "Chuck Norris");
719 strcpy(masters[2]->weapon, "Ranger Kick");
720 masters[2]->strength = 85;
721 masters[2]->gold = 0;
722 masters[2]->exp = 0;
723 masters[2]->maxhp = 70;
724 masters[2]->hp = 70;
725 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!");
726
727
728 strcpy(masters[3]->name, "Mr. Miagi");
729 strcpy(masters[3]->weapon, "Petrified Bonsai");
730 masters[3]->strength = 120;
731 masters[3]->gold = 0;
732 masters[3]->exp = 0;
733 masters[3]->maxhp = 120;
734 masters[3]->hp = 120;
735 strcpy(masters[3]->death, "Skill comes from repeating the correct but seemingly mundane actions. Wax ON, wax OFF!");
736
737 strcpy(masters[4]->name, "Jackie Chan");
738 strcpy(masters[4]->weapon, "Kung Fu Kick");
739 masters[4]->strength = 135;
740 masters[4]->gold = 0;
741 masters[4]->exp = 0;
742 masters[4]->maxhp = 200;
743 masters[4]->hp = 200;
744 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!");
745
746 strcpy(masters[5]->name, "Jet Li");
747 strcpy(masters[5]->weapon, "Motorcycle");
748 masters[5]->strength = 160;
749 masters[5]->gold = 0;
750 masters[5]->exp = 0;
751 masters[5]->maxhp = 400;
752 masters[5]->hp = 400;
753 strcpy(masters[5]->death, "Failure is a fuel for excuses. It's the doing the do, that makes the making.");
754
755
756 strcpy(masters[6]->name, "Muhammad Ali");
757 strcpy(masters[6]->weapon, "Quick Jab");
758 masters[6]->strength = 185;
759 masters[6]->gold = 0;
760 masters[6]->exp = 0;
761 masters[6]->maxhp = 600;
762 masters[6]->hp = 600;
763 strcpy(masters[6]->death, "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up.");
764
765 strcpy(masters[7]->name, "Li Mu Bai");
766 strcpy(masters[7]->weapon, "Green Destiny");
767 masters[7]->strength = 210;
768 masters[7]->gold = 0;
769 masters[7]->exp = 0;
770 masters[7]->maxhp = 800;
771 masters[7]->hp = 800;
772 strcpy(masters[7]->death, "No growth without resistance. No action without reaction. No desire without restraint.");
773
774
775 strcpy(masters[8]->name, "Jimmy Wang Yu");
776 strcpy(masters[8]->weapon, "Flying Guillotine");
777 masters[8]->strength = 275;
778 masters[8]->gold = 0;
779 masters[8]->exp = 0;
780 masters[8]->maxhp = 1200;
781 masters[8]->hp = 1200;
782 strcpy(masters[8]->death, "You have beaten the one armed boxer. Proceed with caution!");
783
784 strcpy(masters[9]->name, "Wong Fei Hung");
785 strcpy(masters[9]->weapon, "Drunken Boxing");
786 masters[9]->strength = 360;
787 masters[9]->gold = 0;
788 masters[9]->exp = 0;
789 masters[9]->maxhp = 1800;
790 masters[9]->hp = 1800;
791 strcpy(masters[9]->death, "Hiccup! Monkey drinks master's wine!");
792
793 strcpy(masters[10]->name, "Bruce Lee");
794 strcpy(masters[10]->weapon, "Fists of fury");
795 masters[10]->strength = 575;
796 masters[10]->gold = 0;
797 masters[10]->exp = 0;
798 masters[10]->maxhp = 2500;
799 masters[10]->hp = 2500;
800 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.");
801 }
802
803 void init_monsters()
804 {
805 #ifdef DEBUGMODE
806 log("Calling delete_monsters");
807 #endif
808
809 delete_monsters();
810
811 for (int x = 0; x < LEVELS; x++)
812 for (int y = 0; y < MONSTERS; y++)
813 monsters[x][y] = new Monster();
814 }
815
816 void delete_monsters()
817 {
818 for (int x = 0; x < LEVELS; x++)
819 for (int y = 0; y < MONSTERS; y++)
820 if (monsters[x][y])
821 delete monsters[x][y];
822 }
823
824 void delete_masters()
825 {
826 for (int x = 0; x < LEVELS; x++)
827 if (masters[x])
828 delete masters[x];
829 }
830
831 void display_monster(char *u)
832 {
833 if (is_playing(u))
834 {
835 aClient *user = find(u);
836 Player *ni = user->stats;
837
838 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->hp);
839 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name, ni->fight->hp);
840 notice(s_GameServ, u, "Here are your commands:");
841 notice(s_GameServ, u, "/msg %S attack");
842 notice(s_GameServ, u, "/msg %S run");
843 notice(s_GameServ, u, "What will you do?");
844 }
845 }
846
847 void display_players(char *u)
848 {
849 if (is_playing(u))
850 {
851 aClient *ni = find(u);
852
853 aClient *battle = ni->stats->battle;
854
855 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->stats->hp);
856 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name,
857 battle->stats->hp);
858 notice(s_GameServ, u, "Here are your commands:");
859 notice(s_GameServ, u, "/msg %S attack");
860 notice(s_GameServ, u, "/msg %S run");
861 notice(s_GameServ, u, "What will you do?");
862 }
863 }
864 void display_players(aClient *user)
865 {
866 char *u = user->getNick();
867 if (is_playing(user) && player_fight(user))
868 {
869 aClient *battle = user->stats->battle;
870 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", user->stats->hp);
871 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name, battle->stats->hp);
872 notice(s_GameServ, u, "Here are your commands:");
873 notice(s_GameServ, u, "/msg %S attack");
874 notice(s_GameServ, u, "/msg %S run");
875 notice(s_GameServ, u, "What will you do?");
876 }
877 }
878
879
880 bool is_playing(char *u)
881 {
882 aClient *user;
883 if (!(user = find(u)))
884 {
885 return false;
886 }
887 else
888 {
889 return user->stats != NULL;
890 }
891 }
892
893 bool is_playing(aClient *user)
894 {
895 return user->stats != NULL && (stricmp(user->getNick(), "!NULL!") != 0);
896 }
897
898 bool is_fighting(char *u)
899 {
900 aClient *user;
901
902 if (!(user = find(u)))
903 {
904 return false;
905 }
906 else if (user->stats)
907 {
908 return user->stats->fight != NULL || user->stats->battle != NULL
909 || user->stats->master != NULL;
910 }
911 else
912 return false;
913 }
914 bool is_fighting(aClient *user)
915 {
916 if (!is_playing(user))
917 return false;
918 else
919 return (user->stats->fight != NULL || user->stats->battle != NULL || user->stats->master != NULL);
920 }
921
922 bool player_fight(char *u)
923 {
924 aClient *user;
925
926 if (!(user = find(u)))
927 return false;
928 else if (user->stats)
929 return user->stats->battle != NULL;
930 else
931 return false;
932 }
933 bool player_fight(aClient *user)
934 {
935 if (!is_fighting(user))
936 return false;
937 else
938 return user->stats->battle != NULL;
939 }
940
941 bool master_fight(char *u)
942 {
943 aClient *user;
944
945 if (!(user = find(u)))
946 return false;
947 else if (user->stats)
948 return user->stats->master != NULL;
949 else
950 return false;
951 }
952 bool master_fight(aClient *user)
953 {
954 if (!is_playing(user))
955 return false;
956 else
957 return user->stats->master != NULL;
958 }
959
960 void do_fight(char *u)
961 {
962 aClient *ni, *battle;
963
964 char *nick = strtok(NULL, " ");
965
966 if (!nick)
967 {
968 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
969 }
970 else if (!(ni = find(u)))
971 {
972 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
973 return;
974 }
975 else if (!(battle = findbyrealnick(nick)))
976 {
977 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
978 return;
979 }
980 else if (!is_playing(ni))
981 {
982 notice(s_GameServ, u, "You are not playing!");
983 return;
984 }
985 /*
986 * Offline fighting not implemented yet.
987 * else if (!(fight = finduser(nick)))
988 * {
989 * ni->stats->battle = battle;
990 * battle->battle = ni;
991 * ni->yourturn = 1;
992 * battle->yourturn = 0;
993 * notice(s_GameServ, u, "You decide to fight %s while they're not online!",
994 * battle->stats->name);
995 * display_players(u);
996 * }
997 */
998 else if (!isAlive(ni->stats))
999 {
1000 notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!");
1001 return;
1002 }
1003 else if (player_fight(battle))
1004 {
1005 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name);
1006 return;
1007 }
1008 else if (is_fighting(battle))
1009 {
1010 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name);
1011 return;
1012 }
1013 else if (is_playing(ni) && is_playing(battle) && stricmp(ni->stats->name, battle->stats->name) != 0)
1014 {
1015 // Set your battle pointer to the other player
1016 ni->stats->battle = battle;
1017
1018 // Set the other player's battle pointer to you
1019 battle->stats->battle = ni;
1020
1021 // The initiator gets the first move (perhaps this should be 50/50)
1022 setYourTurn(ni->stats);
1023 clearYourTurn(battle->stats);
1024
1025 // Initiate Battle sequence!
1026 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name);
1027 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name);
1028 notice(s_GameServ, battle->getNick(), "%s gets to go first because he initiated!", ni->stats->name);
1029 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name);
1030 display_players(u);
1031 }
1032 }
1033 void do_use(char *u)
1034 {
1035 aClient *user;
1036 Pouch *p;
1037
1038 char *item = strtok(NULL, " ");
1039
1040 if (!item)
1041 {
1042 notice(s_GameServ, u, "SYNTAX: USE ITEM");
1043 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1044 return;
1045 }
1046 else if (!(user = find(u)))
1047 {
1048 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1049 return;
1050 }
1051 else if (!is_playing(user))
1052 {
1053 notice(s_GameServ, u, "You must be playing to use items!");
1054 return;
1055 }
1056
1057 p = &user->stats->inventory;
1058
1059 if (stricmp(item, "HEALTH") == 0)
1060 {
1061 if (p->Healing() <= 0)
1062 {
1063 notice(s_GameServ, u, "You are out of Health Potions!");
1064 return;
1065 }
1066 int oldhealth = user->stats->hp;
1067 notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
1068 notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
1069 user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
1070 notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealth);
1071 p->decHealing();
1072 }
1073 else if (stricmp(item, "STRENGTH") == 0)
1074 {
1075 if (p->Strength() <= 0)
1076 {
1077 notice(s_GameServ, u, "You are out of Strength Potions!");
1078 return;
1079 }
1080 int oldstrength = user->stats->strength;
1081 notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!");
1082 notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!");
1083 user->stats->strength += 1 + rand() % 2; // 1 - 2 Strength Added
1084 notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength);
1085 p->decStrength();
1086 }
1087 else if (stricmp(item, "DEFENSE") == 0)
1088 {
1089 if (p->Defense() <= 0)
1090 {
1091 notice(s_GameServ, u, "You are out of Defense Potions!");
1092 return;
1093 }
1094 int olddefense = user->stats->defense;
1095 notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust.");
1096 notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!");
1097 user->stats->defense += 1 + rand() % 2; // 1 - 2 Defense Added
1098 notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense);
1099 p->decDefense();
1100 }
1101 else if (stricmp(item, "HP") == 0)
1102 {
1103 if (p->HP() <= 0)
1104 {
1105 notice(s_GameServ, u, "You are out of HP Potions!");
1106 return;
1107 }
1108 int oldHP = user->stats->maxhp;
1109 notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid.");
1110 user->stats->maxhp += 1 + rand() % 5; // 1 - 5 Maxhp
1111 notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP);
1112 p->decHP();
1113 }
1114 else
1115 {
1116 notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALTH | STRENGTH | DEFENSE}");
1117 return;
1118 }
1119
1120 end_turn(user); // If they're fighting, end their turn
1121 }
1122 void do_run(char *u)
1123 {
1124 aClient *user;
1125 Player *p, *p2 = NULL;
1126
1127 if (!(user = find(u)))
1128 {
1129 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1130 return;
1131 }
1132
1133 p = user->stats;
1134
1135 if (p->battle)
1136 p2 = p->battle->stats;
1137
1138 if (!is_fighting(user))
1139 notice(s_GameServ, u, "You run in place... try fighting next time.");
1140 else if (!player_fight(user) && !master_fight(user))
1141 {
1142 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name);
1143 delete p->fight;
1144 p->fight = NULL;
1145 }
1146 else if (player_fight(user) && isYourTurn(p))
1147 {
1148 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name);
1149 notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->name);
1150 p2->battle = NULL;
1151 }
1152 else if (player_fight(user) && !isYourTurn(p))
1153 {
1154 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->name);
1155 }
1156 else if (master_fight(user))
1157 {
1158 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name);
1159 }
1160 p->battle = NULL;
1161 }
1162
1163 void end_turn(aClient *user)
1164 {
1165 char *nick, *u = user->getNick();
1166 Monster *fight;
1167 aClient *battle;
1168 int mhit;
1169
1170 nick = new char[strlen(user->getNick()) + 1];
1171
1172 if (!user || !is_playing(user) || !is_fighting(user))
1173 goto endturn;
1174
1175 if (!player_fight(user) && !master_fight(user))
1176 fight = user->stats->fight;
1177 else
1178 fight = user->stats->master;
1179 battle = user->stats->battle;
1180
1181 if (!player_fight(user))
1182 {
1183 // Opponent's Hit
1184 mhit = (fight->strength / 2) +
1185 (rand() % (fight->strength / 2) - (user->stats->defense +
1186 arbonus[user->stats->armor]));
1187 }
1188 else
1189 {
1190 // Opponent's Hit
1191 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1192 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1193 (user->stats->defense + arbonus[user->stats->armor]));
1194 }
1195 if (!player_fight(user))
1196 {
1197
1198 if (mhit > 0)
1199 {
1200 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1201 fight->name, fight->weapon, mhit);
1202 }
1203 else if (mhit <= 0)
1204 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1205
1206 if (mhit >= user->stats->hp)
1207 {
1208 if (!master_fight(user))
1209 {
1210 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1211 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1212 "of your experience!");
1213 user->stats->gold = 0;
1214 user->stats->exp -= (long int)(user->stats->exp * .10);
1215 user->stats->fight = NULL;
1216 clearAlive(user->stats);
1217 goto endturn;
1218 }
1219 else
1220 {
1221 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1222 "until tomorrow to try again", user->stats->master->name);
1223 user->stats->fight = NULL;
1224 user->stats->master = NULL;
1225 goto endturn;
1226 }
1227 }
1228 else
1229 {
1230 if (mhit > 0)
1231 user->stats->hp -= mhit;
1232 display_monster(u);
1233 goto endturn;
1234 }
1235 }
1236 else
1237 {
1238 clearYourTurn(user->stats);
1239 setYourTurn(battle->stats);
1240 display_players(battle);
1241 }
1242 endturn:
1243 delete nick;
1244 }
1245
1246 void do_attack(char *u)
1247 {
1248 int hit, mhit;
1249 aClient *ni, *battle; // The player and perhaps the player they're fighting
1250 Monster *fight; // The monster they may be fighting
1251
1252 if (!(ni = find(u)))
1253 {
1254 notice(s_GameServ, u, "Fatal error in do_attack. Contact a(n) %S admin for help.");
1255 return;
1256 }
1257 else if (!is_playing(ni))
1258 {
1259 notice(s_GameServ, u, "You're not playing!");
1260 return;
1261 }
1262 else if (!is_fighting(ni))
1263 {
1264 notice(s_GameServ, u, "You're not in battle!");
1265 return;
1266 }
1267 else
1268 {
1269 if (!ni->stats->master) // This is not a master fight
1270 fight = ni->stats->fight; // Monster Could be NULL
1271 else // This IS a master fight
1272 fight = ni->stats->master; // Master Could be NULL
1273
1274 battle = ni->stats->battle; // Player Could be NULL
1275
1276 // One has to be !NULL based on the previous else if
1277 // We wouldn't be here if they were all NULL
1278 }
1279
1280 if (!player_fight(ni))
1281 {
1282 // Player's Hit
1283 hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1284 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
1285
1286 // Opponent's Hit
1287 mhit = (fight->strength / 2) +
1288 (rand() % (fight->strength / 2) - (ni->stats->defense +
1289 arbonus[ni->stats->armor]));
1290 }
1291 else
1292 {
1293 // Opponent's Hit
1294 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1295 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1296 (ni->stats->defense + arbonus[ni->stats->armor]));
1297
1298 // Player's Hit
1299 hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1300 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
1301 (battle->stats->defense + arbonus[battle->stats->armor]));
1302 }
1303
1304 if (!player_fight(ni))
1305 {
1306 if (hit > 0)
1307 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
1308 else
1309 notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
1310
1311 if (hit >= fight->hp)
1312 {
1313 if (master_fight(ni))
1314 notice(s_GameServ, u, "You have bested %s!", fight->name);
1315 else
1316 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
1317
1318 notice(s_GameServ, u, "%s", fight->death);
1319 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
1320 fight->exp, fight->gold);
1321
1322 // If your new experience (or gold) will be greater than 2 billion,
1323 // then set your exp to 2bil. (2 billion max)... otherwise add them.
1324 // This could be a problem with overflowing out of the sign bit.
1325 // Unsigned long int maybe? Leave it for now.
1326 ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 :
1327 ni->stats->exp + fight->exp);
1328
1329 ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 :
1330 ni->stats->gold + fight->gold);
1331
1332
1333 if (master_fight(ni))
1334 {
1335 notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
1336 notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
1337 strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
1338
1339 // Increase your level
1340 ni->stats->level++;
1341
1342 // Increase your maximum hit points
1343 ni->stats->maxhp += hpbonus[ni->stats->level - 1];
1344
1345 // Heal the player by setting hp to their max
1346 ni->stats->hp = ni->stats->maxhp;
1347
1348 // Add to your strength
1349 ni->stats->strength += strbonus[ni->stats->level - 1];
1350
1351 // Add to your defensive power
1352 ni->stats->defense += defbonus[ni->stats->level - 1];
1353
1354 // Clear the pointer for your master
1355 ni->stats->master = NULL;
1356 }
1357
1358 // They're dead so remove the pointer
1359 delete ni->stats->fight;
1360 ni->stats->fight = NULL;
1361 ni->stats->master = NULL;
1362
1363 return;
1364 }
1365 else
1366 {
1367 if (hit > 0)
1368 fight->hp -= hit;
1369 if (mhit > 0)
1370 {
1371 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1372 fight->name, fight->weapon, mhit);
1373 }
1374 else if (mhit <= 0)
1375 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1376
1377 if (mhit >= ni->stats->hp)
1378 {
1379 if (!master_fight(ni))
1380 {
1381 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1382 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1383 "of your experience!");
1384 ni->stats->gold = 0;
1385 ni->stats->exp -= (long int)(ni->stats->exp * .10);
1386 ni->stats->fight = NULL;
1387 clearAlive(ni->stats);
1388 return;
1389 }
1390 else
1391 {
1392 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1393 "until tomorrow to try again", ni->stats->master->name);
1394 ni->stats->fight = NULL;
1395 ni->stats->master = NULL;
1396 return;
1397 }
1398 }
1399 else
1400 {
1401 if (mhit > 0)
1402 ni->stats->hp -= mhit;
1403 display_monster(u);
1404 return;
1405 }
1406 }
1407 }
1408 else if (player_fight(ni))
1409 {
1410 /* Offline fighting not available yet
1411 if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
1412 {
1413 if (hit > 0)
1414 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
1415 else
1416 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
1417 if (hit >= battle->stats->hp)
1418 {
1419 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
1420 * notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1421 (long int)(battle->stats->exp * .10), battle->stats->gold);
1422 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1423 {
1424 ni->stats->exp += (long int)(battle->stats->exp * .10);
1425 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1426 }
1427 * else
1428 {
1429 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1430 ni->stats->exp = 2000000000;
1431 }
1432
1433 if (2000000000 - ni->stats->gold > battle->stats->gold)
1434 {
1435 * ni->stats->gold += battle->stats->gold;
1436 battle->stats->gold = 0;
1437 }
1438 else
1439 {
1440 battle->stats->gold = 2000000000 - ni->stats->gold;
1441 ni->stats->gold = 2000000000;
1442 }
1443 * ni->stats->battle->stats->alive = 0;
1444 ni->stats->battle->battle = NULL;
1445 ni->stats->battle = NULL;
1446 return;
1447 }
1448 else
1449 {
1450 if (hit > 0)
1451 * battle->stats->hp -= hit;
1452 if (mhit > 0)
1453 {
1454 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1455 battle->nick, weapons[battle->stats->weapon], mhit);
1456 }
1457 else if (mhit <= 0)
1458 notice(s_GameServ, u, "%s completely misses you!", battle->nick);
1459 *
1460 if (mhit >= ni->stats->hp)
1461 {
1462 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
1463 if (2000000000 - battle->stats->gold > ni->stats->gold)
1464 {
1465 notice(s_GameServ, u, "%s took all your gold!", battle->nick);
1466 battle->stats->gold += ni->stats->gold;
1467 * ni->stats->gold = 0;
1468 }
1469 else
1470 {
1471 notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
1472 battle->nick);
1473 ni->stats->gold -= (2000000000 - battle->stats->gold);
1474 notice(s_GameServ, u, "You were left dead with %d gold.",
1475 * (long int)ni->stats->gold);
1476 battle->stats->gold = 2000000000;
1477 }
1478 ni->stats->battle->battle = NULL;
1479 ni->stats->battle = NULL;
1480 ni->stats->alive = 0;
1481 return;
1482 }
1483 * else
1484 {
1485 if (mhit > 0)
1486 ni->stats->hp -= mhit;
1487 display_players(u);
1488 return;
1489 }
1490 }
1491 }
1492 * end offline fighting */
1493
1494 if (is_playing(battle))
1495 {
1496 if (!isYourTurn(ni->stats))
1497 {
1498 notice(s_GameServ, u, "Please wait until %s decides what to do!",
1499 battle->stats->name);
1500 return;
1501 }
1502 if (hit > 0)
1503 {
1504 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->stats->name, hit);
1505
1506 notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
1507 "\ 2%d\ 2 damage!", ni->stats->name,
1508 weapons[ni->stats->weapon], hit);
1509 clearYourTurn(ni->stats);
1510 setYourTurn(battle->stats);
1511 display_players(battle->getNick());
1512 }
1513 else
1514 {
1515 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->stats->name);
1516 notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name);
1517 clearYourTurn(ni->stats);
1518 setYourTurn(battle->stats);
1519 display_players(battle->getNick());
1520 }
1521 if (hit >= battle->stats->hp)
1522 {
1523 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name);
1524 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1525 (long int)(battle->stats->exp * .10), battle->stats->gold);
1526 notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!",
1527 ni->stats->name);
1528 battle->stats->hp = 0;
1529 clearAlive(battle->stats);
1530
1531 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1532 {
1533 ni->stats->exp += (long int)(battle->stats->exp * .10);
1534 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1535 }
1536 else
1537 {
1538 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1539 ni->stats->exp = 2000000000;
1540 }
1541
1542 if (2000000000 - ni->stats->gold > battle->stats->gold)
1543 {
1544 notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
1545 "all gold on hand!");
1546 ni->stats->gold += battle->stats->gold;
1547 battle->stats->gold = 0;
1548 }
1549 else
1550 {
1551 battle->stats->gold = 2000000000 - ni->stats->gold;
1552 notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
1553
1554 notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
1555 "gold.", ni->stats->name);
1556
1557 notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
1558 "left. All is not lost!", battle->stats->gold);
1559
1560 ni->stats->gold = 2000000000;
1561 }
1562 battle->stats->battle = NULL;
1563 ni->stats->battle = NULL;
1564 return;
1565 }
1566 else
1567 {
1568 if (hit > 0)
1569 battle->stats->hp -= hit;
1570 clearYourTurn(ni->stats);
1571 setYourTurn(battle->stats);
1572 notice(s_GameServ, u, "Please wait while %s decides what to do!",
1573 battle->stats->name);
1574
1575 return;
1576 }
1577 }
1578 }
1579 }
1580
1581 void do_heal(char *u)
1582 {
1583 aClient *ni;
1584 char *amount = strtok(NULL, " ");
1585 int price, num;
1586
1587 if (!amount)
1588 {
1589 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1590 }
1591 else if (!(ni = find(u)))
1592 {
1593 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1594 return;
1595 }
1596 else if (!is_playing(ni))
1597 {
1598 notice(s_GameServ, u, "You aren't playing!");
1599 return;
1600 }
1601 else if (!isAlive(ni->stats))
1602 {
1603 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
1604 return;
1605 }
1606 else if (is_fighting(ni))
1607 {
1608 notice(s_GameServ, u, "You can't heal in battle!");
1609 }
1610 else if (ni->stats->hp >= ni->stats->maxhp)
1611 {
1612 notice(s_GameServ, u, "You don't need healing!");
1613 }
1614 else if (stricmp(amount, "ALL") == 0)
1615 {
1616 price = ni->stats->level * 3;
1617 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
1618 {
1619 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1620 (long int)ni->stats->gold/price, price);
1621 ni->stats->hp += ni->stats->gold / price;
1622 ni->stats->gold %= price;
1623 }
1624 else
1625 {
1626 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1627 "per point.", price);
1628 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
1629 (ni->stats->maxhp - ni->stats->hp),
1630 (price * (ni->stats->maxhp - ni->stats->hp)) );
1631 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1632 ni->stats->hp = ni->stats->maxhp;
1633 }
1634 }
1635 else if (isstringnum(amount))
1636 {
1637 num = stringtoint(amount);
1638 price = ni->stats->level * 3;
1639 if (ni->stats->gold < price * num)
1640 {
1641 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
1642 (long int)ni->stats->gold/price);
1643 }
1644 else if (num <= ni->stats->maxhp - ni->stats->hp)
1645 {
1646 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
1647 num, price);
1648 ni->stats->hp += num;
1649 ni->stats->gold -= num * price;
1650 }
1651 else if (num > ni->stats->maxhp - ni->stats->hp)
1652 {
1653 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1654 "per point.", price);
1655 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
1656 (ni->stats->maxhp - ni->stats->hp));
1657 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1658 ni->stats->hp = ni->stats->maxhp;
1659 }
1660 }
1661 else if (amount[0] == '-')
1662 notice(s_GameServ, u, "You trying to cheat?");
1663 else
1664 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1665 }
1666
1667 int isstringnum(char *num)
1668 {
1669 unsigned int x;
1670 for (x = 0; x < strlen(num); x++)
1671 {
1672 if ((int)num[x] < 48 || (int)num[x] > 57)
1673 return 0;
1674 }
1675 return 1;
1676 }
1677
1678 long int stringtoint(char *number)
1679 {
1680 long int x, len = strlen(number), sum = 0;
1681 if (len == 1)
1682 return chartoint(number[0]);
1683 sum += chartoint(number[len - 1]);
1684 for (x = len - 2; x >= 0; x--)
1685 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
1686 return sum;
1687 }
1688
1689 long int pow(int x, int y)
1690 {
1691 long int value = 0;
1692 int count = 0;
1693 value += x;
1694
1695 if (x != 0 && y != 0)
1696 {
1697 for (count = 1; count <= y - 1; count++)
1698 value *= x;
1699 }
1700 else
1701 return 1;
1702 return value;
1703 }
1704
1705 long int chartoint(char ch)
1706 {
1707 if (int(ch) >= 48 && int(ch) <= 57)
1708 return int(ch) - 48;
1709 else
1710 return 0;
1711 }
1712
1713 int save_gs_dbase()
1714 {
1715 ListNode<aClient> *ptr = players.First();
1716 Player *it;
1717 ofstream outfile;
1718
1719 outfile.open(playerdata);
1720
1721 if (!outfile)
1722 {
1723 log("Error opening %s", playerdata);
1724 return 0;
1725 }
1726
1727 while(ptr)
1728 {
1729 it = ptr->getData()->stats;
1730 outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
1731 << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
1732 << it->armor << ' ' << it->weapon << ' '
1733 << it->forest_fights << ' ' << it->player_fights << ' '
1734 << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
1735 << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl;
1736 ptr = ptr->Next();
1737 }
1738 outfile.close();
1739 return 1;
1740 }
1741
1742 int load_gs_dbase()
1743 {
1744 ifstream infile;
1745 aClient *temp;
1746 Player *p;
1747 char *tempname, *buf, *password;
1748 buf = new char[1023];
1749
1750 infile.open(playerdata);
1751
1752 if (infile.fail())
1753 {
1754 log("Error opening %s", playerdata);
1755 return 0;
1756 }
1757
1758 while (infile.getline(buf, 1024, '\n'))
1759 {
1760 temp = new aClient;
1761 tempname = strtok(buf, " ");
1762 temp->stats = new Player(tempname);
1763 p = temp->stats;
1764
1765 p->level = stringtoint(strtok(NULL, " "));
1766 p->exp = stringtoint(strtok(NULL, " "));
1767 p->gold = stringtoint(strtok(NULL, " "));
1768 p->bank = stringtoint(strtok(NULL, " "));
1769 p->hp = stringtoint(strtok(NULL, " "));
1770 p->maxhp = stringtoint(strtok(NULL, " "));
1771 p->strength = stringtoint(strtok(NULL, " "));
1772 p->defense = stringtoint(strtok(NULL, " "));
1773 p->armor = stringtoint(strtok(NULL, " "));
1774 p->weapon = stringtoint(strtok(NULL, " "));
1775 p->forest_fights = stringtoint(strtok(NULL, " "));
1776 p->player_fights = stringtoint(strtok(NULL, " "));
1777 p->setFlags(stringtoint(strtok(NULL, " ")));
1778
1779 password = strtok(NULL, " ");
1780 strcpy(p->password, password);
1781 temp->setNick("!NULL!");
1782 #ifdef P10
1783 temp->setRealNick("!NULL!");
1784 #endif
1785
1786 p->inventory.reset(); // Set inventory to all 0s
1787 // Old player databases didn't have these three extra values
1788 // If they come up null, leave them to 0 as the default.
1789 // On the next gameserv database save, it will save the values.
1790 tempname = strtok(NULL, " ");
1791 if (tempname)
1792 p->inventory.setHealing(stringtoint(tempname));
1793
1794 tempname = strtok(NULL, " ");
1795 if (tempname)
1796 p->inventory.setStrength(stringtoint(tempname));
1797
1798 tempname = strtok(NULL, " ");
1799 if (tempname)
1800 p->inventory.setDefense(stringtoint(tempname));
1801
1802 tempname = strtok(NULL, " ");
1803 if (tempname)
1804 p->inventory.setHP(stringtoint(tempname));
1805
1806 players.insertAtBack(temp);
1807 delete temp;
1808 }
1809 delete [] buf;
1810 infile.close();
1811 return 1;
1812 }
1813
1814 bool passcmp(char *encrypted, char *plaintext)
1815 {
1816 char salt[3];
1817 char *plaintext2, *plainToencrypt;
1818 bool same = false;
1819
1820 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
1821 strcpy(plaintext2, plaintext);
1822
1823 salt[0] = encrypted[0];
1824 salt[1] = encrypted[1];
1825 salt[3] = '\0';
1826
1827 plainToencrypt = crypt(plaintext2, salt);
1828
1829 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
1830
1831 delete []plaintext2;
1832
1833 return same;
1834 }
1835
1836 bool check_password(char *name, char *plaintext)
1837 {
1838 aClient *client;
1839
1840 if (!(client = findplayer(name)))
1841 return false;
1842 else
1843 {
1844 return passcmp(client->stats->password, plaintext);
1845 }
1846 }
1847
1848 void do_store(char *u)
1849 {
1850 char *cmd = strtok(NULL, " ");
1851 char *item = strtok(NULL, " ");
1852 char *num = strtok(NULL, " ");
1853 char *space;
1854 int wep;
1855 aClient *user;
1856 Player *p;
1857
1858 if (!cmd || !item)
1859 {
1860 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
1861 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
1862 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
1863 }
1864 else if (!(user = find(u)) || !is_playing(user))
1865 notice(s_GameServ, u, "You must be playing to use the store!");
1866 else if (!isAlive(user->stats))
1867 {
1868 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
1869 return;
1870 }
1871 else if (stricmp(cmd, "LIST") == 0)
1872 {
1873 if (stricmp(item, "WEAPONS") == 0)
1874 {
1875 notice(s_GameServ, u, "Welcome to Kain's Armory");
1876 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
1877 for (int x = 1; x < WNA; x++)
1878 {
1879 space = spaces(strlen(weapons[x]), ".");
1880 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
1881 free(space);
1882 }
1883 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
1884 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
1885
1886 }
1887 else if (stricmp(item, "ARMOR") == 0)
1888 {
1889 notice(s_GameServ, u, "Welcome to Kain's Armory");
1890 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
1891 for (int x = 1; x < WNA; x++)
1892 {
1893 space = spaces(strlen(armors[x]), ".");
1894 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
1895 free(space);
1896 }
1897 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
1898 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
1899
1900
1901 }
1902 } else if (stricmp(cmd, "BUY") == 0) {
1903 if (!num)
1904 {
1905 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
1906 return;
1907 }
1908 else if (!isstringnum(num))
1909 {
1910 notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
1911 return;
1912 }
1913 if (stricmp(item, "WEAPON") == 0)
1914 {
1915 wep = stringtoint(num);
1916 if (wep >= WNA || wep < 1)
1917 {
1918 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
1919 return;
1920 }
1921
1922 p = user->stats;
1923
1924 if (p->weapon != 0)
1925 notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
1926 else if (p->gold < prices[wep - 1])
1927 notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
1928 else
1929 {
1930 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
1931 p->weapon = wep;
1932 p->gold -= prices[wep - 1];
1933 }
1934 }
1935 else if (stricmp(item, "ARMOR") == 0)
1936 {
1937 wep = stringtoint(num);
1938 if (wep >= WNA || wep < 1)
1939 {
1940 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
1941 return;
1942 }
1943
1944 p = user->stats;
1945
1946 if (p->armor != 0)
1947 notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
1948 else if (p->gold < prices[wep - 1])
1949 notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
1950 else
1951 {
1952 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
1953 p->armor = wep;
1954 p->gold -= prices[wep - 1];
1955 }
1956 }
1957 }
1958 else if (stricmp(cmd, "SELL" ) == 0)
1959 {
1960 p = user->stats;
1961
1962 if (stricmp(item, "WEAPON") == 0)
1963 {
1964 if (p->weapon == 0)
1965 {
1966 notice(s_GameServ, u, "You want me to chop off your hands?");
1967 return;
1968 }
1969 else if (p->gold == 2000000000)
1970 {
1971 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
1972 p->weapon = 0;
1973 }
1974 else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
1975 {
1976 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
1977 notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
1978 p->gold = 2000000000;
1979 p->weapon = 0;
1980 }
1981 else
1982 {
1983 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
1984 p->gold += (prices[p->weapon - 1] / 2);
1985 p->weapon = 0;
1986 }
1987 }
1988 else if (stricmp(item, "ARMOR") == 0)
1989 {
1990 p = user->stats;
1991
1992 if (p->armor == 0)
1993 {
1994 notice(s_GameServ, u, "I don't think you can be any more naked...");
1995 return;
1996 }
1997 if (p->gold == 2000000000)
1998 {
1999 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2000 p->armor = 0;
2001 }
2002 else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
2003 {
2004 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2005 notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
2006 p->gold = 2000000000;
2007 p->armor = 0;
2008 }
2009 else
2010 {
2011 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
2012 (prices[p->armor - 1] / 2));
2013
2014 p->gold += (prices[p->armor - 1] / 2);
2015 p->armor = 0;
2016 }
2017 }
2018 else
2019 {
2020 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2021 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2022 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2023 }
2024 }
2025 }
2026 void do_inventory(char *u)
2027 {
2028 aClient *user;
2029
2030 if (!(user = find(u)))
2031 {
2032 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2033 return;
2034 }
2035 else if (!is_playing(user))
2036 {
2037 notice(s_GameServ, u, "You must be playing to check your inventory!");
2038 return;
2039 }
2040 showinventory(user, user);
2041 }
2042 void showinventory(aClient *from, aClient *to)
2043 {
2044 char *nick = to->getNick();
2045
2046 if (!to)
2047 to = from;
2048 if (is_playing(from))
2049 {
2050 Pouch *p = &from->stats->inventory;
2051 notice(s_GameServ, nick, "Inventory for %s:", from->stats->name);
2052 notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
2053 notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
2054 notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
2055 notice(s_GameServ, nick, " HP Potions: %d", p->HP());
2056 }
2057 }
2058 void do_tavern(char *u)
2059 {
2060 char *cmd = strtok(NULL, " ");
2061 long int price;
2062
2063 aClient *user;
2064 Player *p;
2065 if (!(user = find(u)))
2066 {
2067 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2068 return;
2069 }
2070 else if (!is_playing(user))
2071 {
2072 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2073 return;
2074 }
2075 else if (is_fighting(user))
2076 {
2077 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2078 return;
2079 }
2080 p = user->stats;
2081 if (!cmd)
2082 {
2083 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
2084 notice(s_GameServ, u, "Your commands:");
2085 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2086 notice(s_GameServ, u, "What'll it be?");
2087 }
2088 else if (stricmp(cmd, "LIST") == 0)
2089 {
2090 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2091 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10));
2092 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10));
2093 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10));
2094 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10));
2095 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2096 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2097 notice(s_GameServ, u, "By something will ya!");
2098 }
2099 else if (stricmp(cmd, "BUY") == 0)
2100 {
2101 char *chnum = strtok(NULL, " ");
2102 int num = stringtoint(chnum);
2103
2104 if (!chnum)
2105 {
2106 notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
2107 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
2108 return;
2109 }
2110 if (num < 1 || num > 4)
2111 {
2112 notice(s_GameServ, u, "Invalid Choice!");
2113 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2114 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10));
2115 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10));
2116 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10));
2117 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10));
2118 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2119 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2120 return;
2121 }
2122 switch(num)
2123 {
2124 case 1:
2125 price = (1000 * p->level) + (p->exp / 10);
2126 if (p->gold >= price)
2127 {
2128 notice(s_GameServ, u, "One healing potion coming right up!");
2129 p->inventory.incHealing();
2130 p->gold -= price;
2131 }
2132 else
2133 notice(s_GameServ, u, "You don't have enough gold!");
2134 break;
2135 case 2:
2136 price = (2050 * p->level) + (p->exp / 10);
2137 if (p->gold >= price)
2138 {
2139 notice(s_GameServ, u, "One strength boost coming right up!");
2140 p->inventory.incStrength();
2141 p->gold -= price;
2142 }
2143 else
2144 notice(s_GameServ, u, "You don't have enough gold!");
2145 break;
2146 case 3:
2147 price = (2000 * p->level) + (p->exp / 10);
2148 if (p->gold >= price)
2149 {
2150 notice(s_GameServ, u, "One defense boost coming right up!");
2151 p->inventory.incDefense();
2152 p->gold -= price;
2153 }
2154 else
2155 notice(s_GameServ, u, "You don't have enough gold!");
2156 break;
2157 case 4:
2158 price = (2300 * p->level) + (p->exp / 10);
2159 if (p->gold >= price)
2160 {
2161 notice(s_GameServ, u, "One HP Potion coming right up!");
2162 p->inventory.incHP();
2163 p->gold -= price;
2164 }
2165 else
2166 notice(s_GameServ, u, "You don't have enough gold!");
2167 break;
2168 default:
2169 notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
2170 break;
2171 }
2172 }
2173 else
2174 {
2175 notice(s_GameServ, u, "Improper Syntax.");
2176 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2177 }
2178 }
2179
2180 void do_bank(char *u)
2181 {
2182 char *cmd = strtok(NULL, " ");
2183 char *amount = strtok(NULL, " ");
2184 char *nick = strtok(NULL, " ");
2185
2186 aClient *user;
2187 Player *p;
2188
2189 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
2190 {
2191 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
2192 notice (s_GameServ, u, "BANK BALANCE");
2193 return;
2194 }
2195
2196 user = find(u);
2197 if (!is_playing(user))
2198 {
2199 notice(s_GameServ, u, "You must be playing to use the bank!");
2200 return;
2201 }
2202 else if (stricmp(cmd, "BALANCE") == 0)
2203 {
2204 showBankBalance(u);
2205 return;
2206 }
2207 else if (!isAlive(user->stats))
2208 {
2209 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2210 return;
2211 }
2212 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2213 {
2214 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2215 return;
2216 }
2217
2218 p = user->stats;
2219
2220 if (stricmp(cmd, "DEPOSIT") == 0)
2221 {
2222 if (p->bank == 2000000000)
2223 {
2224 notice(s_GameServ, u, "Your bank account is full, sire!");
2225 return;
2226 }
2227 else if (stricmp(amount, "ALL") == 0)
2228 {
2229 if (2000000000 - p->bank < p->gold)
2230 {
2231 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2232 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
2233 p->gold -= (2000000000 - p->bank);
2234 p->bank = 2000000000;
2235 showBankBalance(u);
2236 }
2237 else
2238 {
2239 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
2240 p->bank += p->gold;
2241 p->gold = 0;
2242 showBankBalance(u);
2243 }
2244 }
2245 else if (stringtoint(amount) > p->gold)
2246 {
2247 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
2248 showBankBalance(u);
2249 return;
2250 }
2251 else
2252 {
2253 if (2000000000 - p->bank < stringtoint(amount))
2254 {
2255 notice(s_GameServ, u, "You don't have room in your account for that much.");
2256 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
2257 p->gold -= (2000000000 - p->bank);
2258 p->bank = 2000000000;
2259 showBankBalance(u);
2260 }
2261 else
2262 {
2263 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2264 p->bank += stringtoint(amount);
2265 p->gold -= stringtoint(amount);
2266 showBankBalance(u);
2267 }
2268 }
2269 }
2270 else if (stricmp(cmd, "WITHDRAW") == 0)
2271 {
2272 if (p->gold == 2000000000)
2273 {
2274 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
2275 showBankBalance(u);
2276 return;
2277 }
2278 else if (stricmp(amount, "ALL") == 0)
2279 {
2280 if (2000000000 - p->gold < p->bank)
2281 {
2282 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2283 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
2284 p->bank -= (2000000000 - p->gold);
2285 p->gold = 2000000000;
2286 showBankBalance(u);
2287 }
2288 else
2289 {
2290 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
2291 p->gold += p->bank;
2292 p->bank = 0;
2293 showBankBalance(u);
2294 }
2295 }
2296 else if (stringtoint(amount) > p->bank)
2297 {
2298 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
2299 showBankBalance(u);
2300 return;
2301 }
2302 else
2303 {
2304 if (2000000000 - p->gold < stringtoint(amount))
2305 {
2306 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2307 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2308 (2000000000 - p->gold));
2309 p->bank -= (2000000000 - p->gold);
2310 p->gold = 2000000000;
2311 showBankBalance(u);
2312 }
2313 else
2314 {
2315 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2316 p->gold += stringtoint(amount);
2317 p->bank -= stringtoint(amount);
2318 showBankBalance(u);
2319 }
2320 }
2321 }
2322
2323 }
2324
2325 void do_master(char *u)
2326 {
2327 aClient *user;
2328 user = find(u);
2329
2330 if (!user)
2331 {
2332 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2333 return;
2334 }
2335 else if (is_fighting(user))
2336 {
2337 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
2338 return;
2339 }
2340 else if (!isAlive(user->stats))
2341 {
2342 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2343 return;
2344 }
2345 else if (!is_playing(user))
2346 {
2347 notice(s_GameServ, u, "You must be playing to see your master!");
2348 return;
2349 }
2350
2351 char *cmd = strtok(NULL, " ");
2352 Player *p = user->stats;
2353 long int need = 0;
2354
2355 if (seenMaster(p))
2356 {
2357 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
2358 return;
2359 }
2360
2361 if (cmd != NULL)
2362 {
2363 switch(p->level)
2364 {
2365 case 1:
2366 need = 100;
2367 break;
2368 case 2:
2369 need = 400;
2370 break;
2371 case 3:
2372 need = 1000;
2373 break;
2374 case 4:
2375 need = 4000;
2376 break;
2377 case 5:
2378 need = 10000;
2379 break;
2380 case 6:
2381 need = 40000;
2382 break;
2383 case 7:
2384 need = 100000;
2385 break;
2386 case 8:
2387 need = 400000;
2388 break;
2389 case 9:
2390 need = 1000000;
2391 break;
2392 case 10:
2393 need = 4000000;
2394 break;
2395 case 11:
2396 need = 10000000;
2397 break;
2398 case 12:
2399 need = p->exp + 1;
2400 notice(s_GameServ, u, "You are at level 12. You are the master. What's left? The DRAGON!");
2401 break;
2402 default:
2403 need = p->exp + 1; // Unknown level... don't let them fight a fake master!
2404 break;
2405 }
2406 }
2407 else
2408 {
2409 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2410 return;
2411 }
2412
2413 if (stricmp(cmd, "FIGHT") == 0)
2414 {
2415 if (p->exp >= need)
2416 {
2417 setMaster(p);
2418 see_master(u);
2419 }
2420 else
2421 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.", masters[p->level - 1]->name, (need - p->exp));
2422 return;
2423 }
2424 else if (stricmp(cmd, "QUESTION") == 0)
2425 {
2426 if (p->exp >= need)
2427 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);
2428 else
2429 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", masters[p->level - 1]->name, p->name);
2430
2431 return;
2432 }
2433 else
2434 {
2435 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2436 }
2437 }
2438
2439 void see_master(char *u)
2440 {
2441 aClient *user;
2442
2443 if (!(user = find(u)))
2444 {
2445 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2446 return;
2447 }
2448
2449 if (!is_fighting(user) && is_playing(user))
2450 {
2451 Player *p = user->stats;
2452 p->master = new Monster(masters[p->level - 1]);
2453 p->fight = p->master;
2454 display_monster(u); // Since master is the same structure, use this function
2455 }
2456 }
2457
2458 void showBankBalance(const char *u)
2459 {
2460 aClient *user;
2461 Player *p;
2462
2463 if (!(user = find(u)))
2464 return;
2465
2466 p = user->stats;
2467
2468 if (!p)
2469 return;
2470
2471 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->bank, p->gold);
2472
2473 }
2474
2475 void refreshall()
2476 {
2477 ListNode <aClient> *it;
2478 Player *p;
2479
2480 it = players.First();
2481
2482 while (it)
2483 {
2484 p = it->getData()->stats;
2485 refresh(p);
2486 it = it->Next();
2487 }
2488 }
2489
2490 void refresh(Player *p)
2491 {
2492 if (!p)
2493 return;
2494
2495 if (p->hp < p->maxhp)
2496 p->hp = p->maxhp;
2497 p->forest_fights = forestfights;
2498 p->player_fights = 3;
2499 setAlive(p);
2500 clearMaster(p);
2501 }
2502
2503 void do_refresh(char *u)
2504 {
2505 char *nick = strtok(NULL, " ");
2506 aClient *user;
2507
2508 if (!(user = find(u)))
2509 {
2510 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
2511 log("Error: aClient not found: %s", u);
2512 return;
2513 }
2514 else if (!isAdmin(user))
2515 {
2516 notice(s_GameServ, u, "You must be a %S admin to use this command!");
2517 return;
2518 }
2519 if (!nick)
2520 {
2521 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
2522 return;
2523 }
2524 else if (stricmp(nick, "ALL") == 0)
2525 {
2526 notice(s_GameServ, u, "Refreshing everyone's stats!");
2527 refreshall();
2528 }
2529 else if ((user = findbyrealnick(nick)))
2530 {
2531 if (is_playing(user))
2532 {
2533 #ifdef P10
2534 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
2535 #else
2536 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
2537 #endif
2538 refresh(user->stats);
2539 }
2540 else
2541 {
2542 #ifdef P10
2543 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
2544 #else
2545 notice(s_GameServ, u, "%s is not playing.", user->getNick());
2546 #endif
2547 }
2548 }
2549 else
2550 {
2551 notice(s_GameServ, u, "Nick %s not found.", nick);
2552 return;
2553 }
2554 }
2555
2556
2557 void resetall()
2558 {
2559 ListNode <aClient> *it;
2560 Player *p;
2561
2562 it = players.First();
2563
2564 while (it)
2565 {
2566 p = it->getData()->stats;
2567 reset(p);
2568 it = it->Next();
2569 }
2570 }
2571
2572 void reset(Player *p)
2573 {
2574 if (!p)
2575 return;
2576
2577 p->reset();
2578 }
2579
2580 void do_reset(char *u)
2581 {
2582 char *nick = strtok(NULL, " ");
2583 aClient *user;
2584
2585 if (!(user = find(u)))
2586 {
2587 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
2588 log("Error: aClient not found: %s", u);
2589 return;
2590 }
2591 else if (!isAdmin(user))
2592 {
2593 notice(s_GameServ, u, "You must be a %S admin to use this command!");
2594 return;
2595 }
2596 if (!nick)
2597 {
2598 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
2599 return;
2600 }
2601 else if (stricmp(nick, "ALL") == 0)
2602 {
2603 notice(s_GameServ, u, "Resetting everyone's stats!");
2604 resetall();
2605 }
2606 else if ((user = findbyrealnick(nick)))
2607 {
2608 if (is_playing(user))
2609 {
2610 #ifdef P10
2611 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
2612 #else
2613 notice(s_GameServ, u, "Resetting %s.", user->getNick());
2614 #endif
2615 reset(user->stats);
2616 }
2617 else
2618 {
2619 #ifdef P10
2620 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
2621 #else
2622 notice(s_GameServ, u, "%s is not playing.", user->getNick());
2623 #endif
2624 }
2625 }
2626 else
2627 {
2628 notice(s_GameServ, u, "Nick %s not found.", nick);
2629 return;
2630 }
2631 }
2632
2633 void do_help(char *u)
2634 {
2635 char *cmd = strtok(NULL, " ");
2636
2637 display_help(u, cmd);
2638 }
2639
2640 void display_help(char *u, char *file)
2641 {
2642 ifstream infile;
2643 char *buf;
2644
2645 if (!file)
2646 {
2647 infile.open("helpfiles/help");
2648 if (infile.fail())
2649 {
2650 log("Error opening helpfiles/help");
2651 notice(s_GameServ, u, "Error opening helpfiles/help");
2652 return;
2653 }
2654 buf = new char[1024];
2655 while(infile.getline(buf, 1024))
2656 {
2657 // Written this way, it will process %S in the helpfiles
2658 // Instead of notice(s_GameServ, u, "%s", buf);
2659 notice(s_GameServ, u, buf);
2660 }
2661
2662 // Minor recursion
2663 aClient *user = find(u);
2664 if (user && isAdmin(user))
2665 display_help(u, "admin_commands");
2666 }
2667 else
2668 {
2669 char *filename;
2670 filename = new char[strlen(file) + 11];
2671 strcpy(filename, "helpfiles/");
2672 strcat(filename, file);
2673
2674 for (unsigned int x = 10; x < strlen(filename); x++)
2675 filename[x] = tolower(filename[x]);
2676
2677 infile.open(filename);
2678 delete [] filename;
2679 if (infile.fail())
2680 {
2681 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
2682 return;
2683 }
2684 buf = new char[1024];
2685 while(infile.getline(buf, 1024))
2686 {
2687 // Written this way, it will process %S in the helpfiles
2688 // Instead of notice(s_GameServ, u, "%s", buf);
2689 notice(s_GameServ, u, buf);
2690 }
2691 }
2692 infile.close();
2693 delete [] buf;
2694 }
2695
2696 void do_admin(char *u)
2697 {
2698 aClient *user;
2699 char *pass = strtok(NULL, " ");
2700
2701 if (!(user = find(u)))
2702 {
2703 log("Error: aClient not found: %s", u);
2704 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
2705 return;
2706 }
2707 if (!pass)
2708 {
2709 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
2710 return;
2711 }
2712
2713 if (isAdmin(user))
2714 {
2715 notice(s_GameServ, u, "You already have administrator privledges.");
2716 return;
2717 }
2718 else if (strcmp(pass, adminpass) == 0)
2719 {
2720 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
2721 setAdmin(user);
2722 #ifdef P10
2723 log("%s became an administrator.", user->getRealNick());
2724 #else
2725 log("%s became an administrator.", user->getNick());
2726 #endif
2727 }
2728 else
2729 {
2730 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
2731 return;
2732 }
2733 }
2734
2735 bool load_monsters()
2736 {
2737 ifstream infile;
2738 infile.open("monsters.dat");
2739
2740 char *buf;
2741
2742 if (infile.fail())
2743 {
2744 log("Error opening monsters.dat");
2745 return false;
2746 }
2747 init_monsters();
2748 buf = new char[2048];
2749
2750 #ifdef DEBUGMODE
2751 log("Loading monsters from monsters.dat");
2752 #endif
2753
2754 for (int l = 0; l < REALLEVELS; l++)
2755 {
2756 for (int m = 0; m < MONSTERS;)
2757 {
2758 infile.getline(buf, 2048);
2759 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
2760 continue;
2761 else
2762 {
2763 strcpy(monsters[l][m]->name, strtok(buf, "~"));
2764 strcpy(monsters[l][m]->weapon, strtok(NULL, "~"));
2765 monsters[l][m]->strength = stringtoint(strtok(NULL, "~"));
2766 monsters[l][m]->gold = stringtoint(strtok(NULL, "~"));
2767 monsters[l][m]->exp = stringtoint(strtok(NULL, "~"));
2768 monsters[l][m]->maxhp = stringtoint(strtok(NULL, "~"));
2769 monsters[l][m]->hp = monsters[l][m]->maxhp;
2770 strcpy(monsters[l][m]->death, strtok(NULL, ""));
2771 m++;
2772 }
2773 }
2774 }
2775 delete [] buf;
2776 return true;
2777 }