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