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