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