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