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