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