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