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