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