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