]> jfr.im git - irc/gameservirc.git/blame - gameserv/gameserv.cpp
Added pidfile to extern.h... somehow my compiler didn't catch this.
[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"
96f71fee 6#include "sockhelp.h"
7
85ce9d3e 8#include <cctype>
fb37ecc7 9#include <fstream>
10
11using std::ifstream;
12using std::ofstream;
c1068b6e 13
14#if defined(HAVE_CRYPT_H)
15
e3c5fe46 16#include <crypt.h>
85ce9d3e 17
c1068b6e 18#elif defined(HAVE_UNISTD_H)
19
20#include <unistd.h>
21
22#endif
c8ada07e 23
85ce9d3e 24List<aClient> players;
fc9d2643 25
c8ada07e 26Monster *monsters[LEVELS][MONSTERS]; // Monsters per level. Total = MONSTERS * LEVELS
27
28Monster *masters[LEVELS]; // A master for each level
85ce9d3e 29
a8fb9757 30// Database functions
85ce9d3e 31int save_gs_dbase();
32int load_gs_dbase();
33
34// String functions
653c4f62 35#ifndef HAVE_STRTOK
85ce9d3e 36char *strtok(char *str, const char *delim);
653c4f62 37#endif
38
85ce9d3e 39int stricmp(const char *s1, const char *s2);
40int strnicmp(const char *s1, const char *s2, size_t len);
41// String Functions
42
e3c5fe46 43
44/********** Password functions **********/
45
46bool passcmp(char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
47
48bool check_password(char *name, char *plaintext); // Finds a password for the given name, and checks it with passcmp against the plaintext password given.
49
50/********** Password functions **********/
51
52
53/********** GameServ Booleans **********/
54
55bool is_playing(char *u); // True if the given nickname in the clients list is playing.
1af35752 56bool is_playing(aClient *user);
57
e3c5fe46 58bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
1af35752 59bool is_fighting(aClient *user);
60
e3c5fe46 61bool player_fight(char *u); // True if the player is fighting another player.
1af35752 62bool player_fight(aClient *user);
63
e3c5fe46 64bool master_fight(char *u); // True if the player is fighting their master.
1af35752 65bool master_fight(aClient *user);
e3c5fe46 66
67/********** GameServ Booleans **********/
85ce9d3e 68
c7340cbd 69void display_help(char *u, char *file = NULL);
85ce9d3e 70void display_monster(char *u);
71void display_players(char *u);
83cf716f 72void display_players(aClient *user);
85ce9d3e 73long int chartoint(char ch);
74int isstringnum(char *num);
75long int pow (int x, int y);
76long int stringtoint(char *number);
77
78char *spaces(int len, char *seperator);
44ea29f7 79void refresh(Player *p);
85ce9d3e 80void refreshall();
ee38284f 81void reset(Player *p);
c8ada07e 82void init_masters();
85ce9d3e 83void init_monsters();
4dde2ed9 84bool load_monsters();
c8ada07e 85void delete_monsters();
86void delete_masters();
85ce9d3e 87
96f71fee 88void do_admin(char *u);
c7340cbd 89void do_attack(char *u);
90void do_bank(char *u);
91void do_fight(char *u);
92void do_heal(char *u);
93void do_help(char *u);
85ce9d3e 94void do_identify(char *u);
9cda831c 95void do_inventory(char *u);
c7340cbd 96void do_refresh(char *u);
97void do_register(char *u);
98void do_list(char *u);
99void do_master(char *u);
85ce9d3e 100void do_play(char *u);
101void do_quitg(char *u);
102void do_reset(char *u);
85ce9d3e 103void do_run(char *u);
85ce9d3e 104void do_stats(char *u);
c7340cbd 105void do_store(char *u);
f5c25639 106void do_tavern(char *u);
83cf716f 107void do_use(char *u);
c7340cbd 108void see_master(char *u);
85ce9d3e 109
110void showstats(const char *u, const char *nick);
c62d75be 111void showinventory(aClient *from, aClient *to);
e282e9d2 112void showBankBalance(const char *u);
83cf716f 113void end_turn(aClient *user);
85ce9d3e 114
115#define WNA 16
116char *weapons[WNA] = { "Fists", "Stick", "Dagger", "Quarterstaff", "Short Sword",
117 "Long Sword", "Silver Spear", "Battle Axe", "The Ragnarok",
118 "Chain Saw", "Poison Sword", "Flame Sword", "Earth Hammer",
119 "Light Saber", "Masamune", "Mystical Sword"};
120
121char *armors[WNA] = { "Nothing", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor",
122 "Full Body Armor", "Magic Mail", "Graphite Suit", "Steel Suit",
123 "Force Field", "Armor of Light", "Mythril Vest", "DemiGod Armor",
e7a0d0ab 124 "Hades' Cloak", "Dragon Scales", "Adamantium"};
85ce9d3e 125
126int prices[WNA - 1] = {200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000,
127 1000000, 4000000, 10000000, 40000000, 100000000, 400000000};
128int webonus[WNA] = {0, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
129int arbonus[WNA] = {0, 1, 3, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000};
130
131int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550};
132int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200};
133int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
134
85ce9d3e 135void gameserv(char *source, char *buf)
136{
28f552b8 137 char *cmd;
85ce9d3e 138 cmd = strtok(buf, " ");
139
fc9d2643 140 #ifndef P10
141 source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
142 #endif
143
144 if (cmd[0] == ':')
145 cmd++; // Get rid of that : at the beginning of the :text (command)
85ce9d3e 146
9f8c2acc 147 #ifdef DEBUGMODE
148 log("Source: %s Command: %s", source, cmd);
149 #endif
150
abbfcdb9 151 struct tm *tm;
152 time_t ti;
153 time(&ti);
154 tm = localtime(&ti);
44ea29f7 155
abbfcdb9 156 int curday = tm->tm_mday;
157
158 if (curday != day)
44ea29f7 159 {
160 refreshall();
abbfcdb9 161 day = curday;
162 save_day();
44ea29f7 163 }
164
0eeaca4c 165 if (strnicmp(cmd, "\1PING", 6) == 0)
85ce9d3e 166 {
44ea29f7 167 char *ts;
168 ts = strtok(NULL, "\1");
169 notice(s_GameServ, source, "\1PING %s\1", ts);
0eeaca4c 170 } else if (stricmp(cmd, "\1VERSION\1") == 0) {
173302fe 171 notice(s_GameServ, source, "\1VERSION %s %s +devel\1", PACKAGE, VERSION);
85ce9d3e 172 } else if (stricmp(cmd, "SEARCH") == 0) {
173 cmd = strtok(NULL, " ");
174
175 if (!cmd)
176 notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
177 else
178 do_forest(source);
1af35752 179
85ce9d3e 180 } else if (stricmp(cmd, "FIGHT") == 0) {
181 do_fight(source);
182 } else if (stricmp(cmd, "ATTACK") == 0) {
183 do_attack(source);
c8ada07e 184 } else if (stricmp(cmd, "RUN") == 0) {
185 do_run(source);
83cf716f 186 } else if (stricmp(cmd, "USE") == 0) {
187 do_use(source);
85ce9d3e 188 } else if (stricmp(cmd, "HEAL") == 0) {
189 do_heal(source);
9cda831c 190 } else if (stricmp(cmd, "INVENTORY") == 0) {
191 do_inventory(source);
ab4f4ec0 192 } else if (stricmp(cmd, "MASTER") == 0) {
193 do_master(source);
ad7dfaa0 194 } else if (stricmp(cmd, "STORE") == 0) {
195 do_store(source);
8c126acc 196 } else if (stricmp(cmd, "BANK") == 0) {
197 do_bank(source);
96f71fee 198 } else if (stricmp(cmd, "ADMIN") == 0) {
199 do_admin(source);
c7340cbd 200 } else if (stricmp(cmd, "REFRESH") == 0) {
96f71fee 201 do_refresh(source);
ee38284f 202 } else if (stricmp(cmd, "RESET") == 0) {
203 do_reset(source);
f5c25639 204 } else if (stricmp(cmd, "TAVERN") == 0) {
205 do_tavern(source);
85ce9d3e 206 } else if (stricmp(cmd, "LIST") == 0) {
207 do_list(source);
fc9d2643 208 #ifdef DEBUGMODE
209 } else if (stricmp(cmd, "PRINT") == 0) {
210 cout << "Printing the clients list:" << endl;
211 clients.print();
212 cout << "\nPrinting the players list:" << endl;
213 players.print();
214 #endif
85ce9d3e 215 } else if (stricmp(cmd, "REGISTER") == 0) {
216 do_register(source);
217 } else if (stricmp(cmd, "IDENTIFY") == 0) {
218 do_identify(source);
219 } else if (stricmp(cmd, "HELP") == 0) {
c7340cbd 220 do_help(source);
85ce9d3e 221 } else if (stricmp(cmd, "STATS") == 0) {
222 do_stats(source);
223 } else if (stricmp(cmd, "SHUTDOWN") == 0) {
96f71fee 224 aClient *user;
225
226 if (!(user = find(source)))
45a84400 227 {
96f71fee 228 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
9f8c2acc 229 log("Error: aClient not found: %s", source);
96f71fee 230 }
231 else if (!isAdmin(user))
232 {
233 notice(s_GameServ, source, "You must be a %S admin to use this command!");
45a84400 234 }
235 else
236 {
96f71fee 237 save_gs_dbase();
23ec3ff4 238 #ifdef P10
ce61cdfa 239 raw("[] SQ %s 0 :leaving: %s used the Shutdown command.", servername, user->getRealNick());
23ec3ff4 240 #else
4e5760fd 241 raw("SQUIT %s :leaving: %s used the Shutdown command.", servername, source);
23ec3ff4 242 #endif
45a84400 243 }
85ce9d3e 244 } else if (stricmp(cmd, "SAVE") == 0) {
96f71fee 245 aClient *user;
246
247 if (!(user = find(source)))
248 {
249 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
9f8c2acc 250 log("Error: aClient not found: %s", source);
96f71fee 251 }
252 else if (!isAdmin(user))
253 {
254 notice(s_GameServ, source, "You must be a %S admin to use this command!");
255 }
256 else
45a84400 257 {
258 save_gs_dbase();
259 }
85ce9d3e 260 } else if (stricmp(cmd, "LOAD") == 0) {
96f71fee 261 aClient *user;
262
263 if (!(user = find(source)))
264 {
265 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
5d04eb42 266 log("Error: aClient not found: %s", source);
96f71fee 267 }
268 else if (!isAdmin(user))
269 {
270 notice(s_GameServ, source, "You must be a %S admin to use this command!");
271 }
272 else
45a84400 273 {
4dde2ed9 274 char *cmd2 = strtok(NULL, " ");
275 if (!cmd2)
276 {
277 notice(s_GameServ, source, "Loading player data from %s", playerdata);
278 load_gs_dbase();
279 }
280 else if (stricmp(cmd2, "MONSTERS") == 0)
281 {
282 notice(s_GameServ, source, "Loading monster data from %s", monsterdata);
283 load_monsters();
284 }
285 else
286 display_help(source, cmd);
45a84400 287 }
85ce9d3e 288 } else if (stricmp(cmd, "RAW") == 0) {
96f71fee 289 aClient *user;
290
291 if (!(user = find(source)))
292 {
293 notice(s_GameServ, source, "Error: aClient not found. Contact a %S admin");
9f8c2acc 294 log("Error: aClient not found: %s", source);
96f71fee 295 }
296 else if (!isAdmin(user))
297 {
298 notice(s_GameServ, source, "You must be a %S admin to use this command!");
299 }
300 else
45a84400 301 {
302 char *rest = strtok(NULL, "");
303 raw("%s", rest);
304 }
42ec1800 305 } else {
306 notice(s_GameServ, source, "Unknown command \002%s\002. Type /msg %S \002HELP\002 to get a list of commands.", cmd);
c7340cbd 307 }
85ce9d3e 308
c7340cbd 309 source--; // Bring the ':' back so we don't leak memory
85ce9d3e 310 cmd--; // Same thing :)
311}
312
313int stricmp(const char *s1, const char *s2)
314{
315 register int c;
316
317 while ((c = tolower(*s1)) == tolower(*s2)) {
318 if (c == 0)
319 return 0;
320 s1++;
321 s2++;
322 }
323 if (c < tolower(*s2))
324 return -1;
325 return 1;
326}
327
328void showstats(const char *u, const char *nick)
329{
330 aClient *ni, *sender = find(u);
331 char *buf;
332 buf = new char[50];
333 char *space;
334
335
73c71976 336 if (!(ni = findplayer(nick)))
85ce9d3e 337 {
338 notice(s_GameServ, u, "%s not found", nick);
339 }
340 else if (ni->stats)
341 {
85ce9d3e 342 notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name);
343
344 sprintf(buf, "Experience: %ld", ni->stats->exp);
345 space = spaces(strlen(buf), " ");
346 notice(s_GameServ, sender->getNick(), "%s%sLevel: %d", buf, space,
347 ni->stats->level);
1cf88153 348 delete [] space;
85ce9d3e 349
350 sprintf(buf, "Gold: %ld", ni->stats->gold);
351 space = spaces(strlen(buf), " ");
352 notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, ni->stats->bank);
1cf88153 353 delete [] space;
85ce9d3e 354
c7340cbd 355 notice(s_GameServ, sender->getNick(), "Hit Points: %d of %d", ni->stats->hp,
85ce9d3e 356 ni->stats->maxhp);
357
358 sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->weapon]);
359 space = spaces(strlen(buf), " ");
360 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
361 buf, space, ni->stats->defense + arbonus[ni->stats->armor]);
1cf88153 362 delete [] space;
85ce9d3e 363
364 sprintf(buf, "Armor: %s", armors[ni->stats->armor]);
365 space = spaces(strlen(buf), " ");
366 notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
367 weapons[ni->stats->weapon]);
1cf88153 368 delete [] space;
85ce9d3e 369
370 sprintf(buf, "Forest Fights: %d", ni->stats->forest_fights);
371 space = spaces(strlen(buf), " ");
372 notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->player_fights);
1cf88153 373 delete [] space;
85ce9d3e 374 }
73c71976 375 else
376 {
377 notice(s_GameServ, u, "%s is not playing!", ni->stats->name);
378 }
1cf88153 379 delete [] buf;
85ce9d3e 380}
381
382char *spaces(int len, char *seperator)
383{
384 char *final;
42ec1800 385 final = new char[30];
85ce9d3e 386 int y;
387 strcpy(final, seperator);
42ec1800 388 for (y = 0; y < 30 - len; y++)
85ce9d3e 389 strcat(final, seperator);
390 return final;
391}
392
393void raw(const char *fmt, ...)
394{
395 va_list args;
396 char *input;
397 const char *t = fmt;
398 input = new char[1024];
399 va_start(args, fmt);
400 memset(input, 0, sizeof(input)); // Initialize to NULL
401 for (; *t; t++)
402 {
403 if (*t == '%')
404 {
405 switch(*++t) {
406 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
407 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
408 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
409 case 'l':
410 if (*++t == 'd')
411 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
412 }
413 }
414 else
415 {
416 sprintf(input, "%s%c", input, *t);
417 }
418
419 }
9f8c2acc 420 #ifdef DEBUGMODE
421 log("Input: %s", input);
422 #endif
423
85ce9d3e 424 sprintf(input, "%s%s", input, "\r\n");
85ce9d3e 425 sock_puts(sock, input);
1cf88153 426 delete [] input;
85ce9d3e 427 va_end(args);
428}
429/* Send a NOTICE from the given source to the given nick. */
430
431void notice(const char *source, const char *dest, const char *fmt, ...)
432{
c7340cbd 433 if (fmt[0] == '\0')
434 return;
435
85ce9d3e 436 va_list args;
437 char *input;
438 const char *t = fmt;
439 input = new char[1024];
440 va_start(args, fmt);
441 if (dest[0] == ':')
442 {
443 dest++;
ba2a880f 444
445 #if !defined(P10)
85ce9d3e 446 sprintf(input, ":%s NOTICE %s :", source, dest);
ba2a880f 447 #else
fc9d2643 448 sprintf(input, "%s O %s :", gsnum, dest);
ba2a880f 449 #endif
450
85ce9d3e 451 dest--;
452 }
453 else
ba2a880f 454 {
455 #if !defined(P10)
85ce9d3e 456 sprintf(input, ":%s NOTICE %s :", source, dest);
ba2a880f 457 #else
fc9d2643 458 sprintf(input, "%s O %s :", gsnum, dest);
ba2a880f 459 #endif
460 }
85ce9d3e 461
462 for (; *t; t++)
463 {
464 if (*t == '%')
465 {
466 switch(*++t) {
467 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
468 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
469 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
470 case 'l':
471 if (*++t == 'd')
472 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
473 }
474 }
475 else
476 {
477 sprintf(input, "%s%c", input, *t);
478 }
479
480 }
9f8c2acc 481 #ifdef DEBUGMODE
482 log("Input: %s", input);
483 #endif
85ce9d3e 484 sprintf(input, "%s%s", input, "\r\n");
85ce9d3e 485 sock_puts(sock, input);
1cf88153 486 delete [] input;
85ce9d3e 487va_end(args);
488}
489
490
491int strnicmp(const char *s1, const char *s2, size_t len)
492{
493 register int c;
494
495 if (!len)
496 return 0;
497 while ((c = tolower(*s1)) == tolower(*s2) && len > 0) {
498 if (c == 0 || --len == 0)
499 return 0;
500 s1++;
501 s2++;
502 }
503 if (c < tolower(*s2))
504 return -1;
505 return 1;
506}
507
653c4f62 508#ifndef HAVE_STRTOK
85ce9d3e 509char *strtok(char *str, const char *delim)
510{
511 static char *current = NULL;
512 char *ret;
513
514 if (str)
515 current = str;
516 if (!current)
517 return NULL;
518 current += strspn(current, delim);
519 ret = *current ? current : NULL;
520 current += strcspn(current, delim);
521 if (!*current)
522 current = NULL;
523 else
524 *current++ = 0;
525 return ret;
526}
653c4f62 527#endif
85ce9d3e 528
529void do_list(char *u)
530{
531 ListNode<aClient> *temp;
532 temp = players.First();
533 if (!players.isEmpty())
534 {
535 notice(s_GameServ, u, "People Playing:");
536 while(temp)
537 {
ce61cdfa 538
539 #ifdef P10
540 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getRealNick(),
541 temp->getData()->stats->name);
542 #else
543 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(),
544 temp->getData()->stats->name);
545 #endif
546
85ce9d3e 547 temp = temp->Next();
548 }
549 notice(s_GameServ, u, "End of List");
550 }
551 else
552 notice(s_GameServ, u, "No one is playing");
553}
1af35752 554
85ce9d3e 555void do_register(char *u)
556{
e1c41a84 557 char *password, *name;
f27a378f 558 aClient *user, *p;
e1c41a84 559 name = strtok(NULL, " ");
85ce9d3e 560 password = strtok(NULL, " ");
561
e3c5fe46 562 static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
563 static char salt[3];
564
565 salt[0] = saltChars[rand() % strlen(saltChars)];
566 salt[1] = saltChars[rand() % strlen(saltChars)];
f27a378f 567 salt[2] = '\0';
e3c5fe46 568
e1c41a84 569 if (!name)
570 {
571 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
572 }
573 else if (!password)
85ce9d3e 574 {
e1c41a84 575 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER NAME PASSWORD");
85ce9d3e 576 }
28f552b8 577 else if ((user = find(u)))
85ce9d3e 578 {
f27a378f 579 p = findplayer(u);
580 if (!user->stats && !p)
85ce9d3e 581 {
582 user->stats = new Player(user);
85ce9d3e 583 user->stats->user = user; // Set the backwards pointer
e3c5fe46 584 strcpy(user->stats->password, crypt(password, salt));
e1c41a84 585 strcpy(user->stats->name, name);
85ce9d3e 586 players.insertAtBack(user);
c7340cbd 587 notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name, password);
588 notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!");
5d04eb42 589 log("Nickname %s registered player %s.", u, user->stats->name);
85ce9d3e 590 }
591 else
592 {
593 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
594 }
595 }
596}
597
598void do_identify(char *u)
599{
0a1518fa 600 char *password, *name;
601 aClient *user, *p;
602 name = strtok(NULL, " ");
85ce9d3e 603 password = strtok(NULL, " ");
20d5d721 604 user = find(u);
0a1518fa 605 if (!password || !name)
85ce9d3e 606 {
0a1518fa 607 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
85ce9d3e 608 }
20d5d721 609 else if (!user)
5d04eb42 610 {
611 notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, ""));
612 log("Error: aClient not found: %s", u);
613 }
0a1518fa 614 else if (!(p = findplayer(name)) || !p->stats)
615 notice(s_GameServ, u, "Player %s not found", name);
20d5d721 616 else if (!check_password(name, password) && !isAdmin(user))
85ce9d3e 617 {
0a1518fa 618 notice(s_GameServ, u, "Password incorrect");
85ce9d3e 619 }
20d5d721 620 else
85ce9d3e 621 {
20d5d721 622 if (p->stats->user && !isAdmin(user))
623 {
624 notice(s_GameServ, u, "That player has already identified.");
625 return;
626 }
85ce9d3e 627 if (!user->stats)
628 {
1cf88153 629 ListNode<aClient> *temp;
630 temp = players.Find(p);
631 if (!temp)
632 {
633 notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s",
634 strtok(NULL, ""));
635 return;
636 }
cdc9a6db 637 user->stats = new Player(p->stats->name);
9f8c2acc 638 #ifdef DEBUGMODE
639 log("Setting data for identified");
640 #endif
1cf88153 641 user->stats->setData(p->stats);
9f8c2acc 642
643 #ifdef DEBUGMODE
644 log("Player Identified");
645 #endif
cdc9a6db 646
647 temp->setPtr(user);
648
649 notice(s_GameServ, u, "Password Accepted. Identified.");
1cf88153 650
85ce9d3e 651 }
652 else
653 {
654 notice(s_GameServ, u, "Already identified. Contact a %S admin for help.");
655 }
656 }
657}
658
659void do_stats(char *u)
660{
661 char *nick;
73c71976 662 aClient *user;
85ce9d3e 663
664 nick = strtok(NULL, " ");
85ce9d3e 665
666 if (!nick)
73c71976 667 {
668 if (!(user = find(u)))
669 {
670 notice(s_GameServ, u, "Fatal Error in do_stats(). Contact a %S admin for help!");
5d04eb42 671 log("Error: aClient not found: %s", u);
73c71976 672 return;
673 }
674 else if (!is_playing(user))
675 {
676 notice(s_GameServ, u, "You're not playing, so you have no stats!");
677 return;
678 }
679 else
680 showstats(u, user->stats->name);
681 }
85ce9d3e 682 else
683 showstats(u, nick);
684}
ad7dfaa0 685void init_masters()
686{
5d04eb42 687 #ifdef DEBUGMODE
688 log("Calling delete_masters()");
689 #endif
690
ab4f4ec0 691 delete_masters();
c8ada07e 692
5d04eb42 693 #ifdef DEBUGMODE
694 log("Initializing masters");
695 #endif
696
c8ada07e 697 for (int x = 0; x < LEVELS; x++)
698 masters[x] = new Monster;
699
700 strcpy(masters[0]->name, "Old Bones");
701 strcpy(masters[0]->weapon, "Dull Sword Cane");
c7340cbd 702 masters[0]->strength = 15;
c8ada07e 703 masters[0]->gold = 0;
704 masters[0]->exp = 0;
705 masters[0]->maxhp = 30;
e282e9d2 706 masters[0]->hp = 30;
c8ada07e 707 strcpy(masters[0]->death, "You have done well my student, but the road is long. Use your new strength with humility and honor as you progress in levels!");
e282e9d2 708
c8ada07e 709 strcpy(masters[1]->name, "Master Chang");
710 strcpy(masters[1]->weapon, "Nanchaku");
c7340cbd 711 masters[1]->strength = 30;
c8ada07e 712 masters[1]->gold = 0;
713 masters[1]->exp = 0;
714 masters[1]->maxhp = 40;
e282e9d2 715 masters[1]->hp = 40;
c8ada07e 716 strcpy(masters[1]->death, "You try to make out what Master Chang is saying, but the only thing you catch is something about a grasshopper.");
717
718 strcpy(masters[2]->name, "Chuck Norris");
719 strcpy(masters[2]->weapon, "Ranger Kick");
720 masters[2]->strength = 85;
721 masters[2]->gold = 0;
722 masters[2]->exp = 0;
723 masters[2]->maxhp = 70;
e282e9d2 724 masters[2]->hp = 70;
c8ada07e 725 strcpy(masters[2]->death, "Be strong, and keep your goals in site. Drink milk, and don't do drugs. One day you may be fighting next to me as a Texas Ranger YEEHAW!");
726
727
728 strcpy(masters[3]->name, "Mr. Miagi");
729 strcpy(masters[3]->weapon, "Petrified Bonsai");
9b17b158 730 masters[3]->strength = 120;
c8ada07e 731 masters[3]->gold = 0;
732 masters[3]->exp = 0;
733 masters[3]->maxhp = 120;
e282e9d2 734 masters[3]->hp = 120;
c8ada07e 735 strcpy(masters[3]->death, "Skill comes from repeating the correct but seemingly mundane actions. Wax ON, wax OFF!");
736
737 strcpy(masters[4]->name, "Jackie Chan");
e282e9d2 738 strcpy(masters[4]->weapon, "Kung Fu Kick");
9b17b158 739 masters[4]->strength = 135;
c8ada07e 740 masters[4]->gold = 0;
741 masters[4]->exp = 0;
e282e9d2 742 masters[4]->maxhp = 200;
743 masters[4]->hp = 200;
c8ada07e 744 strcpy(masters[4]->death, "I like to let people talk who like to talk... it's easier to find out how full of it they really are!");
745
746 strcpy(masters[5]->name, "Jet Li");
747 strcpy(masters[5]->weapon, "Motorcycle");
9b17b158 748 masters[5]->strength = 160;
c8ada07e 749 masters[5]->gold = 0;
750 masters[5]->exp = 0;
e282e9d2 751 masters[5]->maxhp = 400;
752 masters[5]->hp = 400;
c8ada07e 753 strcpy(masters[5]->death, "Failure is a fuel for excuses. It's the doing the do, that makes the making.");
754
755
756 strcpy(masters[6]->name, "Muhammad Ali");
757 strcpy(masters[6]->weapon, "Quick Jab");
9b17b158 758 masters[6]->strength = 185;
c8ada07e 759 masters[6]->gold = 0;
760 masters[6]->exp = 0;
e282e9d2 761 masters[6]->maxhp = 600;
762 masters[6]->hp = 600;
c8ada07e 763 strcpy(masters[6]->death, "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up.");
764
765 strcpy(masters[7]->name, "Li Mu Bai");
766 strcpy(masters[7]->weapon, "Green Destiny");
9b17b158 767 masters[7]->strength = 210;
c8ada07e 768 masters[7]->gold = 0;
769 masters[7]->exp = 0;
e282e9d2 770 masters[7]->maxhp = 800;
771 masters[7]->hp = 800;
c8ada07e 772 strcpy(masters[7]->death, "No growth without resistance. No action without reaction. No desire without restraint.");
773
774
775 strcpy(masters[8]->name, "Jimmy Wang Yu");
776 strcpy(masters[8]->weapon, "Flying Guillotine");
777 masters[8]->strength = 275;
c8ada07e 778 masters[8]->gold = 0;
779 masters[8]->exp = 0;
e282e9d2 780 masters[8]->maxhp = 1200;
781 masters[8]->hp = 1200;
c8ada07e 782 strcpy(masters[8]->death, "You have beaten the one armed boxer. Proceed with caution!");
783
784 strcpy(masters[9]->name, "Wong Fei Hung");
785 strcpy(masters[9]->weapon, "Drunken Boxing");
9b17b158 786 masters[9]->strength = 360;
c8ada07e 787 masters[9]->gold = 0;
788 masters[9]->exp = 0;
e282e9d2 789 masters[9]->maxhp = 1800;
790 masters[9]->hp = 1800;
791 strcpy(masters[9]->death, "Hiccup! Monkey drinks master's wine!");
c8ada07e 792
793 strcpy(masters[10]->name, "Bruce Lee");
794 strcpy(masters[10]->weapon, "Fists of fury");
795 masters[10]->strength = 575;
c8ada07e 796 masters[10]->gold = 0;
797 masters[10]->exp = 0;
e282e9d2 798 masters[10]->maxhp = 2500;
799 masters[10]->hp = 2500;
c8ada07e 800 strcpy(masters[10]->death, "You must learn to concentrate. It is like a finger pointing away to the moon... DONT concentrate on the finger, or you will miss all the heavenly glory.");
ad7dfaa0 801}
85ce9d3e 802
803void init_monsters()
804{
5d04eb42 805 #ifdef DEBUGMODE
806 log("Calling delete_monsters");
807 #endif
808
c8ada07e 809 delete_monsters();
5d04eb42 810
c8ada07e 811 for (int x = 0; x < LEVELS; x++)
812 for (int y = 0; y < MONSTERS; y++)
813 monsters[x][y] = new Monster();
c8ada07e 814}
815
816void delete_monsters()
817{
818 for (int x = 0; x < LEVELS; x++)
819 for (int y = 0; y < MONSTERS; y++)
820 if (monsters[x][y])
821 delete monsters[x][y];
822}
823
824void delete_masters()
825{
826 for (int x = 0; x < LEVELS; x++)
827 if (masters[x])
828 delete masters[x];
85ce9d3e 829}
830
831void display_monster(char *u)
832{
833 if (is_playing(u))
834 {
835 aClient *user = find(u);
836 Player *ni = user->stats;
837
838 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->hp);
839 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name, ni->fight->hp);
840 notice(s_GameServ, u, "Here are your commands:");
841 notice(s_GameServ, u, "/msg %S attack");
842 notice(s_GameServ, u, "/msg %S run");
843 notice(s_GameServ, u, "What will you do?");
844 }
845}
846
847void display_players(char *u)
848{
849 if (is_playing(u))
850 {
851 aClient *ni = find(u);
852
853 aClient *battle = ni->stats->battle;
854
855 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->stats->hp);
ce61cdfa 856 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name,
85ce9d3e 857 battle->stats->hp);
85ce9d3e 858 notice(s_GameServ, u, "Here are your commands:");
83cf716f 859 notice(s_GameServ, u, "/msg %S attack");
860 notice(s_GameServ, u, "/msg %S run");
861 notice(s_GameServ, u, "What will you do?");
862 }
863}
864void display_players(aClient *user)
865{
866 char *u = user->getNick();
867 if (is_playing(user) && player_fight(user))
868 {
869 aClient *battle = user->stats->battle;
870 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", user->stats->hp);
ce61cdfa 871 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name, battle->stats->hp);
83cf716f 872 notice(s_GameServ, u, "Here are your commands:");
873 notice(s_GameServ, u, "/msg %S attack");
874 notice(s_GameServ, u, "/msg %S run");
85ce9d3e 875 notice(s_GameServ, u, "What will you do?");
876 }
877}
878
879
880bool is_playing(char *u)
881{
882 aClient *user;
883 if (!(user = find(u)))
884 {
885 return false;
886 }
887 else
888 {
889 return user->stats != NULL;
890 }
891}
892
1af35752 893bool is_playing(aClient *user)
894{
73c71976 895 return user->stats != NULL && (stricmp(user->getNick(), "!NULL!") != 0);
1af35752 896}
897
85ce9d3e 898bool is_fighting(char *u)
899{
900 aClient *user;
901
902 if (!(user = find(u)))
903 {
904 return false;
905 }
906 else if (user->stats)
907 {
908 return user->stats->fight != NULL || user->stats->battle != NULL
909 || user->stats->master != NULL;
910 }
911 else
912 return false;
913}
1af35752 914bool is_fighting(aClient *user)
915{
916 if (!is_playing(user))
917 return false;
918 else
919 return (user->stats->fight != NULL || user->stats->battle != NULL || user->stats->master != NULL);
920}
85ce9d3e 921
922bool player_fight(char *u)
923{
924 aClient *user;
925
926 if (!(user = find(u)))
927 return false;
928 else if (user->stats)
929 return user->stats->battle != NULL;
930 else
931 return false;
932}
1af35752 933bool player_fight(aClient *user)
934{
935 if (!is_fighting(user))
936 return false;
937 else
938 return user->stats->battle != NULL;
939}
85ce9d3e 940
941bool master_fight(char *u)
942{
943 aClient *user;
944
945 if (!(user = find(u)))
946 return false;
947 else if (user->stats)
948 return user->stats->master != NULL;
949 else
950 return false;
951}
1af35752 952bool master_fight(aClient *user)
85ce9d3e 953{
1af35752 954 if (!is_playing(user))
955 return false;
956 else
957 return user->stats->master != NULL;
85ce9d3e 958}
959
960void do_fight(char *u)
961{
962 aClient *ni, *battle;
963
964 char *nick = strtok(NULL, " ");
965
966 if (!nick)
967 {
968 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
969 }
970 else if (!(ni = find(u)))
971 {
1af35752 972 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
85ce9d3e 973 return;
974 }
ce61cdfa 975 else if (!(battle = findbyrealnick(nick)))
85ce9d3e 976 {
977 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
1902338e 978 return;
85ce9d3e 979 }
1af35752 980 else if (!is_playing(ni))
85ce9d3e 981 {
982 notice(s_GameServ, u, "You are not playing!");
1902338e 983 return;
85ce9d3e 984 }
985/*
986 * Offline fighting not implemented yet.
987 * else if (!(fight = finduser(nick)))
988 * {
989 * ni->stats->battle = battle;
990 * battle->battle = ni;
991 * ni->yourturn = 1;
992 * battle->yourturn = 0;
993 * notice(s_GameServ, u, "You decide to fight %s while they're not online!",
ce61cdfa 994 * battle->stats->name);
85ce9d3e 995 * display_players(u);
996 * }
997 */
ee38284f 998 else if (!isAlive(ni->stats))
1af35752 999 {
1000 notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!");
1001 return;
1002 }
1902338e 1003 else if (player_fight(battle))
1004 {
1005 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->battle->stats->name);
1006 return;
1007 }
1008 else if (is_fighting(battle))
1009 {
1010 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name, battle->stats->fight->name);
1011 return;
1012 }
1af35752 1013 else if (is_playing(ni) && is_playing(battle) && stricmp(ni->stats->name, battle->stats->name) != 0)
85ce9d3e 1014 {
1015 // Set your battle pointer to the other player
1016 ni->stats->battle = battle;
1017
1018 // Set the other player's battle pointer to you
1019 battle->stats->battle = ni;
1020
1021 // The initiator gets the first move (perhaps this should be 50/50)
ee38284f 1022 setYourTurn(ni->stats);
1023 clearYourTurn(battle->stats);
85ce9d3e 1024
1025 // Initiate Battle sequence!
ce61cdfa 1026 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name);
1027 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", ni->stats->name);
1028 notice(s_GameServ, battle->getNick(), "%s gets to go first because he initiated!", ni->stats->name);
1029 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", ni->stats->name);
85ce9d3e 1030 display_players(u);
1031 }
1032}
83cf716f 1033void do_use(char *u)
1034{
1035 aClient *user;
1036 Pouch *p;
1037
1038 char *item = strtok(NULL, " ");
1039
1040 if (!item)
1041 {
1042 notice(s_GameServ, u, "SYNTAX: USE ITEM");
1043 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1044 return;
1045 }
1046 else if (!(user = find(u)))
1047 {
1048 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1049 return;
1050 }
1051 else if (!is_playing(user))
1052 {
1053 notice(s_GameServ, u, "You must be playing to use items!");
1054 return;
1055 }
1056
1057 p = &user->stats->inventory;
1058
1059 if (stricmp(item, "HEALTH") == 0)
1060 {
1061 if (p->Healing() <= 0)
1062 {
1063 notice(s_GameServ, u, "You are out of Health Potions!");
1064 return;
1065 }
1066 int oldhealth = user->stats->hp;
1067 notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
1068 notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
1069 user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
1070 notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealth);
1071 p->decHealing();
1072 }
1073 else if (stricmp(item, "STRENGTH") == 0)
1074 {
1075 if (p->Strength() <= 0)
1076 {
1077 notice(s_GameServ, u, "You are out of Strength Potions!");
1078 return;
1079 }
1080 int oldstrength = user->stats->strength;
1081 notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!");
1082 notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!");
b2641ac4 1083 user->stats->strength += 1 + rand() % 2; // 1 - 2 Strength Added
83cf716f 1084 notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength);
1085 p->decStrength();
1086 }
1087 else if (stricmp(item, "DEFENSE") == 0)
1088 {
1089 if (p->Defense() <= 0)
1090 {
1091 notice(s_GameServ, u, "You are out of Defense Potions!");
1092 return;
1093 }
8c734eb9 1094 int olddefense = user->stats->defense;
83cf716f 1095 notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust.");
1096 notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!");
b2641ac4 1097 user->stats->defense += 1 + rand() % 2; // 1 - 2 Defense Added
83cf716f 1098 notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense);
1099 p->decDefense();
1100 }
8c734eb9 1101 else if (stricmp(item, "HP") == 0)
1102 {
1103 if (p->HP() <= 0)
1104 {
1105 notice(s_GameServ, u, "You are out of HP Potions!");
1106 return;
1107 }
1108 int oldHP = user->stats->maxhp;
1109 notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid.");
1110 user->stats->maxhp += 1 + rand() % 5; // 1 - 5 Maxhp
1111 notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP);
1112 p->decHP();
1113 }
ee38284f 1114 else
1115 {
1116 notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALTH | STRENGTH | DEFENSE}");
1117 return;
1118 }
83cf716f 1119
1120 end_turn(user); // If they're fighting, end their turn
1121}
c8ada07e 1122void do_run(char *u)
1123{
1124 aClient *user;
28f552b8 1125 Player *p, *p2 = NULL;
85ce9d3e 1126
c8ada07e 1127 if (!(user = find(u)))
1128 {
1129 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1130 return;
1131 }
1132
1133 p = user->stats;
1134
1135 if (p->battle)
1136 p2 = p->battle->stats;
1137
1af35752 1138 if (!is_fighting(user))
c8ada07e 1139 notice(s_GameServ, u, "You run in place... try fighting next time.");
1af35752 1140 else if (!player_fight(user) && !master_fight(user))
c8ada07e 1141 {
1142 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name);
1143 delete p->fight;
1144 p->fight = NULL;
1145 }
ee38284f 1146 else if (player_fight(user) && isYourTurn(p))
c8ada07e 1147 {
1148 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name);
1149 notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!", p->name);
1150 p2->battle = NULL;
1151 }
ee38284f 1152 else if (player_fight(user) && !isYourTurn(p))
c8ada07e 1153 {
1154 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.", p2->name);
1155 }
1af35752 1156 else if (master_fight(user))
c8ada07e 1157 {
1158 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name);
1159 }
1160 p->battle = NULL;
1161}
83cf716f 1162
1163void end_turn(aClient *user)
1164{
1165 char *nick, *u = user->getNick();
1166 Monster *fight;
1167 aClient *battle;
1168 int mhit;
1169
1170 nick = new char[strlen(user->getNick()) + 1];
1171
1172 if (!user || !is_playing(user) || !is_fighting(user))
1173 goto endturn;
1174
1175 if (!player_fight(user) && !master_fight(user))
1176 fight = user->stats->fight;
1177 else
1178 fight = user->stats->master;
1179 battle = user->stats->battle;
1180
1181 if (!player_fight(user))
1182 {
1183 // Opponent's Hit
1184 mhit = (fight->strength / 2) +
1185 (rand() % (fight->strength / 2) - (user->stats->defense +
1186 arbonus[user->stats->armor]));
1187 }
1188 else
1189 {
1190 // Opponent's Hit
1191 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1192 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1193 (user->stats->defense + arbonus[user->stats->armor]));
1194 }
1195 if (!player_fight(user))
1196 {
1197
1198 if (mhit > 0)
1199 {
1200 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
1201 fight->name, fight->weapon, mhit);
1202 }
1203 else if (mhit <= 0)
1204 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1205
1206 if (mhit >= user->stats->hp)
1207 {
1208 if (!master_fight(user))
1209 {
1210 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1211 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1212 "of your experience!");
1213 user->stats->gold = 0;
1214 user->stats->exp -= (long int)(user->stats->exp * .10);
1215 user->stats->fight = NULL;
ee38284f 1216 clearAlive(user->stats);
83cf716f 1217 goto endturn;
1218 }
1219 else
1220 {
1221 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1222 "until tomorrow to try again", user->stats->master->name);
1223 user->stats->fight = NULL;
1224 user->stats->master = NULL;
1225 goto endturn;
1226 }
1227 }
1228 else
1229 {
1230 if (mhit > 0)
1231 user->stats->hp -= mhit;
1232 display_monster(u);
1233 goto endturn;
1234 }
1235 }
1236 else
1237 {
ee38284f 1238 clearYourTurn(user->stats);
1239 setYourTurn(battle->stats);
83cf716f 1240 display_players(battle);
1241 }
1242endturn:
1243 delete nick;
1244}
1245
85ce9d3e 1246void do_attack(char *u)
1247{
1248 int hit, mhit;
1249 aClient *ni, *battle; // The player and perhaps the player they're fighting
1250 Monster *fight; // The monster they may be fighting
1251
1252 if (!(ni = find(u)))
83cf716f 1253 {
1254 notice(s_GameServ, u, "Fatal error in do_attack. Contact a(n) %S admin for help.");
1255 return;
1256 }
1257 else if (!is_playing(ni))
85ce9d3e 1258 {
1259 notice(s_GameServ, u, "You're not playing!");
1260 return;
1261 }
83cf716f 1262 else if (!is_fighting(ni))
85ce9d3e 1263 {
1264 notice(s_GameServ, u, "You're not in battle!");
1265 return;
1266 }
1267 else
1268 {
1269 if (!ni->stats->master) // This is not a master fight
1270 fight = ni->stats->fight; // Monster Could be NULL
1271 else // This IS a master fight
1272 fight = ni->stats->master; // Master Could be NULL
1273
1274 battle = ni->stats->battle; // Player Could be NULL
1275
1276 // One has to be !NULL based on the previous else if
1277 // We wouldn't be here if they were all NULL
1278 }
1279
1af35752 1280 if (!player_fight(ni))
85ce9d3e 1281 {
1282 // Player's Hit
1283 hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1284 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
1285
1286 // Opponent's Hit
1287 mhit = (fight->strength / 2) +
1288 (rand() % (fight->strength / 2) - (ni->stats->defense +
1289 arbonus[ni->stats->armor]));
1290 }
1291 else
1292 {
1293 // Opponent's Hit
1294 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1295 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1296 (ni->stats->defense + arbonus[ni->stats->armor]));
1297
1298 // Player's Hit
1299 hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1300 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
1301 (battle->stats->defense + arbonus[battle->stats->armor]));
1302 }
1303
1af35752 1304 if (!player_fight(ni))
85ce9d3e 1305 {
1306 if (hit > 0)
1307 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
1308 else
1309 notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
1310
1311 if (hit >= fight->hp)
1312 {
1af35752 1313 if (master_fight(ni))
85ce9d3e 1314 notice(s_GameServ, u, "You have bested %s!", fight->name);
1315 else
1316 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
1317
1318 notice(s_GameServ, u, "%s", fight->death);
1319 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
1320 fight->exp, fight->gold);
1321
1322 // If your new experience (or gold) will be greater than 2 billion,
1323 // then set your exp to 2bil. (2 billion max)... otherwise add them.
1324 // This could be a problem with overflowing out of the sign bit.
1325 // Unsigned long int maybe? Leave it for now.
1326 ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 :
1327 ni->stats->exp + fight->exp);
ee38284f 1328
85ce9d3e 1329 ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 :
1330 ni->stats->gold + fight->gold);
c8ada07e 1331
85ce9d3e 1332
1af35752 1333 if (master_fight(ni))
85ce9d3e 1334 {
1335 notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
1336 notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
1337 strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
1338
1339 // Increase your level
1340 ni->stats->level++;
1341
1342 // Increase your maximum hit points
1343 ni->stats->maxhp += hpbonus[ni->stats->level - 1];
1344
1345 // Heal the player by setting hp to their max
1346 ni->stats->hp = ni->stats->maxhp;
1347
1348 // Add to your strength
1349 ni->stats->strength += strbonus[ni->stats->level - 1];
1350
1351 // Add to your defensive power
1352 ni->stats->defense += defbonus[ni->stats->level - 1];
1353
1354 // Clear the pointer for your master
1355 ni->stats->master = NULL;
1356 }
ab4f4ec0 1357
1358 // They're dead so remove the pointer
1359 delete ni->stats->fight;
1360 ni->stats->fight = NULL;
1361 ni->stats->master = NULL;
1362
85ce9d3e 1363 return;
1364 }
1365 else
1366 {
1367 if (hit > 0)
1368 fight->hp -= hit;
1369 if (mhit > 0)
1370 {
e282e9d2 1371 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
85ce9d3e 1372 fight->name, fight->weapon, mhit);
1373 }
1374 else if (mhit <= 0)
1375 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1376
1377 if (mhit >= ni->stats->hp)
1378 {
1af35752 1379 if (!master_fight(ni))
85ce9d3e 1380 {
1381 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1382 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1383 "of your experience!");
1384 ni->stats->gold = 0;
1385 ni->stats->exp -= (long int)(ni->stats->exp * .10);
1386 ni->stats->fight = NULL;
ee38284f 1387 clearAlive(ni->stats);
85ce9d3e 1388 return;
1389 }
1390 else
1391 {
1392 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1393 "until tomorrow to try again", ni->stats->master->name);
1394 ni->stats->fight = NULL;
1395 ni->stats->master = NULL;
1396 return;
1397 }
1398 }
1399 else
1400 {
1401 if (mhit > 0)
1402 ni->stats->hp -= mhit;
1403 display_monster(u);
1404 return;
1405 }
1406 }
1407 }
1af35752 1408 else if (player_fight(ni))
85ce9d3e 1409 {
1410/* Offline fighting not available yet
1411 if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
1412 {
1413 if (hit > 0)
1414 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
1415 else
1416 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
1417 if (hit >= battle->stats->hp)
1418 {
1419 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
1420* notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1421 (long int)(battle->stats->exp * .10), battle->stats->gold);
1422 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1423 {
1424 ni->stats->exp += (long int)(battle->stats->exp * .10);
1425 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1426 }
1427* else
1428 {
1429 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1430 ni->stats->exp = 2000000000;
1431 }
1432
1433 if (2000000000 - ni->stats->gold > battle->stats->gold)
1434 {
1435* ni->stats->gold += battle->stats->gold;
1436 battle->stats->gold = 0;
1437 }
1438 else
1439 {
1440 battle->stats->gold = 2000000000 - ni->stats->gold;
1441 ni->stats->gold = 2000000000;
1442 }
1443* ni->stats->battle->stats->alive = 0;
1444 ni->stats->battle->battle = NULL;
1445 ni->stats->battle = NULL;
1446 return;
1447 }
1448 else
1449 {
1450 if (hit > 0)
1451* battle->stats->hp -= hit;
1452 if (mhit > 0)
1453 {
1454 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1455 battle->nick, weapons[battle->stats->weapon], mhit);
1456 }
1457 else if (mhit <= 0)
1458 notice(s_GameServ, u, "%s completely misses you!", battle->nick);
1459*
1460 if (mhit >= ni->stats->hp)
1461 {
1462 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
1463 if (2000000000 - battle->stats->gold > ni->stats->gold)
1464 {
1465 notice(s_GameServ, u, "%s took all your gold!", battle->nick);
1466 battle->stats->gold += ni->stats->gold;
1467* ni->stats->gold = 0;
1468 }
1469 else
1470 {
1471 notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
1472 battle->nick);
1473 ni->stats->gold -= (2000000000 - battle->stats->gold);
1474 notice(s_GameServ, u, "You were left dead with %d gold.",
1475* (long int)ni->stats->gold);
1476 battle->stats->gold = 2000000000;
1477 }
1478 ni->stats->battle->battle = NULL;
1479 ni->stats->battle = NULL;
1480 ni->stats->alive = 0;
1481 return;
1482 }
1483* else
1484 {
1485 if (mhit > 0)
1486 ni->stats->hp -= mhit;
1487 display_players(u);
1488 return;
1489 }
1490 }
1491 }
1492* end offline fighting */
1493
ce61cdfa 1494 if (is_playing(battle))
85ce9d3e 1495 {
ee38284f 1496 if (!isYourTurn(ni->stats))
85ce9d3e 1497 {
1498 notice(s_GameServ, u, "Please wait until %s decides what to do!",
ce61cdfa 1499 battle->stats->name);
85ce9d3e 1500 return;
1501 }
1502 if (hit > 0)
1503 {
ce61cdfa 1504 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->stats->name, hit);
85ce9d3e 1505
1506 notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
ce61cdfa 1507 "\ 2%d\ 2 damage!", ni->stats->name,
1508 weapons[ni->stats->weapon], hit);
ee38284f 1509 clearYourTurn(ni->stats);
1510 setYourTurn(battle->stats);
85ce9d3e 1511 display_players(battle->getNick());
1512 }
1513 else
1514 {
ce61cdfa 1515 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->stats->name);
1516 notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name);
ee38284f 1517 clearYourTurn(ni->stats);
1518 setYourTurn(battle->stats);
85ce9d3e 1519 display_players(battle->getNick());
1520 }
1521 if (hit >= battle->stats->hp)
1522 {
ce61cdfa 1523 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name);
85ce9d3e 1524 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1525 (long int)(battle->stats->exp * .10), battle->stats->gold);
ce61cdfa 1526 notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!",
1527 ni->stats->name);
85ce9d3e 1528 battle->stats->hp = 0;
ee38284f 1529 clearAlive(battle->stats);
85ce9d3e 1530
1531 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1532 {
1533 ni->stats->exp += (long int)(battle->stats->exp * .10);
1534 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1535 }
1536 else
1537 {
1538 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1539 ni->stats->exp = 2000000000;
1540 }
1541
1542 if (2000000000 - ni->stats->gold > battle->stats->gold)
1543 {
1544 notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
1545 "all gold on hand!");
1546 ni->stats->gold += battle->stats->gold;
1547 battle->stats->gold = 0;
1548 }
1549 else
1550 {
1551 battle->stats->gold = 2000000000 - ni->stats->gold;
1552 notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
1553
1554 notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
ce61cdfa 1555 "gold.", ni->stats->name);
85ce9d3e 1556
1557 notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
1558 "left. All is not lost!", battle->stats->gold);
1559
1560 ni->stats->gold = 2000000000;
1561 }
1562 battle->stats->battle = NULL;
1563 ni->stats->battle = NULL;
1564 return;
1565 }
1566 else
1567 {
1568 if (hit > 0)
1569 battle->stats->hp -= hit;
ee38284f 1570 clearYourTurn(ni->stats);
1571 setYourTurn(battle->stats);
85ce9d3e 1572 notice(s_GameServ, u, "Please wait while %s decides what to do!",
ce61cdfa 1573 battle->stats->name);
85ce9d3e 1574
1575 return;
1576 }
1577 }
1578 }
1579}
ce61cdfa 1580
85ce9d3e 1581void do_heal(char *u)
1582{
1583 aClient *ni;
1584 char *amount = strtok(NULL, " ");
1585 int price, num;
1586
1587 if (!amount)
1588 {
1589 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1590 }
1af35752 1591 else if (!(ni = find(u)))
1592 {
1593 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1594 return;
1595 }
1596 else if (!is_playing(ni))
85ce9d3e 1597 {
1598 notice(s_GameServ, u, "You aren't playing!");
1af35752 1599 return;
1600 }
ee38284f 1601 else if (!isAlive(ni->stats))
1af35752 1602 {
1603 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
1604 return;
85ce9d3e 1605 }
1af35752 1606 else if (is_fighting(ni))
85ce9d3e 1607 {
1608 notice(s_GameServ, u, "You can't heal in battle!");
1609 }
1610 else if (ni->stats->hp >= ni->stats->maxhp)
1611 {
1612 notice(s_GameServ, u, "You don't need healing!");
1613 }
1614 else if (stricmp(amount, "ALL") == 0)
1615 {
1616 price = ni->stats->level * 3;
1617 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
1618 {
1619 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1620 (long int)ni->stats->gold/price, price);
1621 ni->stats->hp += ni->stats->gold / price;
1622 ni->stats->gold %= price;
1623 }
1624 else
1625 {
1626 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1627 "per point.", price);
ad7dfaa0 1628 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
1629 (ni->stats->maxhp - ni->stats->hp),
1630 (price * (ni->stats->maxhp - ni->stats->hp)) );
85ce9d3e 1631 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1632 ni->stats->hp = ni->stats->maxhp;
1633 }
1634 }
1635 else if (isstringnum(amount))
1636 {
1637 num = stringtoint(amount);
1638 price = ni->stats->level * 3;
1639 if (ni->stats->gold < price * num)
1640 {
1641 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
1642 (long int)ni->stats->gold/price);
1643 }
1644 else if (num <= ni->stats->maxhp - ni->stats->hp)
1645 {
1646 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
1647 num, price);
1648 ni->stats->hp += num;
1649 ni->stats->gold -= num * price;
1650 }
1651 else if (num > ni->stats->maxhp - ni->stats->hp)
1652 {
1653 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1654 "per point.", price);
1655 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
1656 (ni->stats->maxhp - ni->stats->hp));
1657 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1658 ni->stats->hp = ni->stats->maxhp;
1659 }
1660 }
1661 else if (amount[0] == '-')
1662 notice(s_GameServ, u, "You trying to cheat?");
1663 else
1664 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1665}
1666
1667int isstringnum(char *num)
1668{
28f552b8 1669 unsigned int x;
85ce9d3e 1670 for (x = 0; x < strlen(num); x++)
1671 {
1672 if ((int)num[x] < 48 || (int)num[x] > 57)
1673 return 0;
1674 }
1675return 1;
1676}
1677
1678long int stringtoint(char *number)
1679{
1680 long int x, len = strlen(number), sum = 0;
1681 if (len == 1)
1682 return chartoint(number[0]);
1683 sum += chartoint(number[len - 1]);
1684 for (x = len - 2; x >= 0; x--)
85ce9d3e 1685 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
85ce9d3e 1686 return sum;
1687}
1688
1689long int pow(int x, int y)
1690{
1691 long int value = 0;
1692 int count = 0;
1693 value += x;
1694
1695 if (x != 0 && y != 0)
1696 {
1697 for (count = 1; count <= y - 1; count++)
1698 value *= x;
1699 }
1700 else
1701 return 1;
1702return value;
1703}
1704
1705long int chartoint(char ch)
1706{
8c126acc 1707 if (int(ch) >= 48 && int(ch) <= 57)
1708 return int(ch) - 48;
1709 else
1710 return 0;
85ce9d3e 1711}
1712
1713int save_gs_dbase()
1714{
1715 ListNode<aClient> *ptr = players.First();
1716 Player *it;
1717 ofstream outfile;
1718
1719 outfile.open(playerdata);
1720
1721 if (!outfile)
1722 {
fb37ecc7 1723 log("Error opening %s", playerdata);
85ce9d3e 1724 return 0;
1725 }
1726
1727 while(ptr)
1728 {
1729 it = ptr->getData()->stats;
1730 outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
1731 << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
ee38284f 1732 << it->armor << ' ' << it->weapon << ' '
e3c5fe46 1733 << it->forest_fights << ' ' << it->player_fights << ' '
266608f6 1734 << it->getFlags() << ' ' << it->password << ' ' << it->inventory.Healing()
9d3b1d42 1735 << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP() << endl;
85ce9d3e 1736 ptr = ptr->Next();
1737 }
1738outfile.close();
28f552b8 1739return 1;
85ce9d3e 1740}
1741
1742int load_gs_dbase()
1743{
1744 ifstream infile;
1745 aClient *temp;
1746 Player *p;
ee38284f 1747 char *tempname, *buf, *password;
85ce9d3e 1748 buf = new char[1023];
1749
1750 infile.open(playerdata);
1751
1752 if (infile.fail())
1753 {
fb37ecc7 1754 log("Error opening %s", playerdata);
85ce9d3e 1755 return 0;
1756 }
1757
1758 while (infile.getline(buf, 1024, '\n'))
1759 {
1760 temp = new aClient;
1761 tempname = strtok(buf, " ");
1762 temp->stats = new Player(tempname);
1763 p = temp->stats;
1764
85ce9d3e 1765 p->level = stringtoint(strtok(NULL, " "));
1766 p->exp = stringtoint(strtok(NULL, " "));
1767 p->gold = stringtoint(strtok(NULL, " "));
1768 p->bank = stringtoint(strtok(NULL, " "));
1769 p->hp = stringtoint(strtok(NULL, " "));
1770 p->maxhp = stringtoint(strtok(NULL, " "));
1771 p->strength = stringtoint(strtok(NULL, " "));
1772 p->defense = stringtoint(strtok(NULL, " "));
1773 p->armor = stringtoint(strtok(NULL, " "));
1774 p->weapon = stringtoint(strtok(NULL, " "));
85ce9d3e 1775 p->forest_fights = stringtoint(strtok(NULL, " "));
1776 p->player_fights = stringtoint(strtok(NULL, " "));
1af35752 1777 p->setFlags(stringtoint(strtok(NULL, " ")));
ee38284f 1778
e3c5fe46 1779 password = strtok(NULL, " ");
1780 strcpy(p->password, password);
73c71976 1781 temp->setNick("!NULL!");
ce61cdfa 1782 #ifdef P10
1783 temp->setRealNick("!NULL!");
1784 #endif
85ce9d3e 1785
9d3b1d42 1786 p->inventory.reset(); // Set inventory to all 0s
ee38284f 1787 // Old player databases didn't have these three extra values
1788 // If they come up null, leave them to 0 as the default.
1789 // On the next gameserv database save, it will save the values.
266608f6 1790 tempname = strtok(NULL, " ");
9d3b1d42 1791 if (tempname)
1792 p->inventory.setHealing(stringtoint(tempname));
1793
1794 tempname = strtok(NULL, " ");
1795 if (tempname)
1796 p->inventory.setStrength(stringtoint(tempname));
1797
1798 tempname = strtok(NULL, " ");
1799 if (tempname)
1800 p->inventory.setDefense(stringtoint(tempname));
1801
1802 tempname = strtok(NULL, " ");
1803 if (tempname)
1804 p->inventory.setHP(stringtoint(tempname));
e3c5fe46 1805
85ce9d3e 1806 players.insertAtBack(temp);
1807 delete temp;
1808 }
1cf88153 1809delete [] buf;
28f552b8 1810infile.close();
1811return 1;
85ce9d3e 1812}
1813
e3c5fe46 1814bool passcmp(char *encrypted, char *plaintext)
1815{
1816 char salt[3];
cdc9a6db 1817 char *plaintext2, *plainToencrypt;
1818 bool same = false;
1819
1820 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
1821 strcpy(plaintext2, plaintext);
1822
e3c5fe46 1823 salt[0] = encrypted[0];
1824 salt[1] = encrypted[1];
1825 salt[3] = '\0';
cdc9a6db 1826
1827 plainToencrypt = crypt(plaintext2, salt);
1828
1829 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
1830
1831 delete []plaintext2;
1832
1833 return same;
e3c5fe46 1834}
1835
1836bool check_password(char *name, char *plaintext)
1837{
0a1518fa 1838 aClient *client;
e3c5fe46 1839
0a1518fa 1840 if (!(client = findplayer(name)))
1841 return false;
1842 else
e3c5fe46 1843 {
0a1518fa 1844 return passcmp(client->stats->password, plaintext);
e3c5fe46 1845 }
e3c5fe46 1846}
1cf88153 1847
ad7dfaa0 1848void do_store(char *u)
1849{
1850 char *cmd = strtok(NULL, " ");
1851 char *item = strtok(NULL, " ");
1852 char *num = strtok(NULL, " ");
1853 char *space;
8c126acc 1854 int wep;
1855 aClient *user;
1856 Player *p;
ad7dfaa0 1857
1af35752 1858 if (!cmd || !item)
ad7dfaa0 1859 {
1860 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
1861 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
1862 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
1863 }
1af35752 1864 else if (!(user = find(u)) || !is_playing(user))
1865 notice(s_GameServ, u, "You must be playing to use the store!");
ee38284f 1866 else if (!isAlive(user->stats))
1af35752 1867 {
1868 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
1869 return;
1870 }
ad7dfaa0 1871 else if (stricmp(cmd, "LIST") == 0)
1872 {
1873 if (stricmp(item, "WEAPONS") == 0)
1874 {
1875 notice(s_GameServ, u, "Welcome to Kain's Armory");
1876 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
1877 for (int x = 1; x < WNA; x++)
1878 {
1879 space = spaces(strlen(weapons[x]), ".");
1880 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
1881 free(space);
1882 }
1883 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
1884 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
1885
1886 }
1887 else if (stricmp(item, "ARMOR") == 0)
1888 {
1889 notice(s_GameServ, u, "Welcome to Kain's Armory");
1890 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
1891 for (int x = 1; x < WNA; x++)
1892 {
1893 space = spaces(strlen(armors[x]), ".");
1894 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
1895 free(space);
1896 }
1897 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
1898 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
1899
1900
1901 }
1902 } else if (stricmp(cmd, "BUY") == 0) {
8c126acc 1903 if (!num)
1904 {
1905 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
1906 return;
1907 }
1908 else if (!isstringnum(num))
1909 {
1910 notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
1911 return;
1912 }
1913 if (stricmp(item, "WEAPON") == 0)
1914 {
1915 wep = stringtoint(num);
1916 if (wep >= WNA || wep < 1)
1917 {
1918 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
1919 return;
1920 }
1921
1922 p = user->stats;
1923
1924 if (p->weapon != 0)
1925 notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
1926 else if (p->gold < prices[wep - 1])
1927 notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
1928 else
1929 {
1930 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
1931 p->weapon = wep;
1932 p->gold -= prices[wep - 1];
1933 }
1934 }
1935 else if (stricmp(item, "ARMOR") == 0)
1936 {
1937 wep = stringtoint(num);
1938 if (wep >= WNA || wep < 1)
1939 {
1940 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
1941 return;
1942 }
1943
1944 p = user->stats;
1945
1946 if (p->armor != 0)
1947 notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
1948 else if (p->gold < prices[wep - 1])
1949 notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
1950 else
1951 {
1952 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
1953 p->armor = wep;
1954 p->gold -= prices[wep - 1];
1955 }
1956 }
1957 }
1958 else if (stricmp(cmd, "SELL" ) == 0)
1959 {
1960 p = user->stats;
1961
1962 if (stricmp(item, "WEAPON") == 0)
1963 {
1964 if (p->weapon == 0)
1965 {
1966 notice(s_GameServ, u, "You want me to chop off your hands?");
1967 return;
1968 }
1969 else if (p->gold == 2000000000)
1970 {
1971 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
1972 p->weapon = 0;
1973 }
1974 else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
1975 {
1976 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
1977 notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
1978 p->gold = 2000000000;
1979 p->weapon = 0;
1980 }
1981 else
1982 {
1983 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
1984 p->gold += (prices[p->weapon - 1] / 2);
1985 p->weapon = 0;
1986 }
1987 }
1988 else if (stricmp(item, "ARMOR") == 0)
1989 {
1990 p = user->stats;
1991
1992 if (p->armor == 0)
1993 {
1994 notice(s_GameServ, u, "I don't think you can be any more naked...");
1995 return;
1996 }
1997 if (p->gold == 2000000000)
1998 {
1999 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2000 p->armor = 0;
2001 }
2002 else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
2003 {
2004 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2005 notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
2006 p->gold = 2000000000;
2007 p->armor = 0;
2008 }
2009 else
2010 {
2011 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
2012 (prices[p->armor - 1] / 2));
2013
2014 p->gold += (prices[p->armor - 1] / 2);
2015 p->armor = 0;
2016 }
2017 }
2018 else
2019 {
2020 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2021 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2022 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2023 }
2024 }
2025}
9cda831c 2026void do_inventory(char *u)
2027{
2028 aClient *user;
2029
2030 if (!(user = find(u)))
2031 {
2032 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2033 return;
2034 }
2035 else if (!is_playing(user))
2036 {
2037 notice(s_GameServ, u, "You must be playing to check your inventory!");
2038 return;
2039 }
2040 showinventory(user, user);
2041}
2042void showinventory(aClient *from, aClient *to)
2043{
2044 char *nick = to->getNick();
8c126acc 2045
9cda831c 2046 if (!to)
2047 to = from;
2048 if (is_playing(from))
2049 {
2050 Pouch *p = &from->stats->inventory;
ce61cdfa 2051 notice(s_GameServ, nick, "Inventory for %s:", from->stats->name);
9cda831c 2052 notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
2053 notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
2054 notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
9d3b1d42 2055 notice(s_GameServ, nick, " HP Potions: %d", p->HP());
9cda831c 2056 }
2057}
f5c25639 2058void do_tavern(char *u)
2059{
2060 char *cmd = strtok(NULL, " ");
2061 long int price;
2062
2063 aClient *user;
2064 Player *p;
2065 if (!(user = find(u)))
2066 {
2067 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2068 return;
2069 }
2070 else if (!is_playing(user))
2071 {
2072 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2073 return;
2074 }
9cda831c 2075 else if (is_fighting(user))
2076 {
2077 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2078 return;
2079 }
f5c25639 2080 p = user->stats;
2081 if (!cmd)
2082 {
2083 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
2084 notice(s_GameServ, u, "Your commands:");
2085 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2086 notice(s_GameServ, u, "What'll it be?");
2087 }
2088 else if (stricmp(cmd, "LIST") == 0)
2089 {
2090 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2091 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10));
2092 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10));
2093 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10));
8c734eb9 2094 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10));
f5c25639 2095 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2096 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
2097 notice(s_GameServ, u, "By something will ya!");
2098 }
2099 else if (stricmp(cmd, "BUY") == 0)
2100 {
2101 char *chnum = strtok(NULL, " ");
2102 int num = stringtoint(chnum);
2103
2104 if (!chnum)
2105 {
2106 notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
2107 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
2108 return;
2109 }
8c734eb9 2110 if (num < 1 || num > 4)
f5c25639 2111 {
2112 notice(s_GameServ, u, "Invalid Choice!");
2113 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2114 notice(s_GameServ, u, "1. Healing Potions for %ld Gold", 1000 * p->level + (p->exp / 10));
2115 notice(s_GameServ, u, "2. Strength Potions for %ld Gold", 2050 * p->level + (p->exp / 10));
2116 notice(s_GameServ, u, "3. Defense Potions for %ld Gold", 2000 * p->level + (p->exp / 10));
8c734eb9 2117 notice(s_GameServ, u, "4. HP Potions for %ld Gold", 2300 * p->level + (p->exp / 10));
f5c25639 2118 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2119 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
ee38284f 2120 return;
f5c25639 2121 }
2122 switch(num)
2123 {
2124 case 1:
2125 price = (1000 * p->level) + (p->exp / 10);
2126 if (p->gold >= price)
2127 {
2128 notice(s_GameServ, u, "One healing potion coming right up!");
2129 p->inventory.incHealing();
ee38284f 2130 p->gold -= price;
f5c25639 2131 }
2132 else
2133 notice(s_GameServ, u, "You don't have enough gold!");
2134 break;
2135 case 2:
2136 price = (2050 * p->level) + (p->exp / 10);
2137 if (p->gold >= price)
2138 {
2139 notice(s_GameServ, u, "One strength boost coming right up!");
2140 p->inventory.incStrength();
ee38284f 2141 p->gold -= price;
f5c25639 2142 }
2143 else
2144 notice(s_GameServ, u, "You don't have enough gold!");
2145 break;
2146 case 3:
2147 price = (2000 * p->level) + (p->exp / 10);
2148 if (p->gold >= price)
2149 {
2150 notice(s_GameServ, u, "One defense boost coming right up!");
2151 p->inventory.incDefense();
ee38284f 2152 p->gold -= price;
f5c25639 2153 }
2154 else
2155 notice(s_GameServ, u, "You don't have enough gold!");
2156 break;
8c734eb9 2157 case 4:
2158 price = (2300 * p->level) + (p->exp / 10);
2159 if (p->gold >= price)
2160 {
2161 notice(s_GameServ, u, "One HP Potion coming right up!");
2162 p->inventory.incHP();
2163 p->gold -= price;
2164 }
2165 else
2166 notice(s_GameServ, u, "You don't have enough gold!");
2167 break;
f5c25639 2168 default:
2169 notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
2170 break;
2171 }
2172 }
9cda831c 2173 else
2174 {
2175 notice(s_GameServ, u, "Improper Syntax.");
2176 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2177 }
f5c25639 2178}
2179
8c126acc 2180void do_bank(char *u)
2181{
2182 char *cmd = strtok(NULL, " ");
2183 char *amount = strtok(NULL, " ");
2184 char *nick = strtok(NULL, " ");
2185
2186 aClient *user;
2187 Player *p;
2188
8c734eb9 2189 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
8c126acc 2190 {
2191 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
e282e9d2 2192 notice (s_GameServ, u, "BANK BALANCE");
8c126acc 2193 return;
2194 }
1af35752 2195
2196 user = find(u);
2197 if (!is_playing(user))
8c126acc 2198 {
2199 notice(s_GameServ, u, "You must be playing to use the bank!");
2200 return;
ad7dfaa0 2201 }
fa376453 2202 else if (stricmp(cmd, "BALANCE") == 0)
2203 {
2204 showBankBalance(u);
2205 return;
2206 }
ee38284f 2207 else if (!isAlive(user->stats))
1af35752 2208 {
2209 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2210 return;
2211 }
8c126acc 2212 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2213 {
2214 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2215 return;
2216 }
2217
2218 p = user->stats;
2219
fa376453 2220 if (stricmp(cmd, "DEPOSIT") == 0)
8c126acc 2221 {
2222 if (p->bank == 2000000000)
2223 {
2224 notice(s_GameServ, u, "Your bank account is full, sire!");
2225 return;
2226 }
2227 else if (stricmp(amount, "ALL") == 0)
2228 {
2229 if (2000000000 - p->bank < p->gold)
2230 {
2231 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2232 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
2233 p->gold -= (2000000000 - p->bank);
2234 p->bank = 2000000000;
e282e9d2 2235 showBankBalance(u);
8c126acc 2236 }
2237 else
2238 {
2239 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
2240 p->bank += p->gold;
2241 p->gold = 0;
e282e9d2 2242 showBankBalance(u);
8c126acc 2243 }
2244 }
2245 else if (stringtoint(amount) > p->gold)
2246 {
2247 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
e282e9d2 2248 showBankBalance(u);
8c126acc 2249 return;
2250 }
2251 else
2252 {
2253 if (2000000000 - p->bank < stringtoint(amount))
2254 {
2255 notice(s_GameServ, u, "You don't have room in your account for that much.");
2256 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
2257 p->gold -= (2000000000 - p->bank);
2258 p->bank = 2000000000;
e282e9d2 2259 showBankBalance(u);
8c126acc 2260 }
2261 else
2262 {
2263 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2264 p->bank += stringtoint(amount);
2265 p->gold -= stringtoint(amount);
e282e9d2 2266 showBankBalance(u);
8c126acc 2267 }
2268 }
2269 }
2270 else if (stricmp(cmd, "WITHDRAW") == 0)
2271 {
2272 if (p->gold == 2000000000)
2273 {
2274 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
e282e9d2 2275 showBankBalance(u);
8c126acc 2276 return;
2277 }
2278 else if (stricmp(amount, "ALL") == 0)
2279 {
2280 if (2000000000 - p->gold < p->bank)
2281 {
2282 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2283 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
2284 p->bank -= (2000000000 - p->gold);
2285 p->gold = 2000000000;
e282e9d2 2286 showBankBalance(u);
8c126acc 2287 }
2288 else
2289 {
2290 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
2291 p->gold += p->bank;
2292 p->bank = 0;
e282e9d2 2293 showBankBalance(u);
8c126acc 2294 }
2295 }
2296 else if (stringtoint(amount) > p->bank)
2297 {
2298 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
e282e9d2 2299 showBankBalance(u);
8c126acc 2300 return;
2301 }
2302 else
2303 {
2304 if (2000000000 - p->gold < stringtoint(amount))
2305 {
2306 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2307 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2308 (2000000000 - p->gold));
2309 p->bank -= (2000000000 - p->gold);
2310 p->gold = 2000000000;
e282e9d2 2311 showBankBalance(u);
8c126acc 2312 }
2313 else
2314 {
2315 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2316 p->gold += stringtoint(amount);
2317 p->bank -= stringtoint(amount);
e282e9d2 2318 showBankBalance(u);
8c126acc 2319 }
2320 }
2321 }
2322
ad7dfaa0 2323}
ab4f4ec0 2324
2325void do_master(char *u)
2326{
2327 aClient *user;
1af35752 2328 user = find(u);
2329
2330 if (!user)
ab4f4ec0 2331 {
2332 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2333 return;
2334 }
1af35752 2335 else if (is_fighting(user))
ab4f4ec0 2336 {
2337 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
2338 return;
2339 }
ee38284f 2340 else if (!isAlive(user->stats))
1af35752 2341 {
2342 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2343 return;
2344 }
2345 else if (!is_playing(user))
ab4f4ec0 2346 {
2347 notice(s_GameServ, u, "You must be playing to see your master!");
2348 return;
2349 }
c7340cbd 2350
2351 char *cmd = strtok(NULL, " ");
2352 Player *p = user->stats;
2353 long int need = 0;
2354
1af35752 2355 if (seenMaster(p))
2356 {
2357 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
2358 return;
2359 }
2360
c7340cbd 2361 if (cmd != NULL)
ab4f4ec0 2362 {
ab4f4ec0 2363 switch(p->level)
2364 {
2365 case 1:
2366 need = 100;
2367 break;
2368 case 2:
2369 need = 400;
2370 break;
2371 case 3:
2372 need = 1000;
2373 break;
2374 case 4:
2375 need = 4000;
2376 break;
2377 case 5:
2378 need = 10000;
2379 break;
2380 case 6:
2381 need = 40000;
2382 break;
2383 case 7:
2384 need = 100000;
2385 break;
2386 case 8:
2387 need = 400000;
2388 break;
2389 case 9:
2390 need = 1000000;
2391 break;
2392 case 10:
2393 need = 4000000;
2394 break;
2395 case 11:
2396 need = 10000000;
2397 break;
2398 case 12:
2399 need = p->exp + 1;
2400 notice(s_GameServ, u, "You are at level 12. You are the master. What's left? The DRAGON!");
2401 break;
2402 default:
2403 need = p->exp + 1; // Unknown level... don't let them fight a fake master!
2404 break;
c7340cbd 2405 }
2406 }
2407 else
2408 {
2409 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2410 return;
2411 }
2412
2413 if (stricmp(cmd, "FIGHT") == 0)
2414 {
ab4f4ec0 2415 if (p->exp >= need)
1af35752 2416 {
2417 setMaster(p);
ab4f4ec0 2418 see_master(u);
1af35752 2419 }
ab4f4ec0 2420 else
2421 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.", masters[p->level - 1]->name, (need - p->exp));
c7340cbd 2422 return;
2423 }
2424 else if (stricmp(cmd, "QUESTION") == 0)
2425 {
2426 if (p->exp >= need)
2427 notice(s_GameServ, u, "%s looks you up and down and decides you are more ready than you will ever be.", masters[p->level - 1]->name);
2428 else
2429 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!", masters[p->level - 1]->name, p->name);
2430
2431 return;
2432 }
2433 else
2434 {
2435 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
ab4f4ec0 2436 }
2437}
2438
2439void see_master(char *u)
2440{
2441 aClient *user;
1af35752 2442
ab4f4ec0 2443 if (!(user = find(u)))
2444 {
2445 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2446 return;
2447 }
2448
1af35752 2449 if (!is_fighting(user) && is_playing(user))
ab4f4ec0 2450 {
2451 Player *p = user->stats;
2452 p->master = new Monster(masters[p->level - 1]);
2453 p->fight = p->master;
2454 display_monster(u); // Since master is the same structure, use this function
2455 }
2456}
e282e9d2 2457
2458void showBankBalance(const char *u)
2459{
2460 aClient *user;
2461 Player *p;
1af35752 2462
e282e9d2 2463 if (!(user = find(u)))
2464 return;
2465
2466 p = user->stats;
2467
2468 if (!p)
2469 return;
2470
2471 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->bank, p->gold);
2472
2473}
44ea29f7 2474
2475void refreshall()
2476{
2477 ListNode <aClient> *it;
2478 Player *p;
2479
2480 it = players.First();
2481
2482 while (it)
2483 {
2484 p = it->getData()->stats;
2485 refresh(p);
2486 it = it->Next();
2487 }
2488}
2489
2490void refresh(Player *p)
2491{
2492 if (!p)
2493 return;
2494
ee38284f 2495 if (p->hp < p->maxhp)
2496 p->hp = p->maxhp;
20d5d721 2497 p->forest_fights = forestfights;
44ea29f7 2498 p->player_fights = 3;
ee38284f 2499 setAlive(p);
1af35752 2500 clearMaster(p);
44ea29f7 2501}
c7340cbd 2502
2503void do_refresh(char *u)
2504{
2505 char *nick = strtok(NULL, " ");
2506 aClient *user;
2507
96f71fee 2508 if (!(user = find(u)))
2509 {
2510 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
5d04eb42 2511 log("Error: aClient not found: %s", u);
96f71fee 2512 return;
2513 }
2514 else if (!isAdmin(user))
2515 {
2516 notice(s_GameServ, u, "You must be a %S admin to use this command!");
2517 return;
2518 }
c7340cbd 2519 if (!nick)
2520 {
96f71fee 2521 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
c7340cbd 2522 return;
2523 }
2524 else if (stricmp(nick, "ALL") == 0)
2525 {
2526 notice(s_GameServ, u, "Refreshing everyone's stats!");
2527 refreshall();
2528 }
ce61cdfa 2529 else if ((user = findbyrealnick(nick)))
c7340cbd 2530 {
1af35752 2531 if (is_playing(user))
c7340cbd 2532 {
ce61cdfa 2533 #ifdef P10
2534 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
2535 #else
c7340cbd 2536 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
ce61cdfa 2537 #endif
c7340cbd 2538 refresh(user->stats);
2539 }
2540 else
2541 {
ce61cdfa 2542 #ifdef P10
2543 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
2544 #else
c7340cbd 2545 notice(s_GameServ, u, "%s is not playing.", user->getNick());
ce61cdfa 2546 #endif
c7340cbd 2547 }
2548 }
2549 else
2550 {
2551 notice(s_GameServ, u, "Nick %s not found.", nick);
2552 return;
2553 }
2554}
2555
ee38284f 2556
2557void resetall()
2558{
2559 ListNode <aClient> *it;
2560 Player *p;
2561
2562 it = players.First();
2563
2564 while (it)
2565 {
2566 p = it->getData()->stats;
2567 reset(p);
2568 it = it->Next();
2569 }
2570}
2571
2572void reset(Player *p)
2573{
2574 if (!p)
2575 return;
2576
2577 p->reset();
2578}
2579
2580void do_reset(char *u)
2581{
2582 char *nick = strtok(NULL, " ");
2583 aClient *user;
2584
2585 if (!(user = find(u)))
2586 {
2587 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
5d04eb42 2588 log("Error: aClient not found: %s", u);
ee38284f 2589 return;
2590 }
2591 else if (!isAdmin(user))
2592 {
2593 notice(s_GameServ, u, "You must be a %S admin to use this command!");
2594 return;
2595 }
2596 if (!nick)
2597 {
2598 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
2599 return;
2600 }
2601 else if (stricmp(nick, "ALL") == 0)
2602 {
2603 notice(s_GameServ, u, "Resetting everyone's stats!");
2604 resetall();
2605 }
ce61cdfa 2606 else if ((user = findbyrealnick(nick)))
ee38284f 2607 {
2608 if (is_playing(user))
2609 {
ce61cdfa 2610 #ifdef P10
2611 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
2612 #else
ee38284f 2613 notice(s_GameServ, u, "Resetting %s.", user->getNick());
ce61cdfa 2614 #endif
ee38284f 2615 reset(user->stats);
2616 }
2617 else
2618 {
ce61cdfa 2619 #ifdef P10
2620 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
2621 #else
ee38284f 2622 notice(s_GameServ, u, "%s is not playing.", user->getNick());
ce61cdfa 2623 #endif
ee38284f 2624 }
2625 }
2626 else
2627 {
2628 notice(s_GameServ, u, "Nick %s not found.", nick);
2629 return;
2630 }
2631}
2632
c7340cbd 2633void do_help(char *u)
2634{
2635 char *cmd = strtok(NULL, " ");
2636
c7340cbd 2637 display_help(u, cmd);
2638}
2639
2640void display_help(char *u, char *file)
2641{
2642 ifstream infile;
2643 char *buf;
2644
2645 if (!file)
2646 {
2647 infile.open("helpfiles/help");
2648 if (infile.fail())
2649 {
fb37ecc7 2650 log("Error opening helpfiles/help");
c7340cbd 2651 notice(s_GameServ, u, "Error opening helpfiles/help");
2652 return;
2653 }
2654 buf = new char[1024];
2655 while(infile.getline(buf, 1024))
2656 {
2657 // Written this way, it will process %S in the helpfiles
2658 // Instead of notice(s_GameServ, u, "%s", buf);
2659 notice(s_GameServ, u, buf);
2660 }
2661
2662 // Minor recursion
96f71fee 2663 aClient *user = find(u);
2664 if (user && isAdmin(user))
2665 display_help(u, "admin_commands");
c7340cbd 2666 }
2667 else
2668 {
2669 char *filename;
f27a378f 2670 filename = new char[strlen(file) + 11];
2671 strcpy(filename, "helpfiles/");
2672 strcat(filename, file);
4dde2ed9 2673
f27a378f 2674 for (unsigned int x = 10; x < strlen(filename); x++)
2675 filename[x] = tolower(filename[x]);
4dde2ed9 2676
c7340cbd 2677 infile.open(filename);
2678 delete [] filename;
2679 if (infile.fail())
2680 {
2681 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
2682 return;
2683 }
2684 buf = new char[1024];
2685 while(infile.getline(buf, 1024))
2686 {
2687 // Written this way, it will process %S in the helpfiles
2688 // Instead of notice(s_GameServ, u, "%s", buf);
2689 notice(s_GameServ, u, buf);
2690 }
2691 }
2692 infile.close();
2693 delete [] buf;
2694}
96f71fee 2695
2696void do_admin(char *u)
2697{
2698 aClient *user;
2699 char *pass = strtok(NULL, " ");
2700
2701 if (!(user = find(u)))
2702 {
5d04eb42 2703 log("Error: aClient not found: %s", u);
96f71fee 2704 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
2705 return;
2706 }
2707 if (!pass)
2708 {
2709 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
2710 return;
2711 }
2712
1af35752 2713 if (isAdmin(user))
2714 {
2715 notice(s_GameServ, u, "You already have administrator privledges.");
2716 return;
2717 }
2718 else if (strcmp(pass, adminpass) == 0)
96f71fee 2719 {
2720 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
2721 setAdmin(user);
ce61cdfa 2722 #ifdef P10
2723 log("%s became an administrator.", user->getRealNick());
2724 #else
5d04eb42 2725 log("%s became an administrator.", user->getNick());
ce61cdfa 2726 #endif
96f71fee 2727 }
2728 else
2729 {
2730 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
2731 return;
2732 }
2733}
1af35752 2734
4dde2ed9 2735bool load_monsters()
2736{
2737 ifstream infile;
2738 infile.open("monsters.dat");
2739
2740 char *buf;
2741
2742 if (infile.fail())
2743 {
fb37ecc7 2744 log("Error opening monsters.dat");
4dde2ed9 2745 return false;
2746 }
2747 init_monsters();
2748 buf = new char[2048];
2749
5d04eb42 2750 #ifdef DEBUGMODE
2751 log("Loading monsters from monsters.dat");
2752 #endif
2753
4dde2ed9 2754 for (int l = 0; l < REALLEVELS; l++)
2755 {
2756 for (int m = 0; m < MONSTERS;)
2757 {
2758 infile.getline(buf, 2048);
2759 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
2760 continue;
2761 else
2762 {
2763 strcpy(monsters[l][m]->name, strtok(buf, "~"));
2764 strcpy(monsters[l][m]->weapon, strtok(NULL, "~"));
2765 monsters[l][m]->strength = stringtoint(strtok(NULL, "~"));
2766 monsters[l][m]->gold = stringtoint(strtok(NULL, "~"));
2767 monsters[l][m]->exp = stringtoint(strtok(NULL, "~"));
2768 monsters[l][m]->maxhp = stringtoint(strtok(NULL, "~"));
ee38284f 2769 monsters[l][m]->hp = monsters[l][m]->maxhp;
4dde2ed9 2770 strcpy(monsters[l][m]->death, strtok(NULL, ""));
2771 m++;
2772 }
2773 }
2774 }
2775 delete [] buf;
2776return true;
2777}