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