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