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