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