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