]> jfr.im git - irc/gameservirc.git/blame - gameserv/gameserv.cpp
Implemented the myString class in the player and monster classes. This should make...
[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 {
ddef84f1 368 notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name.getString());
85ce9d3e 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 {
ddef84f1 417 notice(s_GameServ, u, "%s is not playing!", ni->stats->name.getString());
73c71976 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(),
ddef84f1 637 temp->getData()->stats->name.getString());
9cb6f227 638 #else
639 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(),
ddef84f1 640 temp->getData()->stats->name.getString());
9cb6f227 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 {
ddef84f1 688 notice(s_GameServ, u, "Logging out %s", user->stats->name.getString());
18b84d11 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;
ddef84f1 716 unsigned long hv = iHASH((unsigned char *) user->stats->name.getString());
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
ddef84f1 809 user->stats->password = crypt(password, salt);
810 user->stats->name = name;
811
448a1531 812 unsigned long hv = iHASH((unsigned char *) name);
40251952 813 updateTS(user->stats);
ae2685f6 814 temp = players[hv].insertAtBack_RLN(user);
815 temp->setPtr(user); // This is an extra step, but necessary for now
816
14e24ba1 817 // Update the last login time
818 user->stats->lastlogin = time(NULL);
819
ddef84f1 820 notice(s_GameServ, u, "Player %s registered with password %s.", user->stats->name.getString(), password);
c7340cbd 821 notice(s_GameServ, u, "Write this password down. If you lose it, there is no way to retrieve it!");
ddef84f1 822 log("Nickname %s registered player %s.", u, user->stats->name.getString());
3f243b0b 823 setPlaying(user); // set the playing flag
85ce9d3e 824 }
825 else
826 {
827 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
828 }
829 }
830}
831
832void do_identify(char *u)
833{
0a1518fa 834 char *password, *name;
835 aClient *user, *p;
836 name = strtok(NULL, " ");
85ce9d3e 837 password = strtok(NULL, " ");
0a1518fa 838 if (!password || !name)
85ce9d3e 839 {
0a1518fa 840 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
85ce9d3e 841 }
448a1531 842 else if (!(user = find(u)))
5d04eb42 843 {
844 notice(s_GameServ, u, "Fatal error. Cannot find aClient. Buf: %s", strtok(NULL, ""));
845 log("Error: aClient not found: %s", u);
846 }
448a1531 847 else if (isIgnore(user))
848 {
849 #ifdef DEBUGMODE
850 log("Ignoring %s.", user->getNick());
851 #endif
852 return;
853 }
0a1518fa 854 else if (!(p = findplayer(name)) || !p->stats)
855 notice(s_GameServ, u, "Player %s not found", name);
b0359af9 856 else if (is_playing(user))
857 {
858 notice(s_GameServ, u, "You are already playing!");
859 }
85bcf836 860 else if (p->stats->client != NULL && !isAdmin(user))
1579dfa2 861 {
862 notice(s_GameServ, u, "That player has already identified.");
1579dfa2 863 }
20d5d721 864 else if (!check_password(name, password) && !isAdmin(user))
85ce9d3e 865 {
0a1518fa 866 notice(s_GameServ, u, "Password incorrect");
85ce9d3e 867 }
1579dfa2 868 else {
b0359af9 869 ListNode<aClient> *temp;
ddef84f1 870 unsigned long hv = iHASH((unsigned char *) p->stats->name.getString());
7996e5fd 871 temp = players[hv].Find(p);
b0359af9 872 if (!temp)
85ce9d3e 873 {
b0359af9 874 notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s",
875 strtok(NULL, ""));
876 return;
85ce9d3e 877 }
ddef84f1 878 user->stats = new Player(p->stats->name.getString());
b0359af9 879 #ifdef DEBUGMODE
880 log("Setting data for identified");
881 #endif
0b6098d5 882 user->stats->setData(p->stats);
448a1531 883 user->stats->client = user;
40251952 884 updateTS(user->stats);
885
b0359af9 886
887 #ifdef DEBUGMODE
ddef84f1 888 log("Player %s IRC: %s Identified", user->stats->name.getString(),
448a1531 889 user->getNick());
b0359af9 890 #endif
891
3f243b0b 892 setPlaying(user); // set the playing flag
893
b0359af9 894 temp->setPtr(user);
14e24ba1 895
896 // Update the last login time
897 user->stats->lastlogin = time(NULL);
898
c260a8d7 899 notice(s_GameServ, u, "Password Accepted. Identified.");
900 showNews(u, todaysnews);
85ce9d3e 901 }
902}
903
904void do_stats(char *u)
905{
906 char *nick;
73c71976 907 aClient *user;
85ce9d3e 908
909 nick = strtok(NULL, " ");
85ce9d3e 910
448a1531 911 if (!(user = find(u)))
73c71976 912 {
448a1531 913 log("Fatal Error: %s not found in client list", u);
914 return;
915 }
916 else if (isIgnore(user))
917 {
918 #ifdef DEBUGMODE
919 log("Ignoring %s.", user->getNick());
920 #endif
921 return;
922 }
923 else if (!nick)
924 {
925 if (!is_playing(user))
73c71976 926 {
927 notice(s_GameServ, u, "You're not playing, so you have no stats!");
928 return;
929 }
930 else
40251952 931 {
932 updateTS(user->stats);
ddef84f1 933 showstats(u, user->stats->name.getString());
40251952 934 }
73c71976 935 }
85ce9d3e 936 else
937 showstats(u, nick);
938}
448a1531 939
ad7dfaa0 940void init_masters()
941{
5d04eb42 942 #ifdef DEBUGMODE
943 log("Calling delete_masters()");
944 #endif
945
ab4f4ec0 946 delete_masters();
c8ada07e 947
5d04eb42 948 #ifdef DEBUGMODE
949 log("Initializing masters");
950 #endif
951
c8ada07e 952 for (int x = 0; x < LEVELS; x++)
953 masters[x] = new Monster;
954
ddef84f1 955 masters[0]->name = "Old Bones";
956 masters[0]->weapon = "Dull Sword Cane";
f0314ad5 957 masters[0]->strength = 32;
c8ada07e 958 masters[0]->gold = 0;
959 masters[0]->exp = 0;
6d053d90 960 masters[0]->maxhp = 35;
961 masters[0]->hp = 35;
ddef84f1 962 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 963
ddef84f1 964 masters[1]->name = "Master Chang";
965 masters[1]->weapon = "Nanchaku";
f0314ad5 966 masters[1]->strength = 48;
c8ada07e 967 masters[1]->gold = 0;
968 masters[1]->exp = 0;
6d053d90 969 masters[1]->maxhp = 51;
970 masters[1]->hp = 51;
ddef84f1 971 masters[1]->death = "You try to make out what Master Chang is saying, but the only thing you catch is something about a grasshopper.";
c8ada07e 972
ddef84f1 973 masters[2]->name = "Chuck Norris";
974 masters[2]->weapon = "Ranger Kick";
f0314ad5 975 masters[2]->strength = 88;
c8ada07e 976 masters[2]->gold = 0;
977 masters[2]->exp = 0;
6d053d90 978 masters[2]->maxhp = 100;
979 masters[2]->hp = 100;
ddef84f1 980 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!";
c8ada07e 981
982
ddef84f1 983 masters[3]->name = "Mr. Miagi";
984 masters[3]->weapon = "Petrified Bonsai";
f0314ad5 985 masters[3]->strength = 169;
c8ada07e 986 masters[3]->gold = 0;
987 masters[3]->exp = 0;
6d053d90 988 masters[3]->maxhp = 165;
989 masters[3]->hp = 165;
ddef84f1 990 masters[3]->death = "Skill comes from repeating the correct but seemingly mundane actions. Wax ON, wax OFF!";
c8ada07e 991
ddef84f1 992 masters[4]->name = "Jackie Chan";
993 masters[4]->weapon = "Kung Fu Kick";
f0314ad5 994 masters[4]->strength = 275;
c8ada07e 995 masters[4]->gold = 0;
996 masters[4]->exp = 0;
6d053d90 997 masters[4]->maxhp = 232;
998 masters[4]->hp = 232;
ddef84f1 999 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!";
c8ada07e 1000
ddef84f1 1001 masters[5]->name = "Jet Li";
1002 masters[5]->weapon = "Motorcycle";
f0314ad5 1003 masters[5]->strength = 347;
c8ada07e 1004 masters[5]->gold = 0;
1005 masters[5]->exp = 0;
6d053d90 1006 masters[5]->maxhp = 504;
1007 masters[5]->hp = 504;
ddef84f1 1008 masters[5]->death = "Failure is a fuel for excuses. It's the doing the do, that makes the making.";
c8ada07e 1009
1010
ddef84f1 1011 masters[6]->name = "Muhammad Ali";
1012 masters[6]->weapon = "Quick Jab";
f0314ad5 1013 masters[6]->strength = 515;
c8ada07e 1014 masters[6]->gold = 0;
1015 masters[6]->exp = 0;
6d053d90 1016 masters[6]->maxhp = 1078;
1017 masters[6]->hp = 1078;
ddef84f1 1018 masters[6]->death = "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up.";
c8ada07e 1019
ddef84f1 1020 masters[7]->name = "Li Mu Bai";
1021 masters[7]->weapon = "Green Destiny";
f0314ad5 1022 masters[7]->strength = 655;
c8ada07e 1023 masters[7]->gold = 0;
1024 masters[7]->exp = 0;
6d053d90 1025 masters[7]->maxhp = 2207;
1026 masters[7]->hp = 2207;
ddef84f1 1027 masters[7]->death = "No growth without resistance. No action without reaction. No desire without restraint.";
c8ada07e 1028
1029
ddef84f1 1030 masters[8]->name = "Jimmy Wang Yu";
1031 masters[8]->weapon = "Flying Guillotine";
f0314ad5 1032 masters[8]->strength = 819;
c8ada07e 1033 masters[8]->gold = 0;
1034 masters[8]->exp = 0;
6d053d90 1035 masters[8]->maxhp = 2780;
1036 masters[8]->hp = 2780;
ddef84f1 1037 masters[8]->death = "You have beaten the one armed boxer. Proceed with caution!";
c8ada07e 1038
ddef84f1 1039 masters[9]->name = "Wong Fei Hong";
1040 masters[9]->weapon = "Drunken Boxing";
f0314ad5 1041 masters[9]->strength = 1014;
c8ada07e 1042 masters[9]->gold = 0;
1043 masters[9]->exp = 0;
6d053d90 1044 masters[9]->maxhp = 3046;
1045 masters[9]->hp = 3046;
ddef84f1 1046 masters[9]->death = "Hiccup! Monkey drinks master's wine!";
c8ada07e 1047
ddef84f1 1048 masters[10]->name = "Bruce Lee";
1049 masters[10]->weapon = "Fists of fury";
f0314ad5 1050 masters[10]->strength = 1286;
c8ada07e 1051 masters[10]->gold = 0;
1052 masters[10]->exp = 0;
6d053d90 1053 masters[10]->maxhp = 3988;
1054 masters[10]->hp = 3988;
ddef84f1 1055 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 1056}
85ce9d3e 1057
c8ada07e 1058void delete_monsters()
1059{
1060 for (int x = 0; x < LEVELS; x++)
42106907 1061 levels[x].monsters.deleteNodes();
c8ada07e 1062}
1063
1064void delete_masters()
1065{
1066 for (int x = 0; x < LEVELS; x++)
1067 if (masters[x])
1068 delete masters[x];
85ce9d3e 1069}
1070
1071void display_monster(char *u)
1072{
1073 if (is_playing(u))
1074 {
1075 aClient *user = find(u);
1076 Player *ni = user->stats;
1077
1078 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->hp);
ddef84f1 1079 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name.getString(), ni->fight->hp);
85ce9d3e 1080 notice(s_GameServ, u, "Here are your commands:");
1081 notice(s_GameServ, u, "/msg %S attack");
1082 notice(s_GameServ, u, "/msg %S run");
1083 notice(s_GameServ, u, "What will you do?");
1084 }
1085}
1086
1087void display_players(char *u)
1088{
85bcf836 1089 aClient *user;
1090 if (!(user = find(u)))
85ce9d3e 1091 {
85bcf836 1092 log("Fatal error in display_players(): Couldn't find %s", u);
83cf716f 1093 }
85bcf836 1094 else
1095 display_players(user);
83cf716f 1096}
85bcf836 1097
83cf716f 1098void display_players(aClient *user)
1099{
1100 char *u = user->getNick();
1101 if (is_playing(user) && player_fight(user))
1102 {
1103 aClient *battle = user->stats->battle;
1104 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", user->stats->hp);
ddef84f1 1105 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->stats->name.getString(), battle->stats->hp);
83cf716f 1106 notice(s_GameServ, u, "Here are your commands:");
1107 notice(s_GameServ, u, "/msg %S attack");
1108 notice(s_GameServ, u, "/msg %S run");
85ce9d3e 1109 notice(s_GameServ, u, "What will you do?");
1110 }
1111}
1112
1113
1114bool is_playing(char *u)
1115{
1116 aClient *user;
1117 if (!(user = find(u)))
85ce9d3e 1118 return false;
85ce9d3e 1119 else
40251952 1120 return is_playing(user);
85ce9d3e 1121}
1122
1af35752 1123bool is_playing(aClient *user)
1124{
03a4bdbb 1125 if (user->stats == NULL)
f1ab3b7c 1126 {
03a4bdbb 1127 return false;
f1ab3b7c 1128 }
03a4bdbb 1129 else if (user->stats->client == NULL)
f1ab3b7c 1130 {
03a4bdbb 1131 return false;
f1ab3b7c 1132 }
3f243b0b 1133 else if (!FL_is_playing(user))
1134 {
1135 return false;
1136 }
03a4bdbb 1137 else
1138 return true;
1af35752 1139}
1140
85ce9d3e 1141bool is_fighting(char *u)
1142{
1143 aClient *user;
1144
1145 if (!(user = find(u)))
85ce9d3e 1146 return false;
85ce9d3e 1147 else
40251952 1148 return is_fighting(user);
85ce9d3e 1149}
40251952 1150
1af35752 1151bool is_fighting(aClient *user)
1152{
1153 if (!is_playing(user))
1154 return false;
1155 else
448a1531 1156 return player_fight(user) || master_fight(user) || user->stats->fight != NULL;
1af35752 1157}
85ce9d3e 1158
1159bool player_fight(char *u)
1160{
1161 aClient *user;
1162
1163 if (!(user = find(u)))
1164 return false;
40251952 1165 else
1166 return player_fight(user);
85ce9d3e 1167}
448a1531 1168
1af35752 1169bool player_fight(aClient *user)
1170{
448a1531 1171 if (!is_playing(user))
1af35752 1172 return false;
a51f0dcd 1173 else if (user->stats->battle != NULL)
1174 {
1175 return user->stats->battle->stats != NULL;
1176 }
1177 return false;
1af35752 1178}
85ce9d3e 1179
1180bool master_fight(char *u)
1181{
1182 aClient *user;
1183
1184 if (!(user = find(u)))
1185 return false;
85ce9d3e 1186 else
40251952 1187 return master_fight(user);
85ce9d3e 1188}
40251952 1189
1af35752 1190bool master_fight(aClient *user)
85ce9d3e 1191{
1af35752 1192 if (!is_playing(user))
1193 return false;
1194 else
1195 return user->stats->master != NULL;
85ce9d3e 1196}
1197
1198void do_fight(char *u)
1199{
1200 aClient *ni, *battle;
1201
1202 char *nick = strtok(NULL, " ");
1203
1204 if (!nick)
1205 {
1206 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
40251952 1207 return;
85ce9d3e 1208 }
1209 else if (!(ni = find(u)))
1210 {
1af35752 1211 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
40251952 1212 return;
85ce9d3e 1213 }
448a1531 1214 else if (isIgnore(ni))
1215 {
1216 #ifdef DEBUGMODE
1217 log("Ignoring %s.", ni->getNick());
1218 #endif
1219 return;
1220 }
71098075 1221 else if (!is_playing(ni))
85ce9d3e 1222 {
71098075 1223 notice(s_GameServ, u, "You are not playing!");
40251952 1224 return;
85ce9d3e 1225 }
40251952 1226
1227 updateTS(ni->stats);
1228
1229 if (ni->stats->player_fights <= 0)
3348c24e 1230 {
1231 ni->stats->player_fights = 0; // just to be safe
1232 notice(s_GameServ, u, "You are out of player fights for the "\
1233 "day. You have to wait until tomorrow!");
1234 }
71098075 1235 else if (!(battle = findplayer(nick)))
b0359af9 1236 {
1237 notice(s_GameServ, u, "Player %s not found!", nick);
1238 }
448a1531 1239 else if (!isAlive(ni->stats))
1240 {
1241 notice(s_GameServ, u, "You are dead. Wait until tomorrow to fight others!");
1242 }
b0359af9 1243 else if (!is_playing(battle))
85ce9d3e 1244 {
71098075 1245 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
85ce9d3e 1246 }
b478c0df 1247
1248/* offline fighting not available yet
1249 else if (!(fight = finduser(nick)))
1250 {
1251 ni->stats->battle = battle;
1252 battle->battle = ni;
1253 setYourTurn(ni->stats);
1254 clearYourTurn(battle->stats);
1255
1256 notice(s_GameServ, u, "You decide to fight %s while they're "\
1257 "not in the realm!",
ddef84f1 1258 battle->stats->name.getString());
b478c0df 1259 display_players(u);
1260 }
1261*/
ddef84f1 1262 else if (stricmp(ni->stats->name.getString(), battle->stats->name.getString()) == 0)
b0359af9 1263 {
1264 notice(s_GameServ, u, "Are you trying to commit suicide!?");
1af35752 1265 }
da5cf17a 1266 else if (!isAlive(battle->stats))
1267 {
1268 notice(s_GameServ, u, "They are dead. Cannot fight dead players!");
da5cf17a 1269 }
1902338e 1270 else if (player_fight(battle))
1271 {
ddef84f1 1272 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name.getString(),
1273 battle->stats->battle->stats->name.getString());
1902338e 1274 }
448a1531 1275 else if (master_fight(battle))
1276 {
ddef84f1 1277 notice(s_GameServ, u, "%s is fighting their master!", battle->stats->name.getString());
448a1531 1278 }
1902338e 1279 else if (is_fighting(battle))
1280 {
ddef84f1 1281 notice(s_GameServ, u, "%s is fighting %s already!", battle->stats->name.getString(),
1282 battle->stats->fight->name.getString());
1902338e 1283 }
8450c018 1284 else if (ni->stats->level - battle->stats->level > maxbfightdistance)
1285 {
1286 // You can't fight someone below you by more than X level(s)
1287 // level 12 can fight level (12 - X) but not < (12 - X)
1288 notice(s_GameServ, u, "You may not fight %s. You're too strong!",
ddef84f1 1289 battle->stats->name.getString());
8450c018 1290 }
1291 else if (battle->stats->level - ni->stats->level > maxafightdistance)
1292 {
1293 // You can't fight someone above you by more than X level(S)
1294 // level 1 can fight level (1 + X), but not > (1 + X)
1295 notice(s_GameServ, u, "%s, do you really have a death wish? Try the forest you "\
ddef84f1 1296 "weakling!", ni->stats->name.getString());
8450c018 1297 }
b0359af9 1298 else
85ce9d3e 1299 {
1300 // Set your battle pointer to the other player
1301 ni->stats->battle = battle;
1302
1303 // Set the other player's battle pointer to you
448a1531 1304 ni->stats->battle->stats->battle = ni;
85ce9d3e 1305
1306 // The initiator gets the first move (perhaps this should be 50/50)
ee38284f 1307 setYourTurn(ni->stats);
1308 clearYourTurn(battle->stats);
85ce9d3e 1309
1310 // Initiate Battle sequence!
b0359af9 1311 ni->stats->player_fights -= 1;
f2072f1a 1312
ddef84f1 1313 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->stats->name.getString());
1314 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!",
1315 ni->stats->name.getString());
71098075 1316 notice(s_GameServ, battle->getNick(), "%s gets to go first "\
ddef84f1 1317 "because they initiated!", ni->stats->name.getString());
1318 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.",
1319 ni->stats->name.getString());
85bcf836 1320 display_players(ni);
85ce9d3e 1321 }
1322}
40251952 1323
83cf716f 1324void do_use(char *u)
1325{
1326 aClient *user;
1327 Pouch *p;
1328
1329 char *item = strtok(NULL, " ");
1330
1331 if (!item)
1332 {
1333 notice(s_GameServ, u, "SYNTAX: USE ITEM");
1334 notice(s_GameServ, u, "Type /msg %S HELP USE for more information.");
1335 return;
1336 }
1337 else if (!(user = find(u)))
1338 {
1339 notice(s_GameServ, u, "Fatal Error in do_use. Contact a(n) %S Admin");
1340 return;
1341 }
448a1531 1342 else if (isIgnore(user))
1343 {
1344 #ifdef DEBUGMODE
1345 log("Ignoring %s.", user->getNick());
1346 #endif
1347 return;
1348 }
83cf716f 1349 else if (!is_playing(user))
1350 {
1351 notice(s_GameServ, u, "You must be playing to use items!");
1352 return;
1353 }
1354
40251952 1355 updateTS(user->stats);
1356
83cf716f 1357 p = &user->stats->inventory;
1358
35cba3f5 1359 if (stricmp(item, "HEALING") == 0)
83cf716f 1360 {
1361 if (p->Healing() <= 0)
1362 {
35cba3f5 1363 notice(s_GameServ, u, "You are out of Healing Potions!");
83cf716f 1364 return;
1365 }
35cba3f5 1366 int oldhealing = user->stats->hp;
36b31e1c 1367 user->stats->hp += (10 * user->stats->level) + (rand() % 10) * user->stats->level;
1368 if (user->stats->hp - user->stats->maxhp >= 100)
1369 {
1370 user->stats->hp = user->stats->maxhp + 100;
1371
1372 if (oldhealing >= (user->stats->maxhp + 100))
1373 {
1374 notice(s_GameServ, u, "You cannot hold anymore HP!");
1375 return;
1376 }
1377 }
1378
83cf716f 1379 notice(s_GameServ, u, "You hastiliy gulp down the flask of cool life-giving waters.");
1380 notice(s_GameServ, u, "Rejuvination spreads throughout your body.");
35cba3f5 1381 notice(s_GameServ, u, "You gain %d HP!", user->stats->hp - oldhealing);
83cf716f 1382 p->decHealing();
35cba3f5 1383 if (player_fight(user))
1384 {
1385 notice(s_GameServ, user->stats->battle->getNick(),
1386 "%s has used a healing potion!");
1387 }
83cf716f 1388 }
1389 else if (stricmp(item, "STRENGTH") == 0)
1390 {
1391 if (p->Strength() <= 0)
1392 {
1393 notice(s_GameServ, u, "You are out of Strength Potions!");
1394 return;
1395 }
1396 int oldstrength = user->stats->strength;
1397 notice(s_GameServ, u, "As you grip the flask containing pure power, you feel adrenaline coarse through your veins!");
1398 notice(s_GameServ, u, "In one swallow you drink the potion and feel your muscle fibers bulging andgrowing!");
ae2685f6 1399 user->stats->strength += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
83cf716f 1400 notice(s_GameServ, u, "You gain %d Strength points!", user->stats->strength - oldstrength);
1401 p->decStrength();
35cba3f5 1402 if (player_fight(user))
1403 {
1404 notice(s_GameServ, user->stats->battle->getNick(),
1405 "%s has used a strength potion!");
1406 }
83cf716f 1407 }
1408 else if (stricmp(item, "DEFENSE") == 0)
1409 {
1410 if (p->Defense() <= 0)
1411 {
1412 notice(s_GameServ, u, "You are out of Defense Potions!");
1413 return;
1414 }
8c734eb9 1415 int olddefense = user->stats->defense;
83cf716f 1416 notice(s_GameServ, u, "You drink the foul tasting viscous liquid while pinching your nose in disgust.");
1417 notice(s_GameServ, u, "It tasted bad, but you feel like you are unbeatable!");
ae2685f6 1418 user->stats->defense += 1 + (rand() % 10 >= 8 ? 1 : 0); // 1-2
83cf716f 1419 notice(s_GameServ, u, "You gain %d Defense points!", user->stats->defense - olddefense);
1420 p->decDefense();
35cba3f5 1421 if (player_fight(user))
1422 {
1423 notice(s_GameServ, user->stats->battle->getNick(),
1424 "%s has used a defense potion!");
1425 }
83cf716f 1426 }
8c734eb9 1427 else if (stricmp(item, "HP") == 0)
1428 {
1429 if (p->HP() <= 0)
1430 {
1431 notice(s_GameServ, u, "You are out of HP Potions!");
1432 return;
1433 }
1434 int oldHP = user->stats->maxhp;
1435 notice(s_GameServ, u, "You feel your life growing longer as you drink the green glowing liquid.");
4e64da60 1436 user->stats->maxhp += 2 +
1437 (rand() % 100 > 70 ? (rand() % 7) : (rand() % 2) );
ae2685f6 1438
8c734eb9 1439 notice(s_GameServ, u, "You gain %d Maximum hit points!", user->stats->maxhp - oldHP);
1440 p->decHP();
35cba3f5 1441 if (player_fight(user))
1442 {
1443 notice(s_GameServ, user->stats->battle->getNick(),
1444 "%s has used a HP potion!");
1445 }
8c734eb9 1446 }
ee38284f 1447 else
1448 {
35cba3f5 1449 notice(s_GameServ, u, "SYNTAX: /msg %S USE {HEALING | STRENGTH | DEFENSE | HP}");
ee38284f 1450 return;
1451 }
83cf716f 1452
1453 end_turn(user); // If they're fighting, end their turn
1454}
c8ada07e 1455void do_run(char *u)
1456{
1457 aClient *user;
28f552b8 1458 Player *p, *p2 = NULL;
85ce9d3e 1459
c8ada07e 1460 if (!(user = find(u)))
1461 {
1462 notice(s_GameServ, u, "Couldn't find you. Error. Contact a %S admin");
1463 return;
1464 }
448a1531 1465 else if (isIgnore(user))
1466 {
1467 #ifdef DEBUGMODE
1468 log("Ignoring %s.", user->getNick());
1469 #endif
1470 return;
1471 }
bb668fcf 1472 else if (!is_playing(user))
1473 {
adaf4cdb 1474 notice(s_GameServ, u, "You must be playing to run!");
bb668fcf 1475 return;
1476 }
1477
40251952 1478 updateTS(user->stats);
c8ada07e 1479 p = user->stats;
1480
1481 if (p->battle)
1482 p2 = p->battle->stats;
1483
1af35752 1484 if (!is_fighting(user))
c8ada07e 1485 notice(s_GameServ, u, "You run in place... try fighting next time.");
1af35752 1486 else if (!player_fight(user) && !master_fight(user))
c8ada07e 1487 {
ddef84f1 1488 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p->fight->name.getString());
c8ada07e 1489 delete p->fight;
1490 p->fight = NULL;
1491 }
ee38284f 1492 else if (player_fight(user) && isYourTurn(p))
c8ada07e 1493 {
ddef84f1 1494 notice(s_GameServ, u, "You run away from \ 2%s\ 2 like a little baby!", p2->name.getString());
1495 notice(s_GameServ, p->battle->getNick(), "\ 2%s\ 2 ran away from you like a little baby!",
1496 p->name.getString());
c8ada07e 1497 p2->battle = NULL;
1498 }
ee38284f 1499 else if (player_fight(user) && !isYourTurn(p))
c8ada07e 1500 {
ddef84f1 1501 notice(s_GameServ, u, "It is not your turn. Please wait until \ 2%s\ 2 decides what to do.",
1502 p2->name.getString());
c8ada07e 1503 }
1af35752 1504 else if (master_fight(user))
c8ada07e 1505 {
ddef84f1 1506 notice(s_GameServ, u, "You cannot run from \ 2%s\ 2! FIGHT!", p->master->name.getString());
c8ada07e 1507 }
1508 p->battle = NULL;
1509}
83cf716f 1510
1511void end_turn(aClient *user)
1512{
1513 char *nick, *u = user->getNick();
1514 Monster *fight;
1515 aClient *battle;
1516 int mhit;
1517
1518 nick = new char[strlen(user->getNick()) + 1];
1519
1520 if (!user || !is_playing(user) || !is_fighting(user))
1521 goto endturn;
1522
1523 if (!player_fight(user) && !master_fight(user))
1524 fight = user->stats->fight;
1525 else
1526 fight = user->stats->master;
1527 battle = user->stats->battle;
1528
1529 if (!player_fight(user))
1530 {
1531 // Opponent's Hit
1532 mhit = (fight->strength / 2) +
1533 (rand() % (fight->strength / 2) - (user->stats->defense +
1534 arbonus[user->stats->armor]));
1535 }
1536 else
1537 {
1538 // Opponent's Hit
1539 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1540 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1541 (user->stats->defense + arbonus[user->stats->armor]));
1542 }
1543 if (!player_fight(user))
1544 {
1545
1546 if (mhit > 0)
1547 {
1548 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
ddef84f1 1549 fight->name.getString(), fight->weapon.getString(), mhit);
83cf716f 1550 }
1551 else if (mhit <= 0)
ddef84f1 1552 notice(s_GameServ, u, "%s completely misses you!", fight->name.getString());
83cf716f 1553
1554 if (mhit >= user->stats->hp)
1555 {
1556 if (!master_fight(user))
1557 {
ddef84f1 1558 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name.getString());
83cf716f 1559 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1560 "of your experience!");
1561 user->stats->gold = 0;
1562 user->stats->exp -= (long int)(user->stats->exp * .10);
b478c0df 1563 user->stats->hp = 0;
83cf716f 1564 user->stats->fight = NULL;
ee38284f 1565 clearAlive(user->stats);
83cf716f 1566 goto endturn;
1567 }
1568 else
1569 {
1570 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
ddef84f1 1571 "until tomorrow to try again", user->stats->master->name.getString());
83cf716f 1572 user->stats->fight = NULL;
1573 user->stats->master = NULL;
1574 goto endturn;
1575 }
1576 }
1577 else
1578 {
1579 if (mhit > 0)
1580 user->stats->hp -= mhit;
1581 display_monster(u);
1582 goto endturn;
1583 }
1584 }
1585 else
1586 {
ee38284f 1587 clearYourTurn(user->stats);
1588 setYourTurn(battle->stats);
83cf716f 1589 display_players(battle);
1590 }
1591endturn:
1592 delete nick;
1593}
1594
85ce9d3e 1595void do_attack(char *u)
1596{
1597 int hit, mhit;
1598 aClient *ni, *battle; // The player and perhaps the player they're fighting
1599 Monster *fight; // The monster they may be fighting
1600
1601 if (!(ni = find(u)))
83cf716f 1602 {
1603 notice(s_GameServ, u, "Fatal error in do_attack. Contact a(n) %S admin for help.");
1604 return;
1605 }
448a1531 1606 else if (isIgnore(ni))
1607 {
1608 #ifdef DEBUGMODE
1609 log("Ignoring %s.", ni->getNick());
1610 #endif
1611 return;
1612 }
83cf716f 1613 else if (!is_playing(ni))
85ce9d3e 1614 {
1615 notice(s_GameServ, u, "You're not playing!");
1616 return;
1617 }
83cf716f 1618 else if (!is_fighting(ni))
85ce9d3e 1619 {
1620 notice(s_GameServ, u, "You're not in battle!");
1621 return;
1622 }
1623 else
1624 {
1625 if (!ni->stats->master) // This is not a master fight
1626 fight = ni->stats->fight; // Monster Could be NULL
1627 else // This IS a master fight
1628 fight = ni->stats->master; // Master Could be NULL
1629
1630 battle = ni->stats->battle; // Player Could be NULL
1631
1632 // One has to be !NULL based on the previous else if
1633 // We wouldn't be here if they were all NULL
1634 }
40251952 1635 updateTS(ni->stats);
85ce9d3e 1636
1af35752 1637 if (!player_fight(ni))
85ce9d3e 1638 {
1639 // Player's Hit
1640 hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1641 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
1642
1643 // Opponent's Hit
1644 mhit = (fight->strength / 2) +
1645 (rand() % (fight->strength / 2) - (ni->stats->defense +
1646 arbonus[ni->stats->armor]));
1647 }
1648 else
1649 {
1650 // Opponent's Hit
1651 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1652 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1653 (ni->stats->defense + arbonus[ni->stats->armor]));
1654
1655 // Player's Hit
1656 hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1657 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
1658 (battle->stats->defense + arbonus[battle->stats->armor]));
1659 }
1660
1af35752 1661 if (!player_fight(ni))
85ce9d3e 1662 {
1663 if (hit > 0)
ddef84f1 1664 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name.getString(), hit);
85ce9d3e 1665 else
ddef84f1 1666 notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name.getString());
85ce9d3e 1667
1668 if (hit >= fight->hp)
1669 {
1af35752 1670 if (master_fight(ni))
c260a8d7 1671 {
ddef84f1 1672 notice(s_GameServ, u, "You have bested %s!", fight->name.getString());
c260a8d7 1673 addNews(todaysnews, "%s has bested %s and moved "\
ddef84f1 1674 "to level %d", ni->stats->name.getString(), fight->name.getString(),
c260a8d7 1675 (ni->stats->level + 1));
1676 }
85ce9d3e 1677 else
ddef84f1 1678 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name.getString());
85ce9d3e 1679
ddef84f1 1680 notice(s_GameServ, u, "%s", fight->death.getString());
85ce9d3e 1681 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
1682 fight->exp, fight->gold);
1683
1684 // If your new experience (or gold) will be greater than 2 billion,
1685 // then set your exp to 2bil. (2 billion max)... otherwise add them.
1686 // This could be a problem with overflowing out of the sign bit.
1687 // Unsigned long int maybe? Leave it for now.
082f064d 1688 ni->stats->exp += fight->exp;
1689 if (ni->stats->exp < 0 || ni->stats->exp > 2000000000)
1690 ni->stats->exp = 2000000000;
c8ada07e 1691
082f064d 1692 ni->stats->gold += fight->gold;
1693 if (ni->stats->gold < 0 || ni->stats->gold > 2000000000)
1694 ni->stats->gold = 2000000000;
85ce9d3e 1695
1af35752 1696 if (master_fight(ni))
85ce9d3e 1697 {
1698 notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
1699 notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
1700 strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
1701
1702 // Increase your level
85ce9d3e 1703
1704 // Increase your maximum hit points
1705 ni->stats->maxhp += hpbonus[ni->stats->level - 1];
1706
1707 // Heal the player by setting hp to their max
1708 ni->stats->hp = ni->stats->maxhp;
1709
1710 // Add to your strength
1711 ni->stats->strength += strbonus[ni->stats->level - 1];
1712
1713 // Add to your defensive power
1714 ni->stats->defense += defbonus[ni->stats->level - 1];
1715
6370e3da 1716 ni->stats->level++;
1717
85ce9d3e 1718 // Clear the pointer for your master
1719 ni->stats->master = NULL;
1720 }
ab4f4ec0 1721
1722 // They're dead so remove the pointer
1723 delete ni->stats->fight;
1724 ni->stats->fight = NULL;
1725 ni->stats->master = NULL;
1726
85ce9d3e 1727 return;
1728 }
1729 else
1730 {
1731 if (hit > 0)
1732 fight->hp -= hit;
1733 if (mhit > 0)
1734 {
e282e9d2 1735 notice(s_GameServ, u, "\1f%s\1f attacks with their \1f%s\1f for \ 2%d\ 2 damage!",
ddef84f1 1736 fight->name.getString(), fight->weapon.getString(), mhit);
85ce9d3e 1737 }
1738 else if (mhit <= 0)
ddef84f1 1739 notice(s_GameServ, u, "%s completely misses you!", fight->name.getString());
85ce9d3e 1740
1741 if (mhit >= ni->stats->hp)
1742 {
1af35752 1743 if (!master_fight(ni))
85ce9d3e 1744 {
ddef84f1 1745 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name.getString());
85ce9d3e 1746 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1747 "of your experience!");
c260a8d7 1748 addNews(todaysnews, "%s has been killed by %s!",
ddef84f1 1749 ni->stats->name.getString(), fight->name.getString());
85ce9d3e 1750 ni->stats->gold = 0;
1751 ni->stats->exp -= (long int)(ni->stats->exp * .10);
b478c0df 1752 ni->stats->hp = 0;
85ce9d3e 1753 ni->stats->fight = NULL;
ee38284f 1754 clearAlive(ni->stats);
85ce9d3e 1755 return;
1756 }
1757 else
1758 {
1759 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
ddef84f1 1760 "until tomorrow to try again", ni->stats->master->name.getString());
c260a8d7 1761 addNews(todaysnews, "%s tried to best %s and failed!",
ddef84f1 1762 ni->stats->name.getString(), fight->name.getString());
85ce9d3e 1763 ni->stats->fight = NULL;
1764 ni->stats->master = NULL;
1765 return;
1766 }
1767 }
1768 else
1769 {
1770 if (mhit > 0)
1771 ni->stats->hp -= mhit;
1772 display_monster(u);
1773 return;
1774 }
1775 }
1776 }
1af35752 1777 else if (player_fight(ni))
85ce9d3e 1778 {
1779/* Offline fighting not available yet
1780 if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
1781 {
1782 if (hit > 0)
1783 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
1784 else
1785 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
1786 if (hit >= battle->stats->hp)
1787 {
1788 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
1789* notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1790 (long int)(battle->stats->exp * .10), battle->stats->gold);
1791 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1792 {
1793 ni->stats->exp += (long int)(battle->stats->exp * .10);
1794 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1795 }
1796* else
1797 {
1798 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1799 ni->stats->exp = 2000000000;
1800 }
1801
1802 if (2000000000 - ni->stats->gold > battle->stats->gold)
1803 {
1804* ni->stats->gold += battle->stats->gold;
1805 battle->stats->gold = 0;
1806 }
1807 else
1808 {
1809 battle->stats->gold = 2000000000 - ni->stats->gold;
1810 ni->stats->gold = 2000000000;
1811 }
1812* ni->stats->battle->stats->alive = 0;
1813 ni->stats->battle->battle = NULL;
1814 ni->stats->battle = NULL;
1815 return;
1816 }
1817 else
1818 {
1819 if (hit > 0)
1820* battle->stats->hp -= hit;
1821 if (mhit > 0)
1822 {
1823 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1824 battle->nick, weapons[battle->stats->weapon], mhit);
1825 }
1826 else if (mhit <= 0)
1827 notice(s_GameServ, u, "%s completely misses you!", battle->nick);
1828*
1829 if (mhit >= ni->stats->hp)
1830 {
1831 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
1832 if (2000000000 - battle->stats->gold > ni->stats->gold)
1833 {
1834 notice(s_GameServ, u, "%s took all your gold!", battle->nick);
1835 battle->stats->gold += ni->stats->gold;
1836* ni->stats->gold = 0;
1837 }
1838 else
1839 {
1840 notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
1841 battle->nick);
1842 ni->stats->gold -= (2000000000 - battle->stats->gold);
1843 notice(s_GameServ, u, "You were left dead with %d gold.",
1844* (long int)ni->stats->gold);
1845 battle->stats->gold = 2000000000;
1846 }
1847 ni->stats->battle->battle = NULL;
1848 ni->stats->battle = NULL;
1849 ni->stats->alive = 0;
1850 return;
1851 }
1852* else
1853 {
1854 if (mhit > 0)
1855 ni->stats->hp -= mhit;
1856 display_players(u);
1857 return;
1858 }
1859 }
1860 }
1861* end offline fighting */
1862
ce61cdfa 1863 if (is_playing(battle))
85ce9d3e 1864 {
ee38284f 1865 if (!isYourTurn(ni->stats))
85ce9d3e 1866 {
1867 notice(s_GameServ, u, "Please wait until %s decides what to do!",
ddef84f1 1868 battle->stats->name.getString());
85ce9d3e 1869 return;
1870 }
1871 if (hit > 0)
1872 {
ddef84f1 1873 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->stats->name.getString(), hit);
85ce9d3e 1874
1875 notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
ddef84f1 1876 "\ 2%d\ 2 damage!", ni->stats->name.getString(),
ce61cdfa 1877 weapons[ni->stats->weapon], hit);
85ce9d3e 1878 }
1879 else
1880 {
ddef84f1 1881 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->stats->name.getString());
1882 notice(s_GameServ, battle->getNick(), "%s misses you completely!", ni->stats->name.getString());
85ce9d3e 1883 }
c260a8d7 1884
85ce9d3e 1885 if (hit >= battle->stats->hp)
1886 {
ddef84f1 1887 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->stats->name.getString());
85ce9d3e 1888 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1889 (long int)(battle->stats->exp * .10), battle->stats->gold);
ce61cdfa 1890 notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!",
ddef84f1 1891 ni->stats->name.getString());
85ce9d3e 1892 battle->stats->hp = 0;
ee38284f 1893 clearAlive(battle->stats);
85ce9d3e 1894
082f064d 1895 ni->stats->exp += (long int)(battle->stats->exp * .10);
1896 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1897
1898 if (ni->stats->exp < 0 || ni->stats->exp > 2000000000)
85ce9d3e 1899 ni->stats->exp = 2000000000;
85ce9d3e 1900
1901 if (2000000000 - ni->stats->gold > battle->stats->gold)
1902 {
1903 notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
1904 "all gold on hand!");
1905 ni->stats->gold += battle->stats->gold;
1906 battle->stats->gold = 0;
1907 }
1908 else
1909 {
1910 battle->stats->gold = 2000000000 - ni->stats->gold;
1911 notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
1912
1913 notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
ddef84f1 1914 "gold.", ni->stats->name.getString());
85ce9d3e 1915
1916 notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
1917 "left. All is not lost!", battle->stats->gold);
1918
1919 ni->stats->gold = 2000000000;
1920 }
082f064d 1921
c260a8d7 1922 clearYourTurn(ni->stats);
1923 clearYourTurn(battle->stats);
85ce9d3e 1924 battle->stats->battle = NULL;
1925 ni->stats->battle = NULL;
1926 return;
1927 }
1928 else
1929 {
1930 if (hit > 0)
1931 battle->stats->hp -= hit;
ee38284f 1932 clearYourTurn(ni->stats);
1933 setYourTurn(battle->stats);
c260a8d7 1934 display_players(battle);
85ce9d3e 1935 notice(s_GameServ, u, "Please wait while %s decides what to do!",
ddef84f1 1936 battle->stats->name.getString());
85ce9d3e 1937 return;
1938 }
1939 }
1940 }
1941}
ce61cdfa 1942
85ce9d3e 1943void do_heal(char *u)
1944{
1945 aClient *ni;
1946 char *amount = strtok(NULL, " ");
1947 int price, num;
1948
1949 if (!amount)
1950 {
1951 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
40251952 1952 return;
85ce9d3e 1953 }
1af35752 1954 else if (!(ni = find(u)))
1955 {
1956 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
1957 return;
1958 }
448a1531 1959 else if (isIgnore(ni))
1960 {
1961 #ifdef DEBUGMODE
1962 log("Ignoring %s.", ni->getNick());
1963 #endif
1964 return;
1965 }
1af35752 1966 else if (!is_playing(ni))
85ce9d3e 1967 {
1968 notice(s_GameServ, u, "You aren't playing!");
1af35752 1969 return;
1970 }
ee38284f 1971 else if (!isAlive(ni->stats))
1af35752 1972 {
1973 notice(s_GameServ, u, "You are dead. Wait until tomorrow for healing.");
1974 return;
85ce9d3e 1975 }
1af35752 1976 else if (is_fighting(ni))
85ce9d3e 1977 {
1978 notice(s_GameServ, u, "You can't heal in battle!");
40251952 1979 return;
85ce9d3e 1980 }
1981 else if (ni->stats->hp >= ni->stats->maxhp)
1982 {
1983 notice(s_GameServ, u, "You don't need healing!");
40251952 1984 return;
85ce9d3e 1985 }
40251952 1986
1987 updateTS(ni->stats);
1988 if (stricmp(amount, "ALL") == 0)
85ce9d3e 1989 {
1990 price = ni->stats->level * 3;
1991 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
1992 {
1993 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1994 (long int)ni->stats->gold/price, price);
1995 ni->stats->hp += ni->stats->gold / price;
1996 ni->stats->gold %= price;
1997 }
1998 else
1999 {
2000 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
2001 "per point.", price);
ad7dfaa0 2002 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
2003 (ni->stats->maxhp - ni->stats->hp),
2004 (price * (ni->stats->maxhp - ni->stats->hp)) );
85ce9d3e 2005 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
2006 ni->stats->hp = ni->stats->maxhp;
2007 }
2008 }
2009 else if (isstringnum(amount))
2010 {
2011 num = stringtoint(amount);
2012 price = ni->stats->level * 3;
2013 if (ni->stats->gold < price * num)
2014 {
2015 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
2016 (long int)ni->stats->gold/price);
2017 }
2018 else if (num <= ni->stats->maxhp - ni->stats->hp)
2019 {
2020 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
2021 num, price);
2022 ni->stats->hp += num;
2023 ni->stats->gold -= num * price;
2024 }
2025 else if (num > ni->stats->maxhp - ni->stats->hp)
2026 {
2027 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
2028 "per point.", price);
2029 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
2030 (ni->stats->maxhp - ni->stats->hp));
2031 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
2032 ni->stats->hp = ni->stats->maxhp;
2033 }
2034 }
2035 else if (amount[0] == '-')
2036 notice(s_GameServ, u, "You trying to cheat?");
2037 else
2038 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
2039}
2040
2041int isstringnum(char *num)
2042{
28f552b8 2043 unsigned int x;
85ce9d3e 2044 for (x = 0; x < strlen(num); x++)
2045 {
2046 if ((int)num[x] < 48 || (int)num[x] > 57)
2047 return 0;
2048 }
2049return 1;
2050}
2051
2052long int stringtoint(char *number)
2053{
2054 long int x, len = strlen(number), sum = 0;
2055 if (len == 1)
2056 return chartoint(number[0]);
2057 sum += chartoint(number[len - 1]);
2058 for (x = len - 2; x >= 0; x--)
85ce9d3e 2059 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
85ce9d3e 2060 return sum;
2061}
2062
2063long int pow(int x, int y)
2064{
2065 long int value = 0;
2066 int count = 0;
2067 value += x;
2068
2069 if (x != 0 && y != 0)
2070 {
2071 for (count = 1; count <= y - 1; count++)
2072 value *= x;
2073 }
2074 else
2075 return 1;
2076return value;
2077}
2078
2079long int chartoint(char ch)
2080{
8c126acc 2081 if (int(ch) >= 48 && int(ch) <= 57)
2082 return int(ch) - 48;
2083 else
2084 return 0;
85ce9d3e 2085}
2086
2087int save_gs_dbase()
2088{
7996e5fd 2089 ListNode<aClient> *ptr;
85ce9d3e 2090 Player *it;
2091 ofstream outfile;
2092
2093 outfile.open(playerdata);
2094
2095 if (!outfile)
2096 {
fb37ecc7 2097 log("Error opening %s", playerdata);
85ce9d3e 2098 return 0;
2099 }
2100
7996e5fd 2101 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
2102 {
2103 ptr = players[x].First();
85ce9d3e 2104 while(ptr)
2105 {
2106 it = ptr->getData()->stats;
ae2685f6 2107 clearYourTurn(it);
ddef84f1 2108 outfile << it->name.getString() << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' '
2109 << it->bank << ' ' << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense
2110 << ' ' << it->armor << ' ' << it->weapon << ' '
e3c5fe46 2111 << it->forest_fights << ' ' << it->player_fights << ' '
ddef84f1 2112 << it->getFlags() << ' ' << it->password.getString() << ' ' << it->inventory.Healing()
14e24ba1 2113 << ' ' << it->inventory.Strength() << ' ' << it->inventory.Defense() << ' ' << it->inventory.HP()
82c01ddf 2114 << ' ' << it->lastlogin << endl;
85ce9d3e 2115 ptr = ptr->Next();
2116 }
7996e5fd 2117 }
85ce9d3e 2118outfile.close();
28f552b8 2119return 1;
85ce9d3e 2120}
2121
2122int load_gs_dbase()
2123{
2124 ifstream infile;
2125 aClient *temp;
2126 Player *p;
ee38284f 2127 char *tempname, *buf, *password;
85ce9d3e 2128 buf = new char[1023];
2129
2130 infile.open(playerdata);
2131
2132 if (infile.fail())
2133 {
fb37ecc7 2134 log("Error opening %s", playerdata);
85ce9d3e 2135 return 0;
2136 }
2137
19795233 2138 for (int x = 0; x < U_TABLE_SIZE; x++)
2139 {
2140 ListNode<aClient> *tempNode;
2141 tempNode = players[x].First();
2142 while (tempNode)
2143 {
2144 if (tempNode->getData()->stats->client)
2145 logout(tempNode->getData()->stats->client);
2146 tempNode = tempNode->Next();
2147 }
2148 players[x].deleteNodes();
2149 }
2150
85ce9d3e 2151 while (infile.getline(buf, 1024, '\n'))
2152 {
2153 temp = new aClient;
2154 tempname = strtok(buf, " ");
2155 temp->stats = new Player(tempname);
2156 p = temp->stats;
2157
85ce9d3e 2158 p->level = stringtoint(strtok(NULL, " "));
2159 p->exp = stringtoint(strtok(NULL, " "));
2160 p->gold = stringtoint(strtok(NULL, " "));
2161 p->bank = stringtoint(strtok(NULL, " "));
2162 p->hp = stringtoint(strtok(NULL, " "));
2163 p->maxhp = stringtoint(strtok(NULL, " "));
2164 p->strength = stringtoint(strtok(NULL, " "));
2165 p->defense = stringtoint(strtok(NULL, " "));
2166 p->armor = stringtoint(strtok(NULL, " "));
2167 p->weapon = stringtoint(strtok(NULL, " "));
85ce9d3e 2168 p->forest_fights = stringtoint(strtok(NULL, " "));
2169 p->player_fights = stringtoint(strtok(NULL, " "));
1af35752 2170 p->setFlags(stringtoint(strtok(NULL, " ")));
ee38284f 2171
e3c5fe46 2172 password = strtok(NULL, " ");
ddef84f1 2173 p->password = password;
2174
448a1531 2175 temp->setNick("Not Playing");
ce61cdfa 2176 #ifdef P10
448a1531 2177 temp->setRealNick("Not Playing");
ce61cdfa 2178 #endif
85ce9d3e 2179
9d3b1d42 2180 p->inventory.reset(); // Set inventory to all 0s
ee38284f 2181 // Old player databases didn't have these three extra values
2182 // If they come up null, leave them to 0 as the default.
2183 // On the next gameserv database save, it will save the values.
266608f6 2184 tempname = strtok(NULL, " ");
9d3b1d42 2185 if (tempname)
2186 p->inventory.setHealing(stringtoint(tempname));
2187
2188 tempname = strtok(NULL, " ");
2189 if (tempname)
2190 p->inventory.setStrength(stringtoint(tempname));
2191
2192 tempname = strtok(NULL, " ");
2193 if (tempname)
2194 p->inventory.setDefense(stringtoint(tempname));
2195
2196 tempname = strtok(NULL, " ");
2197 if (tempname)
2198 p->inventory.setHP(stringtoint(tempname));
14e24ba1 2199
2200 tempname = strtok(NULL, " ");
2201 if (tempname)
2202 p->lastlogin = stringtoint(tempname);
2203 else
2204 p->lastlogin = time(NULL);
2205
ddef84f1 2206 unsigned long hv = iHASH((unsigned char *) temp->stats->name.getString());
85bcf836 2207
2208 temp->stats->client = NULL;
7996e5fd 2209 players[hv].insertAtBack(temp);
85ce9d3e 2210 delete temp;
2211 }
1cf88153 2212delete [] buf;
28f552b8 2213infile.close();
2214return 1;
85ce9d3e 2215}
2216
e3c5fe46 2217bool passcmp(char *encrypted, char *plaintext)
2218{
2219 char salt[3];
cdc9a6db 2220 char *plaintext2, *plainToencrypt;
2221 bool same = false;
2222
2223 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
2224 strcpy(plaintext2, plaintext);
2225
e3c5fe46 2226 salt[0] = encrypted[0];
2227 salt[1] = encrypted[1];
2228 salt[3] = '\0';
cdc9a6db 2229
2230 plainToencrypt = crypt(plaintext2, salt);
2231
2232 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
2233
2234 delete []plaintext2;
2235
2236 return same;
e3c5fe46 2237}
2238
2239bool check_password(char *name, char *plaintext)
2240{
0a1518fa 2241 aClient *client;
e3c5fe46 2242
0a1518fa 2243 if (!(client = findplayer(name)))
2244 return false;
2245 else
e3c5fe46 2246 {
ddef84f1 2247 return passcmp(client->stats->password.getString(), plaintext);
e3c5fe46 2248 }
e3c5fe46 2249}
1cf88153 2250
ad7dfaa0 2251void do_store(char *u)
2252{
2253 char *cmd = strtok(NULL, " ");
2254 char *item = strtok(NULL, " ");
2255 char *num = strtok(NULL, " ");
2256 char *space;
8c126acc 2257 int wep;
2258 aClient *user;
2259 Player *p;
ad7dfaa0 2260
1af35752 2261 if (!cmd || !item)
ad7dfaa0 2262 {
2263 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2264 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2265 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
40251952 2266 return;
ad7dfaa0 2267 }
448a1531 2268 else if (!(user = find(u)))
2269 {
2270 log("Fatal Error: could not find %s in client list", u);
2271 return;
2272 }
2273 else if (isIgnore(user))
2274 {
2275 #ifdef DEBUGMODE
2276 log("Ignoring %s.", user->getNick());
2277 #endif
2278 return;
2279 }
2280 else if (!is_playing(user))
40251952 2281 {
1af35752 2282 notice(s_GameServ, u, "You must be playing to use the store!");
40251952 2283 return;
2284 }
ee38284f 2285 else if (!isAlive(user->stats))
1af35752 2286 {
2287 notice(s_GameServ, u, "You are dead. Wait until tomorrow to purchase weapons and armor!");
2288 return;
2289 }
40251952 2290 updateTS(user->stats);
2291
2292 if (stricmp(cmd, "LIST") == 0)
ad7dfaa0 2293 {
2294 if (stricmp(item, "WEAPONS") == 0)
2295 {
2296 notice(s_GameServ, u, "Welcome to Kain's Armory");
2297 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
2298 for (int x = 1; x < WNA; x++)
2299 {
2300 space = spaces(strlen(weapons[x]), ".");
2301 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
2302 free(space);
2303 }
2304 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
2305 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
2306
2307 }
2308 else if (stricmp(item, "ARMOR") == 0)
2309 {
2310 notice(s_GameServ, u, "Welcome to Kain's Armory");
2311 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
2312 for (int x = 1; x < WNA; x++)
2313 {
2314 space = spaces(strlen(armors[x]), ".");
2315 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
2316 free(space);
2317 }
2318 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
2319 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
2320
2321
2322 }
2323 } else if (stricmp(cmd, "BUY") == 0) {
8c126acc 2324 if (!num)
2325 {
2326 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2327 return;
2328 }
2329 else if (!isstringnum(num))
2330 {
2331 notice(s_GameServ, u, "You must specify a number between 1 and %d. Not %s!", WNA - 1, num);
2332 return;
2333 }
2334 if (stricmp(item, "WEAPON") == 0)
2335 {
2336 wep = stringtoint(num);
2337 if (wep >= WNA || wep < 1)
2338 {
2339 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2340 return;
2341 }
2342
2343 p = user->stats;
2344
2345 if (p->weapon != 0)
2346 notice(s_GameServ, u, "You have to sell your %s first!", weapons[p->weapon]);
2347 else if (p->gold < prices[wep - 1])
2348 notice(s_GameServ, u, "You don't have enough gold for %s!", weapons[wep]);
2349 else
2350 {
2351 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", weapons[wep]);
2352 p->weapon = wep;
2353 p->gold -= prices[wep - 1];
2354 }
2355 }
2356 else if (stricmp(item, "ARMOR") == 0)
2357 {
2358 wep = stringtoint(num);
2359 if (wep >= WNA || wep < 1)
2360 {
2361 notice(s_GameServ, u, "The number %d is out of range. The number you provide must be between 1 and %d.", wep, WNA - 1);
2362 return;
2363 }
2364
2365 p = user->stats;
2366
2367 if (p->armor != 0)
2368 notice(s_GameServ, u, "You have to sell your %s first!", armors[p->armor]);
2369 else if (p->gold < prices[wep - 1])
2370 notice(s_GameServ, u, "You don't have enough gold for %s!", armors[wep]);
2371 else
2372 {
2373 notice(s_GameServ, u, "You have purchased %s! Thanks for the gold!", armors[wep]);
2374 p->armor = wep;
2375 p->gold -= prices[wep - 1];
2376 }
2377 }
a02e93a1 2378 else
2379 {
2380 notice(s_GameServ, u, "SYNTAX: \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2381 }
8c126acc 2382 }
2383 else if (stricmp(cmd, "SELL" ) == 0)
2384 {
2385 p = user->stats;
2386
2387 if (stricmp(item, "WEAPON") == 0)
2388 {
2389 if (p->weapon == 0)
2390 {
2391 notice(s_GameServ, u, "You want me to chop off your hands?");
2392 return;
2393 }
2394 else if (p->gold == 2000000000)
2395 {
2396 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2397 p->weapon = 0;
2398 }
2399 else if (2000000000 - p->gold < (prices[p->weapon - 1] / 2))
2400 {
2401 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2402 notice(s_GameServ, u, "However, you have no weapon... can I interest you in the %s?", weapons[WNA - 1]);
2403 p->gold = 2000000000;
2404 p->weapon = 0;
2405 }
2406 else
2407 {
2408 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no weapon!", (prices[p->weapon - 1] / 2));
2409 p->gold += (prices[p->weapon - 1] / 2);
2410 p->weapon = 0;
2411 }
2412 }
2413 else if (stricmp(item, "ARMOR") == 0)
2414 {
2415 p = user->stats;
2416
2417 if (p->armor == 0)
2418 {
2419 notice(s_GameServ, u, "I don't think you can be any more naked...");
2420 return;
2421 }
2422 if (p->gold == 2000000000)
2423 {
2424 notice(s_GameServ, u, "You have enough gold. I'll just take that off your hands, sire.");
2425 p->armor = 0;
2426 }
2427 else if (2000000000 - p->gold < (prices[p->armor - 1] / 2))
2428 {
2429 notice(s_GameServ, u, "Thank you for your business! You now have as much gold as you can carry.");
2430 notice(s_GameServ, u, "However, you have no armor... can I interest you in %s?", armors[WNA - 1]);
2431 p->gold = 2000000000;
2432 p->armor = 0;
2433 }
2434 else
2435 {
2436 notice(s_GameServ, u, "Thank you for your business! You now have %d more gold but no armor!",
2437 (prices[p->armor - 1] / 2));
2438
2439 p->gold += (prices[p->armor - 1] / 2);
2440 p->armor = 0;
2441 }
2442 }
2443 else
2444 {
2445 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2446 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2447 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2448 }
2449 }
6d053d90 2450 else
2451 {
2452 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
2453 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
2454 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
2455 return;
2456 }
8c126acc 2457}
9cda831c 2458void do_inventory(char *u)
2459{
2460 aClient *user;
2461
2462 if (!(user = find(u)))
2463 {
2464 notice(s_GameServ, u, "Fatal Error. Contact a %S admin!");
2465 return;
2466 }
448a1531 2467 else if (isIgnore(user))
2468 {
2469 #ifdef DEBUGMODE
2470 log("Ignoring %s.", user->getNick());
2471 #endif
2472 return;
2473 }
9cda831c 2474 else if (!is_playing(user))
2475 {
2476 notice(s_GameServ, u, "You must be playing to check your inventory!");
2477 return;
2478 }
40251952 2479 updateTS(user->stats);
9cda831c 2480 showinventory(user, user);
2481}
2482void showinventory(aClient *from, aClient *to)
2483{
2484 char *nick = to->getNick();
8c126acc 2485
9cda831c 2486 if (!to)
2487 to = from;
2488 if (is_playing(from))
2489 {
2490 Pouch *p = &from->stats->inventory;
ddef84f1 2491 notice(s_GameServ, nick, "Inventory for %s:", from->stats->name.getString());
9cda831c 2492 notice(s_GameServ, nick, " Healing Potions: %d", p->Healing());
2493 notice(s_GameServ, nick, "Strength Potions: %d", p->Strength());
2494 notice(s_GameServ, nick, " Defense Potions: %d", p->Defense());
9d3b1d42 2495 notice(s_GameServ, nick, " HP Potions: %d", p->HP());
9cda831c 2496 }
2497}
f5c25639 2498void do_tavern(char *u)
2499{
2500 char *cmd = strtok(NULL, " ");
2501 long int price;
2502
2503 aClient *user;
2504 Player *p;
a6352eed 2505
f5c25639 2506 if (!(user = find(u)))
2507 {
2508 notice(s_GameServ, u, "Fatal Error. See a %S admin for help");
2509 return;
2510 }
448a1531 2511 else if (isIgnore(user))
2512 {
2513 #ifdef DEBUGMODE
2514 log("Ignoring %s.", user->getNick());
2515 #endif
2516 return;
2517 }
f5c25639 2518 else if (!is_playing(user))
2519 {
2520 notice(s_GameServ, u, "You must be playing to go to the Tavern");
2521 return;
2522 }
9cda831c 2523 else if (is_fighting(user))
2524 {
2525 notice(s_GameServ, u, "You cannot go to the Tavern during a fight!");
2526 return;
2527 }
40251952 2528
2529 updateTS(user->stats);
f5c25639 2530 p = user->stats;
40251952 2531
f5c25639 2532 if (!cmd)
2533 {
2534 notice(s_GameServ, u, "Welcome to Boot Liquors Mystic Apothecary");
2535 notice(s_GameServ, u, "Your commands:");
2536 notice(s_GameServ, u, "/msg %S TAVERN {LIST | BUY} [NUMBER]");
2537 notice(s_GameServ, u, "What'll it be?");
2538 }
2539 else if (stricmp(cmd, "LIST") == 0)
2540 {
a6352eed 2541 notice(s_GameServ, u, "Here is a list of what we have to offer:");
2542 notice(s_GameServ, u, "1. Healing Potions for %ld Gold",
2543 1000 * p->level * 4);
2544 notice(s_GameServ, u, "2. Strength Potions for %ld Gold",
2545 2500 * p->level * 4);
2546 notice(s_GameServ, u, "3. Defense Potions for %ld Gold",
2547 3000 * p->level * 4);
2548 notice(s_GameServ, u, "4. HP Potions for %ld Gold",
2549 2000 * p->level * 4);
2550 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2551 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
f5c25639 2552 }
2553 else if (stricmp(cmd, "BUY") == 0)
2554 {
2555 char *chnum = strtok(NULL, " ");
f5c25639 2556
2557 if (!chnum)
2558 {
2559 notice(s_GameServ, u, "SYNTAX: TAVERN BUY #");
2560 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1");
2561 return;
2562 }
19795233 2563 int num = stringtoint(chnum);
2564
8c734eb9 2565 if (num < 1 || num > 4)
f5c25639 2566 {
2567 notice(s_GameServ, u, "Invalid Choice!");
2568 notice(s_GameServ, u, "Here is a list of what we have to offer:");
a6352eed 2569 notice(s_GameServ, u, "1. Healing Potions for %ld Gold",
2570 1000 * p->level * 4);
2571 notice(s_GameServ, u, "2. Strength Potions for %ld Gold",
2572 2500 * p->level * 4);
2573 notice(s_GameServ, u, "3. Defense Potions for %ld Gold",
2574 3000 * p->level * 4);
2575 notice(s_GameServ, u, "4. HP Potions for %ld Gold",
2576 2000 * p->level * 4);
f5c25639 2577 notice(s_GameServ, u, "To buy a potion, type /msg %S TAVERN BUY #");
2578 notice(s_GameServ, u, "Example: /msg %S TAVERN BUY 1 buys a healing potion!");
ee38284f 2579 return;
f5c25639 2580 }
2581 switch(num)
2582 {
2583 case 1:
a6352eed 2584 price = (1000 * p->level * 4);
f5c25639 2585 if (p->gold >= price)
2586 {
2587 notice(s_GameServ, u, "One healing potion coming right up!");
2588 p->inventory.incHealing();
ee38284f 2589 p->gold -= price;
f5c25639 2590 }
2591 else
2592 notice(s_GameServ, u, "You don't have enough gold!");
2593 break;
2594 case 2:
a6352eed 2595 price = 2500 * p->level * 4;
f5c25639 2596 if (p->gold >= price)
2597 {
2598 notice(s_GameServ, u, "One strength boost coming right up!");
2599 p->inventory.incStrength();
ee38284f 2600 p->gold -= price;
f5c25639 2601 }
2602 else
2603 notice(s_GameServ, u, "You don't have enough gold!");
2604 break;
2605 case 3:
a6352eed 2606 price = 3000 * p->level * 4;
f5c25639 2607 if (p->gold >= price)
2608 {
2609 notice(s_GameServ, u, "One defense boost coming right up!");
2610 p->inventory.incDefense();
ee38284f 2611 p->gold -= price;
f5c25639 2612 }
2613 else
2614 notice(s_GameServ, u, "You don't have enough gold!");
2615 break;
8c734eb9 2616 case 4:
40b9580b 2617 price = 2000 * p->level * 4;
8c734eb9 2618 if (p->gold >= price)
2619 {
2620 notice(s_GameServ, u, "One HP Potion coming right up!");
2621 p->inventory.incHP();
2622 p->gold -= price;
2623 }
2624 else
2625 notice(s_GameServ, u, "You don't have enough gold!");
2626 break;
f5c25639 2627 default:
2628 notice(s_GameServ, u, "Logical Error. See a %S admin for help!");
2629 break;
2630 }
2631 }
9cda831c 2632 else
2633 {
2634 notice(s_GameServ, u, "Improper Syntax.");
2635 notice(s_GameServ, u, "Type /msg %S HELP TAVERN for help");
2636 }
f5c25639 2637}
2638
8c126acc 2639void do_bank(char *u)
2640{
2641 char *cmd = strtok(NULL, " ");
2642 char *amount = strtok(NULL, " ");
2643 char *nick = strtok(NULL, " ");
2644
2645 aClient *user;
2646 Player *p;
2647
8c734eb9 2648 if (!cmd || (!amount && stricmp(cmd, "BALANCE") != 0) || (stricmp(cmd, "TRANSFER") == 0 && !nick))
8c126acc 2649 {
2650 notice(s_GameServ, u, "BANK {WITHDRAW | DEPOSIT} {ALL | AMOUNT}");
e282e9d2 2651 notice (s_GameServ, u, "BANK BALANCE");
8c126acc 2652 return;
2653 }
40251952 2654 else if (!(user = find(u)))
2655 {
2656 notice(s_GameServ, u, "Fatal Error. Couldn't find your aClient. Contact a(n) %S "\
2657 " admin for help");
2658 log("Fatal Error. Couldn't find %s while executing do_bank()", u);
2659 return;
2660 }
448a1531 2661 else if (isIgnore(user))
2662 {
2663 #ifdef DEBUGMODE
2664 log("Ignoring %s.", user->getNick());
2665 #endif
2666 return;
2667 }
40251952 2668 else if (!is_playing(user))
8c126acc 2669 {
2670 notice(s_GameServ, u, "You must be playing to use the bank!");
2671 return;
ad7dfaa0 2672 }
2158299e 2673 else if (is_fighting(user))
2674 {
2675 notice(s_GameServ, u, "You can't go to the bank during a fight!");
2676 return;
2677 }
40251952 2678 updateTS(user->stats);
2679 if (stricmp(cmd, "BALANCE") == 0)
fa376453 2680 {
2681 showBankBalance(u);
2682 return;
2683 }
ee38284f 2684 else if (!isAlive(user->stats))
1af35752 2685 {
2686 notice(s_GameServ, u, "You are dead. We don't accept gold from dead folk! Wait 'til tomorrow!");
2687 return;
2688 }
8c126acc 2689 else if (!isstringnum(amount) && stricmp(amount, "ALL") != 0)
2690 {
2691 notice(s_GameServ, u, "I don't know how to convert alphabet letters into currency, sire!");
2692 return;
2693 }
11f32a66 2694 if (stringtoint(amount) < 0)
2695 {
2696 notice(s_GameServ, u, "Sorry. This bank is not licensed "\
2697 "to handle such sums of cash, noble Lord.");
2698 return;
2699 }
8c126acc 2700 p = user->stats;
2701
fa376453 2702 if (stricmp(cmd, "DEPOSIT") == 0)
8c126acc 2703 {
2704 if (p->bank == 2000000000)
2705 {
2706 notice(s_GameServ, u, "Your bank account is full, sire!");
2707 return;
2708 }
2709 else if (stricmp(amount, "ALL") == 0)
2710 {
2711 if (2000000000 - p->bank < p->gold)
2712 {
2713 notice(s_GameServ, u, "You don't have enough room for all of your gold.");
2714 notice(s_GameServ, u, "Depositing %ld gold into your account", (2000000000 - p->bank));
2715 p->gold -= (2000000000 - p->bank);
2716 p->bank = 2000000000;
e282e9d2 2717 showBankBalance(u);
8c126acc 2718 }
2719 else
2720 {
2721 notice(s_GameServ, u, "Depositing %ld gold into your account!", p->gold);
2722 p->bank += p->gold;
2723 p->gold = 0;
e282e9d2 2724 showBankBalance(u);
8c126acc 2725 }
2726 }
2727 else if (stringtoint(amount) > p->gold)
2728 {
2729 notice(s_GameServ, u, "Sire, you only have %ld gold!", p->gold);
e282e9d2 2730 showBankBalance(u);
8c126acc 2731 return;
2732 }
2733 else
2734 {
2735 if (2000000000 - p->bank < stringtoint(amount))
2736 {
2737 notice(s_GameServ, u, "You don't have room in your account for that much.");
2738 notice(s_GameServ, u, "Capping off your account with %ld gold!", (2000000000 - p->bank));
2739 p->gold -= (2000000000 - p->bank);
2740 p->bank = 2000000000;
e282e9d2 2741 showBankBalance(u);
8c126acc 2742 }
2743 else
2744 {
2745 notice(s_GameServ, u, "Depositing %d gold into your account!", stringtoint(amount));
2746 p->bank += stringtoint(amount);
2747 p->gold -= stringtoint(amount);
e282e9d2 2748 showBankBalance(u);
8c126acc 2749 }
2750 }
2751 }
2752 else if (stricmp(cmd, "WITHDRAW") == 0)
2753 {
2754 if (p->gold == 2000000000)
2755 {
2756 notice(s_GameServ, u, "You cannot carry any more gold, sire!");
e282e9d2 2757 showBankBalance(u);
8c126acc 2758 return;
2759 }
2760 else if (stricmp(amount, "ALL") == 0)
2761 {
2762 if (2000000000 - p->gold < p->bank)
2763 {
2764 notice(s_GameServ, u, "You don't have enough room to carry all that gold.");
2765 notice(s_GameServ, u, "Withdrawing %ld gold from your account", (2000000000 - p->gold));
2766 p->bank -= (2000000000 - p->gold);
2767 p->gold = 2000000000;
e282e9d2 2768 showBankBalance(u);
8c126acc 2769 }
2770 else
2771 {
2772 notice(s_GameServ, u, "Withdrawing %ld gold from your account!", p->bank);
2773 p->gold += p->bank;
2774 p->bank = 0;
e282e9d2 2775 showBankBalance(u);
8c126acc 2776 }
2777 }
2778 else if (stringtoint(amount) > p->bank)
2779 {
2780 notice(s_GameServ, u, "Sire, you only have %ld gold in the bank!", p->bank);
e282e9d2 2781 showBankBalance(u);
8c126acc 2782 return;
2783 }
2784 else
2785 {
2786 if (2000000000 - p->gold < stringtoint(amount))
2787 {
2788 notice(s_GameServ, u, "You don't enough have room to carry that much gold!");
2789 notice(s_GameServ, u, "You fill your pockets with %ld gold!",
2790 (2000000000 - p->gold));
2791 p->bank -= (2000000000 - p->gold);
2792 p->gold = 2000000000;
e282e9d2 2793 showBankBalance(u);
8c126acc 2794 }
2795 else
2796 {
2797 notice(s_GameServ, u, "Withdrawing %d gold from your account!", stringtoint(amount));
2798 p->gold += stringtoint(amount);
2799 p->bank -= stringtoint(amount);
e282e9d2 2800 showBankBalance(u);
8c126acc 2801 }
2802 }
2803 }
2804
ad7dfaa0 2805}
ab4f4ec0 2806
fcca861d 2807void do_dragon(char *u)
2808{
2809 aClient *user;
2810
2811 if (!(user = find(u)))
2812 {
2813 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2814 return;
2815 }
2816 else if (isIgnore(user))
2817 {
2818 #ifdef DEBUGMODE
2819 log("Ignoring %s.", user->getNick());
2820 #endif
2821 return;
2822 }
2823 else if (!is_playing(user))
2824 {
2825 notice(s_GameServ, u, "You must be playing to fight the dragon!");
2826 return;
2827 }
2828 else if (is_fighting(user))
2829 {
2830 notice(s_GameServ, u, "You are already in a fight. How will you fight the almighty dragon!?");
2831 return;
2832 }
2833 else if (!isAlive(user->stats))
2834 {
2835 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2836 return;
2837 }
016a160f 2838 else if (user->stats->level < REALLEVELS)
fcca861d 2839 {
2840 notice(s_GameServ, u, "You fool! Only those strong enough "\
2841 "to vanquish any foe should DARE fight the dragon!");
2842 notice(s_GameServ, u, "To put it in terms you can understand: "\
016a160f 2843 "You are too weak. You must be Level %d!", REALLEVELS);
68379f96 2844 return;
fcca861d 2845 }
2846
2847 updateTS(user->stats);
2848
fcca861d 2849 Player *p = user->stats;
082f064d 2850 p->fight = new Monster(&boss);
fcca861d 2851 notice(s_GameServ, u, "You approach the dragon's lair cautiously.");
2852 notice(s_GameServ, u, "The stench of sulfer fills the air as a "\
2853 "deep, red fog rolls in. The air is filled with the "\
2854 "heated mist of deadly fire from beyond the cave "\
2855 "entrance.");
9cb6f227 2856 notice(s_GameServ, u, "You adjust your %s, tighten your grip on "\
fcca861d 2857 "your %s, and venture into the hot, dark cave. "\
2858 "You are surprised at the angle of descent as you climb "\
af20337c 2859 "lower and lower, deeper into the dragon's den.", armors[p->level - 1], weapons[p->level - 1]);
fcca861d 2860 notice(s_GameServ, u, "You come to the end of the cave to find "\
2861 "a tooth. It is a large tooth... bigger than your torso."\
2862 " Suddenly the darkness lifts from the gleam of an eye "\
2863 " staring into your soul! The eye is large... HUGE!");
2864 notice(s_GameServ, u, "Just then you notice the eye begin to "\
2865 "glare orange! The tooth is moving... but it is still too "\
2866 "dark for you to make out.... THE DRAGON! You see it!");
9cb6f227 2867 display_monster(u);
fcca861d 2868}
2869
ab4f4ec0 2870void do_master(char *u)
2871{
2872 aClient *user;
1af35752 2873
448a1531 2874
2875 if (!(user = find(u)))
ab4f4ec0 2876 {
2877 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
2878 return;
2879 }
448a1531 2880 else if (isIgnore(user))
2881 {
2882 #ifdef DEBUGMODE
2883 log("Ignoring %s.", user->getNick());
2884 #endif
2885 return;
2886 }
c047f947 2887 else if (!is_playing(user))
2888 {
2889 notice(s_GameServ, u, "You must be playing to see your master!");
2890 return;
2891 }
1af35752 2892 else if (is_fighting(user))
ab4f4ec0 2893 {
2894 notice(s_GameServ, u, "You're in the middle of a fight! Pay attention!");
2895 return;
2896 }
ee38284f 2897 else if (!isAlive(user->stats))
1af35752 2898 {
2899 notice(s_GameServ, u, "You're dead. Wait until tomorrow to see your master!");
2900 return;
2901 }
40251952 2902
2903 updateTS(user->stats);
c047f947 2904
c7340cbd 2905 char *cmd = strtok(NULL, " ");
2906 Player *p = user->stats;
2907 long int need = 0;
2908
1af35752 2909 if (seenMaster(p))
2910 {
2911 notice(s_GameServ, u, "You have already seen your master today. Wait until tomorrow to try again");
2912 return;
2913 }
2914
c7340cbd 2915 if (cmd != NULL)
ab4f4ec0 2916 {
ab4f4ec0 2917 switch(p->level)
2918 {
2919 case 1:
fcca861d 2920 need = 200;
ab4f4ec0 2921 break;
2922 case 2:
fcca861d 2923 need = 800;
ab4f4ec0 2924 break;
2925 case 3:
fcca861d 2926 need = 2000;
ab4f4ec0 2927 break;
2928 case 4:
fcca861d 2929 need = 8000;
ab4f4ec0 2930 break;
2931 case 5:
fcca861d 2932 need = 20000;
ab4f4ec0 2933 break;
2934 case 6:
fcca861d 2935 need = 80000;
ab4f4ec0 2936 break;
2937 case 7:
fcca861d 2938 need = 200000;
ab4f4ec0 2939 break;
2940 case 8:
fcca861d 2941 need = 800000;
ab4f4ec0 2942 break;
2943 case 9:
fcca861d 2944 need = 2000000;
ab4f4ec0 2945 break;
2946 case 10:
fcca861d 2947 need = 8000000;
ab4f4ec0 2948 break;
2949 case 11:
fcca861d 2950 need = 20000000;
ab4f4ec0 2951 break;
016a160f 2952
2953 case REALLEVELS:
ab4f4ec0 2954 need = p->exp + 1;
016a160f 2955 notice(s_GameServ, u, "You are at level %d. You are the master. What's left? The DRAGON!", REALLEVELS);
fcca861d 2956 return;
ab4f4ec0 2957 break;
2958 default:
2959 need = p->exp + 1; // Unknown level... don't let them fight a fake master!
2960 break;
c7340cbd 2961 }
2962 }
2963 else
2964 {
2965 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
2966 return;
2967 }
2968
2969 if (stricmp(cmd, "FIGHT") == 0)
2970 {
ab4f4ec0 2971 if (p->exp >= need)
1af35752 2972 {
2973 setMaster(p);
ab4f4ec0 2974 see_master(u);
1af35752 2975 }
ab4f4ec0 2976 else
ddef84f1 2977 notice(s_GameServ, u, "You are not worthy of fighting %s! You need %ld more experience.",
2978 masters[p->level - 1]->name.getString(), (need - p->exp));
c7340cbd 2979 return;
2980 }
2981 else if (stricmp(cmd, "QUESTION") == 0)
2982 {
2983 if (p->exp >= need)
ddef84f1 2984 notice(s_GameServ, u, "%s looks you up and down and decides you are more ready than you will ever be.",
2985 masters[p->level - 1]->name.getString());
c7340cbd 2986 else
ddef84f1 2987 notice(s_GameServ, u, "You pathetic fool! You are no match for %s, %s!",
2988 masters[p->level - 1]->name.getString(), p->name.getString());
c7340cbd 2989
2990 return;
2991 }
2992 else
2993 {
2994 notice(s_GameServ, u, "SYNTAX: MASTER {FIGHT | QUESTION}");
ab4f4ec0 2995 }
2996}
2997
2998void see_master(char *u)
2999{
3000 aClient *user;
1af35752 3001
ab4f4ec0 3002 if (!(user = find(u)))
3003 {
3004 notice(s_GameServ, u, "Fatal error. Contact a(n) %S admin. buf: %s", strtok(NULL, ""));
3005 return;
3006 }
3007
1af35752 3008 if (!is_fighting(user) && is_playing(user))
ab4f4ec0 3009 {
3010 Player *p = user->stats;
3011 p->master = new Monster(masters[p->level - 1]);
3012 p->fight = p->master;
3013 display_monster(u); // Since master is the same structure, use this function
3014 }
3015}
e282e9d2 3016
3017void showBankBalance(const char *u)
3018{
3019 aClient *user;
3020 Player *p;
1af35752 3021
e282e9d2 3022 if (!(user = find(u)))
3023 return;
3024
3025 p = user->stats;
3026
3027 if (!p)
3028 return;
3029
3030 notice(s_GameServ, u, "Account Balance: %ld Gold On hand: %ld", p->bank, p->gold);
3031
3032}
44ea29f7 3033
3034void refreshall()
3035{
3036 ListNode <aClient> *it;
3037 Player *p;
7996e5fd 3038 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3039 {
3040 it = players[x].First();
44ea29f7 3041
3042 while (it)
3043 {
3044 p = it->getData()->stats;
3045 refresh(p);
3046 it = it->Next();
3047 }
7996e5fd 3048 }
44ea29f7 3049}
3050
3051void refresh(Player *p)
3052{
3053 if (!p)
3054 return;
3055
ee38284f 3056 if (p->hp < p->maxhp)
3057 p->hp = p->maxhp;
20d5d721 3058 p->forest_fights = forestfights;
44ea29f7 3059 p->player_fights = 3;
ee38284f 3060 setAlive(p);
1af35752 3061 clearMaster(p);
44ea29f7 3062}
c7340cbd 3063
3064void do_refresh(char *u)
3065{
3066 char *nick = strtok(NULL, " ");
3067 aClient *user;
3068
96f71fee 3069 if (!(user = find(u)))
3070 {
3071 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
5d04eb42 3072 log("Error: aClient not found: %s", u);
96f71fee 3073 return;
3074 }
448a1531 3075 else if (isIgnore(user))
3076 {
3077 #ifdef DEBUGMODE
3078 log("Ignoring %s.", user->getNick());
3079 #endif
3080 return;
3081 }
96f71fee 3082 else if (!isAdmin(user))
3083 {
3084 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3085 return;
3086 }
c7340cbd 3087 if (!nick)
3088 {
96f71fee 3089 notice(s_GameServ, u, "SYNTAX: REFRESH {ALL | NICK}");
c7340cbd 3090 return;
3091 }
3092 else if (stricmp(nick, "ALL") == 0)
3093 {
3094 notice(s_GameServ, u, "Refreshing everyone's stats!");
3095 refreshall();
3096 }
ae2685f6 3097 else if ((user = findplayer(nick)))
c7340cbd 3098 {
1af35752 3099 if (is_playing(user))
c7340cbd 3100 {
ce61cdfa 3101 #ifdef P10
3102 notice(s_GameServ, u, "Refreshing %s.", user->getRealNick());
3103 #else
c7340cbd 3104 notice(s_GameServ, u, "Refreshing %s.", user->getNick());
ce61cdfa 3105 #endif
c7340cbd 3106 refresh(user->stats);
3107 }
3108 else
3109 {
ce61cdfa 3110 #ifdef P10
3111 notice(s_GameServ, u, "%s is not playing.", user->getRealNick());
3112 #else
c7340cbd 3113 notice(s_GameServ, u, "%s is not playing.", user->getNick());
ce61cdfa 3114 #endif
c7340cbd 3115 }
3116 }
3117 else
3118 {
3119 notice(s_GameServ, u, "Nick %s not found.", nick);
3120 return;
3121 }
3122}
3123
ee38284f 3124
3125void resetall()
3126{
3127 ListNode <aClient> *it;
3128 Player *p;
3129
7996e5fd 3130 for (unsigned long x = 0; x < U_TABLE_SIZE; x++)
3131 {
3132 it = players[x].First();
ee38284f 3133
3134 while (it)
3135 {
3136 p = it->getData()->stats;
3137 reset(p);
3138 it = it->Next();
3139 }
7996e5fd 3140 }
ee38284f 3141}
3142
3143void reset(Player *p)
3144{
ddef84f1 3145 myString *myname;
3146 myname = new myString(p->name);
3147
ee38284f 3148 if (!p)
3149 return;
3150
3151 p->reset();
ddef84f1 3152 p->name = *myname;
3153
3154 delete myname;
ee38284f 3155}
3156
40251952 3157void updateTS(Player *p)
3158{
3159 if (!p)
3160 return;
0b6098d5 3161
3162 #ifdef DEBUGMODE
ddef84f1 3163 log("Old timestamp for %s: %ld", p->name.getString(), p->lastcommand);
0b6098d5 3164 #endif
40251952 3165 p->lastcommand = time(NULL);
0b6098d5 3166 #ifdef DEBUGMODE
ddef84f1 3167 log("New timestamp for %s: %ld", p->name.getString(), p->lastcommand);
0b6098d5 3168 #endif
3169
40251952 3170}
3171
3172bool timedOut(Player *p)
3173{
3174 if (!p)
3175 return false;
0b6098d5 3176 else if (p->lastcommand == 0)
3177 return false;
40251952 3178 else
0b6098d5 3179 {
3180 if ((time(NULL) - p->lastcommand) >= maxidletime)
3181 return true;
3182
3183 return false;
3184 }
40251952 3185}
3186
3187void timeOutEvent(Player *p)
3188{
ddef84f1 3189 aClient *user = findplayer(p->name.getString());
40251952 3190
ae2685f6 3191 if (!user || !p->client) // then they're not playing
40251952 3192 return;
3193
3194 char *nick = user->getNick();
3195
0b6098d5 3196 if (player_fight(user) && isYourTurn(p))
3197 {
3198 // Check to see if they were the idler or if it was the other
3199 // person
3200 if (p->lastcommand != p->battle->stats->lastcommand)
3201 {
3202 // This person's last command was given earlier,
3203 // so this person is the idler
3204 notice(s_GameServ, nick, "You timed out "\
3205 "during a fight. You lose your turn!");
3206 notice(s_GameServ, p->battle->getNick(),
ddef84f1 3207 "%s hesitated for too long. Your move.", p->name.getString());
0b6098d5 3208 clearYourTurn(p);
3209 setYourTurn(p->battle->stats);
3210
3211 // Update the TS for both players to give them another
3212 // Chance to wake up, but if the other player doesn't
3213 // Attack now, they both get logged out.
3214 updateTS(p);
3215 p->battle->stats->lastcommand = p->lastcommand;
3216 display_players(p->battle);
3217 return;
3218 }
3219 else
3220 {
3221 notice(s_GameServ, p->battle->getNick(),
3222 "You and %s timed out at the same time."\
3223 " Don't fight if you're just going to "\
ddef84f1 3224 "sit there!", p->name.getString());
0b6098d5 3225 notice(s_GameServ, user->getNick(),
3226 "You and %s timed out at the same time."\
3227 " Don't fight if you're just going to "\
ddef84f1 3228 "sit there!", p->battle->stats->name.getString());
0b6098d5 3229 logout(p->battle);
3230 logout(user);
3231 return;
3232 }
3233 }
3234 else if (!player_fight(user))
eb7608de 3235 {
c047f947 3236 if (isAlive(user->stats) && user->stats->gold > 0)
903cd861 3237 {
eb7608de 3238 // Place fun stuff here :)
3239 int randnum = 1 + rand() % 100; // 1-100
0b259dff 3240 #define GSN(s) notice(s_GameServ, nick, s)
3241 #define GSN2(s, f) notice(s_GameServ, nick, s, f)
eb7608de 3242
3243 if (randnum < 50)
3244 {
0b259dff 3245 // 35-100% of your gold goes pffft - kain
3246 int stolen = (35 + (rand() % 66)) * user->stats->gold / 100;
3247
eb7608de 3248 GSN("You stop for a moment to rest on the "\
3249 "street corner. All of a sudden, you "\
3250 "are ambushed from all sides by a hoarde "\
3251 "of knife wielding thugs.");
3252 GSN2("The thugs beat you into utter submission "\
3253 "and steal %d gold from you!", stolen);
3254 user->stats->gold -= stolen;
3255 }
0b259dff 3256 else if (randnum >= 50 && randnum < 75)
3257 {
3258 // 25-65% of your gold goes pffft - kain
3259 int stolen = (25 + (rand() % 41)) * user->stats->gold / 100;
3260 GSN("While dilly dallying around, you lose "\
3261 "your sense of time. Little did you know, "\
3262 "but thieves lifted your gold while you "\
3263 "weren't watching.");
3264 GSN2("Better luck next time... you lose %d gold", stolen);
3265 user->stats->gold -= stolen;
3266 }
3267 else if (randnum >= 75)
3268 {
3269 // 25-75% of your gold goes pffft - kain
3270 int stolen = (25 + (rand() % 51)) * user->stats->gold / 100;
3271 GSN("Good grief! A gaggle of gooey green ghostlike "\
3272 "goblins grabbed your gold!");
3273 GSN2("They stole %d gold from you!", stolen);
3274 user->stats->gold -= stolen;
3275 }
903cd861 3276 }
eb7608de 3277
3278 // Always log out the user
0b6098d5 3279 logout(user);
eb7608de 3280 }
40251952 3281}
3282
ee38284f 3283void do_reset(char *u)
3284{
3285 char *nick = strtok(NULL, " ");
3286 aClient *user;
3287
3288 if (!(user = find(u)))
3289 {
3290 notice(s_GameServ, u, "Error: aClient not found. Contact a %S admin");
5d04eb42 3291 log("Error: aClient not found: %s", u);
ee38284f 3292 return;
3293 }
3294 else if (!isAdmin(user))
3295 {
3296 notice(s_GameServ, u, "You must be a %S admin to use this command!");
3297 return;
3298 }
448a1531 3299
ee38284f 3300 if (!nick)
3301 {
3302 notice(s_GameServ, u, "SYNTAX: RESET {ALL | NICK}");
3303 return;
3304 }
3305 else if (stricmp(nick, "ALL") == 0)
3306 {
3307 notice(s_GameServ, u, "Resetting everyone's stats!");
3308 resetall();
3309 }
082f064d 3310 else if ((user = findplayer(nick)))
ee38284f 3311 {
3312 if (is_playing(user))
3313 {
ce61cdfa 3314 #ifdef P10
3315 notice(s_GameServ, u, "Resetting %s.", user->getRealNick());
3316 #else
ee38284f 3317 notice(s_GameServ, u, "Resetting %s.", user->getNick());
ce61cdfa 3318 #endif
ee38284f 3319 reset(user->stats);
3320 }
3321 else
3322 {
ddef84f1 3323 notice(s_GameServ, u, "Resetting %s", user->stats->name.getString());
082f064d 3324 reset(user->stats);
ee38284f 3325 }
3326 }
3327 else
3328 {
3329 notice(s_GameServ, u, "Nick %s not found.", nick);
3330 return;
3331 }
3332}
3333
c7340cbd 3334void do_help(char *u)
3335{
3336 char *cmd = strtok(NULL, " ");
3337
c7340cbd 3338 display_help(u, cmd);
3339}
3340
3341void display_help(char *u, char *file)
3342{
3343 ifstream infile;
3344 char *buf;
3345
3346 if (!file)
3347 {
3348 infile.open("helpfiles/help");
3349 if (infile.fail())
3350 {
fb37ecc7 3351 log("Error opening helpfiles/help");
c7340cbd 3352 notice(s_GameServ, u, "Error opening helpfiles/help");
3353 return;
3354 }
3355 buf = new char[1024];
3356 while(infile.getline(buf, 1024))
3357 {
3358 // Written this way, it will process %S in the helpfiles
3359 // Instead of notice(s_GameServ, u, "%s", buf);
3360 notice(s_GameServ, u, buf);
3361 }
3362
3363 // Minor recursion
96f71fee 3364 aClient *user = find(u);
3365 if (user && isAdmin(user))
3366 display_help(u, "admin_commands");
c7340cbd 3367 }
3368 else
3369 {
3370 char *filename;
f27a378f 3371 filename = new char[strlen(file) + 11];
3372 strcpy(filename, "helpfiles/");
3373 strcat(filename, file);
4dde2ed9 3374
f27a378f 3375 for (unsigned int x = 10; x < strlen(filename); x++)
3376 filename[x] = tolower(filename[x]);
4dde2ed9 3377
c7340cbd 3378 infile.open(filename);
3379 delete [] filename;
3380 if (infile.fail())
3381 {
3382 notice(s_GameServ, u, "No help for \ 2%s\ 2", file);
3383 return;
3384 }
3385 buf = new char[1024];
3386 while(infile.getline(buf, 1024))
3387 {
3388 // Written this way, it will process %S in the helpfiles
3389 // Instead of notice(s_GameServ, u, "%s", buf);
3390 notice(s_GameServ, u, buf);
3391 }
3392 }
3393 infile.close();
3394 delete [] buf;
3395}
96f71fee 3396
3397void do_admin(char *u)
3398{
3399 aClient *user;
3400 char *pass = strtok(NULL, " ");
3401
3402 if (!(user = find(u)))
3403 {
5d04eb42 3404 log("Error: aClient not found: %s", u);
96f71fee 3405 notice(s_GameServ, u, "Error: aClient not found. Contact %S admin.");
3406 return;
3407 }
448a1531 3408
96f71fee 3409 if (!pass)
3410 {
3411 notice(s_GameServ, u, "SYNTAX: \ 2ADMIN\ 2 \ 2\1fpassword\1f\ 2");
3412 return;
3413 }
3414
1af35752 3415 if (isAdmin(user))
3416 {
3417 notice(s_GameServ, u, "You already have administrator privledges.");
3418 return;
3419 }
3420 else if (strcmp(pass, adminpass) == 0)
96f71fee 3421 {
3422 notice(s_GameServ, u, "Password accepted. You now have administrator privledges.");
3423 setAdmin(user);
ce61cdfa 3424 #ifdef P10
3425 log("%s became an administrator.", user->getRealNick());
3426 #else
5d04eb42 3427 log("%s became an administrator.", user->getNick());
ce61cdfa 3428 #endif
96f71fee 3429 }
3430 else
3431 {
3432 notice(s_GameServ, u, "Invalid password. Remember: case sensitive");
3433 return;
3434 }
3435}
1af35752 3436
ea93c39a 3437bool load_levels()
3438{
3439 char *filename;
3440 filename = new char[256];
3441
3442 for (int x = 1; x <= LEVELS; x++)
3443 {
3444 sprintf(filename, "data/levels/level%d.dat", x);
3445 if (levels[x - 1].loadLevel(filename) == false)
3446 return false;
3447 }
3448
3449 delete []filename;
3450 return true;
3451}
4dde2ed9 3452bool load_monsters()
3453{
bf3a2ff9 3454 char *filename;
4dde2ed9 3455 ifstream infile;
4dde2ed9 3456 char *buf;
bf3a2ff9 3457 buf = new char[2048];
4dde2ed9 3458
bf3a2ff9 3459 for (int level = 1; level <= LEVELS; level++)
3460 {
3461 filename = new char[256];
b5cea1ad 3462 sprintf(filename, "data/monsters/level%d.dat", level);
bf3a2ff9 3463 infile.open(filename);
3464
3465 if (!infile)
4dde2ed9 3466 {
bf3a2ff9 3467 log("Error opening %s", filename);
4dde2ed9 3468 return false;
3469 }
4dde2ed9 3470
5d04eb42 3471 #ifdef DEBUGMODE
bf3a2ff9 3472 log("Loading monsters from %s", filename);
5d04eb42 3473 #endif
3474
bf3a2ff9 3475 while (infile.getline(buf, 2048))
4dde2ed9 3476 {
bf3a2ff9 3477 if (buf[0] == '^')
3478 break;
4dde2ed9 3479 if (buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
3480 continue;
bf3a2ff9 3481 Monster *temp;
3482 temp = new Monster;
3483
ddef84f1 3484 temp->name = strtok(buf, "~");
3485 temp->weapon = strtok(NULL, "~");
3486 temp->death = strtok(NULL, "~");
bf3a2ff9 3487
42106907 3488 levels[level - 1].monsters.insertAtBack_RLN(temp);
bf3a2ff9 3489 delete temp;
4dde2ed9 3490 }
bf3a2ff9 3491 delete [] filename;
3492 infile.close();
4dde2ed9 3493 }
3494 delete [] buf;
3495return true;
3496}