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