]> jfr.im git - irc/gameservirc.git/blame - gameserv/gameserv.cpp
changed the version number to 1.2.6
[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
389 sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->weapon]);
390 space = spaces(strlen(buf), " ");
391 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
392 buf, space, ni->stats->defense + arbonus[ni->stats->armor]);
1cf88153 393 delete [] space;
85ce9d3e 394
395 sprintf(buf, "Armor: %s", armors[ni->stats->armor]);
396 space = spaces(strlen(buf), " ");
397 notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
398 weapons[ni->stats->weapon]);
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
cbd4ede4 988 target->stats->weapon = stringtoint(cmd2);
6e147995 989
990 if (target->stats->weapon < 0)
991 target->stats->weapon = 0;
992 else if (target->stats->weapon >= WNA)
993 target->stats->weapon = WNA - 1;
cbd4ede4 994 notice(s_GameServ, u, "Weapon set to %s", weapons[target->stats->weapon]);
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 }
cbd4ede4 1012 target->stats->armor = stringtoint(cmd2);
6e147995 1013
1014 if (target->stats->armor < 0)
1015 target->stats->armor = 0;
1016 else if (target->stats->armor >= WNA)
1017 target->stats->armor = WNA - 1;
1018
cbd4ede4 1019 notice(s_GameServ, u, "Armor set to %s", armors[target->stats->armor]);
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 }
1290 else if (!password)
85ce9d3e 1291 {
e1c41a84 1292 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
85ce9d3e 1293 }
03e0a9d8 1294 else if ((user = findplayer(name)))
1295 {
1296 notice(s_GameServ, u, "%s is already registered!", name);
1297 notice(s_GameServ, u, "Choose another name!");
1298 }
448a1531 1299 else if (!(user = find(u)))
1300 {
1301 log("Fatal Error: Couldn't find %s in the clients list", u);
1302 }
1303 else if (isIgnore(user))
1304 {
1305 #ifdef DEBUGMODE
1306 log("Ignoring %s.", user->getNick());
1307 #endif
1308 return;
1309 }
1310 else
85ce9d3e 1311 {
3f243b0b 1312 if (!is_playing(user))
85ce9d3e 1313 {
ae2685f6 1314 ListNode<aClient> *temp;
85ce9d3e 1315 user->stats = new Player(user);
85bcf836 1316 user->stats->client = user; // Set the backwards pointer
ae2685f6 1317 user->stats->reset(); // set the user up
1563e73b 1318 user->stats->setPassword(password);
ddef84f1 1319 user->stats->name = name;
448a1531 1320 unsigned long hv = iHASH((unsigned char *) name);
40251952 1321 updateTS(user->stats);
ae2685f6 1322 temp = players[hv].insertAtBack_RLN(user);
1323 temp->setPtr(user); // This is an extra step, but necessary for now
1324
14e24ba1 1325 // Update the last login time
1326 user->stats->lastlogin = time(NULL);
1327
5c449fde 1328 notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name.c_str(), password);
c7340cbd 1329 notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!");
5c449fde 1330 log("Nickname %s registered player %s.", u, user->stats->name.c_str());
3f243b0b 1331 setPlaying(user); // set the playing flag
85ce9d3e 1332 }
1333 else
1334 {
1335 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
1336 }
1337 }
1338}
1339
1340void do_identify(char *u)
1341{
0a1518fa 1342 char *password, *name;
1343 aClient *user, *p;
1344 name = strtok(NULL, " ");
85ce9d3e 1345 password = strtok(NULL, " ");
0a1518fa 1346 if (!password || !name)
85ce9d3e 1347 {
0a1518fa 1348 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
85ce9d3e 1349 }
448a1531 1350 else if (!(user = find(u)))
5d04eb42 1351 {
1352 notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, ""));
1353 log("Error: aClient not found: %s", u);
1354 }
448a1531 1355 else if (isIgnore(user))
1356 {
1357 #ifdef DEBUGMODE
1358 log("Ignoring %s.", user->getNick());
1359 #endif
1360 return;
1361 }
0a1518fa 1362 else if (!(p = findplayer(name)) || !p->stats)
1363 notice(s_GameServ, u, "Player %s not found", name);
b0359af9 1364 else if (is_playing(user))
1365 {
1366 notice(s_GameServ, u, "You are already playing!");
1367 }
85bcf836 1368 else if (p->stats->client != NULL && !isAdmin(user))
1579dfa2 1369 {
1370 notice(s_GameServ, u, "That player has already identified.");
1579dfa2 1371 }
20d5d721 1372 else if (!check_password(name, password) && !isAdmin(user))
85ce9d3e 1373 {
0a1518fa 1374 notice(s_GameServ, u, "Password incorrect");
85ce9d3e 1375 }
1579dfa2 1376 else {
b0359af9 1377 ListNode<aClient> *temp;
5c449fde 1378 unsigned long hv = iHASH((unsigned char *) p->stats->name.c_str());
7996e5fd 1379 temp = players[hv].Find(p);
b0359af9 1380 if (!temp)
85ce9d3e 1381 {
b0359af9 1382 notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s",
1383 strtok(NULL, ""));
1384 return;
85ce9d3e 1385 }
5c449fde 1386 user->stats = new Player(p->stats->name);
b0359af9 1387 #ifdef DEBUGMODE
1388 log("Setting data for identified");
1389 #endif
0b6098d5 1390 user->stats->setData(p->stats);
448a1531 1391 user->stats->client = user;
40251952 1392 updateTS(user->stats);
1393
b0359af9 1394
1395 #ifdef DEBUGMODE
5c449fde 1396 log("Player %s IRC: %s Identified", user->stats->name.c_str(),
448a1531 1397 user->getNick());
b0359af9 1398 #endif
1399
3f243b0b 1400 setPlaying(user); // set the playing flag
1401
b0359af9 1402 temp->setPtr(user);
14e24ba1 1403
1404 // Update the last login time
1405 user->stats->lastlogin = time(NULL);
1406
c260a8d7 1407 notice(s_GameServ, u, "Password Accepted. Identified.");
1408 showNews(u, todaysnews);
85ce9d3e 1409 }
1410}
1411
1412void do_stats(char *u)
1413{
1414 char *nick;
73c71976 1415 aClient *user;
85ce9d3e 1416
1417 nick = strtok(NULL, " ");
85ce9d3e 1418
448a1531 1419 if (!(user = find(u)))
73c71976 1420 {
448a1531 1421 log("Fatal Error: %s not found in client list", u);
1422 return;
1423 }
1424 else if (isIgnore(user))
1425 {
1426 #ifdef DEBUGMODE
1427 log("Ignoring %s.", user->getNick());
1428 #endif
1429 return;
1430 }
1431 else if (!nick)
1432 {
1433 if (!is_playing(user))
73c71976 1434 {
1435 notice(s_GameServ, u, "You're not playing, so you have no stats!");
1436 return;
1437 }
1438 else
40251952 1439 {
1440 updateTS(user->stats);
5c449fde 1441 showstats(u, user->stats->name.c_str());
40251952 1442 }
73c71976 1443 }
85ce9d3e 1444 else
1445 showstats(u, nick);
1446}
448a1531 1447
5c449fde 1448bool load_masters()
ad7dfaa0 1449{
8e800549 1450 ifstream infile(masterdata);
5c449fde 1451 char *buf;
1452 int l = 0;
1453 buf = new char[1024];
5d04eb42 1454
5c449fde 1455 if (infile.fail())
1456 {
8e800549 1457 log("Error opening %s", masterdata);
5c449fde 1458 return false;
1459 }
c8ada07e 1460
5d04eb42 1461 #ifdef DEBUGMODE
8e800549 1462 log("Loading masters from %s", masterdata);
5d04eb42 1463 #endif
1464
8e800549 1465 for (l = 0; l < LEVELS - 1; l++)
5c449fde 1466 {
1467 infile.getline(buf, 1024, '\n');
1468
1469 log("%s", buf);
1470 if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r')
1471 {
1472 l--;
1473 continue;
1474 }
1475 else if (buf[0] == '^')
1476 break;
1477
1478 Monster *master = &levels[l].master;
1479
1480 char *name, *weapon, *strength, *gold, *exp, *maxhp, *death;
1481
1482
1483 name = strtok(buf, "~");
1484 weapon = strtok(NULL, "~");
1485 strength = strtok(NULL, "~");
1486 gold = strtok(NULL, "~");
1487 exp = strtok(NULL, "~");
1488 maxhp = strtok(NULL, "~");
1489 death = strtok(NULL, "~");
1490
1491 master->name = name;
1492 master->weapon = weapon;
1493 master->strength = stringtoint(strength);
1494 master->gold = stringtoint(gold);
1495 master->exp = stringtoint(exp);
1496 master->maxhp = stringtoint(maxhp);
1497 master->hp = master->maxhp;
1498 master->death = death;
1499 }
1500
1501 delete []buf;
1502
8e800549 1503 if (l < LEVELS - 1) // We didn't load a master for every level - check data/masters.dat
5c449fde 1504 return false;
1505 else
1506 return true;
ad7dfaa0 1507}
85ce9d3e 1508
c8ada07e 1509void delete_monsters()
1510{
1511 for (int x = 0; x < LEVELS; x++)
42106907 1512 levels[x].monsters.deleteNodes();
c8ada07e 1513}
1514
85ce9d3e 1515void display_monster(char *u)
1516{
1517 if (is_playing(u))
1518 {
1519 aClient *user = find(u);
1520 Player *ni = user->stats;
1521
1522 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->hp);
5c449fde 1523 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name.c_str(), ni->fight->hp);
85ce9d3e 1524 notice(s_GameServ, u, "Here are your commands:");
1525 notice(s_GameServ, u, "/msg %S attack");
1526 notice(s_GameServ, u, "/msg %S run");
1527 notice(s_GameServ, u, "What will you do?");
1528 }
1529}
1530
1531void display_players(char *u)
1532{
85bcf836 1533 aClient *user;
1534 if (!(user = find(u)))
85ce9d3e 1535 {
85bcf836 1536 log("Fatal error in display_players(): Couldn't find %s", u);
83cf716f 1537 }
85bcf836 1538 else
1539 display_players(user);
83cf716f 1540}
85bcf836 1541
83cf716f 1542void display_players(aClient *user)
1543{
1544 char *u = user->getNick();
1545 if (is_playing(user) && player_fight(user))
1546 {
1547 aClient *battle = user->stats->battle;
1548 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", user->stats->hp);
5c449fde 1549 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name.c_str(), battle->stats->hp);
83cf716f 1550 notice(s_GameServ, u, "Here are your commands:");
1551 notice(s_GameServ, u, "/msg %S attack");
1552 notice(s_GameServ, u, "/msg %S run");
85ce9d3e 1553 notice(s_GameServ, u, "What will you do?");
1554 }
1555}
1556
1557
1558bool is_playing(char *u)
1559{
1560 aClient *user;
1561 if (!(user = find(u)))
85ce9d3e 1562 return false;
85ce9d3e 1563 else
40251952 1564 return is_playing(user);
85ce9d3e 1565}
1566
1af35752 1567bool is_playing(aClient *user)
1568{
03a4bdbb 1569 if (user->stats == NULL)
f1ab3b7c 1570 {
03a4bdbb 1571 return false;
f1ab3b7c 1572 }
03a4bdbb 1573 else if (user->stats->client == NULL)
f1ab3b7c 1574 {
03a4bdbb 1575 return false;
f1ab3b7c 1576 }
3f243b0b 1577 else if (!FL_is_playing(user))
1578 {
1579 return false;
1580 }
03a4bdbb 1581 else
1582 return true;
1af35752 1583}
1584
85ce9d3e 1585bool is_fighting(char *u)
1586{
1587 aClient *user;
1588
1589 if (!(user = find(u)))
85ce9d3e 1590 return false;
85ce9d3e 1591 else
40251952 1592 return is_fighting(user);
85ce9d3e 1593}
40251952 1594
1af35752 1595bool is_fighting(aClient *user)
1596{
1597 if (!is_playing(user))
1598 return false;
1599 else
448a1531 1600 return player_fight(user) || master_fight(user) || user->stats->fight != NULL;
1af35752 1601}
85ce9d3e 1602
1603bool player_fight(char *u)
1604{
1605 aClient *user;
1606
1607 if (!(user = find(u)))
1608 return false;
40251952 1609 else
1610 return player_fight(user);
85ce9d3e 1611}
448a1531 1612
1af35752 1613bool player_fight(aClient *user)
1614{
448a1531 1615 if (!is_playing(user))
1af35752 1616 return false;
9fe7af4c 1617 else if (user->stats->battle != NULL && is_playing(user->stats->battle))
a51f0dcd 1618 {
1619 return user->stats->battle->stats != NULL;
1620 }
1621 return false;
1af35752 1622}
85ce9d3e 1623
1624bool master_fight(char *u)
1625{
1626 aClient *user;
1627
1628 if (!(user = find(u)))
1629 return false;
85ce9d3e 1630 else
40251952 1631 return master_fight(user);
85ce9d3e 1632}
40251952 1633
1af35752 1634bool master_fight(aClient *user)
85ce9d3e 1635{
1af35752 1636 if (!is_playing(user))
1637 return false;
1638 else
1639 return user->stats->master != NULL;
85ce9d3e 1640}
1641
fd270bdd 1642bool dragon_fight(char *u)
1643{
1644 aClient *user;
1645 if (!(user = find(u)))
1646 return false;
1647 else
1648 return dragon_fight(user);
1649}
1650
1651bool dragon_fight(aClient *user)
1652{
1653 if (!is_playing(user))
1654 return false;
1655 else
8e800549 1656 return (isDragonFight(user->stats));
fd270bdd 1657}
85ce9d3e 1658void do_fight(char *u)
1659{
1660 aClient *ni, *battle;
1661
1662 char *nick = strtok(NULL, " ");
1663
1664 if (!nick)
1665 {
1666 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
40251952 1667 return;
85ce9d3e 1668 }
1669 else if (!(ni = find(u)))
1670 {
1af35752 1671 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
40251952 1672 return;
85ce9d3e 1673 }
448a1531 1674 else if (isIgnore(ni))
1675 {
1676 #ifdef DEBUGMODE
1677 log("Ignoring %s.", ni->getNick());
1678 #endif
1679 return;
1680 }
71098075 1681 else if (!is_playing(ni))
85ce9d3e 1682 {
71098075 1683 notice(s_GameServ, u, "You are not playing!");
40251952 1684 return;
85ce9d3e 1685 }
40251952 1686
1687 updateTS(ni->stats);
1688
1689 if (ni->stats->player_fights <= 0)
3348c24e 1690 {
1691 ni->stats->player_fights = 0; // just to be safe
1692 notice(s_GameServ, u, "You are out of player fights for the "\
1693 "day. You have to wait until tomorrow!");
1694 }
71098075 1695 else if (!(battle = findplayer(nick)))
b0359af9 1696 {
1697 notice(s_GameServ, u, "Player %s not found!", nick);
1698 }
448a1531 1699 else if (!isAlive(ni->stats))
1700 {
1701 notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!");
1702 }
b0359af9 1703 else if (!is_playing(battle))
85ce9d3e 1704 {
71098075 1705 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
85ce9d3e 1706 }
b478c0df 1707
1708/* offline fighting not available yet
1709 else if (!(fight = finduser(nick)))
1710 {
1711 ni->stats->battle = battle;
1712 battle->battle = ni;
1713 setYourTurn(ni->stats);
1714 clearYourTurn(battle->stats);
1715
1716 notice(s_GameServ, u, "You decide to fight %s while they're "\
1717 "not in the realm!",
5c449fde 1718 battle->stats->name.c_str());
b478c0df 1719 display_players(u);
1720 }
1721*/
5c449fde 1722 else if (stricmp(ni->stats->name.c_str(), battle->stats->name.c_str()) == 0)
b0359af9 1723 {
1724 notice(s_GameServ, u, "Are you trying to commit suicide!?");
1af35752 1725 }
da5cf17a 1726 else if (!isAlive(battle->stats))
1727 {
1728 notice(s_GameServ, u, "They are dead. Cannot fight dead players!");
da5cf17a 1729 }
1902338e 1730 else if (player_fight(battle))
1731 {
5c449fde 1732 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name.c_str(), battle->stats->battle->stats->name.c_str());
1902338e 1733 }
448a1531 1734 else if (master_fight(battle))
1735 {
5c449fde 1736 notice(s_GameServ, u, "%s is fighting their master!", battle->stats->name.c_str());
448a1531 1737 }
1902338e 1738 else if (is_fighting(battle))
1739 {
5c449fde 1740 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name.c_str(), battle->stats->fight->name.c_str());
1902338e 1741 }
8450c018 1742 else if (ni->stats->level - battle->stats->level > maxbfightdistance)
1743 {
1744 // You can't fight someone below you by more than X level(s)
1745 // level 12 can fight level (12 - X) but not < (12 - X)
1746 notice(s_GameServ, u, "You may not fight %s. You're too strong!",
5c449fde 1747 battle->stats->name.c_str());
8450c018 1748 }
1749 else if (battle->stats->level - ni->stats->level > maxafightdistance)
1750 {
1751 // You can't fight someone above you by more than X level(S)
1752 // level 1 can fight level (1 + X), but not > (1 + X)
1753 notice(s_GameServ, u, "%s, do you really have a death wish? Try the forest you "\
5c449fde 1754 "weakling!", ni->stats->name.c_str());
8450c018 1755 }
b0359af9 1756 else
85ce9d3e 1757 {
1758 // Set your battle pointer to the other player
1759 ni->stats->battle = battle;
1760
1761 // Set the other player's battle pointer to you
448a1531 1762 ni->stats->battle->stats->battle = ni;
85ce9d3e 1763
1764 // The initiator gets the first move (perhaps this should be 50/50)
ee38284f 1765 setYourTurn(ni->stats);
1766 clearYourTurn(battle->stats);
85ce9d3e 1767
1768 // Initiate Battle sequence!
b0359af9 1769 ni->stats->player_fights -= 1;
f2072f1a 1770
5c449fde 1771 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name.c_str());
1772 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name.c_str());
71098075 1773 notice(s_GameServ, battle->getNick(), "%s gets to go first "\
5c449fde 1774 "because they initiated!", ni->stats->name.c_str());
1775 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name.c_str());
85bcf836 1776 display_players(ni);
85ce9d3e 1777 }
1778}
40251952 1779
83cf716f 1780void do_use(char *u)
1781{
1782 aClient *user;
1783 Pouch *p;
1784
1785 char *item = strtok(NULL, " ");
1786
1787 if (!item)
1788 {
1789 notice(s_GameServ, u, "SYNTAX: USE ITEM");
1790 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1791 return;
1792 }
1793 else if (!(user = find(u)))
1794 {
1795 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1796 return;
1797 }
448a1531 1798 else if (isIgnore(user))
1799 {
1800 #ifdef DEBUGMODE
1801 log("Ignoring %s.", user->getNick());
1802 #endif
1803 return;
1804 }
83cf716f 1805 else if (!is_playing(user))
1806 {
1807 notice(s_GameServ, u, "You must be playing to use items!");
1808 return;
1809 }
1810
40251952 1811 updateTS(user->stats);
1812
83cf716f 1813 p = &user->stats->inventory;
1814
35cba3f5 1815 if (stricmp(item, "HEALING") == 0)
83cf716f 1816 {
1817 if (p->Healing() <= 0)
1818 {
35cba3f5 1819 notice(s_GameServ, u, "You are out of Healing Potions!");
83cf716f 1820 return;
1821 }
35cba3f5 1822 int oldhealing = user->stats->hp;
36b31e1c 1823 user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
1824 if (user->stats->hp - user->stats->maxhp >= 100)
1825 {
1826 user->stats->hp = user->stats->maxhp + 100;
1827
1828 if (oldhealing >= (user->stats->maxhp + 100))
1829 {
1830 notice(s_GameServ, u, "You cannot hold anymore HP!");
1831 return;
1832 }
1833 }
1834
83cf716f 1835 notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
1836 notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
35cba3f5 1837 notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealing);
83cf716f 1838 p->decHealing();
35cba3f5 1839 if (player_fight(user))
1840 {
1841 notice(s_GameServ, user->stats->battle->getNick(),
1842 "%s has used a healing potion!");
1843 }
83cf716f 1844 }
1845 else if (stricmp(item, "STRENGTH") == 0)
1846 {
1847 if (p->Strength() <= 0)
1848 {
1849 notice(s_GameServ, u, "You are out of Strength Potions!");
1850 return;
1851 }
1852 int oldstrength = user->stats->strength;
1853 notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!");
1854 notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!");
ae2685f6 1855 user->stats->strength += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
83cf716f 1856 notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength);
1857 p->decStrength();
35cba3f5 1858 if (player_fight(user))
1859 {
1860 notice(s_GameServ, user->stats->battle->getNick(),
1861 "%s has used a strength potion!");
1862 }
83cf716f 1863 }
1864 else if (stricmp(item, "DEFENSE") == 0)
1865 {
1866 if (p->Defense() <= 0)
1867 {
1868 notice(s_GameServ, u, "You are out of Defense Potions!");
1869 return;
1870 }
8c734eb9 1871 int olddefense = user->stats->defense;
83cf716f 1872 notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust.");
1873 notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!");
ae2685f6 1874 user->stats->defense += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
83cf716f 1875 notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense);
1876 p->decDefense();
35cba3f5 1877 if (player_fight(user))
1878 {
1879 notice(s_GameServ, user->stats->battle->getNick(),
1880 "%s has used a defense potion!");
1881 }
83cf716f 1882 }
8c734eb9 1883 else if (stricmp(item, "HP") == 0)
1884 {
1885 if (p->HP() <= 0)
1886 {
1887 notice(s_GameServ, u, "You are out of HP Potions!");
1888 return;
1889 }
1890 int oldHP = user->stats->maxhp;
1891 notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid.");
4e64da60 1892 user->stats->maxhp += 2 +
1893 (rand() % 100 > 70 ? (rand() % 7) : (rand() % 2) );
ae2685f6 1894
8c734eb9 1895 notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP);
1896 p->decHP();
35cba3f5 1897 if (player_fight(user))
1898 {
1899 notice(s_GameServ, user->stats->battle->getNick(),
1900 "%s has used a HP potion!");
1901 }
8c734eb9 1902 }
ee38284f 1903 else
1904 {
35cba3f5 1905 notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALING | STRENGTH | DEFENSE | HP}");
ee38284f 1906 return;
1907 }
83cf716f 1908
1909 end_turn(user); // If they're fighting, end their turn
1910}
c8ada07e 1911void do_run(char *u)
1912{
1913 aClient *user;
28f552b8 1914 Player *p, *p2 = NULL;
85ce9d3e 1915
c8ada07e 1916 if (!(user = find(u)))
1917 {
1918 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1919 return;
1920 }
448a1531 1921 else if (isIgnore(user))
1922 {
1923 #ifdef DEBUGMODE
1924 log("Ignoring %s.", user->getNick());
1925 #endif
1926 return;
1927 }
bb668fcf 1928 else if (!is_playing(user))
1929 {
adaf4cdb 1930 notice(s_GameServ, u, "You must be playing to run!");
bb668fcf 1931 return;
1932 }
1933
40251952 1934 updateTS(user->stats);
c8ada07e 1935 p = user->stats;
1936
1937 if (p->battle)
1938 p2 = p->battle->stats;
1939
1af35752 1940 if (!is_fighting(user))
c8ada07e 1941 notice(s_GameServ, u, "You run in place... try fighting next time.");
1af35752 1942 else if (!player_fight(user) && !master_fight(user))
c8ada07e 1943 {
5c449fde 1944 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name.c_str());
c8ada07e 1945 delete p->fight;
1946 p->fight = NULL;
1947 }
ee38284f 1948 else if (player_fight(user) && isYourTurn(p))
c8ada07e 1949 {
5c449fde 1950 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name.c_str());
1951 notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->name.c_str());
c8ada07e 1952 p2->battle = NULL;
1953 }
ee38284f 1954 else if (player_fight(user) && !isYourTurn(p))
c8ada07e 1955 {
5c449fde 1956 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->name.c_str());
c8ada07e 1957 }
1af35752 1958 else if (master_fight(user))
c8ada07e 1959 {
5c449fde 1960 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name.c_str());
c8ada07e 1961 }
1962 p->battle = NULL;
1963}
83cf716f 1964
1965void end_turn(aClient *user)
1966{
1967 char *nick, *u = user->getNick();
1968 Monster *fight;
1969 aClient *battle;
1970 int mhit;
1971
1972 nick = new char[strlen(user->getNick()) + 1];
1973
1974 if (!user || !is_playing(user) || !is_fighting(user))
1975 goto endturn;
1976
1977 if (!player_fight(user) && !master_fight(user))
1978 fight = user->stats->fight;
1979 else
1980 fight = user->stats->master;
1981 battle = user->stats->battle;
1982
1983 if (!player_fight(user))
1984 {
1985 // Opponent's Hit
1986 mhit = (fight->strength / 2) +
1987 (rand() % (fight->strength / 2) - (user->stats->defense +
1988 arbonus[user->stats->armor]));
1989 }
1990 else
1991 {
1992 // Opponent's Hit
1993 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1994 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1995 (user->stats->defense + arbonus[user->stats->armor]));
1996 }
1997 if (!player_fight(user))
1998 {
1999
2000 if (mhit > 0)
2001 {
2002 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
5c449fde 2003 fight->name.c_str(), fight->weapon.c_str(), mhit);
83cf716f 2004 }
2005 else if (mhit <= 0)
5c449fde 2006 notice(s_GameServ, u, "%s completely misses you!", fight->name.c_str());
83cf716f 2007
2008 if (mhit >= user->stats->hp)
2009 {
2010 if (!master_fight(user))
2011 {
5c449fde 2012 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name.c_str());
83cf716f 2013 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
2014 "of your experience!");
2015 user->stats->gold = 0;
2016 user->stats->exp -= (long int)(user->stats->exp * .10);
b478c0df 2017 user->stats->hp = 0;
83cf716f 2018 user->stats->fight = NULL;
ee38284f 2019 clearAlive(user->stats);
83cf716f 2020 goto endturn;
2021 }
2022 else
2023 {
2024 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
5c449fde 2025 "until tomorrow to try again", user->stats->master->name.c_str());
83cf716f 2026 user->stats->fight = NULL;
2027 user->stats->master = NULL;
2028 goto endturn;
2029 }
2030 }
2031 else
2032 {
2033 if (mhit > 0)
2034 user->stats->hp -= mhit;
2035 display_monster(u);
2036 goto endturn;
2037 }
2038 }
2039 else
2040 {
ee38284f 2041 clearYourTurn(user->stats);
2042 setYourTurn(battle->stats);
83cf716f 2043 display_players(battle);
2044 }
2045endturn:
2046 delete nick;
2047}
2048
85ce9d3e 2049void do_heal(char *u)
2050{
2051 aClient *ni;
2052 char *amount = strtok(NULL, " ");
2053 int price, num;
2054
2055 if (!amount)
2056 {
2057 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
40251952 2058 return;
85ce9d3e 2059 }
1af35752 2060 else if (!(ni = find(u)))
2061 {
2062 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2063 return;
2064 }
448a1531 2065 else if (isIgnore(ni))
2066 {
2067 #ifdef DEBUGMODE
2068 log("Ignoring %s.", ni->getNick());
2069 #endif
2070 return;
2071 }
1af35752 2072 else if (!is_playing(ni))
85ce9d3e 2073 {
2074 notice(s_GameServ, u, "You aren't playing!");
1af35752 2075 return;
2076 }
ee38284f 2077 else if (!isAlive(ni->stats))
1af35752 2078 {
2079 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
2080 return;
85ce9d3e 2081 }
1af35752 2082 else if (is_fighting(ni))
85ce9d3e 2083 {
2084 notice(s_GameServ, u, "You can't heal in battle!");
40251952 2085 return;
85ce9d3e 2086 }
2087 else if (ni->stats->hp >= ni->stats->maxhp)
2088 {
2089 notice(s_GameServ, u, "You don't need healing!");
40251952 2090 return;
85ce9d3e 2091 }
40251952 2092
2093 updateTS(ni->stats);
2094 if (stricmp(amount, "ALL") == 0)
85ce9d3e 2095 {
2096 price = ni->stats->level * 3;
2097 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
2098 {
2099 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
2100 (long int)ni->stats->gold/price, price);
2101 ni->stats->hp += ni->stats->gold / price;
2102 ni->stats->gold %= price;
2103 }
2104 else
2105 {
2106 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
2107 "per point.", price);
ad7dfaa0 2108 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
2109 (ni->stats->maxhp - ni->stats->hp),
2110 (price * (ni->stats->maxhp - ni->stats->hp)) );
85ce9d3e 2111 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
2112 ni->stats->hp = ni->stats->maxhp;
2113 }
2114 }
2115 else if (isstringnum(amount))
2116 {
2117 num = stringtoint(amount);
2118 price = ni->stats->level * 3;
2119 if (ni->stats->gold < price * num)
2120 {
2121 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
2122 (long int)ni->stats->gold/price);
2123 }
2124 else if (num <= ni->stats->maxhp - ni->stats->hp)
2125 {
2126 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
2127 num, price);
2128 ni->stats->hp += num;
2129 ni->stats->gold -= num * price;
2130 }
2131 else if (num > ni->stats->maxhp - ni->stats->hp)
2132 {
2133 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
2134 "per point.", price);
2135 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
2136 (ni->stats->maxhp - ni->stats->hp));
2137 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
2138 ni->stats->hp = ni->stats->maxhp;
2139 }
2140 }
2141 else if (amount[0] == '-')
2142 notice(s_GameServ, u, "You trying to cheat?");
2143 else
2144 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
2145}
2146
2147int isstringnum(char *num)
2148{
28f552b8 2149 unsigned int x;
85ce9d3e 2150 for (x = 0; x < strlen(num); x++)
2151 {
2152 if ((int)num[x] < 48 || (int)num[x] > 57)
2153 return 0;
2154 }
2155return 1;
2156}
2157
2158long int stringtoint(char *number)
2159{
9fe7af4c 2160 return atol(number);
2161/*
85ce9d3e 2162 long int x, len = strlen(number), sum = 0;
2163 if (len == 1)
2164 return chartoint(number[0]);
2165 sum += chartoint(number[len - 1]);
2166 for (x = len - 2; x >= 0; x--)
85ce9d3e 2167 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
85ce9d3e 2168 return sum;
9fe7af4c 2169*/
85ce9d3e 2170}
2171
2172long int pow(int x, int y)
2173{
2174 long int value = 0;
2175 int count = 0;
2176 value += x;
2177
2178 if (x != 0 && y != 0)
2179 {
2180 for (count = 1; count <= y - 1; count++)
2181 value *= x;
2182 }
2183 else
2184 return 1;
2185return value;
2186}
2187
2188long int chartoint(char ch)
2189{
8c126acc 2190 if (int(ch) >= 48 && int(ch) <= 57)
2191 return int(ch) - 48;
2192 else
2193 return 0;
85ce9d3e 2194}
2195
2196int save_gs_dbase()
2197{
7996e5fd 2198 ListNode<aClient> *ptr;
85ce9d3e 2199 Player *it;
2200 ofstream outfile;
2201
2202 outfile.open(playerdata);
2203
2204 if (!outfile)
2205 {
fb37ecc7 2206 log("Error opening %s", playerdata);
85ce9d3e 2207 return 0;
2208 }
2209
7996e5fd 2210 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
2211 {
2212 ptr = players[x].First();
85ce9d3e 2213 while(ptr)
2214 {
2215 it = ptr->getData()->stats;
ae2685f6 2216 clearYourTurn(it);
5c449fde 2217 outfile << it->name.c_str() << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
2218 << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
2219 << it->armor << ' ' << it->weapon << ' '
e3c5fe46 2220 << it->forest_fights << ' ' << it->player_fights << ' '
5c449fde 2221 << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
14e24ba1 2222 << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP()
82c01ddf 2223 << ' ' << it->lastlogin << endl;
85ce9d3e 2224 ptr = ptr->Next();
2225 }
7996e5fd 2226 }
85ce9d3e 2227outfile.close();
28f552b8 2228return 1;
85ce9d3e 2229}
2230
8e800549 2231int load_dragon()
2232{
2233 ifstream infile;
2234 char *buf;
2235
2236 infile.open(dragondata);
2237
2238 if (infile.fail())
2239 {
2240 infile.clear();
2241 log ("Error opening %s. Trying initialdragon.dat", dragondata);
2242 infile.open("data/initialdragon.dat");
2243 if (infile.fail())
2244 {
2245 log ("Error opening data/initialdragon.dat");
2246 return 0;
2247 }
2248 }
2249
2250 buf = new char[1024];
2251
2252 infile.getline(buf, 1024, '\n');
2253 infile.close(); // Done with the file... we have what we want
2254
2255 dragon.name = strtok(buf, "~");
2256 dragon.weapon = strtok(NULL, "~");
2257 dragon.gold = 0;
2258 dragon.exp = 0;
2259 dragon.strength = stringtoint(strtok(NULL, "~"));
2260 dragon.hp = stringtoint(strtok(NULL, "~"));
2261 dragon.defense = stringtoint(strtok(NULL, "~"));
2262 dragon.death = strtok(NULL, "");
2263
2264 log ("loaded dragon: %s", dragon.name.c_str());
2265
2266 delete []buf;
2267
2268return save_dragon(); // Save the dragon file and return the status code :)
2269}
2270
2271int save_dragon()
2272{
2273 ofstream outfile;
2274
2275 outfile.open(dragondata);
2276
2277 if (outfile.fail())
2278 {
2279 log ("Error opening %s. Exiting.", dragondata);
2280 return 0;
2281 }
2282
2283 outfile << dragon.name.c_str() << '~' << dragon.weapon.c_str() << '~'
2284 << dragon.strength << '~' << dragon.hp << '~'
2285 << dragon.defense << '~' << dragon.death.c_str() << "\n^"
2286 << endl;
2287
2288outfile.close();
2289
2290return 1;
2291}
2292
85ce9d3e 2293int load_gs_dbase()
2294{
2295 ifstream infile;
2296 aClient *temp;
2297 Player *p;
ee38284f 2298 char *tempname, *buf, *password;
8e800549 2299 buf = new char[1024];
85ce9d3e 2300
2301 infile.open(playerdata);
2302
2303 if (infile.fail())
2304 {
fb37ecc7 2305 log("Error opening %s", playerdata);
85ce9d3e 2306 return 0;
2307 }
2308
19795233 2309 for (int x = 0; x < U_TABLE_SIZE; x++)
2310 {
2311 ListNode<aClient> *tempNode;
2312 tempNode = players[x].First();
2313 while (tempNode)
2314 {
2315 if (tempNode->getData()->stats->client)
2316 logout(tempNode->getData()->stats->client);
2317 tempNode = tempNode->Next();
2318 }
2319 players[x].deleteNodes();
2320 }
2321
85ce9d3e 2322 while (infile.getline(buf, 1024, '\n'))
2323 {
2324 temp = new aClient;
2325 tempname = strtok(buf, " ");
2326 temp->stats = new Player(tempname);
2327 p = temp->stats;
2328
85ce9d3e 2329 p->level = stringtoint(strtok(NULL, " "));
2330 p->exp = stringtoint(strtok(NULL, " "));
2331 p->gold = stringtoint(strtok(NULL, " "));
2332 p->bank = stringtoint(strtok(NULL, " "));
2333 p->hp = stringtoint(strtok(NULL, " "));
2334 p->maxhp = stringtoint(strtok(NULL, " "));
2335 p->strength = stringtoint(strtok(NULL, " "));
2336 p->defense = stringtoint(strtok(NULL, " "));
2337 p->armor = stringtoint(strtok(NULL, " "));
2338 p->weapon = stringtoint(strtok(NULL, " "));
85ce9d3e 2339 p->forest_fights = stringtoint(strtok(NULL, " "));
2340 p->player_fights = stringtoint(strtok(NULL, " "));
1af35752 2341 p->setFlags(stringtoint(strtok(NULL, " ")));
ee38284f 2342
e3c5fe46 2343 password = strtok(NULL, " ");
ddef84f1 2344 p->password = password;
448a1531 2345 temp->setNick("Not Playing");
ce61cdfa 2346 #ifdef P10
448a1531 2347 temp->setRealNick("Not Playing");
ce61cdfa 2348 #endif
85ce9d3e 2349
9d3b1d42 2350 p->inventory.reset(); // Set inventory to all 0s
ee38284f 2351 // Old player databases didn't have these three extra values
2352 // If they come up null, leave them to 0 as the default.
2353 // On the next gameserv database save, it will save the values.
266608f6 2354 tempname = strtok(NULL, " ");
9d3b1d42 2355 if (tempname)
2356 p->inventory.setHealing(stringtoint(tempname));
2357
2358 tempname = strtok(NULL, " ");
2359 if (tempname)
2360 p->inventory.setStrength(stringtoint(tempname));
2361
2362 tempname = strtok(NULL, " ");
2363 if (tempname)
2364 p->inventory.setDefense(stringtoint(tempname));
2365
2366 tempname = strtok(NULL, " ");
2367 if (tempname)
2368 p->inventory.setHP(stringtoint(tempname));
14e24ba1 2369
2370 tempname = strtok(NULL, " ");
2371 if (tempname)
2372 p->lastlogin = stringtoint(tempname);
2373 else
2374 p->lastlogin = time(NULL);
2375
5c449fde 2376 unsigned long hv = iHASH((unsigned char *) temp->stats->name.c_str());
85bcf836 2377
2378 temp->stats->client = NULL;
7996e5fd 2379 players[hv].insertAtBack(temp);
85ce9d3e 2380 delete temp;
2381 }
1cf88153 2382delete [] buf;
28f552b8 2383infile.close();
2384return 1;
85ce9d3e 2385}
2386
5c449fde 2387bool passcmp(const char *encrypted, char *plaintext)
e3c5fe46 2388{
2389 char salt[3];
cdc9a6db 2390 char *plaintext2, *plainToencrypt;
2391 bool same = false;
2392
2393 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
2394 strcpy(plaintext2, plaintext);
2395
e3c5fe46 2396 salt[0] = encrypted[0];
2397 salt[1] = encrypted[1];
2398 salt[3] = '\0';
cdc9a6db 2399
2400 plainToencrypt = crypt(plaintext2, salt);
2401
2402 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
2403
2404 delete []plaintext2;
2405
2406 return same;
e3c5fe46 2407}
2408
2409bool check_password(char *name, char *plaintext)
2410{
0a1518fa 2411 aClient *client;
e3c5fe46 2412
0a1518fa 2413 if (!(client = findplayer(name)))
2414 return false;
2415 else
e3c5fe46 2416 {
5c449fde 2417 return passcmp(client->stats->password.c_str(), plaintext);
e3c5fe46 2418 }
e3c5fe46 2419}
1cf88153 2420
ad7dfaa0 2421void do_store(char *u)
2422{
2423 char *cmd = strtok(NULL, " ");
2424 char *item = strtok(NULL, " ");
2425 char *num = strtok(NULL, " ");
2426 char *space;
8c126acc 2427 int wep;
2428 aClient *user;
2429 Player *p;
ad7dfaa0 2430
1af35752 2431 if (!cmd || !item)
ad7dfaa0 2432 {
2433 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2434 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2435 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
40251952 2436 return;
ad7dfaa0 2437 }
448a1531 2438 else if (!(user = find(u)))
2439 {
2440 log("Fatal Error: could not find %s in client list", u);
2441 return;
2442 }
2443 else if (isIgnore(user))
2444 {
2445 #ifdef DEBUGMODE
2446 log("Ignoring %s.", user->getNick());
2447 #endif
2448 return;
2449 }
2450 else if (!is_playing(user))
40251952 2451 {
1af35752 2452 notice(s_GameServ, u, "You must be playing to use the store!");
40251952 2453 return;
2454 }
ee38284f 2455 else if (!isAlive(user->stats))
1af35752 2456 {
2457 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
2458 return;
2459 }
40251952 2460 updateTS(user->stats);
2461
2462 if (stricmp(cmd, "LIST") == 0)
ad7dfaa0 2463 {
2464 if (stricmp(item, "WEAPONS") == 0)
2465 {
2466 notice(s_GameServ, u, "Welcome to Kain's Armory");
2467 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
2468 for (int x = 1; x < WNA; x++)
2469 {
2470 space = spaces(strlen(weapons[x]), ".");
2471 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
2472 free(space);
2473 }
2474 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
2475 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
2476
2477 }
2478 else if (stricmp(item, "ARMOR") == 0)
2479 {
2480 notice(s_GameServ, u, "Welcome to Kain's Armory");
2481 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
2482 for (int x = 1; x < WNA; x++)
2483 {
2484 space = spaces(strlen(armors[x]), ".");
2485 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
2486 free(space);
2487 }
2488 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
2489 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
2490
2491
2492 }
2493 } else if (stricmp(cmd, "BUY") == 0) {
8c126acc 2494 if (!num)
2495 {
2496 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2497 return;
2498 }
2499 else if (!isstringnum(num))
2500 {
2501 notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
2502 return;
2503 }
2504 if (stricmp(item, "WEAPON") == 0)
2505 {
2506 wep = stringtoint(num);
2507 if (wep >= WNA || wep < 1)
2508 {
2509 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2510 return;
2511 }
2512
2513 p = user->stats;
2514
2515 if (p->weapon != 0)
2516 notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
2517 else if (p->gold < prices[wep - 1])
2518 notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
2519 else
2520 {
2521 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
2522 p->weapon = wep;
2523 p->gold -= prices[wep - 1];
2524 }
2525 }
2526 else if (stricmp(item, "ARMOR") == 0)
2527 {
2528 wep = stringtoint(num);
2529 if (wep >= WNA || wep < 1)
2530 {
2531 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2532 return;
2533 }
2534
2535 p = user->stats;
2536
2537 if (p->armor != 0)
2538 notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
2539 else if (p->gold < prices[wep - 1])
2540 notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
2541 else
2542 {
2543 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
2544 p->armor = wep;
2545 p->gold -= prices[wep - 1];
2546 }
2547 }
a02e93a1 2548 else
2549 {
2550 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
5c449fde 2551 return;
a02e93a1 2552 }
8c126acc 2553 }
2554 else if (stricmp(cmd, "SELL" ) == 0)
2555 {
2556 p = user->stats;
2557
2558 if (stricmp(item, "WEAPON") == 0)
2559 {
2560 if (p->weapon == 0)
2561 {
2562 notice(s_GameServ, u, "You want me to chop off your hands?");
2563 return;
2564 }
2565 else if (p->gold == 2000000000)
2566 {
2567 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2568 p->weapon = 0;
2569 }
2570 else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
2571 {
2572 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2573 notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
2574 p->gold = 2000000000;
2575 p->weapon = 0;
2576 }
2577 else
2578 {
2579 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
2580 p->gold += (prices[p->weapon - 1] / 2);
2581 p->weapon = 0;
2582 }
2583 }
2584 else if (stricmp(item, "ARMOR") == 0)
2585 {
2586 p = user->stats;
2587
2588 if (p->armor == 0)
2589 {
2590 notice(s_GameServ, u, "I don't think you can be any more naked...");
2591 return;
2592 }
2593 if (p->gold == 2000000000)
2594 {
2595 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2596 p->armor = 0;
2597 }
2598 else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
2599 {
2600 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2601 notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
2602 p->gold = 2000000000;
2603 p->armor = 0;
2604 }
2605 else
2606 {
2607 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
2608 (prices[p->armor - 1] / 2));
2609
2610 p->gold += (prices[p->armor - 1] / 2);
2611 p->armor = 0;
2612 }
2613 }
2614 else
2615 {
2616 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2617 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2618 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2619 }
2620 }
6d053d90 2621 else
2622 {
2623 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2624 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2625 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2626 return;
2627 }
8c126acc 2628}
9cda831c 2629void do_inventory(char *u)
2630{
2631 aClient *user;
2632
2633 if (!(user = find(u)))
2634 {
2635 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2636 return;
2637 }
448a1531 2638 else if (isIgnore(user))
2639 {
2640 #ifdef DEBUGMODE
2641 log("Ignoring %s.", user->getNick());
2642 #endif
2643 return;
2644 }
9cda831c 2645 else if (!is_playing(user))
2646 {
2647 notice(s_GameServ, u, "You must be playing to check your inventory!");
2648 return;
2649 }
40251952 2650 updateTS(user->stats);
9cda831c 2651 showinventory(user, user);
2652}
2653void showinventory(aClient *from, aClient *to)
2654{
2655 char *nick = to->getNick();
8c126acc 2656
9cda831c 2657 if (!to)
2658 to = from;
2659 if (is_playing(from))
2660 {
2661 Pouch *p = &from->stats->inventory;
5c449fde 2662 notice(s_GameServ, nick, "Inventory for %s:", from->stats->name.c_str());
9cda831c 2663 notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
2664 notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
2665 notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
9d3b1d42 2666 notice(s_GameServ, nick, " HP Potions: %d", p->HP());
9cda831c 2667 }
2668}
f5c25639 2669void do_tavern(char *u)
2670{
2671 char *cmd = strtok(NULL, " ");
2672 long int price;
2673
2674 aClient *user;
2675 Player *p;
a6352eed 2676
f5c25639 2677 if (!(user = find(u)))
2678 {
2679 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2680 return;
2681 }
448a1531 2682 else if (isIgnore(user))
2683 {
2684 #ifdef DEBUGMODE
2685 log("Ignoring %s.", user->getNick());
2686 #endif
2687 return;
2688 }
f5c25639 2689 else if (!is_playing(user))
2690 {
2691 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2692 return;
2693 }
9cda831c 2694 else if (is_fighting(user))
2695 {
2696 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2697 return;
2698 }
40251952 2699
2700 updateTS(user->stats);
f5c25639 2701 p = user->stats;
40251952 2702
f5c25639 2703 if (!cmd)
2704 {
2705 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
2706 notice(s_GameServ, u, "Your commands:");
2707 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2708 notice(s_GameServ, u, "What'll it be?");
2709 }
2710 else if (stricmp(cmd, "LIST") == 0)
2711 {
a6352eed 2712 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2713 notice(s_GameServ, u, "1. Healing Potions for %ld Gold",
2714 1000 * p->level * 4);
2715 notice(s_GameServ, u, "2. Strength Potions for %ld Gold",
2716 2500 * p->level * 4);
2717 notice(s_GameServ, u, "3. Defense Potions for %ld Gold",
2718 3000 * p->level * 4);
2719 notice(s_GameServ, u, "4. HP Potions for %ld Gold",
2720 2000 * p->level * 4);
2721 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2722 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
f5c25639 2723 }
2724 else if (stricmp(cmd, "BUY") == 0)
2725 {
2726 char *chnum = strtok(NULL, " ");
f5c25639 2727
2728 if (!chnum)
2729 {
2730 notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
2731 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
2732 return;
2733 }
19795233 2734 int num = stringtoint(chnum);
2735
8c734eb9 2736 if (num < 1 || num > 4)
f5c25639 2737 {
2738 notice(s_GameServ, u, "Invalid Choice!");
2739 notice(s_GameServ, u, "Here is a list of what we have to offer:");
a6352eed 2740 notice(s_GameServ, u, "1. Healing Potions for %ld Gold",
2741 1000 * p->level * 4);
2742 notice(s_GameServ, u, "2. Strength Potions for %ld Gold",
2743 2500 * p->level * 4);
2744 notice(s_GameServ, u, "3. Defense Potions for %ld Gold",
2745 3000 * p->level * 4);
2746 notice(s_GameServ, u, "4. HP Potions for %ld Gold",
2747 2000 * p->level * 4);
f5c25639 2748 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2749 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
ee38284f 2750 return;
f5c25639 2751 }
2752 switch(num)
2753 {
2754 case 1:
a6352eed 2755 price = (1000 * p->level * 4);
f5c25639 2756 if (p->gold >= price)
2757 {
2758 notice(s_GameServ, u, "One healing potion coming right up!");
2759 p->inventory.incHealing();
ee38284f 2760 p->gold -= price;
f5c25639 2761 }
2762 else
2763 notice(s_GameServ, u, "You don't have enough gold!");
2764 break;
2765 case 2:
a6352eed 2766 price = 2500 * p->level * 4;
f5c25639 2767 if (p->gold >= price)
2768 {
2769 notice(s_GameServ, u, "One strength boost coming right up!");
2770 p->inventory.incStrength();
ee38284f 2771 p->gold -= price;
f5c25639 2772 }
2773 else
2774 notice(s_GameServ, u, "You don't have enough gold!");
2775 break;
2776 case 3:
a6352eed 2777 price = 3000 * p->level * 4;
f5c25639 2778 if (p->gold >= price)
2779 {
2780 notice(s_GameServ, u, "One defense boost coming right up!");
2781 p->inventory.incDefense();
ee38284f 2782 p->gold -= price;
f5c25639 2783 }
2784 else
2785 notice(s_GameServ, u, "You don't have enough gold!");
2786 break;
8c734eb9 2787 case 4:
5c449fde 2788 price = 3000 * p->level * 4;
8c734eb9 2789 if (p->gold >= price)
2790 {
2791 notice(s_GameServ, u, "One HP Potion coming right up!");
2792 p->inventory.incHP();
2793 p->gold -= price;
2794 }
2795 else
2796 notice(s_GameServ, u, "You don't have enough gold!");
2797 break;
f5c25639 2798 default:
2799 notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
2800 break;
2801 }
2802 }
9cda831c 2803 else
2804 {
2805 notice(s_GameServ, u, "Improper Syntax.");
2806 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2807 }
f5c25639 2808}
2809
8c126acc 2810void do_bank(char *u)
2811{
2812 char *cmd = strtok(NULL, " ");
2813 char *amount = strtok(NULL, " ");
2814 char *nick = strtok(NULL, " ");
2815
2816 aClient *user;
2817 Player *p;
2818
8c734eb9 2819 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
8c126acc 2820 {
2821 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
e282e9d2 2822 notice (s_GameServ, u, "BANK BALANCE");
8c126acc 2823 return;
2824 }
40251952 2825 else if (!(user = find(u)))
2826 {
2827 notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\
2828 " admin for help");
2829 log("Fatal Error. Couldn't find %s while executing do_bank()", u);
2830 return;
2831 }
448a1531 2832 else if (isIgnore(user))
2833 {
2834 #ifdef DEBUGMODE
2835 log("Ignoring %s.", user->getNick());
2836 #endif
2837 return;
2838 }
40251952 2839 else if (!is_playing(user))
8c126acc 2840 {
2841 notice(s_GameServ, u, "You must be playing to use the bank!");
2842 return;
ad7dfaa0 2843 }
2158299e 2844 else if (is_fighting(user))
2845 {
2846 notice(s_GameServ, u, "You can't go to the bank during a fight!");
2847 return;
2848 }
40251952 2849 updateTS(user->stats);
2850 if (stricmp(cmd, "BALANCE") == 0)
fa376453 2851 {
2852 showBankBalance(u);
2853 return;
2854 }
ee38284f 2855 else if (!isAlive(user->stats))
1af35752 2856 {
2857 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2858 return;
2859 }
8c126acc 2860 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2861 {
2862 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2863 return;
2864 }
11f32a66 2865 if (stringtoint(amount) < 0)
2866 {
2867 notice(s_GameServ, u, "Sorry. This bank is not licensed "\
2868 "to handle such sums of cash, noble Lord.");
2869 return;
2870 }
8c126acc 2871 p = user->stats;
2872
fa376453 2873 if (stricmp(cmd, "DEPOSIT") == 0)
8c126acc 2874 {
2875 if (p->bank == 2000000000)
2876 {
2877 notice(s_GameServ, u, "Your bank account is full, sire!");
2878 return;
2879 }
2880 else if (stricmp(amount, "ALL") == 0)
2881 {
2882 if (2000000000 - p->bank < p->gold)
2883 {
2884 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2885 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
2886 p->gold -= (2000000000 - p->bank);
2887 p->bank = 2000000000;
e282e9d2 2888 showBankBalance(u);
8c126acc 2889 }
2890 else
2891 {
2892 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
2893 p->bank += p->gold;
2894 p->gold = 0;
e282e9d2 2895 showBankBalance(u);
8c126acc 2896 }
2897 }
2898 else if (stringtoint(amount) > p->gold)
2899 {
2900 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
e282e9d2 2901 showBankBalance(u);
8c126acc 2902 return;
2903 }
2904 else
2905 {
2906 if (2000000000 - p->bank < stringtoint(amount))
2907 {
2908 notice(s_GameServ, u, "You don't have room in your account for that much.");
2909 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
2910 p->gold -= (2000000000 - p->bank);
2911 p->bank = 2000000000;
e282e9d2 2912 showBankBalance(u);
8c126acc 2913 }
2914 else
2915 {
2916 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2917 p->bank += stringtoint(amount);
2918 p->gold -= stringtoint(amount);
e282e9d2 2919 showBankBalance(u);
8c126acc 2920 }
2921 }
2922 }
2923 else if (stricmp(cmd, "WITHDRAW") == 0)
2924 {
2925 if (p->gold == 2000000000)
2926 {
2927 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
e282e9d2 2928 showBankBalance(u);
8c126acc 2929 return;
2930 }
2931 else if (stricmp(amount, "ALL") == 0)
2932 {
2933 if (2000000000 - p->gold < p->bank)
2934 {
2935 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2936 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
2937 p->bank -= (2000000000 - p->gold);
2938 p->gold = 2000000000;
e282e9d2 2939 showBankBalance(u);
8c126acc 2940 }
2941 else
2942 {
2943 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
2944 p->gold += p->bank;
2945 p->bank = 0;
e282e9d2 2946 showBankBalance(u);
8c126acc 2947 }
2948 }
2949 else if (stringtoint(amount) > p->bank)
2950 {
2951 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
e282e9d2 2952 showBankBalance(u);
8c126acc 2953 return;
2954 }
2955 else
2956 {
2957 if (2000000000 - p->gold < stringtoint(amount))
2958 {
2959 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2960 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2961 (2000000000 - p->gold));
2962 p->bank -= (2000000000 - p->gold);
2963 p->gold = 2000000000;
e282e9d2 2964 showBankBalance(u);
8c126acc 2965 }
2966 else
2967 {
2968 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2969 p->gold += stringtoint(amount);
2970 p->bank -= stringtoint(amount);
e282e9d2 2971 showBankBalance(u);
8c126acc 2972 }
2973 }
2974 }
2975
ad7dfaa0 2976}
ab4f4ec0 2977
fcca861d 2978void do_dragon(char *u)
2979{
2980 aClient *user;
2981
2982 if (!(user = find(u)))
2983 {
2984 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2985 return;
2986 }
2987 else if (isIgnore(user))
2988 {
2989 #ifdef DEBUGMODE
2990 log("Ignoring %s.", user->getNick());
2991 #endif
2992 return;
2993 }
2994 else if (!is_playing(user))
2995 {
2996 notice(s_GameServ, u, "You must be playing to fight the dragon!");
2997 return;
2998 }
2999 else if (is_fighting(user))
3000 {
3001 notice(s_GameServ, u, "You are already in a fight. How will you fight the almighty dragon!?");
3002 return;
3003 }
3004 else if (!isAlive(user->stats))
3005 {
3006 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
3007 return;
3008 }
fd270bdd 3009 else if (user->stats->level < LEVELS)
fcca861d 3010 {
3011 notice(s_GameServ, u, "You fool! Only those strong enough "\
3012 "to vanquish any foe should DARE fight the dragon!");
3013 notice(s_GameServ, u, "To put it in terms you can understand: "\
016a160f 3014 "You are too weak. You must be Level %d!", REALLEVELS);
68379f96 3015 return;
fcca861d 3016 }
3017
3018 updateTS(user->stats);
3019
fcca861d 3020 Player *p = user->stats;
fd270bdd 3021 setMaster(p);
fcca861d 3022 notice(s_GameServ, u, "You approach the dragon's lair cautiously.");
3023 notice(s_GameServ, u, "The stench of sulfer fills the air as a "\
3024 "deep, red fog rolls in. The air is filled with the "\
3025 "heated mist of deadly fire from beyond the cave "\
3026 "entrance.");
9cb6f227 3027 notice(s_GameServ, u, "You adjust your %s, tighten your grip on "\
fcca861d 3028 "your %s, and venture into the hot, dark cave. "\
3029 "You are surprised at the angle of descent as you climb "\
fd270bdd 3030 "lower and lower, deeper into the dragon's den.",
3031 armors[p->armor], weapons[p->weapon]);
fcca861d 3032 notice(s_GameServ, u, "You come to the end of the cave to find "\
3033 "a tooth. It is a large tooth... bigger than your torso."\
3034 " Suddenly the darkness lifts from the gleam of an eye "\
3035 " staring into your soul! The eye is large... HUGE!");
3036 notice(s_GameServ, u, "Just then you notice the eye begin to "\
3037 "glare orange! The tooth is moving... but it is still too "\
3038 "dark for you to make out.... THE DRAGON! You see it!");
8e800549 3039 p->fight = new Monster(dragon);
3040 setDragonFight(p);
3041 display_monster(u);
fcca861d 3042}
3043
ab4f4ec0 3044void do_master(char *u)
3045{
3046 aClient *user;
1af35752 3047
448a1531 3048
3049 if (!(user = find(u)))
ab4f4ec0 3050 {
3051 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3052 return;
3053 }
448a1531 3054 else if (isIgnore(user))
3055 {
3056 #ifdef DEBUGMODE
3057 log("Ignoring %s.", user->getNick());
3058 #endif
3059 return;
3060 }
c047f947 3061 else if (!is_playing(user))
3062 {
3063 notice(s_GameServ, u, "You must be playing to see your master!");
3064 return;
3065 }
1af35752 3066 else if (is_fighting(user))
ab4f4ec0 3067 {
3068 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
3069 return;
3070 }
ee38284f 3071 else if (!isAlive(user->stats))
1af35752 3072 {
3073 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
3074 return;
3075 }
40251952 3076
3077 updateTS(user->stats);
c047f947 3078
c7340cbd 3079 char *cmd = strtok(NULL, " ");
3080 Player *p = user->stats;
3081 long int need = 0;
3082
1af35752 3083 if (seenMaster(p))
3084 {
3085 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
3086 return;
3087 }
3088
c7340cbd 3089 if (cmd != NULL)
ab4f4ec0 3090 {
ab4f4ec0 3091 switch(p->level)
3092 {
3093 case 1:
fcca861d 3094 need = 200;
ab4f4ec0 3095 break;
3096 case 2:
fcca861d 3097 need = 800;
ab4f4ec0 3098 break;
3099 case 3:
fcca861d 3100 need = 2000;
ab4f4ec0 3101 break;
3102 case 4:
fcca861d 3103 need = 8000;
ab4f4ec0 3104 break;
3105 case 5:
fcca861d 3106 need = 20000;
ab4f4ec0 3107 break;
3108 case 6:
fcca861d 3109 need = 80000;
ab4f4ec0 3110 break;
3111 case 7:
fcca861d 3112 need = 200000;
ab4f4ec0 3113 break;
3114 case 8:
fcca861d 3115 need = 800000;
ab4f4ec0 3116 break;
3117 case 9:
fcca861d 3118 need = 2000000;
ab4f4ec0 3119 break;
3120 case 10:
fcca861d 3121 need = 8000000;
ab4f4ec0 3122 break;
3123 case 11:
fcca861d 3124 need = 20000000;
ab4f4ec0 3125 break;
016a160f 3126
3127 case REALLEVELS:
ab4f4ec0 3128 need = p->exp + 1;
016a160f 3129 notice(s_GameServ, u, "You are at level %d. You are the master. What's left? The DRAGON!", REALLEVELS);
fcca861d 3130 return;
ab4f4ec0 3131 break;
3132 default:
3133 need = p->exp + 1; // Unknown level... don't let them fight a fake master!
3134 break;
c7340cbd 3135 }
3136 }
3137 else
3138 {
3139 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
3140 return;
3141 }
3142
3143 if (stricmp(cmd, "FIGHT") == 0)
3144 {
ab4f4ec0 3145 if (p->exp >= need)
1af35752 3146 {
3147 setMaster(p);
ab4f4ec0 3148 see_master(u);
1af35752 3149 }
ab4f4ec0 3150 else
ddef84f1 3151 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.",
5c449fde 3152 levels[p->level - 1].master.name.c_str(), (need - p->exp));
c7340cbd 3153 return;
3154 }
3155 else if (stricmp(cmd, "QUESTION") == 0)
3156 {
3157 if (p->exp >= need)
ddef84f1 3158 notice(s_GameServ, u, "%s looks you up and down and decides you are more ready than you will ever be.",
5c449fde 3159 levels[p->level - 1].master.name.c_str());
c7340cbd 3160 else
ddef84f1 3161 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!",
5c449fde 3162 levels[p->level - 1].master.name.c_str(), p->name.c_str());
c7340cbd 3163
3164 return;
3165 }
3166 else
3167 {
3168 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
ab4f4ec0 3169 }
3170}
3171
3172void see_master(char *u)
3173{
3174 aClient *user;
1af35752 3175
ab4f4ec0 3176 if (!(user = find(u)))
3177 {
3178 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3179 return;
3180 }
3181
1af35752 3182 if (!is_fighting(user) && is_playing(user))
ab4f4ec0 3183 {
3184 Player *p = user->stats;
5c449fde 3185 p->master = new Monster(&levels[p->level - 1].master);
ab4f4ec0 3186 p->fight = p->master;
3187 display_monster(u); // Since master is the same structure, use this function
3188 }
3189}
e282e9d2 3190
3191void showBankBalance(const char *u)
3192{
3193 aClient *user;
3194 Player *p;
1af35752 3195
e282e9d2 3196 if (!(user = find(u)))
3197 return;
3198
3199 p = user->stats;
3200
3201 if (!p)
3202 return;
3203
3204 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->bank, p->gold);
3205
3206}
44ea29f7 3207
3208void refreshall()
3209{
3210 ListNode <aClient> *it;
3211 Player *p;
7996e5fd 3212 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3213 {
3214 it = players[x].First();
44ea29f7 3215
3216 while (it)
3217 {
3218 p = it->getData()->stats;
3219 refresh(p);
3220 it = it->Next();
3221 }
7996e5fd 3222 }
44ea29f7 3223}
3224
3225void refresh(Player *p)
3226{
3227 if (!p)
3228 return;
3229
ee38284f 3230 if (p->hp < p->maxhp)
3231 p->hp = p->maxhp;
20d5d721 3232 p->forest_fights = forestfights;
44ea29f7 3233 p->player_fights = 3;
ee38284f 3234 setAlive(p);
1af35752 3235 clearMaster(p);
44ea29f7 3236}
c7340cbd 3237
3238void do_refresh(char *u)
3239{
3240 char *nick = strtok(NULL, " ");
3241 aClient *user;
3242
96f71fee 3243 if (!(user = find(u)))
3244 {
3245 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
5d04eb42 3246 log("Error: aClient not found: %s", u);
96f71fee 3247 return;
3248 }
448a1531 3249 else if (isIgnore(user))
3250 {
3251 #ifdef DEBUGMODE
3252 log("Ignoring %s.", user->getNick());
3253 #endif
3254 return;
3255 }
96f71fee 3256 else if (!isAdmin(user))
3257 {
3258 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3259 return;
3260 }
c7340cbd 3261 if (!nick)
3262 {
96f71fee 3263 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
c7340cbd 3264 return;
3265 }
3266 else if (stricmp(nick, "ALL") == 0)
3267 {
3268 notice(s_GameServ, u, "Refreshing everyone's stats!");
3269 refreshall();
3270 }
ae2685f6 3271 else if ((user = findplayer(nick)))
c7340cbd 3272 {
1af35752 3273 if (is_playing(user))
c7340cbd 3274 {
ce61cdfa 3275 #ifdef P10
3276 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
3277 #else
c7340cbd 3278 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
ce61cdfa 3279 #endif
c7340cbd 3280 refresh(user->stats);
3281 }
3282 else
3283 {
ce61cdfa 3284 #ifdef P10
3285 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
3286 #else
c7340cbd 3287 notice(s_GameServ, u, "%s is not playing.", user->getNick());
ce61cdfa 3288 #endif
c7340cbd 3289 }
3290 }
3291 else
3292 {
3293 notice(s_GameServ, u, "Nick %s not found.", nick);
3294 return;
3295 }
3296}
3297
ee38284f 3298
3299void resetall()
3300{
3301 ListNode <aClient> *it;
3302 Player *p;
3303
7996e5fd 3304 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3305 {
3306 it = players[x].First();
ee38284f 3307
3308 while (it)
3309 {
3310 p = it->getData()->stats;
3311 reset(p);
3312 it = it->Next();
3313 }
7996e5fd 3314 }
ee38284f 3315}
3316
3317void reset(Player *p)
3318{
5c449fde 3319 string *myname;
ddef84f1 3320
ee38284f 3321 if (!p)
3322 return;
3323
5c449fde 3324 myname = new string(p->name);
3325
ee38284f 3326 p->reset();
ddef84f1 3327 p->name = *myname;
ddef84f1 3328 delete myname;
ee38284f 3329}
3330
40251952 3331void updateTS(Player *p)
3332{
3333 if (!p)
3334 return;
0b6098d5 3335
3336 #ifdef DEBUGMODE
5c449fde 3337 log("Old timestamp for %s: %ld", p->name.c_str(), p->lastcommand);
0b6098d5 3338 #endif
40251952 3339 p->lastcommand = time(NULL);
0b6098d5 3340 #ifdef DEBUGMODE
5c449fde 3341 log("New timestamp for %s: %ld", p->name.c_str(), p->lastcommand);
0b6098d5 3342 #endif
3343
40251952 3344}
3345
3346bool timedOut(Player *p)
3347{
3348 if (!p)
3349 return false;
0b6098d5 3350 else if (p->lastcommand == 0)
3351 return false;
40251952 3352 else
0b6098d5 3353 {
3354 if ((time(NULL) - p->lastcommand) >= maxidletime)
3355 return true;
3356
3357 return false;
3358 }
40251952 3359}
3360
3361void timeOutEvent(Player *p)
3362{
5c449fde 3363 aClient *user = findplayer(p->name.c_str());
40251952 3364
ae2685f6 3365 if (!user || !p->client) // then they're not playing
40251952 3366 return;
3367
3368 char *nick = user->getNick();
3369
0b6098d5 3370 if (player_fight(user) && isYourTurn(p))
3371 {
3372 // Check to see if they were the idler or if it was the other
3373 // person
3374 if (p->lastcommand != p->battle->stats->lastcommand)
3375 {
3376 // This person's last command was given earlier,
3377 // so this person is the idler
3378 notice(s_GameServ, nick, "You timed out "\
3379 "during a fight. You lose your turn!");
3380 notice(s_GameServ, p->battle->getNick(),
5c449fde 3381 "%s hesitated for too long. Your move.", p->name.c_str());
0b6098d5 3382 clearYourTurn(p);
3383 setYourTurn(p->battle->stats);
3384
3385 // Update the TS for both players to give them another
3386 // Chance to wake up, but if the other player doesn't
3387 // Attack now, they both get logged out.
3388 updateTS(p);
3389 p->battle->stats->lastcommand = p->lastcommand;
3390 display_players(p->battle);
3391 return;
3392 }
3393 else
3394 {
3395 notice(s_GameServ, p->battle->getNick(),
3396 "You and %s timed out at the same time."\
3397 " Don't fight if you're just going to "\
5c449fde 3398 "sit there!", p->name.c_str());
0b6098d5 3399 notice(s_GameServ, user->getNick(),
3400 "You and %s timed out at the same time."\
3401 " Don't fight if you're just going to "\
5c449fde 3402 "sit there!", p->battle->stats->name.c_str());
0b6098d5 3403 logout(p->battle);
3404 logout(user);
3405 return;
3406 }
3407 }
3408 else if (!player_fight(user))
eb7608de 3409 {
c047f947 3410 if (isAlive(user->stats) && user->stats->gold > 0)
903cd861 3411 {
eb7608de 3412 // Place fun stuff here :)
3413 int randnum = 1 + rand() % 100; // 1-100
0b259dff 3414 #define GSN(s) notice(s_GameServ, nick, s)
3415 #define GSN2(s, f) notice(s_GameServ, nick, s, f)
eb7608de 3416
3417 if (randnum < 50)
3418 {
0b259dff 3419 // 35-100% of your gold goes pffft - kain
3420 int stolen = (35 + (rand() % 66)) * user->stats->gold / 100;
3421
eb7608de 3422 GSN("You stop for a moment to rest on the "\
3423 "street corner. All of a sudden, you "\
3424 "are ambushed from all sides by a hoarde "\
3425 "of knife wielding thugs.");
3426 GSN2("The thugs beat you into utter submission "\
3427 "and steal %d gold from you!", stolen);
3428 user->stats->gold -= stolen;
3429 }
0b259dff 3430 else if (randnum >= 50 && randnum < 75)
3431 {
3432 // 25-65% of your gold goes pffft - kain
3433 int stolen = (25 + (rand() % 41)) * user->stats->gold / 100;
3434 GSN("While dilly dallying around, you lose "\
3435 "your sense of time. Little did you know, "\
3436 "but thieves lifted your gold while you "\
3437 "weren't watching.");
3438 GSN2("Better luck next time... you lose %d gold", stolen);
3439 user->stats->gold -= stolen;
3440 }
3441 else if (randnum >= 75)
3442 {
3443 // 25-75% of your gold goes pffft - kain
3444 int stolen = (25 + (rand() % 51)) * user->stats->gold / 100;
3445 GSN("Good grief! A gaggle of gooey green ghostlike "\
3446 "goblins grabbed your gold!");
3447 GSN2("They stole %d gold from you!", stolen);
3448 user->stats->gold -= stolen;
3449 }
903cd861 3450 }
eb7608de 3451
3452 // Always log out the user
0b6098d5 3453 logout(user);
eb7608de 3454 }
40251952 3455}
3456
ee38284f 3457void do_reset(char *u)
3458{
3459 char *nick = strtok(NULL, " ");
3460 aClient *user;
3461
3462 if (!(user = find(u)))
3463 {
3464 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
5d04eb42 3465 log("Error: aClient not found: %s", u);
ee38284f 3466 return;
3467 }
3468 else if (!isAdmin(user))
3469 {
3470 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3471 return;
3472 }
448a1531 3473
ee38284f 3474 if (!nick)
3475 {
3476 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
3477 return;
3478 }
3479 else if (stricmp(nick, "ALL") == 0)
3480 {
3481 notice(s_GameServ, u, "Resetting everyone's stats!");
3482 resetall();
3483 }
082f064d 3484 else if ((user = findplayer(nick)))
ee38284f 3485 {
3486 if (is_playing(user))
3487 {
ce61cdfa 3488 #ifdef P10
3489 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
3490 #else
ee38284f 3491 notice(s_GameServ, u, "Resetting %s.", user->getNick());
ce61cdfa 3492 #endif
ee38284f 3493 reset(user->stats);
3494 }
3495 else
3496 {
5c449fde 3497 notice(s_GameServ, u, "Resetting %s", user->stats->name.c_str());
082f064d 3498 reset(user->stats);
ee38284f 3499 }
3500 }
3501 else
3502 {
3503 notice(s_GameServ, u, "Nick %s not found.", nick);
3504 return;
3505 }
3506}
3507
c7340cbd 3508void do_help(char *u)
3509{
3510 char *cmd = strtok(NULL, " ");
3511
c7340cbd 3512 display_help(u, cmd);
3513}
3514
3515void display_help(char *u, char *file)
3516{
3517 ifstream infile;
3518 char *buf;
3519
3520 if (!file)
3521 {
3522 infile.open("helpfiles/help");
3523 if (infile.fail())
3524 {
fb37ecc7 3525 log("Error opening helpfiles/help");
c7340cbd 3526 notice(s_GameServ, u, "Error opening helpfiles/help");
3527 return;
3528 }
3529 buf = new char[1024];
3530 while(infile.getline(buf, 1024))
3531 {
3532 // Written this way, it will process %S in the helpfiles
3533 // Instead of notice(s_GameServ, u, "%s", buf);
3534 notice(s_GameServ, u, buf);
3535 }
3536
3537 // Minor recursion
96f71fee 3538 aClient *user = find(u);
3539 if (user && isAdmin(user))
3540 display_help(u, "admin_commands");
c7340cbd 3541 }
3542 else
3543 {
3544 char *filename;
f27a378f 3545 filename = new char[strlen(file) + 11];
3546 strcpy(filename, "helpfiles/");
3547 strcat(filename, file);
4dde2ed9 3548
f27a378f 3549 for (unsigned int x = 10; x < strlen(filename); x++)
3550 filename[x] = tolower(filename[x]);
4dde2ed9 3551
c7340cbd 3552 infile.open(filename);
3553 delete [] filename;
3554 if (infile.fail())
3555 {
3556 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
3557 return;
3558 }
3559 buf = new char[1024];
3560 while(infile.getline(buf, 1024))
3561 {
3562 // Written this way, it will process %S in the helpfiles
3563 // Instead of notice(s_GameServ, u, "%s", buf);
3564 notice(s_GameServ, u, buf);
3565 }
3566 }
3567 infile.close();
3568 delete [] buf;
3569}
96f71fee 3570
3571void do_admin(char *u)
3572{
3573 aClient *user;
3574 char *pass = strtok(NULL, " ");
3575
3576 if (!(user = find(u)))
3577 {
5d04eb42 3578 log("Error: aClient not found: %s", u);
96f71fee 3579 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
3580 return;
3581 }
448a1531 3582
96f71fee 3583 if (!pass)
3584 {
3585 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
3586 return;
3587 }
3588
1af35752 3589 if (isAdmin(user))
3590 {
3591 notice(s_GameServ, u, "You already have administrator privledges.");
3592 return;
3593 }
3594 else if (strcmp(pass, adminpass) == 0)
96f71fee 3595 {
3596 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
3597 setAdmin(user);
ce61cdfa 3598 #ifdef P10
3599 log("%s became an administrator.", user->getRealNick());
3600 #else
5d04eb42 3601 log("%s became an administrator.", user->getNick());
ce61cdfa 3602 #endif
96f71fee 3603 }
3604 else
3605 {
3606 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
3607 return;
3608 }
3609}
1af35752 3610
ea93c39a 3611bool load_levels()
3612{
3613 char *filename;
3614 filename = new char[256];
3615
3616 for (int x = 1; x <= LEVELS; x++)
3617 {
3618 sprintf(filename, "data/levels/level%d.dat", x);
3619 if (levels[x - 1].loadLevel(filename) == false)
3620 return false;
3621 }
3622
3623 delete []filename;
3624 return true;
3625}
4dde2ed9 3626bool load_monsters()
3627{
bf3a2ff9 3628 char *filename;
4dde2ed9 3629 ifstream infile;
4dde2ed9 3630 char *buf;
bf3a2ff9 3631 buf = new char[2048];
4dde2ed9 3632
bf3a2ff9 3633 for (int level = 1; level <= LEVELS; level++)
3634 {
3635 filename = new char[256];
b5cea1ad 3636 sprintf(filename, "data/monsters/level%d.dat", level);
bf3a2ff9 3637 infile.open(filename);
3638
3639 if (!infile)
4dde2ed9 3640 {
bf3a2ff9 3641 log("Error opening %s", filename);
4dde2ed9 3642 return false;
3643 }
4dde2ed9 3644
5d04eb42 3645 #ifdef DEBUGMODE
bf3a2ff9 3646 log("Loading monsters from %s", filename);
5d04eb42 3647 #endif
3648
bf3a2ff9 3649 while (infile.getline(buf, 2048))
4dde2ed9 3650 {
bf3a2ff9 3651 if (buf[0] == '^')
3652 break;
4dde2ed9 3653 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
3654 continue;
bf3a2ff9 3655 Monster *temp;
3656 temp = new Monster;
3657
5c449fde 3658 temp->name = strtok(buf, "~");
3659 temp->weapon = strtok(NULL, "~");
3660 temp->death = strtok(NULL, "~");
bf3a2ff9 3661
42106907 3662 levels[level - 1].monsters.insertAtBack_RLN(temp);
bf3a2ff9 3663 delete temp;
4dde2ed9 3664 }
bf3a2ff9 3665 delete [] filename;
3666 infile.close();
4dde2ed9 3667 }
3668 delete [] buf;
3669return true;
3670}