]> jfr.im git - irc/gameservirc.git/blob - gameserv/gameserv.cpp
Fixed bug # 998029 causing a crash on gentoo systems due to a mistake in code:
[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 "level.h"
7 #include "sockhelp.h"
8
9 #include <cctype>
10 #include <fstream>
11
12 using std::ifstream;
13 using std::ofstream;
14 using std::ios;
15
16 #if defined(HAVE_CRYPT_H)
17
18 #include <crypt.h>
19
20 #elif defined(HAVE_UNISTD_H)
21
22 #include <unistd.h>
23
24 #endif
25
26
27 Monster boss; // The boss monster
28 Level levels[LEVELS]; // The newest way to store monsters
29
30 Monster *masters[LEVELS]; // A master for each level
31
32 // Database functions
33 int save_gs_dbase();
34 int load_gs_dbase();
35
36 // String functions
37 #ifndef HAVE_STRTOK
38 char *strtok(char *str, const char *delim);
39 #endif
40
41 int stricmp(const char *s1, const char *s2);
42 int strnicmp(const char *s1, const char *s2, size_t len);
43 // String Functions
44
45 /********** Password functions **********/
46
47 bool passcmp(char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
48
49 bool check_password(char *name, char *plaintext); // Finds a password for the given name, and checks it with passcmp against the plaintext password given.
50
51 /********** Password functions **********/
52
53
54 /********** GameServ Booleans **********/
55
56 bool shuttingdown;
57 bool timedOut(Player *p);
58 void updateTS(Player *p);
59 void timeOutEvent(Player *p);
60
61 bool is_playing(char *u); // True if the given nickname in the clients list is playing.
62 bool is_playing(aClient *user);
63
64 bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
65 bool is_fighting(aClient *user);
66
67 bool player_fight(char *u); // True if the player is fighting another player.
68 bool player_fight(aClient *user);
69
70 bool master_fight(char *u); // True if the player is fighting their master.
71 bool master_fight(aClient *user);
72
73 /********** GameServ Booleans **********/
74
75 void display_help(char *u, char *file = NULL);
76 void display_monster(char *u);
77 void display_players(char *u);
78 void display_players(aClient *user);
79 long int chartoint(char ch);
80 int isstringnum(char *num);
81 long int pow (int x, int y);
82 long int stringtoint(char *number);
83
84 char *spaces(int len, char *seperator);
85 void refresh(Player *p);
86 void refreshall();
87 void updateTS(Player *p);
88 void reset(Player *p);
89 void init_masters();
90 bool load_monsters();
91 bool load_levels();
92 void delete_monsters();
93 void delete_masters();
94
95 void do_admin(char *u);
96 void do_attack(char *u);
97 void do_bank(char *u);
98 void do_check(char *u);
99 void do_fight(char *u);
100 void do_heal(char *u);
101 void do_help(char *u);
102 void do_identify(char *u);
103 void do_inventory(char *u);
104 void do_refresh(char *u);
105 void do_register(char *u);
106 void do_list(char *u);
107 void do_logout(char *u);
108 void do_master(char *u);
109 void do_dragon(char *u);
110 void do_play(char *u);
111 void do_quitg(char *u);
112 void do_reset(char *u);
113 void do_run(char *u);
114 void do_stats(char *u);
115 void do_store(char *u);
116 void do_tavern(char *u);
117 void do_use(char *u);
118 void see_master(char *u);
119
120 void logout(aClient *user);
121 void showstats(const char *u, const char *nick);
122 void showinventory(aClient *from, aClient *to);
123 void showBankBalance(const char *u);
124 void end_turn(aClient *user);
125
126 #define WNA 16
127 char *weapons[WNA] = { "Fists", "Stick", "Dagger", "Quarterstaff", "Short Sword",
128 "Long Sword", "Silver Spear", "Battle Axe", "The Ragnarok",
129 "Chain Saw", "Poison Sword", "Flame Sword", "Earth Hammer",
130 "Light Saber", "Masamune", "Mystical Sword"};
131
132 char *armors[WNA] = { "Birthday Suit", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor",
133 "Full Body Armor", "Magic Mail", "Graphite Suit", "Steel Suit",
134 "Force Field", "Armor of Light", "Mythril Vest", "DemiGod Armor",
135 "Hades' Cloak", "Dragon Scales", "Adamantium"};
136
137 int prices[WNA - 1] = {200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000,
138 1000000, 4000000, 10000000, 40000000, 100000000, 400000000};
139 int webonus[WNA] = {2, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
140 int arbonus[WNA] = {2, 3, 5, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000};
141
142 int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550};
143 int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200};
144 int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
145
146 void gameserv(char *source, char *buf)
147 {
148 char *cmd, z;
149 cmd = strtok(buf, " ");
150
151 #ifndef P10
152 source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
153 #endif
154
155 z = cmd[0];
156 if (z == ':')
157 cmd++; // Get rid of that : at the beginning of the :text (command)
158
159 #ifdef DEBUGMODE
160 log("Source: %s Command: %s", source, cmd);
161 #endif
162
163 if (strnicmp(cmd, "\1PING", 6) == 0)
164 {
165 char *ts;
166 ts = strtok(NULL, "\1");
167 notice(s_GameServ, source, "\1PING %s\1", ts);
168 } else if (stricmp(cmd, "\1VERSION\1") == 0) {
169 notice(s_GameServ, source, "\1VERSION %s %s\1", PACKAGE, VERSION);
170 } else if (stricmp(cmd, "SEARCH") == 0) {
171 cmd = strtok(NULL, " ");
172
173 if (!cmd)
174 notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
175 else
176 do_forest(source);
177
178 } else if (stricmp(cmd, "FIGHT") == 0) {
179 do_fight(source);
180 } else if (stricmp(cmd, "ATTACK") == 0) {
181 do_attack(source);
182 } else if (stricmp(cmd, "CHECK") == 0) {
183 do_check(source);
184 } else if (stricmp(cmd, "RUN") == 0) {
185 do_run(source);
186 } else if (stricmp(cmd, "USE") == 0) {
187 do_use(source);
188 } else if (stricmp(cmd, "HEAL") == 0) {
189 do_heal(source);
190 } else if (stricmp(cmd, "INVENTORY") == 0) {
191 do_inventory(source);
192 } else if (stricmp(cmd, "MASTER") == 0) {
193 do_master(source);
194 } else if (stricmp(cmd, "DRAGON") == 0) {
195 do_dragon(source);
196 } else if (stricmp(cmd, "STORE") == 0) {
197 do_store(source);
198 } else if (stricmp(cmd, "BANK") == 0) {
199 do_bank(source);
200 } else if (stricmp(cmd, "ADMIN") == 0) {
201 do_admin(source);
202 } else if (stricmp(cmd, "REFRESH") == 0) {
203 do_refresh(source);
204 } else if (stricmp(cmd, "RESET") == 0) {
205 do_reset(source);
206 } else if (stricmp(cmd, "TAVERN") == 0) {
207 do_tavern(source);
208 } else if (stricmp(cmd, "LIST") == 0) {
209 do_list(source);
210 } else if (stricmp(cmd, "LOGOUT") == 0) {
211 do_logout(source);
212 } else if (stricmp(cmd, "NEWS") == 0) {
213 do_news(source);
214 } else if (stricmp(cmd, "REGISTER") == 0) {
215 do_register(source);
216 } else if (stricmp(cmd, "IDENTIFY") == 0) {
217 do_identify(source);
218 } else if (stricmp(cmd, "HELP") == 0) {
219 do_help(source);
220 } else if (stricmp(cmd, "STATS") == 0) {
221 do_stats(source);
222 } else if (stricmp(cmd, "SHUTDOWN") == 0) {
223 aClient *user;
224
225 if (!(user = find(source)))
226 {
227 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
228 log("Error: aClient not found: %s", source);
229 }
230 else if (!isAdmin(user))
231 {
232 notice(s_GameServ, source, "You must be a %S admin to use this command!");
233 }
234 else
235 {
236 save_gs_dbase();
237 #ifdef P10
238 raw("[] SQ %s 0 :leaving: %s used the Shutdown command.", servername, user->getRealNick());
239 #else
240 raw("SQUIT %s :leaving: %s used the Shutdown command.", servername, source);
241 #endif
242 shuttingdown = true;
243 }
244 } else if (stricmp(cmd, "SAVE") == 0) {
245 aClient *user;
246
247 if (!(user = find(source)))
248 {
249 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
250 log("Error: aClient not found: %s", source);
251 }
252 else if (!isAdmin(user))
253 {
254 notice(s_GameServ, source, "You must be a %S admin to use this command!");
255 }
256 else
257 {
258 save_gs_dbase();
259 }
260 } else if (stricmp(cmd, "LOAD") == 0) {
261 aClient *user;
262
263 if (!(user = find(source)))
264 {
265 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
266 log("Error: aClient not found: %s", source);
267 }
268 else if (!isAdmin(user))
269 {
270 notice(s_GameServ, source, "You must be a %S admin to use this command!");
271 }
272 else
273 {
274 char *cmd2 = strtok(NULL, " ");
275 if (!cmd2)
276 {
277 notice(s_GameServ, source, "Loading player data from %s", playerdata);
278 load_gs_dbase();
279 }
280 else if (stricmp(cmd2, "MONSTERS") == 0)
281 {
282 notice(s_GameServ, source, "Loading monster data from %s", monsterdata);
283 load_monsters();
284 }
285 else
286 display_help(source, cmd);
287 }
288 #ifdef DEBUGMODE
289 } else if (stricmp(cmd, "RAW") == 0) {
290 aClient *user;
291
292 if (!(user = find(source)))
293 {
294 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
295 log("Error: aClient not found: %s", source);
296 }
297 else if (!isAdmin(user))
298 {
299 notice(s_GameServ, source, "You must be a %S admin to use this command!");
300 }
301 else
302 {
303 char *rest = strtok(NULL, "");
304 raw("%s", rest);
305 }
306 } else if (stricmp(cmd, "PRINT") == 0) {
307 for (int x = 0; x < LEVELS; x++)
308 levels[x].monsters.print();
309 } else if (stricmp(cmd, "RANDOM") == 0) {
310 char *rstr = strtok(NULL, "");
311 range trange;
312 trange.setRange(rstr);
313 notice(s_GameServ, source, "Random number in that range: %d", trange.random());
314 #endif
315 } else {
316 aClient *user;
317 if ((user = find(source)))
318 {
319 if (isIgnore(user))
320 {
321 #ifdef DEBUGMODE
322 log("Ignoring %s.", user->getNick());
323 #endif
324 }
325 else
326 {
327 notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd);
328 }
329 }
330 }
331
332 #ifndef P10
333 source--; // Bring the ':' back so we don't leak memory
334 #endif
335 if (z == ':')
336 cmd--; // Same thing :)
337 }
338
339 int stricmp(const char *s1, const char *s2)
340 {
341 register int c;
342
343 while ((c = tolower(*s1)) == tolower(*s2)) {
344 if (c == 0)
345 return 0;
346 s1++;
347 s2++;
348 }
349 if (c < tolower(*s2))
350 return -1;
351 return 1;
352 }
353
354 void showstats(const char *u, const char *nick)
355 {
356 aClient *ni, *sender = find(u);
357 char *buf;
358 buf = new char[50];
359 char *space;
360
361
362 if (!(ni = findplayer(nick)))
363 {
364 notice(s_GameServ, u, "%s not found", nick);
365 }
366 else if (ni->stats)
367 {
368 notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name);
369
370 sprintf(buf, "Experience: %ld", ni->stats->exp);
371 space = spaces(strlen(buf), " ");
372 notice(s_GameServ, sender->getNick(), "%s%sLevel: %d", buf, space,
373 ni->stats->level);
374 delete [] space;
375
376 sprintf(buf, "Gold: %ld", ni->stats->gold);
377 space = spaces(strlen(buf), " ");
378 notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, ni->stats->bank);
379 delete [] space;
380
381 notice(s_GameServ, sender->getNick(), "Hit Points: %d of %d", ni->stats->hp,
382 ni->stats->maxhp);
383
384 sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->weapon]);
385 space = spaces(strlen(buf), " ");
386 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
387 buf, space, ni->stats->defense + arbonus[ni->stats->armor]);
388 delete [] space;
389
390 sprintf(buf, "Armor: %s", armors[ni->stats->armor]);
391 space = spaces(strlen(buf), " ");
392 notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
393 weapons[ni->stats->weapon]);
394 delete [] space;
395
396 sprintf(buf, "Forest Fights: %d", ni->stats->forest_fights);
397 space = spaces(strlen(buf), " ");
398 notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->player_fights);
399 delete [] space;
400 Pouch *inv = &ni->stats->inventory;
401
402 notice(s_GameServ, u, "Potions");
403 sprintf(buf, "Healing: %d", inv->Healing());
404 space = spaces(strlen(buf), " ");
405 notice(s_GameServ, sender->getNick(), "%s%sHP: %d", buf,
406 space, inv->HP());
407 delete [] space;
408
409 sprintf(buf, "Strength: %d", inv->Strength());
410 space = spaces(strlen(buf), " ");
411 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d", buf,
412 space, inv->Defense());
413 delete [] space;
414 }
415 else
416 {
417 notice(s_GameServ, u, "%s is not playing!", ni->stats->name);
418 }
419 delete [] buf;
420 }
421
422 char *spaces(int len, char *seperator)
423 {
424 char *final;
425 final = new char[30];
426 int y;
427 strcpy(final, seperator);
428 for (y = 0; y < 30 - len; y++)
429 strcat(final, seperator);
430 return final;
431 }
432
433 void raw(const char *fmt, ...)
434 {
435 va_list args;
436 char *input;
437 const char *t = fmt;
438 input = new char[1024];
439 va_start(args, fmt);
440 memset(input, 0, sizeof(input)); // Initialize to NULL
441 for (; *t; t++)
442 {
443 if (*t == '%')
444 {
445 switch(*++t) {
446 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
447 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
448 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
449 case 'l':
450 if (*++t == 'd')
451 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
452 }
453 }
454 else
455 {
456 sprintf(input, "%s%c", input, *t);
457 }
458
459 }
460 #ifdef DEBUGMODE
461 log("Input: %s", input);
462 #endif
463
464 sprintf(input, "%s%s", input, "\r\n");
465 sock_puts(sock, input);
466 delete [] input;
467 va_end(args);
468 }
469 /* Send a NOTICE from the given source to the given nick. */
470
471 void notice(const char *source, const char *dest, const char *fmt, ...)
472 {
473 if (fmt[0] == '\0')
474 return;
475
476 char *commanduse;
477 commanduse = new char[16];
478
479 #ifdef P10
480 if (isUsePrivmsg())
481 strcpy(commanduse, "P");
482 else
483 strcpy(commanduse, "O");
484 #else
485
486 if (isUsePrivmsg())
487 strcpy(commanduse, "PRIVMSG");
488 else
489 strcpy(commanduse, "NOTICE");
490 #endif
491
492 va_list args;
493 char *input;
494 const char *t = fmt;
495 input = new char[1024];
496 va_start(args, fmt);
497 if (dest[0] == ':')
498 {
499 dest++;
500
501 #if !defined(P10)
502 sprintf(input, ":%s %s %s :", source, commanduse, dest);
503 #else
504 sprintf(input, "%s %s %s :", gsnum, commanduse, dest);
505 #endif
506
507 dest--;
508 }
509 else
510 {
511 #if !defined(P10)
512 sprintf(input, ":%s %s %s :", source, commanduse, dest);
513 #else
514 sprintf(input, "%s %s %s :", gsnum, commanduse, dest);
515 #endif
516 }
517
518 for (; *t; t++)
519 {
520 if (*t == '%')
521 {
522 switch(*++t) {
523 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
524 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
525 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
526 case 'l':
527 if (*++t == 'd')
528 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
529 }
530 }
531 else
532 {
533 sprintf(input, "%s%c", input, *t);
534 }
535
536 }
537 #ifdef DEBUGMODE
538 log("Input: %s", input);
539 #endif
540 sprintf(input, "%s%s", input, "\r\n");
541 sock_puts(sock, input);
542 delete [] commanduse;
543 delete [] input;
544 va_end(args);
545 }
546
547
548 int strnicmp(const char *s1, const char *s2, size_t len)
549 {
550 register int c;
551
552 if (!len)
553 return 0;
554 while ((c = tolower(*s1)) == tolower(*s2) && len > 0) {
555 if (c == 0 || --len == 0)
556 return 0;
557 s1++;
558 s2++;
559 }
560 if (c < tolower(*s2))
561 return -1;
562 return 1;
563 }
564
565 #ifndef HAVE_STRTOK
566 char *strtok(char *str, const char *delim)
567 {
568 static char *current = NULL;
569 char *ret;
570
571 if (str)
572 current = str;
573 if (!current)
574 return NULL;
575 current += strspn(current, delim);
576 ret = *current ? current : NULL;
577 current += strcspn(current, delim);
578 if (!*current)
579 current = NULL;
580 else
581 *current++ = 0;
582 return ret;
583 }
584 #endif
585
586 void do_check(char *u)
587 {
588 int days, hours, minutes, seconds;
589 long complete;
590 complete = (lastrefresh + refreshperiod) - time(NULL);
591 days = complete / 86400;
592 hours = (complete % 86400) / 3600;
593 minutes = (complete % 86400) % 3600 / 60;
594 seconds = (complete % 86400) % 3600 % 60;
595
596 notice(s_GameServ, u, "Time left to next refresh: %dd %dh %dm %ds",
597 days, hours, minutes, seconds);
598 }
599
600 void do_list(char *u)
601 {
602 aClient *user;
603 char *cmd = strtok(NULL, " ");
604
605 if (!(user = find(u)))
606 {
607 log("Fatal Error: Couldn't find %s in the client list", u);
608 return;
609 }
610 else if (isIgnore(user))
611 {
612 #ifdef DEBUGMODE
613 log("Ignoring %s. Command LIST", user->getNick());
614 #endif
615 return;
616 }
617
618 ListNode<aClient> *temp;
619 bool header = false;
620
621 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
622 {
623 temp = players[x].First();
624 if (!players[x].isEmpty())
625 {
626 while(temp)
627 {
628 if (cmd || is_playing(temp->getData()))
629 {
630 if (!header)
631 {
632 notice(s_GameServ, u, "Players:");
633 header = true;
634 }
635 #ifdef P10
636 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getRealNick(),
637 temp->getData()->stats->name);
638 #else
639 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(),
640 temp->getData()->stats->name);
641 #endif
642 }
643
644 temp = temp->Next();
645 }
646 }
647 }
648 if (!header)
649 notice(s_GameServ, u, "No one is playing");
650 else
651 notice(s_GameServ, u, "End of List");
652
653 }
654
655 void do_logout(char *u)
656 {
657 aClient *user;
658 char *name = strtok(NULL, " ");
659
660 if (!(user = find(u)))
661 {
662 notice(s_GameServ, u, "Fatal error. Cannot find aClient. "\
663 "Buf: %s LOGOUT", u);
664 log("Could not find aClient Buf: %s LOGOUT",
665 u);
666 return;
667 }
668 else if (isIgnore(user))
669 {
670 #ifdef DEBUGMODE
671 log("Ignoring %s.", user->getNick());
672 #endif
673 return;
674 }
675
676 if (name)
677 {
678 if (!isAdmin(user))
679 {
680 notice(s_GameServ, u, "You must be a %S admin to use this command!");
681 }
682 else if (!(user = findplayer(name)))
683 {
684 notice(s_GameServ, u, "Couldn't find a player named %s", name);
685 }
686 else
687 {
688 notice(s_GameServ, u, "Logging out %s", user->stats->name);
689 logout(user);
690 }
691 }
692 else if (!name)
693 {
694 if (!is_playing(user))
695 {
696 notice(s_GameServ, u, "You're not logged in!");
697 }
698 else if (is_fighting(user))
699 {
700 notice(s_GameServ, u, "You can't logout while fighting!");
701 }
702 else
703 {
704 notice(s_GameServ, u, "You have left the fields. You have lived to kill another day!");
705 logout(user);
706 }
707 }
708 }
709
710 void logout(aClient *user)
711 {
712 if (is_playing(user))
713 {
714 ListNode<aClient> *it;
715 aClient *temp;
716 unsigned long hv = iHASH((unsigned char *) user->stats->name);
717 it = players[hv].Find(user);
718
719 if (!it)
720 {
721 notice(s_GameServ, user->getNick(), "Fatal error. Contact "\
722 "%S Admin. Cannot find you in the players list.");
723 log("Error on logout(). Can't find %s in the players list",
724 #ifdef P10
725 user->getRealNick()
726 #else
727 user->getNick()
728 #endif
729 );
730 return;
731 }
732
733 temp = new aClient;
734 temp->stats = new Player;
735 temp->stats->setData(user->stats);
736 user->stats->client = NULL;
737
738 if (player_fight(user))
739 user->stats->battle->stats->battle = NULL;
740
741 delete user->stats;
742 user->stats = NULL;
743 temp->stats->client = NULL;
744 #ifdef P10
745 temp->setRealNick("Not Playing");
746 #endif
747 temp->setNick("Not Playing");
748
749 it->setNewPtr(temp);
750 #ifdef DEBUGMODE
751 log("Logged out player %s",
752 #ifdef P10
753 user->getRealNick()
754 #else
755 user->getNick()
756 #endif
757 );
758 #endif
759 }
760 clearPlaying(user);
761 }
762
763 void do_register(char *u)
764 {
765 char *password, *name;
766 aClient *user;
767 name = strtok(NULL, " ");
768 password = strtok(NULL, " ");
769
770 static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
771 static char salt[3];
772
773 salt[0] = saltChars[rand() % strlen(saltChars)];
774 salt[1] = saltChars[rand() % strlen(saltChars)];
775 salt[2] = '\0';
776
777 if (!name)
778 {
779 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
780 }
781 else if (!password)
782 {
783 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
784 }
785 else if ((user = findplayer(name)))
786 {
787 notice(s_GameServ, u, "%s is already registered!", name);
788 notice(s_GameServ, u, "Choose another name!");
789 }
790 else if (!(user = find(u)))
791 {
792 log("Fatal Error: Couldn't find %s in the clients list", u);
793 }
794 else if (isIgnore(user))
795 {
796 #ifdef DEBUGMODE
797 log("Ignoring %s.", user->getNick());
798 #endif
799 return;
800 }
801 else
802 {
803 if (!is_playing(user))
804 {
805 ListNode<aClient> *temp;
806 user->stats = new Player(user);
807 user->stats->client = user; // Set the backwards pointer
808 user->stats->reset(); // set the user up
809 strncpy(user->stats->password, crypt(password, salt), 255);
810 strncpy(user->stats->name, name, 255);
811 unsigned long hv = iHASH((unsigned char *) name);
812 updateTS(user->stats);
813 temp = players[hv].insertAtBack_RLN(user);
814 temp->setPtr(user); // This is an extra step, but necessary for now
815
816 // Update the last login time
817 user->stats->lastlogin = time(NULL);
818
819 notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name, password);
820 notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!");
821 log("Nickname %s registered player %s.", u, user->stats->name);
822 setPlaying(user); // set the playing flag
823 }
824 else
825 {
826 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
827 }
828 }
829 }
830
831 void do_identify(char *u)
832 {
833 char *password, *name;
834 aClient *user, *p;
835 name = strtok(NULL, " ");
836 password = strtok(NULL, " ");
837 if (!password || !name)
838 {
839 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
840 }
841 else if (!(user = find(u)))
842 {
843 notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, ""));
844 log("Error: aClient not found: %s", u);
845 }
846 else if (isIgnore(user))
847 {
848 #ifdef DEBUGMODE
849 log("Ignoring %s.", user->getNick());
850 #endif
851 return;
852 }
853 else if (!(p = findplayer(name)) || !p->stats)
854 notice(s_GameServ, u, "Player %s not found", name);
855 else if (is_playing(user))
856 {
857 notice(s_GameServ, u, "You are already playing!");
858 }
859 else if (p->stats->client != NULL && !isAdmin(user))
860 {
861 notice(s_GameServ, u, "That player has already identified.");
862 }
863 else if (!check_password(name, password) && !isAdmin(user))
864 {
865 notice(s_GameServ, u, "Password incorrect");
866 }
867 else {
868 ListNode<aClient> *temp;
869 unsigned long hv = iHASH((unsigned char *) p->stats->name);
870 temp = players[hv].Find(p);
871 if (!temp)
872 {
873 notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s",
874 strtok(NULL, ""));
875 return;
876 }
877 user->stats = new Player(p->stats->name);
878 #ifdef DEBUGMODE
879 log("Setting data for identified");
880 #endif
881 user->stats->setData(p->stats);
882 user->stats->client = user;
883 updateTS(user->stats);
884
885
886 #ifdef DEBUGMODE
887 log("Player %s IRC: %s Identified", user->stats->name,
888 user->getNick());
889 #endif
890
891 setPlaying(user); // set the playing flag
892
893 temp->setPtr(user);
894
895 // Update the last login time
896 user->stats->lastlogin = time(NULL);
897
898 notice(s_GameServ, u, "Password Accepted. Identified.");
899 showNews(u, todaysnews);
900 }
901 }
902
903 void do_stats(char *u)
904 {
905 char *nick;
906 aClient *user;
907
908 nick = strtok(NULL, " ");
909
910 if (!(user = find(u)))
911 {
912 log("Fatal Error: %s not found in client list", u);
913 return;
914 }
915 else if (isIgnore(user))
916 {
917 #ifdef DEBUGMODE
918 log("Ignoring %s.", user->getNick());
919 #endif
920 return;
921 }
922 else if (!nick)
923 {
924 if (!is_playing(user))
925 {
926 notice(s_GameServ, u, "You're not playing, so you have no stats!");
927 return;
928 }
929 else
930 {
931 updateTS(user->stats);
932 showstats(u, user->stats->name);
933 }
934 }
935 else
936 showstats(u, nick);
937 }
938
939 void init_masters()
940 {
941 #ifdef DEBUGMODE
942 log("Calling delete_masters()");
943 #endif
944
945 delete_masters();
946
947 #ifdef DEBUGMODE
948 log("Initializing masters");
949 #endif
950
951 for (int x = 0; x < LEVELS; x++)
952 masters[x] = new Monster;
953
954 strcpy(masters[0]->name, "Old Bones");
955 strcpy(masters[0]->weapon, "Dull Sword Cane");
956 masters[0]->strength = 32;
957 masters[0]->gold = 0;
958 masters[0]->exp = 0;
959 masters[0]->maxhp = 35;
960 masters[0]->hp = 35;
961 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!");
962
963 strcpy(masters[1]->name, "Master Chang");
964 strcpy(masters[1]->weapon, "Nanchaku");
965 masters[1]->strength = 48;
966 masters[1]->gold = 0;
967 masters[1]->exp = 0;
968 masters[1]->maxhp = 51;
969 masters[1]->hp = 51;
970 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.");
971
972 strcpy(masters[2]->name, "Chuck Norris");
973 strcpy(masters[2]->weapon, "Ranger Kick");
974 masters[2]->strength = 88;
975 masters[2]->gold = 0;
976 masters[2]->exp = 0;
977 masters[2]->maxhp = 100;
978 masters[2]->hp = 100;
979 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!");
980
981
982 strcpy(masters[3]->name, "Mr. Miagi");
983 strcpy(masters[3]->weapon, "Petrified Bonsai");
984 masters[3]->strength = 169;
985 masters[3]->gold = 0;
986 masters[3]->exp = 0;
987 masters[3]->maxhp = 165;
988 masters[3]->hp = 165;
989 strcpy(masters[3]->death, "Skill comes from repeating the correct but seemingly mundane actions. Wax ON, wax OFF!");
990
991 strcpy(masters[4]->name, "Jackie Chan");
992 strcpy(masters[4]->weapon, "Kung Fu Kick");
993 masters[4]->strength = 275;
994 masters[4]->gold = 0;
995 masters[4]->exp = 0;
996 masters[4]->maxhp = 232;
997 masters[4]->hp = 232;
998 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!");
999
1000 strcpy(masters[5]->name, "Jet Li");
1001 strcpy(masters[5]->weapon, "Motorcycle");
1002 masters[5]->strength = 347;
1003 masters[5]->gold = 0;
1004 masters[5]->exp = 0;
1005 masters[5]->maxhp = 504;
1006 masters[5]->hp = 504;
1007 strcpy(masters[5]->death, "Failure is a fuel for excuses. It's the doing the do, that makes the making.");
1008
1009
1010 strcpy(masters[6]->name, "Muhammad Ali");
1011 strcpy(masters[6]->weapon, "Quick Jab");
1012 masters[6]->strength = 515;
1013 masters[6]->gold = 0;
1014 masters[6]->exp = 0;
1015 masters[6]->maxhp = 1078;
1016 masters[6]->hp = 1078;
1017 strcpy(masters[6]->death, "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up.");
1018
1019 strcpy(masters[7]->name, "Li Mu Bai");
1020 strcpy(masters[7]->weapon, "Green Destiny");
1021 masters[7]->strength = 655;
1022 masters[7]->gold = 0;
1023 masters[7]->exp = 0;
1024 masters[7]->maxhp = 2207;
1025 masters[7]->hp = 2207;
1026 strcpy(masters[7]->death, "No growth without resistance. No action without reaction. No desire without restraint.");
1027
1028
1029 strcpy(masters[8]->name, "Jimmy Wang Yu");
1030 strcpy(masters[8]->weapon, "Flying Guillotine");
1031 masters[8]->strength = 819;
1032 masters[8]->gold = 0;
1033 masters[8]->exp = 0;
1034 masters[8]->maxhp = 2780;
1035 masters[8]->hp = 2780;
1036 strcpy(masters[8]->death, "You have beaten the one armed boxer. Proceed with caution!");
1037
1038 strcpy(masters[9]->name, "Wong Fei Hung");
1039 strcpy(masters[9]->weapon, "Drunken Boxing");
1040 masters[9]->strength = 1014;
1041 masters[9]->gold = 0;
1042 masters[9]->exp = 0;
1043 masters[9]->maxhp = 3046;
1044 masters[9]->hp = 3046;
1045 strcpy(masters[9]->death, "Hiccup! Monkey drinks master's wine!");
1046
1047 strcpy(masters[10]->name, "Bruce Lee");
1048 strcpy(masters[10]->weapon, "Fists of fury");
1049 masters[10]->strength = 1286;
1050 masters[10]->gold = 0;
1051 masters[10]->exp = 0;
1052 masters[10]->maxhp = 3988;
1053 masters[10]->hp = 3988;
1054 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.");
1055 }
1056
1057 void delete_monsters()
1058 {
1059 for (int x = 0; x < LEVELS; x++)
1060 levels[x].monsters.deleteNodes();
1061 }
1062
1063 void delete_masters()
1064 {
1065 for (int x = 0; x < LEVELS; x++)
1066 if (masters[x])
1067 delete masters[x];
1068 }
1069
1070 void display_monster(char *u)
1071 {
1072 if (is_playing(u))
1073 {
1074 aClient *user = find(u);
1075 Player *ni = user->stats;
1076
1077 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->hp);
1078 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name, ni->fight->hp);
1079 notice(s_GameServ, u, "Here are your commands:");
1080 notice(s_GameServ, u, "/msg %S attack");
1081 notice(s_GameServ, u, "/msg %S run");
1082 notice(s_GameServ, u, "What will you do?");
1083 }
1084 }
1085
1086 void display_players(char *u)
1087 {
1088 aClient *user;
1089 if (!(user = find(u)))
1090 {
1091 log("Fatal error in display_players(): Couldn't find %s", u);
1092 }
1093 else
1094 display_players(user);
1095 }
1096
1097 void display_players(aClient *user)
1098 {
1099 char *u = user->getNick();
1100 if (is_playing(user) && player_fight(user))
1101 {
1102 aClient *battle = user->stats->battle;
1103 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", user->stats->hp);
1104 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name, battle->stats->hp);
1105 notice(s_GameServ, u, "Here are your commands:");
1106 notice(s_GameServ, u, "/msg %S attack");
1107 notice(s_GameServ, u, "/msg %S run");
1108 notice(s_GameServ, u, "What will you do?");
1109 }
1110 }
1111
1112
1113 bool is_playing(char *u)
1114 {
1115 aClient *user;
1116 if (!(user = find(u)))
1117 return false;
1118 else
1119 return is_playing(user);
1120 }
1121
1122 bool is_playing(aClient *user)
1123 {
1124 if (user->stats == NULL)
1125 {
1126 return false;
1127 }
1128 else if (user->stats->client == NULL)
1129 {
1130 return false;
1131 }
1132 else if (!FL_is_playing(user))
1133 {
1134 return false;
1135 }
1136 else
1137 return true;
1138 }
1139
1140 bool is_fighting(char *u)
1141 {
1142 aClient *user;
1143
1144 if (!(user = find(u)))
1145 return false;
1146 else
1147 return is_fighting(user);
1148 }
1149
1150 bool is_fighting(aClient *user)
1151 {
1152 if (!is_playing(user))
1153 return false;
1154 else
1155 return player_fight(user) || master_fight(user) || user->stats->fight != NULL;
1156 }
1157
1158 bool player_fight(char *u)
1159 {
1160 aClient *user;
1161
1162 if (!(user = find(u)))
1163 return false;
1164 else
1165 return player_fight(user);
1166 }
1167
1168 bool player_fight(aClient *user)
1169 {
1170 if (!is_playing(user))
1171 return false;
1172 else if (user->stats->battle != NULL)
1173 {
1174 return user->stats->battle->stats != NULL;
1175 }
1176 return false;
1177 }
1178
1179 bool master_fight(char *u)
1180 {
1181 aClient *user;
1182
1183 if (!(user = find(u)))
1184 return false;
1185 else
1186 return master_fight(user);
1187 }
1188
1189 bool master_fight(aClient *user)
1190 {
1191 if (!is_playing(user))
1192 return false;
1193 else
1194 return user->stats->master != NULL;
1195 }
1196
1197 void do_fight(char *u)
1198 {
1199 aClient *ni, *battle;
1200
1201 char *nick = strtok(NULL, " ");
1202
1203 if (!nick)
1204 {
1205 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
1206 return;
1207 }
1208 else if (!(ni = find(u)))
1209 {
1210 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1211 return;
1212 }
1213 else if (isIgnore(ni))
1214 {
1215 #ifdef DEBUGMODE
1216 log("Ignoring %s.", ni->getNick());
1217 #endif
1218 return;
1219 }
1220 else if (!is_playing(ni))
1221 {
1222 notice(s_GameServ, u, "You are not playing!");
1223 return;
1224 }
1225
1226 updateTS(ni->stats);
1227
1228 if (ni->stats->player_fights <= 0)
1229 {
1230 ni->stats->player_fights = 0; // just to be safe
1231 notice(s_GameServ, u, "You are out of player fights for the "\
1232 "day. You have to wait until tomorrow!");
1233 }
1234 else if (!(battle = findplayer(nick)))
1235 {
1236 notice(s_GameServ, u, "Player %s not found!", nick);
1237 }
1238 else if (!isAlive(ni->stats))
1239 {
1240 notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!");
1241 }
1242 else if (!is_playing(battle))
1243 {
1244 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
1245 }
1246
1247 /* offline fighting not available yet
1248 else if (!(fight = finduser(nick)))
1249 {
1250 ni->stats->battle = battle;
1251 battle->battle = ni;
1252 setYourTurn(ni->stats);
1253 clearYourTurn(battle->stats);
1254
1255 notice(s_GameServ, u, "You decide to fight %s while they're "\
1256 "not in the realm!",
1257 battle->stats->name);
1258 display_players(u);
1259 }
1260 */
1261 else if (stricmp(ni->stats->name, battle->stats->name) == 0)
1262 {
1263 notice(s_GameServ, u, "Are you trying to commit suicide!?");
1264 }
1265 else if (!isAlive(battle->stats))
1266 {
1267 notice(s_GameServ, u, "They are dead. Cannot fight dead players!");
1268 }
1269 else if (player_fight(battle))
1270 {
1271 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name);
1272 }
1273 else if (master_fight(battle))
1274 {
1275 notice(s_GameServ, u, "%s is fighting their master!", battle->stats->name);
1276 }
1277 else if (is_fighting(battle))
1278 {
1279 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name);
1280 }
1281 else if (ni->stats->level - battle->stats->level > maxbfightdistance)
1282 {
1283 // You can't fight someone below you by more than X level(s)
1284 // level 12 can fight level (12 - X) but not < (12 - X)
1285 notice(s_GameServ, u, "You may not fight %s. You're too strong!",
1286 battle->stats->name);
1287 }
1288 else if (battle->stats->level - ni->stats->level > maxafightdistance)
1289 {
1290 // You can't fight someone above you by more than X level(S)
1291 // level 1 can fight level (1 + X), but not > (1 + X)
1292 notice(s_GameServ, u, "%s, do you really have a death wish? Try the forest you "\
1293 "weakling!", ni->stats->name);
1294 }
1295 else
1296 {
1297 // Set your battle pointer to the other player
1298 ni->stats->battle = battle;
1299
1300 // Set the other player's battle pointer to you
1301 ni->stats->battle->stats->battle = ni;
1302
1303 // The initiator gets the first move (perhaps this should be 50/50)
1304 setYourTurn(ni->stats);
1305 clearYourTurn(battle->stats);
1306
1307 // Initiate Battle sequence!
1308 ni->stats->player_fights -= 1;
1309
1310 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name);
1311 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name);
1312 notice(s_GameServ, battle->getNick(), "%s gets to go first "\
1313 "because they initiated!", ni->stats->name);
1314 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name);
1315 display_players(ni);
1316 }
1317 }
1318
1319 void do_use(char *u)
1320 {
1321 aClient *user;
1322 Pouch *p;
1323
1324 char *item = strtok(NULL, " ");
1325
1326 if (!item)
1327 {
1328 notice(s_GameServ, u, "SYNTAX: USE ITEM");
1329 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1330 return;
1331 }
1332 else if (!(user = find(u)))
1333 {
1334 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1335 return;
1336 }
1337 else if (isIgnore(user))
1338 {
1339 #ifdef DEBUGMODE
1340 log("Ignoring %s.", user->getNick());
1341 #endif
1342 return;
1343 }
1344 else if (!is_playing(user))
1345 {
1346 notice(s_GameServ, u, "You must be playing to use items!");
1347 return;
1348 }
1349
1350 updateTS(user->stats);
1351
1352 p = &user->stats->inventory;
1353
1354 if (stricmp(item, "HEALING") == 0)
1355 {
1356 if (p->Healing() <= 0)
1357 {
1358 notice(s_GameServ, u, "You are out of Healing Potions!");
1359 return;
1360 }
1361 int oldhealing = user->stats->hp;
1362 user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
1363 if (user->stats->hp - user->stats->maxhp >= 100)
1364 {
1365 user->stats->hp = user->stats->maxhp + 100;
1366
1367 if (oldhealing >= (user->stats->maxhp + 100))
1368 {
1369 notice(s_GameServ, u, "You cannot hold anymore HP!");
1370 return;
1371 }
1372 }
1373
1374 notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
1375 notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
1376 notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealing);
1377 p->decHealing();
1378 if (player_fight(user))
1379 {
1380 notice(s_GameServ, user->stats->battle->getNick(),
1381 "%s has used a healing potion!");
1382 }
1383 }
1384 else if (stricmp(item, "STRENGTH") == 0)
1385 {
1386 if (p->Strength() <= 0)
1387 {
1388 notice(s_GameServ, u, "You are out of Strength Potions!");
1389 return;
1390 }
1391 int oldstrength = user->stats->strength;
1392 notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!");
1393 notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!");
1394 user->stats->strength += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
1395 notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength);
1396 p->decStrength();
1397 if (player_fight(user))
1398 {
1399 notice(s_GameServ, user->stats->battle->getNick(),
1400 "%s has used a strength potion!");
1401 }
1402 }
1403 else if (stricmp(item, "DEFENSE") == 0)
1404 {
1405 if (p->Defense() <= 0)
1406 {
1407 notice(s_GameServ, u, "You are out of Defense Potions!");
1408 return;
1409 }
1410 int olddefense = user->stats->defense;
1411 notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust.");
1412 notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!");
1413 user->stats->defense += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
1414 notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense);
1415 p->decDefense();
1416 if (player_fight(user))
1417 {
1418 notice(s_GameServ, user->stats->battle->getNick(),
1419 "%s has used a defense potion!");
1420 }
1421 }
1422 else if (stricmp(item, "HP") == 0)
1423 {
1424 if (p->HP() <= 0)
1425 {
1426 notice(s_GameServ, u, "You are out of HP Potions!");
1427 return;
1428 }
1429 int oldHP = user->stats->maxhp;
1430 notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid.");
1431 user->stats->maxhp += 2 +
1432 (rand() % 100 > 70 ? (rand() % 7) : (rand() % 2) );
1433
1434 notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP);
1435 p->decHP();
1436 if (player_fight(user))
1437 {
1438 notice(s_GameServ, user->stats->battle->getNick(),
1439 "%s has used a HP potion!");
1440 }
1441 }
1442 else
1443 {
1444 notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALING | STRENGTH | DEFENSE | HP}");
1445 return;
1446 }
1447
1448 end_turn(user); // If they're fighting, end their turn
1449 }
1450 void do_run(char *u)
1451 {
1452 aClient *user;
1453 Player *p, *p2 = NULL;
1454
1455 if (!(user = find(u)))
1456 {
1457 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1458 return;
1459 }
1460 else if (isIgnore(user))
1461 {
1462 #ifdef DEBUGMODE
1463 log("Ignoring %s.", user->getNick());
1464 #endif
1465 return;
1466 }
1467 else if (!is_playing(user))
1468 {
1469 notice(s_GameServ, u, "You must be playing to run!");
1470 return;
1471 }
1472
1473 updateTS(user->stats);
1474 p = user->stats;
1475
1476 if (p->battle)
1477 p2 = p->battle->stats;
1478
1479 if (!is_fighting(user))
1480 notice(s_GameServ, u, "You run in place... try fighting next time.");
1481 else if (!player_fight(user) && !master_fight(user))
1482 {
1483 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name);
1484 delete p->fight;
1485 p->fight = NULL;
1486 }
1487 else if (player_fight(user) && isYourTurn(p))
1488 {
1489 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name);
1490 notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->name);
1491 p2->battle = NULL;
1492 }
1493 else if (player_fight(user) && !isYourTurn(p))
1494 {
1495 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->name);
1496 }
1497 else if (master_fight(user))
1498 {
1499 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name);
1500 }
1501 p->battle = NULL;
1502 }
1503
1504 void end_turn(aClient *user)
1505 {
1506 char *nick, *u = user->getNick();
1507 Monster *fight;
1508 aClient *battle;
1509 int mhit;
1510
1511 nick = new char[strlen(user->getNick()) + 1];
1512
1513 if (!user || !is_playing(user) || !is_fighting(user))
1514 goto endturn;
1515
1516 if (!player_fight(user) && !master_fight(user))
1517 fight = user->stats->fight;
1518 else
1519 fight = user->stats->master;
1520 battle = user->stats->battle;
1521
1522 if (!player_fight(user))
1523 {
1524 // Opponent's Hit
1525 mhit = (fight->strength / 2) +
1526 (rand() % (fight->strength / 2) - (user->stats->defense +
1527 arbonus[user->stats->armor]));
1528 }
1529 else
1530 {
1531 // Opponent's Hit
1532 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1533 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1534 (user->stats->defense + arbonus[user->stats->armor]));
1535 }
1536 if (!player_fight(user))
1537 {
1538
1539 if (mhit > 0)
1540 {
1541 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1542 fight->name, fight->weapon, mhit);
1543 }
1544 else if (mhit <= 0)
1545 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1546
1547 if (mhit >= user->stats->hp)
1548 {
1549 if (!master_fight(user))
1550 {
1551 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1552 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1553 "of your experience!");
1554 user->stats->gold = 0;
1555 user->stats->exp -= (long int)(user->stats->exp * .10);
1556 user->stats->hp = 0;
1557 user->stats->fight = NULL;
1558 clearAlive(user->stats);
1559 goto endturn;
1560 }
1561 else
1562 {
1563 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1564 "until tomorrow to try again", user->stats->master->name);
1565 user->stats->fight = NULL;
1566 user->stats->master = NULL;
1567 goto endturn;
1568 }
1569 }
1570 else
1571 {
1572 if (mhit > 0)
1573 user->stats->hp -= mhit;
1574 display_monster(u);
1575 goto endturn;
1576 }
1577 }
1578 else
1579 {
1580 clearYourTurn(user->stats);
1581 setYourTurn(battle->stats);
1582 display_players(battle);
1583 }
1584 endturn:
1585 delete nick;
1586 }
1587
1588 void do_attack(char *u)
1589 {
1590 int hit, mhit;
1591 aClient *ni, *battle; // The player and perhaps the player they're fighting
1592 Monster *fight; // The monster they may be fighting
1593
1594 if (!(ni = find(u)))
1595 {
1596 notice(s_GameServ, u, "Fatal error in do_attack. Contact a(n) %S admin for help.");
1597 return;
1598 }
1599 else if (isIgnore(ni))
1600 {
1601 #ifdef DEBUGMODE
1602 log("Ignoring %s.", ni->getNick());
1603 #endif
1604 return;
1605 }
1606 else if (!is_playing(ni))
1607 {
1608 notice(s_GameServ, u, "You're not playing!");
1609 return;
1610 }
1611 else if (!is_fighting(ni))
1612 {
1613 notice(s_GameServ, u, "You're not in battle!");
1614 return;
1615 }
1616 else
1617 {
1618 if (!ni->stats->master) // This is not a master fight
1619 fight = ni->stats->fight; // Monster Could be NULL
1620 else // This IS a master fight
1621 fight = ni->stats->master; // Master Could be NULL
1622
1623 battle = ni->stats->battle; // Player Could be NULL
1624
1625 // One has to be !NULL based on the previous else if
1626 // We wouldn't be here if they were all NULL
1627 }
1628 updateTS(ni->stats);
1629
1630 if (!player_fight(ni))
1631 {
1632 // Player's Hit
1633 hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1634 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
1635
1636 // Opponent's Hit
1637 mhit = (fight->strength / 2) +
1638 (rand() % (fight->strength / 2) - (ni->stats->defense +
1639 arbonus[ni->stats->armor]));
1640 }
1641 else
1642 {
1643 // Opponent's Hit
1644 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1645 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1646 (ni->stats->defense + arbonus[ni->stats->armor]));
1647
1648 // Player's Hit
1649 hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1650 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
1651 (battle->stats->defense + arbonus[battle->stats->armor]));
1652 }
1653
1654 if (!player_fight(ni))
1655 {
1656 if (hit > 0)
1657 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
1658 else
1659 notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
1660
1661 if (hit >= fight->hp)
1662 {
1663 if (master_fight(ni))
1664 {
1665 notice(s_GameServ, u, "You have bested %s!", fight->name);
1666 addNews(todaysnews, "%s has bested %s and moved "\
1667 "to level %d", ni->stats->name, fight->name,
1668 (ni->stats->level + 1));
1669 }
1670 else
1671 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
1672
1673 notice(s_GameServ, u, "%s", fight->death);
1674 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
1675 fight->exp, fight->gold);
1676
1677 // If your new experience (or gold) will be greater than 2 billion,
1678 // then set your exp to 2bil. (2 billion max)... otherwise add them.
1679 // This could be a problem with overflowing out of the sign bit.
1680 // Unsigned long int maybe? Leave it for now.
1681 ni->stats->exp += fight->exp;
1682 if (ni->stats->exp < 0 || ni->stats->exp > 2000000000)
1683 ni->stats->exp = 2000000000;
1684
1685 ni->stats->gold += fight->gold;
1686 if (ni->stats->gold < 0 || ni->stats->gold > 2000000000)
1687 ni->stats->gold = 2000000000;
1688
1689 if (master_fight(ni))
1690 {
1691 notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
1692 notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
1693 strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
1694
1695 // Increase your level
1696
1697 // Increase your maximum hit points
1698 ni->stats->maxhp += hpbonus[ni->stats->level - 1];
1699
1700 // Heal the player by setting hp to their max
1701 ni->stats->hp = ni->stats->maxhp;
1702
1703 // Add to your strength
1704 ni->stats->strength += strbonus[ni->stats->level - 1];
1705
1706 // Add to your defensive power
1707 ni->stats->defense += defbonus[ni->stats->level - 1];
1708
1709 ni->stats->level++;
1710
1711 // Clear the pointer for your master
1712 ni->stats->master = NULL;
1713 }
1714
1715 // They're dead so remove the pointer
1716 delete ni->stats->fight;
1717 ni->stats->fight = NULL;
1718 ni->stats->master = NULL;
1719
1720 return;
1721 }
1722 else
1723 {
1724 if (hit > 0)
1725 fight->hp -= hit;
1726 if (mhit > 0)
1727 {
1728 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1729 fight->name, fight->weapon, mhit);
1730 }
1731 else if (mhit <= 0)
1732 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1733
1734 if (mhit >= ni->stats->hp)
1735 {
1736 if (!master_fight(ni))
1737 {
1738 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1739 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1740 "of your experience!");
1741 addNews(todaysnews, "%s has been killed by %s!",
1742 ni->stats->name, fight->name);
1743 ni->stats->gold = 0;
1744 ni->stats->exp -= (long int)(ni->stats->exp * .10);
1745 ni->stats->hp = 0;
1746 ni->stats->fight = NULL;
1747 clearAlive(ni->stats);
1748 return;
1749 }
1750 else
1751 {
1752 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1753 "until tomorrow to try again", ni->stats->master->name);
1754 addNews(todaysnews, "%s tried to best %s and failed!",
1755 ni->stats->name, fight->name);
1756 ni->stats->fight = NULL;
1757 ni->stats->master = NULL;
1758 return;
1759 }
1760 }
1761 else
1762 {
1763 if (mhit > 0)
1764 ni->stats->hp -= mhit;
1765 display_monster(u);
1766 return;
1767 }
1768 }
1769 }
1770 else if (player_fight(ni))
1771 {
1772 /* Offline fighting not available yet
1773 if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
1774 {
1775 if (hit > 0)
1776 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
1777 else
1778 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
1779 if (hit >= battle->stats->hp)
1780 {
1781 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
1782 * notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1783 (long int)(battle->stats->exp * .10), battle->stats->gold);
1784 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1785 {
1786 ni->stats->exp += (long int)(battle->stats->exp * .10);
1787 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1788 }
1789 * else
1790 {
1791 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1792 ni->stats->exp = 2000000000;
1793 }
1794
1795 if (2000000000 - ni->stats->gold > battle->stats->gold)
1796 {
1797 * ni->stats->gold += battle->stats->gold;
1798 battle->stats->gold = 0;
1799 }
1800 else
1801 {
1802 battle->stats->gold = 2000000000 - ni->stats->gold;
1803 ni->stats->gold = 2000000000;
1804 }
1805 * ni->stats->battle->stats->alive = 0;
1806 ni->stats->battle->battle = NULL;
1807 ni->stats->battle = NULL;
1808 return;
1809 }
1810 else
1811 {
1812 if (hit > 0)
1813 * battle->stats->hp -= hit;
1814 if (mhit > 0)
1815 {
1816 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1817 battle->nick, weapons[battle->stats->weapon], mhit);
1818 }
1819 else if (mhit <= 0)
1820 notice(s_GameServ, u, "%s completely misses you!", battle->nick);
1821 *
1822 if (mhit >= ni->stats->hp)
1823 {
1824 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
1825 if (2000000000 - battle->stats->gold > ni->stats->gold)
1826 {
1827 notice(s_GameServ, u, "%s took all your gold!", battle->nick);
1828 battle->stats->gold += ni->stats->gold;
1829 * ni->stats->gold = 0;
1830 }
1831 else
1832 {
1833 notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
1834 battle->nick);
1835 ni->stats->gold -= (2000000000 - battle->stats->gold);
1836 notice(s_GameServ, u, "You were left dead with %d gold.",
1837 * (long int)ni->stats->gold);
1838 battle->stats->gold = 2000000000;
1839 }
1840 ni->stats->battle->battle = NULL;
1841 ni->stats->battle = NULL;
1842 ni->stats->alive = 0;
1843 return;
1844 }
1845 * else
1846 {
1847 if (mhit > 0)
1848 ni->stats->hp -= mhit;
1849 display_players(u);
1850 return;
1851 }
1852 }
1853 }
1854 * end offline fighting */
1855
1856 if (is_playing(battle))
1857 {
1858 if (!isYourTurn(ni->stats))
1859 {
1860 notice(s_GameServ, u, "Please wait until %s decides what to do!",
1861 battle->stats->name);
1862 return;
1863 }
1864 if (hit > 0)
1865 {
1866 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->stats->name, hit);
1867
1868 notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
1869 "\ 2%d\ 2 damage!", ni->stats->name,
1870 weapons[ni->stats->weapon], hit);
1871 }
1872 else
1873 {
1874 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->stats->name);
1875 notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name);
1876 }
1877
1878 if (hit >= battle->stats->hp)
1879 {
1880 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name);
1881 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1882 (long int)(battle->stats->exp * .10), battle->stats->gold);
1883 notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!",
1884 ni->stats->name);
1885 battle->stats->hp = 0;
1886 clearAlive(battle->stats);
1887
1888 ni->stats->exp += (long int)(battle->stats->exp * .10);
1889 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1890
1891 if (ni->stats->exp < 0 || ni->stats->exp > 2000000000)
1892 ni->stats->exp = 2000000000;
1893
1894 if (2000000000 - ni->stats->gold > battle->stats->gold)
1895 {
1896 notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
1897 "all gold on hand!");
1898 ni->stats->gold += battle->stats->gold;
1899 battle->stats->gold = 0;
1900 }
1901 else
1902 {
1903 battle->stats->gold = 2000000000 - ni->stats->gold;
1904 notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
1905
1906 notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
1907 "gold.", ni->stats->name);
1908
1909 notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
1910 "left. All is not lost!", battle->stats->gold);
1911
1912 ni->stats->gold = 2000000000;
1913 }
1914
1915 clearYourTurn(ni->stats);
1916 clearYourTurn(battle->stats);
1917 battle->stats->battle = NULL;
1918 ni->stats->battle = NULL;
1919 return;
1920 }
1921 else
1922 {
1923 if (hit > 0)
1924 battle->stats->hp -= hit;
1925 clearYourTurn(ni->stats);
1926 setYourTurn(battle->stats);
1927 display_players(battle);
1928 notice(s_GameServ, u, "Please wait while %s decides what to do!",
1929 battle->stats->name);
1930 return;
1931 }
1932 }
1933 }
1934 }
1935
1936 void do_heal(char *u)
1937 {
1938 aClient *ni;
1939 char *amount = strtok(NULL, " ");
1940 int price, num;
1941
1942 if (!amount)
1943 {
1944 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1945 return;
1946 }
1947 else if (!(ni = find(u)))
1948 {
1949 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1950 return;
1951 }
1952 else if (isIgnore(ni))
1953 {
1954 #ifdef DEBUGMODE
1955 log("Ignoring %s.", ni->getNick());
1956 #endif
1957 return;
1958 }
1959 else if (!is_playing(ni))
1960 {
1961 notice(s_GameServ, u, "You aren't playing!");
1962 return;
1963 }
1964 else if (!isAlive(ni->stats))
1965 {
1966 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
1967 return;
1968 }
1969 else if (is_fighting(ni))
1970 {
1971 notice(s_GameServ, u, "You can't heal in battle!");
1972 return;
1973 }
1974 else if (ni->stats->hp >= ni->stats->maxhp)
1975 {
1976 notice(s_GameServ, u, "You don't need healing!");
1977 return;
1978 }
1979
1980 updateTS(ni->stats);
1981 if (stricmp(amount, "ALL") == 0)
1982 {
1983 price = ni->stats->level * 3;
1984 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
1985 {
1986 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1987 (long int)ni->stats->gold/price, price);
1988 ni->stats->hp += ni->stats->gold / price;
1989 ni->stats->gold %= price;
1990 }
1991 else
1992 {
1993 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1994 "per point.", price);
1995 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
1996 (ni->stats->maxhp - ni->stats->hp),
1997 (price * (ni->stats->maxhp - ni->stats->hp)) );
1998 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1999 ni->stats->hp = ni->stats->maxhp;
2000 }
2001 }
2002 else if (isstringnum(amount))
2003 {
2004 num = stringtoint(amount);
2005 price = ni->stats->level * 3;
2006 if (ni->stats->gold < price * num)
2007 {
2008 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
2009 (long int)ni->stats->gold/price);
2010 }
2011 else if (num <= ni->stats->maxhp - ni->stats->hp)
2012 {
2013 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
2014 num, price);
2015 ni->stats->hp += num;
2016 ni->stats->gold -= num * price;
2017 }
2018 else if (num > ni->stats->maxhp - ni->stats->hp)
2019 {
2020 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
2021 "per point.", price);
2022 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
2023 (ni->stats->maxhp - ni->stats->hp));
2024 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
2025 ni->stats->hp = ni->stats->maxhp;
2026 }
2027 }
2028 else if (amount[0] == '-')
2029 notice(s_GameServ, u, "You trying to cheat?");
2030 else
2031 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
2032 }
2033
2034 int isstringnum(char *num)
2035 {
2036 unsigned int x;
2037 for (x = 0; x < strlen(num); x++)
2038 {
2039 if ((int)num[x] < 48 || (int)num[x] > 57)
2040 return 0;
2041 }
2042 return 1;
2043 }
2044
2045 long int stringtoint(char *number)
2046 {
2047 long int x, len = strlen(number), sum = 0;
2048 if (len == 1)
2049 return chartoint(number[0]);
2050 sum += chartoint(number[len - 1]);
2051 for (x = len - 2; x >= 0; x--)
2052 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
2053 return sum;
2054 }
2055
2056 long int pow(int x, int y)
2057 {
2058 long int value = 0;
2059 int count = 0;
2060 value += x;
2061
2062 if (x != 0 && y != 0)
2063 {
2064 for (count = 1; count <= y - 1; count++)
2065 value *= x;
2066 }
2067 else
2068 return 1;
2069 return value;
2070 }
2071
2072 long int chartoint(char ch)
2073 {
2074 if (int(ch) >= 48 && int(ch) <= 57)
2075 return int(ch) - 48;
2076 else
2077 return 0;
2078 }
2079
2080 int save_gs_dbase()
2081 {
2082 ListNode<aClient> *ptr;
2083 Player *it;
2084 ofstream outfile;
2085
2086 outfile.open(playerdata);
2087
2088 if (!outfile)
2089 {
2090 log("Error opening %s", playerdata);
2091 return 0;
2092 }
2093
2094 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
2095 {
2096 ptr = players[x].First();
2097 while(ptr)
2098 {
2099 it = ptr->getData()->stats;
2100 clearYourTurn(it);
2101 outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
2102 << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
2103 << it->armor << ' ' << it->weapon << ' '
2104 << it->forest_fights << ' ' << it->player_fights << ' '
2105 << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
2106 << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP()
2107 << ' ' << it->lastlogin << endl;
2108 ptr = ptr->Next();
2109 }
2110 }
2111 outfile.close();
2112 return 1;
2113 }
2114
2115 int load_gs_dbase()
2116 {
2117 ifstream infile;
2118 aClient *temp;
2119 Player *p;
2120 char *tempname, *buf, *password;
2121 buf = new char[1023];
2122
2123 infile.open(playerdata);
2124
2125 if (infile.fail())
2126 {
2127 log("Error opening %s", playerdata);
2128 return 0;
2129 }
2130
2131 for (int x = 0; x < U_TABLE_SIZE; x++)
2132 {
2133 ListNode<aClient> *tempNode;
2134 tempNode = players[x].First();
2135 while (tempNode)
2136 {
2137 if (tempNode->getData()->stats->client)
2138 logout(tempNode->getData()->stats->client);
2139 tempNode = tempNode->Next();
2140 }
2141 players[x].deleteNodes();
2142 }
2143
2144 while (infile.getline(buf, 1024, '\n'))
2145 {
2146 temp = new aClient;
2147 tempname = strtok(buf, " ");
2148 temp->stats = new Player(tempname);
2149 p = temp->stats;
2150
2151 p->level = stringtoint(strtok(NULL, " "));
2152 p->exp = stringtoint(strtok(NULL, " "));
2153 p->gold = stringtoint(strtok(NULL, " "));
2154 p->bank = stringtoint(strtok(NULL, " "));
2155 p->hp = stringtoint(strtok(NULL, " "));
2156 p->maxhp = stringtoint(strtok(NULL, " "));
2157 p->strength = stringtoint(strtok(NULL, " "));
2158 p->defense = stringtoint(strtok(NULL, " "));
2159 p->armor = stringtoint(strtok(NULL, " "));
2160 p->weapon = stringtoint(strtok(NULL, " "));
2161 p->forest_fights = stringtoint(strtok(NULL, " "));
2162 p->player_fights = stringtoint(strtok(NULL, " "));
2163 p->setFlags(stringtoint(strtok(NULL, " ")));
2164
2165 password = strtok(NULL, " ");
2166 strcpy(p->password, password);
2167 temp->setNick("Not Playing");
2168 #ifdef P10
2169 temp->setRealNick("Not Playing");
2170 #endif
2171
2172 p->inventory.reset(); // Set inventory to all 0s
2173 // Old player databases didn't have these three extra values
2174 // If they come up null, leave them to 0 as the default.
2175 // On the next gameserv database save, it will save the values.
2176 tempname = strtok(NULL, " ");
2177 if (tempname)
2178 p->inventory.setHealing(stringtoint(tempname));
2179
2180 tempname = strtok(NULL, " ");
2181 if (tempname)
2182 p->inventory.setStrength(stringtoint(tempname));
2183
2184 tempname = strtok(NULL, " ");
2185 if (tempname)
2186 p->inventory.setDefense(stringtoint(tempname));
2187
2188 tempname = strtok(NULL, " ");
2189 if (tempname)
2190 p->inventory.setHP(stringtoint(tempname));
2191
2192 tempname = strtok(NULL, " ");
2193 if (tempname)
2194 p->lastlogin = stringtoint(tempname);
2195 else
2196 p->lastlogin = time(NULL);
2197
2198 unsigned long hv = iHASH((unsigned char *) temp->stats->name);
2199
2200 temp->stats->client = NULL;
2201 players[hv].insertAtBack(temp);
2202 delete temp;
2203 }
2204 delete [] buf;
2205 infile.close();
2206 return 1;
2207 }
2208
2209 bool passcmp(char *encrypted, char *plaintext)
2210 {
2211 char salt[3];
2212 char *plaintext2, *plainToencrypt;
2213 bool same = false;
2214
2215 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
2216 strcpy(plaintext2, plaintext);
2217
2218 salt[0] = encrypted[0];
2219 salt[1] = encrypted[1];
2220 salt[3] = '\0';
2221
2222 plainToencrypt = crypt(plaintext2, salt);
2223
2224 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
2225
2226 delete []plaintext2;
2227
2228 return same;
2229 }
2230
2231 bool check_password(char *name, char *plaintext)
2232 {
2233 aClient *client;
2234
2235 if (!(client = findplayer(name)))
2236 return false;
2237 else
2238 {
2239 return passcmp(client->stats->password, plaintext);
2240 }
2241 }
2242
2243 void do_store(char *u)
2244 {
2245 char *cmd = strtok(NULL, " ");
2246 char *item = strtok(NULL, " ");
2247 char *num = strtok(NULL, " ");
2248 char *space;
2249 int wep;
2250 aClient *user;
2251 Player *p;
2252
2253 if (!cmd || !item)
2254 {
2255 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2256 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2257 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2258 return;
2259 }
2260 else if (!(user = find(u)))
2261 {
2262 log("Fatal Error: could not find %s in client list", u);
2263 return;
2264 }
2265 else if (isIgnore(user))
2266 {
2267 #ifdef DEBUGMODE
2268 log("Ignoring %s.", user->getNick());
2269 #endif
2270 return;
2271 }
2272 else if (!is_playing(user))
2273 {
2274 notice(s_GameServ, u, "You must be playing to use the store!");
2275 return;
2276 }
2277 else if (!isAlive(user->stats))
2278 {
2279 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
2280 return;
2281 }
2282 updateTS(user->stats);
2283
2284 if (stricmp(cmd, "LIST") == 0)
2285 {
2286 if (stricmp(item, "WEAPONS") == 0)
2287 {
2288 notice(s_GameServ, u, "Welcome to Kain's Armory");
2289 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
2290 for (int x = 1; x < WNA; x++)
2291 {
2292 space = spaces(strlen(weapons[x]), ".");
2293 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
2294 free(space);
2295 }
2296 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
2297 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
2298
2299 }
2300 else if (stricmp(item, "ARMOR") == 0)
2301 {
2302 notice(s_GameServ, u, "Welcome to Kain's Armory");
2303 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
2304 for (int x = 1; x < WNA; x++)
2305 {
2306 space = spaces(strlen(armors[x]), ".");
2307 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
2308 free(space);
2309 }
2310 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
2311 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
2312
2313
2314 }
2315 } else if (stricmp(cmd, "BUY") == 0) {
2316 if (!num)
2317 {
2318 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2319 return;
2320 }
2321 else if (!isstringnum(num))
2322 {
2323 notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
2324 return;
2325 }
2326 if (stricmp(item, "WEAPON") == 0)
2327 {
2328 wep = stringtoint(num);
2329 if (wep >= WNA || wep < 1)
2330 {
2331 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2332 return;
2333 }
2334
2335 p = user->stats;
2336
2337 if (p->weapon != 0)
2338 notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
2339 else if (p->gold < prices[wep - 1])
2340 notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
2341 else
2342 {
2343 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
2344 p->weapon = wep;
2345 p->gold -= prices[wep - 1];
2346 }
2347 }
2348 else if (stricmp(item, "ARMOR") == 0)
2349 {
2350 wep = stringtoint(num);
2351 if (wep >= WNA || wep < 1)
2352 {
2353 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2354 return;
2355 }
2356
2357 p = user->stats;
2358
2359 if (p->armor != 0)
2360 notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
2361 else if (p->gold < prices[wep - 1])
2362 notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
2363 else
2364 {
2365 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
2366 p->armor = wep;
2367 p->gold -= prices[wep - 1];
2368 }
2369 }
2370 }
2371 else if (stricmp(cmd, "SELL" ) == 0)
2372 {
2373 p = user->stats;
2374
2375 if (stricmp(item, "WEAPON") == 0)
2376 {
2377 if (p->weapon == 0)
2378 {
2379 notice(s_GameServ, u, "You want me to chop off your hands?");
2380 return;
2381 }
2382 else if (p->gold == 2000000000)
2383 {
2384 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2385 p->weapon = 0;
2386 }
2387 else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
2388 {
2389 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2390 notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
2391 p->gold = 2000000000;
2392 p->weapon = 0;
2393 }
2394 else
2395 {
2396 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
2397 p->gold += (prices[p->weapon - 1] / 2);
2398 p->weapon = 0;
2399 }
2400 }
2401 else if (stricmp(item, "ARMOR") == 0)
2402 {
2403 p = user->stats;
2404
2405 if (p->armor == 0)
2406 {
2407 notice(s_GameServ, u, "I don't think you can be any more naked...");
2408 return;
2409 }
2410 if (p->gold == 2000000000)
2411 {
2412 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2413 p->armor = 0;
2414 }
2415 else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
2416 {
2417 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2418 notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
2419 p->gold = 2000000000;
2420 p->armor = 0;
2421 }
2422 else
2423 {
2424 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
2425 (prices[p->armor - 1] / 2));
2426
2427 p->gold += (prices[p->armor - 1] / 2);
2428 p->armor = 0;
2429 }
2430 }
2431 else
2432 {
2433 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2434 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2435 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2436 }
2437 }
2438 else
2439 {
2440 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2441 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2442 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2443 return;
2444 }
2445 }
2446 void do_inventory(char *u)
2447 {
2448 aClient *user;
2449
2450 if (!(user = find(u)))
2451 {
2452 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2453 return;
2454 }
2455 else if (isIgnore(user))
2456 {
2457 #ifdef DEBUGMODE
2458 log("Ignoring %s.", user->getNick());
2459 #endif
2460 return;
2461 }
2462 else if (!is_playing(user))
2463 {
2464 notice(s_GameServ, u, "You must be playing to check your inventory!");
2465 return;
2466 }
2467 updateTS(user->stats);
2468 showinventory(user, user);
2469 }
2470 void showinventory(aClient *from, aClient *to)
2471 {
2472 char *nick = to->getNick();
2473
2474 if (!to)
2475 to = from;
2476 if (is_playing(from))
2477 {
2478 Pouch *p = &from->stats->inventory;
2479 notice(s_GameServ, nick, "Inventory for %s:", from->stats->name);
2480 notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
2481 notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
2482 notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
2483 notice(s_GameServ, nick, " HP Potions: %d", p->HP());
2484 }
2485 }
2486 void do_tavern(char *u)
2487 {
2488 char *cmd = strtok(NULL, " ");
2489 long int price;
2490
2491 aClient *user;
2492 Player *p;
2493
2494 if (!(user = find(u)))
2495 {
2496 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2497 return;
2498 }
2499 else if (isIgnore(user))
2500 {
2501 #ifdef DEBUGMODE
2502 log("Ignoring %s.", user->getNick());
2503 #endif
2504 return;
2505 }
2506 else if (!is_playing(user))
2507 {
2508 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2509 return;
2510 }
2511 else if (is_fighting(user))
2512 {
2513 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2514 return;
2515 }
2516
2517 updateTS(user->stats);
2518 p = user->stats;
2519
2520 if (!cmd)
2521 {
2522 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
2523 notice(s_GameServ, u, "Your commands:");
2524 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2525 notice(s_GameServ, u, "What'll it be?");
2526 }
2527 else if (stricmp(cmd, "LIST") == 0)
2528 {
2529 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2530 notice(s_GameServ, u, "1. Healing Potions for %ld Gold",
2531 1000 * p->level * 4);
2532 notice(s_GameServ, u, "2. Strength Potions for %ld Gold",
2533 2500 * p->level * 4);
2534 notice(s_GameServ, u, "3. Defense Potions for %ld Gold",
2535 3000 * p->level * 4);
2536 notice(s_GameServ, u, "4. HP Potions for %ld Gold",
2537 2000 * p->level * 4);
2538 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2539 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2540 }
2541 else if (stricmp(cmd, "BUY") == 0)
2542 {
2543 char *chnum = strtok(NULL, " ");
2544
2545 if (!chnum)
2546 {
2547 notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
2548 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
2549 return;
2550 }
2551 int num = stringtoint(chnum);
2552
2553 if (num < 1 || num > 4)
2554 {
2555 notice(s_GameServ, u, "Invalid Choice!");
2556 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2557 notice(s_GameServ, u, "1. Healing Potions for %ld Gold",
2558 1000 * p->level * 4);
2559 notice(s_GameServ, u, "2. Strength Potions for %ld Gold",
2560 2500 * p->level * 4);
2561 notice(s_GameServ, u, "3. Defense Potions for %ld Gold",
2562 3000 * p->level * 4);
2563 notice(s_GameServ, u, "4. HP Potions for %ld Gold",
2564 2000 * p->level * 4);
2565 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2566 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2567 return;
2568 }
2569 switch(num)
2570 {
2571 case 1:
2572 price = (1000 * p->level * 4);
2573 if (p->gold >= price)
2574 {
2575 notice(s_GameServ, u, "One healing potion coming right up!");
2576 p->inventory.incHealing();
2577 p->gold -= price;
2578 }
2579 else
2580 notice(s_GameServ, u, "You don't have enough gold!");
2581 break;
2582 case 2:
2583 price = 2500 * p->level * 4;
2584 if (p->gold >= price)
2585 {
2586 notice(s_GameServ, u, "One strength boost coming right up!");
2587 p->inventory.incStrength();
2588 p->gold -= price;
2589 }
2590 else
2591 notice(s_GameServ, u, "You don't have enough gold!");
2592 break;
2593 case 3:
2594 price = 3000 * p->level * 4;
2595 if (p->gold >= price)
2596 {
2597 notice(s_GameServ, u, "One defense boost coming right up!");
2598 p->inventory.incDefense();
2599 p->gold -= price;
2600 }
2601 else
2602 notice(s_GameServ, u, "You don't have enough gold!");
2603 break;
2604 case 4:
2605 price = 2000 * p->level * 4;
2606 if (p->gold >= price)
2607 {
2608 notice(s_GameServ, u, "One HP Potion coming right up!");
2609 p->inventory.incHP();
2610 p->gold -= price;
2611 }
2612 else
2613 notice(s_GameServ, u, "You don't have enough gold!");
2614 break;
2615 default:
2616 notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
2617 break;
2618 }
2619 }
2620 else
2621 {
2622 notice(s_GameServ, u, "Improper Syntax.");
2623 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2624 }
2625 }
2626
2627 void do_bank(char *u)
2628 {
2629 char *cmd = strtok(NULL, " ");
2630 char *amount = strtok(NULL, " ");
2631 char *nick = strtok(NULL, " ");
2632
2633 aClient *user;
2634 Player *p;
2635
2636 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
2637 {
2638 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
2639 notice (s_GameServ, u, "BANK BALANCE");
2640 return;
2641 }
2642 else if (!(user = find(u)))
2643 {
2644 notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\
2645 " admin for help");
2646 log("Fatal Error. Couldn't find %s while executing do_bank()", u);
2647 return;
2648 }
2649 else if (isIgnore(user))
2650 {
2651 #ifdef DEBUGMODE
2652 log("Ignoring %s.", user->getNick());
2653 #endif
2654 return;
2655 }
2656 else if (!is_playing(user))
2657 {
2658 notice(s_GameServ, u, "You must be playing to use the bank!");
2659 return;
2660 }
2661 else if (is_fighting(user))
2662 {
2663 notice(s_GameServ, u, "You can't go to the bank during a fight!");
2664 return;
2665 }
2666 updateTS(user->stats);
2667 if (stricmp(cmd, "BALANCE") == 0)
2668 {
2669 showBankBalance(u);
2670 return;
2671 }
2672 else if (!isAlive(user->stats))
2673 {
2674 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2675 return;
2676 }
2677 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2678 {
2679 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2680 return;
2681 }
2682 if (stringtoint(amount) < 0)
2683 {
2684 notice(s_GameServ, u, "Sorry. This bank is not licensed "\
2685 "to handle such sums of cash, noble Lord.");
2686 return;
2687 }
2688 p = user->stats;
2689
2690 if (stricmp(cmd, "DEPOSIT") == 0)
2691 {
2692 if (p->bank == 2000000000)
2693 {
2694 notice(s_GameServ, u, "Your bank account is full, sire!");
2695 return;
2696 }
2697 else if (stricmp(amount, "ALL") == 0)
2698 {
2699 if (2000000000 - p->bank < p->gold)
2700 {
2701 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2702 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
2703 p->gold -= (2000000000 - p->bank);
2704 p->bank = 2000000000;
2705 showBankBalance(u);
2706 }
2707 else
2708 {
2709 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
2710 p->bank += p->gold;
2711 p->gold = 0;
2712 showBankBalance(u);
2713 }
2714 }
2715 else if (stringtoint(amount) > p->gold)
2716 {
2717 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
2718 showBankBalance(u);
2719 return;
2720 }
2721 else
2722 {
2723 if (2000000000 - p->bank < stringtoint(amount))
2724 {
2725 notice(s_GameServ, u, "You don't have room in your account for that much.");
2726 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
2727 p->gold -= (2000000000 - p->bank);
2728 p->bank = 2000000000;
2729 showBankBalance(u);
2730 }
2731 else
2732 {
2733 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2734 p->bank += stringtoint(amount);
2735 p->gold -= stringtoint(amount);
2736 showBankBalance(u);
2737 }
2738 }
2739 }
2740 else if (stricmp(cmd, "WITHDRAW") == 0)
2741 {
2742 if (p->gold == 2000000000)
2743 {
2744 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
2745 showBankBalance(u);
2746 return;
2747 }
2748 else if (stricmp(amount, "ALL") == 0)
2749 {
2750 if (2000000000 - p->gold < p->bank)
2751 {
2752 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2753 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
2754 p->bank -= (2000000000 - p->gold);
2755 p->gold = 2000000000;
2756 showBankBalance(u);
2757 }
2758 else
2759 {
2760 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
2761 p->gold += p->bank;
2762 p->bank = 0;
2763 showBankBalance(u);
2764 }
2765 }
2766 else if (stringtoint(amount) > p->bank)
2767 {
2768 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
2769 showBankBalance(u);
2770 return;
2771 }
2772 else
2773 {
2774 if (2000000000 - p->gold < stringtoint(amount))
2775 {
2776 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2777 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2778 (2000000000 - p->gold));
2779 p->bank -= (2000000000 - p->gold);
2780 p->gold = 2000000000;
2781 showBankBalance(u);
2782 }
2783 else
2784 {
2785 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2786 p->gold += stringtoint(amount);
2787 p->bank -= stringtoint(amount);
2788 showBankBalance(u);
2789 }
2790 }
2791 }
2792
2793 }
2794
2795 void do_dragon(char *u)
2796 {
2797 aClient *user;
2798
2799 if (!(user = find(u)))
2800 {
2801 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2802 return;
2803 }
2804 else if (isIgnore(user))
2805 {
2806 #ifdef DEBUGMODE
2807 log("Ignoring %s.", user->getNick());
2808 #endif
2809 return;
2810 }
2811 else if (!is_playing(user))
2812 {
2813 notice(s_GameServ, u, "You must be playing to fight the dragon!");
2814 return;
2815 }
2816 else if (is_fighting(user))
2817 {
2818 notice(s_GameServ, u, "You are already in a fight. How will you fight the almighty dragon!?");
2819 return;
2820 }
2821 else if (!isAlive(user->stats))
2822 {
2823 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2824 return;
2825 }
2826 else if (user->stats->level < REALLEVELS)
2827 {
2828 notice(s_GameServ, u, "You fool! Only those strong enough "\
2829 "to vanquish any foe should DARE fight the dragon!");
2830 notice(s_GameServ, u, "To put it in terms you can understand: "\
2831 "You are too weak. You must be Level %d!", REALLEVELS);
2832 return;
2833 }
2834
2835 updateTS(user->stats);
2836
2837 Player *p = user->stats;
2838 p->fight = new Monster(&boss);
2839 notice(s_GameServ, u, "You approach the dragon's lair cautiously.");
2840 notice(s_GameServ, u, "The stench of sulfer fills the air as a "\
2841 "deep, red fog rolls in. The air is filled with the "\
2842 "heated mist of deadly fire from beyond the cave "\
2843 "entrance.");
2844 notice(s_GameServ, u, "You adjust your %s, tighten your grip on "\
2845 "your %s, and venture into the hot, dark cave. "\
2846 "You are surprised at the angle of descent as you climb "\
2847 "lower and lower, deeper into the dragon's den.", armors[p->level - 1], weapons[p->level - 1]);
2848 notice(s_GameServ, u, "You come to the end of the cave to find "\
2849 "a tooth. It is a large tooth... bigger than your torso."\
2850 " Suddenly the darkness lifts from the gleam of an eye "\
2851 " staring into your soul! The eye is large... HUGE!");
2852 notice(s_GameServ, u, "Just then you notice the eye begin to "\
2853 "glare orange! The tooth is moving... but it is still too "\
2854 "dark for you to make out.... THE DRAGON! You see it!");
2855 display_monster(u);
2856 }
2857
2858 void do_master(char *u)
2859 {
2860 aClient *user;
2861
2862
2863 if (!(user = find(u)))
2864 {
2865 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2866 return;
2867 }
2868 else if (isIgnore(user))
2869 {
2870 #ifdef DEBUGMODE
2871 log("Ignoring %s.", user->getNick());
2872 #endif
2873 return;
2874 }
2875 else if (!is_playing(user))
2876 {
2877 notice(s_GameServ, u, "You must be playing to see your master!");
2878 return;
2879 }
2880 else if (is_fighting(user))
2881 {
2882 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
2883 return;
2884 }
2885 else if (!isAlive(user->stats))
2886 {
2887 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2888 return;
2889 }
2890
2891 updateTS(user->stats);
2892
2893 char *cmd = strtok(NULL, " ");
2894 Player *p = user->stats;
2895 long int need = 0;
2896
2897 if (seenMaster(p))
2898 {
2899 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
2900 return;
2901 }
2902
2903 if (cmd != NULL)
2904 {
2905 switch(p->level)
2906 {
2907 case 1:
2908 need = 200;
2909 break;
2910 case 2:
2911 need = 800;
2912 break;
2913 case 3:
2914 need = 2000;
2915 break;
2916 case 4:
2917 need = 8000;
2918 break;
2919 case 5:
2920 need = 20000;
2921 break;
2922 case 6:
2923 need = 80000;
2924 break;
2925 case 7:
2926 need = 200000;
2927 break;
2928 case 8:
2929 need = 800000;
2930 break;
2931 case 9:
2932 need = 2000000;
2933 break;
2934 case 10:
2935 need = 8000000;
2936 break;
2937 case 11:
2938 need = 20000000;
2939 break;
2940
2941 case REALLEVELS:
2942 need = p->exp + 1;
2943 notice(s_GameServ, u, "You are at level %d. You are the master. What's left? The DRAGON!", REALLEVELS);
2944 return;
2945 break;
2946 default:
2947 need = p->exp + 1; // Unknown level... don't let them fight a fake master!
2948 break;
2949 }
2950 }
2951 else
2952 {
2953 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2954 return;
2955 }
2956
2957 if (stricmp(cmd, "FIGHT") == 0)
2958 {
2959 if (p->exp >= need)
2960 {
2961 setMaster(p);
2962 see_master(u);
2963 }
2964 else
2965 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.", masters[p->level - 1]->name, (need - p->exp));
2966 return;
2967 }
2968 else if (stricmp(cmd, "QUESTION") == 0)
2969 {
2970 if (p->exp >= need)
2971 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);
2972 else
2973 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", masters[p->level - 1]->name, p->name);
2974
2975 return;
2976 }
2977 else
2978 {
2979 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2980 }
2981 }
2982
2983 void see_master(char *u)
2984 {
2985 aClient *user;
2986
2987 if (!(user = find(u)))
2988 {
2989 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2990 return;
2991 }
2992
2993 if (!is_fighting(user) && is_playing(user))
2994 {
2995 Player *p = user->stats;
2996 p->master = new Monster(masters[p->level - 1]);
2997 p->fight = p->master;
2998 display_monster(u); // Since master is the same structure, use this function
2999 }
3000 }
3001
3002 void showBankBalance(const char *u)
3003 {
3004 aClient *user;
3005 Player *p;
3006
3007 if (!(user = find(u)))
3008 return;
3009
3010 p = user->stats;
3011
3012 if (!p)
3013 return;
3014
3015 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->bank, p->gold);
3016
3017 }
3018
3019 void refreshall()
3020 {
3021 ListNode <aClient> *it;
3022 Player *p;
3023 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3024 {
3025 it = players[x].First();
3026
3027 while (it)
3028 {
3029 p = it->getData()->stats;
3030 refresh(p);
3031 it = it->Next();
3032 }
3033 }
3034 }
3035
3036 void refresh(Player *p)
3037 {
3038 if (!p)
3039 return;
3040
3041 if (p->hp < p->maxhp)
3042 p->hp = p->maxhp;
3043 p->forest_fights = forestfights;
3044 p->player_fights = 3;
3045 setAlive(p);
3046 clearMaster(p);
3047 }
3048
3049 void do_refresh(char *u)
3050 {
3051 char *nick = strtok(NULL, " ");
3052 aClient *user;
3053
3054 if (!(user = find(u)))
3055 {
3056 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3057 log("Error: aClient not found: %s", u);
3058 return;
3059 }
3060 else if (isIgnore(user))
3061 {
3062 #ifdef DEBUGMODE
3063 log("Ignoring %s.", user->getNick());
3064 #endif
3065 return;
3066 }
3067 else if (!isAdmin(user))
3068 {
3069 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3070 return;
3071 }
3072 if (!nick)
3073 {
3074 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
3075 return;
3076 }
3077 else if (stricmp(nick, "ALL") == 0)
3078 {
3079 notice(s_GameServ, u, "Refreshing everyone's stats!");
3080 refreshall();
3081 }
3082 else if ((user = findplayer(nick)))
3083 {
3084 if (is_playing(user))
3085 {
3086 #ifdef P10
3087 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
3088 #else
3089 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
3090 #endif
3091 refresh(user->stats);
3092 }
3093 else
3094 {
3095 #ifdef P10
3096 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
3097 #else
3098 notice(s_GameServ, u, "%s is not playing.", user->getNick());
3099 #endif
3100 }
3101 }
3102 else
3103 {
3104 notice(s_GameServ, u, "Nick %s not found.", nick);
3105 return;
3106 }
3107 }
3108
3109
3110 void resetall()
3111 {
3112 ListNode <aClient> *it;
3113 Player *p;
3114
3115 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3116 {
3117 it = players[x].First();
3118
3119 while (it)
3120 {
3121 p = it->getData()->stats;
3122 reset(p);
3123 it = it->Next();
3124 }
3125 }
3126 }
3127
3128 void reset(Player *p)
3129 {
3130 char *myname;
3131 myname = new char[strlen(p->name)];
3132 strcpy(myname, p->name);
3133 if (!p)
3134 return;
3135
3136 p->reset();
3137 strcpy(p->name, myname);
3138 delete [] myname;
3139 }
3140
3141 void updateTS(Player *p)
3142 {
3143 if (!p)
3144 return;
3145
3146 #ifdef DEBUGMODE
3147 log("Old timestamp for %s: %ld", p->name, p->lastcommand);
3148 #endif
3149 p->lastcommand = time(NULL);
3150 #ifdef DEBUGMODE
3151 log("New timestamp for %s: %ld", p->name, p->lastcommand);
3152 #endif
3153
3154 }
3155
3156 bool timedOut(Player *p)
3157 {
3158 if (!p)
3159 return false;
3160 else if (p->lastcommand == 0)
3161 return false;
3162 else
3163 {
3164 if ((time(NULL) - p->lastcommand) >= maxidletime)
3165 return true;
3166
3167 return false;
3168 }
3169 }
3170
3171 void timeOutEvent(Player *p)
3172 {
3173 aClient *user = findplayer(p->name);
3174
3175 if (!user || !p->client) // then they're not playing
3176 return;
3177
3178 char *nick = user->getNick();
3179
3180 if (player_fight(user) && isYourTurn(p))
3181 {
3182 // Check to see if they were the idler or if it was the other
3183 // person
3184 if (p->lastcommand != p->battle->stats->lastcommand)
3185 {
3186 // This person's last command was given earlier,
3187 // so this person is the idler
3188 notice(s_GameServ, nick, "You timed out "\
3189 "during a fight. You lose your turn!");
3190 notice(s_GameServ, p->battle->getNick(),
3191 "%s hesitated for too long. Your move.", p->name);
3192 clearYourTurn(p);
3193 setYourTurn(p->battle->stats);
3194
3195 // Update the TS for both players to give them another
3196 // Chance to wake up, but if the other player doesn't
3197 // Attack now, they both get logged out.
3198 updateTS(p);
3199 p->battle->stats->lastcommand = p->lastcommand;
3200 display_players(p->battle);
3201 return;
3202 }
3203 else
3204 {
3205 notice(s_GameServ, p->battle->getNick(),
3206 "You and %s timed out at the same time."\
3207 " Don't fight if you're just going to "\
3208 "sit there!", p->name);
3209 notice(s_GameServ, user->getNick(),
3210 "You and %s timed out at the same time."\
3211 " Don't fight if you're just going to "\
3212 "sit there!", p->battle->stats->name);
3213 logout(p->battle);
3214 logout(user);
3215 return;
3216 }
3217 }
3218 else if (!player_fight(user))
3219 {
3220 if (isAlive(user->stats) && user->stats->gold > 0)
3221 {
3222 // Place fun stuff here :)
3223 int randnum = 1 + rand() % 100; // 1-100
3224 #define GSN(s) notice(s_GameServ, nick, s)
3225 #define GSN2(s, f) notice(s_GameServ, nick, s, f)
3226
3227 if (randnum < 50)
3228 {
3229 // 35-100% of your gold goes pffft - kain
3230 int stolen = (35 + (rand() % 66)) * user->stats->gold / 100;
3231
3232 GSN("You stop for a moment to rest on the "\
3233 "street corner. All of a sudden, you "\
3234 "are ambushed from all sides by a hoarde "\
3235 "of knife wielding thugs.");
3236 GSN2("The thugs beat you into utter submission "\
3237 "and steal %d gold from you!", stolen);
3238 user->stats->gold -= stolen;
3239 }
3240 else if (randnum >= 50 && randnum < 75)
3241 {
3242 // 25-65% of your gold goes pffft - kain
3243 int stolen = (25 + (rand() % 41)) * user->stats->gold / 100;
3244 GSN("While dilly dallying around, you lose "\
3245 "your sense of time. Little did you know, "\
3246 "but thieves lifted your gold while you "\
3247 "weren't watching.");
3248 GSN2("Better luck next time... you lose %d gold", stolen);
3249 user->stats->gold -= stolen;
3250 }
3251 else if (randnum >= 75)
3252 {
3253 // 25-75% of your gold goes pffft - kain
3254 int stolen = (25 + (rand() % 51)) * user->stats->gold / 100;
3255 GSN("Good grief! A gaggle of gooey green ghostlike "\
3256 "goblins grabbed your gold!");
3257 GSN2("They stole %d gold from you!", stolen);
3258 user->stats->gold -= stolen;
3259 }
3260 }
3261
3262 // Always log out the user
3263 logout(user);
3264 }
3265 }
3266
3267 void do_reset(char *u)
3268 {
3269 char *nick = strtok(NULL, " ");
3270 aClient *user;
3271
3272 if (!(user = find(u)))
3273 {
3274 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
3275 log("Error: aClient not found: %s", u);
3276 return;
3277 }
3278 else if (!isAdmin(user))
3279 {
3280 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3281 return;
3282 }
3283
3284 if (!nick)
3285 {
3286 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
3287 return;
3288 }
3289 else if (stricmp(nick, "ALL") == 0)
3290 {
3291 notice(s_GameServ, u, "Resetting everyone's stats!");
3292 resetall();
3293 }
3294 else if ((user = findplayer(nick)))
3295 {
3296 if (is_playing(user))
3297 {
3298 #ifdef P10
3299 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
3300 #else
3301 notice(s_GameServ, u, "Resetting %s.", user->getNick());
3302 #endif
3303 reset(user->stats);
3304 }
3305 else
3306 {
3307 notice(s_GameServ, u, "Resetting %s", user->stats->name);
3308 reset(user->stats);
3309 }
3310 }
3311 else
3312 {
3313 notice(s_GameServ, u, "Nick %s not found.", nick);
3314 return;
3315 }
3316 }
3317
3318 void do_help(char *u)
3319 {
3320 char *cmd = strtok(NULL, " ");
3321
3322 display_help(u, cmd);
3323 }
3324
3325 void display_help(char *u, char *file)
3326 {
3327 ifstream infile;
3328 char *buf;
3329
3330 if (!file)
3331 {
3332 infile.open("helpfiles/help");
3333 if (infile.fail())
3334 {
3335 log("Error opening helpfiles/help");
3336 notice(s_GameServ, u, "Error opening helpfiles/help");
3337 return;
3338 }
3339 buf = new char[1024];
3340 while(infile.getline(buf, 1024))
3341 {
3342 // Written this way, it will process %S in the helpfiles
3343 // Instead of notice(s_GameServ, u, "%s", buf);
3344 notice(s_GameServ, u, buf);
3345 }
3346
3347 // Minor recursion
3348 aClient *user = find(u);
3349 if (user && isAdmin(user))
3350 display_help(u, "admin_commands");
3351 }
3352 else
3353 {
3354 char *filename;
3355 filename = new char[strlen(file) + 11];
3356 strcpy(filename, "helpfiles/");
3357 strcat(filename, file);
3358
3359 for (unsigned int x = 10; x < strlen(filename); x++)
3360 filename[x] = tolower(filename[x]);
3361
3362 infile.open(filename);
3363 delete [] filename;
3364 if (infile.fail())
3365 {
3366 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
3367 return;
3368 }
3369 buf = new char[1024];
3370 while(infile.getline(buf, 1024))
3371 {
3372 // Written this way, it will process %S in the helpfiles
3373 // Instead of notice(s_GameServ, u, "%s", buf);
3374 notice(s_GameServ, u, buf);
3375 }
3376 }
3377 infile.close();
3378 delete [] buf;
3379 }
3380
3381 void do_admin(char *u)
3382 {
3383 aClient *user;
3384 char *pass = strtok(NULL, " ");
3385
3386 if (!(user = find(u)))
3387 {
3388 log("Error: aClient not found: %s", u);
3389 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
3390 return;
3391 }
3392
3393 if (!pass)
3394 {
3395 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
3396 return;
3397 }
3398
3399 if (isAdmin(user))
3400 {
3401 notice(s_GameServ, u, "You already have administrator privledges.");
3402 return;
3403 }
3404 else if (strcmp(pass, adminpass) == 0)
3405 {
3406 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
3407 setAdmin(user);
3408 #ifdef P10
3409 log("%s became an administrator.", user->getRealNick());
3410 #else
3411 log("%s became an administrator.", user->getNick());
3412 #endif
3413 }
3414 else
3415 {
3416 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
3417 return;
3418 }
3419 }
3420
3421 bool load_levels()
3422 {
3423 char *filename;
3424 filename = new char[256];
3425
3426 for (int x = 1; x <= LEVELS; x++)
3427 {
3428 sprintf(filename, "data/levels/level%d.dat", x);
3429 if (levels[x - 1].loadLevel(filename) == false)
3430 return false;
3431 }
3432
3433 delete []filename;
3434 return true;
3435 }
3436 bool load_monsters()
3437 {
3438 char *filename;
3439 ifstream infile;
3440 char *buf;
3441 buf = new char[2048];
3442
3443 for (int level = 1; level <= LEVELS; level++)
3444 {
3445 filename = new char[256];
3446 sprintf(filename, "data/monsters/level%d.dat", level);
3447 infile.open(filename);
3448
3449 if (!infile)
3450 {
3451 log("Error opening %s", filename);
3452 return false;
3453 }
3454
3455 #ifdef DEBUGMODE
3456 log("Loading monsters from %s", filename);
3457 #endif
3458
3459 while (infile.getline(buf, 2048))
3460 {
3461 if (buf[0] == '^')
3462 break;
3463 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
3464 continue;
3465 Monster *temp;
3466 temp = new Monster;
3467
3468 strcpy(temp->name, strtok(buf, "~"));
3469 strcpy(temp->weapon, strtok(NULL, "~"));
3470 strcpy(temp->death, strtok(NULL, "~"));
3471
3472 levels[level - 1].monsters.insertAtBack_RLN(temp);
3473 delete temp;
3474 }
3475 delete [] filename;
3476 infile.close();
3477 }
3478 delete [] buf;
3479 return true;
3480 }