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