]> jfr.im git - irc/gameservirc.git/blame - gameserv/gameserv.cpp
Added the do_store command, and some store functionality. Also added an init_masters...
[irc/gameservirc.git] / gameserv / gameserv.cpp
CommitLineData
85ce9d3e 1#include "sockhelp.h"
2#include "aClient.h"
3#include "list.h"
4#include "extern.h"
5#include <cctype>
6#include <fstream.h>
e3c5fe46 7#include <crypt.h>
85ce9d3e 8
9List<aClient> players;
10Monster monsters[5][12];
ad7dfaa0 11Monster masters[12];
85ce9d3e 12
a8fb9757 13// Database functions
85ce9d3e 14int save_gs_dbase();
15int load_gs_dbase();
16
17// String functions
18#undef strtok
19char *strtok(char *str, const char *delim);
20int stricmp(const char *s1, const char *s2);
21int strnicmp(const char *s1, const char *s2, size_t len);
22// String Functions
23
e3c5fe46 24
25/********** Password functions **********/
26
27bool passcmp(char *encrypted, char *plaintext); // Compares an encrypted pass with a plain text one
28
29bool check_password(char *name, char *plaintext); // Finds a password for the given name, and checks it with passcmp against the plaintext password given.
30
31/********** Password functions **********/
32
33
34/********** GameServ Booleans **********/
35
36bool is_playing(char *u); // True if the given nickname in the clients list is playing.
37bool has_started(char *u); // True if the given nickname in the clients list has started playing.
38bool is_fighting(char *u); // True if the given nick in the clients list is fighting anything.
39bool isnt_fighting(char *u); // True if the given nick isn't fighting. Same as !is_fighting(u).
40bool player_fight(char *u); // True if the player is fighting another player.
41bool master_fight(char *u); // True if the player is fighting their master.
42
43/********** GameServ Booleans **********/
85ce9d3e 44
45
46void display_monster(char *u);
47void display_players(char *u);
48long int chartoint(char ch);
49int isstringnum(char *num);
50long int pow (int x, int y);
51long int stringtoint(char *number);
52
53char *spaces(int len, char *seperator);
54void init_masters();
55void refresh(aClient *ni);
56void refreshall();
57void reset(aClient *ni);
58void init_monsters();
59
60void do_list(char *u);
61void do_register(char *u);
62void do_identify(char *u);
63void do_play(char *u);
64void do_quitg(char *u);
65void do_reset(char *u);
66void do_fight(char *u);
67void do_store(char *u);
68void do_heal(char *u);
69void do_bank(char *u);
70void do_attack(char *u);
71void do_run(char *u);
72void do_visit(char *u);
73void do_stats(char *u);
74void see_mystic(char *u);
75
76void showstats(const char *u, const char *nick);
77
78#define WNA 16
79char *weapons[WNA] = { "Fists", "Stick", "Dagger", "Quarterstaff", "Short Sword",
80 "Long Sword", "Silver Spear", "Battle Axe", "The Ragnarok",
81 "Chain Saw", "Poison Sword", "Flame Sword", "Earth Hammer",
82 "Light Saber", "Masamune", "Mystical Sword"};
83
84char *armors[WNA] = { "Nothing", "Clothes", "Leather Vest", "Chain Mail", "Plate Armor",
85 "Full Body Armor", "Magic Mail", "Graphite Suit", "Steel Suit",
86 "Force Field", "Armor of Light", "Mythril Vest", "DemiGod Armor",
87 "Hades' Cloak", "Dragon Scales", "Mystical Armor"};
88
89int prices[WNA - 1] = {200, 1000, 3000, 10000, 30000, 100000, 150000, 200000, 400000,
90 1000000, 4000000, 10000000, 40000000, 100000000, 400000000};
91int webonus[WNA] = {0, 10, 15, 25, 35, 45, 65, 85, 125, 185, 255, 355, 505, 805, 1205, 1805};
92int arbonus[WNA] = {0, 1, 3, 10, 15, 25, 35, 50, 75, 100, 150, 225, 300, 400, 600, 1000};
93
94int hpbonus[11] = {10, 15, 20, 30, 50, 75, 125, 185, 250, 350, 550};
95int strbonus[11] = {5, 7, 10, 12, 20, 35, 50, 75, 110, 150, 200};
96int defbonus[11] = {2, 3, 5, 10, 15, 22, 35, 60, 80, 120, 150};
97
98
99void gameserv(char *source, char *buf)
100{
101 char *cmd, input[1024];
102 cmd = strtok(buf, " ");
103
104 source++; // Get rid of that : at the beginning of a :Nick privmsg Gameserv :text
105 cmd++; // Get rid of that : at the beginning of the :text (command)
106
107 cout << "Source: " << source << "\ncmd: " << cmd << endl;
108 if (strnicmp(cmd, ":\1PING", 6) == 0)
109 {
110 char *timestamp;
111 timestamp = strtok(NULL, "\1");
112 notice(s_GameServ, source, "\1PING %s\1", timestamp);
113 } else if (stricmp(cmd, ":\1VERSION\1") == 0) {
114 notice(s_GameServ, source, "\1VERSION GameServ v1.0b\1");
115 } else if (stricmp(cmd, "SEARCH") == 0) {
116 cmd = strtok(NULL, " ");
117
118 if (!cmd)
119 notice(s_GameServ, source, "SYNTAX: /msg %S SEARCH FOREST");
120 else
121 do_forest(source);
122 } else if (stricmp(cmd, "FIGHT") == 0) {
123 do_fight(source);
124 } else if (stricmp(cmd, "ATTACK") == 0) {
125 do_attack(source);
126 } else if (stricmp(cmd, "HEAL") == 0) {
127 do_heal(source);
ad7dfaa0 128 } else if (stricmp(cmd, "STORE") == 0) {
129 do_store(source);
85ce9d3e 130 } else if (stricmp(cmd, "PRINT") == 0) {
131 cout << "Printing Clients List: " << endl;
132 clients.print();
0a1518fa 133 cout << "\nPrinting Player List: " << endl;
85ce9d3e 134 players.print();
135 } else if (stricmp(cmd, "LIST") == 0) {
136 do_list(source);
137 } else if (stricmp(cmd, "REGISTER") == 0) {
138 do_register(source);
139 } else if (stricmp(cmd, "IDENTIFY") == 0) {
140 do_identify(source);
141 } else if (stricmp(cmd, "HELP") == 0) {
142 } else if (stricmp(cmd, "STATS") == 0) {
143 do_stats(source);
144 } else if (stricmp(cmd, "SHUTDOWN") == 0) {
ad7dfaa0 145 save_gs_dbase();
85ce9d3e 146 raw("SQUIT %s :leaving", servername);
147 } else if (stricmp(cmd, "SAVE") == 0) {
148 save_gs_dbase();
149 } else if (stricmp(cmd, "LOAD") == 0) {
150 load_gs_dbase();
151 } else if (stricmp(cmd, "RAW") == 0) {
152 char *rest = strtok(NULL, "");
153 raw(rest);
154 }
155
156 source--; // Bring the : back so we don't leak memory
157 cmd--; // Same thing :)
158}
159
160int stricmp(const char *s1, const char *s2)
161{
162 register int c;
163
164 while ((c = tolower(*s1)) == tolower(*s2)) {
165 if (c == 0)
166 return 0;
167 s1++;
168 s2++;
169 }
170 if (c < tolower(*s2))
171 return -1;
172 return 1;
173}
174
175void showstats(const char *u, const char *nick)
176{
177 aClient *ni, *sender = find(u);
178 char *buf;
179 buf = new char[50];
180 char *space;
181
182
183 cout << "\n\nu: " << u << "\nnick: " << nick << endl;
184 if (!(ni = findbynick(nick)))
185 {
186 notice(s_GameServ, u, "%s not found", nick);
187 }
188 else if (ni->stats)
189 {
190
191 notice(s_GameServ, sender->getNick(), "Stats for %s:", ni->stats->name);
192
193 sprintf(buf, "Experience: %ld", ni->stats->exp);
194 space = spaces(strlen(buf), " ");
195 notice(s_GameServ, sender->getNick(), "%s%sLevel: %d", buf, space,
196 ni->stats->level);
1cf88153 197 delete [] space;
85ce9d3e 198
199 sprintf(buf, "Gold: %ld", ni->stats->gold);
200 space = spaces(strlen(buf), " ");
201 notice(s_GameServ, sender->getNick(), "%s%sGold in Bank: %ld", buf, space, ni->stats->bank);
1cf88153 202 delete [] space;
85ce9d3e 203
204 notice(s_GameServ, sender->getNick(), "Health Points: %d of %d", ni->stats->hp,
205 ni->stats->maxhp);
206
207 sprintf(buf, "Strength: %d", ni->stats->strength + webonus[ni->stats->weapon]);
208 space = spaces(strlen(buf), " ");
209 notice(s_GameServ, sender->getNick(), "%s%sDefense: %d",
210 buf, space, ni->stats->defense + arbonus[ni->stats->armor]);
1cf88153 211 delete [] space;
85ce9d3e 212
213 sprintf(buf, "Armor: %s", armors[ni->stats->armor]);
214 space = spaces(strlen(buf), " ");
215 notice(s_GameServ, sender->getNick(), "%s%sWeapon: %s", buf, space,
216 weapons[ni->stats->weapon]);
1cf88153 217 delete [] space;
85ce9d3e 218
219 sprintf(buf, "Forest Fights: %d", ni->stats->forest_fights);
220 space = spaces(strlen(buf), " ");
221 notice(s_GameServ, sender->getNick(), "%s%sPlayer Fights: %d", buf, space, ni->stats->player_fights);
1cf88153 222 delete [] space;
85ce9d3e 223 }
1cf88153 224 delete [] buf;
85ce9d3e 225
226}
227
228char *spaces(int len, char *seperator)
229{
230 char *final;
231 final = new char[40];
232 int y;
233 strcpy(final, seperator);
234 for (y = 0; y < 40 - len; y++)
235 strcat(final, seperator);
236 return final;
237}
238
239void raw(const char *fmt, ...)
240{
241 va_list args;
242 char *input;
243 const char *t = fmt;
244 input = new char[1024];
245 va_start(args, fmt);
246 memset(input, 0, sizeof(input)); // Initialize to NULL
247 for (; *t; t++)
248 {
249 if (*t == '%')
250 {
251 switch(*++t) {
252 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
253 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
254 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
255 case 'l':
256 if (*++t == 'd')
257 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
258 }
259 }
260 else
261 {
262 sprintf(input, "%s%c", input, *t);
263 }
264
265 }
266 sprintf(input, "%s%s", input, "\r\n");
267 cout << "input: " << input << flush;
268 sock_puts(sock, input);
1cf88153 269 delete [] input;
85ce9d3e 270 va_end(args);
271}
272/* Send a NOTICE from the given source to the given nick. */
273
274void notice(const char *source, const char *dest, const char *fmt, ...)
275{
276 va_list args;
277 char *input;
278 const char *t = fmt;
279 input = new char[1024];
280 va_start(args, fmt);
281 if (dest[0] == ':')
282 {
283 dest++;
284 sprintf(input, ":%s NOTICE %s :", source, dest);
285 dest--;
286 }
287 else
288 sprintf(input, ":%s NOTICE %s :", source, dest);
289
290 for (; *t; t++)
291 {
292 if (*t == '%')
293 {
294 switch(*++t) {
295 case 'd': sprintf(input, "%s%d", input, va_arg(args, int)); break;
296 case 's': sprintf(input, "%s%s", input, va_arg(args, char *)); break;
297 case 'S': sprintf(input, "%s%s", input, s_GameServ); break;
298 case 'l':
299 if (*++t == 'd')
300 sprintf(input, "%s%ld", input, va_arg(args, long int)); break;
301 }
302 }
303 else
304 {
305 sprintf(input, "%s%c", input, *t);
306 }
307
308 }
309 sprintf(input, "%s%s", input, "\r\n");
310 cout << "input: " << input << flush;
311 sock_puts(sock, input);
1cf88153 312 delete [] input;
85ce9d3e 313va_end(args);
314}
315
316
317int strnicmp(const char *s1, const char *s2, size_t len)
318{
319 register int c;
320
321 if (!len)
322 return 0;
323 while ((c = tolower(*s1)) == tolower(*s2) && len > 0) {
324 if (c == 0 || --len == 0)
325 return 0;
326 s1++;
327 s2++;
328 }
329 if (c < tolower(*s2))
330 return -1;
331 return 1;
332}
333
334char *strtok(char *str, const char *delim)
335{
336 static char *current = NULL;
337 char *ret;
338
339 if (str)
340 current = str;
341 if (!current)
342 return NULL;
343 current += strspn(current, delim);
344 ret = *current ? current : NULL;
345 current += strcspn(current, delim);
346 if (!*current)
347 current = NULL;
348 else
349 *current++ = 0;
350 return ret;
351}
352
353void do_list(char *u)
354{
355 ListNode<aClient> *temp;
356 temp = players.First();
357 if (!players.isEmpty())
358 {
359 notice(s_GameServ, u, "People Playing:");
360 while(temp)
361 {
362 notice(s_GameServ, u, "IRC: %s Game: %s", temp->getData()->getNick(), temp->getData()->stats->name);
363 temp = temp->Next();
364 }
365 notice(s_GameServ, u, "End of List");
366 }
367 else
368 notice(s_GameServ, u, "No one is playing");
369}
370void do_register(char *u)
371{
372 char *password;
373 aClient *user;
374 password = strtok(NULL, " ");
375
e3c5fe46 376 static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
377 static char salt[3];
378
379 salt[0] = saltChars[rand() % strlen(saltChars)];
380 salt[1] = saltChars[rand() % strlen(saltChars)];
381 salt[3] = '\0';
382
85ce9d3e 383 if (!password)
384 {
385 notice(s_GameServ, u, "SYNTAX: /msg %S REGISTER PASSWORD");
386 }
387 else if (user = find(u))
388 {
389 if (!user->stats)
390 {
391 user->stats = new Player(user);
392 user->stats->started = 1;
393 user->stats->user = user; // Set the backwards pointer
e3c5fe46 394 strcpy(user->stats->password, crypt(password, salt));
85ce9d3e 395 players.insertAtBack(user);
396 }
397 else
398 {
399 notice(s_GameServ, u, "Already registered. Contact a %S admin for help.");
400 }
401 }
402}
403
404void do_identify(char *u)
405{
0a1518fa 406 char *password, *name;
407 aClient *user, *p;
408 name = strtok(NULL, " ");
85ce9d3e 409 password = strtok(NULL, " ");
cdc9a6db 410
0a1518fa 411 if (!password || !name)
85ce9d3e 412 {
0a1518fa 413 notice(s_GameServ, u, "SYNTAX: /msg %S IDENTIFY NAME PASSWORD");
85ce9d3e 414 }
0a1518fa 415 else if (!(p = findplayer(name)) || !p->stats)
416 notice(s_GameServ, u, "Player %s not found", name);
417 else if (!check_password(name, password))
85ce9d3e 418 {
0a1518fa 419 notice(s_GameServ, u, "Password incorrect");
85ce9d3e 420 }
0a1518fa 421 else if (user = find(u))
85ce9d3e 422 {
423 if (!user->stats)
424 {
1cf88153 425 ListNode<aClient> *temp;
426 temp = players.Find(p);
427 if (!temp)
428 {
429 notice(s_GameServ, u, "Fatal error. Contact %S Admin. Buf: %s",
430 strtok(NULL, ""));
431 return;
432 }
cdc9a6db 433 user->stats = new Player(p->stats->name);
434 cout << "Setting data for identified" << endl;
1cf88153 435 user->stats->setData(p->stats);
cdc9a6db 436 cout << "Player Identified" << endl << flush;
437
438 temp->setPtr(user);
439
440 notice(s_GameServ, u, "Password Accepted. Identified.");
1cf88153 441
85ce9d3e 442 }
443 else
444 {
445 notice(s_GameServ, u, "Already identified. Contact a %S admin for help.");
446 }
447 }
448}
449
450void do_stats(char *u)
451{
452 char *nick;
453 aClient *source;
454
455 nick = strtok(NULL, " ");
456 source = find(u);
457
458 if (!nick)
459 showstats(u, source->getNick());
460 else
461 showstats(u, nick);
462}
ad7dfaa0 463void init_masters()
464{
465 masters[0].name = "Old Bones";
466 masters[0].weapon = "Dull Sword Cane";
467 masters[0].strength = 30;
468 masters[0].gold = 0;
469 masters[0].exp = 0;
470 masters[0].maxhp = 30;
471 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!";
472
473 masters[1].name = "Master Chang";
474 masters[1].weapon = "Nanchaku";
475 masters[1].strength = 57;
476 masters[1].gold = 0;
477 masters[1].exp = 0;
478 masters[1].maxhp = 40;
479 masters[1].death = "You try to make out what Master Chang is saying, but the only thing you catch is something about a grasshopper.";
480
481 masters[2].name = "Chuck Norris";
482 masters[2].weapon = "Ranger Kick";
483 masters[2].strength = 85;
484 masters[2].gold = 0;
485 masters[2].exp = 0;
486 masters[2].maxhp = 70;
487 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!";
488
489
490 masters[3].name = "Mr. Miagi";
491 masters[3].weapon = "Petrified Bonsai";
492 masters[3].strength = 100;
493 masters[3].gold = 0;
494 masters[3].exp = 0;
495 masters[3].maxhp = 120;
496 masters[3].death = "Skill comes from repeating the correct but seemingly mundane actions. Wax ON, wax OFF!";
497
498 masters[4].name = "Jackie Chan";
499 masters[4].weapon = "Drunken Boxing";
500 masters[4].strength = 125;
501 masters[4].maxhp = 200;
502 masters[4].gold = 0;
503 masters[4].exp = 0;
504 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!";
505
506 masters[5].name = "Jet Li";
507 masters[5].weapon = "Motorcycle";
508 masters[5].strength = 150;
509 masters[5].maxhp = 400;
510 masters[5].gold = 0;
511 masters[5].exp = 0;
512 masters[5].death = "Failure is a fuel for excuses. It's the doing the do, that makes the making.";
513
514
515 masters[6].name = "Muhammad Ali";
516 masters[6].weapon = "Quick Jab";
517 masters[6].strength = 175;
518 masters[6].maxhp = 600;
519 masters[6].gold = 0;
520 masters[6].exp = 0;
521 masters[6].death = "It's just a job. Grass grows, birds fly, waves pound the sand. I beat people up.";
522
523 masters[7].name = "Li Mu Bai";
524 masters[7].weapon = "Green Destiny";
525 masters[7].strength = 200;
526 masters[7].maxhp = 800;
527 masters[7].gold = 0;
528 masters[7].exp = 0;
529 masters[7].death = "No growth without resistance. No action without reaction. No desire without restraint.";
530
531
532 masters[8].name = "Jimmy Wang Yu";
533 masters[8].weapon = "Flying Guillotine";
534 masters[8].strength = 275;
535 masters[8].maxhp = 1200;
536 masters[8].gold = 0;
537 masters[8].exp = 0;
538 masters[8].death = "You have beaten the one armed boxer. Proceed with caution!";
539
540 masters[9].name = "Wong Fei Hung";
541 masters[9].weapon = "Drunken Boxing";
542 masters[9].strength = 350;
543 masters[9].maxhp = 1800;
544 masters[9].gold = 0;
545 masters[9].exp = 0;
546 masters[9].death = "";
547
548 masters[10].name = "Bruce Lee";
549 masters[10].strength = 575;
550 masters[10].maxhp = 2500;
551 masters[10].gold = 0;
552 masters[10].exp = 0;
553 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.";
554}
85ce9d3e 555
556void init_monsters()
557{
558 // Hard coded for now - Kain
559 monsters[0][0].name = "Slime";
560 monsters[0][0].weapon = "Acid Goo";
561 monsters[0][0].strength = 6;
562 monsters[0][0].gold = 50;
563 monsters[0][0].exp = 3;
564 monsters[0][0].maxhp = 9;
565 monsters[0][0].death = "The slime oozes into nothing... you clean the acid goo off of your weapon";
566
567 monsters[0][1].name = "Ghost";
568 monsters[0][1].weapon = "Cold Breath";
569 monsters[0][1].strength = 8;
570 monsters[0][1].gold = 100;
571 monsters[0][1].exp = 10;
572 monsters[0][1].maxhp = 10;
573 monsters[0][1].death = "You feel a chill as the spirit leaves the realm.";
574
575 monsters[0][2].name = "Ugly Rodent";
576 monsters[0][2].weapon = "Sharp Teeth";
577 monsters[0][2].strength = 9;
578 monsters[0][2].gold = 75;
579 monsters[0][2].exp = 8;
580 monsters[0][2].maxhp = 13;
581 monsters[0][2].death = "You stomp on the Ugly Rodent's remains for a finishing blow.";
582
583 monsters[0][3].name = "Whart Hog";
584 monsters[0][3].weapon = "Tusks";
585 monsters[0][3].strength = 10;
586 monsters[0][3].gold = 80;
587 monsters[0][3].exp = 6;
588 monsters[0][3].maxhp = 10;
589 monsters[0][3].death = "You cook and eat the hog for good measure!";
590
591 monsters[0][4].name = "Pesky Kid";
592 monsters[0][4].weapon = "Slingshot";
593 monsters[0][4].strength = 8;
594 monsters[0][4].gold = 30;
595 monsters[0][4].exp = 4;
596 monsters[0][4].maxhp = 6;
597 monsters[0][4].death = "You take his slingshot and snap the band, sending the kid crying home to mom!";
598
599 monsters[0][5].name = "Playground Bully";
600 monsters[0][5].weapon = "Painful Noogie";
601 monsters[0][5].strength = 11;
602 monsters[0][5].gold = 44;
603 monsters[0][5].exp = 6;
604 monsters[0][5].maxhp = 10;
605 monsters[0][5].death = "You give him an indian burn, and punt him across the schoolyard!";
606
607 monsters[0][6].name = "Small Imp";
608 monsters[0][6].weapon = "Dagger";
609 monsters[0][6].strength = 6;
610 monsters[0][6].gold = 64;
611 monsters[0][6].exp = 10;
612 monsters[0][6].maxhp = 10;
613 monsters[0][6].death = "You can't help but laugh as he stumbles and falls onto his own dagger!";
614
615 monsters[0][7].name = "Little Monkey";
616 monsters[0][7].weapon = "Monkey Wrench";
617 monsters[0][7].strength = 6;
618 monsters[0][7].gold = 53;
619 monsters[0][7].exp = 9;
620 monsters[0][7].maxhp = 9;
621 monsters[0][7].death = "You want to cook it, but you just can't think of eating something that looks so human!";
622
623 monsters[0][8].name = "Grub Worm";
624 monsters[0][8].weapon = "Minor Nudge";
625 monsters[0][8].strength = 2;
626 monsters[0][8].gold = 10;
627 monsters[0][8].exp = 3;
628 monsters[0][8].maxhp = 3;
629 monsters[0][8].death = "You decide to save the poor little fella for your next fishing trip.";
630
631 monsters[0][9].name = "Drakee";
632 monsters[0][9].weapon = "Tail Slap";
633 monsters[0][9].strength = 5;
634 monsters[0][9].gold = 22;
635 monsters[0][9].exp = 7;
636 monsters[0][9].maxhp = 5;
637 monsters[0][9].death = "You pull the little Drakee by its tale and slam it down on a dry stump!";
638
639 monsters[0][10].name = "Fat Slob";
640 monsters[0][10].weapon = "Smelly Breath";
641 monsters[0][10].strength = 6;
642 monsters[0][10].gold = 40;
643 monsters[0][10].exp = 10;
644 monsters[0][10].maxhp = 7;
645 monsters[0][10].death = "You kick his stomach for fun, and are thrown back by the spring of it all!";
646
647 monsters[0][11].name = "Lost Warrior";
648 monsters[0][11].weapon = "Long Sword";
649 monsters[0][11].strength = 10;
650 monsters[0][11].gold = 250;
651 monsters[0][11].exp = 19;
652 monsters[0][11].maxhp = 15;
653 monsters[0][11].death = "You give him a proper burial in respect for the dead warrior.";
654
655 monsters[1][0].name = "Lost Warrior's Cousin Larry";
656 monsters[1][0].weapon = "Wood Axe";
657 monsters[1][0].strength = 19;
658 monsters[1][0].gold = 134;
659 monsters[1][0].exp = 24;
660 monsters[1][0].maxhp = 30;
661 monsters[1][0].death = "He was pretty pissed you killed his cousin, but he seems to have suffered the same fate!";
662
663 monsters[1][1].name = "Sandman";
664 monsters[1][1].weapon = "Sleeping Dust";
665 monsters[1][1].strength = 25;
666 monsters[1][1].gold = 80;
667 monsters[1][1].exp = 6;
668 monsters[1][1].maxhp = 27;
669 monsters[1][1].death = "You put the sandman to his final sleep.";
670
671 monsters[1][2].name = "Dirty Transvestite";
672 monsters[1][2].weapon = "Stiletto Heel";
673 monsters[1][2].strength = 21;
674 monsters[1][2].gold = 160;
675 monsters[1][2].exp = 12;
676 monsters[1][2].maxhp = 25;
677 monsters[1][2].death = "You shudder at the thought of ever mistaking this for a woman!";
678
679 monsters[1][3].name = "Goblin Gardener";
680 monsters[1][3].weapon = "Garden Spade";
681 monsters[1][3].strength = 18;
682 monsters[1][3].gold = 130;
683 monsters[1][3].exp = 8;
684 monsters[1][3].maxhp = 20;
685 monsters[1][3].death = "You trample on his garden after slaying him... that felt good!";
686
687 monsters[1][4].name = "Evil Elf";
688 monsters[1][4].weapon = "Elvish Bow";
689 monsters[1][4].strength = 23;
690 monsters[1][4].gold = 136;
691 monsters[1][4].exp = 13;
692 monsters[1][4].maxhp = 24;
693 monsters[1][4].death = "Elves are usually nice you thought... hmm.";
694
695 monsters[1][5].name = "Viking Warrior";
696 monsters[1][5].weapon = "Broad Sword";
697 monsters[1][5].strength = 21;
698 monsters[1][5].gold = 330;
699 monsters[1][5].exp = 20;
700 monsters[1][5].maxhp = 18;
701 monsters[1][5].death = "You heard vikings were big, but not THAT big you thought.";
702
703 monsters[1][6].name = "Wicked Witch";
704 monsters[1][6].weapon = "Cackling Laugh";
705 monsters[1][6].strength = 20;
706 monsters[1][6].gold = 130;
707 monsters[1][6].exp = 20;
708 monsters[1][6].maxhp = 26;
709 monsters[1][6].death = "Just for kicks, you splash some water on her and watch her melt.";
710
711 monsters[1][7].name = "Vampire Bat";
712 monsters[1][7].weapon = "Blood Sucking Fangs";
713 monsters[1][7].strength = 18;
714 monsters[1][7].gold = 125;
715 monsters[1][7].exp = 21;
716 monsters[1][7].maxhp = 29;
717 monsters[1][7].death = "You fry up the bat and eat it... needs garlic.";
718
719 monsters[1][8].name = "Thorn Bush";
720 monsters[1][8].weapon = "101 Thorns";
721 monsters[1][8].strength = 16;
722 monsters[1][8].gold = 94;
723 monsters[1][8].exp = 15;
724 monsters[1][8].maxhp = 25;
725 monsters[1][8].death = "You set the bush ablaze and roast some marshmallows.";
726
727 monsters[1][9].name = "Barbarian";
728 monsters[1][9].weapon = "Heavy Sword";
729 monsters[1][9].strength = 29;
730 monsters[1][9].gold = 250;
731 monsters[1][9].exp = 25;
732 monsters[1][9].maxhp = 30;
733 monsters[1][9].death = "You listen to him moan as he falls over dead.";
734
735 monsters[1][10].name = "Crypt Rat";
736 monsters[1][10].weapon = "Stinging Bite";
737 monsters[1][10].strength = 25;
738 monsters[1][10].gold = 119;
739 monsters[1][10].exp = 20;
740 monsters[1][10].maxhp = 26;
741 monsters[1][10].death = "You squash the little rodent for fear that it might not be dead.";
742
743 monsters[1][11].name = "Small Orc";
744 monsters[1][11].weapon = "blade";
745 monsters[1][11].strength = 28;
746 monsters[1][11].gold = 300;
747 monsters[1][11].exp = 30;
748 monsters[1][11].maxhp = 36;
749 monsters[1][11].death = "It's an ugly one, and it would've grown up to be a terror...";
750
751 monsters[2][0].name = "Teferi";
752 monsters[2][0].weapon = "Puzzle Box";
753 monsters[2][0].strength = 29;
754 monsters[2][0].gold = 380;
755 monsters[2][0].exp = 18;
756 monsters[2][0].maxhp = 29;
757 monsters[2][0].death = "It was a puzzling experience.";
758
759 monsters[2][1].name = "Spineless Thug";
760 monsters[2][1].weapon = "Spiked Bat";
761 monsters[2][1].strength = 37;
762 monsters[2][1].gold = 384;
763 monsters[2][1].exp = 27;
764 monsters[2][1].maxhp = 32;
765 monsters[2][1].death = "See you at the crossroads!";
766
767 monsters[2][2].name = "Pyromaniac";
768 monsters[2][2].weapon = "Pyrotechnics";
769 monsters[2][2].strength = 29;
770 monsters[2][2].gold = 563;
771 monsters[2][2].exp = 22;
772 monsters[2][2].maxhp = 45;
773 monsters[2][2].death = "He chants FIRE FIRE as he falls to the ground... a burning heap of flesh.";
774
775 monsters[2][3].name = "Evil Enchantress";
776 monsters[2][3].weapon = "Deadly Spell";
777 monsters[2][3].strength = 50;
778 monsters[2][3].gold = 830;
779 monsters[2][3].exp = 35;
780 monsters[2][3].maxhp = 35;
781 monsters[2][3].death = "She looked just about as good as she fought.";
782
783 monsters[2][4].name = "Killer Leprechaun";
784 monsters[2][4].weapon = "Gold Rush";
785 monsters[2][4].strength = 35;
786 monsters[2][4].gold = 1300;
787 monsters[2][4].exp = 30;
788 monsters[2][4].maxhp = 37;
789 monsters[2][4].death = "You steal his pot of gold... that's a lot of money!";
790
791 monsters[2][5].name = "Avalanche Rider";
792 monsters[2][5].weapon = "Huge Snowball";
793 monsters[2][5].strength = 32;
794 monsters[2][5].gold = 700;
795 monsters[2][5].exp = 32;
796 monsters[2][5].maxhp = 38;
797 monsters[2][5].death = "You take his snowboard and snap it in two!";
798
799 monsters[2][6].name = "Blundering Idiot";
800 monsters[2][6].weapon = "Stupidity";
801 monsters[2][6].strength = 14;
802 monsters[2][6].gold = 700;
803 monsters[2][6].exp = 20;
804 monsters[2][6].maxhp = 29;
805 monsters[2][6].death = "Now there's one person you don't feel sorry for killing!";
806
807 monsters[2][7].name = "Militant Anarchist";
808 monsters[2][7].weapon = "Molotov Cocktail";
809 monsters[2][7].strength = 33;
810 monsters[2][7].gold = 245;
811 monsters[2][7].exp = 45;
812 monsters[2][7].maxhp = 32;
813 monsters[2][7].death = "Order has been restored for now...";
814
815 monsters[2][8].name = "Scathe Zombies";
816 monsters[2][8].weapon = "Death Grip";
817 monsters[2][8].strength = 38;
818 monsters[2][8].gold = 763;
819 monsters[2][8].exp = 15;
820 monsters[2][8].maxhp = 45;
821 monsters[2][8].death = "That was perhaps the scariest experience of your life.";
822
823 monsters[2][9].name = "Spitting Llama";
824 monsters[2][9].weapon = "Spit Spray";
825 monsters[2][9].strength = 48;
826 monsters[2][9].gold = 638;
827 monsters[2][9].exp = 28;
828 monsters[2][9].maxhp = 34;
829 monsters[2][9].death = "You wipe the spit off your face and fling it back at the Llama.";
830
831 monsters[2][10].name = "Juggalo";
832 monsters[2][10].weapon = "Clown Axe";
833 monsters[2][10].strength = 60;
834 monsters[2][10].gold = 650;
835 monsters[2][10].exp = 30;
836 monsters[2][10].maxhp = 29;
837 monsters[2][10].death = "What is a Juggalo? I don't know!";
838
839 monsters[2][11].name = "The Boogie Man";
840 monsters[2][11].weapon = "Striking Fear";
841 monsters[2][11].strength = 46;
842 monsters[2][11].gold = 600;
843 monsters[2][11].exp = 35;
844 monsters[2][11].maxhp = 27;
845 monsters[2][11].death = "He's scared you for the very last time!";
846
847 monsters[3][0].name = "Living Fire";
848 monsters[3][0].weapon = "Scorching Wind";
849 monsters[3][0].strength = 55;
850 monsters[3][0].gold = 1100;
851 monsters[3][0].exp = 36;
852 monsters[3][0].maxhp = 55;
853 monsters[3][0].death = "You extinguish the Living Flame once and for all!";
854
855 monsters[3][1].name = "Raging Orc";
856 monsters[3][1].weapon = "Orcish Artillary";
857 monsters[3][1].strength = 89;
858 monsters[3][1].gold = 900;
859 monsters[3][1].exp = 25;
860 monsters[3][1].maxhp = 50;
861 monsters[3][1].death = "This orc was a bit tougher than you remembered!";
862
863 monsters[3][2].name = "Huge Tarantula";
864 monsters[3][2].weapon = "Tangling Web";
865 monsters[3][2].strength = 59;
866 monsters[3][2].gold = 1000;
867 monsters[3][2].exp = 35;
868 monsters[3][2].maxhp = 60;
869 monsters[3][2].death = "You're glad you overcame your arachniphobia so soon!";
870
871 monsters[3][3].name = "Rabid Wolf";
872 monsters[3][3].weapon = "Cujo Bite";
873 monsters[3][3].strength = 40;
874 monsters[3][3].gold = 1200;
875 monsters[3][3].exp = 47;
876 monsters[3][3].maxhp = 76;
877 monsters[3][3].death = "The mutt falls over dead as white foam drips from its deadly canines...";
878
879 monsters[3][4].name = "Goblin Fighter";
880 monsters[3][4].weapon = "Morning Star";
881 monsters[3][4].strength = 38;
882 monsters[3][4].gold = 700;
883 monsters[3][4].exp = 30;
884 monsters[3][4].maxhp = 75;
885 monsters[3][4].death = "He almost caught you with his chain mace, but you sliced off his head.";
886
887 monsters[3][5].name = "Grizzly Bear";
888 monsters[3][5].weapon = "Razor Claws";
889 monsters[3][5].strength = 68;
890 monsters[3][5].gold = 1747;
891 monsters[3][5].exp = 81;
892 monsters[3][5].maxhp = 51;
893 monsters[3][5].death = "It almost got you this time... better be careful";
894
895 monsters[3][6].name = "Skeleton Man";
896 monsters[3][6].weapon = "Leg Bone";
897 monsters[3][6].strength = 70;
898 monsters[3][6].gold = 597;
899 monsters[3][6].exp = 57;
900 monsters[3][6].maxhp = 60;
901 monsters[3][6].death = "As a finisher, you wind up with the broad side of your weapon and hit his skull off for a home run!";
902
903 monsters[3][7].name = "Young Werewolf";
904 monsters[3][7].weapon = "Howling Bites";
905 monsters[3][7].strength = 75;
906 monsters[3][7].gold = 1742;
907 monsters[3][7].exp = 65;
908 monsters[3][7].maxhp = 42;
909 monsters[3][7].death = "You scatter the wolf's body parts in hopes he will stay dead!";
910
911 monsters[3][8].name = "Dark Infantry";
912 monsters[3][8].weapon = "Flesh Reaper";
913 monsters[3][8].strength = 69;
914 monsters[3][8].gold = 870;
915 monsters[3][8].exp = 43;
916 monsters[3][8].maxhp = 65;
917 monsters[3][8].death = "Light has prevailed this time... but it's only so long before you meet again.";
918
919 monsters[3][9].name = "Erie Spirit";
920 monsters[3][9].weapon = "Deadly Grin";
921 monsters[3][9].strength = 63;
922 monsters[3][9].gold = 1300;
923 monsters[3][9].exp = 32;
924 monsters[3][9].maxhp = 50;
925 monsters[3][9].death = "His cousin the ghost was a little bit easier.";
926
927 monsters[3][10].name = "Gollum";
928 monsters[3][10].weapon = "Precious Treasure";
929 monsters[3][10].strength = 66;
930 monsters[3][10].gold = 1492;
931 monsters[3][10].exp = 73;
932 monsters[3][10].maxhp = 54;
933 monsters[3][10].death = "Gollum screams out \"MY PRECIOUS\" as his small body falls limp from your blow.";
934
935 monsters[3][11].name = "Rock Fighter";
936 monsters[3][11].weapon = "Small Boulders";
937 monsters[3][11].strength = 87;
938 monsters[3][11].gold = 1742;
939 monsters[3][11].exp = 99;
940 monsters[3][11].maxhp = 65;
941 monsters[3][11].death = "You dodge his last rock, and counter with a low blow, cutting off his legs.";
942
943
944 monsters[4][0].name = "Giant Sphinx";
945 monsters[4][0].weapon = "Ancient Curse";
946 monsters[4][0].strength = 120;
947 monsters[4][0].gold = 1000;
948 monsters[4][0].exp = 100;
949 monsters[4][0].maxhp = 80;
950 monsters[4][0].death = "You look in awe at the great wonder, collapsed at your feet!";
951
952 monsters[4][1].name = "Giant Ogre";
953 monsters[4][1].weapon = "Big Log";
954 monsters[4][1].strength = 130;
955 monsters[4][1].gold = 857;
956 monsters[4][1].exp = 175;
957 monsters[4][1].maxhp = 100;
958 monsters[4][1].death = "Your witz outmatched the ogres brawn... big dumb thing.";
959
960 monsters[4][2].name = "Massive Cockroach";
961 monsters[4][2].weapon = "Piercing Hiss";
962 monsters[4][2].strength = 125;
963 monsters[4][2].gold = 700;
964 monsters[4][2].exp = 150;
965 monsters[4][2].maxhp = 112;
966 monsters[4][2].death = "Where's the exterminator when you need one?";
967
968 monsters[4][3].name = "Big Venomous Snake";
969 monsters[4][3].weapon = "Poison Fangs";
970 monsters[4][3].strength = 140;
971 monsters[4][3].gold = 900;
972 monsters[4][3].exp = 175;
973 monsters[4][3].maxhp = 126;
974 monsters[4][3].death = "After killing this beast you check for puncture marks... you find none, luckily.";
975
976 monsters[4][4].name = "Lizard Man";
977 monsters[4][4].weapon = "Deadly Jaws";
978 monsters[4][4].strength = 145;
979 monsters[4][4].gold = 1250;
980 monsters[4][4].exp = 175;
981 monsters[4][4].maxhp = 150;
982 monsters[4][4].death = "His scales made for tough armor, and his jaws for a tougher opponent!";
983
984 monsters[4][5].name = "Face Dancer";
985 monsters[4][5].weapon = "Illusion Scyth";
986 monsters[4][5].strength = 138;
987 monsters[4][5].gold = 1603;
988 monsters[4][5].exp = 198;
989 monsters[4][5].maxhp = 173;
990 monsters[4][5].death = "His carcus takes the shape of many things before it dies. His true form is so repulsive, you know why he changed faces so much!";
991
992 monsters[4][6].name = "Darklord Longbow Archer";
993 monsters[4][6].weapon = "Deadly Bow and Arrows";
994 monsters[4][6].strength = 145;
995 monsters[4][6].gold = 1569;
996 monsters[4][6].exp = 243;
997 monsters[4][6].maxhp = 170;
998 monsters[4][6].death = "Your face turns white with horror after you realize you just met the devil's protector!";
999
1000 monsters[4][7].name = "Hell's Paladin";
1001 monsters[4][7].weapon = "Sword of Hellfire";
1002 monsters[4][7].strength = 200;
1003 monsters[4][7].gold = 2191;
1004 monsters[4][7].exp = 254;
1005 monsters[4][7].maxhp = 175;
1006 monsters[4][7].death = "This is starting to get tough you think. Do you really want to go to level 12?";
1007
1008 monsters[4][8].name = "The Unknown Soldier";
1009 monsters[4][8].weapon = "Soul Torture";
1010 monsters[4][8].strength = 175;
1011 monsters[4][8].gold = 1890;
1012 monsters[4][8].exp = 200;
1013 monsters[4][8].maxhp = 180;
1014 monsters[4][8].death = "Who was that? Where was he from? And what was that weapon??";
1015
1016 monsters[4][9].name = "Undead Cult Leader";
1017 monsters[4][9].weapon = "Lance of Deceit";
1018 monsters[4][9].strength = 180;
1019 monsters[4][9].gold = 1792;
1020 monsters[4][9].exp = 195;
1021 monsters[4][9].maxhp = 190;
1022 monsters[4][9].death = "His words fall on deaf ears... this is one cult you will NOT be part of!";
1023
1024 monsters[4][10].name = "Water Serpent";
1025 monsters[4][10].weapon = "Forked Tongue";
1026 monsters[4][10].strength = 150;
1027 monsters[4][10].gold = 1500;
1028 monsters[4][10].exp = 176;
1029 monsters[4][10].maxhp = 220;
1030 monsters[4][10].death = "The serpent squeals as you cut off its head!";
1031
1032 monsters[4][11].name = "Silverback Gorilla";
1033 monsters[4][11].weapon = "Deadly Banana Peel";
1034 monsters[4][11].strength = 160;
1035 monsters[4][11].gold = 1300;
1036 monsters[4][11].exp = 150;
1037 monsters[4][11].maxhp = 178;
1038 monsters[4][11].death = "Was that gorilla or guerilla?";
1039}
1040
1041void display_monster(char *u)
1042{
1043 if (is_playing(u))
1044 {
1045 aClient *user = find(u);
1046 Player *ni = user->stats;
1047
1048 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->hp);
1049 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", ni->fight->name, ni->fight->hp);
1050 notice(s_GameServ, u, "Here are your commands:");
1051 notice(s_GameServ, u, "/msg %S attack");
1052 notice(s_GameServ, u, "/msg %S run");
1053 notice(s_GameServ, u, "What will you do?");
1054 }
1055}
1056
1057void display_players(char *u)
1058{
1059 if (is_playing(u))
1060 {
1061 aClient *ni = find(u);
1062
1063 aClient *battle = ni->stats->battle;
1064
1065 notice(s_GameServ, u, "Your Hitpoints: \ 2%d\ 2", ni->stats->hp);
1066 notice(s_GameServ, u, "%s's Hitpoints: \ 2%d\ 2", battle->getNick(),
1067 battle->stats->hp);
1068
1069 notice(s_GameServ, u, "Here are your commands:");
1070 notice(s_GameServ, u, "/msg %s attack", s_GameServ);
1071 notice(s_GameServ, u, "/msg %s run", s_GameServ);
1072 notice(s_GameServ, u, "What will you do?");
1073 }
1074}
1075
1076
1077bool is_playing(char *u)
1078{
1079 aClient *user;
1080 if (!(user = find(u)))
1081 {
1082 return false;
1083 }
1084 else
1085 {
1086 return user->stats != NULL;
1087 }
1088}
1089
1090bool is_fighting(char *u)
1091{
1092 aClient *user;
1093
1094 if (!(user = find(u)))
1095 {
1096 return false;
1097 }
1098 else if (user->stats)
1099 {
1100 return user->stats->fight != NULL || user->stats->battle != NULL
1101 || user->stats->master != NULL;
1102 }
1103 else
1104 return false;
1105}
1106
1107bool player_fight(char *u)
1108{
1109 aClient *user;
1110
1111 if (!(user = find(u)))
1112 return false;
1113 else if (user->stats)
1114 return user->stats->battle != NULL;
1115 else
1116 return false;
1117}
1118
1119bool master_fight(char *u)
1120{
1121 aClient *user;
1122
1123 if (!(user = find(u)))
1124 return false;
1125 else if (user->stats)
1126 return user->stats->master != NULL;
1127 else
1128 return false;
1129}
1130
1131bool isnt_fighting(char *u)
1132{
1133 return !is_fighting(u);
1134}
1135
1136void do_fight(char *u)
1137{
1138 aClient *ni, *battle;
1139
1140 char *nick = strtok(NULL, " ");
1141
1142 if (!nick)
1143 {
1144 notice(s_GameServ, u, "SYNTAX: /msg %S FIGHT PLAYER");
1145 }
1146 else if (!(ni = find(u)))
1147 {
1148 return;
1149 }
1150 else if (!(battle = find(nick)))
1151 {
1152 notice(s_GameServ, u, "You can't attack %s while they aren't playing!", nick);
1153 }
1154 else if (!is_playing(u))
1155 {
1156 notice(s_GameServ, u, "You are not playing!");
1157 }
1158/*
1159 * Offline fighting not implemented yet.
1160 * else if (!(fight = finduser(nick)))
1161 * {
1162 * ni->stats->battle = battle;
1163 * battle->battle = ni;
1164 * ni->yourturn = 1;
1165 * battle->yourturn = 0;
1166 * notice(s_GameServ, u, "You decide to fight %s while they're not online!",
1167 * battle->getNick());
1168 * display_players(u);
1169 * }
1170 */
1171 else if (is_playing(u) && is_playing(nick))
1172 {
1173 // Set your battle pointer to the other player
1174 ni->stats->battle = battle;
1175
1176 // Set the other player's battle pointer to you
1177 battle->stats->battle = ni;
1178
1179 // The initiator gets the first move (perhaps this should be 50/50)
1180 ni->stats->yourturn = 1;
1181 battle->stats->yourturn = 0;
1182
1183 // Initiate Battle sequence!
1184 notice(s_GameServ, u, "You challenge %s to an online duel!", battle->getNick());
1185 notice(s_GameServ, battle->getNick(), "%s has challenged you to an online duel!", u);
1186 notice(s_GameServ, battle->getNick(), "%s gets to go first because he initiated!", u);
1187 notice(s_GameServ, battle->getNick(), "Please wait while %s decides what to do.", u);
1188 display_players(u);
1189 }
1190}
1191
1192void do_attack(char *u)
1193{
1194 int hit, mhit;
1195 aClient *ni, *battle; // The player and perhaps the player they're fighting
1196 Monster *fight; // The monster they may be fighting
1197
1198 if (!(ni = find(u)))
1199 {
1200 notice(s_GameServ, u, "You're not playing!");
1201 return;
1202 }
1203 else if (!ni->stats->fight && !ni->stats->battle && !ni->stats->master)
1204 {
1205 notice(s_GameServ, u, "You're not in battle!");
1206 return;
1207 }
1208 else
1209 {
1210 if (!ni->stats->master) // This is not a master fight
1211 fight = ni->stats->fight; // Monster Could be NULL
1212 else // This IS a master fight
1213 fight = ni->stats->master; // Master Could be NULL
1214
1215 battle = ni->stats->battle; // Player Could be NULL
1216
1217 // One has to be !NULL based on the previous else if
1218 // We wouldn't be here if they were all NULL
1219 }
1220
1221 if (!player_fight(u))
1222 {
1223 // Player's Hit
1224 hit = ((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1225 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon]) / 2));
1226
1227 // Opponent's Hit
1228 mhit = (fight->strength / 2) +
1229 (rand() % (fight->strength / 2) - (ni->stats->defense +
1230 arbonus[ni->stats->armor]));
1231 }
1232 else
1233 {
1234 // Opponent's Hit
1235 mhit = (((battle->stats->strength + webonus[battle->stats->weapon]) / 2) +
1236 (rand() % ((battle->stats->strength + webonus[battle->stats->weapon])) / 2) -
1237 (ni->stats->defense + arbonus[ni->stats->armor]));
1238
1239 // Player's Hit
1240 hit = (((ni->stats->strength + webonus[ni->stats->weapon]) / 2) +
1241 (rand() % ((ni->stats->strength + webonus[ni->stats->weapon])) / 2) -
1242 (battle->stats->defense + arbonus[battle->stats->armor]));
1243 }
1244
1245 if (!player_fight(u))
1246 {
1247 if (hit > 0)
1248 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", fight->name, hit);
1249 else
1250 notice(s_GameServ, u, "You miss \1f%s\1f completely!", fight->name);
1251
1252 if (hit >= fight->hp)
1253 {
1254 if (master_fight(u))
1255 notice(s_GameServ, u, "You have bested %s!", fight->name);
1256 else
1257 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", fight->name);
1258
1259 notice(s_GameServ, u, "%s", fight->death);
1260 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%d\ 2 gold!",
1261 fight->exp, fight->gold);
1262
1263 // If your new experience (or gold) will be greater than 2 billion,
1264 // then set your exp to 2bil. (2 billion max)... otherwise add them.
1265 // This could be a problem with overflowing out of the sign bit.
1266 // Unsigned long int maybe? Leave it for now.
1267 ni->stats->exp = ( (ni->stats->exp + fight->exp) > 2000000000 ? 2000000000 :
1268 ni->stats->exp + fight->exp);
1269 ni->stats->gold = (ni->stats->gold + fight->gold > 2000000000 ? 2000000000 :
1270 ni->stats->gold + fight->gold);
1271 ni->stats->fight = NULL; // They're dead so remove the pointer
1272
1273 if (master_fight(u))
1274 {
1275 notice(s_GameServ, u, "You are now level %d!", ni->stats->level + 1);
1276 notice(s_GameServ, u, "You gain %d Strength, and %d Defense points!",
1277 strbonus[ni->stats->level - 1], defbonus[ni->stats->level - 1]);
1278
1279 // Increase your level
1280 ni->stats->level++;
1281
1282 // Increase your maximum hit points
1283 ni->stats->maxhp += hpbonus[ni->stats->level - 1];
1284
1285 // Heal the player by setting hp to their max
1286 ni->stats->hp = ni->stats->maxhp;
1287
1288 // Add to your strength
1289 ni->stats->strength += strbonus[ni->stats->level - 1];
1290
1291 // Add to your defensive power
1292 ni->stats->defense += defbonus[ni->stats->level - 1];
1293
1294 // Clear the pointer for your master
1295 ni->stats->master = NULL;
1296 }
1297 return;
1298 }
1299 else
1300 {
1301 if (hit > 0)
1302 fight->hp -= hit;
1303 if (mhit > 0)
1304 {
1305 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1306 fight->name, fight->weapon, mhit);
1307 }
1308 else if (mhit <= 0)
1309 notice(s_GameServ, u, "%s completely misses you!", fight->name);
1310
1311 if (mhit >= ni->stats->hp)
1312 {
1313 if (!master_fight(u))
1314 {
1315 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", fight->name);
1316 notice(s_GameServ, u, "You lose all gold on hand and lose 10 percent "\
1317 "of your experience!");
1318 ni->stats->gold = 0;
1319 ni->stats->exp -= (long int)(ni->stats->exp * .10);
1320 ni->stats->fight = NULL;
1321 return;
1322 }
1323 else
1324 {
1325 notice(s_GameServ, u, "%s has bested you! You will have to wait "\
1326 "until tomorrow to try again", ni->stats->master->name);
1327 ni->stats->fight = NULL;
1328 ni->stats->master = NULL;
1329 return;
1330 }
1331 }
1332 else
1333 {
1334 if (mhit > 0)
1335 ni->stats->hp -= mhit;
1336 display_monster(u);
1337 return;
1338 }
1339 }
1340 }
1341 else if (player_fight(u))
1342 {
1343/* Offline fighting not available yet
1344 if (!(online = finduser(ni->stats->battle->nick)) || !nick_identified(online))
1345 {
1346 if (hit > 0)
1347 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->nick, hit);
1348 else
1349 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->nick);
1350 if (hit >= battle->stats->hp)
1351 {
1352 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->nick);
1353* notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1354 (long int)(battle->stats->exp * .10), battle->stats->gold);
1355 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1356 {
1357 ni->stats->exp += (long int)(battle->stats->exp * .10);
1358 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1359 }
1360* else
1361 {
1362 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1363 ni->stats->exp = 2000000000;
1364 }
1365
1366 if (2000000000 - ni->stats->gold > battle->stats->gold)
1367 {
1368* ni->stats->gold += battle->stats->gold;
1369 battle->stats->gold = 0;
1370 }
1371 else
1372 {
1373 battle->stats->gold = 2000000000 - ni->stats->gold;
1374 ni->stats->gold = 2000000000;
1375 }
1376* ni->stats->battle->stats->alive = 0;
1377 ni->stats->battle->battle = NULL;
1378 ni->stats->battle = NULL;
1379 return;
1380 }
1381 else
1382 {
1383 if (hit > 0)
1384* battle->stats->hp -= hit;
1385 if (mhit > 0)
1386 {
1387 notice(s_GameServ, u, "\1f%s\1f hits you with their \1f%s\1f for \ 2%d\ 2 damage!",
1388 battle->nick, weapons[battle->stats->weapon], mhit);
1389 }
1390 else if (mhit <= 0)
1391 notice(s_GameServ, u, "%s completely misses you!", battle->nick);
1392*
1393 if (mhit >= ni->stats->hp)
1394 {
1395 notice(s_GameServ, u, "You have been \ 2\1fkilled\1f\ 2 by %s!", battle->nick);
1396 if (2000000000 - battle->stats->gold > ni->stats->gold)
1397 {
1398 notice(s_GameServ, u, "%s took all your gold!", battle->nick);
1399 battle->stats->gold += ni->stats->gold;
1400* ni->stats->gold = 0;
1401 }
1402 else
1403 {
1404 notice(s_GameServ, u, "You're lucky, %s couldn't carry all your gold.",
1405 battle->nick);
1406 ni->stats->gold -= (2000000000 - battle->stats->gold);
1407 notice(s_GameServ, u, "You were left dead with %d gold.",
1408* (long int)ni->stats->gold);
1409 battle->stats->gold = 2000000000;
1410 }
1411 ni->stats->battle->battle = NULL;
1412 ni->stats->battle = NULL;
1413 ni->stats->alive = 0;
1414 return;
1415 }
1416* else
1417 {
1418 if (mhit > 0)
1419 ni->stats->hp -= mhit;
1420 display_players(u);
1421 return;
1422 }
1423 }
1424 }
1425* end offline fighting */
1426
1427 if (is_playing(battle->getNick()))
1428 {
1429 if (ni->stats->yourturn == 0)
1430 {
1431 notice(s_GameServ, u, "Please wait until %s decides what to do!",
1432 battle->getNick());
1433 return;
1434 }
1435 if (hit > 0)
1436 {
1437 notice(s_GameServ, u, "You attack \1f%s\1f for \ 2%d\ 2 points!", battle->getNick(), hit);
1438
1439 notice(s_GameServ, battle->getNick(), "%s has hit you with their %s for "\
1440 "\ 2%d\ 2 damage!", u, weapons[ni->stats->weapon],
1441 hit);
1442 ni->stats->yourturn = 0;
1443 battle->stats->yourturn = 1;
1444 display_players(battle->getNick());
1445 }
1446 else
1447 {
1448 notice(s_GameServ, u, "You miss \1f%s\1f completely!", battle->getNick());
1449 notice(s_GameServ, battle->getNick(), "%s misses you completely!", u);
1450 ni->stats->yourturn = 0;
1451 battle->stats->yourturn = 1;
1452 display_players(battle->getNick());
1453 }
1454 if (hit >= battle->stats->hp)
1455 {
1456 notice(s_GameServ, u, "You have killed \ 2%s\ 2!", battle->getNick());
1457 notice(s_GameServ, u, "You recieve \ 2%d\ 2 experience and \ 2%ld\ 2 gold!",
1458 (long int)(battle->stats->exp * .10), battle->stats->gold);
1459 notice(s_GameServ, battle->getNick(), "You have been killed by \ 2%s\ 2!", u);
1460 battle->stats->hp = 0;
1461 battle->stats->alive = 0;
1462
1463 if (2000000000 - ni->stats->exp > (long int)(battle->stats->exp * .10))
1464 {
1465 ni->stats->exp += (long int)(battle->stats->exp * .10);
1466 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1467 }
1468 else
1469 {
1470 battle->stats->exp -= (long int)(battle->stats->exp * .10);
1471 ni->stats->exp = 2000000000;
1472 }
1473
1474 if (2000000000 - ni->stats->gold > battle->stats->gold)
1475 {
1476 notice(s_GameServ, battle->getNick(), "You lose ten percent of experience and "\
1477 "all gold on hand!");
1478 ni->stats->gold += battle->stats->gold;
1479 battle->stats->gold = 0;
1480 }
1481 else
1482 {
1483 battle->stats->gold = 2000000000 - ni->stats->gold;
1484 notice(s_GameServ, battle->getNick(), "You lose ten percent of your experience!");
1485
1486 notice(s_GameServ, battle->getNick(), "However, %s could not carry all of your "\
1487 "gold.", u);
1488
1489 notice(s_GameServ, battle->getNick(), "Luckily, you still have \ 2%ld\ 2 gold "\
1490 "left. All is not lost!", battle->stats->gold);
1491
1492 ni->stats->gold = 2000000000;
1493 }
1494 battle->stats->battle = NULL;
1495 ni->stats->battle = NULL;
1496 return;
1497 }
1498 else
1499 {
1500 if (hit > 0)
1501 battle->stats->hp -= hit;
1502 //display_players(battle->getNick());
1503 ni->stats->yourturn = 0;
1504 battle->stats->yourturn = 1;
1505 notice(s_GameServ, u, "Please wait while %s decides what to do!",
1506 battle->getNick());
1507
1508 return;
1509 }
1510 }
1511 }
1512}
1513void do_heal(char *u)
1514{
1515 aClient *ni;
1516 char *amount = strtok(NULL, " ");
1517 int price, num;
1518
1519 if (!amount)
1520 {
1521 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1522 }
1523 else if (!(ni = find(u)) || !ni->stats)
1524 {
1525 notice(s_GameServ, u, "You aren't playing!");
1526 }
1527 else if (is_fighting(u))
1528 {
1529 notice(s_GameServ, u, "You can't heal in battle!");
1530 }
1531 else if (ni->stats->hp >= ni->stats->maxhp)
1532 {
1533 notice(s_GameServ, u, "You don't need healing!");
1534 }
1535 else if (stricmp(amount, "ALL") == 0)
1536 {
1537 price = ni->stats->level * 3;
1538 if (ni->stats->gold < (ni->stats->maxhp - ni->stats->hp) * price)
1539 {
1540 notice(s_GameServ, u, "Healing \ 2%d\ 2 points for \ 2%d\ 2 gold per point.",
1541 (long int)ni->stats->gold/price, price);
1542 ni->stats->hp += ni->stats->gold / price;
1543 ni->stats->gold %= price;
1544 }
1545 else
1546 {
1547 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1548 "per point.", price);
ad7dfaa0 1549 notice(s_GameServ, u, "\ 2%d\ 2 points healed for \ 2%ld\ 2 gold. HP at MAX!",
1550 (ni->stats->maxhp - ni->stats->hp),
1551 (price * (ni->stats->maxhp - ni->stats->hp)) );
85ce9d3e 1552 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1553 ni->stats->hp = ni->stats->maxhp;
1554 }
1555 }
1556 else if (isstringnum(amount))
1557 {
1558 num = stringtoint(amount);
1559 price = ni->stats->level * 3;
1560 if (ni->stats->gold < price * num)
1561 {
1562 notice(s_GameServ, u, "You only have enough gold to heal \ 2%d\ 2 points!",
1563 (long int)ni->stats->gold/price);
1564 }
1565 else if (num <= ni->stats->maxhp - ni->stats->hp)
1566 {
1567 notice(s_GameServ, u, "Healing \ 2%d\ 2 points at \ 2%d\ 2 gold per point.",
1568 num, price);
1569 ni->stats->hp += num;
1570 ni->stats->gold -= num * price;
1571 }
1572 else if (num > ni->stats->maxhp - ni->stats->hp)
1573 {
1574 notice(s_GameServ, u, "Healing all possible points at \ 2%d\ 2 gold "\
1575 "per point.", price);
1576 notice(s_GameServ, u, "\ 2%d\ 2 points healed. HP at MAX!",
1577 (ni->stats->maxhp - ni->stats->hp));
1578 ni->stats->gold -= price * (ni->stats->maxhp - ni->stats->hp);
1579 ni->stats->hp = ni->stats->maxhp;
1580 }
1581 }
1582 else if (amount[0] == '-')
1583 notice(s_GameServ, u, "You trying to cheat?");
1584 else
1585 notice(s_GameServ, u, "SYNTAX: /msg %S HEAL {ALL | #}");
1586}
1587
1588int isstringnum(char *num)
1589{
1590 int x;
1591 for (x = 0; x < strlen(num); x++)
1592 {
1593 if ((int)num[x] < 48 || (int)num[x] > 57)
1594 return 0;
1595 }
1596return 1;
1597}
1598
1599long int stringtoint(char *number)
1600{
1601 long int x, len = strlen(number), sum = 0;
1602 if (len == 1)
1603 return chartoint(number[0]);
1604 sum += chartoint(number[len - 1]);
1605 for (x = len - 2; x >= 0; x--)
1606 {
1607 sum += chartoint(number[x]) * pow(10, abs(x - len + 1));
1608 }
1609 return sum;
1610}
1611
1612long int pow(int x, int y)
1613{
1614 long int value = 0;
1615 int count = 0;
1616 value += x;
1617
1618 if (x != 0 && y != 0)
1619 {
1620 for (count = 1; count <= y - 1; count++)
1621 value *= x;
1622 }
1623 else
1624 return 1;
1625return value;
1626}
1627
1628long int chartoint(char ch)
1629{
1630 switch(ch)
1631 {
1632 case '0':
1633 return 0;
1634 break;
1635 case '1':
1636 return 1;
1637 case '2':
1638 return 2;
1639 case '3':
1640 return 3;
1641 case '4':
1642 return 4;
1643 case '5':
1644 return 5;
1645 case '6':
1646 return 6;
1647 case '7':
1648 return 7;
1649 case '8':
1650 return 8;
1651 case '9':
1652 return 9;
1653 case '\n':
1654 break;
1655 default:
1656 return -1;
1657 }
1658return -1;
1659}
1660
1661int save_gs_dbase()
1662{
1663 ListNode<aClient> *ptr = players.First();
1664 Player *it;
1665 ofstream outfile;
1666
1667 outfile.open(playerdata);
1668
1669 if (!outfile)
1670 {
1671 cerr << "Error opening " << playerdata << endl;
1672 return 0;
1673 }
1674
1675 while(ptr)
1676 {
1677 it = ptr->getData()->stats;
1678 outfile << it->name << ' ' << it->level << ' ' << it->exp << ' ' << it->gold << ' ' << it->bank << ' '
1679 << it->hp << ' ' << it->maxhp << ' ' << it->strength << ' ' << it->defense << ' '
1680 << it->armor << ' ' << it->weapon << ' ' << (it->alive ? "alive" : "dead") << ' '
e3c5fe46 1681 << it->forest_fights << ' ' << it->player_fights << ' '
1682 << it->password << endl;
85ce9d3e 1683 ptr = ptr->Next();
1684 }
1685outfile.close();
1686}
1687
1688int load_gs_dbase()
1689{
1690 ifstream infile;
1691 aClient *temp;
1692 Player *p;
e3c5fe46 1693 char *alive, *tempname, *buf, *password;
85ce9d3e 1694 buf = new char[1023];
1695
1696 infile.open(playerdata);
1697
1698 if (infile.fail())
1699 {
1700 cerr << "Error opening " << playerdata << endl;
1701 return 0;
1702 }
1703
1704 while (infile.getline(buf, 1024, '\n'))
1705 {
cbf6551f 1706 cout << "temp = new aClient;" << endl << flush;
85ce9d3e 1707 temp = new aClient;
cbf6551f 1708 cout << "tempname = strtok(buf, " ");" << endl << flush;
85ce9d3e 1709 tempname = strtok(buf, " ");
cbf6551f 1710
1711 cout << "temp->stats = new Player(tempname);" << endl << flush;
1712
85ce9d3e 1713 temp->stats = new Player(tempname);
cbf6551f 1714
1715 cout << "p = temp->stats;" << endl << flush;
85ce9d3e 1716 p = temp->stats;
1717
1718 //Kain 1 1 0 500 10 10 0 0 1 1 alive 100 3
1719 p->level = stringtoint(strtok(NULL, " "));
1720 p->exp = stringtoint(strtok(NULL, " "));
1721 p->gold = stringtoint(strtok(NULL, " "));
1722 p->bank = stringtoint(strtok(NULL, " "));
1723 p->hp = stringtoint(strtok(NULL, " "));
1724 p->maxhp = stringtoint(strtok(NULL, " "));
1725 p->strength = stringtoint(strtok(NULL, " "));
1726 p->defense = stringtoint(strtok(NULL, " "));
1727 p->armor = stringtoint(strtok(NULL, " "));
1728 p->weapon = stringtoint(strtok(NULL, " "));
1729 alive = strtok(NULL, " ");
1730 p->alive = (stricmp(alive, "ALIVE") == 0 ? true : false);
1731 p->forest_fights = stringtoint(strtok(NULL, " "));
1732 p->player_fights = stringtoint(strtok(NULL, " "));
e3c5fe46 1733 password = strtok(NULL, " ");
1734 strcpy(p->password, password);
85ce9d3e 1735 temp->setNick("NULL");
1736
e3c5fe46 1737 printf("%s %d %ld %ld %ld %d %d %d %d %d %d %s %d %d %s\n", p->name, p->level,
1738 p->exp, p->gold, p->bank, p->hp, p->maxhp, p->strength, p->defense, p->armor, p->weapon,
1739 alive, p->forest_fights, p->player_fights, p->password);
1740
cbf6551f 1741 cout << "Inserting " << temp->stats->name << " at back of list" << endl;
85ce9d3e 1742 players.insertAtBack(temp);
cbf6551f 1743 cout << temp->stats->name << " Inserted, now deleting" << endl;
85ce9d3e 1744 delete temp;
cbf6551f 1745 cout << "Deleted" << endl;
85ce9d3e 1746 }
1cf88153 1747delete [] buf;
85ce9d3e 1748}
1749
e3c5fe46 1750bool passcmp(char *encrypted, char *plaintext)
1751{
1752 char salt[3];
cdc9a6db 1753 char *plaintext2, *plainToencrypt;
1754 bool same = false;
1755
1756 plaintext2 = new char[strlen(encrypted) + strlen(plaintext)]; // Extra
1757 strcpy(plaintext2, plaintext);
1758
e3c5fe46 1759 salt[0] = encrypted[0];
1760 salt[1] = encrypted[1];
1761 salt[3] = '\0';
cdc9a6db 1762
1763 plainToencrypt = crypt(plaintext2, salt);
1764
1765 same = (strcmp((const char *)encrypted, plainToencrypt) == 0 ? true : false);
1766
1767 delete []plaintext2;
1768
1769 return same;
e3c5fe46 1770}
1771
1772bool check_password(char *name, char *plaintext)
1773{
0a1518fa 1774 aClient *client;
e3c5fe46 1775
0a1518fa 1776 if (!(client = findplayer(name)))
1777 return false;
1778 else
e3c5fe46 1779 {
0a1518fa 1780 return passcmp(client->stats->password, plaintext);
e3c5fe46 1781 }
e3c5fe46 1782}
1cf88153 1783
ad7dfaa0 1784void do_store(char *u)
1785{
1786 char *cmd = strtok(NULL, " ");
1787 char *item = strtok(NULL, " ");
1788 char *num = strtok(NULL, " ");
1789 char *space;
1790
1791 if (!cmd || !item)
1792 {
1793 notice(s_GameServ, u, "SYNTAX: STORE LIST {ARMOR | WEAPONS}");
1794 notice(s_GameServ, u, " \ 2STORE SELL {ARMOR | WEAPON}\ 2");
1795 notice(s_GameServ, u, " \ 2STORE BUY {ARMOR | WEAPON} \1fNUMBER\1f\ 2");
1796 }
1797 else if (stricmp(cmd, "LIST") == 0)
1798 {
1799 if (stricmp(item, "WEAPONS") == 0)
1800 {
1801 notice(s_GameServ, u, "Welcome to Kain's Armory");
1802 notice(s_GameServ, u, "Here are the weapons we have available for the killing, sire:");
1803 for (int x = 1; x < WNA; x++)
1804 {
1805 space = spaces(strlen(weapons[x]), ".");
1806 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, weapons[x], space, prices[x - 1]);
1807 free(space);
1808 }
1809 notice(s_GameServ, u, "To purchase a weapon, type /msg %S STORE BUY \ 2NUM\ 2.");
1810 notice(s_GameServ, u, "Where num. is the weapon number from the menu above.");
1811
1812 }
1813 else if (stricmp(item, "ARMOR") == 0)
1814 {
1815 notice(s_GameServ, u, "Welcome to Kain's Armory");
1816 notice(s_GameServ, u, "I hope you enjoy the fine armor we have available for your protection:");
1817 for (int x = 1; x < WNA; x++)
1818 {
1819 space = spaces(strlen(armors[x]), ".");
1820 notice(s_GameServ, u, "%s%d. %s%s%d",(x < 10 ? " " : ""), x, armors[x], space, prices[x - 1]);
1821 free(space);
1822 }
1823 notice(s_GameServ, u, "To purchase armor, type /msg %S store buy armor num.");
1824 notice(s_GameServ, u, "Where num. is the armor number from the menu above.");
1825
1826
1827 }
1828 } else if (stricmp(cmd, "BUY") == 0) {
1829 }
1830}